codeply-cli 0.5.4 → 0.5.6
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/lib/cloud.mjs +16 -6
- package/lib/github-agent.mjs +1 -1
- package/package.json +1 -1
package/lib/cloud.mjs
CHANGED
|
@@ -792,12 +792,20 @@ export async function downloadShot({ token, repo, path: rel, dest, apiUrl, fetch
|
|
|
792
792
|
* Before coding: is the local branch behind GitHub (a cloud run merged work
|
|
793
793
|
* into it)? Only for projects whose cloud target is their own repo.
|
|
794
794
|
*/
|
|
795
|
-
|
|
795
|
+
/**
|
|
796
|
+
* Background git talks to GitHub with Craft's own GitHub login (when given),
|
|
797
|
+
* never through Windows' credential manager, which would pop up a sign-in
|
|
798
|
+
* window every time Craft checks for new commits.
|
|
799
|
+
*/
|
|
800
|
+
const QUIET_GIT = ['-c', 'credential.helper='];
|
|
801
|
+
const quietAuth = (token) => (token ? { server: 'https://github.com', token } : undefined);
|
|
802
|
+
|
|
803
|
+
export async function checkBehind(cwd, { token } = {}) {
|
|
796
804
|
try {
|
|
797
805
|
const branch = await git(cwd, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
798
806
|
const upstream = await git(cwd, ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}']).catch(() => null);
|
|
799
807
|
if (!upstream) return { ok: false, reason: 'no upstream' };
|
|
800
|
-
await git(cwd, ['fetch', '-q', '--no-tags', upstream.split('/')[0]]);
|
|
808
|
+
await git(cwd, [...QUIET_GIT, 'fetch', '-q', '--no-tags', upstream.split('/')[0]], { auth: quietAuth(token) });
|
|
801
809
|
const [behind, ahead] = (await git(cwd, ['rev-list', '--left-right', '--count', `${upstream}...HEAD`])).split(/\s+/).map(Number);
|
|
802
810
|
const dirty = !!(await git(cwd, ['status', '--porcelain', '--untracked-files=no']));
|
|
803
811
|
const latest = behind ? (await git(cwd, ['log', '-1', '--format=%s', upstream]).catch(() => '')) : '';
|
|
@@ -806,14 +814,14 @@ export async function checkBehind(cwd) {
|
|
|
806
814
|
}
|
|
807
815
|
|
|
808
816
|
/** Pull what GitHub has (a fast-forward when possible, else a merge; stashes local edits around it). */
|
|
809
|
-
export async function pullLatest(cwd) {
|
|
810
|
-
const st = await checkBehind(cwd);
|
|
817
|
+
export async function pullLatest(cwd, { token } = {}) {
|
|
818
|
+
const st = await checkBehind(cwd, { token });
|
|
811
819
|
if (!st.ok) throw new Error(`Can't pull: ${st.reason}.`);
|
|
812
820
|
if (!st.behind) return { pulled: 0 };
|
|
813
821
|
let stashed = false;
|
|
814
822
|
if (st.dirty) { await git(cwd, ['stash', 'push', '-q', '-m', 'craft: before pulling cloud changes']); stashed = true; }
|
|
815
823
|
try {
|
|
816
|
-
await git(cwd, ['-c', 'user.name=Codeply Craft', '-c', 'user.email=craft-bot@users.noreply.github.com', 'pull', '-q', '--no-rebase', '--no-edit']);
|
|
824
|
+
await git(cwd, [...QUIET_GIT, '-c', 'user.name=Codeply Craft', '-c', 'user.email=craft-bot@users.noreply.github.com', 'pull', '-q', '--no-rebase', '--no-edit'], { auth: quietAuth(token) });
|
|
817
825
|
} catch (e) {
|
|
818
826
|
// A conflicting pull is undone, so the project is never left half-merged.
|
|
819
827
|
const conflicted = (await git(cwd, ['diff', '--name-only', '--diff-filter=U']).catch(() => '')).split('\n').filter(Boolean);
|
|
@@ -1209,7 +1217,9 @@ async function runOneTask({ task, env, cwd, api, files, repo, token, serverUrl,
|
|
|
1209
1217
|
await pushProgress(hist.messages.length ? `Continuing the chat (${hist.messages.length / 2} earlier turns).` : 'Working on it.', true);
|
|
1210
1218
|
// Risky actions (deploys...) ask the person unless the repo's Cloud permission is "full".
|
|
1211
1219
|
const ASK_WAIT_MS = 15 * 60 * 1000;
|
|
1212
|
-
|
|
1220
|
+
// Only a repo with the current workflow passes CRAFT_PERMISSIONS (empty when unset): its
|
|
1221
|
+
// Craft and phone can show the question. An older setup keeps the old rule (no) until updated.
|
|
1222
|
+
const rules = ciApprove(cwd, { permission: env.CRAFT_PERMISSIONS, canAsk: env.CRAFT_PERMISSIONS !== undefined });
|
|
1213
1223
|
const approve = async (req) => {
|
|
1214
1224
|
const v = await rules(req);
|
|
1215
1225
|
if (v !== 'ask') return v;
|
package/lib/github-agent.mjs
CHANGED
|
@@ -116,7 +116,7 @@ export function git(cwd, args, { auth, input } = {}) {
|
|
|
116
116
|
const full = auth ? ['-c', `http.${auth.server}/.extraheader=AUTHORIZATION: basic ${Buffer.from(`x-access-token:${auth.token}`).toString('base64')}`, ...args] : args;
|
|
117
117
|
const verb = args.find((a, i) => !a.startsWith('-') && !(i > 0 && /^--(git-dir|work-tree)$/.test(args[i - 1])) && !(i > 0 && args[i - 1] === '-c')) || args[0];
|
|
118
118
|
return new Promise((resolve, reject) => {
|
|
119
|
-
const child = execFile('git', full, { cwd, timeout: 300000, windowsHide: true, maxBuffer: 256 * 1024 * 1024, env: { ...process.env, GIT_TERMINAL_PROMPT: '0' } }, (err, stdout, stderr) => {
|
|
119
|
+
const child = execFile('git', full, { cwd, timeout: 300000, windowsHide: true, maxBuffer: 256 * 1024 * 1024, env: { ...process.env, GIT_TERMINAL_PROMPT: '0', GCM_INTERACTIVE: 'never' } }, (err, stdout, stderr) => {
|
|
120
120
|
if (err) reject(new Error(`git ${verb} failed: ${String(stderr || err.message).trim().split('\n').slice(-2).join(' ')}`));
|
|
121
121
|
else resolve(String(stdout).trim());
|
|
122
122
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeply-cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
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": {
|