opencode-account-manager 0.4.4 → 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.
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ActionPalette = ActionPalette;
37
+ const react_1 = __importStar(require("react"));
38
+ const ink_1 = require("ink");
39
+ function ActionPalette({ actions, onSelect, onClose }) {
40
+ const [search, setSearch] = (0, react_1.useState)("");
41
+ const [selectedIndex, setSelectedIndex] = (0, react_1.useState)(0);
42
+ // Filter actions by search
43
+ const filteredActions = actions.filter(action => {
44
+ const searchLower = search.toLowerCase();
45
+ return (action.label.toLowerCase().includes(searchLower) ||
46
+ action.id.toLowerCase().includes(searchLower) ||
47
+ (action.description?.toLowerCase().includes(searchLower)));
48
+ });
49
+ (0, ink_1.useInput)((input, key) => {
50
+ // Close on Escape
51
+ if (key.escape) {
52
+ onClose();
53
+ return;
54
+ }
55
+ // Navigate up
56
+ if (key.upArrow) {
57
+ setSelectedIndex(prev => Math.max(0, prev - 1));
58
+ return;
59
+ }
60
+ // Navigate down
61
+ if (key.downArrow) {
62
+ setSelectedIndex(prev => Math.min(filteredActions.length - 1, prev + 1));
63
+ return;
64
+ }
65
+ // Select on Enter
66
+ if (key.return) {
67
+ const action = filteredActions[selectedIndex];
68
+ if (action) {
69
+ onSelect(action.id);
70
+ }
71
+ return;
72
+ }
73
+ // Backspace
74
+ if (key.backspace || key.delete) {
75
+ setSearch(prev => prev.slice(0, -1));
76
+ setSelectedIndex(0);
77
+ return;
78
+ }
79
+ // Type to search (printable characters)
80
+ if (input && input.length === 1 && !key.ctrl && !key.meta) {
81
+ setSearch(prev => prev + input);
82
+ setSelectedIndex(0);
83
+ }
84
+ });
85
+ return (react_1.default.createElement(ink_1.Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 0 },
86
+ react_1.default.createElement(ink_1.Box, { marginBottom: 1 },
87
+ react_1.default.createElement(ink_1.Text, { color: "cyan", bold: true },
88
+ ">",
89
+ " "),
90
+ react_1.default.createElement(ink_1.Text, null, search),
91
+ react_1.default.createElement(ink_1.Text, { color: "gray" }, "_")),
92
+ react_1.default.createElement(ink_1.Box, { flexDirection: "column", marginBottom: 1 }, filteredActions.length === 0 ? (react_1.default.createElement(ink_1.Text, { dimColor: true }, "No matching actions")) : (filteredActions.slice(0, 10).map((action, index) => {
93
+ const isSelected = index === selectedIndex;
94
+ return (react_1.default.createElement(ink_1.Box, { key: action.id },
95
+ react_1.default.createElement(ink_1.Text, { backgroundColor: isSelected ? "cyan" : undefined, color: isSelected ? "black" : "white" },
96
+ isSelected ? "▸ " : " ",
97
+ action.label),
98
+ action.shortcut && (react_1.default.createElement(ink_1.Text, { dimColor: true },
99
+ " [",
100
+ action.shortcut,
101
+ "]"))));
102
+ }))),
103
+ react_1.default.createElement(ink_1.Box, null,
104
+ react_1.default.createElement(ink_1.Text, { dimColor: true }, "\u2191\u2193 navigate \u2022 Enter select \u2022 Esc close"))));
105
+ }
106
+ //# sourceMappingURL=ActionPalette.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionPalette.js","sourceRoot":"","sources":["../../../src/tui/components/ActionPalette.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { Account } from "../../core/types";
3
+ interface DashboardViewProps {
4
+ accounts: Account[];
5
+ selectedIndex: number;
6
+ }
7
+ export declare function DashboardView({ accounts, selectedIndex }: DashboardViewProps): React.JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=DashboardView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardView.d.ts","sourceRoot":"","sources":["../../../src/tui/components/DashboardView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AA0DD,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,kBAAkB,qBAwG5E"}
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DashboardView = DashboardView;
7
+ const react_1 = __importDefault(require("react"));
8
+ const ink_1 = require("ink");
9
+ // Model families for rate limit display
10
+ const MODEL_FAMILIES = ["claude", "gemini", "gpt", "deepseek", "o1", "o3"];
11
+ function formatTimeRemaining(resetTime) {
12
+ const now = Date.now();
13
+ if (resetTime <= now)
14
+ return "";
15
+ const remaining = resetTime - now;
16
+ const hours = Math.floor(remaining / 3600000);
17
+ const minutes = Math.floor((remaining % 3600000) / 60000);
18
+ if (hours > 0) {
19
+ return `${hours}h ${minutes}m`;
20
+ }
21
+ return `${minutes}m`;
22
+ }
23
+ function getAccountStatus(account) {
24
+ if (!account.enabled) {
25
+ return { status: "DISABLED", color: "gray" };
26
+ }
27
+ const now = Date.now();
28
+ const rateLimits = account.rateLimitResetTimes || {};
29
+ const limitedModels = Object.entries(rateLimits)
30
+ .filter(([_, time]) => time > now);
31
+ if (limitedModels.length === 0) {
32
+ return { status: "AVAILABLE", color: "green" };
33
+ }
34
+ return { status: "LIMITED", color: "yellow" };
35
+ }
36
+ function getRateLimitBar(account, model) {
37
+ const now = Date.now();
38
+ const resetTime = account.rateLimitResetTimes?.[model] || 0;
39
+ if (resetTime <= now) {
40
+ return { bar: "████████", color: "green", time: "" };
41
+ }
42
+ // Calculate remaining time as percentage (assume 24h max)
43
+ const remaining = resetTime - now;
44
+ const maxTime = 24 * 3600000; // 24 hours
45
+ const percentage = Math.min(1, remaining / maxTime);
46
+ const filledBlocks = Math.round((1 - percentage) * 8);
47
+ const emptyBlocks = 8 - filledBlocks;
48
+ return {
49
+ bar: "█".repeat(filledBlocks) + "░".repeat(emptyBlocks),
50
+ color: percentage > 0.5 ? "red" : "yellow",
51
+ time: formatTimeRemaining(resetTime),
52
+ };
53
+ }
54
+ function DashboardView({ accounts, selectedIndex }) {
55
+ if (accounts.length === 0) {
56
+ return (react_1.default.createElement(ink_1.Box, { flexDirection: "column", padding: 1 },
57
+ react_1.default.createElement(ink_1.Text, { dimColor: true }, "No accounts found. Press P to open actions and import accounts.")));
58
+ }
59
+ // Get all unique models from accounts
60
+ const allModels = new Set();
61
+ accounts.forEach(acc => {
62
+ if (acc.rateLimitResetTimes) {
63
+ Object.keys(acc.rateLimitResetTimes).forEach(m => allModels.add(m));
64
+ }
65
+ });
66
+ // Use predefined families or detected models
67
+ const displayModels = MODEL_FAMILIES.filter(m => accounts.some(acc => acc.rateLimitResetTimes?.[m]));
68
+ if (displayModels.length === 0) {
69
+ displayModels.push("claude", "gemini"); // Default columns
70
+ }
71
+ return (react_1.default.createElement(ink_1.Box, { flexDirection: "column" },
72
+ react_1.default.createElement(ink_1.Box, null,
73
+ react_1.default.createElement(ink_1.Box, { width: 30 },
74
+ react_1.default.createElement(ink_1.Text, { bold: true, color: "cyan" }, "ACCOUNT")),
75
+ react_1.default.createElement(ink_1.Box, { width: 12 },
76
+ react_1.default.createElement(ink_1.Text, { bold: true, color: "cyan" }, "STATUS")),
77
+ displayModels.map(model => (react_1.default.createElement(ink_1.Box, { key: model, width: 14 },
78
+ react_1.default.createElement(ink_1.Text, { bold: true, color: "cyan" }, model.toUpperCase()))))),
79
+ react_1.default.createElement(ink_1.Box, null,
80
+ react_1.default.createElement(ink_1.Text, { dimColor: true }, "─".repeat(30 + 12 + displayModels.length * 14))),
81
+ accounts.map((account, index) => {
82
+ const isSelected = index === selectedIndex;
83
+ const { status, color } = getAccountStatus(account);
84
+ // Truncate email
85
+ const emailDisplay = account.email.length > 28
86
+ ? account.email.slice(0, 25) + "..."
87
+ : account.email;
88
+ return (react_1.default.createElement(ink_1.Box, { key: account.email },
89
+ react_1.default.createElement(ink_1.Text, { color: isSelected ? "cyan" : undefined }, isSelected ? "▸ " : " "),
90
+ react_1.default.createElement(ink_1.Box, { width: 28 },
91
+ react_1.default.createElement(ink_1.Text, { color: isSelected ? "cyan" : (account.enabled === false ? "gray" : "white"), bold: isSelected }, emailDisplay)),
92
+ react_1.default.createElement(ink_1.Box, { width: 12 },
93
+ react_1.default.createElement(ink_1.Text, { color: color }, status)),
94
+ displayModels.map(model => {
95
+ const { bar, color: barColor, time } = getRateLimitBar(account, model);
96
+ return (react_1.default.createElement(ink_1.Box, { key: model, width: 14 },
97
+ react_1.default.createElement(ink_1.Text, { color: barColor }, bar),
98
+ time && react_1.default.createElement(ink_1.Text, { dimColor: true },
99
+ " ",
100
+ time)));
101
+ })));
102
+ }),
103
+ react_1.default.createElement(ink_1.Box, { marginTop: 1 },
104
+ react_1.default.createElement(ink_1.Text, { dimColor: true },
105
+ react_1.default.createElement(ink_1.Text, { color: "green" }, "\u2588\u2588\u2588\u2588"),
106
+ " Available",
107
+ react_1.default.createElement(ink_1.Text, { color: "yellow" }, "\u2591\u2591\u2591\u2591"),
108
+ " Limited",
109
+ react_1.default.createElement(ink_1.Text, { color: "gray" }, "\u2588\u2588\u2588\u2588"),
110
+ " Disabled"))));
111
+ }
112
+ //# sourceMappingURL=DashboardView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardView.js","sourceRoot":"","sources":["../../../src/tui/components/DashboardView.tsx"],"names":[],"mappings":"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"}
@@ -11,4 +11,6 @@ export { PasswordInput } from "./PasswordInput";
11
11
  export { FileBrowser } from "./FileBrowser";
