@cortexkit/aft-opencode 0.9.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bridge.d.ts.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25413 -182
- package/dist/notifications.d.ts +48 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/onnx-runtime.d.ts +35 -0
- package/dist/onnx-runtime.d.ts.map +1 -0
- package/dist/pool.d.ts +2 -0
- package/dist/pool.d.ts.map +1 -1
- package/dist/resolver.d.ts.map +1 -1
- package/dist/shared/opencode-config-dir.d.ts +16 -0
- package/dist/shared/opencode-config-dir.d.ts.map +1 -0
- package/dist/shared/rpc-client.d.ts +16 -0
- package/dist/shared/rpc-client.d.ts.map +1 -0
- package/dist/shared/rpc-server.d.ts +17 -0
- package/dist/shared/rpc-server.d.ts.map +1 -0
- package/dist/shared/rpc-utils.d.ts +11 -0
- package/dist/shared/rpc-utils.d.ts.map +1 -0
- package/dist/shared/runtime.d.ts +10 -0
- package/dist/shared/runtime.d.ts.map +1 -0
- package/dist/shared/status.d.ts +37 -0
- package/dist/shared/status.d.ts.map +1 -0
- package/dist/shared/tui-config.d.ts +2 -0
- package/dist/shared/tui-config.d.ts.map +1 -0
- package/dist/shared/url-fetch.d.ts +11 -0
- package/dist/shared/url-fetch.d.ts.map +1 -0
- package/dist/tools/reading.d.ts.map +1 -1
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/semantic.d.ts +4 -0
- package/dist/tools/semantic.d.ts.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +29 -9
- package/src/shared/opencode-config-dir.ts +46 -0
- package/src/shared/rpc-client.ts +123 -0
- package/src/shared/rpc-server.ts +135 -0
- package/src/shared/rpc-utils.ts +21 -0
- package/src/shared/runtime.ts +26 -0
- package/src/shared/status.ts +206 -0
- package/src/shared/tui-config.ts +58 -0
- package/src/shared/url-fetch.ts +237 -0
- package/src/tui/index.tsx +209 -0
- package/src/tui/types/opencode-plugin-tui.d.ts +232 -0
- package/dist/bridge.js +0 -311
- package/dist/bridge.js.map +0 -1
- package/dist/config.js +0 -302
- package/dist/config.js.map +0 -1
- package/dist/downloader.js +0 -198
- package/dist/downloader.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/logger.js +0 -78
- package/dist/logger.js.map +0 -1
- package/dist/lsp.js +0 -79
- package/dist/lsp.js.map +0 -1
- package/dist/metadata-store.js +0 -53
- package/dist/metadata-store.js.map +0 -1
- package/dist/normalize-schemas.js +0 -45
- package/dist/normalize-schemas.js.map +0 -1
- package/dist/patch-parser.js +0 -247
- package/dist/patch-parser.js.map +0 -1
- package/dist/platform.js +0 -31
- package/dist/platform.js.map +0 -1
- package/dist/pool.js +0 -111
- package/dist/pool.js.map +0 -1
- package/dist/resolver.js +0 -168
- package/dist/resolver.js.map +0 -1
- package/dist/tools/ast.js +0 -200
- package/dist/tools/ast.js.map +0 -1
- package/dist/tools/conflicts.js +0 -20
- package/dist/tools/conflicts.js.map +0 -1
- package/dist/tools/hoisted.js +0 -870
- package/dist/tools/hoisted.js.map +0 -1
- package/dist/tools/imports.js +0 -90
- package/dist/tools/imports.js.map +0 -1
- package/dist/tools/lsp.js +0 -58
- package/dist/tools/lsp.js.map +0 -1
- package/dist/tools/navigation.js +0 -58
- package/dist/tools/navigation.js.map +0 -1
- package/dist/tools/permissions.js +0 -50
- package/dist/tools/permissions.js.map +0 -1
- package/dist/tools/reading.js +0 -229
- package/dist/tools/reading.js.map +0 -1
- package/dist/tools/refactoring.js +0 -129
- package/dist/tools/refactoring.js.map +0 -1
- package/dist/tools/safety.js +0 -83
- package/dist/tools/safety.js.map +0 -1
- package/dist/tools/search.js +0 -88
- package/dist/tools/search.js.map +0 -1
- package/dist/tools/structure.js +0 -157
- package/dist/tools/structure.js.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/** @jsxImportSource @opentui/solid */
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
|
|
4
|
+
import type { TuiPlugin, TuiPluginApi } from "@opencode-ai/plugin/tui";
|
|
5
|
+
import { AftRpcClient } from "../shared/rpc-client";
|
|
6
|
+
import { coerceAftStatus, formatStatusDialogMessage } from "../shared/status";
|
|
7
|
+
|
|
8
|
+
const STATUS_COMMAND = "aft-status";
|
|
9
|
+
|
|
10
|
+
// RPC clients keyed by directory — one per project
|
|
11
|
+
const rpcClients = new Map<string, AftRpcClient>();
|
|
12
|
+
|
|
13
|
+
function getRpcClient(directory: string): AftRpcClient {
|
|
14
|
+
let client = rpcClients.get(directory);
|
|
15
|
+
if (client) return client;
|
|
16
|
+
|
|
17
|
+
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
18
|
+
const dataHome = process.env.XDG_DATA_HOME || `${home}/.local/share`;
|
|
19
|
+
const storageDir = `${dataHome}/opencode/storage/plugin/aft`;
|
|
20
|
+
|
|
21
|
+
client = new AftRpcClient(storageDir, directory);
|
|
22
|
+
rpcClients.set(directory, client);
|
|
23
|
+
return client;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getSessionId(api: TuiPluginApi): string | null {
|
|
27
|
+
try {
|
|
28
|
+
const route = api.route.current;
|
|
29
|
+
if (route?.name === "session" && route.params?.sessionID) {
|
|
30
|
+
return route.params.sessionID;
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
// ignore
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function showStatusDialog(api: TuiPluginApi): Promise<void> {
|
|
39
|
+
const sessionID = getSessionId(api);
|
|
40
|
+
if (!sessionID) {
|
|
41
|
+
api.ui.toast({ message: "No active session", variant: "warning", duration: 5000 });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const directory = api.state.path.directory ?? "";
|
|
46
|
+
if (!directory) {
|
|
47
|
+
api.ui.toast({ message: "No project directory", variant: "warning", duration: 5000 });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const client = getRpcClient(directory);
|
|
52
|
+
|
|
53
|
+
// Fetch status immediately and show the dialog
|
|
54
|
+
let currentMessage = "Connecting to AFT...";
|
|
55
|
+
try {
|
|
56
|
+
const response = await client.call("status", { sessionID });
|
|
57
|
+
if ((response as Record<string, unknown>).success !== false) {
|
|
58
|
+
const status = coerceAftStatus(response as Record<string, unknown>);
|
|
59
|
+
currentMessage = formatStatusDialogMessage(status);
|
|
60
|
+
}
|
|
61
|
+
} catch {
|
|
62
|
+
currentMessage = "AFT is starting up. Status will refresh automatically...";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Track whether dialog is still open for polling cleanup
|
|
66
|
+
let dialogOpen = true;
|
|
67
|
+
let pollTimer: ReturnType<typeof setInterval> | null = null;
|
|
68
|
+
|
|
69
|
+
// Show dialog with initial data
|
|
70
|
+
api.ui.dialog.setSize("large");
|
|
71
|
+
api.ui.dialog.replace(
|
|
72
|
+
() => {
|
|
73
|
+
// Start polling after dialog renders
|
|
74
|
+
if (!pollTimer) {
|
|
75
|
+
pollTimer = setInterval(async () => {
|
|
76
|
+
if (!dialogOpen) {
|
|
77
|
+
if (pollTimer) clearInterval(pollTimer);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const response = await client.call("status", { sessionID });
|
|
82
|
+
if ((response as Record<string, unknown>).success !== false) {
|
|
83
|
+
const status = coerceAftStatus(response as Record<string, unknown>);
|
|
84
|
+
const newMessage = formatStatusDialogMessage(status);
|
|
85
|
+
if (newMessage !== currentMessage) {
|
|
86
|
+
currentMessage = newMessage;
|
|
87
|
+
// Re-render dialog with updated status
|
|
88
|
+
api.ui.dialog.replace(
|
|
89
|
+
() => (
|
|
90
|
+
<api.ui.DialogAlert
|
|
91
|
+
title="AFT Status"
|
|
92
|
+
message={currentMessage}
|
|
93
|
+
onConfirm={() => {
|
|
94
|
+
dialogOpen = false;
|
|
95
|
+
if (pollTimer) clearInterval(pollTimer);
|
|
96
|
+
api.ui.dialog.setSize("medium");
|
|
97
|
+
}}
|
|
98
|
+
/>
|
|
99
|
+
),
|
|
100
|
+
() => {
|
|
101
|
+
dialogOpen = false;
|
|
102
|
+
if (pollTimer) clearInterval(pollTimer);
|
|
103
|
+
api.ui.dialog.setSize("medium");
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
} catch {
|
|
109
|
+
// Polling failure is non-fatal — just skip this tick
|
|
110
|
+
}
|
|
111
|
+
}, 1500);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<api.ui.DialogAlert
|
|
116
|
+
title="AFT Status"
|
|
117
|
+
message={currentMessage}
|
|
118
|
+
onConfirm={() => {
|
|
119
|
+
dialogOpen = false;
|
|
120
|
+
if (pollTimer) clearInterval(pollTimer);
|
|
121
|
+
api.ui.dialog.setSize("medium");
|
|
122
|
+
}}
|
|
123
|
+
/>
|
|
124
|
+
);
|
|
125
|
+
},
|
|
126
|
+
() => {
|
|
127
|
+
dialogOpen = false;
|
|
128
|
+
if (pollTimer) clearInterval(pollTimer);
|
|
129
|
+
api.ui.dialog.setSize("medium");
|
|
130
|
+
},
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async function showStartupNotifications(api: TuiPluginApi): Promise<void> {
|
|
135
|
+
const directory = api.state.path.directory ?? "";
|
|
136
|
+
if (!directory) return;
|
|
137
|
+
|
|
138
|
+
const client = getRpcClient(directory);
|
|
139
|
+
|
|
140
|
+
// Check for feature announcements
|
|
141
|
+
try {
|
|
142
|
+
const announcement = (await client.call("get-announcement", {})) as {
|
|
143
|
+
show?: boolean;
|
|
144
|
+
version?: string;
|
|
145
|
+
features?: string[];
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
if (announcement.show && announcement.version && announcement.features?.length) {
|
|
149
|
+
const featureText = announcement.features.map((f: string) => ` • ${f}`).join("\n");
|
|
150
|
+
|
|
151
|
+
api.ui.dialog.replace(
|
|
152
|
+
() => (
|
|
153
|
+
<api.ui.DialogAlert
|
|
154
|
+
title={`AFT v${announcement.version}`}
|
|
155
|
+
message={`What's new:\n\n${featureText}`}
|
|
156
|
+
onConfirm={() => {
|
|
157
|
+
// Mark as announced so it doesn't show again
|
|
158
|
+
void client.call("mark-announced", {});
|
|
159
|
+
}}
|
|
160
|
+
/>
|
|
161
|
+
),
|
|
162
|
+
() => {
|
|
163
|
+
void client.call("mark-announced", {});
|
|
164
|
+
},
|
|
165
|
+
);
|
|
166
|
+
return; // Show one dialog at a time
|
|
167
|
+
}
|
|
168
|
+
} catch {
|
|
169
|
+
// RPC server not ready yet — skip announcements
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Check for warnings
|
|
173
|
+
try {
|
|
174
|
+
const result = (await client.call("get-warnings", {})) as { warnings?: string[] };
|
|
175
|
+
if (result.warnings?.length) {
|
|
176
|
+
const warningText = result.warnings.join("\n\n");
|
|
177
|
+
api.ui.dialog.replace(
|
|
178
|
+
() => <api.ui.DialogAlert title="AFT Warning" message={warningText} onConfirm={() => {}} />,
|
|
179
|
+
() => {},
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
} catch {
|
|
183
|
+
// RPC server not ready — skip warnings
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const tui: TuiPlugin = async (api) => {
|
|
188
|
+
api.command.register(() => [
|
|
189
|
+
{
|
|
190
|
+
title: "AFT: Status",
|
|
191
|
+
value: "aft.status",
|
|
192
|
+
category: "AFT",
|
|
193
|
+
slash: { name: STATUS_COMMAND },
|
|
194
|
+
onSelect() {
|
|
195
|
+
void showStatusDialog(api);
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
]);
|
|
199
|
+
|
|
200
|
+
// Show startup notifications — RPC server is already running by the time TUI loads
|
|
201
|
+
void showStartupNotifications(api);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const id = "aft-opencode";
|
|
205
|
+
|
|
206
|
+
export default {
|
|
207
|
+
id,
|
|
208
|
+
tui,
|
|
209
|
+
};
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// Type declarations for @opencode-ai/plugin/tui
|
|
2
|
+
// These types are not yet exported by the installed @opencode-ai/plugin package
|
|
3
|
+
|
|
4
|
+
declare module "@opencode-ai/plugin/tui" {
|
|
5
|
+
import type {
|
|
6
|
+
createOpencodeClient as createOpencodeClientV2,
|
|
7
|
+
Event as TuiEvent,
|
|
8
|
+
Message,
|
|
9
|
+
Part,
|
|
10
|
+
Provider,
|
|
11
|
+
Config as SdkConfig,
|
|
12
|
+
} from "@opencode-ai/sdk/v2";
|
|
13
|
+
|
|
14
|
+
import type { CliRenderer, RGBA } from "@opentui/core";
|
|
15
|
+
import type { JSX, SolidPlugin } from "@opentui/solid";
|
|
16
|
+
|
|
17
|
+
type PluginOptions = Record<string, unknown>;
|
|
18
|
+
|
|
19
|
+
export type { CliRenderer };
|
|
20
|
+
|
|
21
|
+
export type TuiThemeCurrent = {
|
|
22
|
+
readonly primary: RGBA;
|
|
23
|
+
readonly secondary: RGBA;
|
|
24
|
+
readonly accent: RGBA;
|
|
25
|
+
readonly error: RGBA;
|
|
26
|
+
readonly warning: RGBA;
|
|
27
|
+
readonly success: RGBA;
|
|
28
|
+
readonly info: RGBA;
|
|
29
|
+
readonly text: RGBA;
|
|
30
|
+
readonly textMuted: RGBA;
|
|
31
|
+
readonly background: RGBA;
|
|
32
|
+
readonly backgroundPanel: RGBA;
|
|
33
|
+
readonly backgroundElement: RGBA;
|
|
34
|
+
readonly backgroundMenu: RGBA;
|
|
35
|
+
readonly border: RGBA;
|
|
36
|
+
readonly borderActive: RGBA;
|
|
37
|
+
readonly borderSubtle: RGBA;
|
|
38
|
+
[key: string]: unknown;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type TuiTheme = {
|
|
42
|
+
readonly current: TuiThemeCurrent;
|
|
43
|
+
has: (name: string) => boolean;
|
|
44
|
+
set: (name: string) => boolean;
|
|
45
|
+
mode: () => "dark" | "light";
|
|
46
|
+
readonly ready: boolean;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type TuiSlotMap = {
|
|
50
|
+
app: Record<string, never>;
|
|
51
|
+
home_logo: Record<string, never>;
|
|
52
|
+
home_bottom: Record<string, never>;
|
|
53
|
+
sidebar_title: {
|
|
54
|
+
session_id: string;
|
|
55
|
+
title: string;
|
|
56
|
+
share_url?: string;
|
|
57
|
+
};
|
|
58
|
+
sidebar_content: {
|
|
59
|
+
session_id: string;
|
|
60
|
+
};
|
|
61
|
+
sidebar_footer: {
|
|
62
|
+
session_id: string;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export type TuiSlotContext = {
|
|
67
|
+
theme: TuiTheme;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type TuiSlotPlugin = Omit<SolidPlugin<TuiSlotMap, TuiSlotContext>, "id"> & {
|
|
71
|
+
id?: never;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export type TuiToast = {
|
|
75
|
+
variant?: "info" | "success" | "warning" | "error";
|
|
76
|
+
title?: string;
|
|
77
|
+
message: string;
|
|
78
|
+
duration?: number;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export type TuiDialogStack = {
|
|
82
|
+
replace: (render: () => JSX.Element, onClose?: () => void) => void;
|
|
83
|
+
clear: () => void;
|
|
84
|
+
setSize: (size: "medium" | "large" | "xlarge") => void;
|
|
85
|
+
readonly size: "medium" | "large" | "xlarge";
|
|
86
|
+
readonly depth: number;
|
|
87
|
+
readonly open: boolean;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export type TuiDialogAlertProps = {
|
|
91
|
+
title: string;
|
|
92
|
+
message: string;
|
|
93
|
+
onConfirm?: () => void;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export type TuiDialogConfirmProps = {
|
|
97
|
+
title: string;
|
|
98
|
+
message: string;
|
|
99
|
+
onConfirm?: () => void;
|
|
100
|
+
onCancel?: () => void;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export type TuiDialogPromptProps = {
|
|
104
|
+
title: string;
|
|
105
|
+
description?: () => JSX.Element;
|
|
106
|
+
placeholder?: string;
|
|
107
|
+
value?: string;
|
|
108
|
+
busy?: boolean;
|
|
109
|
+
busyText?: string;
|
|
110
|
+
onConfirm?: (value: string) => void;
|
|
111
|
+
onCancel?: () => void;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export type TuiDialogSelectOption<Value = unknown> = {
|
|
115
|
+
title: string;
|
|
116
|
+
value: Value;
|
|
117
|
+
description?: string;
|
|
118
|
+
footer?: JSX.Element | string;
|
|
119
|
+
category?: string;
|
|
120
|
+
disabled?: boolean;
|
|
121
|
+
onSelect?: () => void;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export type TuiDialogSelectProps<Value = unknown> = {
|
|
125
|
+
title: string;
|
|
126
|
+
placeholder?: string;
|
|
127
|
+
options: TuiDialogSelectOption<Value>[];
|
|
128
|
+
flat?: boolean;
|
|
129
|
+
onMove?: (option: TuiDialogSelectOption<Value>) => void;
|
|
130
|
+
onFilter?: (query: string) => void;
|
|
131
|
+
onSelect?: (option: TuiDialogSelectOption<Value>) => void;
|
|
132
|
+
skipFilter?: boolean;
|
|
133
|
+
current?: Value;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export type TuiState = {
|
|
137
|
+
readonly ready: boolean;
|
|
138
|
+
readonly config: SdkConfig;
|
|
139
|
+
readonly provider: ReadonlyArray<Provider>;
|
|
140
|
+
readonly path: {
|
|
141
|
+
state: string;
|
|
142
|
+
config: string;
|
|
143
|
+
worktree: string;
|
|
144
|
+
directory: string;
|
|
145
|
+
};
|
|
146
|
+
session: {
|
|
147
|
+
count: () => number;
|
|
148
|
+
messages: (sessionID: string) => ReadonlyArray<Message>;
|
|
149
|
+
};
|
|
150
|
+
part: (messageID: string) => ReadonlyArray<Part>;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export type TuiEventBus = {
|
|
154
|
+
on: <Type extends TuiEvent["type"]>(
|
|
155
|
+
type: Type,
|
|
156
|
+
handler: (event: Extract<TuiEvent, { type: Type }>) => void,
|
|
157
|
+
) => () => void;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export type TuiLifecycle = {
|
|
161
|
+
readonly signal: AbortSignal;
|
|
162
|
+
onDispose: (fn: () => void | Promise<void>) => () => void;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export type TuiPluginApi = {
|
|
166
|
+
app: { readonly version: string };
|
|
167
|
+
command: {
|
|
168
|
+
register: (
|
|
169
|
+
cb: () => Array<{
|
|
170
|
+
title: string;
|
|
171
|
+
value: string;
|
|
172
|
+
description?: string;
|
|
173
|
+
category?: string;
|
|
174
|
+
keybind?: string;
|
|
175
|
+
suggested?: boolean;
|
|
176
|
+
hidden?: boolean;
|
|
177
|
+
enabled?: boolean;
|
|
178
|
+
slash?: {
|
|
179
|
+
name: string;
|
|
180
|
+
aliases?: string[];
|
|
181
|
+
};
|
|
182
|
+
onSelect?: () => void;
|
|
183
|
+
}>,
|
|
184
|
+
) => () => void;
|
|
185
|
+
trigger: (value: string) => void;
|
|
186
|
+
};
|
|
187
|
+
route: {
|
|
188
|
+
register: (
|
|
189
|
+
routes: Array<{
|
|
190
|
+
name: string;
|
|
191
|
+
render: (input: { params?: Record<string, unknown> }) => JSX.Element;
|
|
192
|
+
}>,
|
|
193
|
+
) => () => void;
|
|
194
|
+
navigate: (name: string, params?: Record<string, unknown>) => void;
|
|
195
|
+
readonly current:
|
|
196
|
+
| { name: "home" }
|
|
197
|
+
| { name: "session"; params: { sessionID: string; initialPrompt?: unknown } }
|
|
198
|
+
| { name: string; params?: Record<string, unknown> };
|
|
199
|
+
};
|
|
200
|
+
ui: {
|
|
201
|
+
DialogAlert: (props: TuiDialogAlertProps) => JSX.Element;
|
|
202
|
+
DialogConfirm: (props: TuiDialogConfirmProps) => JSX.Element;
|
|
203
|
+
DialogPrompt: (props: TuiDialogPromptProps) => JSX.Element;
|
|
204
|
+
DialogSelect: <Value = unknown>(props: TuiDialogSelectProps<Value>) => JSX.Element;
|
|
205
|
+
toast: (input: TuiToast) => void;
|
|
206
|
+
dialog: TuiDialogStack;
|
|
207
|
+
};
|
|
208
|
+
state: TuiState;
|
|
209
|
+
theme: TuiTheme;
|
|
210
|
+
client: ReturnType<typeof createOpencodeClientV2>;
|
|
211
|
+
event: TuiEventBus;
|
|
212
|
+
renderer: CliRenderer;
|
|
213
|
+
slots: {
|
|
214
|
+
register: (plugin: TuiSlotPlugin) => string;
|
|
215
|
+
};
|
|
216
|
+
lifecycle: TuiLifecycle;
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
export type TuiPluginMeta = {
|
|
220
|
+
state: "first" | "updated" | "same";
|
|
221
|
+
id: string;
|
|
222
|
+
source: "file" | "npm" | "internal";
|
|
223
|
+
spec: string;
|
|
224
|
+
target: string;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
export type TuiPlugin = (
|
|
228
|
+
api: TuiPluginApi,
|
|
229
|
+
options: PluginOptions | undefined,
|
|
230
|
+
meta: TuiPluginMeta,
|
|
231
|
+
) => Promise<void>;
|
|
232
|
+
}
|