opencode-worktree 0.3.1 → 0.3.2

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.
@@ -5,7 +5,6 @@ import path from 'node:path';
5
5
  import os from 'node:os';
6
6
  import { spawn } from 'node:child_process';
7
7
  import { fileURLToPath } from 'node:url';
8
- import updateNotifier from 'update-notifier';
9
8
 
10
9
  const __filename = fileURLToPath(import.meta.url);
11
10
  const __dirname = path.dirname(__filename);
@@ -13,8 +12,6 @@ const pkg = JSON.parse(
13
12
  fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8'),
14
13
  );
15
14
 
16
- updateNotifier({ pkg }).notify({ isGlobal: true });
17
-
18
15
  const detectPlatformAndArch = () => {
19
16
  let platform;
20
17
  switch (os.platform()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-worktree",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "TUI for managing git worktrees with opencode integration.",
@@ -48,6 +48,7 @@
48
48
  "devDependencies": {
49
49
  "@types/bun": "^1.2.0",
50
50
  "@types/node": "^24.2.0",
51
+ "@types/update-notifier": "^6.0.8",
51
52
  "typescript": "^5.9.3"
52
53
  }
53
54
  }
package/script/build.ts CHANGED
@@ -107,6 +107,8 @@ const buildBinary = async (target: Target) => {
107
107
  OTUI_TREE_SITTER_WORKER_PATH: JSON.stringify(
108
108
  bunfsRoot + workerRelativePath,
109
109
  ),
110
+ __PACKAGE_VERSION__: JSON.stringify(version),
111
+ __PACKAGE_NAME__: JSON.stringify(packageName),
110
112
  },
111
113
  });
112
114
  } catch (error) {
package/src/cli.ts CHANGED
@@ -1,9 +1,19 @@
1
1
  import { runApp } from "./ui.js";
2
2
 
3
+ // Build-time injected constants (defined in script/build.ts)
4
+ // Use typeof check to provide fallbacks for dev mode (bun run dev)
5
+ declare const __PACKAGE_VERSION__: string | undefined;
6
+ declare const __PACKAGE_NAME__: string | undefined;
7
+
8
+ const pkg = {
9
+ name: typeof __PACKAGE_NAME__ !== "undefined" ? __PACKAGE_NAME__ : "opencode-worktree",
10
+ version: typeof __PACKAGE_VERSION__ !== "undefined" ? __PACKAGE_VERSION__ : "dev",
11
+ };
12
+
3
13
  // Accept optional path argument: opencode-worktree [path]
4
14
  const targetPath = process.argv[2] || process.cwd();
5
15
 
6
- runApp(targetPath).catch((error: unknown) => {
16
+ runApp(targetPath, pkg).catch((error: unknown) => {
7
17
  console.error("Failed to start OpenTUI worktree selector.");
8
18
  console.error(error);
9
19
  process.exit(1);
package/src/ui.ts CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  type KeyEvent,
11
11
  type SelectOption,
12
12
  } from "@opentui/core";
13
+ import updateNotifier from "update-notifier";
13
14
  import { basename } from "node:path";
14
15
  import {
15
16
  createWorktree,
@@ -45,14 +46,22 @@ const CONFIRM_UNLINK_VALUE: ConfirmAction = "unlink";
45
46
  const CONFIRM_DELETE_VALUE: ConfirmAction = "delete";
46
47
  const CONFIRM_CANCEL_VALUE: ConfirmAction = "cancel";
47
48
 
48
- export const runApp = async (targetPath: string): Promise<void> => {
49
+ export type PackageInfo = {
50
+ name: string;
51
+ version: string;
52
+ };
53
+
54
+ export const runApp = async (
55
+ targetPath: string,
56
+ pkg?: PackageInfo,
57
+ ): Promise<void> => {
49
58
  const renderer = await createCliRenderer({
50
59
  exitOnCtrlC: false,
51
60
  targetFps: 30,
52
61
  });
53
62
 
54
63
  renderer.setBackgroundColor("transparent");
55
- new WorktreeSelector(renderer, targetPath);
64
+ new WorktreeSelector(renderer, targetPath, pkg);
56
65
  };
57
66
 
58
67
  class WorktreeSelector {
@@ -60,6 +69,7 @@ class WorktreeSelector {
60
69
  private statusText: TextRenderable;
61
70
  private instructions: TextRenderable;
62
71
  private title: TextRenderable;
72
+ private versionNotice: TextRenderable | null = null;
63
73
 
64
74
  private inputContainer: BoxRenderable | null = null;
65
75
  private branchInput: InputRenderable | null = null;
@@ -99,6 +109,7 @@ class WorktreeSelector {
99
109
  constructor(
100
110
  private renderer: CliRenderer,
101
111
  private targetPath: string,
112
+ private pkg?: PackageInfo,
102
113
  ) {
103
114
  // Load worktrees first to get initial options
104
115
  this.repoRoot = resolveRepoRoot(this.targetPath);
@@ -115,6 +126,34 @@ class WorktreeSelector {
115
126
  });
116
127
  this.renderer.root.add(this.title);
117
128
 
129
+ // Display version or update notification in title line
130
+ if (this.pkg) {
131
+ const notifier = updateNotifier({ pkg: this.pkg });
132
+
133
+ let noticeContent: string;
134
+ let noticeColor: string;
135
+
136
+ if (notifier.update) {
137
+ // Update available
138
+ noticeContent = `Update: ${notifier.update.current} → ${notifier.update.latest} (npm i -g)`;
139
+ noticeColor = "#F59E0B"; // Amber
140
+ } else {
141
+ // On latest version
142
+ noticeContent = `v${this.pkg.version}`;
143
+ noticeColor = "#64748B"; // Subtle gray
144
+ }
145
+
146
+ this.versionNotice = new TextRenderable(renderer, {
147
+ id: "version-notice",
148
+ position: "absolute",
149
+ left: 78 - noticeContent.length,
150
+ top: 1,
151
+ content: noticeContent,
152
+ fg: noticeColor,
153
+ });
154
+ this.renderer.root.add(this.versionNotice);
155
+ }
156
+
118
157
  this.selectElement = new SelectRenderable(renderer, {
119
158
  id: "worktree-selector",
120
159
  position: "absolute",