@oisheek_c/codeforge 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.
Files changed (141) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +7 -0
  3. package/apps/cli/bin/codeforge.cmd +2 -0
  4. package/apps/cli/src/bootstrap.js +115 -0
  5. package/apps/cli/src/cli.js +189 -0
  6. package/apps/cli/src/dev/git.js +17 -0
  7. package/apps/cli/src/dev/index.js +68 -0
  8. package/apps/cli/src/dev/provider.js +48 -0
  9. package/apps/cli/src/dev/scanner.js +14 -0
  10. package/apps/cli/src/index.js +31 -0
  11. package/bin/codeforge.js +2 -0
  12. package/package.json +63 -0
  13. package/packages/agent/contextBuilder.js +234 -0
  14. package/packages/agent/executor.js +1729 -0
  15. package/packages/agent/fallback.js +129 -0
  16. package/packages/agent/index.js +26 -0
  17. package/packages/agent/intent.js +73 -0
  18. package/packages/agent/modelSelector.js +469 -0
  19. package/packages/agent/planner.js +379 -0
  20. package/packages/agent/rag.js +412 -0
  21. package/packages/agent/ragSelector.js +570 -0
  22. package/packages/agent/router.js +121 -0
  23. package/packages/agent/thinking.js +54 -0
  24. package/packages/agent/toolCalls.js +258 -0
  25. package/packages/config/config.js +391 -0
  26. package/packages/config/defaults.js +72 -0
  27. package/packages/config/index.js +2 -0
  28. package/packages/core/approvalPolicy.js +140 -0
  29. package/packages/core/context.js +0 -0
  30. package/packages/core/message.js +0 -0
  31. package/packages/core/plan.js +0 -0
  32. package/packages/core/reasoning.js +0 -0
  33. package/packages/core/result.js +0 -0
  34. package/packages/core/retrieval.js +0 -0
  35. package/packages/core/tool.js +536 -0
  36. package/packages/git/branch.js +7 -0
  37. package/packages/git/commit.js +16 -0
  38. package/packages/git/diff.js +15 -0
  39. package/packages/git/git.js +35 -0
  40. package/packages/git/index.js +6 -0
  41. package/packages/git/remote.js +9 -0
  42. package/packages/git/status.js +11 -0
  43. package/packages/memory/index.js +0 -0
  44. package/packages/memory/project.js +0 -0
  45. package/packages/memory/session.js +0 -0
  46. package/packages/prompts/builder.js +43 -0
  47. package/packages/prompts/coder.js +38 -0
  48. package/packages/prompts/index.js +5 -0
  49. package/packages/prompts/planner.js +49 -0
  50. package/packages/prompts/reviewer.js +38 -0
  51. package/packages/prompts/system.js +94 -0
  52. package/packages/providers/index.js +31 -0
  53. package/packages/providers/openrouter.js +380 -0
  54. package/packages/reasoning/budget.js +0 -0
  55. package/packages/reasoning/chain.js +0 -0
  56. package/packages/reasoning/coder.js +0 -0
  57. package/packages/reasoning/evaluator.js +0 -0
  58. package/packages/reasoning/index.js +8 -0
  59. package/packages/reasoning/planner.js +0 -0
  60. package/packages/reasoning/reflector.js +0 -0
  61. package/packages/reasoning/reviewer.js +0 -0
  62. package/packages/reasoning/router.js +0 -0
  63. package/packages/retrieval/budget.js +92 -0
  64. package/packages/retrieval/cache.js +84 -0
  65. package/packages/retrieval/embeddings.js +147 -0
  66. package/packages/retrieval/graph.js +151 -0
  67. package/packages/retrieval/imports.js +74 -0
  68. package/packages/retrieval/index.js +9 -0
  69. package/packages/retrieval/parser/extractors/calls.js +43 -0
  70. package/packages/retrieval/parser/extractors/comments.js +49 -0
  71. package/packages/retrieval/parser/extractors/diagnostics.js +21 -0
  72. package/packages/retrieval/parser/extractors/exports.js +71 -0
  73. package/packages/retrieval/parser/extractors/imports.js +40 -0
  74. package/packages/retrieval/parser/extractors/index.js +12 -0
  75. package/packages/retrieval/parser/extractors/metrics.js +78 -0
  76. package/packages/retrieval/parser/extractors/symbols.js +51 -0
  77. package/packages/retrieval/parser/extractors/todos.js +53 -0
  78. package/packages/retrieval/parser/helpers.js +138 -0
  79. package/packages/retrieval/parser/index.js +10 -0
  80. package/packages/retrieval/parser/languages/c.js +14 -0
  81. package/packages/retrieval/parser/languages/cpp.js +21 -0
  82. package/packages/retrieval/parser/languages/csharp.js +14 -0
  83. package/packages/retrieval/parser/languages/go.js +14 -0
  84. package/packages/retrieval/parser/languages/index.js +12 -0
  85. package/packages/retrieval/parser/languages/java.js +14 -0
  86. package/packages/retrieval/parser/languages/javascript.js +14 -0
  87. package/packages/retrieval/parser/languages/php.js +14 -0
  88. package/packages/retrieval/parser/languages/python.js +14 -0
  89. package/packages/retrieval/parser/languages/ruby.js +14 -0
  90. package/packages/retrieval/parser/languages/rust.js +14 -0
  91. package/packages/retrieval/parser/languages/swift.js +14 -0
  92. package/packages/retrieval/parser/languages/typescript.js +14 -0
  93. package/packages/retrieval/parser/languages.js +218 -0
  94. package/packages/retrieval/parser/parseFile.js +79 -0
  95. package/packages/retrieval/parser/parseRepository.js +78 -0
  96. package/packages/retrieval/parser/queries/c.js +148 -0
  97. package/packages/retrieval/parser/queries/cpp.js +198 -0
  98. package/packages/retrieval/parser/queries/csharp.js +151 -0
  99. package/packages/retrieval/parser/queries/go.js +124 -0
  100. package/packages/retrieval/parser/queries/index.js +35 -0
  101. package/packages/retrieval/parser/queries/java.js +128 -0
  102. package/packages/retrieval/parser/queries/javascript.js +181 -0
  103. package/packages/retrieval/parser/queries/php.js +140 -0
  104. package/packages/retrieval/parser/queries/python.js +110 -0
  105. package/packages/retrieval/parser/queries/ruby.js +105 -0
  106. package/packages/retrieval/parser/queries/rust.js +175 -0
  107. package/packages/retrieval/parser/queries/swift.js +134 -0
  108. package/packages/retrieval/parser/queries/typescript.js +202 -0
  109. package/packages/retrieval/parser/registry.js +107 -0
  110. package/packages/retrieval/parser/traverse.js +82 -0
  111. package/packages/retrieval/parser/types.js +239 -0
  112. package/packages/retrieval/parser.js +78 -0
  113. package/packages/retrieval/ranker.js +73 -0
  114. package/packages/retrieval/retriever.js +910 -0
  115. package/packages/retrieval/symbols.js +145 -0
  116. package/packages/scanner/detect.js +69 -0
  117. package/packages/scanner/ignore.js +12 -0
  118. package/packages/scanner/index.js +2 -0
  119. package/packages/scanner/root.js +21 -0
  120. package/packages/scanner/scanner.js +35 -0
  121. package/packages/scanner/tree.js +45 -0
  122. package/packages/terminal/activity.js +514 -0
  123. package/packages/terminal/banner.js +34 -0
  124. package/packages/terminal/colors.js +16 -0
  125. package/packages/terminal/dashboard.js +94 -0
  126. package/packages/terminal/index.js +19 -0
  127. package/packages/terminal/logger.js +43 -0
  128. package/packages/terminal/prompt.js +11 -0
  129. package/packages/terminal/renderer.js +1209 -0
  130. package/packages/terminal/spinner.js +9 -0
  131. package/packages/tools/editFile.js +261 -0
  132. package/packages/tools/filesystem.js +82 -0
  133. package/packages/tools/index.js +24 -0
  134. package/packages/tools/readFile.js +101 -0
  135. package/packages/tools/registry.js +227 -0
  136. package/packages/tools/searchFiles.js +322 -0
  137. package/packages/tools/shell.js +352 -0
  138. package/packages/tools/writeFile.js +212 -0
  139. package/packages/utils/constants.js +0 -0
  140. package/packages/utils/helpers.js +0 -0
  141. package/packages/utils/logger.js +0 -0
