docit-ai 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 (81) hide show
  1. package/.env.example +1 -0
  2. package/INSTRUCTIONS.MD +70 -0
  3. package/dist/ai/engine.d.ts +24 -0
  4. package/dist/ai/engine.d.ts.map +1 -0
  5. package/dist/ai/engine.js +69 -0
  6. package/dist/ai/engine.js.map +1 -0
  7. package/dist/ai/prompts.d.ts +11 -0
  8. package/dist/ai/prompts.d.ts.map +1 -0
  9. package/dist/ai/prompts.js +116 -0
  10. package/dist/ai/prompts.js.map +1 -0
  11. package/dist/cli/index.d.ts +3 -0
  12. package/dist/cli/index.d.ts.map +1 -0
  13. package/dist/cli/index.js +384 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/formatter/index.d.ts +13 -0
  16. package/dist/formatter/index.d.ts.map +1 -0
  17. package/dist/formatter/index.js +76 -0
  18. package/dist/formatter/index.js.map +1 -0
  19. package/dist/index.d.ts +7 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +9 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/parser/extractor.d.ts +23 -0
  24. package/dist/parser/extractor.d.ts.map +1 -0
  25. package/dist/parser/extractor.js +148 -0
  26. package/dist/parser/extractor.js.map +1 -0
  27. package/dist/scanner/index.d.ts +11 -0
  28. package/dist/scanner/index.d.ts.map +1 -0
  29. package/dist/scanner/index.js +30 -0
  30. package/dist/scanner/index.js.map +1 -0
  31. package/package.json +31 -0
  32. package/server/.env.example +22 -0
  33. package/server/package-lock.json +4426 -0
  34. package/server/package.json +31 -0
  35. package/server/src/config/database.d.ts +18 -0
  36. package/server/src/config/database.d.ts.map +1 -0
  37. package/server/src/config/database.js +8 -0
  38. package/server/src/config/database.js.map +1 -0
  39. package/server/src/config/database.ts +31 -0
  40. package/server/src/index.d.ts +2 -0
  41. package/server/src/index.d.ts.map +1 -0
  42. package/server/src/index.js +33 -0
  43. package/server/src/index.js.map +1 -0
  44. package/server/src/index.ts +55 -0
  45. package/server/src/middleware/auth.d.ts +12 -0
  46. package/server/src/middleware/auth.d.ts.map +1 -0
  47. package/server/src/middleware/auth.js +35 -0
  48. package/server/src/middleware/auth.js.map +1 -0
  49. package/server/src/middleware/auth.ts +56 -0
  50. package/server/src/routes/auth.d.ts +3 -0
  51. package/server/src/routes/auth.d.ts.map +1 -0
  52. package/server/src/routes/auth.js +145 -0
  53. package/server/src/routes/auth.js.map +1 -0
  54. package/server/src/routes/auth.ts +185 -0
  55. package/server/src/routes/dashboard.ts +243 -0
  56. package/server/src/routes/generate.d.ts +3 -0
  57. package/server/src/routes/generate.d.ts.map +1 -0
  58. package/server/src/routes/generate.js +55 -0
  59. package/server/src/routes/generate.js.map +1 -0
  60. package/server/src/routes/generate.ts +75 -0
  61. package/server/src/routes/payment.ts +192 -0
  62. package/server/src/services/ai.d.ts +10 -0
  63. package/server/src/services/ai.d.ts.map +1 -0
  64. package/server/src/services/ai.js +75 -0
  65. package/server/src/services/ai.js.map +1 -0
  66. package/server/src/services/ai.ts +99 -0
  67. package/server/src/services/payment.ts +141 -0
  68. package/server/src/types/flutterwave.d.ts +60 -0
  69. package/server/supabase_payments.sql +35 -0
  70. package/server/supabase_schema.sql +90 -0
  71. package/server/tsconfig.json +17 -0
  72. package/server/vercel.json +15 -0
  73. package/server/verify_dashboard.ts +126 -0
  74. package/src/ai/engine.ts +103 -0
  75. package/src/ai/prompts.ts +123 -0
  76. package/src/cli/index.ts +552 -0
  77. package/src/formatter/index.ts +110 -0
  78. package/src/index.ts +11 -0
  79. package/src/parser/extractor.ts +211 -0
  80. package/src/scanner/index.ts +49 -0
  81. package/tsconfig.json +43 -0
