@denisvieiradev/gitwise-core 0.1.0 → 1.1.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/dist/index.d.ts +6 -1
- package/dist/index.js +46 -37
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -721,7 +721,12 @@ interface FinishReleaseOptions {
|
|
|
721
721
|
* failed strategy merge (typically gitflow's develop merge when develop has
|
|
722
722
|
* advanced) surfaces as `FINISH_MERGE_CONFLICT` — the repo is left mid-merge
|
|
723
723
|
* for manual recovery (`git merge --continue` then tag + push by hand) since
|
|
724
|
-
* the plan can no longer be re-run.
|
|
724
|
+
* the plan can no longer be re-run. A failure in step 9 (tag creation, or a
|
|
725
|
+
* rejected push — typically a non-fast-forward because origin's mainBranch
|
|
726
|
+
* advanced, e.g. a CI bot commit, while this release was being prepared or
|
|
727
|
+
* finished) surfaces as `FINISH_PUSH_FAILED` with the exact fetch/merge/push
|
|
728
|
+
* recovery commands embedded in the message; merge (never rebase) is required
|
|
729
|
+
* because the tag, if already created, is pinned to the release commit's hash.
|
|
725
730
|
*/
|
|
726
731
|
declare function finishRelease(opts: FinishReleaseOptions): Promise<void>;
|
|
727
732
|
interface AbortReleaseOptions {
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ var __export = (target, all) => {
|
|
|
7
7
|
// package.json
|
|
8
8
|
var package_default = {
|
|
9
9
|
name: "@denisvieiradev/gitwise-core",
|
|
10
|
-
version: "
|
|
10
|
+
version: "1.1.0",
|
|
11
11
|
description: "Shared logic for gitwise: non-interactive commit/review/pr/release commands, LLM providers, git/github primitives, prompt templates.",
|
|
12
12
|
type: "module",
|
|
13
13
|
main: "./dist/index.js",
|
|
@@ -890,12 +890,10 @@ function defaultIsProcessAlive(pid) {
|
|
|
890
890
|
}
|
|
891
891
|
|
|
892
892
|
// src/providers/claude-code.ts
|
|
893
|
-
import {
|
|
893
|
+
import { execSync, spawn } from "child_process";
|
|
894
894
|
import fs from "fs";
|
|
895
895
|
import os from "os";
|
|
896
896
|
import path2 from "path";
|
|
897
|
-
import { promisify as promisify3 } from "util";
|
|
898
|
-
var execFileAsync = promisify3(execFile3);
|
|
899
897
|
var LARGE_PROMPT_THRESHOLD = 1e5;
|
|
900
898
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
901
899
|
var COMMON_CLAUDE_PATHS = [
|
|
@@ -973,35 +971,12 @@ var ClaudeCodeProvider = class {
|
|
|
973
971
|
return args;
|
|
974
972
|
}
|
|
975
973
|
async callViaCli(args) {
|
|
976
|
-
|
|
977
|
-
const { stdout } = await execFileAsync(this.claudeBinaryPath, args, {
|
|
978
|
-
timeout: DEFAULT_TIMEOUT_MS,
|
|
979
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
980
|
-
...{ input: "" }
|
|
981
|
-
});
|
|
982
|
-
return this.parseResponse(stdout);
|
|
983
|
-
} catch (err) {
|
|
984
|
-
const execErr = err;
|
|
985
|
-
if (execErr.stdout) {
|
|
986
|
-
try {
|
|
987
|
-
const parsed = JSON.parse(execErr.stdout);
|
|
988
|
-
if (parsed.is_error) {
|
|
989
|
-
throw new Error(`Claude CLI error: ${parsed.result}`);
|
|
990
|
-
}
|
|
991
|
-
} catch (parseErr) {
|
|
992
|
-
if (parseErr instanceof Error && parseErr.message.startsWith("Claude CLI error:")) {
|
|
993
|
-
throw parseErr;
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
const stderr = execErr.stderr?.replace(/Warning: no stdin data.*\n?/g, "").trim();
|
|
998
|
-
if (stderr) {
|
|
999
|
-
throw new Error(`Claude CLI failed: ${stderr}`);
|
|
1000
|
-
}
|
|
1001
|
-
throw this.wrapError(err);
|
|
1002
|
-
}
|
|
974
|
+
return this.spawnClaude(args, "");
|
|
1003
975
|
}
|
|
1004
976
|
async callViaStdin(args, input) {
|
|
977
|
+
return this.spawnClaude(args, input);
|
|
978
|
+
}
|
|
979
|
+
async spawnClaude(args, input) {
|
|
1005
980
|
return new Promise((resolve, reject) => {
|
|
1006
981
|
const child = spawn(this.claudeBinaryPath, args, {
|
|
1007
982
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -1740,9 +1715,9 @@ ${stderr}`;
|
|
|
1740
1715
|
}
|
|
1741
1716
|
|
|
1742
1717
|
// src/commands/pr.ts
|
|
1743
|
-
import { execFile as
|
|
1744
|
-
import { promisify as
|
|
1745
|
-
var exec3 =
|
|
1718
|
+
import { execFile as execFile3 } from "child_process";
|
|
1719
|
+
import { promisify as promisify3 } from "util";
|
|
1720
|
+
var exec3 = promisify3(execFile3);
|
|
1746
1721
|
function parsePrResponse(content) {
|
|
1747
1722
|
const titleMatch = content.match(/^TITLE:\s*(.+)$/m);
|
|
1748
1723
|
const title = titleMatch ? titleMatch[1].trim() : "Update";
|
|
@@ -2473,6 +2448,28 @@ ${dirty}`,
|
|
|
2473
2448
|
await saveReleasePlan(cwd, persistedPlan);
|
|
2474
2449
|
await finishRelease({ cwd, tagAndPush, createGhRelease, workspacePropagation, signTags });
|
|
2475
2450
|
}
|
|
2451
|
+
function finishPushFailure(opts) {
|
|
2452
|
+
const { stage, tag, mainBranch, developBranch, newVersion, err } = opts;
|
|
2453
|
+
const cause = err instanceof Error ? err.message : String(err);
|
|
2454
|
+
const action = stage === "tag" ? `create the tag "${tag}"` : stage === "push-main" ? `push "${mainBranch}" (with tags) to origin` : `push "${developBranch}" to origin`;
|
|
2455
|
+
const recoverySteps = stage === "tag" ? [
|
|
2456
|
+
`git tag -a ${tag} -F .gitwise/release-${newVersion}.md`,
|
|
2457
|
+
`git push origin ${mainBranch} --follow-tags`
|
|
2458
|
+
] : [
|
|
2459
|
+
`git ls-remote --tags origin ${tag} # check whether the tag already reached origin`,
|
|
2460
|
+
`git fetch origin`,
|
|
2461
|
+
`git merge origin/${mainBranch} # do NOT rebase \u2014 that changes the hash ${tag} points to`,
|
|
2462
|
+
`git push origin ${mainBranch} --follow-tags`
|
|
2463
|
+
];
|
|
2464
|
+
return new GitwiseError({
|
|
2465
|
+
code: "FINISH_PUSH_FAILED",
|
|
2466
|
+
message: `Failed to ${action} while finishing v${newVersion}: ${cause}. The release plan file has already been deleted, so "gw release finish" cannot be re-run, and the release commit already exists locally, so "gw release prepare" will refuse with NO_COMMITS. Recover manually:
|
|
2467
|
+
${recoverySteps.map((s) => ` ${s}`).join("\n")}`,
|
|
2468
|
+
exitCode: EXIT_CODES.GIT_FAILED,
|
|
2469
|
+
cause: err,
|
|
2470
|
+
details: { stage, tag, mainBranch, developBranch, newVersion }
|
|
2471
|
+
});
|
|
2472
|
+
}
|
|
2476
2473
|
async function finishRelease(opts) {
|
|
2477
2474
|
const {
|
|
2478
2475
|
cwd,
|
|
@@ -2663,15 +2660,27 @@ ${cause}`,
|
|
|
2663
2660
|
await checkout(cwd, mainBranch);
|
|
2664
2661
|
}
|
|
2665
2662
|
if (tagAndPush) {
|
|
2666
|
-
|
|
2667
|
-
|
|
2663
|
+
try {
|
|
2664
|
+
await createTag(cwd, tag, notes, { signed: signTags !== false });
|
|
2665
|
+
} catch (err) {
|
|
2666
|
+
throw finishPushFailure({ stage: "tag", tag, mainBranch, newVersion: plan.newVersion, err });
|
|
2667
|
+
}
|
|
2668
|
+
try {
|
|
2669
|
+
await pushWithTags(cwd, "origin", mainBranch);
|
|
2670
|
+
} catch (err) {
|
|
2671
|
+
throw finishPushFailure({ stage: "push-main", tag, mainBranch, newVersion: plan.newVersion, err });
|
|
2672
|
+
}
|
|
2668
2673
|
debug("release.finish.tag.pushed", {
|
|
2669
2674
|
tag,
|
|
2670
2675
|
branch: mainBranch,
|
|
2671
2676
|
remote: "origin"
|
|
2672
2677
|
});
|
|
2673
2678
|
if (strategy.requiresDevelop()) {
|
|
2674
|
-
|
|
2679
|
+
try {
|
|
2680
|
+
await push(cwd, "origin", developBranch);
|
|
2681
|
+
} catch (err) {
|
|
2682
|
+
throw finishPushFailure({ stage: "push-develop", tag, mainBranch, developBranch, newVersion: plan.newVersion, err });
|
|
2683
|
+
}
|
|
2675
2684
|
}
|
|
2676
2685
|
}
|
|
2677
2686
|
if (createGhRelease) {
|