@nikcli-ai/plugin 1.364.0 → 1.368.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/v2/ade/context.d.ts +165 -0
- package/dist/v2/ade/context.js +0 -0
- package/dist/v2/ade/index.d.ts +1 -0
- package/dist/v2/ade/index.js +1 -0
- package/dist/v2/ade/plugin.d.ts +14 -0
- package/dist/v2/ade/plugin.js +3 -0
- package/package.json +12 -2
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a v2 plugin is handed when it runs inside ADE.
|
|
3
|
+
*
|
|
4
|
+
* Why this is a second context and not `v2/tui/context.ts`
|
|
5
|
+
* -------------------------------------------------------
|
|
6
|
+
* The two halves of the v2 contract that are genuinely portable — `define`,
|
|
7
|
+
* the `Cleanup` protocol, the shape of `Storage` — are mirrored here on
|
|
8
|
+
* purpose. Everything else in the TUI context is terminal-shaped in ways that
|
|
9
|
+
* do not survive the move:
|
|
10
|
+
*
|
|
11
|
+
* - Its `JSX` comes from `@opentui/solid`. That is the *terminal* renderer's
|
|
12
|
+
* element type: a `<box>` is not a `<div>`, and the two namespaces are not
|
|
13
|
+
* assignable. A plugin written against the TUI context and mounted in ADE
|
|
14
|
+
* would typecheck and then render nothing. Getting this wrong is silent, so
|
|
15
|
+
* the type has to say which surface it is for.
|
|
16
|
+
* - Its `Data` is the nikcli HTTP client's world — messages, parts, permission
|
|
17
|
+
* requests, MCP servers, providers. ADE has no SDK client wired up at all;
|
|
18
|
+
* it drives agent CLIs through a pty and knows about a project and a list of
|
|
19
|
+
* panes. Handing a plugin a `Data` whose every method returns `undefined`
|
|
20
|
+
* here would be worse than not offering it.
|
|
21
|
+
* - Its `UI` is a router plus named string slots. ADE has no router: a pane is
|
|
22
|
+
* a tile in a grid, several of the same kind can be open at once, and each
|
|
23
|
+
* one is closed individually. `navigate` has no meaning when the answer to
|
|
24
|
+
* "where am I" is "in six places".
|
|
25
|
+
*
|
|
26
|
+
* The mapping the ADE adapter implements, stated once so nobody has to infer
|
|
27
|
+
* it from the code: a TUI **page** is an ADE **pane**, a TUI **slot** is an ADE
|
|
28
|
+
* **sidebar section**. Commands are new — the TUI reserves them for v1
|
|
29
|
+
* plugins, but the palette is how ADE is driven, so a v2 plugin that cannot put
|
|
30
|
+
* anything in it is a plugin nobody can reach.
|
|
31
|
+
*/
|
|
32
|
+
import type { JSX } from "solid-js";
|
|
33
|
+
import type { Store } from "solid-js/store";
|
|
34
|
+
export type SessionStatus = "idle" | "provisioning" | "working" | "waiting" | "done" | "error";
|
|
35
|
+
export interface ProjectInfo {
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly root: string;
|
|
38
|
+
readonly branch?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface SessionInfo {
|
|
41
|
+
readonly id: string;
|
|
42
|
+
readonly title: string;
|
|
43
|
+
readonly status: SessionStatus;
|
|
44
|
+
/** The agent CLI behind this session, when it was started from the catalogue. */
|
|
45
|
+
readonly agent?: string;
|
|
46
|
+
readonly model: string;
|
|
47
|
+
readonly cwd?: string;
|
|
48
|
+
/** The project this session is filed under, by name. */
|
|
49
|
+
readonly projectName: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* ADE's live state, read-only.
|
|
53
|
+
*
|
|
54
|
+
* Every accessor is a function rather than a value because these are read from
|
|
55
|
+
* Solid signals: called inside a reactive scope they subscribe, called outside
|
|
56
|
+
* they are a snapshot. Returning the value would freeze a plugin's view of the
|
|
57
|
+
* workbench at setup time.
|
|
58
|
+
*/
|
|
59
|
+
export interface Data {
|
|
60
|
+
/** The project currently open, or `undefined` in the browser harness. */
|
|
61
|
+
project(): ProjectInfo | undefined;
|
|
62
|
+
readonly session: {
|
|
63
|
+
/** Every session ADE knows about, across projects. */
|
|
64
|
+
list(): SessionInfo[];
|
|
65
|
+
get(id: string): SessionInfo | undefined;
|
|
66
|
+
/** The pane the user is in, when it holds a session. */
|
|
67
|
+
focused(): SessionInfo | undefined;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export interface CommandDefinition {
|
|
71
|
+
/**
|
|
72
|
+
* Unique within the plugin. The host namespaces it before it reaches the
|
|
73
|
+
* palette, so a plugin cannot claim `pane.close` — see the adapter.
|
|
74
|
+
*/
|
|
75
|
+
readonly id: string;
|
|
76
|
+
/** Shown in the palette. Italian, like the rest of ADE's chrome. */
|
|
77
|
+
readonly title: string;
|
|
78
|
+
/** The palette section to file it under. Defaults to the plugin's own id. */
|
|
79
|
+
readonly group?: string;
|
|
80
|
+
/** Searchable synonyms that are not in the title. */
|
|
81
|
+
readonly keywords?: readonly string[];
|
|
82
|
+
readonly run: () => Promise<void> | void;
|
|
83
|
+
}
|
|
84
|
+
/** A pane a plugin can open in the grid. The ADE analogue of a TUI page. */
|
|
85
|
+
export interface PaneDefinition {
|
|
86
|
+
/** Unique within the plugin; identifies the kind, not one open instance. */
|
|
87
|
+
readonly name: string;
|
|
88
|
+
/** The pane's header. Defaults to `name`. */
|
|
89
|
+
readonly title?: string;
|
|
90
|
+
readonly render: (input: {
|
|
91
|
+
readonly data?: Record<string, unknown>;
|
|
92
|
+
}) => JSX.Element;
|
|
93
|
+
}
|
|
94
|
+
/** A sidebar section. The ADE analogue of a TUI slot. */
|
|
95
|
+
export type SectionRender = (props: Record<string, unknown>) => JSX.Element;
|
|
96
|
+
export interface SectionDefinition {
|
|
97
|
+
/** Unique within the plugin. Reaches the DOM, so the host validates it. */
|
|
98
|
+
readonly name: string;
|
|
99
|
+
/** The section header. Defaults to `name`. */
|
|
100
|
+
readonly title?: string;
|
|
101
|
+
readonly render: SectionRender;
|
|
102
|
+
}
|
|
103
|
+
/** An open instance of a plugin pane, as the plugin sees it. */
|
|
104
|
+
export interface OpenPane {
|
|
105
|
+
/** The workbench pane id. What `close` takes. */
|
|
106
|
+
readonly id: string;
|
|
107
|
+
readonly name: string;
|
|
108
|
+
readonly data?: Record<string, unknown>;
|
|
109
|
+
}
|
|
110
|
+
export interface UI {
|
|
111
|
+
readonly command: {
|
|
112
|
+
register(command: CommandDefinition): () => void;
|
|
113
|
+
/** Runs one of this plugin's own commands by its unqualified id. */
|
|
114
|
+
run(id: string): void;
|
|
115
|
+
/** Opens the palette, as Ctrl+Shift+P does. */
|
|
116
|
+
palette(): void;
|
|
117
|
+
};
|
|
118
|
+
readonly pane: {
|
|
119
|
+
register(pane: PaneDefinition): () => void;
|
|
120
|
+
/**
|
|
121
|
+
* Opens a tile for a registered pane and returns its workbench id.
|
|
122
|
+
*
|
|
123
|
+
* Returns `undefined` when the name is not registered, rather than
|
|
124
|
+
* throwing: opening is usually a reaction to a click, and a plugin
|
|
125
|
+
* mid-teardown should not take the surface down with it.
|
|
126
|
+
*/
|
|
127
|
+
open(input: {
|
|
128
|
+
readonly name: string;
|
|
129
|
+
readonly data?: Record<string, unknown>;
|
|
130
|
+
}): string | undefined;
|
|
131
|
+
close(paneId: string): void;
|
|
132
|
+
/** This plugin's open tiles. Reactive, like everything on `data`. */
|
|
133
|
+
list(): OpenPane[];
|
|
134
|
+
};
|
|
135
|
+
readonly section: {
|
|
136
|
+
register(section: SectionDefinition): () => void;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Durable and ephemeral plugin state.
|
|
141
|
+
*
|
|
142
|
+
* Structurally the same as the TUI's `Storage` and deliberately so — a plugin
|
|
143
|
+
* that only keeps state should port between the two surfaces unchanged. It is
|
|
144
|
+
* restated rather than imported because importing the TUI context would drag
|
|
145
|
+
* `@opentui/*` into a webview build that has no terminal in it.
|
|
146
|
+
*
|
|
147
|
+
* The backing differs: ADE persists to `localStorage`, which is per-window and
|
|
148
|
+
* per-origin. So "survives a restart" holds, "stays in sync across running
|
|
149
|
+
* instances" does not — there is one ADE window.
|
|
150
|
+
*/
|
|
151
|
+
export interface Storage {
|
|
152
|
+
store<Value extends object>(key: string, options: {
|
|
153
|
+
readonly initial: Value;
|
|
154
|
+
}): readonly [Store<Value>, (mutation: (draft: Value) => void) => Promise<void>];
|
|
155
|
+
/** In-memory only. Survives a plugin reload, gone when the window closes. */
|
|
156
|
+
memory<Value extends object>(key: string, options: {
|
|
157
|
+
readonly initial: Value;
|
|
158
|
+
}): readonly [Store<Value>, (mutation: (draft: Value) => void) => void];
|
|
159
|
+
}
|
|
160
|
+
export interface Context {
|
|
161
|
+
readonly options: Readonly<Record<string, unknown>>;
|
|
162
|
+
readonly data: Data;
|
|
163
|
+
readonly storage: Storage;
|
|
164
|
+
readonly ui: UI;
|
|
165
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as Plugin from "./plugin.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as Plugin from "./plugin.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Context } from "./context.js";
|
|
2
|
+
export type { Context };
|
|
3
|
+
export type Cleanup = () => Promise<void> | void;
|
|
4
|
+
/**
|
|
5
|
+
* Identical in shape to `v2/tui/plugin.ts`, and that is the point: the entry
|
|
6
|
+
* form a plugin author writes does not change between surfaces, only the
|
|
7
|
+
* context they are handed does. A module can export both by re-reading
|
|
8
|
+
* `context.ui` — what it cannot do is assume which one it got.
|
|
9
|
+
*/
|
|
10
|
+
export interface Definition {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly setup: (context: Context) => Promise<Cleanup | void> | Cleanup | void;
|
|
13
|
+
}
|
|
14
|
+
export declare function define(plugin: Definition): Definition;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@nikcli-ai/plugin",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.368.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"scripts": {
|
|
@@ -35,6 +35,14 @@
|
|
|
35
35
|
"import": "./src/v2/tui/*.ts",
|
|
36
36
|
"types": "./src/v2/tui/*.ts"
|
|
37
37
|
},
|
|
38
|
+
"./v2/ade": {
|
|
39
|
+
"import": "./src/v2/ade/index.ts",
|
|
40
|
+
"types": "./src/v2/ade/index.ts"
|
|
41
|
+
},
|
|
42
|
+
"./v2/ade/*": {
|
|
43
|
+
"import": "./src/v2/ade/*.ts",
|
|
44
|
+
"types": "./src/v2/ade/*.ts"
|
|
45
|
+
},
|
|
38
46
|
"./v2/effect": {
|
|
39
47
|
"import": "./src/v2/effect/index.ts",
|
|
40
48
|
"types": "./src/v2/effect/index.ts"
|
|
@@ -62,6 +70,8 @@
|
|
|
62
70
|
"./tui": "./dist/tui.js",
|
|
63
71
|
"./v2/tui": "./dist/v2/tui/index.js",
|
|
64
72
|
"./v2/tui/*": "./dist/v2/tui/*.js",
|
|
73
|
+
"./v2/ade": "./dist/v2/ade/index.js",
|
|
74
|
+
"./v2/ade/*": "./dist/v2/ade/*.js",
|
|
65
75
|
"./v2/effect": "./dist/v2/effect/index.js",
|
|
66
76
|
"./v2/effect/tool": "./dist/v2/effect/tool.js",
|
|
67
77
|
"./v2/promise": "./dist/v2/promise/index.js",
|
|
@@ -69,7 +79,7 @@
|
|
|
69
79
|
}
|
|
70
80
|
},
|
|
71
81
|
"dependencies": {
|
|
72
|
-
"@nikcli-ai/sdk": "1.
|
|
82
|
+
"@nikcli-ai/sdk": "1.368.0",
|
|
73
83
|
"@opentui/core": "0.5.11",
|
|
74
84
|
"@opentui/solid": "0.5.11",
|
|
75
85
|
"effect": "4.0.0-rc.112",
|