@thelioo/opencode-balancer 0.1.8 → 0.2.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.
Files changed (176) hide show
  1. package/INSTALL.txt +53 -25
  2. package/README.md +95 -51
  3. package/dist/core/accounts.ts +404 -0
  4. package/dist/core/database.ts +67 -0
  5. package/dist/core/events.ts +75 -0
  6. package/dist/core/native-auth-suppression.ts +36 -0
  7. package/dist/core/native-connect.ts +31 -0
  8. package/dist/core/path.ts +34 -0
  9. package/dist/core/pending.ts +351 -0
  10. package/dist/core/priority.ts +193 -0
  11. package/dist/core/schema.ts +439 -0
  12. package/dist/core/time.ts +3 -0
  13. package/dist/core/types.ts +72 -0
  14. package/dist/core/usage/index.ts +23 -0
  15. package/dist/core/usage/providers/copilot.ts +243 -0
  16. package/dist/core/usage/providers/openai.ts +179 -0
  17. package/dist/core/usage/redact.ts +80 -0
  18. package/dist/core/usage/store.ts +66 -0
  19. package/dist/core/usage/types.ts +24 -0
  20. package/dist/index.js +173 -4
  21. package/dist/index.js.map +1 -1
  22. package/dist/server/auth-watcher.ts +318 -0
  23. package/dist/server/commands.ts +58 -0
  24. package/dist/server/fetch-patch.ts +162 -0
  25. package/dist/server/index.ts +134 -0
  26. package/dist/server/native.ts +49 -0
  27. package/dist/server/request-balancer.ts +67 -0
  28. package/dist/tui/actions.ts +176 -112
  29. package/dist/tui/balancer-bar-sync.ts +55 -45
  30. package/dist/tui/components/alias-dialog.tsx +71 -56
  31. package/dist/tui/components/dashboard.tsx +530 -358
  32. package/dist/tui/components/priority-screen.tsx +389 -267
  33. package/dist/tui/components/provider-model-dialog.tsx +71 -64
  34. package/dist/tui/components/rename-dialog.tsx +35 -28
  35. package/dist/tui/components/sidebar.tsx +103 -79
  36. package/dist/tui/components/status-indicator.tsx +78 -59
  37. package/dist/tui/components/usage-bar.tsx +18 -7
  38. package/dist/tui/components/usage-display.tsx +32 -16
  39. package/dist/tui/connect.ts +104 -73
  40. package/dist/tui/dashboard-keys.ts +53 -41
  41. package/dist/tui/native-model-apply.ts +45 -36
  42. package/dist/tui/priority-keys.ts +44 -36
  43. package/dist/tui/provider-models.ts +32 -25
  44. package/dist/tui/responsive.ts +10 -7
  45. package/dist/tui/selected-account-bar-sync.ts +23 -23
  46. package/dist/tui/selection-colors.ts +38 -30
  47. package/dist/tui/state.ts +61 -44
  48. package/dist/tui/status-format.ts +24 -20
  49. package/dist/tui/tui.js +165 -153
  50. package/dist/tui/tui.js.map +1 -1
  51. package/dist/tui/tui.tsx +194 -144
  52. package/dist/tui/usage-auto-refresh.ts +52 -45
  53. package/dist/tui/usage-format.ts +9 -9
  54. package/package.json +61 -52
  55. package/dist/core/accounts.d.ts +0 -14
  56. package/dist/core/accounts.js +0 -260
  57. package/dist/core/accounts.js.map +0 -1
  58. package/dist/core/database.d.ts +0 -4
  59. package/dist/core/database.js +0 -69
  60. package/dist/core/database.js.map +0 -1
  61. package/dist/core/events.d.ts +0 -18
  62. package/dist/core/events.js +0 -39
  63. package/dist/core/events.js.map +0 -1
  64. package/dist/core/native-auth-suppression.d.ts +0 -3
  65. package/dist/core/native-auth-suppression.js +0 -19
  66. package/dist/core/native-auth-suppression.js.map +0 -1
  67. package/dist/core/native-connect.d.ts +0 -4
  68. package/dist/core/native-connect.js +0 -19
  69. package/dist/core/native-connect.js.map +0 -1
  70. package/dist/core/path.d.ts +0 -4
  71. package/dist/core/path.js +0 -26
  72. package/dist/core/path.js.map +0 -1
  73. package/dist/core/pending.d.ts +0 -9
  74. package/dist/core/pending.js +0 -237
  75. package/dist/core/pending.js.map +0 -1
  76. package/dist/core/priority.d.ts +0 -20
  77. package/dist/core/priority.js +0 -120
  78. package/dist/core/priority.js.map +0 -1
  79. package/dist/core/schema.d.ts +0 -2
  80. package/dist/core/schema.js +0 -265
  81. package/dist/core/schema.js.map +0 -1
  82. package/dist/core/time.d.ts +0 -1
  83. package/dist/core/time.js +0 -4
  84. package/dist/core/time.js.map +0 -1
  85. package/dist/core/types.d.ts +0 -59
  86. package/dist/core/types.js +0 -2
  87. package/dist/core/types.js.map +0 -1
  88. package/dist/core/usage/index.d.ts +0 -4
  89. package/dist/core/usage/index.js +0 -16
  90. package/dist/core/usage/index.js.map +0 -1
  91. package/dist/core/usage/providers/copilot.d.ts +0 -2
  92. package/dist/core/usage/providers/copilot.js +0 -169
  93. package/dist/core/usage/providers/copilot.js.map +0 -1
  94. package/dist/core/usage/providers/openai.d.ts +0 -2
  95. package/dist/core/usage/providers/openai.js +0 -133
  96. package/dist/core/usage/providers/openai.js.map +0 -1
  97. package/dist/core/usage/redact.d.ts +0 -3
  98. package/dist/core/usage/redact.js +0 -67
  99. package/dist/core/usage/redact.js.map +0 -1
  100. package/dist/core/usage/store.d.ts +0 -4
  101. package/dist/core/usage/store.js +0 -31
  102. package/dist/core/usage/store.js.map +0 -1
  103. package/dist/core/usage/types.d.ts +0 -21
  104. package/dist/core/usage/types.js +0 -2
  105. package/dist/core/usage/types.js.map +0 -1
  106. package/dist/index.d.ts +0 -5
  107. package/dist/server/auth-watcher.d.ts +0 -32
  108. package/dist/server/auth-watcher.js +0 -227
  109. package/dist/server/auth-watcher.js.map +0 -1
  110. package/dist/server/commands.d.ts +0 -2
  111. package/dist/server/commands.js +0 -46
  112. package/dist/server/commands.js.map +0 -1
  113. package/dist/server/fetch-patch.d.ts +0 -3
  114. package/dist/server/fetch-patch.js +0 -118
  115. package/dist/server/fetch-patch.js.map +0 -1
  116. package/dist/server/index.d.ts +0 -8
  117. package/dist/server/index.js +0 -94
  118. package/dist/server/index.js.map +0 -1
  119. package/dist/server/native.d.ts +0 -6
  120. package/dist/server/native.js +0 -35
  121. package/dist/server/native.js.map +0 -1
  122. package/dist/server/request-balancer.d.ts +0 -16
  123. package/dist/server/request-balancer.js +0 -43
  124. package/dist/server/request-balancer.js.map +0 -1
  125. package/dist/tui/actions.d.ts +0 -41
  126. package/dist/tui/actions.js +0 -92
  127. package/dist/tui/actions.js.map +0 -1
  128. package/dist/tui/balancer-bar-sync.d.ts +0 -19
  129. package/dist/tui/balancer-bar-sync.js +0 -45
  130. package/dist/tui/balancer-bar-sync.js.map +0 -1
  131. package/dist/tui/components/alias-dialog.d.ts +0 -4
  132. package/dist/tui/components/dashboard.d.ts +0 -12
  133. package/dist/tui/components/priority-screen.d.ts +0 -9
  134. package/dist/tui/components/provider-model-dialog.d.ts +0 -14
  135. package/dist/tui/components/rename-dialog.d.ts +0 -4
  136. package/dist/tui/components/sidebar.d.ts +0 -10
  137. package/dist/tui/components/status-indicator.d.ts +0 -9
  138. package/dist/tui/components/usage-bar.d.ts +0 -8
  139. package/dist/tui/components/usage-display.d.ts +0 -10
  140. package/dist/tui/connect.d.ts +0 -30
  141. package/dist/tui/connect.js +0 -75
  142. package/dist/tui/connect.js.map +0 -1
  143. package/dist/tui/dashboard-keys.d.ts +0 -45
  144. package/dist/tui/dashboard-keys.js +0 -44
  145. package/dist/tui/dashboard-keys.js.map +0 -1
  146. package/dist/tui/native-model-apply.d.ts +0 -21
  147. package/dist/tui/native-model-apply.js +0 -53
  148. package/dist/tui/native-model-apply.js.map +0 -1
  149. package/dist/tui/priority-keys.d.ts +0 -40
  150. package/dist/tui/priority-keys.js +0 -38
  151. package/dist/tui/priority-keys.js.map +0 -1
  152. package/dist/tui/provider-models.d.ts +0 -19
  153. package/dist/tui/provider-models.js +0 -17
  154. package/dist/tui/provider-models.js.map +0 -1
  155. package/dist/tui/responsive.d.ts +0 -9
  156. package/dist/tui/responsive.js +0 -13
  157. package/dist/tui/responsive.js.map +0 -1
  158. package/dist/tui/selected-account-bar-sync.d.ts +0 -10
  159. package/dist/tui/selected-account-bar-sync.js +0 -26
  160. package/dist/tui/selected-account-bar-sync.js.map +0 -1
  161. package/dist/tui/selection-colors.d.ts +0 -10
  162. package/dist/tui/selection-colors.js +0 -38
  163. package/dist/tui/selection-colors.js.map +0 -1
  164. package/dist/tui/state.d.ts +0 -14
  165. package/dist/tui/state.js +0 -46
  166. package/dist/tui/state.js.map +0 -1
  167. package/dist/tui/status-format.d.ts +0 -15
  168. package/dist/tui/status-format.js +0 -17
  169. package/dist/tui/status-format.js.map +0 -1
  170. package/dist/tui/tui.d.ts +0 -7
  171. package/dist/tui/usage-auto-refresh.d.ts +0 -16
  172. package/dist/tui/usage-auto-refresh.js +0 -46
  173. package/dist/tui/usage-auto-refresh.js.map +0 -1
  174. package/dist/tui/usage-format.d.ts +0 -2
  175. package/dist/tui/usage-format.js +0 -17
  176. package/dist/tui/usage-format.js.map +0 -1
