opencode-account-manager 0.5.0 → 0.5.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.
package/dist/cli.js CHANGED
@@ -35,7 +35,7 @@ const program = new commander_1.Command();
35
35
  program
36
36
  .name("ocam")
37
37
  .description("OpenCode Account Manager - TUI dashboard and CLI for managing accounts")
38
- .version("0.5.0");
38
+ .version("0.5.2");
39
39
  // Default command - show dashboard
40
40
  program
41
41
  .command("dashboard", { isDefault: true })
@@ -1 +1 @@
1
- {"version":3,"file":"Dashboard.d.ts","sourceRoot":"","sources":["../../src/tui/Dashboard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AA8BnD,UAAU,cAAc;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAiBD,wBAAgB,SAAS,CAAC,EAAE,UAAU,EAAE,EAAE,cAAc,qBAwcvD"}
1
+ {"version":3,"file":"Dashboard.d.ts","sourceRoot":"","sources":["../../src/tui/Dashboard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AA+BnD,UAAU,cAAc;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAaD,wBAAgB,SAAS,CAAC,EAAE,UAAU,EAAE,EAAE,cAAc,qBA0hBvD"}
@@ -58,12 +58,19 @@ function Dashboard({ pluginPath }) {
58
58
  const [accounts, setAccounts] = (0, react_1.useState)([]);
59
59
  const [summary, setSummary] = (0, react_1.useState)({ total: 0, available: 0, limited: 0 });
60
60
  const [message, setMessage] = (0, react_1.useState)(null);
61
- // UI state - simplified
61
+ // Main tab state
62
+ const [activeTab, setActiveTab] = (0, react_1.useState)("dashboard");
63
+ // Dashboard tab state
64
+ const [dashboardIndex, setDashboardIndex] = (0, react_1.useState)(0);
65
+ // Settings tab state
62
66
  const [expandedSection, setExpandedSection] = (0, react_1.useState)("accounts");
63
- const [navIndex, setNavIndex] = (0, react_1.useState)(0); // Current navigation index
67
+ const [settingsNavIndex, setSettingsNavIndex] = (0, react_1.useState)(0);
64
68
  const [checkedEmails, setCheckedEmails] = (0, react_1.useState)(new Set());
65
69
  // Modal state
66
70
  const [activeModal, setActiveModal] = (0, react_1.useState)("none");
71
+ // Loading state
72
+ const [isLoading, setIsLoading] = (0, react_1.useState)(false);
73
+ const [loadingStep, setLoadingStep] = (0, react_1.useState)("");
67
74
  const showMessage = (msg, duration = 3000) => {
68
75
  setMessage(msg);
69
76
  setTimeout(() => setMessage(null), duration);
@@ -78,31 +85,39 @@ function Dashboard({ pluginPath }) {
78
85
  setSummary((0, accounts_1.summarizeAccounts)(file.accounts));
79
86
  setCheckedEmails(new Set());
80
87
  };
81
- const refresh = () => {
88
+ const refresh = async () => {
89
+ setIsLoading(true);
90
+ setLoadingStep("Loading OpenCode config...");
91
+ await new Promise(r => setTimeout(r, 100)); // Small delay for UI update
82
92
  loadOpencodeConfig();
93
+ setLoadingStep("Loading accounts...");
94
+ await new Promise(r => setTimeout(r, 100));
83
95
  loadAccounts();
96
+ setLoadingStep("Done!");
97
+ await new Promise(r => setTimeout(r, 300));
98
+ setIsLoading(false);
99
+ setLoadingStep("");
84
100
  showMessage("Refreshed", 2000);
85
101
  };
86
102
  (0, react_1.useEffect)(() => {
87
103
  loadOpencodeConfig();
88
104
  loadAccounts();
89
105
  }, []);
90
- // Build navigation items list
91
- const buildNavItems = () => {
106
+ // Build settings navigation items
107
+ const buildSettingsNavItems = () => {
92
108
  const items = [
93
- { type: "section", id: "providers", label: "PROVIDERS" },
94
- { type: "section", id: "accounts", label: "ACCOUNTS" },
109
+ { type: "section", id: "providers" },
110
+ { type: "section", id: "accounts" },
95
111
  ];
96
- // If accounts section is expanded, add account items
97
112
  if (expandedSection === "accounts") {
98
113
  accounts.forEach((acc, index) => {
99
114
  items.push({ type: "account", index, email: acc.email });
100
115
  });
101
116
  }
102
- items.push({ type: "section", id: "mcp", label: "MCP SERVERS" });
117
+ items.push({ type: "section", id: "mcp" });
103
118
  return items;
104
119
  };
105
- const navItems = buildNavItems();
120
+ const settingsNavItems = buildSettingsNavItems();
106
121
  // Palette actions
107
122
  const paletteActions = [
108
123
  { id: "refresh", label: "Refresh", shortcut: "R" },
@@ -121,13 +136,17 @@ function Dashboard({ pluginPath }) {
121
136
  ];
122
137
  // Keyboard navigation
123
138
  (0, ink_1.useInput)((input, key) => {
124
- // Handle palette separately
125
139
  if (activeModal === "palette")
126
140
  return;
127
141
  if (activeModal !== "none")
128
142
  return;
129
- // Open palette with Ctrl+P or P
130
- if ((key.ctrl && input === "p") || input === "p" || input === "P") {
143
+ // Tab to switch between main tabs
144
+ if (key.tab) {
145
+ setActiveTab(prev => prev === "dashboard" ? "settings" : "dashboard");
146
+ return;
147
+ }
148
+ // Open palette with P
149
+ if (input === "p" || input === "P") {
131
150
  setActiveModal("palette");
132
151
  return;
133
152
  }
@@ -140,56 +159,82 @@ function Dashboard({ pluginPath }) {
140
159
  refresh();
141
160
  return;
142
161
  }
143
- // Navigate up
144
- if (key.upArrow) {
145
- setNavIndex(prev => Math.max(0, prev - 1));
146
- return;
147
- }
148
- // Navigate down
149
- if (key.downArrow) {
150
- setNavIndex(prev => Math.min(navItems.length - 1, prev + 1));
151
- return;
152
- }
153
- // Enter to expand/collapse section or toggle account
154
- if (key.return) {
155
- const currentItem = navItems[navIndex];
156
- if (currentItem?.type === "section") {
157
- setExpandedSection(currentItem.id);
158
- // Reset nav index to stay on section header
162
+ // Tab-specific navigation
163
+ if (activeTab === "dashboard") {
164
+ // Dashboard tab navigation
165
+ if (key.upArrow) {
166
+ setDashboardIndex(prev => Math.max(0, prev - 1));
167
+ return;
159
168
  }
160
- else if (currentItem?.type === "account") {
161
- // Toggle selection
162
- const email = currentItem.email;
163
- setCheckedEmails(prev => {
164
- const next = new Set(prev);
165
- if (next.has(email)) {
166
- next.delete(email);
167
- }
168
- else {
169
- next.add(email);
170
- }
171
- return next;
172
- });
169
+ if (key.downArrow) {
170
+ setDashboardIndex(prev => Math.min(accounts.length - 1, prev + 1));
171
+ return;
172
+ }
173
+ // Space/Enter to toggle selection
174
+ if (input === " " || key.return) {
175
+ const email = accounts[dashboardIndex]?.email;
176
+ if (email) {
177
+ setCheckedEmails(prev => {
178
+ const next = new Set(prev);
179
+ if (next.has(email)) {
180
+ next.delete(email);
181
+ }
182
+ else {
183
+ next.add(email);
184
+ }
185
+ return next;
186
+ });
187
+ }
188
+ return;
173
189
  }
174
- return;
175
190
  }
176
- // Space to toggle selection
177
- if (input === " ") {
178
- const currentItem = navItems[navIndex];
179
- if (currentItem?.type === "account") {
180
- const email = currentItem.email;
181
- setCheckedEmails(prev => {
182
- const next = new Set(prev);
183
- if (next.has(email)) {
184
- next.delete(email);
185
- }
186
- else {
187
- next.add(email);
188
- }
189
- return next;
190
- });
191
+ else {
192
+ // Settings tab navigation
193
+ if (key.upArrow) {
194
+ setSettingsNavIndex(prev => Math.max(0, prev - 1));
195
+ return;
196
+ }
197
+ if (key.downArrow) {
198
+ setSettingsNavIndex(prev => Math.min(settingsNavItems.length - 1, prev + 1));
199
+ return;
200
+ }
201
+ if (key.return) {
202
+ const currentItem = settingsNavItems[settingsNavIndex];
203
+ if (currentItem?.type === "section" && currentItem.id) {
204
+ setExpandedSection(currentItem.id);
205
+ }
206
+ else if (currentItem?.type === "account" && currentItem.email) {
207
+ const email = currentItem.email;
208
+ setCheckedEmails(prev => {
209
+ const next = new Set(prev);
210
+ if (next.has(email)) {
211
+ next.delete(email);
212
+ }
213
+ else {
214
+ next.add(email);
215
+ }
216
+ return next;
217
+ });
218
+ }
219
+ return;
220
+ }
221
+ if (input === " ") {
222
+ const currentItem = settingsNavItems[settingsNavIndex];
223
+ if (currentItem?.type === "account" && currentItem.email) {
224
+ const email = currentItem.email;
225
+ setCheckedEmails(prev => {
226
+ const next = new Set(prev);
227
+ if (next.has(email)) {
228
+ next.delete(email);
229
+ }
230
+ else {
231
+ next.add(email);
232
+ }
233
+ return next;
234
+ });
235
+ }
236
+ return;
191
237
  }
192
- return;
193
238
  }
194
239
  // Escape to clear selection
195
240
  if (key.escape) {
@@ -339,13 +384,9 @@ function Dashboard({ pluginPath }) {
339
384
  }
340
385
  return accounts;
341
386
  };
342
- // Find current nav item for highlighting
343
- const currentNavItem = navItems[navIndex];
344
- const isOnSection = (id) => currentNavItem?.type === "section" && currentNavItem.id === id;
345
- const getAccountNavState = (index) => {
346
- const item = navItems[navIndex];
347
- return item?.type === "account" && item.index === index;
348
- };
387
+ // Settings nav helpers
388
+ const currentSettingsItem = settingsNavItems[settingsNavIndex];
389
+ const isOnSection = (id) => currentSettingsItem?.type === "section" && currentSettingsItem.id === id;
349
390
  // Render modals
350
391
  if (activeModal === "export" || activeModal === "export-selected") {
351
392
  return (react_1.default.createElement(ink_1.Box, { flexDirection: "column", padding: 1 },
@@ -356,28 +397,45 @@ function Dashboard({ pluginPath }) {
356
397
  react_1.default.createElement(components_1.ImportModal, { existingAccounts: accounts, onComplete: handleImportComplete, onCancel: () => setActiveModal("none") })));
357
398
  }
358
399
  return (react_1.default.createElement(ink_1.Box, { flexDirection: "column", padding: 1 },
359
- react_1.default.createElement(components_1.Header, { title: "OpenCode Account Manager", subtitle: "Dashboard" }),
400
+ react_1.default.createElement(components_1.Header, { title: "OpenCode Account Manager", subtitle: activeTab === "dashboard" ? "Dashboard" : "Settings" }),
401
+ react_1.default.createElement(ink_1.Box, { marginBottom: 1 },
402
+ react_1.default.createElement(ink_1.Text, { backgroundColor: activeTab === "dashboard" ? "cyan" : undefined, color: activeTab === "dashboard" ? "black" : "gray", bold: activeTab === "dashboard" }, " DASHBOARD "),
403
+ react_1.default.createElement(ink_1.Text, null, " "),
404
+ react_1.default.createElement(ink_1.Text, { backgroundColor: activeTab === "settings" ? "cyan" : undefined, color: activeTab === "settings" ? "black" : "gray", bold: activeTab === "settings" }, " SETTINGS "),
405
+ react_1.default.createElement(ink_1.Text, { dimColor: true }, " (Tab to switch)")),
360
406
  react_1.default.createElement(components_1.StatsRow, { stats: [
361
- { label: "Providers", value: configSummary?.providers || 0, color: "cyan" },
362
- { label: "Models", value: configSummary?.models || 0, color: "yellow" },
363
- { label: "MCP", value: configSummary?.mcpEnabled || 0, color: "green" },
364
407
  { label: "Accounts", value: summary.total, color: "white" },
365
408
  { label: "Available", value: summary.available, color: "green" },
366
409
  { label: "Limited", value: summary.limited, color: "yellow" },
410
+ { label: "Providers", value: configSummary?.providers || 0, color: "cyan" },
411
+ { label: "MCP", value: configSummary?.mcpEnabled || 0, color: "magenta" },
367
412
  ] }),
368
413
  react_1.default.createElement(ink_1.Box, { marginY: 1 },
369
- react_1.default.createElement(ink_1.Text, { dimColor: true }, "\u2191\u2193 navigate \u2022 Enter expand/select \u2022 Space toggle \u2022 "),
414
+ react_1.default.createElement(ink_1.Text, { dimColor: true }, "\u2191\u2193 navigate \u2022 Space select \u2022 "),
415
+ react_1.default.createElement(ink_1.Text, { color: "cyan", bold: true }, "R"),
416
+ react_1.default.createElement(ink_1.Text, { dimColor: true }, " refresh \u2022 "),
370
417
  react_1.default.createElement(ink_1.Text, { color: "cyan", bold: true }, "P"),
371
418
  react_1.default.createElement(ink_1.Text, { dimColor: true }, " actions \u2022 "),
372
- react_1.default.createElement(ink_1.Text, { dimColor: true }, "Q quit"),
419
+ react_1.default.createElement(ink_1.Text, { color: "cyan", bold: true }, "Tab"),
420
+ react_1.default.createElement(ink_1.Text, { dimColor: true }, " switch \u2022 Q quit"),
373
421
  checkedEmails.size > 0 && (react_1.default.createElement(ink_1.Text, { color: "yellow" },
374
422
  " \u2022 ",
375
423
  checkedEmails.size,
376
424
  " selected"))),
377
- react_1.default.createElement(components_1.SectionBox, { title: "PROVIDERS", borderColor: isOnSection("providers") ? "cyan" : (expandedSection === "providers" ? "white" : "gray"), collapsed: expandedSection !== "providers" }, opencodeInfo && react_1.default.createElement(components_1.ProviderList, { providers: opencodeInfo.providers })),
378
- react_1.default.createElement(components_1.SectionBox, { title: `ACCOUNTS (${opencodeInfo?.plugins[0]?.name || "antigravity-auth"})`, borderColor: isOnSection("accounts") || (currentNavItem?.type === "account") ? "cyan" : (expandedSection === "accounts" ? "white" : "gray"), collapsed: expandedSection !== "accounts" },
379
- react_1.default.createElement(components_1.AccountList, { accounts: accounts, selectedIndex: currentNavItem?.type === "account" ? currentNavItem.index : -1, checkedEmails: checkedEmails, showCheckbox: true })),
380
- react_1.default.createElement(components_1.SectionBox, { title: "MCP SERVERS", borderColor: isOnSection("mcp") ? "cyan" : (expandedSection === "mcp" ? "white" : "gray"), collapsed: expandedSection !== "mcp" }, opencodeInfo && react_1.default.createElement(components_1.McpServerList, { servers: opencodeInfo.mcpServers })),
425
+ isLoading && (react_1.default.createElement(ink_1.Box, { marginBottom: 1, paddingX: 1 },
426
+ react_1.default.createElement(ink_1.Text, { color: "cyan" },
427
+ react_1.default.createElement(ink_1.Text, { color: "cyan" }, "\u27F3 "),
428
+ loadingStep))),
429
+ activeTab === "dashboard" ? (
430
+ // Dashboard Tab - Rate limits view like Antigravity Manager
431
+ react_1.default.createElement(ink_1.Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1 },
432
+ react_1.default.createElement(components_1.DashboardView, { accounts: accounts, selectedIndex: dashboardIndex }))) : (
433
+ // Settings Tab - Original sections view
434
+ react_1.default.createElement(react_1.default.Fragment, null,
435
+ react_1.default.createElement(components_1.SectionBox, { title: "PROVIDERS", borderColor: isOnSection("providers") ? "cyan" : (expandedSection === "providers" ? "white" : "gray"), collapsed: expandedSection !== "providers" }, opencodeInfo && react_1.default.createElement(components_1.ProviderList, { providers: opencodeInfo.providers })),
436
+ react_1.default.createElement(components_1.SectionBox, { title: `ACCOUNTS (${opencodeInfo?.plugins[0]?.name || "antigravity-auth"})`, borderColor: isOnSection("accounts") || (currentSettingsItem?.type === "account") ? "cyan" : (expandedSection === "accounts" ? "white" : "gray"), collapsed: expandedSection !== "accounts" },
437
+ react_1.default.createElement(components_1.AccountList, { accounts: accounts, selectedIndex: currentSettingsItem?.type === "account" ? (currentSettingsItem.index ?? -1) : -1, checkedEmails: checkedEmails, showCheckbox: true })),
438
+ react_1.default.createElement(components_1.SectionBox, { title: "MCP SERVERS", borderColor: isOnSection("mcp") ? "cyan" : (expandedSection === "mcp" ? "white" : "gray"), collapsed: expandedSection !== "mcp" }, opencodeInfo && react_1.default.createElement(components_1.McpServerList, { servers: opencodeInfo.mcpServers })))),
381
439
  react_1.default.createElement(ink_1.Box, { marginTop: 1 },
382
440
  react_1.default.createElement(ink_1.Text, { dimColor: true },
383
441
  "Config: ",
@@ -1 +1 @@
1
- {"version":3,"file":"Dashboard.js","sourceRoot":"","sources":["../../src/tui/Dashboard.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Dashboard.js","sourceRoot":"","sources":["../../src/tui/Dashboard.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CA,8BA0hBC;AAxkBD,+CAAmD;AACnD,6BAAkD;AAClD,6CAYsB;AACtB,+CAM0B;AAC1B,yCAAuE;AAEvE,qDAA8D;AAC9D,6DAIiC;AASjC,SAAS,kBAAkB,CAAC,UAAkB;IAC5C,IAAI,CAAC;QACH,OAAO,IAAA,iCAAsB,EAAC,UAAU,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAA,wCAA6B,GAAE,CAAC;IACzC,CAAC;AACH,CAAC;AAED,SAAgB,SAAS,CAAC,EAAE,UAAU,EAAkB;IACtD,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,YAAM,GAAE,CAAC;IAC1B,MAAM,YAAY,GAAG,IAAA,6BAAqB,EAAC,UAAU,CAAC,CAAC;IAEvD,wBAAwB;IACxB,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,IAAA,gBAAQ,EAAsB,IAAI,CAAC,CAAC;IAE5E,wBAAwB;IACxB,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,IAAA,gBAAQ,EAAY,EAAE,CAAC,CAAC;IACxD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,IAAA,gBAAQ,EAAC,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/E,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,IAAA,gBAAQ,EAAgB,IAAI,CAAC,CAAC;IAE5D,iBAAiB;IACjB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAA,gBAAQ,EAAU,WAAW,CAAC,CAAC;IAEjE,sBAAsB;IACtB,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,IAAA,gBAAQ,EAAC,CAAC,CAAC,CAAC;IAExD,qBAAqB;IACrB,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,IAAA,gBAAQ,EAAmC,UAAU,CAAC,CAAC;IACrG,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,IAAA,gBAAQ,EAAC,CAAC,CAAC,CAAC;IAC5D,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,IAAA,gBAAQ,EAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IAE3E,cAAc;IACd,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAY,MAAM,CAAC,CAAC;IAElE,gBAAgB;IAChB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAC,EAAE,CAAC,CAAC;IAEnD,MAAM,WAAW,GAAG,CAAC,GAAW,EAAE,QAAQ,GAAG,IAAI,EAAE,EAAE;QACnD,UAAU,CAAC,GAAG,CAAC,CAAC;QAChB,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC,CAAC;IAEF,MAAM,kBAAkB,GAAG,GAAG,EAAE;QAC9B,MAAM,IAAI,GAAG,IAAA,mCAAiB,GAAE,CAAC;QACjC,eAAe,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,MAAM,IAAI,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAC9C,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3B,UAAU,CAAC,IAAA,4BAAiB,EAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7C,gBAAgB,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IAC9B,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;QACzB,YAAY,CAAC,IAAI,CAAC,CAAC;QAEnB,cAAc,CAAC,4BAA4B,CAAC,CAAC;QAC7C,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,4BAA4B;QACxE,kBAAkB,EAAE,CAAC;QAErB,cAAc,CAAC,qBAAqB,CAAC,CAAC;QACtC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3C,YAAY,EAAE,CAAC;QAEf,cAAc,CAAC,OAAO,CAAC,CAAC;QACxB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAE3C,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,cAAc,CAAC,EAAE,CAAC,CAAC;QACnB,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC;IAEF,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,kBAAkB,EAAE,CAAC;QACrB,YAAY,EAAE,CAAC;IACjB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,kCAAkC;IAClC,MAAM,qBAAqB,GAAG,GAAG,EAAE;QACjC,MAAM,KAAK,GAAwF;YACjG,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE;YACpC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE;SACpC,CAAC;QAEF,IAAI,eAAe,KAAK,UAAU,EAAE,CAAC;YACnC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;gBAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3C,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,qBAAqB,EAAE,CAAC;IAEjD,kBAAkB;IAClB,MAAM,cAAc,GAAoB;QACtC,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE;QAClD,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,qBAAqB,EAAE,QAAQ,EAAE,GAAG,EAAE;QAC7D,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,GAAG,EAAE;QAC1D,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,iCAAiC,EAAE,QAAQ,EAAE,GAAG,EAAE;QAC5E,GAAG,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YAC3B,EAAE,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,oBAAoB,aAAa,CAAC,IAAI,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;YAC1F,EAAE,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,oBAAoB,aAAa,CAAC,IAAI,GAAG,EAAE;YAC3E,EAAE,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,qBAAqB,aAAa,CAAC,IAAI,GAAG,EAAE;YAC7E,EAAE,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,oBAAoB,aAAa,CAAC,IAAI,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE;YAC5F,EAAE,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,GAAG,EAAE;SACnE,CAAC,CAAC,CAAC,EAAE,CAAC;QACP,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,qBAAqB,EAAE,QAAQ,EAAE,QAAQ,EAAE;QACtE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE;KAC7C,CAAC;IAEF,sBAAsB;IACtB,IAAA,cAAQ,EAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO;QACtC,IAAI,WAAW,KAAK,MAAM;YAAE,OAAO;QAEnC,kCAAkC;QAClC,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QAED,sBAAsB;QACtB,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACnC,cAAc,CAAC,SAAS,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,kBAAkB;QAClB,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACnC,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QACD,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACnC,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,0BAA0B;QAC1B,IAAI,SAAS,KAAK,WAAW,EAAE,CAAC;YAC9B,2BAA2B;YAC3B,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAChB,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;gBACjD,OAAO;YACT,CAAC;YACD,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;gBAClB,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;gBACnE,OAAO;YACT,CAAC;YACD,kCAAkC;YAClC,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;gBAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC;gBAC9C,IAAI,KAAK,EAAE,CAAC;oBACV,gBAAgB,CAAC,IAAI,CAAC,EAAE;wBACtB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;wBAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;4BACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;wBACrB,CAAC;6BAAM,CAAC;4BACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;wBAClB,CAAC;wBACD,OAAO,IAAI,CAAC;oBACd,CAAC,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO;YACT,CAAC;QACH,CAAC;aAAM,CAAC;YACN,0BAA0B;YAC1B,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAChB,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;gBACnD,OAAO;YACT,CAAC;YACD,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;gBAClB,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC7E,OAAO;YACT,CAAC;YACD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;gBACf,MAAM,WAAW,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;gBACvD,IAAI,WAAW,EAAE,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,EAAE,EAAE,CAAC;oBACtD,kBAAkB,CAAC,WAAW,CAAC,EAAsC,CAAC,CAAC;gBACzE,CAAC;qBAAM,IAAI,WAAW,EAAE,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;oBAChE,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;oBAChC,gBAAgB,CAAC,IAAI,CAAC,EAAE;wBACtB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;wBAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;4BACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;wBACrB,CAAC;6BAAM,CAAC;4BACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;wBAClB,CAAC;wBACD,OAAO,IAAI,CAAC;oBACd,CAAC,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO;YACT,CAAC;YACD,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;gBAClB,MAAM,WAAW,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;gBACvD,IAAI,WAAW,EAAE,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;oBACzD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;oBAChC,gBAAgB,CAAC,IAAI,CAAC,EAAE;wBACtB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;wBAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;4BACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;wBACrB,CAAC;6BAAM,CAAC;4BACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;wBAClB,CAAC;wBACD,OAAO,IAAI,CAAC;oBACd,CAAC,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO;YACT,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBAC3B,gBAAgB,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;gBAC5B,WAAW,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;YACzC,CAAC;YACD,OAAO;QACT,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,wBAAwB;IACxB,MAAM,mBAAmB,GAAG,CAAC,QAAgB,EAAE,EAAE;QAC/C,cAAc,CAAC,MAAM,CAAC,CAAC;QAEvB,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,SAAS;gBACZ,OAAO,EAAE,CAAC;gBACV,MAAM;YACR,KAAK,QAAQ;gBACX,cAAc,CAAC,QAAQ,CAAC,CAAC;gBACzB,MAAM;YACR,KAAK,QAAQ;gBACX,cAAc,CAAC,QAAQ,CAAC,CAAC;gBACzB,MAAM;YACR,KAAK,WAAW;gBACd,cAAc,EAAE,CAAC;gBACjB,MAAM;YACR,KAAK,iBAAiB;gBACpB,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;oBAC3B,cAAc,CAAC,iBAAiB,CAAC,CAAC;gBACpC,CAAC;qBAAM,CAAC;oBACN,WAAW,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;gBAC5C,CAAC;gBACD,MAAM;YACR,KAAK,iBAAiB;gBACpB,oBAAoB,EAAE,CAAC;gBACvB,MAAM;YACR,KAAK,kBAAkB;gBACrB,qBAAqB,EAAE,CAAC;gBACxB,MAAM;YACR,KAAK,iBAAiB;gBACpB,oBAAoB,EAAE,CAAC;gBACvB,MAAM;YACR,KAAK,YAAY;gBACf,gBAAgB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtD,WAAW,CAAC,YAAY,QAAQ,CAAC,MAAM,WAAW,EAAE,IAAI,CAAC,CAAC;gBAC1D,MAAM;YACR,KAAK,iBAAiB;gBACpB,gBAAgB,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;gBAC5B,WAAW,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;gBACvC,MAAM;YACR,KAAK,MAAM;gBACT,IAAI,EAAE,CAAC;gBACP,MAAM;QACV,CAAC;IACH,CAAC,CAAC;IAEF,4BAA4B;IAC5B,MAAM,oBAAoB,GAAG,CAAC,QAAgB,EAAE,EAAE;QAChD,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,WAAW,CAAC,eAAe,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC,CAAC;IAEF,4BAA4B;IAC5B,MAAM,oBAAoB,GAAG,CAAC,gBAA2B,EAAE,QAAgB,EAAE,gBAAwB,EAAE,EAAE;QACvG,MAAM,IAAI,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAA,wBAAa,EAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAC9D,IAAA,kCAAuB,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAE5C,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,YAAY,EAAE,CAAC;QACf,WAAW,CAAC,aAAa,QAAQ,SAAS,gBAAgB,UAAU,EAAE,IAAI,CAAC,CAAC;IAC9E,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,GAAG,EAAE;QAC1B,MAAM,MAAM,GAAG,IAAA,uBAAe,GAAE,CAAC;QACjC,MAAM,MAAM,GAAG,IAAA,2BAAkB,EAAC,MAAM,CAAC,CAAC;QAE1C,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,WAAW,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QAED,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,WAAW,CAAC,4BAA4B,MAAM,CAAC,OAAO,CAAC,MAAM,WAAW,EAAE,IAAI,CAAC,CAAC;YAChF,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,IAAA,wBAAa,EAAC,YAAY,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrE,IAAA,kCAAuB,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAE5C,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC;QACpE,WAAW,CACT,qBAAqB,MAAM,CAAC,QAAQ,CAAC,MAAM,WAAW,KAAK,MAAM,EACjE,IAAI,CACL,CAAC;QAEF,YAAY,EAAE,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,oBAAoB,GAAG,GAAG,EAAE;QAChC,IAAI,aAAa,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC7B,WAAW,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YACtC,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YACnC,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC,CAAC,CAAC;QAEH,IAAA,kCAAuB,EAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC1C,WAAW,CAAC,WAAW,KAAK,WAAW,EAAE,IAAI,CAAC,CAAC;QAC/C,YAAY,EAAE,CAAC;QACf,gBAAgB,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IAC9B,CAAC,CAAC;IAEF,MAAM,qBAAqB,GAAG,GAAG,EAAE;QACjC,IAAI,aAAa,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC7B,WAAW,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YACtC,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YACpC,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC,CAAC,CAAC;QAEH,IAAA,kCAAuB,EAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC1C,WAAW,CAAC,YAAY,KAAK,WAAW,EAAE,IAAI,CAAC,CAAC;QAChD,YAAY,EAAE,CAAC;QACf,gBAAgB,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IAC9B,CAAC,CAAC;IAEF,MAAM,oBAAoB,GAAG,GAAG,EAAE;QAChC,IAAI,aAAa,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC7B,WAAW,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAEzC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3E,MAAM,YAAY,GAAG,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAExD,IAAA,kCAAuB,EAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC1C,WAAW,CAAC,WAAW,YAAY,WAAW,EAAE,IAAI,CAAC,CAAC;QACtD,YAAY,EAAE,CAAC;QACf,gBAAgB,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IAC9B,CAAC,CAAC;IAEF,kBAAkB;IAClB,MAAM,aAAa,GAAG,YAAY,CAAC,CAAC,CAAC,IAAA,kCAAgB,EAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE3E,yBAAyB;IACzB,MAAM,oBAAoB,GAAG,GAAc,EAAE;QAC3C,IAAI,WAAW,KAAK,iBAAiB,EAAE,CAAC;YACtC,OAAO,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IAEF,uBAAuB;IACvB,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IAC/D,MAAM,WAAW,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,mBAAmB,EAAE,IAAI,KAAK,SAAS,IAAI,mBAAmB,CAAC,EAAE,KAAK,EAAE,CAAC;IAE7G,gBAAgB;IAChB,IAAI,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,iBAAiB,EAAE,CAAC;QAClE,OAAO,CACL,8BAAC,SAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC;YACpC,8BAAC,wBAAW,IACV,QAAQ,EAAE,oBAAoB,EAAE,EAChC,UAAU,EAAE,oBAAoB,EAChC,QAAQ,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,GACtC,CACE,CACP,CAAC;IACJ,CAAC;IAED,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,CACL,8BAAC,SAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC;YACpC,8BAAC,wBAAW,IACV,gBAAgB,EAAE,QAAQ,EAC1B,UAAU,EAAE,oBAAoB,EAChC,QAAQ,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,GACtC,CACE,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,8BAAC,SAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC;QACpC,8BAAC,mBAAM,IAAC,KAAK,EAAC,0BAA0B,EAAC,QAAQ,EAAE,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,GAAI;QAG3G,8BAAC,SAAG,IAAC,YAAY,EAAE,CAAC;YAClB,8BAAC,UAAI,IACH,eAAe,EAAE,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAC/D,KAAK,EAAE,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EACnD,IAAI,EAAE,SAAS,KAAK,WAAW,IAE9B,aAAa,CACT;YACP,8BAAC,UAAI,YAAS;YACd,8BAAC,UAAI,IACH,eAAe,EAAE,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAC9D,KAAK,EAAE,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAClD,IAAI,EAAE,SAAS,KAAK,UAAU,IAE7B,YAAY,CACR;YACP,8BAAC,UAAI,IAAC,QAAQ,8BAAyB,CACnC;QAGN,8BAAC,qBAAQ,IACP,KAAK,EAAE;gBACL,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE;gBAC3D,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE;gBAChE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE;gBAC7D,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;gBAC3E,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE;aAC1E,GACD;QAGF,8BAAC,SAAG,IAAC,OAAO,EAAE,CAAC;YACb,8BAAC,UAAI,IAAC,QAAQ,8DAAqC;YACnD,8BAAC,UAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,cAAS;YAChC,8BAAC,UAAI,IAAC,QAAQ,6BAAmB;YACjC,8BAAC,UAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,cAAS;YAChC,8BAAC,UAAI,IAAC,QAAQ,6BAAmB;YACjC,8BAAC,UAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,gBAAW;YAClC,8BAAC,UAAI,IAAC,QAAQ,kCAAwB;YACrC,aAAa,CAAC,IAAI,GAAG,CAAC,IAAI,CACzB,8BAAC,UAAI,IAAC,KAAK,EAAC,QAAQ;;gBAAK,aAAa,CAAC,IAAI;4BAAiB,CAC7D,CACG;QAGL,SAAS,IAAI,CACZ,8BAAC,SAAG,IAAC,YAAY,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC;YAC/B,8BAAC,UAAI,IAAC,KAAK,EAAC,MAAM;gBAChB,8BAAC,UAAI,IAAC,KAAK,EAAC,MAAM,cAAU;gBAC3B,WAAW,CACP,CACH,CACP;QAGA,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC;QAC3B,4DAA4D;QAC5D,8BAAC,SAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAC,OAAO,EAAC,WAAW,EAAC,MAAM,EAAC,OAAO,EAAE,CAAC;YAC3E,8BAAC,0BAAa,IACZ,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,cAAc,GAC7B,CACE,CACP,CAAC,CAAC,CAAC;QACF,wCAAwC;QACxC;YACE,8BAAC,uBAAU,IACT,KAAK,EAAC,WAAW,EACjB,WAAW,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,eAAe,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EACrG,SAAS,EAAE,eAAe,KAAK,WAAW,IAEzC,YAAY,IAAI,8BAAC,yBAAY,IAAC,SAAS,EAAE,YAAY,CAAC,SAAS,GAAI,CACzD;YAEb,8BAAC,uBAAU,IACT,KAAK,EAAE,aAAa,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,kBAAkB,GAAG,EAC3E,WAAW,EAAE,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,eAAe,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAChJ,SAAS,EAAE,eAAe,KAAK,UAAU;gBAEzC,8BAAC,wBAAW,IACV,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,mBAAmB,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAC/F,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,IAAI,GAClB,CACS;YAEb,8BAAC,uBAAU,IACT,KAAK,EAAC,aAAa,EACnB,WAAW,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,eAAe,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EACzF,SAAS,EAAE,eAAe,KAAK,KAAK,IAEnC,YAAY,IAAI,8BAAC,0BAAa,IAAC,OAAO,EAAE,YAAY,CAAC,UAAU,GAAI,CACzD,CACZ,CACJ;QAGD,8BAAC,SAAG,IAAC,SAAS,EAAE,CAAC;YACf,8BAAC,UAAI,IAAC,QAAQ;;gBAAU,YAAY,EAAE,UAAU,IAAI,KAAK,CAAQ,CAC7D;QAGL,OAAO,IAAI,CACV,8BAAC,SAAG,IAAC,SAAS,EAAE,CAAC;YACf,8BAAC,UAAI,IAAC,KAAK,EAAC,OAAO;;gBAAI,OAAO,CAAQ,CAClC,CACP;QAGA,WAAW,KAAK,SAAS,IAAI,CAC5B,8BAAC,SAAG,IAAC,QAAQ,EAAC,UAAU,EAAC,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE;YACnD,8BAAC,0BAAa,IACZ,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,GACrC,CACE,CACP,CACG,CACP,CAAC;AACJ,CAAC"}
@@ -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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"}
@@ -12,4 +12,5 @@ export { FileBrowser } from "./FileBrowser";
12
12
  export { ExportModal } from "./ExportModal";
13
13
  export { ImportModal } from "./ImportModal";
14
14
  export { ActionPalette, PaletteAction } from "./ActionPalette";
15
+ export { DashboardView } from "./DashboardView";
15
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;AAC5C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,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.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;
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");
@@ -31,4 +31,6 @@ var ImportModal_1 = require("./ImportModal");
31
31
  Object.defineProperty(exports, "ImportModal", { enumerable: true, get: function () { return ImportModal_1.ImportModal; } });
32
32
  var ActionPalette_1 = require("./ActionPalette");
33
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; } });
34
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;AACpB,iDAA+D;AAAtD,8GAAA,aAAa,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
@@ -54,23 +54,34 @@
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 (Current)
57
+ ### v0.5.0 - OpenCode-style UX
58
58
  - [x] **Action Palette** - Press P to open command palette (like OpenCode Ctrl+P)
59
59
  - [x] **Unified Navigation** - ↑↓ to navigate everything, Enter to expand/select
60
60
  - [x] **Simplified Controls** - No more complex keyboard shortcuts to remember
61
61
  - [x] **Inline Selection** - Space to toggle, selection count shown in help bar
62
62
  - [x] **Removed MenuBar** - Clean minimal interface
63
63
 
64
- **New Controls:**
64
+ ### v0.5.1 - Dashboard Tab
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
+ ### v0.5.2 - Loading Indicator (Current)
72
+ - [x] **Loading State** - Shows progress during refresh
73
+ - [x] **Step Messages** - "Loading OpenCode config...", "Loading accounts...", "Done!"
74
+ - [x] **R Key Shortcut** - Added R to help bar for quick refresh
75
+
76
+ **Controls:**
65
77
  | Key | Action |
66
78
  |-----|--------|
67
- | ↑↓ | Navigate sections and accounts |
68
- | Enter | Expand section / Toggle account selection |
79
+ | Tab | Switch between Dashboard and Settings |
80
+ | ↑↓ | Navigate accounts/sections |
69
81
  | Space | Toggle account selection |
82
+ | R | Refresh with progress indicator |
70
83
  | P | Open Action Palette |
71
84
  | Q | Quit |
72
- | R | Refresh |
73
- | Esc | Clear selection |
74
85
 
75
86
  ---
76
87
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-account-manager",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
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.5.0");
44
+ .version("0.5.2");
45
45
 
46
46
  // Default command - show dashboard
47
47
  program
@@ -11,6 +11,7 @@ import {
11
11
  ImportModal,
12
12
  ActionPalette,
13
13
  PaletteAction,
14
+ DashboardView,
14
15
  } from "./components";
15
16
  import {
16
17
  readPluginAccountsFile,
@@ -33,11 +34,7 @@ interface DashboardProps {
33
34
  }
34
35
 
35
36
  type ModalType = "none" | "export" | "import" | "export-selected" | "palette";
36
-
37
- // Navigation items
38
- type NavItem =
39
- | { type: "section"; id: "providers" | "accounts" | "mcp"; label: string }
40
- | { type: "account"; index: number; email: string };
37
+ type MainTab = "dashboard" | "settings";
41
38
 
42
39
  function safeReadPluginFile(pluginPath: string): PluginAccountsFile {
43
40
  try {
@@ -59,13 +56,23 @@ export function Dashboard({ pluginPath }: DashboardProps) {
59
56
  const [summary, setSummary] = useState({ total: 0, available: 0, limited: 0 });
60
57
  const [message, setMessage] = useState<string | null>(null);
61
58
 
62
- // UI state - simplified
59
+ // Main tab state
60
+ const [activeTab, setActiveTab] = useState<MainTab>("dashboard");
61
+
62
+ // Dashboard tab state
63
+ const [dashboardIndex, setDashboardIndex] = useState(0);
64
+
65
+ // Settings tab state
63
66
  const [expandedSection, setExpandedSection] = useState<"providers" | "accounts" | "mcp">("accounts");
64
- const [navIndex, setNavIndex] = useState(0); // Current navigation index
67
+ const [settingsNavIndex, setSettingsNavIndex] = useState(0);
65
68
  const [checkedEmails, setCheckedEmails] = useState<Set<string>>(new Set());
66
69
 
67
70
  // Modal state
68
71
  const [activeModal, setActiveModal] = useState<ModalType>("none");
72
+
73
+ // Loading state
74
+ const [isLoading, setIsLoading] = useState(false);
75
+ const [loadingStep, setLoadingStep] = useState("");
69
76
 
70
77
  const showMessage = (msg: string, duration = 3000) => {
71
78
  setMessage(msg);
@@ -84,9 +91,22 @@ export function Dashboard({ pluginPath }: DashboardProps) {
84
91
  setCheckedEmails(new Set());
85
92
  };
86
93
 
87
- const refresh = () => {
94
+ const refresh = async () => {
95
+ setIsLoading(true);
96
+
97
+ setLoadingStep("Loading OpenCode config...");
98
+ await new Promise(r => setTimeout(r, 100)); // Small delay for UI update
88
99
  loadOpencodeConfig();
100
+
101
+ setLoadingStep("Loading accounts...");
102
+ await new Promise(r => setTimeout(r, 100));
89
103
  loadAccounts();
104
+
105
+ setLoadingStep("Done!");
106
+ await new Promise(r => setTimeout(r, 300));
107
+
108
+ setIsLoading(false);
109
+ setLoadingStep("");
90
110
  showMessage("Refreshed", 2000);
91
111
  };
92
112
 
@@ -95,26 +115,24 @@ export function Dashboard({ pluginPath }: DashboardProps) {
95
115
  loadAccounts();
96
116
  }, []);
97
117
 
98
- // Build navigation items list
99
- const buildNavItems = (): NavItem[] => {
100
- const items: NavItem[] = [
101
- { type: "section", id: "providers", label: "PROVIDERS" },
102
- { type: "section", id: "accounts", label: "ACCOUNTS" },
118
+ // Build settings navigation items
119
+ const buildSettingsNavItems = () => {
120
+ const items: Array<{ type: "section" | "account"; id?: string; index?: number; email?: string }> = [
121
+ { type: "section", id: "providers" },
122
+ { type: "section", id: "accounts" },
103
123
  ];
104
124
 
105
- // If accounts section is expanded, add account items
106
125
  if (expandedSection === "accounts") {
107
126
  accounts.forEach((acc, index) => {
108
127
  items.push({ type: "account", index, email: acc.email });
109
128
  });
110
129
  }
111
130
 
112
- items.push({ type: "section", id: "mcp", label: "MCP SERVERS" });
113
-
131
+ items.push({ type: "section", id: "mcp" });
114
132
  return items;
115
133
  };
116
134
 
117
- const navItems = buildNavItems();
135
+ const settingsNavItems = buildSettingsNavItems();
118
136
 
119
137
  // Palette actions
120
138
  const paletteActions: PaletteAction[] = [
@@ -135,12 +153,17 @@ export function Dashboard({ pluginPath }: DashboardProps) {
135
153
 
136
154
  // Keyboard navigation
137
155
  useInput((input, key) => {
138
- // Handle palette separately
139
156
  if (activeModal === "palette") return;
140
157
  if (activeModal !== "none") return;
141
158
 
142
- // Open palette with Ctrl+P or P
143
- if ((key.ctrl && input === "p") || input === "p" || input === "P") {
159
+ // Tab to switch between main tabs
160
+ if (key.tab) {
161
+ setActiveTab(prev => prev === "dashboard" ? "settings" : "dashboard");
162
+ return;
163
+ }
164
+
165
+ // Open palette with P
166
+ if (input === "p" || input === "P") {
144
167
  setActiveModal("palette");
145
168
  return;
146
169
  }
@@ -155,56 +178,77 @@ export function Dashboard({ pluginPath }: DashboardProps) {
155
178
  return;
156
179
  }
157
180
 
158
- // Navigate up
159
- if (key.upArrow) {
160
- setNavIndex(prev => Math.max(0, prev - 1));
161
- return;
162
- }
163
-
164
- // Navigate down
165
- if (key.downArrow) {
166
- setNavIndex(prev => Math.min(navItems.length - 1, prev + 1));
167
- return;
168
- }
169
-
170
- // Enter to expand/collapse section or toggle account
171
- if (key.return) {
172
- const currentItem = navItems[navIndex];
173
- if (currentItem?.type === "section") {
174
- setExpandedSection(currentItem.id);
175
- // Reset nav index to stay on section header
176
- } else if (currentItem?.type === "account") {
177
- // Toggle selection
178
- const email = currentItem.email;
179
- setCheckedEmails(prev => {
180
- const next = new Set(prev);
181
- if (next.has(email)) {
182
- next.delete(email);
183
- } else {
184
- next.add(email);
185
- }
186
- return next;
187
- });
181
+ // Tab-specific navigation
182
+ if (activeTab === "dashboard") {
183
+ // Dashboard tab navigation
184
+ if (key.upArrow) {
185
+ setDashboardIndex(prev => Math.max(0, prev - 1));
186
+ return;
188
187
  }
189
- return;
190
- }
191
-
192
- // Space to toggle selection
193
- if (input === " ") {
194
- const currentItem = navItems[navIndex];
195
- if (currentItem?.type === "account") {
196
- const email = currentItem.email;
197
- setCheckedEmails(prev => {
198
- const next = new Set(prev);
199
- if (next.has(email)) {
200
- next.delete(email);
201
- } else {
202
- next.add(email);
203
- }
204
- return next;
205
- });
188
+ if (key.downArrow) {
189
+ setDashboardIndex(prev => Math.min(accounts.length - 1, prev + 1));
190
+ return;
191
+ }
192
+ // Space/Enter to toggle selection
193
+ if (input === " " || key.return) {
194
+ const email = accounts[dashboardIndex]?.email;
195
+ if (email) {
196
+ setCheckedEmails(prev => {
197
+ const next = new Set(prev);
198
+ if (next.has(email)) {
199
+ next.delete(email);
200
+ } else {
201
+ next.add(email);
202
+ }
203
+ return next;
204
+ });
205
+ }
206
+ return;
207
+ }
208
+ } else {
209
+ // Settings tab navigation
210
+ if (key.upArrow) {
211
+ setSettingsNavIndex(prev => Math.max(0, prev - 1));
212
+ return;
213
+ }
214
+ if (key.downArrow) {
215
+ setSettingsNavIndex(prev => Math.min(settingsNavItems.length - 1, prev + 1));
216
+ return;
217
+ }
218
+ if (key.return) {
219
+ const currentItem = settingsNavItems[settingsNavIndex];
220
+ if (currentItem?.type === "section" && currentItem.id) {
221
+ setExpandedSection(currentItem.id as "providers" | "accounts" | "mcp");
222
+ } else if (currentItem?.type === "account" && currentItem.email) {
223
+ const email = currentItem.email;
224
+ setCheckedEmails(prev => {
225
+ const next = new Set(prev);
226
+ if (next.has(email)) {
227
+ next.delete(email);
228
+ } else {
229
+ next.add(email);
230
+ }
231
+ return next;
232
+ });
233
+ }
234
+ return;
235
+ }
236
+ if (input === " ") {
237
+ const currentItem = settingsNavItems[settingsNavIndex];
238
+ if (currentItem?.type === "account" && currentItem.email) {
239
+ const email = currentItem.email;
240
+ setCheckedEmails(prev => {
241
+ const next = new Set(prev);
242
+ if (next.has(email)) {
243
+ next.delete(email);
244
+ } else {
245
+ next.add(email);
246
+ }
247
+ return next;
248
+ });
249
+ }
250
+ return;
206
251
  }
207
- return;
208
252
  }
209
253
 
210
254
  // Escape to clear selection
@@ -383,13 +427,9 @@ export function Dashboard({ pluginPath }: DashboardProps) {
383
427
  return accounts;
384
428
  };
385
429
 
386
- // Find current nav item for highlighting
387
- const currentNavItem = navItems[navIndex];
388
- const isOnSection = (id: string) => currentNavItem?.type === "section" && currentNavItem.id === id;
389
- const getAccountNavState = (index: number) => {
390
- const item = navItems[navIndex];
391
- return item?.type === "account" && item.index === index;
392
- };
430
+ // Settings nav helpers
431
+ const currentSettingsItem = settingsNavItems[settingsNavIndex];
432
+ const isOnSection = (id: string) => currentSettingsItem?.type === "section" && currentSettingsItem.id === id;
393
433
 
394
434
  // Render modals
395
435
  if (activeModal === "export" || activeModal === "export-selected") {
@@ -418,62 +458,105 @@ export function Dashboard({ pluginPath }: DashboardProps) {
418
458
 
419
459
  return (
420
460
  <Box flexDirection="column" padding={1}>
421
- <Header title="OpenCode Account Manager" subtitle="Dashboard" />
461
+ <Header title="OpenCode Account Manager" subtitle={activeTab === "dashboard" ? "Dashboard" : "Settings"} />
462
+
463
+ {/* Tab bar */}
464
+ <Box marginBottom={1}>
465
+ <Text
466
+ backgroundColor={activeTab === "dashboard" ? "cyan" : undefined}
467
+ color={activeTab === "dashboard" ? "black" : "gray"}
468
+ bold={activeTab === "dashboard"}
469
+ >
470
+ {" DASHBOARD "}
471
+ </Text>
472
+ <Text> </Text>
473
+ <Text
474
+ backgroundColor={activeTab === "settings" ? "cyan" : undefined}
475
+ color={activeTab === "settings" ? "black" : "gray"}
476
+ bold={activeTab === "settings"}
477
+ >
478
+ {" SETTINGS "}
479
+ </Text>
480
+ <Text dimColor> (Tab to switch)</Text>
481
+ </Box>
422
482
 
423
483
  {/* Global Stats */}
424
484
  <StatsRow
425
485
  stats={[
426
- { label: "Providers", value: configSummary?.providers || 0, color: "cyan" },
427
- { label: "Models", value: configSummary?.models || 0, color: "yellow" },
428
- { label: "MCP", value: configSummary?.mcpEnabled || 0, color: "green" },
429
486
  { label: "Accounts", value: summary.total, color: "white" },
430
487
  { label: "Available", value: summary.available, color: "green" },
431
488
  { label: "Limited", value: summary.limited, color: "yellow" },
489
+ { label: "Providers", value: configSummary?.providers || 0, color: "cyan" },
490
+ { label: "MCP", value: configSummary?.mcpEnabled || 0, color: "magenta" },
432
491
  ]}
433
492
  />
434
493
 
435
494
  {/* Help bar */}
436
495
  <Box marginY={1}>
437
- <Text dimColor>↑↓ navigate • Enter expand/select • Space toggle • </Text>
496
+ <Text dimColor>↑↓ navigate • Space select • </Text>
497
+ <Text color="cyan" bold>R</Text>
498
+ <Text dimColor> refresh • </Text>
438
499
  <Text color="cyan" bold>P</Text>
439
500
  <Text dimColor> actions • </Text>
440
- <Text dimColor>Q quit</Text>
501
+ <Text color="cyan" bold>Tab</Text>
502
+ <Text dimColor> switch • Q quit</Text>
441
503
  {checkedEmails.size > 0 && (
442
504
  <Text color="yellow"> • {checkedEmails.size} selected</Text>
443
505
  )}
444
506
  </Box>
445
507
 
446
- {/* Providers Section */}
447
- <SectionBox
448
- title="PROVIDERS"
449
- borderColor={isOnSection("providers") ? "cyan" : (expandedSection === "providers" ? "white" : "gray")}
450
- collapsed={expandedSection !== "providers"}
451
- >
452
- {opencodeInfo && <ProviderList providers={opencodeInfo.providers} />}
453
- </SectionBox>
454
-
455
- {/* Plugin Accounts Section */}
456
- <SectionBox
457
- title={`ACCOUNTS (${opencodeInfo?.plugins[0]?.name || "antigravity-auth"})`}
458
- borderColor={isOnSection("accounts") || (currentNavItem?.type === "account") ? "cyan" : (expandedSection === "accounts" ? "white" : "gray")}
459
- collapsed={expandedSection !== "accounts"}
460
- >
461
- <AccountList
462
- accounts={accounts}
463
- selectedIndex={currentNavItem?.type === "account" ? currentNavItem.index : -1}
464
- checkedEmails={checkedEmails}
465
- showCheckbox={true}
466
- />
467
- </SectionBox>
508
+ {/* Loading indicator */}
509
+ {isLoading && (
510
+ <Box marginBottom={1} paddingX={1}>
511
+ <Text color="cyan">
512
+ <Text color="cyan">⟳ </Text>
513
+ {loadingStep}
514
+ </Text>
515
+ </Box>
516
+ )}
468
517
 
469
- {/* MCP Servers Section */}
470
- <SectionBox
471
- title="MCP SERVERS"
472
- borderColor={isOnSection("mcp") ? "cyan" : (expandedSection === "mcp" ? "white" : "gray")}
473
- collapsed={expandedSection !== "mcp"}
474
- >
475
- {opencodeInfo && <McpServerList servers={opencodeInfo.mcpServers} />}
476
- </SectionBox>
518
+ {/* Tab content */}
519
+ {activeTab === "dashboard" ? (
520
+ // Dashboard Tab - Rate limits view like Antigravity Manager
521
+ <Box flexDirection="column" borderStyle="round" borderColor="cyan" padding={1}>
522
+ <DashboardView
523
+ accounts={accounts}
524
+ selectedIndex={dashboardIndex}
525
+ />
526
+ </Box>
527
+ ) : (
528
+ // Settings Tab - Original sections view
529
+ <>
530
+ <SectionBox
531
+ title="PROVIDERS"
532
+ borderColor={isOnSection("providers") ? "cyan" : (expandedSection === "providers" ? "white" : "gray")}
533
+ collapsed={expandedSection !== "providers"}
534
+ >
535
+ {opencodeInfo && <ProviderList providers={opencodeInfo.providers} />}
536
+ </SectionBox>
537
+
538
+ <SectionBox
539
+ title={`ACCOUNTS (${opencodeInfo?.plugins[0]?.name || "antigravity-auth"})`}
540
+ borderColor={isOnSection("accounts") || (currentSettingsItem?.type === "account") ? "cyan" : (expandedSection === "accounts" ? "white" : "gray")}
541
+ collapsed={expandedSection !== "accounts"}
542
+ >
543
+ <AccountList
544
+ accounts={accounts}
545
+ selectedIndex={currentSettingsItem?.type === "account" ? (currentSettingsItem.index ?? -1) : -1}
546
+ checkedEmails={checkedEmails}
547
+ showCheckbox={true}
548
+ />
549
+ </SectionBox>
550
+
551
+ <SectionBox
552
+ title="MCP SERVERS"
553
+ borderColor={isOnSection("mcp") ? "cyan" : (expandedSection === "mcp" ? "white" : "gray")}
554
+ collapsed={expandedSection !== "mcp"}
555
+ >
556
+ {opencodeInfo && <McpServerList servers={opencodeInfo.mcpServers} />}
557
+ </SectionBox>
558
+ </>
559
+ )}
477
560
 
478
561
  {/* Config path */}
479
562
  <Box marginTop={1}>
@@ -489,11 +572,7 @@ export function Dashboard({ pluginPath }: DashboardProps) {
489
572
 
490
573
  {/* Action Palette overlay */}
491
574
  {activeModal === "palette" && (
492
- <Box
493
- position="absolute"
494
- marginTop={3}
495
- marginLeft={10}
496
- >
575
+ <Box position="absolute" marginTop={3} marginLeft={10}>
497
576
  <ActionPalette
498
577
  actions={paletteActions}
499
578
  onSelect={handlePaletteAction}
@@ -0,0 +1,170 @@
1
+ import React from "react";
2
+ import { Box, Text } from "ink";
3
+ import { Account } from "../../core/types";
4
+
5
+ interface DashboardViewProps {
6
+ accounts: Account[];
7
+ selectedIndex: number;
8
+ }
9
+
10
+ // Model families for rate limit display
11
+ const MODEL_FAMILIES = ["claude", "gemini", "gpt", "deepseek", "o1", "o3"];
12
+
13
+ function formatTimeRemaining(resetTime: number): string {
14
+ const now = Date.now();
15
+ if (resetTime <= now) return "";
16
+
17
+ const remaining = resetTime - now;
18
+ const hours = Math.floor(remaining / 3600000);
19
+ const minutes = Math.floor((remaining % 3600000) / 60000);
20
+
21
+ if (hours > 0) {
22
+ return `${hours}h ${minutes}m`;
23
+ }
24
+ return `${minutes}m`;
25
+ }
26
+
27
+ function getAccountStatus(account: Account): { status: string; color: string } {
28
+ if (!account.enabled) {
29
+ return { status: "DISABLED", color: "gray" };
30
+ }
31
+
32
+ const now = Date.now();
33
+ const rateLimits = account.rateLimitResetTimes || {};
34
+ const limitedModels = Object.entries(rateLimits)
35
+ .filter(([_, time]) => time > now);
36
+
37
+ if (limitedModels.length === 0) {
38
+ return { status: "AVAILABLE", color: "green" };
39
+ }
40
+
41
+ return { status: "LIMITED", color: "yellow" };
42
+ }
43
+
44
+ function getRateLimitBar(account: Account, model: string): { bar: string; color: string; time: string } {
45
+ const now = Date.now();
46
+ const resetTime = account.rateLimitResetTimes?.[model] || 0;
47
+
48
+ if (resetTime <= now) {
49
+ return { bar: "████████", color: "green", time: "" };
50
+ }
51
+
52
+ // Calculate remaining time as percentage (assume 24h max)
53
+ const remaining = resetTime - now;
54
+ const maxTime = 24 * 3600000; // 24 hours
55
+ const percentage = Math.min(1, remaining / maxTime);
56
+ const filledBlocks = Math.round((1 - percentage) * 8);
57
+ const emptyBlocks = 8 - filledBlocks;
58
+
59
+ return {
60
+ bar: "█".repeat(filledBlocks) + "░".repeat(emptyBlocks),
61
+ color: percentage > 0.5 ? "red" : "yellow",
62
+ time: formatTimeRemaining(resetTime),
63
+ };
64
+ }
65
+
66
+ export function DashboardView({ accounts, selectedIndex }: DashboardViewProps) {
67
+ if (accounts.length === 0) {
68
+ return (
69
+ <Box flexDirection="column" padding={1}>
70
+ <Text dimColor>No accounts found. Press P to open actions and import accounts.</Text>
71
+ </Box>
72
+ );
73
+ }
74
+
75
+ // Get all unique models from accounts
76
+ const allModels = new Set<string>();
77
+ accounts.forEach(acc => {
78
+ if (acc.rateLimitResetTimes) {
79
+ Object.keys(acc.rateLimitResetTimes).forEach(m => allModels.add(m));
80
+ }
81
+ });
82
+
83
+ // Use predefined families or detected models
84
+ const displayModels = MODEL_FAMILIES.filter(m =>
85
+ accounts.some(acc => acc.rateLimitResetTimes?.[m])
86
+ );
87
+
88
+ if (displayModels.length === 0) {
89
+ displayModels.push("claude", "gemini"); // Default columns
90
+ }
91
+
92
+ return (
93
+ <Box flexDirection="column">
94
+ {/* Header row */}
95
+ <Box>
96
+ <Box width={30}>
97
+ <Text bold color="cyan">ACCOUNT</Text>
98
+ </Box>
99
+ <Box width={12}>
100
+ <Text bold color="cyan">STATUS</Text>
101
+ </Box>
102
+ {displayModels.map(model => (
103
+ <Box key={model} width={14}>
104
+ <Text bold color="cyan">{model.toUpperCase()}</Text>
105
+ </Box>
106
+ ))}
107
+ </Box>
108
+
109
+ {/* Separator */}
110
+ <Box>
111
+ <Text dimColor>{"─".repeat(30 + 12 + displayModels.length * 14)}</Text>
112
+ </Box>
113
+
114
+ {/* Account rows */}
115
+ {accounts.map((account, index) => {
116
+ const isSelected = index === selectedIndex;
117
+ const { status, color } = getAccountStatus(account);
118
+
119
+ // Truncate email
120
+ const emailDisplay = account.email.length > 28
121
+ ? account.email.slice(0, 25) + "..."
122
+ : account.email;
123
+
124
+ return (
125
+ <Box key={account.email}>
126
+ {/* Selection indicator */}
127
+ <Text color={isSelected ? "cyan" : undefined}>
128
+ {isSelected ? "▸ " : " "}
129
+ </Text>
130
+
131
+ {/* Email */}
132
+ <Box width={28}>
133
+ <Text
134
+ color={isSelected ? "cyan" : (account.enabled === false ? "gray" : "white")}
135
+ bold={isSelected}
136
+ >
137
+ {emailDisplay}
138
+ </Text>
139
+ </Box>
140
+
141
+ {/* Status */}
142
+ <Box width={12}>
143
+ <Text color={color}>{status}</Text>
144
+ </Box>
145
+
146
+ {/* Rate limit bars for each model */}
147
+ {displayModels.map(model => {
148
+ const { bar, color: barColor, time } = getRateLimitBar(account, model);
149
+ return (
150
+ <Box key={model} width={14}>
151
+ <Text color={barColor}>{bar}</Text>
152
+ {time && <Text dimColor> {time}</Text>}
153
+ </Box>
154
+ );
155
+ })}
156
+ </Box>
157
+ );
158
+ })}
159
+
160
+ {/* Legend */}
161
+ <Box marginTop={1}>
162
+ <Text dimColor>
163
+ <Text color="green">████</Text> Available
164
+ <Text color="yellow">░░░░</Text> Limited
165
+ <Text color="gray">████</Text> Disabled
166
+ </Text>
167
+ </Box>
168
+ </Box>
169
+ );
170
+ }
@@ -12,3 +12,4 @@ export { FileBrowser } from "./FileBrowser";
12
12
  export { ExportModal } from "./ExportModal";
13
13
  export { ImportModal } from "./ImportModal";
14
14
  export { ActionPalette, PaletteAction } from "./ActionPalette";
15
+ export { DashboardView } from "./DashboardView";