opencode-manager 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 OpenCode contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,188 @@
1
+ OpenCode Metadata Manager — Project Summary
2
+ ==========================================
3
+
4
+ Overview
5
+ --------
6
+ - Purpose: Inspect, filter, and clean OpenCode metadata stored on disk.
7
+ - Scope: Lists projects and sessions from local storage; supports filtering, search, interactive selection and deletion, and quick navigation between views.
8
+ - UI: Terminal UI built with @opentui/react.
9
+
10
+ Architecture
11
+ ------------
12
+ - Entry: `opencode/src/opencode-tui.tsx` — main TUI app and panels.
13
+ - Data layer: `opencode/src/lib/opencode-data.ts` — reads/writes metadata JSON, computes derived fields, formatting helpers.
14
+ - Scripts: `opencode/package.json` → `bun run tui` runs the app.
15
+ - CLI wrapper: `opencode/manage_opencode_projects.py` preserves the legacy entry point, resolves Bun (`--bun` overrides PATH), sets `--root` (defaults to `~/.local/share/opencode`), and forwards any extra args after `--` directly to the TUI.
16
+ - Spec diff script: `opencode/opencode-gen.sh` shells out to `opencode generate`, saves the JSON spec under `~/repos/research/opencode/opencode-<version>-spec.json`, and diffs it against the previous snapshot (prefers `delta`, falls back to `diff`).
17
+
18
+ Metadata Layout & Helpers
19
+ -------------------------
20
+ - Storage root: `DEFAULT_ROOT` is `~/.local/share/opencode`; CLI `--root` values are resolved via `path.resolve` so relative paths and `~` are accepted.
21
+ - Projects: metadata files live under `storage/project` and `storage/sessions`. `loadProjectRecords` walks both buckets, parses timestamps, expands `~`-style worktree paths, and determines `state` by stat-ing the directory so missing projects are surfaced inline.
22
+ - Sessions: JSON files live under `storage/session/<projectId>/`. Records capture `title`, `version`, and both `createdAt`/`updatedAt` stamps; the loader can filter by `projectId` (used by the Sessions tab) and sorts primarily by the active timestamp (updated when available, else created).
23
+ - Formatting/utilities: `formatDisplayPath` shortens paths back to `~`, `formatDate` handles null-safe rendering, and `describeProject`/`describeSession` feed human-readable previews to confirm dialogs.
24
+ - Destructive actions: `deleteProjectMetadata`/`deleteSessionMetadata` accept optional `dryRun` flags, record successes/failures per file, and `ensureDirectory` is available for future write paths.
25
+
26
+ Key Features
27
+ ------------
28
+ - Projects panel
29
+ - Shows project path in the list (more human-friendly than IDs).
30
+ - Details pane shows project ID, VCS, created time, and full path.
31
+ - Missing-only toggle and bulk selection.
32
+ - Sessions panel
33
+ - Shows session title (or falls back to ID) in the list.
34
+ - Sort toggle (S) between “updated” and “created”.
35
+ - Each row shows a timestamp snippet for the active sort (created/updated).
36
+ - Details pane includes title, project ID, updated time, and directory.
37
+ - Projects ↔ Sessions workflow
38
+ - Pressing Enter on a project jumps to the Sessions tab with the project filter set; status text confirms the active filter.
39
+ - `C` clears the filter (and notifies the user) so global searches go back to all sessions.
40
+ - Global search (for current tab)
41
+ - Search box (/) captures input without conflicting with shortcuts; Enter applies, Esc clears, X also clears when not in search mode.
42
+ - Projects: matches project ID or directory path.
43
+ - Sessions: matches title, session ID, directory path, or project ID.
44
+ - Help screen
45
+ - Two-column, color-coded quick reference with “key chips”.
46
+ - Clear grouping by Global, Projects, Sessions, Tips.
47
+ - Status & confirmation bars
48
+ - Status bar tint reflects `info` vs `error` states so reload/deletion feedback is obvious.
49
+ - Confirmation bar shows up to five pending records (project/session descriptors) and states “Y/Enter confirm, N/Esc cancel” while disabling panel shortcuts until resolved.
50
+
51
+ Work Completed
52
+ --------------
53
+ - Switched Projects list labels to show path instead of project ID; kept ID in the details panel.
54
+ - Sessions list uses session title prominently; added title to details; updated onSelect/Enter status lines to show title and ID.
55
+ - Redesigned Help screen into two columns with color-coded sections and key chips; removed wall-of-text effect.
56
+ - Added a small color palette and helper components (Section, Row, Bullet, Columns, KeyChip) to simplify consistent styling.
57
+ - Implemented a global Search bar and input mode:
58
+ - “/” to start, Enter to apply, Esc or “X” to clear.
59
+ - Projects: search `projectId` and `worktree`; Sessions: search `title`, `sessionId`, `directory`, `projectId`.
60
+ - Sessions sorting & context:
61
+ - “S” toggles sort by `updated`/`created`.
62
+ - Show per-row description with the relevant timestamp.
63
+ - Fixed OpenTUI text rendering error by filtering whitespace-only raw text in layout helpers and by removing nested `<text>` nodes around key chips.
64
+ - Verified via `bun run tui` (tmux socket creation is blocked in this environment, but direct run works).
65
+
66
+ How To Run
67
+ ----------
68
+ - Zero-install via npm: `bunx opencode-manager [--root /path/to/storage]` (preferred).
69
+ - Local dev: `bun run tui [-- --root /path/to/storage]`.
70
+ - Legacy launcher: `./manage_opencode_projects.py [--root PATH] [--bun /path/to/bun] [-- ...extra TUI args]` keeps older automation working while delegating to Bun.
71
+ - Keys:
72
+ - Global: `Tab`/`1`/`2` switch tabs, `/` search, `X` clear search, `R` reload, `Q` quit, `?` help
73
+ - Projects: `Space` select, `A` select all, `M` toggle missing, `D` delete, `Enter` view sessions
74
+ - Sessions: `Space` select, `S` sort, `D` delete, `C` clear project filter, `Enter` details
75
+ - Optional tmux usage (when permitted): `tmux new -s opencode-tui 'bun run tui'`
76
+ - CLI help: `bun run tui -- --help` (or `bunx opencode-manager -- --help`, or `manage_opencode_projects.py -- --help`) prints the built-in usage block with key bindings.
77
+
78
+ Packaging & Publish Checklist
79
+ -----------------------------
80
+ 1. Install dependencies with `bun install` (Bun v1.1+ only).
81
+ 2. Type-check via `bun run typecheck` (runs `tsc --noEmit`).
82
+ 3. Update the version in `package.json` as needed.
83
+ 4. Run `npm publish` (package exposes the Bun-native `opencode-manager` bin with public access).
84
+
85
+ Outstanding Recommendations (Not Yet Implemented)
86
+ -------------------------------------------------
87
+ - UI polish
88
+ - Colorize project state in list labels (e.g., green for present, red for missing, gray for unknown).
89
+ - Show a small timestamp snippet for Projects rows (created).
90
+ - Add tiny icons or color accents to distinguish created vs updated descriptions in Sessions.
91
+ - Add per-view mini legends with colored key chips under the panels (Projects/Sessions), consistent with the Help styling.
92
+ - Show filtered counts (e.g., “Showing X of Y”).
93
+ - Search enhancements
94
+ - Optional fuzzy matching; toggle to include/exclude `directory` in Sessions/Projects search for more control.
95
+ - Persist search and sort preferences per tab (and optionally per project filter) during the app run.
96
+ - Save last-used search/sort to a small state file and restore on next launch.
97
+ - Accessibility & layout
98
+ - Ensure all active/inactive/focused states have adequate contrast and consistent highlight styles.
99
+ - Provide a monochrome theme option for minimal terminals.
100
+ - Performance
101
+ - Debounce UI reactions to large search queries; short-circuit expensive filters when query is empty.
102
+ - Testing
103
+ - Add unit coverage for opencode-data helpers (formatting, parsing, sorting).
104
+ - Add basic snapshot/E2E tests for rendering key panels and Help using a headless renderer (if available for @opentui).
105
+ - Packaging/Docs
106
+ - Add a README section specific to the TUI tool, with a short demo, common actions, and troubleshooting.
107
+
108
+ Notes
109
+ -----
110
+ - The TUI uses the OpenTUI renderer’s constraint that all textual content must be inside a `<text>` node; helpers now filter whitespace-only string children to avoid runtime errors.
111
+ - The environment here blocks tmux sockets under `/tmp`; running directly with `bun run tui` is fine. In normal shells, tmux can be used for convenience.
112
+
113
+ ASCII Snapshots
114
+ ---------------
115
+ The following mockups illustrate the current UI layout and labels. Colors are omitted in ASCII; key chips like `[Q]` or `[Enter]` are literal.
116
+
117
+ Projects (path-first labels, details on the right)
118
+ ```
119
+ Tabs: [1] Projects [2] Sessions | Active: projects | Global: Tab switch, / search, X clear, R reload, Q quit, ? help
120
+
121
+ ┌──────────────────────────────── Projects ────────────────────────────────┐
122
+ │ Filter: all │
123
+ │ Total: 12 | Missing: 1 | Selected: 2 │
124
+ │ Keys: Space select, A select all, M toggle missing, D delete, Enter... │
125
+ │ │
126
+ │ [*] #1 ~/work/app │
127
+ │ [ ] #2 ~/work/tools/opencode │
128
+ │ [ ] #3 ~/work/svc/auth │
129
+ │ [ ] #4 ~/work/svc/payments (missing) │
130
+ │ ... │
131
+ │ │
132
+ │ ┌────────────── Details ───────────────┐ │
133
+ │ │ Project: app State: present │ │
134
+ │ │ Bucket: project VCS: git │ │
135
+ │ │ Created: 2025-11-08 12:41 │ │
136
+ │ │ Path: │ │
137
+ │ │ /home/user/work/app │ │
138
+ │ └──────────────────────────────────────┘ │
139
+ └──────────────────────────────────────────────────────────────────────────┘
140
+ ```
141
+
142
+ Sessions (title-first labels, sort snippet per row, search + filter header)
143
+ ```
144
+ Tabs: [1] Projects [2] Sessions | Active: sessions | Global: Tab switch, / search, X clear, R reload, Q quit, ? help
145
+
146
+ Search (sessions): /fix oauth — Enter apply • Esc clear
147
+
148
+ ┌──────────────────────────────── Sessions ───────────────────────────────┐
149
+ │ Filter: project app | Sort: updated | Search: fix oauth | Selected: 0 │
150
+ │ Keys: Space select, S sort, D delete, C clear filter, Enter details... │
151
+ │ │
152
+ │ [ ] #1 Fix OAuth callback handling (v1.3.0) updated: 2025-11-08 14:02 │
153
+ │ [ ] #2 Improve login UX (v1.2.9) updated: 2025-11-08 13:21 │
154
+ │ [ ] #3 Add metrics to auth (v1.2.8) updated: 2025-11-07 19:44 │
155
+ │ ... │
156
+ │ │
157
+ │ ┌────────────── Details ───────────────┐ │
158
+ │ │ Session: sess_2 Version: v1.2.9 │ │
159
+ │ │ Title: Improve login UX │ │
160
+ │ │ Project: app │ │
161
+ │ │ Updated: 2025-11-08 13:21 │ │
162
+ │ │ Directory: │ │
163
+ │ │ /home/user/work/app │ │
164
+ │ └──────────────────────────────────────┘ │
165
+ └──────────────────────────────────────────────────────────────────────────┘
166
+ ```
167
+
168
+ Help Screen (two columns with key chips, reduced wall-of-text)
169
+ ```
170
+ ┌────────────────────────────── Help ─────────────────────────────────────┐
171
+ │ Quick reference for keys and actions │
172
+ │ │
173
+ │ ┌─Global──────────────────────────┐ ┌─Sessions──────────────────────┐ │
174
+ │ │ • [Tab]/[1]/[2] — Switch tabs │ │ • Move: [Up]/[Down] │ │
175
+ │ │ • [/] — start search, [X] clear │ │ • Select: [Space] │ │
176
+ │ │ • [R] — Reload active view │ │ • Sort: [S] (updated/created) │ │
177
+ │ │ • [?]/[H] — Toggle help │ │ • Delete: [D] (confirm) │ │
178
+ │ │ • Quit: [Q] │ │ • Details: [Enter] │ │
179
+ │ └─────────────────────────────────┘ └────────────────────────────────┘ │
180
+ │ ┌─Projects────────────────────────┐ ┌─Tips───────────────────────────┐ │
181
+ │ │ • Move: [Up]/[Down] │ │ • Use [M] to isolate missing │ │
182
+ │ │ • Select: [Space] / [A] all │ │ • Press [R] to refresh │ │
183
+ │ │ • Filter missing: [M] │ │ • Dismiss help: [Enter]/[Esc] │ │
184
+ │ │ • Delete: [D] (confirm) │ └────────────────────────────────┘ │
185
+ │ │ • Open sessions: [Enter] │ │
186
+ │ └─────────────────────────────────┘ │
187
+ └──────────────────────────────────────────────────────────────────────────┘
188
+ ```
package/bun.lock ADDED
@@ -0,0 +1,217 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "workspaces": {
4
+ "": {
5
+ "name": "opencode-tools",
6
+ "dependencies": {
7
+ "@opentui/core": "^0.1.34",
8
+ "@opentui/react": "^0.1.34",
9
+ "react": "^19.0.0",
10
+ },
11
+ "devDependencies": {
12
+ "@types/node": "^22.8.5",
13
+ "@types/react": "^19.0.0",
14
+ "typescript": "^5.6.3",
15
+ },
16
+ },
17
+ },
18
+ "packages": {
19
+ "@dimforge/rapier2d-simd-compat": ["@dimforge/rapier2d-simd-compat@0.17.3", "", {}, "sha512-bijvwWz6NHsNj5e5i1vtd3dU2pDhthSaTUZSh14DUGGKJfw8eMnlWZsxwHBxB/a3AXVNDjL9abuHw1k9FGR+jg=="],
20
+
21
+ "@jimp/core": ["@jimp/core@1.6.0", "", { "dependencies": { "@jimp/file-ops": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "await-to-js": "^3.0.0", "exif-parser": "^0.1.12", "file-type": "^16.0.0", "mime": "3" } }, "sha512-EQQlKU3s9QfdJqiSrZWNTxBs3rKXgO2W+GxNXDtwchF3a4IqxDheFX1ti+Env9hdJXDiYLp2jTRjlxhPthsk8w=="],
22
+
23
+ "@jimp/diff": ["@jimp/diff@1.6.0", "", { "dependencies": { "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "pixelmatch": "^5.3.0" } }, "sha512-+yUAQ5gvRC5D1WHYxjBHZI7JBRusGGSLf8AmPRPCenTzh4PA+wZ1xv2+cYqQwTfQHU5tXYOhA0xDytfHUf1Zyw=="],
24
+
25
+ "@jimp/file-ops": ["@jimp/file-ops@1.6.0", "", {}, "sha512-Dx/bVDmgnRe1AlniRpCKrGRm5YvGmUwbDzt+MAkgmLGf+jvBT75hmMEZ003n9HQI/aPnm/YKnXjg/hOpzNCpHQ=="],
26
+
27
+ "@jimp/js-bmp": ["@jimp/js-bmp@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "bmp-ts": "^1.0.9" } }, "sha512-FU6Q5PC/e3yzLyBDXupR3SnL3htU7S3KEs4e6rjDP6gNEOXRFsWs6YD3hXuXd50jd8ummy+q2WSwuGkr8wi+Gw=="],
28
+
29
+ "@jimp/js-gif": ["@jimp/js-gif@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "gifwrap": "^0.10.1", "omggif": "^1.0.10" } }, "sha512-N9CZPHOrJTsAUoWkWZstLPpwT5AwJ0wge+47+ix3++SdSL/H2QzyMqxbcDYNFe4MoI5MIhATfb0/dl/wmX221g=="],
30
+
31
+ "@jimp/js-jpeg": ["@jimp/js-jpeg@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "jpeg-js": "^0.4.4" } }, "sha512-6vgFDqeusblf5Pok6B2DUiMXplH8RhIKAryj1yn+007SIAQ0khM1Uptxmpku/0MfbClx2r7pnJv9gWpAEJdMVA=="],
32
+
33
+ "@jimp/js-png": ["@jimp/js-png@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "pngjs": "^7.0.0" } }, "sha512-AbQHScy3hDDgMRNfG0tPjL88AV6qKAILGReIa3ATpW5QFjBKpisvUaOqhzJ7Reic1oawx3Riyv152gaPfqsBVg=="],
34
+
35
+ "@jimp/js-tiff": ["@jimp/js-tiff@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "utif2": "^4.1.0" } }, "sha512-zhReR8/7KO+adijj3h0ZQUOiun3mXUv79zYEAKvE0O+rP7EhgtKvWJOZfRzdZSNv0Pu1rKtgM72qgtwe2tFvyw=="],
36
+
37
+ "@jimp/plugin-blit": ["@jimp/plugin-blit@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-M+uRWl1csi7qilnSK8uxK4RJMSuVeBiO1AY0+7APnfUbQNZm6hCe0CCFv1Iyw1D/Dhb8ph8fQgm5mwM0eSxgVA=="],
38
+
39
+ "@jimp/plugin-blur": ["@jimp/plugin-blur@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/utils": "1.6.0" } }, "sha512-zrM7iic1OTwUCb0g/rN5y+UnmdEsT3IfuCXCJJNs8SZzP0MkZ1eTvuwK9ZidCuMo4+J3xkzCidRwYXB5CyGZTw=="],
40
+
41
+ "@jimp/plugin-circle": ["@jimp/plugin-circle@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-xt1Gp+LtdMKAXfDp3HNaG30SPZW6AQ7dtAtTnoRKorRi+5yCJjKqXRgkewS5bvj8DEh87Ko1ydJfzqS3P2tdWw=="],
42
+
43
+ "@jimp/plugin-color": ["@jimp/plugin-color@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "tinycolor2": "^1.6.0", "zod": "^3.23.8" } }, "sha512-J5q8IVCpkBsxIXM+45XOXTrsyfblyMZg3a9eAo0P7VPH4+CrvyNQwaYatbAIamSIN1YzxmO3DkIZXzRjFSz1SA=="],
44
+
45
+ "@jimp/plugin-contain": ["@jimp/plugin-contain@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-oN/n+Vdq/Qg9bB4yOBOxtY9IPAtEfES8J1n9Ddx+XhGBYT1/QTU/JYkGaAkIGoPnyYvmLEDqMz2SGihqlpqfzQ=="],
46
+
47
+ "@jimp/plugin-cover": ["@jimp/plugin-cover@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-Iow0h6yqSC269YUJ8HC3Q/MpCi2V55sMlbkkTTx4zPvd8mWZlC0ykrNDeAy9IJegrQ7v5E99rJwmQu25lygKLA=="],
48
+
49
+ "@jimp/plugin-crop": ["@jimp/plugin-crop@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-KqZkEhvs+21USdySCUDI+GFa393eDIzbi1smBqkUPTE+pRwSWMAf01D5OC3ZWB+xZsNla93BDS9iCkLHA8wang=="],
50
+
51
+ "@jimp/plugin-displace": ["@jimp/plugin-displace@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-4Y10X9qwr5F+Bo5ME356XSACEF55485j5nGdiyJ9hYzjQP9nGgxNJaZ4SAOqpd+k5sFaIeD7SQ0Occ26uIng5Q=="],
52
+
53
+ "@jimp/plugin-dither": ["@jimp/plugin-dither@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0" } }, "sha512-600d1RxY0pKwgyU0tgMahLNKsqEcxGdbgXadCiVCoGd6V6glyCvkNrnnwC0n5aJ56Htkj88PToSdF88tNVZEEQ=="],
54
+
55
+ "@jimp/plugin-fisheye": ["@jimp/plugin-fisheye@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-E5QHKWSCBFtpgZarlmN3Q6+rTQxjirFqo44ohoTjzYVrDI6B6beXNnPIThJgPr0Y9GwfzgyarKvQuQuqCnnfbA=="],
56
+
57
+ "@jimp/plugin-flip": ["@jimp/plugin-flip@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-/+rJVDuBIVOgwoyVkBjUFHtP+wmW0r+r5OQ2GpatQofToPVbJw1DdYWXlwviSx7hvixTWLKVgRWQ5Dw862emDg=="],
58
+
59
+ "@jimp/plugin-hash": ["@jimp/plugin-hash@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/js-bmp": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/js-tiff": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "any-base": "^1.1.0" } }, "sha512-wWzl0kTpDJgYVbZdajTf+4NBSKvmI3bRI8q6EH9CVeIHps9VWVsUvEyb7rpbcwVLWYuzDtP2R0lTT6WeBNQH9Q=="],
60
+
61
+ "@jimp/plugin-mask": ["@jimp/plugin-mask@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-Cwy7ExSJMZszvkad8NV8o/Z92X2kFUFM8mcDAhNVxU0Q6tA0op2UKRJY51eoK8r6eds/qak3FQkXakvNabdLnA=="],
62
+
63
+ "@jimp/plugin-print": ["@jimp/plugin-print@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/types": "1.6.0", "parse-bmfont-ascii": "^1.0.6", "parse-bmfont-binary": "^1.0.6", "parse-bmfont-xml": "^1.1.6", "simple-xml-to-json": "^1.2.2", "zod": "^3.23.8" } }, "sha512-zarTIJi8fjoGMSI/M3Xh5yY9T65p03XJmPsuNet19K/Q7mwRU6EV2pfj+28++2PV2NJ+htDF5uecAlnGyxFN2A=="],
64
+
65
+ "@jimp/plugin-quantize": ["@jimp/plugin-quantize@1.6.0", "", { "dependencies": { "image-q": "^4.0.0", "zod": "^3.23.8" } }, "sha512-EmzZ/s9StYQwbpG6rUGBCisc3f64JIhSH+ncTJd+iFGtGo0YvSeMdAd+zqgiHpfZoOL54dNavZNjF4otK+mvlg=="],
66
+
67
+ "@jimp/plugin-resize": ["@jimp/plugin-resize@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-uSUD1mqXN9i1SGSz5ov3keRZ7S9L32/mAQG08wUwZiEi5FpbV0K8A8l1zkazAIZi9IJzLlTauRNU41Mi8IF9fA=="],
68
+
69
+ "@jimp/plugin-rotate": ["@jimp/plugin-rotate@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-JagdjBLnUZGSG4xjCLkIpQOZZ3Mjbg8aGCCi4G69qR+OjNpOeGI7N2EQlfK/WE8BEHOW5vdjSyglNqcYbQBWRw=="],
70
+
71
+ "@jimp/plugin-threshold": ["@jimp/plugin-threshold@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-hash": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-M59m5dzLoHOVWdM41O8z9SyySzcDn43xHseOH0HavjsfQsT56GGCC4QzU1banJidbUrePhzoEdS42uFE8Fei8w=="],
72
+
73
+ "@jimp/types": ["@jimp/types@1.6.0", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-7UfRsiKo5GZTAATxm2qQ7jqmUXP0DxTArztllTcYdyw6Xi5oT4RaoXynVtCD4UyLK5gJgkZJcwonoijrhYFKfg=="],
74
+
75
+ "@jimp/utils": ["@jimp/utils@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "tinycolor2": "^1.6.0" } }, "sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA=="],
76
+
77
+ "@opentui/core": ["@opentui/core@0.1.39", "", { "dependencies": { "bun-ffi-structs": "^0.1.0", "jimp": "1.6.0", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.39", "@opentui/core-darwin-x64": "0.1.39", "@opentui/core-linux-arm64": "0.1.39", "@opentui/core-linux-x64": "0.1.39", "@opentui/core-win32-arm64": "0.1.39", "@opentui/core-win32-x64": "0.1.39", "bun-webgpu": "0.1.3", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-5gPyg3X/8Nr80RfNEJFiMM8Tj01VFfvFwEMCMQrDiOhmSfFXSH2grF/KPl2bnd2Qa13maXWFEl6W3aATObnrnQ=="],
78
+
79
+ "@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.1.39", "", { "os": "darwin", "cpu": "arm64" }, "sha512-tDUdNdzGeylkDWTiDIy/CalM/9nIeDwMZGN0Q6FLqABnAplwBhdIH2w/gInAcMaTyagm7Qk88p398Wbnxa9uyg=="],
80
+
81
+ "@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.1.39", "", { "os": "darwin", "cpu": "x64" }, "sha512-dWXXNUpdi3ndd+6WotQezsO7g54MLSc/6DmYcl0p7fZrQFct8fX0c9ny/S0xAusNHgBGVS5j5FWE75Mx79301Q=="],
82
+
83
+ "@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.1.39", "", { "os": "linux", "cpu": "arm64" }, "sha512-ookQbxLjsg51iwGb6/KTxCfiVRtE9lSE2OVFLLYork8iVzxg81jX29Uoxe1knZ8FjOJ0+VqTzex2IqQH6mjJlw=="],
84
+
85
+ "@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.1.39", "", { "os": "linux", "cpu": "x64" }, "sha512-CeXVNa3hB7gTYKYoZAuMtxWMIXn2rPhmXLkHKpEvXvDRjODFDk8wN1AIVnT5tfncXbWNa5z35BhmqewpGkl4oQ=="],
86
+
87
+ "@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.1.39", "", { "os": "win32", "cpu": "arm64" }, "sha512-eeBrVOHz7B+JNZ+w7GH6QxXhXQVBxI6jHmw3B05czG905Je62P0skZNHxiol2BZRawDljo1J/nXQdO5XPeAk2A=="],
88
+
89
+ "@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.1.39", "", { "os": "win32", "cpu": "x64" }, "sha512-lLXeQUBg6Wlenauwd+xaBD+0HT4YIcONeZUTHA+Gyd/rqVhxId97rhhzFikp3bBTvNJlYAscJI3yIF2JvRiFNQ=="],
90
+
91
+ "@opentui/react": ["@opentui/react@0.1.39", "", { "dependencies": { "@opentui/core": "0.1.39", "react-reconciler": "^0.32.0" }, "peerDependencies": { "react": ">=19.0.0" } }, "sha512-+d7ftMccu3+jL4jytEEDUX0B0cQjR7PvDHIcdyysog+/WripJq/7q+g0TeNopvTWRWs+VkUrOyhODrT4ImhSYA=="],
92
+
93
+ "@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
94
+
95
+ "@types/node": ["@types/node@22.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA=="],
96
+
97
+ "@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="],
98
+
99
+ "@webgpu/types": ["@webgpu/types@0.1.66", "", {}, "sha512-YA2hLrwLpDsRueNDXIMqN9NTzD6bCDkuXbOSe0heS+f8YE8usA6Gbv1prj81pzVHrbaAma7zObnIC+I6/sXJgA=="],
100
+
101
+ "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
102
+
103
+ "any-base": ["any-base@1.1.0", "", {}, "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="],
104
+
105
+ "await-to-js": ["await-to-js@3.0.0", "", {}, "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g=="],
106
+
107
+ "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
108
+
109
+ "bmp-ts": ["bmp-ts@1.0.9", "", {}, "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw=="],
110
+
111
+ "buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
112
+
113
+ "bun-ffi-structs": ["bun-ffi-structs@0.1.0", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-NoRfJ81pgLIHCzw624/2GS2FuxcU0G4SRJww/4PXvheNVUPSIUjkOC6v1/8rk66tJVCb9oR0D6rDNKK0qT5O2Q=="],
114
+
115
+ "bun-webgpu": ["bun-webgpu@0.1.3", "", { "dependencies": { "@webgpu/types": "^0.1.60" }, "optionalDependencies": { "bun-webgpu-darwin-arm64": "^0.1.3", "bun-webgpu-darwin-x64": "^0.1.3", "bun-webgpu-linux-x64": "^0.1.3", "bun-webgpu-win32-x64": "^0.1.3" } }, "sha512-IXFxaIi4rgsEEpl9n/QVDm5RajCK/0FcOXZeMb52YRjoiAR1YVYK5hLrXT8cm+KDi6LVahA9GJFqOR4yiloVCw=="],
116
+
117
+ "bun-webgpu-darwin-arm64": ["bun-webgpu-darwin-arm64@0.1.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-KkNQ9gT7dxGDndQaHTTHss9miukqpczML3pO2nZJoT/nITwe9lw3ZGFJMujkW41BUQ1mDYKFgo5nBGf9xYHPAg=="],
118
+
119
+ "bun-webgpu-darwin-x64": ["bun-webgpu-darwin-x64@0.1.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-TODWnMUbCoqD/wqzlB3oGOBIUWIFly0lqMeBFz/MBV+ndjbnkNrP9huaZJCTkCVEPKGtd1FCM3ExZUtBbnGziA=="],
120
+
121
+ "bun-webgpu-linux-x64": ["bun-webgpu-linux-x64@0.1.3", "", { "os": "linux", "cpu": "x64" }, "sha512-lVHORoVu1G61XVM8CRRqUsqr6w8kMlpuSpbPGpKUpmvrsoay6ymXAhT5lRPKyrGNamHUQTknmWdI59aRDCfLtQ=="],
122
+
123
+ "bun-webgpu-win32-x64": ["bun-webgpu-win32-x64@0.1.3", "", { "os": "win32", "cpu": "x64" }, "sha512-vlspsFffctJlBnFfs2lW3QgDD6LyFu8VT18ryID7Qka5poTj0clGVRxz7DFRi7yva3GovEGw/82z/WVc5US8Pw=="],
124
+
125
+ "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
126
+
127
+ "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
128
+
129
+ "events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
130
+
131
+ "exif-parser": ["exif-parser@0.1.12", "", {}, "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="],
132
+
133
+ "file-type": ["file-type@16.5.4", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="],
134
+
135
+ "gifwrap": ["gifwrap@0.10.1", "", { "dependencies": { "image-q": "^4.0.0", "omggif": "^1.0.10" } }, "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw=="],
136
+
137
+ "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
138
+
139
+ "image-q": ["image-q@4.0.0", "", { "dependencies": { "@types/node": "16.9.1" } }, "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw=="],
140
+
141
+ "jimp": ["jimp@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/diff": "1.6.0", "@jimp/js-bmp": "1.6.0", "@jimp/js-gif": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/js-tiff": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/plugin-blur": "1.6.0", "@jimp/plugin-circle": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-contain": "1.6.0", "@jimp/plugin-cover": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-displace": "1.6.0", "@jimp/plugin-dither": "1.6.0", "@jimp/plugin-fisheye": "1.6.0", "@jimp/plugin-flip": "1.6.0", "@jimp/plugin-hash": "1.6.0", "@jimp/plugin-mask": "1.6.0", "@jimp/plugin-print": "1.6.0", "@jimp/plugin-quantize": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/plugin-rotate": "1.6.0", "@jimp/plugin-threshold": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0" } }, "sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg=="],
142
+
143
+ "jpeg-js": ["jpeg-js@0.4.4", "", {}, "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="],
144
+
145
+ "mime": ["mime@3.0.0", "", { "bin": "cli.js" }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="],
146
+
147
+ "omggif": ["omggif@1.0.10", "", {}, "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw=="],
148
+
149
+ "pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
150
+
151
+ "parse-bmfont-ascii": ["parse-bmfont-ascii@1.0.6", "", {}, "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA=="],
152
+
153
+ "parse-bmfont-binary": ["parse-bmfont-binary@1.0.6", "", {}, "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA=="],
154
+
155
+ "parse-bmfont-xml": ["parse-bmfont-xml@1.1.6", "", { "dependencies": { "xml-parse-from-string": "^1.0.0", "xml2js": "^0.5.0" } }, "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA=="],
156
+
157
+ "peek-readable": ["peek-readable@4.1.0", "", {}, "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg=="],
158
+
159
+ "pixelmatch": ["pixelmatch@5.3.0", "", { "dependencies": { "pngjs": "^6.0.0" }, "bin": "bin/pixelmatch" }, "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q=="],
160
+
161
+ "planck": ["planck@1.4.2", "", { "peerDependencies": { "stage-js": "^1.0.0-alpha.12" } }, "sha512-mNbhnV3g8X2rwGxzcesjmN8BDA6qfXgQxXVMkWau9MCRlQY0RLNEkyHlVp6yFy/X6qrzAXyNONCnZ1cGDLrNew=="],
162
+
163
+ "pngjs": ["pngjs@7.0.0", "", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="],
164
+
165
+ "process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
166
+
167
+ "react": ["react@19.2.0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="],
168
+
169
+ "react-reconciler": ["react-reconciler@0.32.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-2NPMOzgTlG0ZWdIf3qG+dcbLSoAc/uLfOwckc3ofy5sSK0pLJqnQLpUFxvGcN2rlXSjnVtGeeFLNimCQEj5gOQ=="],
170
+
171
+ "readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="],
172
+
173
+ "readable-web-to-node-stream": ["readable-web-to-node-stream@3.0.4", "", { "dependencies": { "readable-stream": "^4.7.0" } }, "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw=="],
174
+
175
+ "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
176
+
177
+ "sax": ["sax@1.4.3", "", {}, "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ=="],
178
+
179
+ "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="],
180
+
181
+ "simple-xml-to-json": ["simple-xml-to-json@1.2.3", "", {}, "sha512-kWJDCr9EWtZ+/EYYM5MareWj2cRnZGF93YDNpH4jQiHB+hBIZnfPFSQiVMzZOdk+zXWqTZ/9fTeQNu2DqeiudA=="],
182
+
183
+ "stage-js": ["stage-js@1.0.0-alpha.17", "", {}, "sha512-AzlMO+t51v6cFvKZ+Oe9DJnL1OXEH5s9bEy6di5aOrUpcP7PCzI/wIeXF0u3zg0L89gwnceoKxrLId0ZpYnNXw=="],
184
+
185
+ "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
186
+
187
+ "strtok3": ["strtok3@6.3.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^4.1.0" } }, "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw=="],
188
+
189
+ "three": ["three@0.177.0", "", {}, "sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg=="],
190
+
191
+ "tinycolor2": ["tinycolor2@1.6.0", "", {}, "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="],
192
+
193
+ "token-types": ["token-types@4.2.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ=="],
194
+
195
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
196
+
197
+ "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
198
+
199
+ "utif2": ["utif2@4.1.0", "", { "dependencies": { "pako": "^1.0.11" } }, "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w=="],
200
+
201
+ "web-tree-sitter": ["web-tree-sitter@0.25.10", "", { "peerDependencies": { "@types/emscripten": "^1.40.0" }, "optionalPeers": ["@types/emscripten"] }, "sha512-Y09sF44/13XvgVKgO2cNDw5rGk6s26MgoZPXLESvMXeefBf7i6/73eFurre0IsTW6E14Y0ArIzhUMmjoc7xyzA=="],
202
+
203
+ "xml-parse-from-string": ["xml-parse-from-string@1.0.1", "", {}, "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g=="],
204
+
205
+ "xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="],
206
+
207
+ "xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="],
208
+
209
+ "yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="],
210
+
211
+ "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
212
+
213
+ "image-q/@types/node": ["@types/node@16.9.1", "", {}, "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g=="],
214
+
215
+ "pixelmatch/pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="],
216
+ }
217
+ }
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env python3
2
+ """Launch the OpenCode metadata TUI built with OpenTUI.
3
+
4
+ This wrapper keeps the previous entry point name but simply shells out to the
5
+ new Bun-powered React TUI located under ``src/opencode-tui.tsx``. Use
6
+ ``manage_opencode_projects.py -- --help`` to see the TUI's runtime help text.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ import shutil
13
+ import subprocess
14
+ import sys
15
+ from pathlib import Path
16
+ from typing import Sequence
17
+
18
+ DEFAULT_ROOT = Path.home() / ".local" / "share" / "opencode"
19
+ PROJECT_DIR = Path(__file__).resolve().parent
20
+
21
+
22
+ def parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
23
+ parser = argparse.ArgumentParser(
24
+ description="Open the interactive OpenCode metadata manager TUI",
25
+ epilog=(
26
+ "Examples:\n"
27
+ " manage_opencode_projects.py\n"
28
+ " Launch the TUI using the default metadata root.\n\n"
29
+ " manage_opencode_projects.py --root /tmp/opencode\n"
30
+ " Launch the TUI against a different storage directory.\n\n"
31
+ " manage_opencode_projects.py -- --help\n"
32
+ " Show the TUI's built-in CLI help output.\n"
33
+ ),
34
+ )
35
+ parser.add_argument(
36
+ "--root",
37
+ type=Path,
38
+ default=DEFAULT_ROOT,
39
+ help="Metadata root to inspect (defaults to ~/.local/share/opencode)",
40
+ )
41
+ parser.add_argument(
42
+ "--bun",
43
+ type=Path,
44
+ default=None,
45
+ help="Optional path to the bun executable if it's not on PATH",
46
+ )
47
+ parser.add_argument(
48
+ "tui_args",
49
+ nargs=argparse.REMAINDER,
50
+ help=(
51
+ "Additional arguments forwarded to the TUI after '--'. For example: "
52
+ "manage_opencode_projects.py -- --help"
53
+ ),
54
+ )
55
+ return parser.parse_args(argv)
56
+
57
+
58
+ def find_bun(explicit: Path | None) -> str:
59
+ if explicit:
60
+ return str(explicit)
61
+ bun_path = shutil.which("bun")
62
+ if bun_path:
63
+ return bun_path
64
+ raise SystemExit("bun executable not found. Please install Bun to run the TUI.")
65
+
66
+
67
+ def launch_tui(root: Path, bun_exe: str, extra_args: Sequence[str]) -> int:
68
+ # Normalize passthrough args: drop leading "--" if present
69
+ if extra_args and len(extra_args) > 0 and extra_args[0] == "--":
70
+ extra_args = extra_args[1:]
71
+ cmd = [
72
+ bun_exe,
73
+ "run",
74
+ "tui",
75
+ "--",
76
+ "--root",
77
+ str(root.expanduser()),
78
+ ]
79
+ if extra_args:
80
+ cmd.extend(extra_args)
81
+
82
+ process = subprocess.run(cmd, cwd=PROJECT_DIR)
83
+ return process.returncode
84
+
85
+
86
+ def main(argv: Sequence[str] | None = None) -> int:
87
+ args = parse_args(argv)
88
+ bun_exe = find_bun(args.bun)
89
+ extra_args = list(args.tui_args or [])
90
+ return launch_tui(args.root, bun_exe, extra_args)
91
+
92
+
93
+ if __name__ == "__main__":
94
+ sys.exit(main())
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "opencode-manager",
3
+ "version": "0.1.0",
4
+ "description": "Terminal UI for inspecting OpenCode metadata stores.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "packageManager": "bun@1.1.29",
8
+ "engines": {
9
+ "bun": ">=1.1.0"
10
+ },
11
+ "bin": {
12
+ "opencode-manager": "./src/bin/opencode-manager.ts"
13
+ },
14
+ "files": [
15
+ "src",
16
+ "bun.lock",
17
+ "tsconfig.json",
18
+ "PROJECT-SUMMARY.md",
19
+ "manage_opencode_projects.py",
20
+ "LICENSE"
21
+ ],
22
+ "scripts": {
23
+ "tui": "bun src/opencode-tui.tsx",
24
+ "dev": "bun --watch src/opencode-tui.tsx",
25
+ "typecheck": "bunx tsc --noEmit",
26
+ "prepublishOnly": "bun run typecheck"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/kcrommett/oc-manager.git"
31
+ },
32
+ "bugs": {
33
+ "url": "https://github.com/kcrommett/oc-manager/issues"
34
+ },
35
+ "keywords": [
36
+ "tui",
37
+ "bun",
38
+ "opencode",
39
+ "cli",
40
+ "metadata"
41
+ ],
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "dependencies": {
46
+ "@opentui/core": "^0.1.34",
47
+ "@opentui/react": "^0.1.34",
48
+ "react": "^19.0.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^22.8.5",
52
+ "@types/react": "^19.0.0",
53
+ "typescript": "^5.6.3"
54
+ }
55
+ }
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bun
2
+ // Bun-native CLI entry that simply boots the TUI module.
3
+ // Keeping this file tiny lets `bun x opencode-manager` launch instantly without extra bundling.
4
+ import "../opencode-tui"