codeply-cli 0.3.0 → 0.3.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.
- package/bin/codeply.js +2 -6
- package/lib/github-agent.mjs +24 -7
- package/package.json +1 -1
package/bin/codeply.js
CHANGED
|
@@ -509,13 +509,9 @@ githubCmd
|
|
|
509
509
|
let event;
|
|
510
510
|
try { event = JSON.parse(fs.readFileSync(cfg.GITHUB_EVENT_PATH, 'utf8')); } catch (e) { console.error(c.red(`Could not read the event: ${e.message}`)); process.exitCode = 1; return; }
|
|
511
511
|
const r = g.routeFromEnv(cfg);
|
|
512
|
-
|
|
513
|
-
console.error(c.red(r.error));
|
|
514
|
-
process.exitCode = 1;
|
|
515
|
-
return;
|
|
516
|
-
}
|
|
512
|
+
// A setup error is still reported on the issue, so the person who asked isn't left waiting.
|
|
517
513
|
const out = await g.runGithubAgent({
|
|
518
|
-
eventName: cfg.GITHUB_EVENT_NAME, event, token, route: r.route, env: cfg, cwd: process.cwd(),
|
|
514
|
+
eventName: cfg.GITHUB_EVENT_NAME, event, token, route: r.route, setupError: r.error, env: cfg, cwd: process.cwd(),
|
|
519
515
|
maxSteps: Math.max(1, Number(opts.maxSteps) || 40), log: (m) => console.log(m),
|
|
520
516
|
});
|
|
521
517
|
console.log(`${out.status}${out.url ? ` ${out.url}` : ''}`);
|
package/lib/github-agent.mjs
CHANGED
|
@@ -31,6 +31,7 @@ const DEFAULT_ALLOWED = ['OWNER', 'MEMBER', 'COLLABORATOR'];
|
|
|
31
31
|
const MAX_COMMENT = 60000;
|
|
32
32
|
|
|
33
33
|
export const PROVIDERS = {
|
|
34
|
+
ollama: { baseUrl: 'https://ollama.com/v1', model: 'gemma4:31b' },
|
|
34
35
|
openai: { baseUrl: 'https://api.openai.com/v1', model: 'gpt-4o-mini' },
|
|
35
36
|
anthropic: { baseUrl: 'https://api.anthropic.com/v1', model: 'claude-sonnet-5' },
|
|
36
37
|
gemini: { baseUrl: 'https://generativelanguage.googleapis.com/v1beta/openai', model: 'gemini-3.7-flash' },
|
|
@@ -48,8 +49,10 @@ export function routeFromEnv(env) {
|
|
|
48
49
|
const model = env.CODEPLY_MODEL || (preset && preset.model);
|
|
49
50
|
if (!model) return { error: 'Set CODEPLY_MODEL.' };
|
|
50
51
|
const local = /^https?:\/\/(localhost|127\.0\.0\.1|\[::1\])/.test(baseUrl);
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
// Keys pasted on Windows often carry a BOM or a trailing newline, which fetch rejects in a header.
|
|
53
|
+
const apiKey = String(env.CODEPLY_API_KEY || '').replace(/[\s]/g, '');
|
|
54
|
+
if (!apiKey && !local) return { error: 'Set the CODEPLY_API_KEY secret (your own key for the model provider).' };
|
|
55
|
+
return { route: { custom: { id: 'github', name: model, kind: 'openai', baseUrl, model, apiKey } } };
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
/** What the event asks for, or why to skip it. */
|
|
@@ -142,7 +145,7 @@ function buildPrompt(ctx, repo, pr) {
|
|
|
142
145
|
* @returns {Promise<{status: 'skipped'|'answered'|'pushed'|'pr'|'failed', message?: string, url?: string}>}
|
|
143
146
|
*/
|
|
144
147
|
export async function runGithubAgent({
|
|
145
|
-
eventName, event, cwd = process.cwd(), token, route, env = process.env, maxSteps = 40,
|
|
148
|
+
eventName, event, cwd = process.cwd(), token, route, setupError = null, env = process.env, maxSteps = 40,
|
|
146
149
|
fetchImpl = fetch, log = () => {}, runAgentImpl = runAgent,
|
|
147
150
|
}) {
|
|
148
151
|
const allowed = env.CODEPLY_ALLOWED_ASSOCIATIONS ? env.CODEPLY_ALLOWED_ASSOCIATIONS.split(',').map((s) => s.trim().toUpperCase()).filter(Boolean) : DEFAULT_ALLOWED;
|
|
@@ -166,6 +169,11 @@ export async function runGithubAgent({
|
|
|
166
169
|
} catch (e) { log(`Could not post a comment: ${e.message}`); }
|
|
167
170
|
};
|
|
168
171
|
|
|
172
|
+
if (setupError) {
|
|
173
|
+
await say(`Craft can't start yet: ${setupError}`);
|
|
174
|
+
return { status: 'failed', message: setupError };
|
|
175
|
+
}
|
|
176
|
+
|
|
169
177
|
try {
|
|
170
178
|
if (ctx.commentId) await api('POST', `/repos/${repo}/${ctx.commentKind === 'review' ? 'pulls' : 'issues'}/comments/${ctx.commentId}/reactions`, { content: 'eyes' }).catch(() => {});
|
|
171
179
|
await say(`Working on it (${ctx.mode === 'Build' ? 'build' : ctx.mode.toLowerCase()} mode)...`);
|
|
@@ -227,10 +235,19 @@ export async function runGithubAgent({
|
|
|
227
235
|
await say(`${answer}\n\nPushed ${changed} changed file${changed === 1 ? '' : 's'} to \`${branch}\` (${sha}).`);
|
|
228
236
|
return { status: 'pushed', message: answer, url: `${serverUrl}/${repo}/commit/${sha}` };
|
|
229
237
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
238
|
+
let made;
|
|
239
|
+
try {
|
|
240
|
+
made = await api('POST', `/repos/${repo}/pulls`, {
|
|
241
|
+
title: ctx.title ? `Fix: ${ctx.title}`.slice(0, 120) : subject, head: branch, base,
|
|
242
|
+
body: `${answer}\n\nCloses #${ctx.number}\n\n<sub>Opened by Codeply Craft at @${ctx.author}'s request.</sub>`,
|
|
243
|
+
});
|
|
244
|
+
} catch (e) {
|
|
245
|
+
// New repos block Actions from opening PRs; the branch is pushed, so hand over a one-click link.
|
|
246
|
+
if (!/not permitted to create/i.test(e.message)) throw e;
|
|
247
|
+
const compare = `${serverUrl}/${repo}/compare/${base}...${encodeURIComponent(branch)}?expand=1`;
|
|
248
|
+
await say(`${answer}\n\nPushed ${changed} changed file${changed === 1 ? '' : 's'} to \`${branch}\` (${sha}). [Open the pull request](${compare}).\n\nTo let Craft open pull requests itself, turn on Settings > Actions > General > "Allow GitHub Actions to create and approve pull requests".`);
|
|
249
|
+
return { status: 'pushed', message: answer, url: compare };
|
|
250
|
+
}
|
|
234
251
|
await say(`${answer}\n\nOpened ${made.html_url} (${changed} changed file${changed === 1 ? '' : 's'}, ${steps} steps).`);
|
|
235
252
|
return { status: 'pr', message: answer, url: made.html_url };
|
|
236
253
|
} catch (e) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeply-cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Codeply from the terminal: an interactive AI coding agent, a local server (codeply serve), and a GitHub agent that runs in your own Actions runner.",
|
|
5
5
|
"main": "bin/codeply.js",
|
|
6
6
|
"bin": {
|