@meistrari/tela-cli 0.7.43 → 0.7.45
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/dist/index.js +249 -59
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2267,12 +2267,14 @@ var require_git = __commonJS({
|
|
|
2267
2267
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2268
2268
|
exports2.buildGitSshCommand = buildGitSshCommand;
|
|
2269
2269
|
exports2.isSshRemoteUrl = isSshRemoteUrl;
|
|
2270
|
+
exports2.getRemoteUrl = getRemoteUrl;
|
|
2270
2271
|
exports2.findRepositoryRoot = findRepositoryRoot;
|
|
2271
2272
|
exports2.getRepositoryRoot = getRepositoryRoot;
|
|
2272
2273
|
exports2.assertGitRepository = assertGitRepository;
|
|
2273
2274
|
exports2.cloneRepository = cloneRepository;
|
|
2274
2275
|
exports2.getOriginUrl = getOriginUrl;
|
|
2275
2276
|
exports2.fetchOrigin = fetchOrigin;
|
|
2277
|
+
exports2.fetchRemote = fetchRemote;
|
|
2276
2278
|
exports2.fetchAllRemotes = fetchAllRemotes;
|
|
2277
2279
|
exports2.getWorktreeStatus = getWorktreeStatus;
|
|
2278
2280
|
exports2.isWorktreeDirty = isWorktreeDirty;
|
|
@@ -2281,6 +2283,10 @@ var require_git = __commonJS({
|
|
|
2281
2283
|
exports2.unstageMatching = unstageMatching;
|
|
2282
2284
|
exports2.getCurrentBranch = getCurrentBranch;
|
|
2283
2285
|
exports2.getUpstreamBranch = getUpstreamBranch;
|
|
2286
|
+
exports2.getPushBranch = getPushBranch;
|
|
2287
|
+
exports2.refExists = refExists;
|
|
2288
|
+
exports2.getAheadBehind = getAheadBehind;
|
|
2289
|
+
exports2.getCommitCount = getCommitCount;
|
|
2284
2290
|
exports2.pullCurrentBranch = pullCurrentBranch;
|
|
2285
2291
|
exports2.pullDefaultBranch = pullDefaultBranch;
|
|
2286
2292
|
exports2.getShortStatus = getShortStatus;
|
|
@@ -2348,6 +2354,9 @@ var require_git = __commonJS({
|
|
|
2348
2354
|
}
|
|
2349
2355
|
return result.stdout.trim() || null;
|
|
2350
2356
|
}
|
|
2357
|
+
async function getRemoteUrl(cwd, remote) {
|
|
2358
|
+
return await getRemoteUrlInternal(cwd, remote);
|
|
2359
|
+
}
|
|
2351
2360
|
async function remoteRequiresConfiguredSsh(cwd, remote) {
|
|
2352
2361
|
const remoteUrl = await getRemoteUrlInternal(cwd, remote);
|
|
2353
2362
|
return Boolean(remoteUrl && isSshRemoteUrl(remoteUrl));
|
|
@@ -2420,6 +2429,14 @@ var require_git = __commonJS({
|
|
|
2420
2429
|
sshHostKeyPolicy: "accept-new"
|
|
2421
2430
|
});
|
|
2422
2431
|
}
|
|
2432
|
+
async function fetchRemote(cwd, remote, sshPrivateKeyPath) {
|
|
2433
|
+
await runGitCommand(["fetch", remote, "--prune"], {
|
|
2434
|
+
cwd,
|
|
2435
|
+
requireConfiguredSsh: await remoteRequiresConfiguredSsh(cwd, remote),
|
|
2436
|
+
sshPrivateKeyPath,
|
|
2437
|
+
sshHostKeyPolicy: "accept-new"
|
|
2438
|
+
});
|
|
2439
|
+
}
|
|
2423
2440
|
async function fetchAllRemotes(cwd, sshPrivateKeyPath) {
|
|
2424
2441
|
await runGitCommand(["fetch", "--all", "--prune"], {
|
|
2425
2442
|
cwd,
|
|
@@ -2465,6 +2482,38 @@ var require_git = __commonJS({
|
|
|
2465
2482
|
}
|
|
2466
2483
|
return result.stdout.trim() || null;
|
|
2467
2484
|
}
|
|
2485
|
+
async function getPushBranch(cwd) {
|
|
2486
|
+
const result = await runGitCommand(["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{push}"], { cwd, allowFailure: true });
|
|
2487
|
+
if (result.exitCode !== 0) {
|
|
2488
|
+
return null;
|
|
2489
|
+
}
|
|
2490
|
+
return result.stdout.trim() || null;
|
|
2491
|
+
}
|
|
2492
|
+
async function refExists(cwd, ref) {
|
|
2493
|
+
const result = await runGitCommand(["rev-parse", "--verify", "--quiet", ref], {
|
|
2494
|
+
cwd,
|
|
2495
|
+
allowFailure: true
|
|
2496
|
+
});
|
|
2497
|
+
return result.exitCode === 0;
|
|
2498
|
+
}
|
|
2499
|
+
async function getAheadBehind(cwd, ref) {
|
|
2500
|
+
if (!await refExists(cwd, ref)) {
|
|
2501
|
+
return { aheadCount: 0, behindCount: 0 };
|
|
2502
|
+
}
|
|
2503
|
+
const result = await runGitCommand(["rev-list", "--left-right", "--count", `HEAD...${ref}`], { cwd });
|
|
2504
|
+
const [aheadRaw, behindRaw] = result.stdout.trim().split(/\s+/);
|
|
2505
|
+
return {
|
|
2506
|
+
aheadCount: Number.parseInt(aheadRaw ?? "0", 10) || 0,
|
|
2507
|
+
behindCount: Number.parseInt(behindRaw ?? "0", 10) || 0
|
|
2508
|
+
};
|
|
2509
|
+
}
|
|
2510
|
+
async function getCommitCount(cwd, ref = "HEAD") {
|
|
2511
|
+
const result = await runGitCommand(["rev-list", "--count", ref], { cwd, allowFailure: true });
|
|
2512
|
+
if (result.exitCode !== 0) {
|
|
2513
|
+
return 0;
|
|
2514
|
+
}
|
|
2515
|
+
return Number.parseInt(result.stdout.trim(), 10) || 0;
|
|
2516
|
+
}
|
|
2468
2517
|
async function pullCurrentBranch(cwd, sshPrivateKeyPath) {
|
|
2469
2518
|
await runGitCommand(["pull", "--ff-only"], {
|
|
2470
2519
|
cwd,
|
|
@@ -2555,26 +2604,27 @@ var require_git = __commonJS({
|
|
|
2555
2604
|
}
|
|
2556
2605
|
function buildFallbackCommitMessage(files) {
|
|
2557
2606
|
if (files.length === 0) {
|
|
2558
|
-
return "
|
|
2607
|
+
return "chore: update repository files";
|
|
2559
2608
|
}
|
|
2560
2609
|
if (files.length === 1) {
|
|
2561
|
-
return `
|
|
2610
|
+
return `chore: update ${(0, node_path_1.basename)(files[0]) || files[0]}`;
|
|
2562
2611
|
}
|
|
2563
|
-
return `
|
|
2612
|
+
return `chore: update ${(0, node_path_1.basename)(files[0]) || files[0]} and ${files.length - 1} other files`;
|
|
2564
2613
|
}
|
|
2565
2614
|
async function commitWithMessage(cwd, message) {
|
|
2566
|
-
await runGitCommand(["commit", "-F", "-"], {
|
|
2615
|
+
await runGitCommand(["commit", "--no-verify", "-F", "-"], {
|
|
2567
2616
|
cwd,
|
|
2568
2617
|
input: message
|
|
2569
2618
|
});
|
|
2570
2619
|
}
|
|
2571
|
-
async function pushBranch(cwd, branch, setUpstream, sshPrivateKeyPath) {
|
|
2572
|
-
const args = setUpstream ? ["push", "--set-upstream",
|
|
2573
|
-
const requireConfiguredSsh = setUpstream ? await remoteRequiresConfiguredSsh(cwd,
|
|
2620
|
+
async function pushBranch(cwd, branch, setUpstream, sshPrivateKeyPath, remote = "origin") {
|
|
2621
|
+
const args = setUpstream ? ["push", "--set-upstream", remote, branch] : ["push"];
|
|
2622
|
+
const requireConfiguredSsh = sshPrivateKeyPath ? await anyRemoteRequiresConfiguredSsh(cwd) : setUpstream ? await remoteRequiresConfiguredSsh(cwd, remote) : await upstreamRequiresConfiguredSsh(cwd);
|
|
2574
2623
|
await runGitCommand(args, {
|
|
2575
2624
|
cwd,
|
|
2576
2625
|
requireConfiguredSsh,
|
|
2577
|
-
sshPrivateKeyPath
|
|
2626
|
+
sshPrivateKeyPath,
|
|
2627
|
+
sshHostKeyPolicy: "accept-new"
|
|
2578
2628
|
});
|
|
2579
2629
|
}
|
|
2580
2630
|
async function getHeadShortSha(cwd) {
|
|
@@ -3208,33 +3258,73 @@ var require_commit_message = __commonJS({
|
|
|
3208
3258
|
"../../packages/agent/dist/commit-message.js"(exports2) {
|
|
3209
3259
|
"use strict";
|
|
3210
3260
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3261
|
+
exports2.isConventionalCommitMessage = isConventionalCommitMessage;
|
|
3262
|
+
exports2.normalizeConventionalCommitMessage = normalizeConventionalCommitMessage;
|
|
3211
3263
|
exports2.generateCommitMessageWithClaude = generateCommitMessageWithClaude;
|
|
3212
3264
|
exports2.fallbackCommitMessageFromFiles = fallbackCommitMessageFromFiles;
|
|
3213
3265
|
var node_path_1 = require("node:path");
|
|
3214
3266
|
var process_1 = require_process();
|
|
3267
|
+
var conventionalCommitPattern = /^(?:build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(?:\([^)]+\))?!?:\s+\S/;
|
|
3215
3268
|
function firstNonEmptyLine(input) {
|
|
3216
3269
|
return input.split(/\r?\n/).map((line) => line.trim()).find(Boolean) ?? "";
|
|
3217
3270
|
}
|
|
3271
|
+
function splitCommitMessage(message) {
|
|
3272
|
+
const lines = message.trim().split(/\r?\n/);
|
|
3273
|
+
const subjectIndex = lines.findIndex((line) => Boolean(line.trim()));
|
|
3274
|
+
if (subjectIndex === -1) {
|
|
3275
|
+
return { subject: "", body: "" };
|
|
3276
|
+
}
|
|
3277
|
+
return {
|
|
3278
|
+
subject: lines[subjectIndex].trim(),
|
|
3279
|
+
body: lines.slice(subjectIndex + 1).join("\n").trim()
|
|
3280
|
+
};
|
|
3281
|
+
}
|
|
3282
|
+
function cleanCommitSubject(message) {
|
|
3283
|
+
const rawSubject = splitCommitMessage(message).subject;
|
|
3284
|
+
const subject = rawSubject.replace(/^["'`]+|["'`]+$/g, "").replace(/^commit message:\s*/i, "").replace(/^[-*]\s+/, "").replace(/\s+/g, " ").replace(/[.!?]$/, "").trim();
|
|
3285
|
+
if (!subject) {
|
|
3286
|
+
return "update repository files";
|
|
3287
|
+
}
|
|
3288
|
+
return `${subject.charAt(0).toLowerCase()}${subject.slice(1)}`;
|
|
3289
|
+
}
|
|
3290
|
+
function isConventionalCommitMessage(message) {
|
|
3291
|
+
return conventionalCommitPattern.test(firstNonEmptyLine(message));
|
|
3292
|
+
}
|
|
3293
|
+
function normalizeConventionalCommitMessage(message) {
|
|
3294
|
+
const trimmed = message.trim();
|
|
3295
|
+
if (!trimmed) {
|
|
3296
|
+
return "chore: update repository files";
|
|
3297
|
+
}
|
|
3298
|
+
if (isConventionalCommitMessage(trimmed)) {
|
|
3299
|
+
return trimmed;
|
|
3300
|
+
}
|
|
3301
|
+
const { body } = splitCommitMessage(trimmed);
|
|
3302
|
+
const subject = `chore: ${cleanCommitSubject(trimmed)}`;
|
|
3303
|
+
return body ? `${subject}
|
|
3304
|
+
|
|
3305
|
+
${body}` : subject;
|
|
3306
|
+
}
|
|
3218
3307
|
async function generateCommitMessageWithClaude(context) {
|
|
3219
3308
|
const claudePath = await (0, process_1.resolveExecutable)("claude");
|
|
3220
3309
|
if (!claudePath) {
|
|
3221
3310
|
throw new Error("Claude CLI is not available");
|
|
3222
3311
|
}
|
|
3223
|
-
const prompt = `You are writing a git commit message for
|
|
3312
|
+
const prompt = `You are writing a git commit message for pushable changes.
|
|
3224
3313
|
|
|
3225
3314
|
Recent git status:
|
|
3226
3315
|
${context.status || "<empty>"}
|
|
3227
3316
|
|
|
3228
|
-
Recent git diff
|
|
3317
|
+
Recent git diff:
|
|
3229
3318
|
${context.diff || "<empty>"}
|
|
3230
3319
|
|
|
3231
3320
|
Recent git log:
|
|
3232
3321
|
${context.log || "<empty>"}
|
|
3233
3322
|
|
|
3234
|
-
Write exactly one short
|
|
3235
|
-
-
|
|
3323
|
+
Write exactly one short Conventional Commit message.
|
|
3324
|
+
- Format the first line as <type>: <subject>
|
|
3325
|
+
- Use a lowercase type such as feat, fix, docs, refactor, test, chore, or perf
|
|
3236
3326
|
- Focus on the purpose of the change
|
|
3237
|
-
- Keep
|
|
3327
|
+
- Keep the first line under 72 characters when possible
|
|
3238
3328
|
- Return only the commit message text`;
|
|
3239
3329
|
const result = await (0, process_1.runCommand)([
|
|
3240
3330
|
claudePath,
|
|
@@ -3249,16 +3339,16 @@ Write exactly one short natural-language git commit message.
|
|
|
3249
3339
|
if (!message) {
|
|
3250
3340
|
throw new Error("Claude returned an empty commit message");
|
|
3251
3341
|
}
|
|
3252
|
-
return message;
|
|
3342
|
+
return normalizeConventionalCommitMessage(message);
|
|
3253
3343
|
}
|
|
3254
3344
|
function fallbackCommitMessageFromFiles(files) {
|
|
3255
3345
|
if (files.length === 0) {
|
|
3256
|
-
return "
|
|
3346
|
+
return "chore: update repository files";
|
|
3257
3347
|
}
|
|
3258
3348
|
if (files.length === 1) {
|
|
3259
|
-
return `
|
|
3349
|
+
return `chore: update ${(0, node_path_1.basename)(files[0]) || files[0]}`;
|
|
3260
3350
|
}
|
|
3261
|
-
return `
|
|
3351
|
+
return `chore: update ${(0, node_path_1.basename)(files[0]) || files[0]} and ${files.length - 1} other files`;
|
|
3262
3352
|
}
|
|
3263
3353
|
}
|
|
3264
3354
|
});
|
|
@@ -3269,10 +3359,11 @@ var require_push = __commonJS({
|
|
|
3269
3359
|
"use strict";
|
|
3270
3360
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3271
3361
|
exports2.previewPush = previewPush;
|
|
3362
|
+
exports2.preparePushPreview = preparePushPreview;
|
|
3272
3363
|
exports2.pushRepository = pushRepository;
|
|
3273
3364
|
var commit_message_1 = require_commit_message();
|
|
3274
3365
|
var git_1 = require_git();
|
|
3275
|
-
var
|
|
3366
|
+
var errors_1 = require_errors();
|
|
3276
3367
|
var PUSH_ARTIFACT_ROOTS = ["input", "output"];
|
|
3277
3368
|
var PUSH_INCLUDED_PATHSPECS = [
|
|
3278
3369
|
".",
|
|
@@ -3281,14 +3372,6 @@ var require_push = __commonJS({
|
|
|
3281
3372
|
":(exclude)output",
|
|
3282
3373
|
":(exclude)output/**"
|
|
3283
3374
|
];
|
|
3284
|
-
function shouldRetryCommit(error) {
|
|
3285
|
-
if (!(error instanceof process_1.CommandError)) {
|
|
3286
|
-
return false;
|
|
3287
|
-
}
|
|
3288
|
-
const details = `${error.result.stdout}
|
|
3289
|
-
${error.result.stderr}`.toLowerCase();
|
|
3290
|
-
return details.includes("hook") || details.includes("pre-commit") || details.includes("modified") || details.includes("stashed changes conflicted");
|
|
3291
|
-
}
|
|
3292
3375
|
async function resolveCommitMessage(repoRoot, options, mode = "staged") {
|
|
3293
3376
|
if (options.mode === "manual" && options.manualMessage?.trim()) {
|
|
3294
3377
|
return {
|
|
@@ -3307,7 +3390,7 @@ ${error.result.stderr}`.toLowerCase();
|
|
|
3307
3390
|
const generatedMessage = await generateCommitMessage({ status, diff, log });
|
|
3308
3391
|
if (generatedMessage.trim()) {
|
|
3309
3392
|
return {
|
|
3310
|
-
message:
|
|
3393
|
+
message: (0, commit_message_1.normalizeConventionalCommitMessage)(generatedMessage),
|
|
3311
3394
|
source: "claude"
|
|
3312
3395
|
};
|
|
3313
3396
|
}
|
|
@@ -3332,8 +3415,72 @@ ${error.result.stderr}`.toLowerCase();
|
|
|
3332
3415
|
await (0, git_1.stageAllMatching)(repoRoot, PUSH_INCLUDED_PATHSPECS);
|
|
3333
3416
|
await (0, git_1.unstageMatching)(repoRoot, PUSH_ARTIFACT_ROOTS);
|
|
3334
3417
|
}
|
|
3335
|
-
|
|
3336
|
-
|
|
3418
|
+
function getUpstreamRemoteName(upstream) {
|
|
3419
|
+
if (!upstream) {
|
|
3420
|
+
return null;
|
|
3421
|
+
}
|
|
3422
|
+
const separator = upstream.indexOf("/");
|
|
3423
|
+
return separator > 0 ? upstream.slice(0, separator) : null;
|
|
3424
|
+
}
|
|
3425
|
+
async function inspectPushRemoteState(repoRoot, branch, upstream, sshPrivateKeyPath) {
|
|
3426
|
+
const pushRef = await (0, git_1.getPushBranch)(repoRoot);
|
|
3427
|
+
const compareRef = pushRef ?? upstream ?? `origin/${branch}`;
|
|
3428
|
+
const remoteName = getUpstreamRemoteName(compareRef) ?? "origin";
|
|
3429
|
+
const setUpstream = !upstream;
|
|
3430
|
+
const remoteUrl = await (0, git_1.getRemoteUrl)(repoRoot, remoteName);
|
|
3431
|
+
if (!remoteUrl) {
|
|
3432
|
+
return {
|
|
3433
|
+
branch,
|
|
3434
|
+
upstream,
|
|
3435
|
+
remoteName,
|
|
3436
|
+
compareRef,
|
|
3437
|
+
setUpstream,
|
|
3438
|
+
aheadCount: 0,
|
|
3439
|
+
behindCount: 0
|
|
3440
|
+
};
|
|
3441
|
+
}
|
|
3442
|
+
await (0, git_1.fetchRemote)(repoRoot, remoteName, sshPrivateKeyPath);
|
|
3443
|
+
if (!await (0, git_1.refExists)(repoRoot, compareRef)) {
|
|
3444
|
+
return {
|
|
3445
|
+
branch,
|
|
3446
|
+
upstream,
|
|
3447
|
+
remoteName,
|
|
3448
|
+
compareRef,
|
|
3449
|
+
setUpstream,
|
|
3450
|
+
aheadCount: await (0, git_1.getCommitCount)(repoRoot),
|
|
3451
|
+
behindCount: 0
|
|
3452
|
+
};
|
|
3453
|
+
}
|
|
3454
|
+
const counts = await (0, git_1.getAheadBehind)(repoRoot, compareRef);
|
|
3455
|
+
return {
|
|
3456
|
+
branch,
|
|
3457
|
+
upstream,
|
|
3458
|
+
remoteName,
|
|
3459
|
+
compareRef,
|
|
3460
|
+
setUpstream,
|
|
3461
|
+
...counts
|
|
3462
|
+
};
|
|
3463
|
+
}
|
|
3464
|
+
function assertPushRemoteCurrent(state) {
|
|
3465
|
+
if (state.behindCount === 0) {
|
|
3466
|
+
return;
|
|
3467
|
+
}
|
|
3468
|
+
throw (0, errors_1.createUserFacingError)({
|
|
3469
|
+
code: "push_remote_ahead",
|
|
3470
|
+
summary: state.aheadCount > 0 ? "Remote branch has diverged." : "Remote branch has new commits.",
|
|
3471
|
+
details: `${state.compareRef ?? "The push target"} is ${state.behindCount} commit${state.behindCount === 1 ? "" : "s"} ahead of the local branch.`,
|
|
3472
|
+
fixes: [
|
|
3473
|
+
"Run `git pull --rebase --autostash`, resolve conflicts if needed, then retry Push."
|
|
3474
|
+
]
|
|
3475
|
+
});
|
|
3476
|
+
}
|
|
3477
|
+
function getReusableRemoteState(state, branch, upstream) {
|
|
3478
|
+
if (!state || state.branch !== branch || state.upstream !== upstream) {
|
|
3479
|
+
return null;
|
|
3480
|
+
}
|
|
3481
|
+
return state;
|
|
3482
|
+
}
|
|
3483
|
+
async function buildPushPreview(repoRoot, options, mode) {
|
|
3337
3484
|
const [worktreeStatus, statusCounts] = await Promise.all([
|
|
3338
3485
|
(0, git_1.getShortStatus)(repoRoot, PUSH_INCLUDED_PATHSPECS),
|
|
3339
3486
|
(0, git_1.getStatusCounts)(repoRoot, PUSH_INCLUDED_PATHSPECS)
|
|
@@ -3349,15 +3496,24 @@ ${error.result.stderr}`.toLowerCase();
|
|
|
3349
3496
|
detached = true;
|
|
3350
3497
|
}
|
|
3351
3498
|
const upstream = detached ? null : await (0, git_1.getUpstreamBranch)(repoRoot);
|
|
3352
|
-
const
|
|
3499
|
+
const remoteState = branch && !detached ? await inspectPushRemoteState(repoRoot, branch, upstream, options.sshPrivateKeyPath) : null;
|
|
3500
|
+
if (remoteState) {
|
|
3501
|
+
assertPushRemoteCurrent(remoteState);
|
|
3502
|
+
}
|
|
3503
|
+
const hasChanges = mode === "staged" ? await (0, git_1.hasStagedChanges)(repoRoot, PUSH_INCLUDED_PATHSPECS) : Boolean(worktreeStatus.trim());
|
|
3504
|
+
const willCommit = hasChanges;
|
|
3505
|
+
const willPushExistingCommits = !willCommit && Boolean(remoteState && remoteState.aheadCount > 0);
|
|
3353
3506
|
let suggestedMessage;
|
|
3354
3507
|
let messageSource;
|
|
3355
3508
|
let fallbackReason;
|
|
3356
3509
|
if (hasChanges) {
|
|
3357
|
-
const resolved = await resolveCommitMessage(repoRoot, options,
|
|
3510
|
+
const resolved = await resolveCommitMessage(repoRoot, options, mode);
|
|
3358
3511
|
suggestedMessage = resolved.message;
|
|
3359
3512
|
messageSource = resolved.source;
|
|
3360
3513
|
fallbackReason = resolved.fallbackReason;
|
|
3514
|
+
} else if (willPushExistingCommits) {
|
|
3515
|
+
suggestedMessage = await (0, git_1.getHeadCommitMessage)(repoRoot);
|
|
3516
|
+
messageSource = "manual";
|
|
3361
3517
|
}
|
|
3362
3518
|
return {
|
|
3363
3519
|
repoRoot,
|
|
@@ -3369,39 +3525,56 @@ ${error.result.stderr}`.toLowerCase();
|
|
|
3369
3525
|
statusCounts,
|
|
3370
3526
|
suggestedMessage,
|
|
3371
3527
|
messageSource,
|
|
3372
|
-
fallbackReason
|
|
3528
|
+
fallbackReason,
|
|
3529
|
+
aheadCount: remoteState?.aheadCount ?? 0,
|
|
3530
|
+
behindCount: remoteState?.behindCount ?? 0,
|
|
3531
|
+
willCommit,
|
|
3532
|
+
willPushExistingCommits,
|
|
3533
|
+
remoteState: remoteState ?? void 0
|
|
3373
3534
|
};
|
|
3374
3535
|
}
|
|
3536
|
+
async function previewPush(options) {
|
|
3537
|
+
const repoRoot = await (0, git_1.getRepositoryRoot)(options.cwd ?? process.cwd());
|
|
3538
|
+
return await buildPushPreview(repoRoot, options, "worktree");
|
|
3539
|
+
}
|
|
3540
|
+
async function preparePushPreview(options) {
|
|
3541
|
+
const repoRoot = await (0, git_1.getRepositoryRoot)(options.cwd ?? process.cwd());
|
|
3542
|
+
await stagePushableChanges(repoRoot);
|
|
3543
|
+
return await buildPushPreview(repoRoot, options, "staged");
|
|
3544
|
+
}
|
|
3375
3545
|
async function pushRepository(options) {
|
|
3376
3546
|
const repoRoot = await (0, git_1.getRepositoryRoot)(options.cwd ?? process.cwd());
|
|
3547
|
+
const branch = await (0, git_1.getCurrentBranch)(repoRoot);
|
|
3548
|
+
const upstream = await (0, git_1.getUpstreamBranch)(repoRoot);
|
|
3549
|
+
const remoteState = getReusableRemoteState(options.remoteState, branch, upstream) ?? await inspectPushRemoteState(repoRoot, branch, upstream, options.sshPrivateKeyPath);
|
|
3550
|
+
assertPushRemoteCurrent(remoteState);
|
|
3377
3551
|
await stagePushableChanges(repoRoot);
|
|
3378
3552
|
if (!await (0, git_1.hasStagedChanges)(repoRoot, PUSH_INCLUDED_PATHSPECS)) {
|
|
3553
|
+
if (remoteState.aheadCount > 0) {
|
|
3554
|
+
const message2 = options.resolvedMessage?.message ?? options.manualMessage?.trim() ?? await (0, git_1.getHeadCommitMessage)(repoRoot);
|
|
3555
|
+
await (0, git_1.pushBranch)(repoRoot, branch, remoteState.setUpstream, options.sshPrivateKeyPath, remoteState.remoteName ?? "origin");
|
|
3556
|
+
return {
|
|
3557
|
+
repoRoot,
|
|
3558
|
+
branch,
|
|
3559
|
+
message: message2,
|
|
3560
|
+
retriedCommit: false,
|
|
3561
|
+
commitSha: await (0, git_1.getHeadShortSha)(repoRoot),
|
|
3562
|
+
upstream: await (0, git_1.getUpstreamBranch)(repoRoot),
|
|
3563
|
+
messageSource: options.resolvedMessage?.source ?? "manual",
|
|
3564
|
+
fallbackReason: options.resolvedMessage?.fallbackReason
|
|
3565
|
+
};
|
|
3566
|
+
}
|
|
3379
3567
|
throw new Error("No changes to push.");
|
|
3380
3568
|
}
|
|
3381
3569
|
const resolvedMessage = options.resolvedMessage ?? await resolveCommitMessage(repoRoot, options);
|
|
3382
3570
|
const message = resolvedMessage.message;
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
await (0, git_1.commitWithMessage)(repoRoot, message);
|
|
3386
|
-
} catch (error) {
|
|
3387
|
-
if (!shouldRetryCommit(error)) {
|
|
3388
|
-
throw error;
|
|
3389
|
-
}
|
|
3390
|
-
retriedCommit = true;
|
|
3391
|
-
await stagePushableChanges(repoRoot);
|
|
3392
|
-
if (!await (0, git_1.hasStagedChanges)(repoRoot, PUSH_INCLUDED_PATHSPECS)) {
|
|
3393
|
-
throw new Error("No changes to push.");
|
|
3394
|
-
}
|
|
3395
|
-
await (0, git_1.commitWithMessage)(repoRoot, message);
|
|
3396
|
-
}
|
|
3397
|
-
const branch = await (0, git_1.getCurrentBranch)(repoRoot);
|
|
3398
|
-
const upstream = await (0, git_1.getUpstreamBranch)(repoRoot);
|
|
3399
|
-
await (0, git_1.pushBranch)(repoRoot, branch, !upstream, options.sshPrivateKeyPath);
|
|
3571
|
+
await (0, git_1.commitWithMessage)(repoRoot, message);
|
|
3572
|
+
await (0, git_1.pushBranch)(repoRoot, branch, remoteState.setUpstream, options.sshPrivateKeyPath, remoteState.remoteName ?? "origin");
|
|
3400
3573
|
return {
|
|
3401
3574
|
repoRoot,
|
|
3402
3575
|
branch,
|
|
3403
3576
|
message,
|
|
3404
|
-
retriedCommit,
|
|
3577
|
+
retriedCommit: false,
|
|
3405
3578
|
commitSha: await (0, git_1.getHeadShortSha)(repoRoot),
|
|
3406
3579
|
upstream: await (0, git_1.getUpstreamBranch)(repoRoot),
|
|
3407
3580
|
messageSource: resolvedMessage.source,
|
|
@@ -6726,23 +6899,25 @@ var require_cli = __commonJS({
|
|
|
6726
6899
|
});
|
|
6727
6900
|
}
|
|
6728
6901
|
const mode = resolvePushMode(options);
|
|
6902
|
+
const config = await (0, config_1.resolveAgentConfig)();
|
|
6729
6903
|
const preview = await (0, push_1.previewPush)({
|
|
6730
6904
|
cwd: repoRoot,
|
|
6731
6905
|
mode,
|
|
6732
|
-
manualMessage: options.message?.trim() || void 0
|
|
6906
|
+
manualMessage: options.message?.trim() || void 0,
|
|
6907
|
+
sshPrivateKeyPath: config.gitSshKey?.privateKeyPath
|
|
6733
6908
|
});
|
|
6734
|
-
if (!preview.hasChanges) {
|
|
6735
|
-
throw (0, errors_1.createUserFacingError)({
|
|
6736
|
-
code: "push_no_changes",
|
|
6737
|
-
summary: "No changes to push."
|
|
6738
|
-
});
|
|
6739
|
-
}
|
|
6740
6909
|
if (preview.detached) {
|
|
6741
6910
|
throw (0, errors_1.createUserFacingError)({
|
|
6742
6911
|
code: "push_detached_head",
|
|
6743
6912
|
summary: "Detached HEAD; check out a branch before pushing."
|
|
6744
6913
|
});
|
|
6745
6914
|
}
|
|
6915
|
+
if (!preview.hasChanges && !preview.willPushExistingCommits) {
|
|
6916
|
+
throw (0, errors_1.createUserFacingError)({
|
|
6917
|
+
code: "push_no_changes",
|
|
6918
|
+
summary: "No changes to push."
|
|
6919
|
+
});
|
|
6920
|
+
}
|
|
6746
6921
|
if (!options.json) {
|
|
6747
6922
|
write(io.stdout, renderPushPreview(preview));
|
|
6748
6923
|
}
|
|
@@ -6756,15 +6931,24 @@ var require_cli = __commonJS({
|
|
|
6756
6931
|
if (options.dryRun) {
|
|
6757
6932
|
const result2 = {
|
|
6758
6933
|
ok: true,
|
|
6934
|
+
repoRoot: preview.repoRoot,
|
|
6759
6935
|
branch: preview.branch,
|
|
6936
|
+
upstream: preview.upstream,
|
|
6937
|
+
statusCounts: preview.statusCounts,
|
|
6938
|
+
worktreeStatus: preview.worktreeStatus,
|
|
6760
6939
|
commitMessage: resolvedMessage,
|
|
6940
|
+
messageSource: preview.messageSource,
|
|
6941
|
+
fallbackReason: preview.fallbackReason,
|
|
6942
|
+
aheadCount: preview.aheadCount,
|
|
6943
|
+
behindCount: preview.behindCount,
|
|
6944
|
+
willCommit: preview.willCommit,
|
|
6945
|
+
willPushExistingCommits: preview.willPushExistingCommits,
|
|
6761
6946
|
nextActions: ["Run `tela agent push` without `--dry-run` when the plan looks correct."]
|
|
6762
6947
|
};
|
|
6763
6948
|
if (options.json)
|
|
6764
6949
|
emitJson(io, result2);
|
|
6765
6950
|
return 0;
|
|
6766
6951
|
}
|
|
6767
|
-
const config = await (0, config_1.resolveAgentConfig)();
|
|
6768
6952
|
const push = await (0, push_1.pushRepository)({
|
|
6769
6953
|
cwd: repoRoot,
|
|
6770
6954
|
mode: "manual",
|
|
@@ -6774,12 +6958,17 @@ var require_cli = __commonJS({
|
|
|
6774
6958
|
source: preview.messageSource ?? (options.message ? "manual" : "fallback"),
|
|
6775
6959
|
fallbackReason: preview.fallbackReason
|
|
6776
6960
|
},
|
|
6777
|
-
sshPrivateKeyPath: config.gitSshKey?.privateKeyPath
|
|
6961
|
+
sshPrivateKeyPath: config.gitSshKey?.privateKeyPath,
|
|
6962
|
+
remoteState: preview.remoteState
|
|
6778
6963
|
});
|
|
6779
6964
|
const result = {
|
|
6780
6965
|
ok: true,
|
|
6966
|
+
repoRoot: push.repoRoot,
|
|
6781
6967
|
branch: push.branch,
|
|
6968
|
+
upstream: push.upstream,
|
|
6782
6969
|
commitMessage: push.message,
|
|
6970
|
+
messageSource: push.messageSource,
|
|
6971
|
+
fallbackReason: push.fallbackReason,
|
|
6783
6972
|
commitSha: push.commitSha,
|
|
6784
6973
|
retriedCommit: push.retriedCommit,
|
|
6785
6974
|
nextActions: ["Run `tela agent feedback --list` to inspect feedback for the pushed commit."]
|
|
@@ -7229,6 +7418,7 @@ var require_dist2 = __commonJS({
|
|
|
7229
7418
|
__exportStar(require_push(), exports2);
|
|
7230
7419
|
__exportStar(require_run(), exports2);
|
|
7231
7420
|
__exportStar(require_sync(), exports2);
|
|
7421
|
+
__exportStar(require_commit_message(), exports2);
|
|
7232
7422
|
var config_1 = require_config2();
|
|
7233
7423
|
Object.defineProperty(exports2, "getDefaultAgentCloneRoot", { enumerable: true, get: function() {
|
|
7234
7424
|
return config_1.getDefaultAgentCloneRoot;
|