@@ -1,43 +0,0 @@
1
- import { getAccount, listAccounts, normalizeAlias } from "../core/accounts";
2
- import { now } from "../core/time";
3
- export const INTERNAL_REQUEST_HEADER = "x-opencode-balancer-request";
4
- export const BALANCER_METADATA_KEY = "opencodeBalancerCommand";
5
- export const RETRYABLE_STATUS = new Set([429, 500, 502, 503, 504, 529]);
6
- const pendingRequests = new Map();
7
- export function setPendingRequest(requestID, request) {
8
- pendingRequests.set(requestID, request);
9
- }
10
- export function takePendingRequest(requestID) {
11
- const request = pendingRequests.get(requestID);
12
- pendingRequests.delete(requestID);
13
- return request;
14
- }
15
- export function __testGetPendingRequest(requestID) {
16
- return pendingRequests.get(requestID);
17
- }
18
- export function __testClearPendingRequests() {
19
- pendingRequests.clear();
20
- }
21
- export function markRateLimited(db, providerID, alias, retryAfterMs = 60_000) {
22
- const account = getAccount(db, providerID, alias);
23
- if (!account)
24
- return;
25
- const timestamp = now();
26
- db.query(`UPDATE accounts
27
- SET failures = failures + 1,
28
- rate_limited_until = ?,
29
- updated_at = ?
30
- WHERE provider_id = ? AND alias = ?`).run(timestamp + retryAfterMs, timestamp, providerID, account.alias);
31
- }
32
- export function chooseFailoverAccount(db, providerID, currentAlias) {
33
- const timestamp = now();
34
- const normalizedCurrentAlias = normalizeAlias(currentAlias);
35
- return listAccounts(db, providerID).find((account) => {
36
- if (account.alias === normalizedCurrentAlias)
37
- return false;
38
- if (account.disabled)
39
- return false;
40
- return !account.rateLimitedUntil || account.rateLimitedUntil <= timestamp;
41
- });
42
- }
43
- //# sourceMappingURL=request-balancer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"request-balancer.js","sourceRoot":"","sources":["../../src/server/request-balancer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGnC,MAAM,CAAC,MAAM,uBAAuB,GAAG,6BAA6B,CAAC;AACrE,MAAM,CAAC,MAAM,qBAAqB,GAAG,yBAAyB,CAAC;AAE/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAOxE,MAAM,eAAe,GAAG,IAAI,GAAG,EAA0B,CAAC;AAE1D,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAE,OAAuB;IACxE,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAChD,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC/C,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAClC,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACrD,OAAO,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,0BAA0B;IACtC,eAAe,CAAC,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,eAAe,CAC3B,EAAY,EACZ,UAAkB,EAClB,KAAa,EACb,YAAY,GAAG,MAAM;IAErB,MAAM,OAAO,GAAG,UAAU,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IAClD,IAAI,CAAC,OAAO;QAAE,OAAO;IAErB,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;IACxB,EAAE,CAAC,KAAK,CACJ;;;;6CAIqC,CACxC,CAAC,GAAG,CAAC,SAAS,GAAG,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,qBAAqB,CACjC,EAAY,EACZ,UAAkB,EAClB,YAAoB;IAEpB,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;IACxB,MAAM,sBAAsB,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;IAC5D,OAAO,YAAY,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;QACjD,IAAI,OAAO,CAAC,KAAK,KAAK,sBAAsB;YAAE,OAAO,KAAK,CAAC;QAC3D,IAAI,OAAO,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QACnC,OAAO,CAAC,OAAO,CAAC,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,IAAI,SAAS,CAAC;IAC9E,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,41 +0,0 @@
1
- import { refreshAccountUsage } from "../core/usage";
2
- import type { BalancerTuiState } from "./state";
3
- type AuthSetApi = {
4
- client: {
5
- auth: {
6
- set: (input: any) => unknown;
7
- };
8
- };
9
- keymap?: {
10
- dispatchCommand?: (command: string) => unknown;
11
- };
12
- ui?: {
13
- toast: (input: {
14
- variant: "success" | "warning" | "error" | "info";
15
- message: string;
16
- }) => unknown;
17
- };
18
- };
19
- type ActivateAccountOptions = {
20
- sessionProviderID?: string;
21
- applyNativeProviderModel?: (providerID: string) => Promise<boolean>;
22
- };
23
- type ToastApi = {
24
- ui: {
25
- toast: (input: {
26
- variant: "success" | "warning" | "error" | "info";
27
- message: string;
28
- }) => unknown;
29
- };
30
- };
31
- type RefreshUsageOptions = {
32
- refreshUsage?: typeof refreshAccountUsage;
33
- silent?: boolean;
34
- };
35
- export declare function savePendingAlias(state: BalancerTuiState, pendingID: string, alias: string): import("../core/types").Account;
36
- export declare function activateAccount(api: AuthSetApi, state: BalancerTuiState, providerID: string, alias: string, options?: ActivateAccountOptions): Promise<void>;
37
- export declare function refreshUsageForAccount(api: ToastApi, state: BalancerTuiState, providerID: string, alias: string, options?: RefreshUsageOptions): Promise<void>;
38
- export declare function removeAccountFromTui(api: ToastApi, state: BalancerTuiState, providerID: string, alias: string): void;
39
- export declare function renameAccountFromTui(api: ToastApi, state: BalancerTuiState, providerID: string, alias: string, nextAlias: string): import("../core/types").Account;
40
- export declare function removePendingFromTui(api: ToastApi, state: BalancerTuiState, pendingID: string): void;
41
- export {};
@@ -1,92 +0,0 @@
1
- import { getAccount, getActiveAccount, getSelectedAccount, removeAccount, renameAccount, setActiveAccount } from "../core/accounts";
2
- import { appendEvent } from "../core/events";
3
- import { completePendingConnection, removePendingConnection } from "../core/pending";
4
- import { refreshAccountUsage } from "../core/usage";
5
- import { saveUsageSnapshot } from "../core/usage/store";
6
- import { suppressNativeAuthCapture } from "../core/native-auth-suppression";
7
- export function savePendingAlias(state, pendingID, alias) {
8
- const account = completePendingConnection(state.db, pendingID, alias);
9
- state.refresh();
10
- return account;
11
- }
12
- export async function activateAccount(api, state, providerID, alias, options = {}) {
13
- const previousProviderID = getSelectedAccount(state.db)?.providerID;
14
- const account = setActiveAccount(state.db, providerID, alias) ?? getActiveAccount(state.db, providerID);
15
- if (account) {
16
- try {
17
- suppressNativeAuthCapture(state.db, providerID);
18
- await api.client.auth.set({ path: { id: providerID }, body: account.auth });
19
- }
20
- catch { }
21
- }
22
- state.refresh();
23
- const providerChanged = (options.sessionProviderID ?? previousProviderID) !== providerID;
24
- if (providerChanged) {
25
- await options.applyNativeProviderModel?.(providerID);
26
- }
27
- api.ui?.toast({ variant: "success", message: `Activated ${providerID}/${alias}.` });
28
- }
29
- export async function refreshUsageForAccount(api, state, providerID, alias, options = {}) {
30
- const account = getAccount(state.db, providerID, alias) ?? state.accounts().find((candidate) => {
31
- return candidate.providerID === providerID && candidate.alias === alias;
32
- });
33
- if (!account) {
34
- api.ui.toast({ variant: "error", message: `Account not found: ${providerID}/${alias}` });
35
- return;
36
- }
37
- try {
38
- const snapshot = await (options.refreshUsage ?? refreshAccountUsage)(account);
39
- saveUsageSnapshot(state.db, snapshot);
40
- appendEvent(state.db, {
41
- type: snapshot.confidence === "unavailable" ? "usage_unavailable" : "usage_refreshed",
42
- providerID,
43
- alias,
44
- message: snapshot.message,
45
- });
46
- state.refresh();
47
- if (!options.silent) {
48
- api.ui.toast({
49
- variant: snapshot.confidence === "unavailable" ? "warning" : "success",
50
- message: snapshot.message,
51
- });
52
- }
53
- }
54
- catch (error) {
55
- const message = error instanceof Error ? error.message : "Usage refresh failed.";
56
- api.ui.toast({ variant: "error", message });
57
- }
58
- }
59
- export function removeAccountFromTui(api, state, providerID, alias) {
60
- const removed = removeAccount(state.db, providerID, alias);
61
- if (!removed) {
62
- api.ui.toast({ variant: "error", message: `Account not found: ${providerID}/${alias}` });
63
- return;
64
- }
65
- const message = `Removed account ${providerID}/${alias}.`;
66
- appendEvent(state.db, {
67
- type: "account_removed",
68
- providerID,
69
- alias,
70
- message,
71
- });
72
- state.refresh();
73
- state.removeAccountView(providerID, alias);
74
- api.ui.toast({ variant: "success", message });
75
- }
76
- export function renameAccountFromTui(api, state, providerID, alias, nextAlias) {
77
- const account = renameAccount(state.db, providerID, alias, nextAlias);
78
- state.refresh();
79
- api.ui.toast({ variant: "success", message: `Renamed ${providerID}/${alias} to ${account.alias}.` });
80
- return account;
81
- }
82
- export function removePendingFromTui(api, state, pendingID) {
83
- const removed = removePendingConnection(state.db, pendingID);
84
- if (!removed) {
85
- api.ui.toast({ variant: "error", message: "Pending connection not found." });
86
- return;
87
- }
88
- state.refresh();
89
- state.removePendingView(pendingID);
90
- api.ui.toast({ variant: "success", message: "Removed pending connection." });
91
- }
92
- //# sourceMappingURL=actions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/tui/actions.ts"],"names":[],"mappings":"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"}
@@ -1,19 +0,0 @@
1
- import type { TuiPluginApi } from "@opencode-ai/plugin/tui";
2
- import type { BalancerTuiState } from "./state";
3
- import { type NativeModelApplier } from "./native-model-apply";
4
- export type BalancerBarSyncDeps = {
5
- balancingEnabled: () => boolean;
6
- dialogOpen: () => boolean;
7
- activeSelection: () => {
8
- providerID: string;
9
- modelID: string;
10
- } | undefined;
11
- modelTitle: (providerID: string, modelID: string) => string | undefined;
12
- apply: NativeModelApplier;
13
- };
14
- export declare function createBalancerBarSync(deps: BalancerBarSyncDeps): {
15
- maybeSync: () => Promise<boolean>;
16
- };
17
- export declare function createTuiBalancerBarSync(api: TuiPluginApi, state: BalancerTuiState): {
18
- maybeSync: () => Promise<boolean>;
19
- };
@@ -1,45 +0,0 @@
1
- import { getBalancingEnabled, resolveActiveSelection } from "../core/priority";
2
- import { createNativeModelApplier } from "./native-model-apply";
3
- export function createBalancerBarSync(deps) {
4
- let lastApplied;
5
- let applying = false;
6
- const maybeSync = async () => {
7
- if (!deps.balancingEnabled()) {
8
- lastApplied = undefined;
9
- return false;
10
- }
11
- if (applying || deps.dialogOpen())
12
- return false;
13
- const selection = deps.activeSelection();
14
- if (!selection)
15
- return false;
16
- const key = `${selection.providerID}/${selection.modelID}`;
17
- if (key === lastApplied)
18
- return false;
19
- const title = deps.modelTitle(selection.providerID, selection.modelID) ?? selection.modelID;
20
- applying = true;
21
- try {
22
- const applied = await deps.apply(selection, title);
23
- if (applied)
24
- lastApplied = key;
25
- return applied;
26
- }
27
- finally {
28
- applying = false;
29
- }
30
- };
31
- return { maybeSync };
32
- }
33
- export function createTuiBalancerBarSync(api, state) {
34
- return createBalancerBarSync({
35
- balancingEnabled: () => getBalancingEnabled(state.db),
36
- dialogOpen: () => api.ui.dialog.open,
37
- activeSelection: () => resolveActiveSelection(state.db),
38
- modelTitle: (providerID, modelID) => {
39
- const provider = api.state.provider.find((item) => item.id === providerID);
40
- return provider?.models?.[modelID]?.name;
41
- },
42
- apply: createNativeModelApplier(api),
43
- });
44
- }
45
- //# sourceMappingURL=balancer-bar-sync.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"balancer-bar-sync.js","sourceRoot":"","sources":["../../src/tui/balancer-bar-sync.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,OAAO,EAAE,wBAAwB,EAA2B,MAAM,sBAAsB,CAAC;AAUzF,MAAM,UAAU,qBAAqB,CAAC,IAAyB;IAC3D,IAAI,WAA+B,CAAC;IACpC,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;QACzB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;YAC3B,WAAW,GAAG,SAAS,CAAC;YACxB,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE;YAAE,OAAO,KAAK,CAAC;QAEhD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,SAAS;YAAE,OAAO,KAAK,CAAC;QAE7B,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC,UAAU,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;QAC3D,IAAI,GAAG,KAAK,WAAW;YAAE,OAAO,KAAK,CAAC;QAEtC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,OAAO,CAAC;QAC5F,QAAQ,GAAG,IAAI,CAAC;QAChB,IAAI,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACnD,IAAI,OAAO;gBAAE,WAAW,GAAG,GAAG,CAAC;YAC/B,OAAO,OAAO,CAAC;QACnB,CAAC;gBAAS,CAAC;YACP,QAAQ,GAAG,KAAK,CAAC;QACrB,CAAC;IACL,CAAC,CAAC;IAEF,OAAO,EAAE,SAAS,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAiB,EAAE,KAAuB;IAC/E,OAAO,qBAAqB,CAAC;QACzB,gBAAgB,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;QACrD,UAAU,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI;QACpC,eAAe,EAAE,GAAG,EAAE,CAAC,sBAAsB,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,UAAU,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE;YAChC,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;YAC3E,OAAO,QAAQ,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC;QAC7C,CAAC;QACD,KAAK,EAAE,wBAAwB,CAAC,GAAG,CAAC;KACvC,CAAC,CAAC;AACP,CAAC"}
@@ -1,4 +0,0 @@
1
- /** @jsxImportSource @opentui/solid */
2
- import type { TuiPluginApi } from "@opencode-ai/plugin/tui";
3
- import type { BalancerTuiState } from "../state";
4
- export declare function openAliasDialog(api: TuiPluginApi, state: BalancerTuiState, pendingID: string): boolean;
@@ -1,12 +0,0 @@
1
- /** @jsxImportSource @opentui/solid */
2
- import type { TuiPluginApi } from "@opencode-ai/plugin/tui";
3
- import type { BalancerTuiState } from "../state";
4
- export declare function Dashboard(props: {
5
- api: TuiPluginApi;
6
- state: BalancerTuiState;
7
- onBack: () => void;
8
- openPriority: () => void;
9
- openConnect: () => void;
10
- renameAccount: (providerID: string, alias: string) => void;
11
- removeAccount: (providerID: string, alias: string) => void;
12
- }): any;
@@ -1,9 +0,0 @@
1
- /** @jsxImportSource @opentui/solid */
2
- import type { TuiPluginApi } from "@opencode-ai/plugin/tui";
3
- import type { BalancerTuiState } from "../state";
4
- export declare function PriorityScreen(props: {
5
- api: TuiPluginApi;
6
- state: BalancerTuiState;
7
- onBack: () => void;
8
- openModelPicker: (providerID: string, onComplete?: () => void) => void;
9
- }): any;
@@ -1,14 +0,0 @@
1
- /** @jsxImportSource @opentui/solid */
2
- import type { TuiPluginApi } from "@opencode-ai/plugin/tui";
3
- import { type NativeModelApplier } from "../native-model-apply";
4
- import type { BalancerTuiState } from "../state";
5
- type OpenProviderModelDialogOptions = {
6
- applyNativeSelection?: NativeModelApplier | false;
7
- onComplete?: () => void;
8
- onSelected?: (model: {
9
- providerID: string;
10
- modelID: string;
11
- }) => void;
12
- };
13
- export declare function openProviderModelDialog(api: TuiPluginApi, state: Pick<BalancerTuiState, "db" | "refresh">, providerID: string, options?: OpenProviderModelDialogOptions): void;
14
- export {};
@@ -1,4 +0,0 @@
1
- /** @jsxImportSource @opentui/solid */
2
- import type { TuiPluginApi } from "@opencode-ai/plugin/tui";
3
- import type { BalancerTuiState } from "../state";
4
- export declare function openRenameDialog(api: TuiPluginApi, state: BalancerTuiState, providerID: string, alias: string): void;
@@ -1,10 +0,0 @@
1
- /** @jsxImportSource @opentui/solid */
2
- import type { TuiPluginApi } from "@opencode-ai/plugin/tui";
3
- import type { BalancerTuiState } from "../state";
4
- export type BalancerSidebarProps = {
5
- api: TuiPluginApi;
6
- state: BalancerTuiState;
7
- openDashboard: () => void;
8
- activateAccount: (providerID: string, alias: string) => void;
9
- };
10
- export declare function BalancerSidebar(props: BalancerSidebarProps): any;
@@ -1,9 +0,0 @@
1
- /** @jsxImportSource @opentui/solid */
2
- import type { TuiPluginApi } from "@opencode-ai/plugin/tui";
3
- import type { BalancerTuiState } from "../state";
4
- export type BalancerStatusIndicatorProps = {
5
- api: TuiPluginApi;
6
- state: BalancerTuiState;
7
- providerID?: string | (() => string | undefined);
8
- };
9
- export declare function BalancerStatusIndicator(props: BalancerStatusIndicatorProps): any;
@@ -1,8 +0,0 @@
1
- /** @jsxImportSource @opentui/solid */
2
- import type { TuiThemeCurrent } from "@opencode-ai/plugin/tui";
3
- export declare function UsageBar(props: {
4
- theme: TuiThemeCurrent;
5
- percent?: number;
6
- label: string;
7
- muted?: boolean;
8
- }): any;
@@ -1,10 +0,0 @@
1
- /** @jsxImportSource @opentui/solid */
2
- import type { TuiThemeCurrent } from "@opencode-ai/plugin/tui";
3
- import type { ProviderUsageSnapshot } from "../../core/usage/types";
4
- export declare function snapshotPercent(snapshot: ProviderUsageSnapshot | undefined): number | undefined;
5
- export declare function snapshotLabel(snapshot: ProviderUsageSnapshot | undefined): string;
6
- export declare function UsageSnapshotBar(props: {
7
- theme: TuiThemeCurrent;
8
- snapshot?: ProviderUsageSnapshot;
9
- muted?: boolean;
10
- }): any;
@@ -1,30 +0,0 @@
1
- import type { Database } from "bun:sqlite";
2
- import type { AuthInfo } from "../core/types";
3
- type NativeAuthReadResult = {
4
- ok: true;
5
- auth: Record<string, AuthInfo>;
6
- } | {
7
- ok: false;
8
- };
9
- type ConnectApi = {
10
- db?: Database;
11
- readAuth?: () => NativeAuthReadResult;
12
- generateAlias?: () => string;
13
- wait?: (ms: number) => Promise<void>;
14
- maxWaitMs?: number;
15
- pollIntervalMs?: number;
16
- keymap?: {
17
- dispatchCommand?: (command: string) => unknown;
18
- };
19
- ui?: {
20
- dialog?: {
21
- open?: boolean;
22
- };
23
- toast?: (input: {
24
- variant: "success" | "error";
25
- message: string;
26
- }) => unknown;
27
- };
28
- };
29
- export declare function openNativeConnect(api: ConnectApi): Promise<void>;
30
- export {};
@@ -1,75 +0,0 @@
1
- import { listAccounts, saveAccount } from "../core/accounts";
2
- import { clearNativeConnectInProgress, markNativeConnectInProgress } from "../core/native-connect";
3
- import { readNativeAuth, sameSavedAuth } from "../server/auth-watcher";
4
- const aliasAlphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
5
- function generatedAlias() {
6
- let alias = "";
7
- for (let index = 0; index < 5; index++)
8
- alias += aliasAlphabet[Math.floor(Math.random() * aliasAlphabet.length)];
9
- return alias;
10
- }
11
- function authKey(auth) {
12
- return JSON.stringify(auth ?? null);
13
- }
14
- function changedProvider(before, after) {
15
- return Object.entries(after).find(([providerID, auth]) => authKey(before[providerID]) !== authKey(auth));
16
- }
17
- function uniqueAlias(db, providerID, generate) {
18
- for (let attempt = 0; attempt < 100; attempt++) {
19
- const alias = generate();
20
- const existing = db
21
- .query("SELECT alias FROM accounts WHERE provider_id = ? AND alias = ?")
22
- .get(providerID, alias);
23
- if (!existing)
24
- return alias;
25
- }
26
- throw new Error("Could not generate a unique alias");
27
- }
28
- async function waitForChangedProvider(readAuth, before, options) {
29
- const started = Date.now();
30
- while (true) {
31
- const after = readAuth();
32
- if (before.ok && after.ok) {
33
- const changed = changedProvider(before.auth, after.auth);
34
- if (changed)
35
- return changed;
36
- }
37
- if (Date.now() - started >= options.maxWaitMs)
38
- return;
39
- await options.wait(options.pollIntervalMs);
40
- }
41
- }
42
- export async function openNativeConnect(api) {
43
- if (api.keymap?.dispatchCommand) {
44
- const readAuth = api.readAuth ?? readNativeAuth;
45
- const before = readAuth();
46
- if (api.db)
47
- markNativeConnectInProgress(api.db);
48
- await api.keymap.dispatchCommand("provider.connect");
49
- if (api.db) {
50
- try {
51
- const changed = await waitForChangedProvider(readAuth, before, {
52
- wait: api.wait ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms))),
53
- maxWaitMs: api.maxWaitMs ?? (api.ui?.dialog ? 10 * 60 * 1000 : 0),
54
- pollIntervalMs: api.pollIntervalMs ?? 500,
55
- });
56
- if (changed) {
57
- const [providerID, auth] = changed;
58
- const existing = listAccounts(api.db, providerID).find((candidate) => sameSavedAuth(candidate.auth, auth));
59
- const alias = existing?.alias ?? uniqueAlias(api.db, providerID, api.generateAlias ?? generatedAlias);
60
- const account = saveAccount(api.db, providerID, alias, auth);
61
- api.ui?.toast?.({ variant: "success", message: `Saved ${account.providerID}/${account.alias}.` });
62
- }
63
- }
64
- finally {
65
- clearNativeConnectInProgress(api.db);
66
- }
67
- }
68
- return;
69
- }
70
- api.ui?.toast?.({
71
- variant: "error",
72
- message: "Native provider connect is unavailable in this opencode build.",
73
- });
74
- }
75
- //# sourceMappingURL=connect.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/tui/connect.ts"],"names":[],"mappings":"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"}
@@ -1,45 +0,0 @@
1
- export type DashboardKey = {
2
- name: string;
3
- };
4
- export type DashboardIntent = {
5
- type: "move-cursor";
6
- delta: -1 | 1;
7
- } | {
8
- type: "move-header";
9
- delta: -1 | 1;
10
- } | {
11
- type: "primary";
12
- } | {
13
- type: "priority";
14
- } | {
15
- type: "connect";
16
- } | {
17
- type: "alias";
18
- } | {
19
- type: "rename";
20
- } | {
21
- type: "remove";
22
- } | {
23
- type: "confirm";
24
- } | {
25
- type: "cancel";
26
- } | {
27
- type: "back";
28
- } | {
29
- type: "none";
30
- };
31
- export type DashboardFocusArea = "header" | "content";
32
- export declare function moveDashboardFocus(state: {
33
- area: DashboardFocusArea;
34
- cursor: number;
35
- rowCount: number;
36
- }, delta: -1 | 1): {
37
- area: DashboardFocusArea;
38
- cursor: number;
39
- };
40
- export declare function dashboardSelectionMarker(input: {
41
- focusedArea: DashboardFocusArea;
42
- itemArea: DashboardFocusArea;
43
- selected: boolean;
44
- }): "▶" | " ";
45
- export declare function reduceDashboardKey(key: DashboardKey): DashboardIntent;
@@ -1,44 +0,0 @@
1
- export function moveDashboardFocus(state, delta) {
2
- if (state.area === "header") {
3
- return delta > 0 ? { area: "content", cursor: Math.max(0, Math.min(state.cursor, state.rowCount - 1)) } : { area: "header", cursor: state.cursor };
4
- }
5
- if (delta < 0 && state.cursor <= 0)
6
- return { area: "header", cursor: 0 };
7
- return {
8
- area: "content",
9
- cursor: Math.max(0, Math.min(state.cursor + delta, Math.max(0, state.rowCount - 1))),
10
- };
11
- }
12
- export function dashboardSelectionMarker(input) {
13
- return input.selected && input.focusedArea === input.itemArea ? "▶" : " ";
14
- }
15
- export function reduceDashboardKey(key) {
16
- if (key.name === "up" || key.name === "k")
17
- return { type: "move-cursor", delta: -1 };
18
- if (key.name === "down" || key.name === "j")
19
- return { type: "move-cursor", delta: 1 };
20
- if (key.name === "left" || key.name === "h")
21
- return { type: "move-header", delta: -1 };
22
- if (key.name === "right" || key.name === "l")
23
- return { type: "move-header", delta: 1 };
24
- if (key.name === "return" || key.name === "space")
25
- return { type: "primary" };
26
- if (key.name === "p")
27
- return { type: "priority" };
28
- if (key.name === "c")
29
- return { type: "connect" };
30
- if (key.name === "a")
31
- return { type: "alias" };
32
- if (key.name === "r")
33
- return { type: "rename" };
34
- if (key.name === "d")
35
- return { type: "remove" };
36
- if (key.name === "y")
37
- return { type: "confirm" };
38
- if (key.name === "n")
39
- return { type: "cancel" };
40
- if (key.name === "escape")
41
- return { type: "back" };
42
- return { type: "none" };
43
- }
44
- //# sourceMappingURL=dashboard-keys.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard-keys.js","sourceRoot":"","sources":["../../src/tui/dashboard-keys.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,kBAAkB,CAC9B,KAAqE,EACrE,KAAa;IAEb,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;IACvJ,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAEzE,OAAO;QACH,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;KACvF,CAAC;AACN,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAIxC;IACG,OAAO,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAiB;IAChD,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;IACrF,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IACtF,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;IACvF,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IACvF,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC9E,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAClD,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IACjD,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC/C,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAChD,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAChD,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IACjD,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAChD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACnD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC"}
@@ -1,21 +0,0 @@
1
- import type { TuiPluginApi } from "@opencode-ai/plugin/tui";
2
- export type NativeModelApplier = (model: {
3
- providerID: string;
4
- modelID: string;
5
- }, title: string) => Promise<boolean>;
6
- export type NativeModelApplyDeps = {
7
- dispatchCommand: (command: string) => void;
8
- isDialogOpen: () => boolean;
9
- feed: (sequence: string) => boolean;
10
- wait: (ms: number) => Promise<void>;
11
- settleMs?: number;
12
- };
13
- /**
14
- * Drive opencode's native model dialog to select `title`:
15
- * 1. open it via the native `model.list` command
16
- * 2. type the model title to filter the list down to the target
17
- * 3. press Enter to select -> opencode runs `local.model.set` and the bar updates
18
- * 4. dismiss a follow-up variant dialog if one appears
19
- */
20
- export declare function applyNativeModelSelection(deps: NativeModelApplyDeps, title: string): Promise<boolean>;
21
- export declare function createNativeModelApplier(api: TuiPluginApi): NativeModelApplier;
@@ -1,53 +0,0 @@
1
- const ENTER = "\r";
2
- const ESCAPE = "\x1B";
3
- function rendererStdin(api) {
4
- const stdin = api.renderer?.stdin;
5
- return stdin && typeof stdin.emit === "function" ? stdin : undefined;
6
- }
7
- /**
8
- * Feed a raw input sequence into opencode's renderer, exactly like a real
9
- * keypress. opencode's stdin parser dispatches it to the focused element, so
10
- * this drives opencode's own UI even though the plugin runs in a separate
11
- * Solid instance and cannot touch opencode's reactive state directly.
12
- */
13
- function feed(api, sequence) {
14
- const stdin = rendererStdin(api);
15
- if (!stdin)
16
- return false;
17
- stdin.emit("data", Buffer.from(sequence));
18
- return true;
19
- }
20
- /**
21
- * Drive opencode's native model dialog to select `title`:
22
- * 1. open it via the native `model.list` command
23
- * 2. type the model title to filter the list down to the target
24
- * 3. press Enter to select -> opencode runs `local.model.set` and the bar updates
25
- * 4. dismiss a follow-up variant dialog if one appears
26
- */
27
- export async function applyNativeModelSelection(deps, title) {
28
- const settle = deps.settleMs ?? 90;
29
- deps.dispatchCommand("model.list");
30
- await deps.wait(settle);
31
- if (!deps.isDialogOpen())
32
- return false;
33
- if (!deps.feed(title))
34
- return false;
35
- await deps.wait(settle);
36
- if (!deps.feed(ENTER))
37
- return false;
38
- await deps.wait(settle);
39
- // A model with variants opens a follow-up dialog; close it so the bar keeps
40
- // the model we just set (with its default variant).
41
- if (deps.isDialogOpen())
42
- deps.feed(ESCAPE);
43
- return true;
44
- }
45
- export function createNativeModelApplier(api) {
46
- return (_model, title) => applyNativeModelSelection({
47
- dispatchCommand: (command) => api.keymap.dispatchCommand(command),
48
- isDialogOpen: () => api.ui.dialog.open,
49
- feed: (sequence) => feed(api, sequence),
50
- wait: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
51
- }, title);
52
- }
53
- //# sourceMappingURL=native-model-apply.js.map