12
12
  export { ExportModal } from "./ExportModal";
13
13
  export { ImportModal } from "./ImportModal";
14
+ export { ActionPalette, PaletteAction } from "./ActionPalette";
15
+ export { DashboardView } from "./DashboardView";
14
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tui/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tui/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ImportModal = exports.ExportModal = exports.FileBrowser = exports.PasswordInput = exports.SectionBox = exports.McpServerList = exports.ProviderList = exports.MenuBar = exports.AccountList = exports.AccountRow = exports.StatsRow = exports.StatCard = exports.StatusBadge = exports.Header = exports.Box = void 0;
3
+ exports.DashboardView = exports.ActionPalette = exports.ImportModal = exports.ExportModal = exports.FileBrowser = exports.PasswordInput = exports.SectionBox = exports.McpServerList = exports.ProviderList = exports.MenuBar = exports.AccountList = exports.AccountRow = exports.StatsRow = exports.StatCard = exports.StatusBadge = exports.Header = exports.Box = void 0;
4
4
  var Box_1 = require("./Box");
5
5
  Object.defineProperty(exports, "Box", { enumerable: true, get: function () { return Box_1.Box; } });
6
6
  var Header_1 = require("./Header");
@@ -29,4 +29,8 @@ var ExportModal_1 = require("./ExportModal");
29
29
  Object.defineProperty(exports, "ExportModal", { enumerable: true, get: function () { return ExportModal_1.ExportModal; } });