package/LICENSE ADDED
File without changes
package/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # CodeForge AI
2
+
3
+ Terminal-native AI Software Engineering Agent
4
+
5
+ Status
6
+
7
+ 🚧 Under Development
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ node "%~dp0..\src\index.js" %*
@@ -0,0 +1,115 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+
4
+ import dotenv from "dotenv";
5
+
6
+ import {
7
+ scanProject,
8
+ findWorkspaceRoot,
9
+ } from "../../../packages/scanner/index.js";
10
+
11
+ import {
12
+ inspectGit,
13
+ } from "../../../packages/git/index.js";
14
+
15
+ import {
16
+ buildRepository,
17
+ } from "../../../packages/retrieval/index.js";
18
+
19
+ import {
20
+ createSystemPrompt,
21
+ } from "../../../packages/prompts/index.js";
22
+
23
+ import {
24
+ execute,
25
+ } from "../../../packages/agent/index.js";
26
+
27
+ import {
28
+ createOpenRouter,
29
+ } from "../../../packages/providers/index.js";
30
+
31
+ import {
32
+ showBanner,
33
+ logger,
34
+ } from "../../../packages/terminal/index.js";
35
+
36
+ import {
37
+ loadConfig,
38
+ } from "../../../packages/config/index.js";
39
+
40
+ import {
41
+ createToolRegistry,
42
+ readFileTool,
43
+ searchFilesTool,
44
+ writeFileTool,
45
+ editFileTool,
46
+ shellTool,
47
+ } from "../../../packages/tools/index.js";
48
+
49
+ import { startCLI } from "./cli.js";
50
+
51
+ const __filename = fileURLToPath(import.meta.url);
52
+ const __dirname = path.dirname(__filename);
53
+
54
+ dotenv.config({
55
+ path: path.resolve(__dirname, "../../../.env"),
56
+ });
57
+
58
+ export async function bootstrap() {
59
+ try {
60
+ const config = loadConfig();
61
+
62
+ showBanner();
63
+
64
+ logger.success("Configuration loaded.");
65
+
66
+ const root = await findWorkspaceRoot(process.cwd());
67
+
68
+ const project = await scanProject(root);
69
+
70
+ logger.success(`Project: ${project.name}`);
71
+
72
+ logger.info("Building repository index...");
73
+
74
+ const repository = await buildRepository(root);
75
+
76
+ logger.success("Repository indexed.");
77
+
78
+ const git = await inspectGit(root);
79
+
80
+ const provider = createOpenRouter(config);
81
+
82
+ logger.success("OpenRouter provider initialized.");
83
+
84
+ const tools = createToolRegistry([
85
+ readFileTool,
86
+ searchFilesTool,
87
+ writeFileTool,
88
+ editFileTool,
89
+ shellTool,
90
+ ]);
91
+
92
+ logger.success(
93
+ `Tool registry initialized (${tools.size()} tools).`
94
+ );
95
+
96
+ const systemPrompt = createSystemPrompt();
97
+
98
+ logger.success("CodeForge initialized.");
99
+
100
+ startCLI({
101
+ config,
102
+ project,
103
+ git,
104
+ provider,
105
+ repository,
106
+ tools,
107
+ systemPrompt,
108
+ execute,
109
+ });
110
+
111
+ } catch (error) {
112
+ logger.error(error.message);
113
+ process.exit(1);
114
+ }
115
+ }
@@ -0,0 +1,189 @@
1
+ import {
2
+ createPrompt,
3
+ logger,
4
+ createAgentDashboard,
5
+ } from "../../../packages/terminal/index.js";
6
+
7
+ async function requestToolApproval(
8
+ prompt,
9
+ request
10
+ ) {
11
+ const {
12
+ toolName,
13
+ arguments: args = {},
14
+ } = request;
15
+
16
+ logger.plain("");
17
+ logger.line();
18
+
19
+ logger.warn(
20
+ `Approval required`
21
+ );
22
+
23
+ logger.plain(
24
+ `Tool: ${toolName}`
25
+ );
26
+
27
+ if (
28
+ toolName === "execute_command" &&
29
+ typeof args.command === "string"
30
+ ) {
31
+ logger.plain(
32
+ `Command: ${args.command}`
33
+ );
34
+ }
35
+
36
+ if (args.path) {
37
+ logger.plain(
38
+ `Path: ${args.path}`
39
+ );
40
+ }
41
+
42
+ if (
43
+ toolName === "write_file" &&
44
+ typeof args.content === "string"
45
+ ) {
46
+ logger.plain(
47
+ `Content size: ${Buffer.byteLength(
48
+ args.content,
49
+ "utf8"
50
+ )} bytes`
51
+ );
52
+ }
53
+
54
+ logger.line();
55
+
56
+ return new Promise((resolve) => {
57
+ prompt.question(
58
+ "Approve? [y/N] ",
59
+ (answer) => {
60
+ const normalized =
61
+ answer
62
+ .trim()
63
+ .toLowerCase();
64
+
65
+ const approved =
66
+ normalized === "y" ||
67
+ normalized === "yes";
68
+
69
+ logger.plain(
70
+ approved
71
+ ? "Approved."
72
+ : "Denied."
73
+ );
74
+
75
+ logger.plain("");
76
+
77
+ resolve(approved);
78
+ }
79
+ );
80
+ });
81
+ }
82
+
83
+ export function startCLI(app) {
84
+ const {
85
+ config,
86
+ project,
87
+ git,
88
+ provider,
89
+ repository,
90
+ tools,
91
+ systemPrompt,
92
+ execute,
93
+ } = app;
94
+
95
+ logger.success(`Loaded project: ${project.name}`);
96
+
97
+ if (git?.isRepository) {
98
+ logger.info(`Git Branch: ${git.branch.current}`);
99
+
100
+ if (git.status.clean) {
101
+ logger.success("Working tree clean.");
102
+ } else {
103
+ logger.warn("Working tree has uncommitted changes.");
104
+ }
105
+ }
106
+
107
+ const dashboard = createAgentDashboard({
108
+ enabled: config.agentDashboard,
109
+ projectRoot: project.root,
110
+ });
111
+
112
+ const prompt = createPrompt();
113
+
114
+ prompt.prompt();
115
+
116
+ prompt.on("line", async (input) => {
117
+ const command = input.trim();
118
+
119
+ if (!command) {
120
+ prompt.prompt();
121
+ return;
122
+ }
123
+
124
+ if (command.toLowerCase() === "exit") {
125
+ logger.info("Goodbye!");
126
+ prompt.close();
127
+ return;
128
+ }
129
+
130
+ try {
131
+ prompt.pause();
132
+
133
+ const result = await execute({
134
+ prompt: command,
135
+ repository,
136
+ provider,
137
+ providers: [
138
+ {
139
+ name: "openrouter",
140
+ },
141
+ ],
142
+ tools,
143
+ config,
144
+ project,
145
+ git,
146
+ memory: {},
147
+ systemPrompt,
148
+
149
+ requestApproval: async (request) => {
150
+ dashboard.suspend();
151
+
152
+ try {
153
+ return await requestToolApproval(
154
+ prompt,
155
+ request
156
+ );
157
+ } finally {
158
+ dashboard.resume();
159
+ }
160
+ },
161
+
162
+ onEvent: dashboard.handle,
163
+ });
164
+
165
+ dashboard.finish();
166
+
167
+ logger.plain("");
168
+ logger.plain(
169
+ result.response.message?.content ?? "No response."
170
+ );
171
+ logger.plain("");
172
+ } catch (error) {
173
+ dashboard.finish();
174
+ logger.error(error.message);
175
+ } finally {
176
+ prompt.resume();
177
+ prompt.prompt();
178
+ }
179
+ });
180
+
181
+ prompt.on("close", () => {
182
+ process.exit(0);
183
+ });
184
+
185
+ process.on("SIGINT", () => {
186
+ logger.info("Shutting down...");
187
+ prompt.close();
188
+ });
189
+ }
@@ -0,0 +1,17 @@
1
+ import {
2
+ findWorkspaceRoot,
3
+ } from "../../../../packages/scanner/index.js";
4
+
5
+ import {
6
+ inspectGit,
7
+ } from "../../../../packages/git/index.js";
8
+
9
+ export async function testGit() {
10
+ console.log("\n===== Git =====");
11
+
12
+ const root = await findWorkspaceRoot(process.cwd());
13
+
14
+ const git = await inspectGit(root);
15
+
16
+ console.dir(git, { depth: null });
17
+ }
@@ -0,0 +1,68 @@
1
+ import dotenv from "dotenv";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+
5
+ import { loadConfig } from "../../../../packages/config/index.js";
6
+
7
+ import { testScanner } from "./scanner.js";
8
+ import { testGit } from "./git.js";
9
+ import { testProvider } from "./provider.js";
10
+
11
+ const __filename =
12
+ fileURLToPath(import.meta.url);
13
+
14
+ const __dirname =
15
+ path.dirname(__filename);
16
+
17
+ const envPath =
18
+ path.resolve(
19
+ __dirname,
20
+ "../../../../.env"
21
+ );
22
+
23
+ console.log(
24
+ "Loading .env from:",
25
+ envPath
26
+ );
27
+
28
+ const result = dotenv.config({
29
+ path: envPath,
30
+ });
31
+
32
+ if (result.error) {
33
+ console.error(result.error);
34
+ process.exit(1);
35
+ }
36
+
37
+ const config = loadConfig();
38
+
39
+ console.log(
40
+ "Environment loaded successfully."
41
+ );
42
+
43
+ console.log(
44
+ "cwd:",
45
+ process.cwd()
46
+ );
47
+
48
+ console.log(
49
+ "apiKey:",
50
+ config.apiKey
51
+ ? "[present]"
52
+ : "[missing]"
53
+ );
54
+
55
+ console.log("models:");
56
+
57
+ for (
58
+ const [role, model] of
59
+ Object.entries(config.models)
60
+ ) {
61
+ console.log(
62
+ ` ${role}: ${model}`
63
+ );
64
+ }
65
+
66
+ await testScanner();
67
+ await testGit();
68
+ await testProvider();
@@ -0,0 +1,48 @@
1
+ import dotenv from "dotenv";
2
+
3
+ dotenv.config();
4
+
5
+ import {
6
+ createOpenRouter,
7
+ } from "../../../../packages/providers/index.js";
8
+
9
+ import {
10
+ loadConfig,
11
+ } from "../../../../packages/config/index.js";
12
+
13
+ export async function testProvider() {
14
+ console.log("\n===== Provider =====");
15
+
16
+ const config = loadConfig();
17
+
18
+ const provider =
19
+ createOpenRouter(config);
20
+
21
+ const model =
22
+ config.models.fast;
23
+
24
+ console.log(
25
+ "model:",
26
+ model
27
+ );
28
+
29
+ const response =
30
+ await provider.chat({
31
+ model,
32
+
33
+ messages: [
34
+ {
35
+ role: "user",
36
+ content:
37
+ "Reply with exactly: CodeForge Provider OK",
38
+ },
39
+ ],
40
+ });
41
+
42
+ console.dir(
43
+ response,
44
+ {
45
+ depth: null,
46
+ }
47
+ );
48
+ }
@@ -0,0 +1,14 @@
1
+ import {
2
+ findWorkspaceRoot,
3
+ scanProject,
4
+ } from "../../../../packages/scanner/index.js";
5
+
6
+ export async function testScanner() {
7
+ console.log("\n===== Scanner =====");
8
+
9
+ const root = await findWorkspaceRoot(process.cwd());
10
+
11
+ const project = await scanProject(root);
12
+
13
+ console.dir(project, { depth: null });
14
+ }
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+
3
+ import packageJson from "../../../package.json" with { type: "json" };
4
+ import { bootstrap } from "./bootstrap.js";
5
+
6
+ const VERSION = packageJson.version;
7
+
8
+ const args = process.argv.slice(2);
9
+
10
+ if (args.includes("--version") || args.includes("-v")) {
11
+ console.log(`CodeForge AI v${VERSION}`);
12
+ process.exit(0);
13
+ }
14
+
15
+ if (args.includes("--help") || args.includes("-h")) {
16
+ console.log(`
17
+ CodeForge AI v${VERSION}
18
+ Terminal-native AI Software Engineering Agent
19
+
20
+ Usage:
21
+ codeforge Start CodeForge
22
+ codeforge --help Show this help
23
+ codeforge --version Show version
24
+
25
+ Environment:
26
+ OPENROUTER_API_KEY OpenRouter API key
27
+ `);
28
+ process.exit(0);
29
+ }
30
+
31
+ bootstrap();
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "../apps/cli/src/index.js";
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@oisheek_c/codeforge",
3
+ "version": "1.0.1",
4
+ "description": "Terminal-native AI software engineering agent",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "files": [
8
+ "bin",
9
+ "apps/cli/src",
10
+ "apps/cli/bin",
11
+ "packages/agent/*.js",
12
+ "packages/config/*.js",
13
+ "packages/core/*.js",
14
+ "packages/git/*.js",
15
+ "packages/memory/*.js",
16
+ "packages/prompts/*.js",
17
+ "packages/providers/*.js",
18
+ "packages/reasoning/*.js",
19
+ "packages/retrieval/*.js",
20
+ "packages/retrieval/parser/*.js",
21
+ "packages/retrieval/parser/extractors/*.js",
22
+ "packages/retrieval/parser/languages/*.js",
23
+ "packages/retrieval/parser/queries/*.js",
24
+ "packages/scanner/*.js",
25
+ "packages/terminal/*.js",
26
+ "packages/tools/*.js",
27
+ "packages/utils/*.js",
28
+ "LICENSE",
29
+ "README.md"
30
+ ],
31
+ "engines": {
32
+ "node": "\u003e=22.13.0"
33
+ },
34
+ "packageManager": "pnpm@11.17.0",
35
+ "scripts": {
36
+ "dev": "pnpm --filter @codeforge/cli dev",
37
+ "start": "node apps/cli/src/index.js",
38
+ "test": "node --test"
39
+ },
40
+ "dependencies": {
41
+ "@openrouter/sdk": "^1.1.14",
42
+ "chalk": "^6.0.0",
43
+ "commander": "^15.0.0",
44
+ "dotenv": "^17.4.2",
45
+ "openai": "^6.49.0",
46
+ "ora": "^9.4.1",
47
+ "simple-git": "^3.36.0",
48
+ "tree-sitter": "^0.25.1",
49
+ "tree-sitter-c": "^0.24.1",
50
+ "tree-sitter-c-sharp": "^0.23.5",
51
+ "tree-sitter-cpp": "^0.23.4",
52
+ "tree-sitter-go": "^0.25.0",
53
+ "tree-sitter-java": "^0.23.5",
54
+ "tree-sitter-javascript": "^0.25.0",
55
+ "tree-sitter-php": "^0.24.2",
56
+ "tree-sitter-python": "^0.25.0",
57
+ "tree-sitter-ruby": "^0.23.1",
58
+ "tree-sitter-rust": "^0.24.0",
59
+ "tree-sitter-swift": "^0.7.1",
60
+ "tree-sitter-typescript": "^0.23.2",
61
+ "zod": "^4.4.3"
62
+ }
63
+ }