workshell 0.5.0 → 0.5.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/README.md +1 -1
- package/dist/index.js +56 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -112,7 +112,7 @@ After cloning, the `main` branch is checked out. Let's say we want to start work
|
|
|
112
112
|
$ wk new feat-1
|
|
113
113
|
|
|
114
114
|
✓ feat-1 (from main)
|
|
115
|
-
|
|
115
|
+
Opening branch in ephemeral subshell
|
|
116
116
|
Type 'wk close' to return.
|
|
117
117
|
```
|
|
118
118
|
|
package/dist/index.js
CHANGED
|
@@ -8052,7 +8052,8 @@ function loadGlobalStore() {
|
|
|
8052
8052
|
return raw;
|
|
8053
8053
|
}
|
|
8054
8054
|
return { repos: {} };
|
|
8055
|
-
} catch {
|
|
8055
|
+
} catch (err) {
|
|
8056
|
+
console.error(`Warning: failed to load store: ${err instanceof Error ? err.message : String(err)}`);
|
|
8056
8057
|
return { repos: {} };
|
|
8057
8058
|
}
|
|
8058
8059
|
}
|
|
@@ -8116,7 +8117,8 @@ function loadConfig() {
|
|
|
8116
8117
|
const content = readFileSync(configPath, "utf-8");
|
|
8117
8118
|
const parsed = parse(content);
|
|
8118
8119
|
return parsed;
|
|
8119
|
-
} catch {
|
|
8120
|
+
} catch (err) {
|
|
8121
|
+
console.error(`Warning: failed to load ${configPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
8120
8122
|
return null;
|
|
8121
8123
|
}
|
|
8122
8124
|
}
|
|
@@ -8256,7 +8258,8 @@ function getWorktreeForBranch(branch) {
|
|
|
8256
8258
|
}
|
|
8257
8259
|
}
|
|
8258
8260
|
return null;
|
|
8259
|
-
} catch {
|
|
8261
|
+
} catch (err) {
|
|
8262
|
+
console.error(warn(`git worktree list failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
8260
8263
|
return null;
|
|
8261
8264
|
}
|
|
8262
8265
|
}
|
|
@@ -8299,7 +8302,8 @@ function removeGitWorktree(path) {
|
|
|
8299
8302
|
function pruneWorktrees() {
|
|
8300
8303
|
try {
|
|
8301
8304
|
execSync2("git worktree prune", { stdio: "ignore" });
|
|
8302
|
-
} catch {
|
|
8305
|
+
} catch (err) {
|
|
8306
|
+
console.error(warn(`git worktree prune failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
8303
8307
|
}
|
|
8304
8308
|
}
|
|
8305
8309
|
function deleteBranch(name) {
|
|
@@ -8315,6 +8319,16 @@ function branchHasRemote(name) {
|
|
|
8315
8319
|
return false;
|
|
8316
8320
|
}
|
|
8317
8321
|
}
|
|
8322
|
+
function branchHasCommitsAheadOf(baseBranch, branch) {
|
|
8323
|
+
try {
|
|
8324
|
+
const count = execSync2(`git rev-list --count "${baseBranch}".."${branch}"`, {
|
|
8325
|
+
encoding: "utf-8"
|
|
8326
|
+
}).trim();
|
|
8327
|
+
return parseInt(count, 10) > 0;
|
|
8328
|
+
} catch {
|
|
8329
|
+
return false;
|
|
8330
|
+
}
|
|
8331
|
+
}
|
|
8318
8332
|
function canFastForward(baseBranch, targetBranch) {
|
|
8319
8333
|
try {
|
|
8320
8334
|
const baseCommit = execSync2(`git rev-parse "${baseBranch}"`, { encoding: "utf-8" }).trim();
|
|
@@ -8532,8 +8546,19 @@ var installCmds = {
|
|
|
8532
8546
|
pipenv: "pipenv install",
|
|
8533
8547
|
pdm: "pdm install"
|
|
8534
8548
|
};
|
|
8549
|
+
var lockfileNames = {
|
|
8550
|
+
npm: "package-lock.json",
|
|
8551
|
+
yarn: "yarn.lock",
|
|
8552
|
+
pnpm: "pnpm-lock.yaml",
|
|
8553
|
+
bun: "bun.lock",
|
|
8554
|
+
uv: "uv.lock",
|
|
8555
|
+
poetry: "poetry.lock",
|
|
8556
|
+
pipenv: "Pipfile.lock",
|
|
8557
|
+
pdm: "pdm.lock"
|
|
8558
|
+
};
|
|
8535
8559
|
function runPackageManagerInstall(pm, cwd) {
|
|
8536
8560
|
const cmd2 = installCmds[pm];
|
|
8561
|
+
console.log(dim(`Detected ${lockfileNames[pm]}`));
|
|
8537
8562
|
console.log(dim(`Running ${cmd2}...`));
|
|
8538
8563
|
try {
|
|
8539
8564
|
execSync2(cmd2, { cwd, stdio: "inherit" });
|
|
@@ -8590,11 +8615,12 @@ function getIgnoredFiles(repoPath) {
|
|
|
8590
8615
|
try {
|
|
8591
8616
|
const output = execFileSync(
|
|
8592
8617
|
"git",
|
|
8593
|
-
["ls-files", "--others", "--ignored", "--exclude-standard"],
|
|
8594
|
-
{ cwd: repoPath, encoding: "utf-8" }
|
|
8618
|
+
["ls-files", "--others", "--ignored", "--exclude-standard", "--directory"],
|
|
8619
|
+
{ cwd: repoPath, encoding: "utf-8", maxBuffer: 10 * 1024 * 1024 }
|
|
8595
8620
|
);
|
|
8596
|
-
return output.split("\n").filter((p) => p.length > 0 &&
|
|
8597
|
-
} catch {
|
|
8621
|
+
return output.split("\n").map((p) => p.replace(/\/$/, "")).filter((p) => p.length > 0 && p !== ".git");
|
|
8622
|
+
} catch (err) {
|
|
8623
|
+
console.error(warn(`Failed to list ignored files: ${err instanceof Error ? err.message : String(err)}`));
|
|
8598
8624
|
return [];
|
|
8599
8625
|
}
|
|
8600
8626
|
}
|
|
@@ -8626,14 +8652,20 @@ function autoCleanupWorktree(worktreeId, path, store, saveStore2) {
|
|
|
8626
8652
|
console.log(" Pruning worktree...");
|
|
8627
8653
|
try {
|
|
8628
8654
|
removeGitWorktree(path);
|
|
8629
|
-
} catch {
|
|
8655
|
+
} catch (err) {
|
|
8656
|
+
console.error(dim(` git worktree remove failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
8630
8657
|
}
|
|
8631
8658
|
pruneWorktrees();
|
|
8632
8659
|
removeWorktreeMeta(store, worktreeId);
|
|
8633
8660
|
saveStore2(store);
|
|
8634
8661
|
const canMergeBranch = branch !== "[missing]" && branch !== "[detached]" && currentBranch !== "HEAD";
|
|
8635
8662
|
if (!canMergeBranch) {
|
|
8636
|
-
|
|
8663
|
+
const branchNote = branch !== "[missing]" && branch !== "[detached]" ? ` Branch '${cyan(branch)}' still exists.` : "";
|
|
8664
|
+
console.log(` Pruned '${branch}' worktree.${branchNote}`);
|
|
8665
|
+
return;
|
|
8666
|
+
}
|
|
8667
|
+
if (!branchHasCommitsAheadOf(currentBranch, branch)) {
|
|
8668
|
+
console.log(` Pruned worktree. Branch '${cyan(branch)}' still exists.`);
|
|
8637
8669
|
return;
|
|
8638
8670
|
}
|
|
8639
8671
|
if (branchHasRemote(branch)) {
|
|
@@ -8704,6 +8736,7 @@ function newCommand(branchName, fromBranch) {
|
|
|
8704
8736
|
const worktreeId = `${repoName}@${slugify(branch)}`;
|
|
8705
8737
|
const worktreePath = join3(getWorktreesDir(), worktreeId);
|
|
8706
8738
|
mkdirSync3(dirname3(worktreePath), { recursive: true });
|
|
8739
|
+
console.log(dim(`Creating worktree for ${cyan(branch)}...`));
|
|
8707
8740
|
createWorktree(branch, worktreePath, fromBranch);
|
|
8708
8741
|
initSubmodules(worktreePath);
|
|
8709
8742
|
const config = loadConfig();
|
|
@@ -8719,7 +8752,8 @@ function newCommand(branchName, fromBranch) {
|
|
|
8719
8752
|
const parentBranch = getCurrentBranch();
|
|
8720
8753
|
console.log();
|
|
8721
8754
|
console.log(success(bold(branch)), dim(`(from ${cyan(baseBranch)})`));
|
|
8722
|
-
console.log(dim(
|
|
8755
|
+
console.log(dim(worktreePath));
|
|
8756
|
+
console.log(dim(`Opening branch in ephemeral subshell`));
|
|
8723
8757
|
console.log(dim("Type 'wk close' to return."));
|
|
8724
8758
|
console.log();
|
|
8725
8759
|
spawnShell(worktreePath, {
|
|
@@ -8776,7 +8810,8 @@ function fetchPRBranch(prRef, prInfo) {
|
|
|
8776
8810
|
execSync3(`gh pr checkout ${prRef}`, { stdio: "pipe" });
|
|
8777
8811
|
execSync3(`git checkout "${currentBranch}"`, { stdio: "pipe" });
|
|
8778
8812
|
return true;
|
|
8779
|
-
} catch {
|
|
8813
|
+
} catch (err) {
|
|
8814
|
+
console.error(`Warning: gh pr checkout failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
8780
8815
|
try {
|
|
8781
8816
|
execSync3(`git checkout "${currentBranch}"`, { stdio: "pipe" });
|
|
8782
8817
|
} catch {
|
|
@@ -8835,10 +8870,10 @@ function openBranch(branch, prNumber) {
|
|
|
8835
8870
|
console.log();
|
|
8836
8871
|
if (prNumber) {
|
|
8837
8872
|
console.log(success(bold(`PR #${prNumber}`)), dim(`branch: ${cyan(branch)}`));
|
|
8838
|
-
console.log(dim(`
|
|
8873
|
+
console.log(dim(`Opening PR in ephemeral subshell`));
|
|
8839
8874
|
} else {
|
|
8840
8875
|
console.log(success(bold(branch)));
|
|
8841
|
-
console.log(dim(`
|
|
8876
|
+
console.log(dim(`Opening branch in ephemeral subshell`));
|
|
8842
8877
|
}
|
|
8843
8878
|
console.log(dim("Type 'exit' or 'wk close' to return."));
|
|
8844
8879
|
console.log();
|
|
@@ -9785,12 +9820,14 @@ function rmCommand(branch, force = false) {
|
|
|
9785
9820
|
try {
|
|
9786
9821
|
execSync4(`git -C "${worktreePath}" reset --hard HEAD`, { stdio: "ignore" });
|
|
9787
9822
|
execSync4(`git -C "${worktreePath}" clean -fd`, { stdio: "ignore" });
|
|
9788
|
-
} catch {
|
|
9823
|
+
} catch (err) {
|
|
9824
|
+
console.error(warn(`Failed to discard changes: ${err instanceof Error ? err.message : String(err)}`));
|
|
9789
9825
|
}
|
|
9790
9826
|
}
|
|
9791
9827
|
try {
|
|
9792
9828
|
removeGitWorktree(worktreePath);
|
|
9793
|
-
} catch {
|
|
9829
|
+
} catch (err) {
|
|
9830
|
+
console.error(dim(`git worktree remove failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
9794
9831
|
}
|
|
9795
9832
|
pruneWorktrees();
|
|
9796
9833
|
const store = loadStore();
|
|
@@ -9887,7 +9924,8 @@ function precloseCommand(force) {
|
|
|
9887
9924
|
execSync6("git clean -ffd", { stdio: "ignore" });
|
|
9888
9925
|
execSync6("git submodule foreach --recursive 'git reset --hard HEAD; git clean -ffd'", { stdio: "ignore" });
|
|
9889
9926
|
execSync6("git submodule update --init --recursive --force", { stdio: "ignore" });
|
|
9890
|
-
} catch {
|
|
9927
|
+
} catch (err) {
|
|
9928
|
+
console.error(`Warning: failed to discard changes: ${err instanceof Error ? err.message : String(err)}`);
|
|
9891
9929
|
}
|
|
9892
9930
|
process.exit(0);
|
|
9893
9931
|
}
|
|
@@ -9959,7 +9997,7 @@ function promptChoice() {
|
|
|
9959
9997
|
}
|
|
9960
9998
|
|
|
9961
9999
|
// index.ts
|
|
9962
|
-
var VERSION = "0.5.
|
|
10000
|
+
var VERSION = "0.5.1";
|
|
9963
10001
|
function printHelp() {
|
|
9964
10002
|
const dim2 = import_picocolors4.default.dim;
|
|
9965
10003
|
const cyan2 = import_picocolors4.default.cyan;
|