30
30
  var ImportModal_1 = require("./ImportModal");
31
31
  Object.defineProperty(exports, "ImportModal", { enumerable: true, get: function () { return ImportModal_1.ImportModal; } });
32
+ var ActionPalette_1 = require("./ActionPalette");
33
+ Object.defineProperty(exports, "ActionPalette", { enumerable: true, get: function () { return ActionPalette_1.ActionPalette; } });
34
+ var DashboardView_1 = require("./DashboardView");
35
+ Object.defineProperty(exports, "DashboardView", { enumerable: true, get: function () { return DashboardView_1.DashboardView; } });
32
36
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tui/components/index.ts"],"names":[],"mappings":";;;AAAA,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AACZ,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,uCAAgD;AAAvC,oGAAA,QAAQ,OAAA;AAAE,oGAAA,QAAQ,OAAA;AAC3B,6CAAwD;AAA/C,yGAAA,UAAU,OAAA;AAAE,0GAAA,WAAW,OAAA;AAChC,+BAA6C;AAApC,+FAAA,OAAO,OAAA;AAChB,+CAA8C;AAArC,4GAAA,YAAY,OAAA;AACrB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,6CAA4C;AAAnC,0GAAA,WAAW,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tui/components/index.ts"],"names":[],"mappings":";;;AAAA,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AACZ,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,uCAAgD;AAAvC,oGAAA,QAAQ,OAAA;AAAE,oGAAA,QAAQ,OAAA;AAC3B,6CAAwD;AAA/C,yGAAA,UAAU,OAAA;AAAE,0GAAA,WAAW,OAAA;AAChC,+BAA6C;AAApC,+FAAA,OAAO,OAAA;AAChB,+CAA8C;AAArC,4GAAA,YAAY,OAAA;AACrB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,iDAA+D;AAAtD,8GAAA,aAAa,OAAA;AACtB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA"}
package/docs/ROADMAP.md CHANGED
@@ -48,12 +48,36 @@
48
48
  - [x] **Tab Navigation** - Fixed Tab key to cycle through sections
