workshell 0.1.0 → 0.2.0

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.
Files changed (2) hide show
  1. package/dist/index.js +139 -259
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7098,37 +7098,78 @@ function newCommand(branchName, fromBranch) {
7098
7098
  }
7099
7099
 
7100
7100
  // commands/open.ts
7101
+ import { execSync as execSync3 } from "child_process";
7101
7102
  import { mkdirSync as mkdirSync4 } from "fs";
7102
7103
  import { basename as basename4, dirname as dirname4, join as join4 } from "path";
7103
- function openCommand(branch) {
7104
- if (isInsideWorktree()) {
7105
- const currentBranch = getCurrentBranch();
7106
- console.log();
7107
- console.log(warn(`You're inside a worktree (branch: ${cyan(currentBranch)})`));
7108
- console.log(` This will nest subshells (subshell inside subshell).`);
7109
- console.log();
7110
- if (!confirm("Continue?")) {
7111
- process.exit(0);
7104
+ function isGhInstalled() {
7105
+ try {
7106
+ execSync3("gh --version", { stdio: "pipe", encoding: "utf-8" });
7107
+ return true;
7108
+ } catch {
7109
+ return false;
7110
+ }
7111
+ }
7112
+ function isGhAuthenticated() {
7113
+ try {
7114
+ execSync3("gh auth status", { stdio: "pipe", encoding: "utf-8" });
7115
+ return true;
7116
+ } catch {
7117
+ return false;
7118
+ }
7119
+ }
7120
+ function getPRInfo(prRef) {
7121
+ try {
7122
+ const output = execSync3(
7123
+ `gh pr view ${prRef} --json number,headRefName`,
7124
+ { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
7125
+ );
7126
+ return JSON.parse(output);
7127
+ } catch {
7128
+ return null;
7129
+ }
7130
+ }
7131
+ function fetchPRBranch(prRef, prInfo) {
7132
+ try {
7133
+ execSync3(`git fetch origin ${prInfo.headRefName}:${prInfo.headRefName}`, { stdio: "pipe" });
7134
+ return true;
7135
+ } catch {
7136
+ }
7137
+ const currentBranch = getCurrentBranch();
7138
+ try {
7139
+ execSync3(`gh pr checkout ${prRef}`, { stdio: "pipe" });
7140
+ execSync3(`git checkout "${currentBranch}"`, { stdio: "pipe" });
7141
+ return true;
7142
+ } catch {
7143
+ try {
7144
+ execSync3(`git checkout "${currentBranch}"`, { stdio: "pipe" });
7145
+ } catch {
7112
7146
  }
7113
- console.log();
7114
7147
  }
7115
- if (!branchExists(branch)) {
7116
- console.error(`Error: branch '${branch}' not found`);
7117
- process.exit(1);
7148
+ try {
7149
+ execSync3(`git fetch origin pull/${prInfo.number}/head:${prInfo.headRefName}`, { stdio: "pipe" });
7150
+ return true;
7151
+ } catch {
7152
+ return false;
7118
7153
  }
7154
+ }
7155
+ function openBranch(branch, prNumber) {
7119
7156
  const parentBranch = getCurrentBranch();
7157
+ const mainWorktree = getMainWorktree();
7120
7158
  const existingWorktreePath = getWorktreeForBranch(branch);
7121
7159
  if (existingWorktreePath) {
7122
7160
  const worktreeId2 = getWorktreeId(existingWorktreePath);
7123
- const mainWorktree2 = getMainWorktree();
7124
7161
  console.log();
7125
- console.log(success(bold(branch)), dim(`(existing worktree)`));
7162
+ if (prNumber) {
7163
+ console.log(success(bold(`PR #${prNumber}`)), dim(`branch: ${cyan(branch)} (existing worktree)`));
7164
+ } else {
7165
+ console.log(success(bold(branch)), dim(`(existing worktree)`));
7166
+ }
7126
7167
  console.log(dim("Type 'wk close' to return."));
7127
7168
  console.log();
7128
7169
  spawnShell(existingWorktreePath, {
7129
7170
  branch,
7130
7171
  worktreePath: existingWorktreePath,
7131
- repoPath: mainWorktree2
7172
+ repoPath: mainWorktree
7132
7173
  });
7133
7174
  console.log();
7134
7175
  console.log(success(`Back in ${bold(parentBranch)}`));
@@ -7138,7 +7179,6 @@ function openCommand(branch) {
7138
7179
  return;
7139
7180
  }
7140
7181
  const store = loadStore();
7141
- const mainWorktree = getMainWorktree();
7142
7182
  const repoName = basename4(mainWorktree);
7143
7183
  const worktreeId = `${repoName}@${slugify(branch)}`;
7144
7184
  const worktreePath = join4(getWorktreesDir(), worktreeId);
@@ -7150,8 +7190,13 @@ function openCommand(branch) {
7150
7190
  });
7151
7191
  saveStore(store);
7152
7192
  console.log();
7153
- console.log(success(bold(branch)));
7154
- console.log(dim(`Opened branch in ephemeral subshell`));
7193
+ if (prNumber) {
7194
+ console.log(success(bold(`PR #${prNumber}`)), dim(`branch: ${cyan(branch)}`));
7195
+ console.log(dim(`Opened PR in ephemeral subshell`));
7196
+ } else {
7197
+ console.log(success(bold(branch)));
7198
+ console.log(dim(`Opened branch in ephemeral subshell`));
7199
+ }
7155
7200
  console.log(dim("Type 'exit' or 'wk close' to return."));
7156
7201
  console.log();
7157
7202
  spawnShell(worktreePath, {
@@ -7165,6 +7210,55 @@ function openCommand(branch) {
7165
7210
  autoCleanupWorktree(worktreeId, worktreePath, currentStore, saveStore);
7166
7211
  console.log();
7167
7212
  }
7213
+ function openCommand(ref) {
7214
+ if (isInsideWorktree()) {
7215
+ const currentBranch = getCurrentBranch();
7216
+ console.log();
7217
+ console.log(warn(`You're inside a worktree (branch: ${cyan(currentBranch)})`));
7218
+ console.log(` This will nest subshells (subshell inside subshell).`);
7219
+ console.log();
7220
+ if (!confirm("Continue?")) {
7221
+ process.exit(0);
7222
+ }
7223
+ console.log();
7224
+ }
7225
+ if (branchExists(ref)) {
7226
+ openBranch(ref);
7227
+ return;
7228
+ }
7229
+ if (!isGhInstalled()) {
7230
+ console.error(fail(`Branch '${ref}' not found.`));
7231
+ console.error(dim(" Install GitHub CLI (gh) to open PRs: https://cli.github.com/"));
7232
+ process.exit(1);
7233
+ }
7234
+ if (!isGhAuthenticated()) {
7235
+ console.error(fail(`Branch '${ref}' not found.`));
7236
+ console.error(dim(" Run 'gh auth login' to open PRs from GitHub."));
7237
+ process.exit(1);
7238
+ }
7239
+ const prInfo = getPRInfo(ref);
7240
+ if (!prInfo) {
7241
+ console.error(fail(`'${ref}' is not a local branch or GitHub PR.`));
7242
+ process.exit(1);
7243
+ }
7244
+ const branch = prInfo.headRefName;
7245
+ const prNumber = prInfo.number;
7246
+ if (branchExists(branch)) {
7247
+ console.log(dim(`PR #${prNumber} \u2192 ${branch}`));
7248
+ openBranch(branch, prNumber);
7249
+ return;
7250
+ }
7251
+ console.log(dim(`Fetching PR #${prNumber}...`));
7252
+ if (!fetchPRBranch(ref, prInfo)) {
7253
+ console.error(fail(`Failed to fetch branch '${branch}' for PR #${prNumber}`));
7254
+ process.exit(1);
7255
+ }
7256
+ if (!branchExists(branch)) {
7257
+ console.error(fail(`Failed to fetch branch '${branch}' for PR #${prNumber}`));
7258
+ process.exit(1);
7259
+ }
7260
+ openBranch(branch, prNumber);
7261
+ }
7168
7262
 
7169
7263
  // commands/ls.ts
7170
7264
  var import_table = __toESM(require_src(), 1);
@@ -8015,7 +8109,7 @@ function lsCommand(plain = false) {
8015
8109
  }
8016
8110
 
8017
8111
  // commands/rm.ts
8018
- import { execSync as execSync3 } from "child_process";
8112
+ import { execSync as execSync4 } from "child_process";
8019
8113
  import { resolve as resolve2 } from "path";
8020
8114
  function rmCommand(branch, force = false) {
8021
8115
  const mainWorktree = getMainWorktree();
@@ -8046,8 +8140,8 @@ function rmCommand(branch, force = false) {
8046
8140
  }
8047
8141
  if (isDirty && force) {
8048
8142
  try {
8049
- execSync3(`git -C "${worktreePath}" reset --hard HEAD`, { stdio: "ignore" });
8050
- execSync3(`git -C "${worktreePath}" clean -fd`, { stdio: "ignore" });
8143
+ execSync4(`git -C "${worktreePath}" reset --hard HEAD`, { stdio: "ignore" });
8144
+ execSync4(`git -C "${worktreePath}" clean -fd`, { stdio: "ignore" });
8051
8145
  } catch {
8052
8146
  }
8053
8147
  }
@@ -8065,7 +8159,7 @@ function rmCommand(branch, force = false) {
8065
8159
  }
8066
8160
 
8067
8161
  // commands/status.ts
8068
- import { execSync as execSync4 } from "child_process";
8162
+ import { execSync as execSync5 } from "child_process";
8069
8163
  import { existsSync as existsSync4, readdirSync as readdirSync3 } from "fs";
8070
8164
  import { resolve as resolve3 } from "path";
8071
8165
  function getDetailedStatus(path) {
@@ -8073,7 +8167,7 @@ function getDetailedStatus(path) {
8073
8167
  return [];
8074
8168
  }
8075
8169
  try {
8076
- const status = execSync4(`git -C "${path}" status --short`, { encoding: "utf-8" }).trim();
8170
+ const status = execSync5(`git -C "${path}" status --short`, { encoding: "utf-8" }).trim();
8077
8171
  if (!status) {
8078
8172
  return [];
8079
8173
  }
@@ -8139,17 +8233,17 @@ function statusCommand() {
8139
8233
  }
8140
8234
 
8141
8235
  // commands/preclose.ts
8142
- import { execSync as execSync5 } from "child_process";
8236
+ import { execSync as execSync6 } from "child_process";
8143
8237
  function precloseCommand(force) {
8144
8238
  if (!hasUncommittedChanges()) {
8145
8239
  process.exit(0);
8146
8240
  }
8147
8241
  if (force) {
8148
8242
  try {
8149
- execSync5("git reset --hard HEAD", { stdio: "ignore" });
8150
- execSync5("git clean -ffd", { stdio: "ignore" });
8151
- execSync5("git submodule foreach --recursive 'git reset --hard HEAD; git clean -ffd'", { stdio: "ignore" });
8152
- execSync5("git submodule update --init --recursive --force", { stdio: "ignore" });
8243
+ execSync6("git reset --hard HEAD", { stdio: "ignore" });
8244
+ execSync6("git clean -ffd", { stdio: "ignore" });
8245
+ execSync6("git submodule foreach --recursive 'git reset --hard HEAD; git clean -ffd'", { stdio: "ignore" });
8246
+ execSync6("git submodule update --init --recursive --force", { stdio: "ignore" });
8153
8247
  } catch {
8154
8248
  }
8155
8249
  process.exit(0);
@@ -8221,162 +8315,8 @@ function promptChoice() {
8221
8315
  }
8222
8316
  }
8223
8317
 
8224
- // commands/pr.ts
8225
- import { execSync as execSync6 } from "child_process";
8226
- import { mkdirSync as mkdirSync5 } from "fs";
8227
- import { basename as basename5, dirname as dirname5, join as join6 } from "path";
8228
- function checkGhInstalled() {
8229
- try {
8230
- execSync6("gh --version", { stdio: "pipe", encoding: "utf-8" });
8231
- } catch {
8232
- console.error(fail("GitHub CLI (gh) is not installed."));
8233
- console.error(dim(" Install it from: https://cli.github.com/"));
8234
- process.exit(1);
8235
- }
8236
- }
8237
- function checkGhAuthenticated() {
8238
- try {
8239
- execSync6("gh auth status", { stdio: "pipe", encoding: "utf-8" });
8240
- } catch {
8241
- console.error(fail("Not authenticated with GitHub CLI."));
8242
- console.error(dim(" Run: gh auth login"));
8243
- process.exit(1);
8244
- }
8245
- }
8246
- function getPRInfo(prRef) {
8247
- try {
8248
- const output = execSync6(
8249
- `gh pr view ${prRef} --json number,headRefName,headRepository,headRepositoryOwner,isCrossRepository`,
8250
- { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
8251
- );
8252
- return JSON.parse(output);
8253
- } catch (err) {
8254
- const message = err instanceof Error && "stderr" in err ? err.stderr : String(err);
8255
- if (message.includes("Could not resolve")) {
8256
- console.error(fail(`PR '${prRef}' not found.`));
8257
- console.error(dim(" Make sure you're in a GitHub repository and the PR exists."));
8258
- } else if (message.includes("no pull requests found")) {
8259
- console.error(fail(`No pull request found for '${prRef}'.`));
8260
- } else {
8261
- console.error(fail(`Failed to get PR info: ${message}`));
8262
- }
8263
- process.exit(1);
8264
- }
8265
- }
8266
- function fetchPRBranch(prRef, prInfo) {
8267
- try {
8268
- execSync6(`git fetch origin ${prInfo.headRefName}:${prInfo.headRefName}`, { stdio: "pipe" });
8269
- return;
8270
- } catch {
8271
- }
8272
- const currentBranch = getCurrentBranch();
8273
- try {
8274
- execSync6(`gh pr checkout ${prRef}`, { stdio: "pipe" });
8275
- execSync6(`git checkout "${currentBranch}"`, { stdio: "pipe" });
8276
- return;
8277
- } catch {
8278
- try {
8279
- execSync6(`git checkout "${currentBranch}"`, { stdio: "pipe" });
8280
- } catch {
8281
- }
8282
- }
8283
- try {
8284
- execSync6(`git fetch origin pull/${prInfo.number}/head:${prInfo.headRefName}`, { stdio: "pipe" });
8285
- return;
8286
- } catch (fetchErr) {
8287
- const message = fetchErr instanceof Error ? fetchErr.message : String(fetchErr);
8288
- console.error(fail(`Failed to fetch PR branch: ${message}`));
8289
- process.exit(1);
8290
- }
8291
- }
8292
- function branchExistsLocally(branch) {
8293
- try {
8294
- execSync6(`git show-ref --verify --quiet refs/heads/${branch}`);
8295
- return true;
8296
- } catch {
8297
- return false;
8298
- }
8299
- }
8300
- function createWorktreeForPR(branch, path) {
8301
- execSync6(`git worktree add "${path}" "${branch}"`, { stdio: "ignore" });
8302
- }
8303
- function prOpenCommand(prRef) {
8304
- checkGhInstalled();
8305
- checkGhAuthenticated();
8306
- const prInfo = getPRInfo(prRef);
8307
- const branch = prInfo.headRefName;
8308
- const prNumber = prInfo.number;
8309
- if (isInsideWorktree()) {
8310
- const currentBranch = getCurrentBranch();
8311
- console.log();
8312
- console.log(warn(`You're inside a worktree (branch: ${cyan(currentBranch)})`));
8313
- console.log(` This will nest subshells (subshell inside subshell).`);
8314
- console.log();
8315
- if (!confirm("Continue?")) {
8316
- process.exit(0);
8317
- }
8318
- console.log();
8319
- }
8320
- const parentBranch = getCurrentBranch();
8321
- const existingWorktreePath = getWorktreeForBranch(branch);
8322
- if (existingWorktreePath) {
8323
- const worktreeId2 = getWorktreeId(existingWorktreePath);
8324
- const mainWorktree2 = getMainWorktree();
8325
- console.log();
8326
- console.log(success(bold(`PR #${prNumber}`)), dim(`branch: ${cyan(branch)} (existing worktree)`));
8327
- console.log(dim("Type 'wk close' to return."));
8328
- console.log();
8329
- spawnShell(existingWorktreePath, {
8330
- branch,
8331
- worktreePath: existingWorktreePath,
8332
- repoPath: mainWorktree2
8333
- });
8334
- console.log();
8335
- console.log(success(`Back in ${bold(parentBranch)}`));
8336
- const currentStore2 = loadStore();
8337
- autoCleanupWorktree(worktreeId2, existingWorktreePath, currentStore2, saveStore);
8338
- console.log();
8339
- return;
8340
- }
8341
- if (!branchExistsLocally(branch)) {
8342
- console.log(dim(`Fetching PR #${prNumber}...`));
8343
- fetchPRBranch(prRef, prInfo);
8344
- }
8345
- if (!branchExistsLocally(branch)) {
8346
- console.error(fail(`Failed to fetch branch '${branch}' for PR #${prNumber}`));
8347
- process.exit(1);
8348
- }
8349
- const store = loadStore();
8350
- const mainWorktree = getMainWorktree();
8351
- const repoName = basename5(mainWorktree);
8352
- const worktreeId = `${repoName}@${slugify(branch)}`;
8353
- const worktreePath = join6(getWorktreesDir(), worktreeId);
8354
- mkdirSync5(dirname5(worktreePath), { recursive: true });
8355
- createWorktreeForPR(branch, worktreePath);
8356
- initSubmodules(worktreePath);
8357
- setWorktreeMeta(store, worktreeId, {
8358
- created_at: (/* @__PURE__ */ new Date()).toISOString()
8359
- });
8360
- saveStore(store);
8361
- console.log();
8362
- console.log(success(bold(`PR #${prNumber}`)), dim(`branch: ${cyan(branch)}`));
8363
- console.log(dim(`Opened PR in ephemeral subshell`));
8364
- console.log(dim("Type 'exit' or 'wk close' to return."));
8365
- console.log();
8366
- spawnShell(worktreePath, {
8367
- branch,
8368
- worktreePath,
8369
- repoPath: mainWorktree
8370
- });
8371
- console.log();
8372
- console.log(success(`Back in ${bold(parentBranch)}`));
8373
- const currentStore = loadStore();
8374
- autoCleanupWorktree(worktreeId, worktreePath, currentStore, saveStore);
8375
- console.log();
8376
- }
8377
-
8378
8318
  // index.ts
8379
- var VERSION = "0.1.0";
8319
+ var VERSION = "0.2.0";
8380
8320
  function printHelp() {
8381
8321
  const dim2 = import_picocolors4.default.dim;
8382
8322
  const cyan2 = import_picocolors4.default.cyan;
@@ -8387,8 +8327,7 @@ ${import_picocolors4.default.bold("Usage:")} ${cyan2("wk")} ${dim2("<command>")}
8387
8327
 
8388
8328
  ${import_picocolors4.default.bold("Commands:")}
8389
8329
  ${green2("new")} ${dim2("[branch]")} Create a branch and open it ${dim2("[--from <branch>]")}
8390
- ${green2("open")} ${dim2("<branch>")} Open a branch in an ephemeral subshell
8391
- ${green2("pr open")} ${dim2("<ref>")} Open a GitHub PR in an ephemeral subshell
8330
+ ${green2("open")} ${dim2("<ref>")} Open a branch or PR in an ephemeral subshell
8392
8331
  ${green2("close")} Exit current subshell
8393
8332
  ${green2("ls")} List open branches
8394
8333
  ${green2("status")} Show current branch
@@ -8453,15 +8392,24 @@ ${import_picocolors4.default.bold("Description:")}
8453
8392
  function printOpenHelp() {
8454
8393
  const dim2 = import_picocolors4.default.dim;
8455
8394
  const cyan2 = import_picocolors4.default.cyan;
8456
- console.log(`${import_picocolors4.default.bold("wk open")} - Open a branch in an ephemeral subshell
8395
+ console.log(`${import_picocolors4.default.bold("wk open")} - Open a branch or PR in an ephemeral subshell
8457
8396
 
8458
- ${import_picocolors4.default.bold("Usage:")} ${cyan2("wk open")} ${dim2("<branch>")}
8397
+ ${import_picocolors4.default.bold("Usage:")} ${cyan2("wk open")} ${dim2("<ref>")}
8459
8398
 
8460
8399
  ${import_picocolors4.default.bold("Arguments:")}
8461
- ${dim2("<branch>")} Branch name ${dim2("(required)")}
8400
+ ${dim2("<ref>")} Branch name, PR number, or PR URL ${dim2("(required)")}
8401
+
8402
+ ${import_picocolors4.default.bold("Examples:")}
8403
+ ${dim2("$")} ${cyan2("wk open feature-branch")} ${dim2("# Open local branch")}
8404
+ ${dim2("$")} ${cyan2("wk open 123")} ${dim2("# Open PR #123")}
8405
+ ${dim2("$")} ${cyan2("wk open https://github.com/o/r/pull/123")}
8462
8406
 
8463
8407
  ${import_picocolors4.default.bold("Description:")}
8464
- Opens the specified branch in an ephemeral subshell.
8408
+ Opens the specified ref in an ephemeral subshell.
8409
+
8410
+ First tries to open as a local branch. If not found, tries to fetch
8411
+ as a GitHub PR (requires gh CLI to be installed and authenticated).
8412
+
8465
8413
  If a worktree already exists for the branch, uses that.
8466
8414
  Otherwise, creates a new worktree automatically.
8467
8415
  Type 'wk close' to return.`);
@@ -8544,51 +8492,6 @@ ${import_picocolors4.default.bold("Config locations")} ${dim2("(in precedence or
8544
8492
  ${cyan2(".git/workshell.toml")} Local only, not committed
8545
8493
  ${cyan2("workshell.toml")} Project root, can be committed`);
8546
8494
  }
8547
- function printPrHelp() {
8548
- const dim2 = import_picocolors4.default.dim;
8549
- const cyan2 = import_picocolors4.default.cyan;
8550
- console.log(`${import_picocolors4.default.bold("wk pr")} - Work with GitHub Pull Requests
8551
-
8552
- ${import_picocolors4.default.bold("Usage:")} ${cyan2("wk pr")} ${dim2("<subcommand>")} ${dim2("[options]")}
8553
-
8554
- ${import_picocolors4.default.bold("Subcommands:")}
8555
- ${cyan2("open")} ${dim2("<ref>")} Open a PR in an ephemeral subshell
8556
-
8557
- ${import_picocolors4.default.bold("Examples:")}
8558
- ${dim2("$")} ${cyan2("wk pr open 123")} ${dim2("# Open PR by number")}
8559
- ${dim2("$")} ${cyan2("wk pr open https://github.com/o/r/pull/123")} ${dim2("# Open PR by URL")}
8560
-
8561
- ${import_picocolors4.default.bold("Requirements:")}
8562
- Requires GitHub CLI (gh) to be installed and authenticated.
8563
- ${dim2("Install: https://cli.github.com/")}
8564
- ${dim2("Auth: gh auth login")}`);
8565
- }
8566
- function printPrOpenHelp() {
8567
- const dim2 = import_picocolors4.default.dim;
8568
- const cyan2 = import_picocolors4.default.cyan;
8569
- console.log(`${import_picocolors4.default.bold("wk pr open")} - Open a GitHub PR in an ephemeral subshell
8570
-
8571
- ${import_picocolors4.default.bold("Usage:")} ${cyan2("wk pr open")} ${dim2("<ref>")}
8572
-
8573
- ${import_picocolors4.default.bold("Arguments:")}
8574
- ${dim2("<ref>")} PR number, URL, or branch name ${dim2("(required)")}
8575
-
8576
- ${import_picocolors4.default.bold("Examples:")}
8577
- ${dim2("$")} ${cyan2("wk pr open 123")}
8578
- ${dim2("$")} ${cyan2("wk pr open https://github.com/owner/repo/pull/123")}
8579
- ${dim2("$")} ${cyan2("wk pr open feature-branch")}
8580
-
8581
- ${import_picocolors4.default.bold("Description:")}
8582
- Fetches the PR branch and opens it in an ephemeral subshell.
8583
- If a worktree already exists for the branch, uses that.
8584
- Otherwise, creates a new worktree automatically.
8585
- Type 'wk close' to return.
8586
-
8587
- ${import_picocolors4.default.bold("Requirements:")}
8588
- Requires GitHub CLI (gh) to be installed and authenticated.
8589
- ${dim2("Install: https://cli.github.com/")}
8590
- ${dim2("Auth: gh auth login")}`);
8591
- }
8592
8495
  function isHelp(arg) {
8593
8496
  return arg === "--help" || arg === "-h";
8594
8497
  }
@@ -8630,7 +8533,7 @@ switch (cmd) {
8630
8533
  process.exit(0);
8631
8534
  }
8632
8535
  if (!args[1]) {
8633
- console.error("Usage: wk open <branch>");
8536
+ console.error("Usage: wk open <branch|pr-number|pr-url>");
8634
8537
  process.exit(1);
8635
8538
  }
8636
8539
  openCommand(args[1]);
@@ -8667,29 +8570,6 @@ switch (cmd) {
8667
8570
  }
8668
8571
  configCommand();
8669
8572
  break;
8670
- case "pr": {
8671
- const subCmd = args[1];
8672
- if (!subCmd || isHelp(subCmd)) {
8673
- printPrHelp();
8674
- process.exit(0);
8675
- }
8676
- if (subCmd === "open") {
8677
- if (isHelp(args[2])) {
8678
- printPrOpenHelp();
8679
- process.exit(0);
8680
- }
8681
- if (!args[2]) {
8682
- console.error("Usage: wk pr open <pr-number|url|branch>");
8683
- process.exit(1);
8684
- }
8685
- prOpenCommand(args[2]);
8686
- } else {
8687
- console.error(`Unknown pr subcommand: ${subCmd}`);
8688
- console.error("Run 'wk pr --help' for usage.");
8689
- process.exit(1);
8690
- }
8691
- break;
8692
- }
8693
8573
  case "close":
8694
8574
  if (isHelp(args[1])) {
8695
8575
  printCloseHelp();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workshell",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Agent- and human-friendly Git multitasking, powered by worktrees",
5
5
  "type": "module",
6
6
  "license": "MIT",