@@ -0,0 +1,110 @@
1
+ import type { DocumentationResult } from "../ai/engine.js";
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+
5
+ /**
6
+ * Formatter Module
7
+ * Generates the DOCIT.md documentation file with the three-view hierarchy.
8
+ */
9
+
10
+ export interface FormatterOptions {
11
+ outputPath?: string;
12
+ projectName?: string;
13
+ }
14
+
15
+ export function formatDocumentation(
16
+ results: DocumentationResult[],
17
+ options: FormatterOptions = {},
18
+ ): string {
19
+ const projectName = options.projectName ?? "Project";
20
+ const timestamp = new Date().toISOString().split("T")[0];
21
+
22
+ const strategicContent =
23
+ results.find((r) => r.view === "strategic")?.content ?? "";
24
+ const technicalContent =
25
+ results.find((r) => r.view === "technical")?.content ?? "";
26
+ const personalContent =
27
+ results.find((r) => r.view === "personal")?.content ?? "";
28
+
29
+ const doc = `# ${projectName} Documentation
30
+
31
+ > Auto-generated by Docit on ${timestamp}
32
+
33
+ ---
34
+
35
+ ## Table of Contents
36
+
37
+ 1. [PM Dashboard (Strategic View)](#pm-dashboard-strategic-view)
38
+ 2. [Developer Reference (Technical View)](#developer-reference-technical-view)
39
+ 3. [Personal Roadmap (Individual View)](#personal-roadmap-individual-view)
40
+
41
+ ---
42
+
43
+ # PM Dashboard (Strategic View)
44
+
45
+ *For Project Managers and Stakeholders*
46
+
47
+ ${strategicContent}
48
+
49
+ ---
50
+
51
+ # Developer Reference (Technical View)
52
+
53
+ *For Developers and Engineers*
54
+
55
+ ${technicalContent}
56
+
57
+ ---
58
+
59
+ # Personal Roadmap (Individual View)
60
+
61
+ *For Solo Developers and Contributors*
62
+
63
+ ${personalContent}
64
+
65
+ ---
66
+
67
+ ## Changelog
68
+
69
+ | Date | Changes |
70
+ |------|---------|
71
+ | ${timestamp} | Documentation generated |
72
+
73
+ ---
74
+
75
+ *Generated by [Docit](https://github.com/docit) - Your AI-powered documentation companion*
76
+ `;
77
+
78
+ return doc;
79
+ }
80
+
81
+ export function writeDocumentation(
82
+ content: string,
83
+ outputPath: string = "./DOCIT.md",
84
+ ): void {
85
+ const absolutePath = path.resolve(outputPath);
86
+ fs.writeFileSync(absolutePath, content, "utf-8");
87
+ }
88
+
89
+ export function appendToChangelog(
90
+ existingContent: string,
91
+ newEntry: string,
92
+ ): string {
93
+ const changelogPattern =
94
+ /## Changelog\n\n\| Date \| Changes \|\n\|------\|---------\|\n/;
95
+ const match = existingContent.match(changelogPattern);
96
+
97
+ if (match) {
98
+ const insertPosition = (match.index ?? 0) + match[0].length;
99
+ const timestamp = new Date().toISOString().split("T")[0];
100
+ const newRow = `| ${timestamp} | ${newEntry} |\n`;
101
+
102
+ return (
103
+ existingContent.slice(0, insertPosition) +
104
+ newRow +
105
+ existingContent.slice(insertPosition)
106
+ );
107
+ }
108
+
109
+ return existingContent;
110
+ }
package/src/index.ts ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Docit - AI-powered documentation generator
5
+ * Entry point for the CLI application
6
+ */
7
+
8
+ import { createCli } from "./cli/index.js";
9
+
10
+ const program = createCli();
11
+ program.parse(process.argv);
@@ -0,0 +1,211 @@
1
+ import Parser from "tree-sitter";
2
+ import TypeScript from "tree-sitter-typescript";
3
+ import * as fs from "fs";
4
+
5
+ /**
6
+ * Parser Module
7
+ * Uses tree-sitter to extract "Code Skeletons" from TypeScript files.
8
+ */
9
+
10
+ export interface CodeSkeleton {
11
+ name: string;
12
+ kind: "function" | "class" | "interface" | "type" | "variable" | "export";
13
+ signature: string;
14
+ parameters?: string[] | undefined;
15
+ returnType?: string | undefined;
16
+ comments?: string | undefined;
17
+ startLine: number;
18
+ endLine: number;
19
+ }
20
+
21
+ export interface FileAnalysis {
22
+ filePath: string;
23
+ skeletons: CodeSkeleton[];
24
+ todos: string[];
25
+ }
26
+
27
+ const parser = new Parser();
28
+ parser.setLanguage(TypeScript.typescript);
29
+
30
+ function extractComments(
31
+ node: Parser.SyntaxNode,
32
+ sourceCode: string,
33
+ ): string | undefined {
34
+ // Look for preceding comments
35
+ let sibling = node.previousNamedSibling;
36
+ while (sibling && sibling.type === "comment") {
37
+ const commentText = sourceCode.slice(sibling.startIndex, sibling.endIndex);
38
+ return commentText
39
+ .replace(/^\/\*\*?|\*\/$/g, "")
40
+ .replace(/^\s*\* ?/gm, "")
41
+ .trim();
42
+ }
43
+ return undefined;
44
+ }
45
+
46
+ function extractTodos(sourceCode: string): string[] {
47
+ const todoPattern = /\/\/\s*TODO[:\s](.+)|\/\*\s*TODO[:\s](.+?)\*\//gi;
48
+ const todos: string[] = [];
49
+ let match;
50
+
51
+ while ((match = todoPattern.exec(sourceCode)) !== null) {
52
+ todos.push((match[1] ?? match[2] ?? "").trim());
53
+ }
54
+
55
+ return todos;
56
+ }
57
+
58
+ function getNodeText(
59
+ node: Parser.SyntaxNode | null,
60
+ sourceCode: string,
61
+ ): string {
62
+ if (!node) return "";
63
+ return sourceCode.slice(node.startIndex, node.endIndex);
64
+ }
65
+
66
+ function extractFunctionSkeleton(
67
+ node: Parser.SyntaxNode,
68
+ sourceCode: string,
69
+ ): CodeSkeleton {
70
+ const nameNode = node.childForFieldName("name");
71
+ const paramsNode = node.childForFieldName("parameters");
72
+ const returnTypeNode = node.childForFieldName("return_type");
73
+
74
+ const parameters = paramsNode
75
+ ? getNodeText(paramsNode, sourceCode)
76
+ .replace(/^\(|\)$/g, "")
77
+ .split(",")
78
+ .map((p) => p.trim())
79
+ .filter((p) => p.length > 0)
80
+ : [];
81
+
82
+ return {
83
+ name: nameNode ? getNodeText(nameNode, sourceCode) : "anonymous",
84
+ kind: "function",
85
+ signature: `function ${getNodeText(nameNode, sourceCode)}${getNodeText(paramsNode, sourceCode)}${returnTypeNode ? ": " + getNodeText(returnTypeNode, sourceCode).replace(/^:\s*/, "") : ""}`,
86
+ parameters,
87
+ returnType: returnTypeNode
88
+ ? getNodeText(returnTypeNode, sourceCode).replace(/^:\s*/, "")
89
+ : undefined,
90
+ comments: extractComments(node, sourceCode),
91
+ startLine: node.startPosition.row + 1,
92
+ endLine: node.endPosition.row + 1,
93
+ };
94
+ }
95
+
96
+ function extractClassSkeleton(
97
+ node: Parser.SyntaxNode,
98
+ sourceCode: string,
99
+ ): CodeSkeleton {
100
+ const nameNode = node.childForFieldName("name");
101
+
102
+ return {
103
+ name: nameNode ? getNodeText(nameNode, sourceCode) : "AnonymousClass",
104
+ kind: "class",
105
+ signature: `class ${getNodeText(nameNode, sourceCode)}`,
106
+ comments: extractComments(node, sourceCode),
107
+ startLine: node.startPosition.row + 1,
108
+ endLine: node.endPosition.row + 1,
109
+ };
110
+ }
111
+
112
+ function extractInterfaceSkeleton(
113
+ node: Parser.SyntaxNode,
114
+ sourceCode: string,
115
+ ): CodeSkeleton {
116
+ const nameNode = node.childForFieldName("name");
117
+
118
+ return {
119
+ name: nameNode ? getNodeText(nameNode, sourceCode) : "AnonymousInterface",
120
+ kind: "interface",
121
+ signature: `interface ${getNodeText(nameNode, sourceCode)}`,
122
+ comments: extractComments(node, sourceCode),
123
+ startLine: node.startPosition.row + 1,
124
+ endLine: node.endPosition.row + 1,
125
+ };
126
+ }
127
+
128
+ function extractTypeSkeleton(
129
+ node: Parser.SyntaxNode,
130
+ sourceCode: string,
131
+ ): CodeSkeleton {
132
+ const nameNode = node.childForFieldName("name");
133
+
134
+ return {
135
+ name: nameNode ? getNodeText(nameNode, sourceCode) : "AnonymousType",
136
+ kind: "type",
137
+ signature: `type ${getNodeText(nameNode, sourceCode)}`,
138
+ comments: extractComments(node, sourceCode),
139
+ startLine: node.startPosition.row + 1,
140
+ endLine: node.endPosition.row + 1,
141
+ };
142
+ }
143
+
144
+ export function extractSkeletons(sourceCode: string): CodeSkeleton[] {
145
+ const tree = parser.parse(sourceCode);
146
+ const skeletons: CodeSkeleton[] = [];
147
+
148
+ function traverse(node: Parser.SyntaxNode) {
149
+ switch (node.type) {
150
+ case "function_declaration":
151
+ case "arrow_function":
152
+ case "method_definition":
153
+ skeletons.push(extractFunctionSkeleton(node, sourceCode));
154
+ break;
155
+ case "class_declaration":
156
+ skeletons.push(extractClassSkeleton(node, sourceCode));
157
+ break;
158
+ case "interface_declaration":
159
+ skeletons.push(extractInterfaceSkeleton(node, sourceCode));
160
+ break;
161
+ case "type_alias_declaration":
162
+ skeletons.push(extractTypeSkeleton(node, sourceCode));
163
+ break;
164
+ case "export_statement":
165
+ // Handle exported declarations
166
+ for (const child of node.children) {
167
+ traverse(child);
168
+ }
169
+ return; // Don't traverse children again
170
+ }
171
+
172
+ for (const child of node.children) {
173
+ traverse(child);
174
+ }
175
+ }
176
+
177
+ traverse(tree.rootNode);
178
+ return skeletons;
179
+ }
180
+
181
+ export function analyzeFile(filePath: string): FileAnalysis {
182
+ const sourceCode = fs.readFileSync(filePath, "utf-8");
183
+
184
+ return {
185
+ filePath,
186
+ skeletons: extractSkeletons(sourceCode),
187
+ todos: extractTodos(sourceCode),
188
+ };
189
+ }
190
+
191
+ export function formatSkeletonForLLM(analysis: FileAnalysis): string {
192
+ const lines: string[] = [`File: ${analysis.filePath}`, "---"];
193
+
194
+ for (const skeleton of analysis.skeletons) {
195
+ lines.push(`[${skeleton.kind.toUpperCase()}] ${skeleton.signature}`);
196
+ if (skeleton.comments) {
197
+ lines.push(` Comment: ${skeleton.comments}`);
198
+ }
199
+ lines.push(` Lines: ${skeleton.startLine}-${skeleton.endLine}`);
200
+ lines.push("");
201
+ }
202
+
203
+ if (analysis.todos.length > 0) {
204
+ lines.push("TODOs:");
205
+ for (const todo of analysis.todos) {
206
+ lines.push(` - ${todo}`);
207
+ }
208
+ }
209
+
210
+ return lines.join("\n");
211
+ }
@@ -0,0 +1,49 @@
1
+ import { simpleGit, type SimpleGit } from "simple-git";
2
+ import * as path from "path";
3
+
4
+ /**
5
+ * Scanner Module
6
+ * Uses simple-git to identify files modified in the last commit.
7
+ */
8
+
9
+ export interface ChangedFile {
10
+ path: string;
11
+ status: string;
12
+ }
13
+
14
+ export async function getChangedFiles(
15
+ repoPath: string = ".",
16
+ ): Promise<ChangedFile[]> {
17
+ const git: SimpleGit = simpleGit(repoPath);
18
+
19
+ try {
20
+ // Get the diff of the last commit
21
+ const diffSummary = await git.diffSummary(["HEAD~1", "HEAD"]);
22
+
23
+ const changedFiles: ChangedFile[] = diffSummary.files.map((file) => ({
24
+ path: path.resolve(repoPath, file.file),
25
+ status: "binary" in file ? "binary" : "modified",
26
+ }));
27
+
28
+ return changedFiles;
29
+ } catch {
30
+ // If there's no previous commit, get all tracked files
31
+ const status = await git.status();
32
+ const allFiles = [...status.modified, ...status.created, ...status.staged];
33
+
34
+ return [...new Set(allFiles)].map((filePath) => ({
35
+ path: path.resolve(repoPath, filePath),
36
+ status: "new",
37
+ }));
38
+ }
39
+ }
40
+
41
+ export async function getModifiedTypeScriptFiles(
42
+ repoPath: string = ".",
43
+ ): Promise<string[]> {
44
+ const changedFiles = await getChangedFiles(repoPath);
45
+
46
+ return changedFiles
47
+ .filter((file) => file.path.endsWith(".ts") || file.path.endsWith(".tsx"))
48
+ .map((file) => file.path);
49
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ // Visit https://aka.ms/tsconfig to read more about this file
3
+ "compilerOptions": {
4
+ // File Layout
5
+ "rootDir": "./src",
6
+ "outDir": "./dist",
7
+
8
+ // Environment Settings
9
+ // See also https://aka.ms/tsconfig/module
10
+ "module": "nodenext",
11
+ "target": "esnext",
12
+ "lib": ["esnext"],
13
+ "types": ["node"],
14
+
15
+ // Other Outputs
16
+ "sourceMap": true,
17
+ "declaration": true,
18
+ "declarationMap": true,
19
+
20
+ // Stricter Typechecking Options
21
+ "noUncheckedIndexedAccess": true,
22
+ "exactOptionalPropertyTypes": true,
23
+
24
+ // Style Options
25
+ // "noImplicitReturns": true,
26
+ // "noImplicitOverride": true,
27
+ // "noUnusedLocals": true,
28
+ // "noUnusedParameters": true,
29
+ // "noFallthroughCasesInSwitch": true,
30
+ // "noPropertyAccessFromIndexSignature": true,
31
+
32
+ // Recommended Options
33
+ "strict": true,
34
+ "jsx": "react-jsx",
35
+ "verbatimModuleSyntax": true,
36
+ "isolatedModules": true,
37
+ "noUncheckedSideEffectImports": true,
38
+ "moduleDetection": "force",
39
+ "skipLibCheck": true
40
+ },
41
+ "include": ["src/**/*"],
42
+ "exclude": ["node_modules", "dist", "server"]
43
+ }