Skip to content

Commit f02d248

Browse files
committed
cli version of cline
1 parent 185476a commit f02d248

File tree

11 files changed

+783
-82
lines changed

11 files changed

+783
-82
lines changed

package-lock.json

Lines changed: 4 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@
215215
"@typescript-eslint/parser": "^7.11.0",
216216
"@vscode/test-cli": "^0.0.9",
217217
"@vscode/test-electron": "^2.4.0",
218-
"dotenv": "^16.4.7",
219218
"esbuild": "^0.24.0",
220219
"eslint": "^8.57.0",
221220
"husky": "^9.1.7",
@@ -238,6 +237,7 @@
238237
"@types/turndown": "^5.0.5",
239238
"@vscode/codicons": "^0.0.36",
240239
"axios": "^1.7.4",
240+
"chalk": "^4.1.2",
241241
"cheerio": "^1.0.0",
242242
"chokidar": "^4.0.1",
243243
"clone-deep": "^4.0.1",

src/cli.js

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
#!/usr/bin/env node
2+
"use strict";
3+
var __extends = (this && this.__extends) || (function () {
4+
var extendStatics = function (d, b) {
5+
extendStatics = Object.setPrototypeOf ||
6+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
7+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
8+
return extendStatics(d, b);
9+
};
10+
return function (d, b) {
11+
if (typeof b !== "function" && b !== null)
12+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
13+
extendStatics(d, b);
14+
function __() { this.constructor = d; }
15+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
16+
};
17+
})();
18+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
19+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
20+
return new (P || (P = Promise))(function (resolve, reject) {
21+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
22+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
23+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
24+
step((generator = generator.apply(thisArg, _arguments || [])).next());
25+
});
26+
};
27+
var __generator = (this && this.__generator) || function (thisArg, body) {
28+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
29+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
30+
function verb(n) { return function (v) { return step([n, v]); }; }
31+
function step(op) {
32+
if (f) throw new TypeError("Generator is already executing.");
33+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
34+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
35+
if (y = 0, t) op = [op[0] & 2, t.value];
36+
switch (op[0]) {
37+
case 0: case 1: t = op; break;
38+
case 4: _.label++; return { value: op[1], done: false };
39+
case 5: _.label++; y = op[1]; op = [0]; continue;
40+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
41+
default:
42+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
43+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
44+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
45+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
46+
if (t[2]) _.ops.pop();
47+
_.trys.pop(); continue;
48+
}
49+
op = body.call(thisArg, _);
50+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
51+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
52+
}
53+
};
54+
var __asyncValues = (this && this.__asyncValues) || function (o) {
55+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
56+
var m = o[Symbol.asyncIterator], i;
57+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
58+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
59+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
60+
};
61+
Object.defineProperty(exports, "__esModule", { value: true });
62+
var dotenv = require("dotenv");
63+
var child_process_1 = require("child_process");
64+
var lib_1 = require("./lib");
65+
dotenv.config();
66+
var CliToolExecutor = /** @class */ (function (_super) {
67+
__extends(CliToolExecutor, _super);
68+
function CliToolExecutor() {
69+
return _super !== null && _super.apply(this, arguments) || this;
70+
}
71+
CliToolExecutor.prototype.executeCommand = function (command) {
72+
return __awaiter(this, void 0, void 0, function () {
73+
var _this = this;
74+
return __generator(this, function (_a) {
75+
return [2 /*return*/, new Promise(function (resolve) {
76+
var process = (0, child_process_1.spawn)(command, [], {
77+
shell: true,
78+
cwd: _this.getCurrentWorkingDirectory()
79+
});
80+
var output = '';
81+
var error = '';
82+
process.stdout.on('data', function (data) {
83+
output += data.toString();
84+
console.log(data.toString());
85+
});
86+
process.stderr.on('data', function (data) {
87+
error += data.toString();
88+
console.error(data.toString());
89+
});
90+
process.on('close', function (code) {
91+
if (code !== 0) {
92+
resolve([true, 'Command failed with code ' + code + '\n' + error]);
93+
}
94+
else {
95+
resolve([false, output]);
96+
}
97+
});
98+
})];
99+
});
100+
});
101+
};
102+
CliToolExecutor.prototype.getCurrentWorkingDirectory = function () {
103+
return process.cwd();
104+
};
105+
return CliToolExecutor;
106+
}(lib_1.BaseToolExecutor));
107+
function main() {
108+
return __awaiter(this, void 0, void 0, function () {
109+
var args, task, apiKey, apiConfiguration, cwd, toolExecutor, contextProvider, messageParser, apiClient, envDetails, toolDocs, systemPromptParts, systemPrompt, history_1, _a, _b, _c, chunk, toolUse, _d, error, result, e_1_1, error_1;
110+
var _e, e_1, _f, _g;
111+
return __generator(this, function (_h) {
112+
switch (_h.label) {
113+
case 0:
114+
args = process.argv.slice(2);
115+
task = args[0];
116+
if (!task) {
117+
console.error('Usage: cline "My Task" [--tools]');
118+
process.exit(1);
119+
}
120+
apiKey = process.env.OPENROUTER_API_KEY;
121+
if (!apiKey) {
122+
console.error('Error: OPENROUTER_API_KEY environment variable is required');
123+
process.exit(1);
124+
}
125+
apiConfiguration = {
126+
apiKey: apiKey,
127+
apiModelId: 'anthropic/claude-3-sonnet-20240229',
128+
apiProvider: 'openrouter',
129+
};
130+
cwd = process.cwd();
131+
toolExecutor = new CliToolExecutor(cwd);
132+
contextProvider = new lib_1.CliContextProvider(cwd);
133+
messageParser = new lib_1.MessageParser(lib_1.AVAILABLE_TOOLS);
134+
apiClient = (0, lib_1.createApiClient)(apiConfiguration);
135+
_h.label = 1;
136+
case 1:
137+
_h.trys.push([1, 19, , 20]);
138+
return [4 /*yield*/, contextProvider.getEnvironmentDetails(true)];
139+
case 2:
140+
envDetails = _h.sent();
141+
toolDocs = lib_1.AVAILABLE_TOOLS.map(function (tool) {
142+
var params = Object.entries(tool.parameters)
143+
.map(function (_a) {
144+
var name = _a[0], param = _a[1];
145+
return '- ' + name + ': (' + (param.required ? 'required' : 'optional') + ') ' + param.description;
146+
})
147+
.join('\n');
148+
return '## ' + tool.name + '\nDescription: ' + tool.description + '\nParameters:\n' + params;
149+
}).join('\n\n');
150+
systemPromptParts = [
151+
'You are Cline, a highly skilled software engineer.',
152+
'',
153+
'TOOLS',
154+
'',
155+
'You have access to the following tools that must be used with XML tags:',
156+
'',
157+
toolDocs,
158+
'',
159+
'RULES',
160+
'',
161+
'1. Use one tool at a time',
162+
'2. Wait for tool execution results before proceeding',
163+
'3. Handle errors appropriately',
164+
'4. Document your changes',
165+
'',
166+
'TASK',
167+
'',
168+
task
169+
];
170+
systemPrompt = systemPromptParts.join('\n');
171+
history_1 = [
172+
{ role: 'user', content: "<task>".concat(task, "</task><environment_details>").concat(envDetails, "</environment_details>") }
173+
];
174+
_h.label = 3;
175+
case 3:
176+
_h.trys.push([3, 12, 13, 18]);
177+
_a = true, _b = __asyncValues(apiClient.createMessage(systemPrompt, history_1));
178+
_h.label = 4;
179+
case 4: return [4 /*yield*/, _b.next()];
180+
case 5:
181+
if (!(_c = _h.sent(), _e = _c.done, !_e)) return [3 /*break*/, 11];
182+
_g = _c.value;
183+
_a = false;
184+
chunk = _g;
185+
if (!(chunk.type === 'text' && chunk.text)) return [3 /*break*/, 9];
186+
toolUse = messageParser.parseMessage(chunk.text);
187+
if (!toolUse) return [3 /*break*/, 7];
188+
return [4 /*yield*/, toolExecutor.executeCommand(toolUse.command)];
189+
case 6:
190+
_d = _h.sent(), error = _d[0], result = _d[1];
191+
history_1.push({ role: 'assistant', content: chunk.text }, { role: 'user', content: "[".concat(toolUse.name, "] Result: ").concat(result) });
192+
return [3 /*break*/, 8];
193+
case 7:
194+
console.log(chunk.text);
195+
_h.label = 8;
196+
case 8: return [3 /*break*/, 10];
197+
case 9:
198+
if (chunk.type === 'usage') {
199+
// Log usage metrics if needed
200+
// console.log('Usage:', chunk);
201+
}
202+
_h.label = 10;
203+
case 10:
204+
_a = true;
205+
return [3 /*break*/, 4];
206+
case 11: return [3 /*break*/, 18];
207+
case 12:
208+
e_1_1 = _h.sent();
209+
e_1 = { error: e_1_1 };
210+
return [3 /*break*/, 18];
211+
case 13:
212+
_h.trys.push([13, , 16, 17]);
213+
if (!(!_a && !_e && (_f = _b.return))) return [3 /*break*/, 15];
214+
return [4 /*yield*/, _f.call(_b)];
215+
case 14:
216+
_h.sent();
217+
_h.label = 15;
218+
case 15: return [3 /*break*/, 17];
219+
case 16:
220+
if (e_1) throw e_1.error;
221+
return [7 /*endfinally*/];
222+
case 17: return [7 /*endfinally*/];
223+
case 18: return [3 /*break*/, 20];
224+
case 19:
225+
error_1 = _h.sent();
226+
console.error('Error:', error_1.message);
227+
process.exit(1);
228+
return [3 /*break*/, 20];
229+
case 20: return [2 /*return*/];
230+
}
231+
});
232+
});
233+
}
234+
main().catch(function (error) {
235+
console.error('Fatal error:', error);
236+
process.exit(1);
237+
});

0 commit comments

Comments
 (0)