editcodewithai 0.1.0 → 1.1.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.
@@ -1,158 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.challenges = void 0;
4
- // Challenges definition. Each has multiple files (some with TODO).
5
- // "index.mjs" includes the test code that calls process.exit(1) if it fails.
6
- exports.challenges = [
7
- {
8
- name: "add",
9
- prompt: "Implement the 'add' function to correctly add two numbers (a+b) and pass the test in index.mjs.",
10
- files: {
11
- file1: {
12
- name: "index.mjs",
13
- text: `
14
- import { add } from "./functions.mjs";
15
-
16
- // A simple test:
17
- const result = add(3, 4);
18
- if (result !== 7) {
19
- console.error("Test failed: expected 7, got", result);
20
- process.exit(1);
21
- }
22
- console.log("Add test passed");
23
- process.exit(0);
24
- `,
25
- },
26
- file2: {
27
- name: "functions.mjs",
28
- text: `
29
- // TODO: Implement the add function
30
- export function add(a, b) {
31
- // TODO
32
- }
33
- `,
34
- },
35
- },
36
- },
37
- {
38
- name: "multiply",
39
- prompt: "Implement the 'multiply' function to correctly multiply two numbers and pass the unit test in index.mjs.",
40
- files: {
41
- file1: {
42
- name: "index.mjs",
43
- text: `
44
- import { multiply } from "./functions.mjs";
45
-
46
- const result = multiply(6, 7);
47
- if (result !== 42) {
48
- console.error("Test failed: expected 42, got", result);
49
- process.exit(1);
50
- }
51
- console.log("Multiply test passed");
52
- process.exit(0);
53
- `,
54
- },
55
- file2: {
56
- name: "functions.mjs",
57
- text: `
58
- // TODO: Implement the multiply function
59
- export function multiply(a, b) {
60
- // TODO
61
- }
62
- `,
63
- },
64
- },
65
- },
66
- {
67
- name: "square",
68
- prompt: "Implement the 'square' function that returns x*x.",
69
- files: {
70
- file1: {
71
- name: "index.mjs",
72
- text: `
73
- import { square } from "./functions.mjs";
74
-
75
- const input = 5;
76
- const result = square(input);
77
- if (result !== 25) {
78
- console.error("Test failed: expected 25, got", result);
79
- process.exit(1);
80
- }
81
- console.log("Square test passed");
82
- process.exit(0);
83
- `,
84
- },
85
- file2: {
86
- name: "functions.mjs",
87
- text: `
88
- // TODO: Implement the square function
89
- export function square(x) {
90
- // TODO
91
- }
92
- `,
93
- },
94
- },
95
- },
96
- {
97
- name: "toUpperCase",
98
- prompt: "Implement the toUpperCase function that returns the given string in uppercase.",
99
- files: {
100
- file1: {
101
- name: "index.mjs",
102
- text: `
103
- import { toUpperCase } from "./functions.mjs";
104
-
105
- const input = "hello";
106
- const result = toUpperCase(input);
107
- if (result !== "HELLO") {
108
- console.error("Test failed: expected 'HELLO', got", result);
109
- process.exit(1);
110
- }
111
- console.log("toUpperCase test passed");
112
- process.exit(0);
113
- `,
114
- },
115
- file2: {
116
- name: "functions.mjs",
117
- text: `
118
- // TODO: Implement the toUpperCase function
119
- export function toUpperCase(str) {
120
- // TODO
121
- }
122
- `,
123
- },
124
- },
125
- },
126
- {
127
- name: "reverseString",
128
- prompt: "Implement the reverseString function that reverses the given string.",
129
- files: {
130
- file1: {
131
- name: "index.mjs",
132
- text: `
133
- import { reverseString } from "./functions.mjs";
134
-
135
- const input = "OpenAI";
136
- const expected = "IAnepO";
137
-
138
- const result = reverseString(input);
139
- if (result !== expected) {
140
- console.error("Test failed: expected", expected, "but got", result);
141
- process.exit(1);
142
- }
143
- console.log("reverseString test passed");
144
- process.exit(0);
145
- `,
146
- },
147
- file2: {
148
- name: "functions.mjs",
149
- text: `
150
- // TODO: Implement the reverseString function
151
- export function reverseString(str) {
152
- // TODO
153
- }
154
- `,
155
- },
156
- },
157
- },
158
- ];
@@ -1,15 +0,0 @@
1
- import { VizFiles } from "@vizhub/viz-types";
2
- import { ChallengeResult } from "./types";
3
- /**
4
- * Writes the files for a given challenge into a folder named after challenge.name + model
5
- * e.g. "benchmarks/challenges/add/gpt4" to keep them separate per model.
6
- */
7
- export declare function writeChallengeFiles(challengeName: string, model: string, changedFiles: VizFiles, llmResponse?: string): string;
8
- /**
9
- * Writes results to a CSV file
10
- */
11
- export declare function writeResultsToCsv(results: ChallengeResult[], filePath?: string): string;
12
- /**
13
- * Ensures a cache directory exists
14
- */
15
- export declare function ensureCacheDir(cacheDirBase: string): void;
@@ -1,55 +0,0 @@
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.writeChallengeFiles = writeChallengeFiles;
7
- exports.writeResultsToCsv = writeResultsToCsv;
8
- exports.ensureCacheDir = ensureCacheDir;
9
- const fs_1 = __importDefault(require("fs"));
10
- const path_1 = __importDefault(require("path"));
11
- /**
12
- * Writes the files for a given challenge into a folder named after challenge.name + model
13
- * e.g. "benchmarks/challenges/add/gpt4" to keep them separate per model.
14
- */
15
- function writeChallengeFiles(challengeName, model, changedFiles, llmResponse) {
16
- const challengeDir = path_1.default.join("benchmarks", "challenges", challengeName, model);
17
- if (!fs_1.default.existsSync(challengeDir)) {
18
- fs_1.default.mkdirSync(challengeDir, { recursive: true });
19
- }
20
- Object.keys(changedFiles).forEach((fileKey) => {
21
- const { name, text } = changedFiles[fileKey];
22
- const filePath = path_1.default.join(challengeDir, name);
23
- fs_1.default.writeFileSync(filePath, text, "utf-8");
24
- });
25
- // Write the LLM response to a file if provided
26
- if (llmResponse) {
27
- const responsePath = path_1.default.join(challengeDir, "llmResponse.md");
28
- fs_1.default.writeFileSync(responsePath, llmResponse, "utf-8");
29
- }
30
- return challengeDir;
31
- }
32
- /**
33
- * Writes results to a CSV file
34
- */
35
- function writeResultsToCsv(results, filePath = "benchmarks/results.csv") {
36
- let csv = "challenge,model,passFail\n";
37
- for (const r of results) {
38
- csv += `${r.challenge},${r.model},${r.passFail}\n`;
39
- }
40
- // Ensure benchmarks directory exists
41
- const dir = path_1.default.dirname(filePath);
42
- if (!fs_1.default.existsSync(dir)) {
43
- fs_1.default.mkdirSync(dir, { recursive: true });
44
- }
45
- fs_1.default.writeFileSync(filePath, csv, "utf-8");
46
- return csv;
47
- }
48
- /**
49
- * Ensures a cache directory exists
50
- */
51
- function ensureCacheDir(cacheDirBase) {
52
- if (!fs_1.default.existsSync(cacheDirBase)) {
53
- fs_1.default.mkdirSync(cacheDirBase, { recursive: true });
54
- }
55
- }
@@ -1,5 +0,0 @@
1
- export { runAllChallenges } from "./benchmarkRunner";
2
- export { challenges } from "./challenges";
3
- export { createOpenRouterLlmFunction } from "./llm";
4
- export { runNodeTest } from "./runner";
5
- export { writeChallengeFiles, writeResultsToCsv } from "./fileUtils";
@@ -1,44 +0,0 @@
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.writeResultsToCsv = exports.writeChallengeFiles = exports.runNodeTest = exports.createOpenRouterLlmFunction = exports.challenges = exports.runAllChallenges = void 0;
7
- /**********************************************************************
8
- * benchmark.ts
9
- * --------------------------------------------------------------------
10
- * Requires environment variables to be set in a .env file
11
- * --------------------------------------------------------------------
12
- * Defines 5 challenges, each with index.js (ES module) that performs
13
- * a simple unit test. The code calls process.exit(0) on success or
14
- * process.exit(1) on failure.
15
- *
16
- * Runs all challenges on 5 different models:
17
- * ["gpt3", "gpt4", "gpt5", "deepseek", "qwen32"]
18
- *
19
- * Writes final results to "results.csv" with columns:
20
- * challenge, model, passFail, exitCode
21
- **********************************************************************/
22
- const dotenv_1 = __importDefault(require("dotenv"));
23
- const benchmarkRunner_1 = require("./benchmarkRunner");
24
- // Load environment variables from .env file
25
- dotenv_1.default.config();
26
- // Run if invoked directly
27
- if (require.main === module) {
28
- (0, benchmarkRunner_1.runAllChallenges)().catch((error) => {
29
- console.error("Error running challenges:", error);
30
- process.exit(1);
31
- });
32
- }
33
- // Re-export for programmatic usage
34
- var benchmarkRunner_2 = require("./benchmarkRunner");
35
- Object.defineProperty(exports, "runAllChallenges", { enumerable: true, get: function () { return benchmarkRunner_2.runAllChallenges; } });
36
- var challenges_1 = require("./challenges");
37
- Object.defineProperty(exports, "challenges", { enumerable: true, get: function () { return challenges_1.challenges; } });
38
- var llm_1 = require("./llm");
39
- Object.defineProperty(exports, "createOpenRouterLlmFunction", { enumerable: true, get: function () { return llm_1.createOpenRouterLlmFunction; } });
40
- var runner_1 = require("./runner");
41
- Object.defineProperty(exports, "runNodeTest", { enumerable: true, get: function () { return runner_1.runNodeTest; } });
42
- var fileUtils_1 = require("./fileUtils");
43
- Object.defineProperty(exports, "writeChallengeFiles", { enumerable: true, get: function () { return fileUtils_1.writeChallengeFiles; } });
44
- Object.defineProperty(exports, "writeResultsToCsv", { enumerable: true, get: function () { return fileUtils_1.writeResultsToCsv; } });
@@ -1,10 +0,0 @@
1
- import { LlmFunction } from "../types";
2
- import { LocalFileCache } from "langchain/cache/file_system";
3
- /**
4
- * Creates an LLM function that connects to OpenRouter
5
- * @param model The model identifier to use
6
- * @param apiKey OpenRouter API key
7
- * @param cache Optional local file cache to avoid duplicate requests
8
- * @returns A function that can be used with performAiEdit
9
- */
10
- export declare function createOpenRouterLlmFunction(model: string, apiKey: string, cache?: LocalFileCache): LlmFunction;
@@ -1,29 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createOpenRouterLlmFunction = createOpenRouterLlmFunction;
4
- const openai_1 = require("@langchain/openai");
5
- const output_parsers_1 = require("@langchain/core/output_parsers");
6
- /**
7
- * Creates an LLM function that connects to OpenRouter
8
- * @param model The model identifier to use
9
- * @param apiKey OpenRouter API key
10
- * @param cache Optional local file cache to avoid duplicate requests
11
- * @returns A function that can be used with performAiEdit
12
- */
13
- function createOpenRouterLlmFunction(model, apiKey, cache) {
14
- return async (prompt) => {
15
- // Create OpenAI chat model with OpenRouter configuration
16
- const chatModel = new openai_1.ChatOpenAI({
17
- modelName: model,
18
- configuration: { apiKey, baseURL: "https://openrouter.ai/api/v1" },
19
- streaming: false,
20
- cache,
21
- });
22
- // Invoke the model
23
- const result = await chatModel.invoke(prompt);
24
- // Parse to string
25
- const parser = new output_parsers_1.StringOutputParser();
26
- const resultString = await parser.invoke(result);
27
- return { content: resultString, generationId: result.lc_kwargs.id };
28
- };
29
- }
@@ -1 +0,0 @@
1
- export declare const models: string[];
@@ -1,21 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.models = void 0;
4
- exports.models = [
5
- "anthropic/claude-3.7-sonnet",
6
- "anthropic/claude-3.7-sonnet:thinking",
7
- "google/gemini-2.0-flash-001",
8
- "anthropic/claude-3.5-sonnet",
9
- "deepseek/deepseek-r1",
10
- "openai/o3-mini-high",
11
- "openai/o3-mini",
12
- "deepseek/deepseek-chat",
13
- "qwen/qwen-2.5-72b-instruct",
14
- "qwen/qwq-32b",
15
- "anthropic/claude-3.5-haiku",
16
- "qwen/qwen-2.5-7b-instruct",
17
- "amazon/nova-micro-v1",
18
- "meta-llama/llama-3.1-8b-instruct",
19
- "meta-llama/llama-3.2-3b-instruct",
20
- "meta-llama/llama-3.2-1b-instruct",
21
- ];
@@ -1,4 +0,0 @@
1
- /**
2
- * Runs "index.mjs" for a given challenge directory with Node and returns exit code.
3
- */
4
- export declare function runNodeTest(challengeDir: string): number;
@@ -1,35 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runNodeTest = runNodeTest;
4
- const child_process_1 = require("child_process");
5
- /**
6
- * Runs "index.mjs" for a given challenge directory with Node and returns exit code.
7
- */
8
- function runNodeTest(challengeDir) {
9
- const result = runNodeProcess(challengeDir);
10
- logTestResult(challengeDir, result);
11
- return result.status ?? 1; // If status is null, consider that a failure
12
- }
13
- /**
14
- * Executes the Node.js process for a test
15
- */
16
- function runNodeProcess(challengeDir) {
17
- const child = (0, child_process_1.spawnSync)("node", ["index.mjs"], {
18
- cwd: challengeDir,
19
- encoding: "utf-8",
20
- });
21
- return {
22
- status: child.status,
23
- stdout: child.stdout,
24
- stderr: child.stderr
25
- };
26
- }
27
- /**
28
- * Logs the test result to the console
29
- */
30
- function logTestResult(challengeDir, result) {
31
- console.log(`--- Running test in ${challengeDir} ---`);
32
- console.log("stdout:\n", result.stdout.trim());
33
- console.log("stderr:\n", result.stderr.trim());
34
- console.log("exit code:", result.status, "\n");
35
- }
@@ -1,16 +0,0 @@
1
- import { VizFiles } from "@vizhub/viz-types";
2
- export interface Challenge {
3
- name: string;
4
- prompt: string;
5
- files: VizFiles;
6
- }
7
- export interface ChallengeResult {
8
- challenge: string;
9
- model: string;
10
- passFail: "pass" | "fail" | "error";
11
- }
12
- export interface TestRunResult {
13
- status: number | null;
14
- stdout: string;
15
- stderr: string;
16
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
package/dist/cli.d.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
package/dist/cli.js DELETED
@@ -1,157 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || (function () {
20
- var ownKeys = function(o) {
21
- ownKeys = Object.getOwnPropertyNames || function (o) {
22
- var ar = [];
23
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
- return ar;
25
- };
26
- return ownKeys(o);
27
- };
28
- return function (mod) {
29
- if (mod && mod.__esModule) return mod;
30
- var result = {};
31
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
- __setModuleDefault(result, mod);
33
- return result;
34
- };
35
- })();
36
- var __importDefault = (this && this.__importDefault) || function (mod) {
37
- return (mod && mod.__esModule) ? mod : { "default": mod };
38
- };
39
- Object.defineProperty(exports, "__esModule", { value: true });
40
- const commander_1 = require("commander");
41
- const path = __importStar(require("path"));
42
- const readline = __importStar(require("readline"));
43
- const index_1 = require("./index");
44
- const llm_1 = require("./benchmarks/llm");
45
- const computeInitialDocument_1 = require("./computeInitialDocument");
46
- const dotenv_1 = __importDefault(require("dotenv"));
47
- const fs = __importStar(require("fs/promises"));
48
- // Load environment variables
49
- dotenv_1.default.config();
50
- const program = new commander_1.Command();
51
- program
52
- .name("editcode")
53
- .description("Edit code files using AI")
54
- .option("-p, --prompt <prompt>", "The instruction for editing the code")
55
- .option("-d, --dir <directory>", "Directory to process", process.cwd())
56
- .option("--dry-run", "Show changes without writing them", false)
57
- .option("--model <model>", "OpenRouter model to use", "anthropic/claude-3.7-sonnet")
58
- .action(async (options) => {
59
- try {
60
- // Get prompt from user if not provided as argument
61
- if (!options.prompt) {
62
- const rl = readline.createInterface({
63
- input: process.stdin,
64
- output: process.stdout
65
- });
66
- options.prompt = await new Promise((resolve) => {
67
- rl.question("> ", (answer) => {
68
- rl.close();
69
- resolve(answer);
70
- });
71
- });
72
- }
73
- if (!options.prompt.trim()) {
74
- console.error("Error: Prompt cannot be empty");
75
- process.exit(1);
76
- }
77
- // Debug: Log environment
78
- console.log('Environment variables:', {
79
- OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY ? '[PRESENT]' : '[MISSING]',
80
- NODE_ENV: process.env.NODE_ENV,
81
- PATH: process.env.PATH?.substring(0, 50) + '...'
82
- });
83
- // Validate API key
84
- const apiKey = process.env.OPENROUTER_API_KEY;
85
- if (!apiKey) {
86
- console.error("Error: OPENROUTER_API_KEY environment variable is required");
87
- process.exit(1);
88
- }
89
- // Get absolute path
90
- const fullPath = path.resolve(options.dir);
91
- console.log(`Processing directory: ${fullPath}`);
92
- // Use computeInitialDocument to get files (respects .ignore files)
93
- const initialDocument = (0, computeInitialDocument_1.computeInitialDocument)({ fullPath });
94
- // Convert to VizFiles format
95
- const vizFiles = {};
96
- Object.entries(initialDocument.files).forEach(([id, file]) => {
97
- if (file.text !== null) {
98
- // Skip directories
99
- vizFiles[id] = {
100
- name: path.relative(process.cwd(), path.join(fullPath, file.name)),
101
- text: file.text,
102
- };
103
- }
104
- });
105
- const fileCount = Object.keys(vizFiles).length;
106
- if (fileCount === 0) {
107
- console.error("No files found to process");
108
- process.exit(1);
109
- }
110
- console.log(`Found ${fileCount} files to process`);
111
- // Create LLM function
112
- const llmFunction = (0, llm_1.createOpenRouterLlmFunction)(options.model, apiKey);
113
- // Perform the edit
114
- console.log("\nRequesting changes from AI...");
115
- const result = await (0, index_1.performAiEdit)({
116
- prompt: options.prompt,
117
- files: vizFiles,
118
- llmFunction,
119
- apiKey,
120
- });
121
- // Show changes
122
- console.log("\nProposed changes:");
123
- for (const [id, file] of Object.entries(result.changedFiles)) {
124
- const original = vizFiles[id];
125
- if (!original) {
126
- console.log(`\nNew file: ${file.name}`);
127
- console.log(file.text);
128
- }
129
- else if (original.text !== file.text) {
130
- console.log(`\nModified: ${file.name}`);
131
- console.log(file.text);
132
- }
133
- }
134
- // Write changes if not dry run
135
- if (!options.dryRun) {
136
- console.log("\nWriting changes...");
137
- for (const [_, file] of Object.entries(result.changedFiles)) {
138
- const fullPath = path.resolve(file.name);
139
- await fs.mkdir(path.dirname(fullPath), { recursive: true });
140
- await fs.writeFile(fullPath, file.text);
141
- console.log(`Updated ${fullPath}`);
142
- }
143
- }
144
- // Show metadata
145
- console.log("\nMetadata:");
146
- console.log(`Model: ${options.model}`);
147
- console.log(`Provider: ${result.provider}`);
148
- console.log(`Cost: ${result.upstreamCostCents / 100} USD`);
149
- console.log(`Input tokens: ${result.inputTokens}`);
150
- console.log(`Output tokens: ${result.outputTokens}`);
151
- }
152
- catch (error) {
153
- console.error("Error:", error);
154
- process.exit(1);
155
- }
156
- });
157
- program.parse();
@@ -1,13 +0,0 @@
1
- interface InitialDocument {
2
- files: {
3
- [key: string]: {
4
- text: string | null;
5
- name: string;
6
- };
7
- };
8
- }
9
- export declare const isDirectory: (path: string) => boolean;
10
- export declare const computeInitialDocument: ({ fullPath }: {
11
- fullPath: string;
12
- }) => InitialDocument;
13
- export {};