49
49
  - [x] **UI Indicator** - Show `[1] Providers [2] Accounts [3] MCP` in header
50
50
 
51
- ### v0.4.4 - Arrow Key Navigation (Current)
51
+ ### v0.4.4 - Arrow Key Navigation
52
52
  - [x] **←→ Arrow Keys** - Switch between sections (Providers ↔ Accounts ↔ MCP)
53
53
  - [x] **↑↓ Arrow Keys** - Navigate account list, auto-enters select mode
54
54
  - [x] **Space Key** - Toggle selection in select mode
55
55
  - [x] **Updated Help Text** - Show arrow key hints in UI
56
56
 
57
+ ### v0.5.0 - OpenCode-style UX
58
+ - [x] **Action Palette** - Press P to open command palette (like OpenCode Ctrl+P)
59
+ - [x] **Unified Navigation** - ↑↓ to navigate everything, Enter to expand/select
60
+ - [x] **Simplified Controls** - No more complex keyboard shortcuts to remember
61
+ - [x] **Inline Selection** - Space to toggle, selection count shown in help bar
62
+ - [x] **Removed MenuBar** - Clean minimal interface
63
+
64
+ ### v0.5.1 - Dashboard Tab (Current)
65
+ - [x] **Two Tabs** - Dashboard (rate limits) + Settings (providers, accounts, MCP)
66
+ - [x] **Tab Switching** - Press Tab to switch between Dashboard and Settings
67
+ - [x] **Rate Limit View** - Like Antigravity Manager, shows accounts with model limits
68
+ - [x] **Progress Bars** - Visual indicator of rate limit status per model
69
+ - [x] **Time Remaining** - Shows hours/minutes until limit resets
70
+
71
+ **New Controls:**
72
+ | Key | Action |
73
+ |-----|--------|
74
+ | Tab | Switch between Dashboard and Settings |
75
+ | ↑↓ | Navigate accounts/sections |
76
+ | Space | Toggle account selection |
77
+ | P | Open Action Palette |
78
+ | Q | Quit |
79
+ | R | Refresh |
80
+
57
81
  ---
58
82
 
59
83
  ## Future Ideas (Backlog)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-account-manager",
3
- "version": "0.4.4",
3
+ "version": "0.5.1",
4
4
  "description": "TUI Dashboard for OpenCode - View providers, MCP servers, and plugin accounts",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {
package/src/cli.ts CHANGED
@@ -41,7 +41,7 @@ const program = new Command();
41
41
  program
42
42
  .name("ocam")
43
43
  .description("OpenCode Account Manager - TUI dashboard and CLI for managing accounts")
44
- .version("0.4.4");
44
+ .version("0.5.1");
45
45
 
46
46
  // Default command - show dashboard
47
47
  program