@akonwi/kit 0.3.4 → 0.4.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/kit CHANGED
Binary file
package/dist/plugin.d.ts CHANGED
@@ -2,11 +2,38 @@ export { Type } from "typebox";
2
2
 
3
3
  import type { AgentMessage } from "@earendil-works/pi-agent-core";
4
4
  import type { Api, Model, Static, TSchema } from "@earendil-works/pi-ai";
5
+ import type {
6
+ SyntaxPalette,
7
+ ThemeConfig,
8
+ ThemeColorTokens as ThemeTokens,
9
+ } from "./themes";
5
10
  import type { ToastInput } from "./toasts";
6
11
 
12
+ export type { SyntaxPalette, ThemeConfig, ThemeTokens };
13
+
7
14
  export type Disposer = () => void;
8
15
 
16
+ export type KitTextStyle = {
17
+ fg?: string;
18
+ bg?: string;
19
+ bold?: boolean;
20
+ dim?: boolean;
21
+ italic?: boolean;
22
+ underline?: boolean;
23
+ strikethrough?: boolean;
24
+ };
25
+
26
+ export type KitText = {
27
+ readonly __kitText: true;
28
+ readonly text: string;
29
+ readonly style?: KitTextStyle;
30
+ };
31
+
32
+ export type KitTextContent = string | KitText | readonly (string | KitText)[];
33
+
9
34
  interface UI {
35
+ text: (text: string, style?: KitTextStyle) => KitText;
36
+ theme: () => ThemeConfig;
10
37
  toast: (toast: ToastInput) => void;
11
38
  select(input: {
12
39
  title: string;
@@ -161,6 +188,26 @@ type ModelAPI = {
161
188
  getCurrent: () => Model<Api> | undefined;
162
189
  };
163
190
 
191
+ export type ChromeContributionSide = "left" | "right";
192
+
193
+ export type ChromeContributionOptions = {
194
+ side?: ChromeContributionSide;
195
+ onClick?: () => void | Promise<void>;
196
+ };
197
+
198
+ type ChromeContributionAPI = {
199
+ set: (
200
+ id: string,
201
+ content: KitTextContent,
202
+ options?: ChromeContributionOptions,
203
+ ) => void;
204
+ clear: (id: string) => void;
205
+ hide: (id: string) => Disposer;
206
+ };
207
+
208
+ type FooterAPI = ChromeContributionAPI;
209
+ type HeaderAPI = ChromeContributionAPI;
210
+
164
211
  type SystemAPI = {
165
212
  readonly cwd: string;
166
213
  open: (url: string | URL) => Promise<void>;
@@ -172,6 +219,8 @@ export type EventContext = {
172
219
  session: SessionAPI;
173
220
  settings: SettingsAPI;
174
221
  model: ModelAPI;
222
+ footer: FooterAPI;
223
+ header: HeaderAPI;
175
224
  system: SystemAPI;
176
225
  };
177
226
 
@@ -201,6 +250,8 @@ export interface PluginAPI {
201
250
  session: SessionAPI;
202
251
  settings: SettingsAPI;
203
252
  model: ModelAPI;
253
+ footer: FooterAPI;
254
+ header: HeaderAPI;
204
255
  system: SystemAPI;
205
256
  on(handler: EventHandler): Disposer;
206
257
  on<Type extends string>(type: Type, handler: EventHandler<Type>): Disposer;
@@ -0,0 +1,137 @@
1
+ import type { RGBA } from "@opentui/core";
2
+
3
+ /** All color tokens consumed by shell components. */
4
+ export type ThemeTokens = {
5
+ // Backgrounds
6
+ bg: string;
7
+ bgSurface: string;
8
+ bgMuted: string;
9
+ bgAccent: string;
10
+ bgTransparent: string;
11
+ modalBackdrop: RGBA;
12
+
13
+ // Borders
14
+ borderDefault: string;
15
+ borderFocused: string;
16
+ borderAccent: string;
17
+ borderDebug: string;
18
+ borderStatus: string;
19
+ composerBashBorder: string;
20
+ composerBashExcludedBorder: string;
21
+
22
+ // Text
23
+ textPrimary: string;
24
+ textSecondary: string;
25
+ textMuted: string;
26
+ textPlaceholder: string;
27
+ textDebug: string;
28
+
29
+ // Semantic (message roles)
30
+ userText: string;
31
+ userTextFocused: string;
32
+ userBorder: string;
33
+ assistantText: string;
34
+ toolText: string;
35
+ reviewText: string;
36
+ errorText: string;
37
+ warningText: string;
38
+ debugLabel: string;
39
+
40
+ // Secondary
41
+ metaText: string;
42
+ attachmentText: string;
43
+
44
+ // Cursor
45
+ cursor: string;
46
+
47
+ // Picker
48
+ pickerBg: string;
49
+ pickerBorder: string;
50
+ pickerFocusedBg: string;
51
+ pickerFocusedText: string;
52
+ pickerItemText: string;
53
+ pickerScrollThumb: string;
54
+ pickerScrollTrack: string;
55
+
56
+ // Scrollbar
57
+ scrollbarFg: string;
58
+ scrollbarBg: string;
59
+
60
+ // Spinner / panel
61
+ panelText: string;
62
+
63
+ // Progress bar
64
+ progressNormal: string;
65
+ progressWarning: string;
66
+ progressCritical: string;
67
+
68
+ // Toggle
69
+ toggleOn: string;
70
+
71
+ // Diff
72
+ diffAddedBg: string;
73
+ diffRemovedBg: string;
74
+ diffAddedContentBg: string;
75
+ diffRemovedContentBg: string;
76
+ diffAddedLineNumberBg: string;
77
+ diffRemovedLineNumberBg: string;
78
+ diffCursorBg: string;
79
+ diffCursorGutterBg: string;
80
+ diffCursorAddedBg: string;
81
+ diffCursorRemovedBg: string;
82
+ };
83
+
84
+ /** Named color slots for syntax highlighting rules. */
85
+ export type SyntaxPalette = {
86
+ text: string;
87
+ heading: string;
88
+ bold: string;
89
+ italic: string;
90
+ link: string;
91
+ list: string;
92
+ quote: string;
93
+ codeInline: string;
94
+ codeBlock: string;
95
+ strikethrough: string;
96
+ conceal: string;
97
+ comment: string;
98
+ string: string;
99
+ escape: string;
100
+ number: string;
101
+ keyword: string;
102
+ keywordType: string;
103
+ function: string;
104
+ operator: string;
105
+ variable: string;
106
+ member: string;
107
+ builtin: string;
108
+ type: string;
109
+ punctuation: string;
110
+ tag: string;
111
+ tagAttribute: string;
112
+ tagDelimiter: string;
113
+ attribute: string;
114
+ label: string;
115
+ };
116
+
117
+ /** Color tokens safe to expose outside the shell. */
118
+ export type ThemeColorTokens = Omit<ThemeTokens, "modalBackdrop">;
119
+
120
+ /** A fully resolved theme with all tokens filled in (except modalBackdrop). */
121
+ export type ResolvedTheme = {
122
+ tokens: ThemeColorTokens;
123
+ syntaxPalette: SyntaxPalette;
124
+ };
125
+
126
+ /** Public resolved theme config exposed to plugins. */
127
+ export type ThemeConfig = ResolvedTheme & { name: string };
128
+
129
+ /**
130
+ * A partial theme definition for overrides.
131
+ * User themes provide partial overrides
132
+ * that get merged on top of the system theme.
133
+ */
134
+ export type ThemeDefinition = {
135
+ tokens?: Partial<ThemeColorTokens>;
136
+ syntaxPalette?: Partial<SyntaxPalette>;
137
+ };
@@ -123,7 +123,51 @@ const ok = await kit.ui.confirm({
123
123
  });
124
124
  ```
125
125
 
126
- These helpers use Kit-owned dialogs and return `undefined` when selection/input is cancelled. `confirm` returns `false` for cancel/escape. The public plugin UI API is intentionally limited to `toast`, `select`, `input`, and `confirm` so Kit can keep ownership of rendering, focus, theme, and compatibility.
126
+ These helpers use Kit-owned dialogs and return `undefined` when selection/input is cancelled. `confirm` returns `false` for cancel/escape. The public plugin UI API is intentionally limited to `toast`, `select`, `input`, `confirm`, and the `text`/`theme` helpers so Kit can keep ownership of rendering, focus, theme, and compatibility.
127
+
128
+ ## Header and footer status contributions
129
+
130
+ Plugins can contribute short text items to the header and bottom footer. Kit owns the rendering and layout; plugins provide text or styled text chunks.
131
+
132
+ ```ts
133
+ kit.footer.set("build", "build: passing", { side: "right" });
134
+ kit.footer.set("mode", "watching", { side: "left" });
135
+ kit.header.set("branch", "main", { side: "right" });
136
+
137
+ const theme = kit.ui.theme();
138
+
139
+ kit.footer.set(
140
+ "ci",
141
+ [
142
+ kit.ui.text("✓", { fg: theme.tokens.toolText, bold: true }),
143
+ " tests ",
144
+ kit.ui.text("passing", { fg: theme.tokens.toolText }),
145
+ ],
146
+ {
147
+ side: "right",
148
+ onClick: () => kit.system.open("https://github.com/org/repo/actions"),
149
+ },
150
+ );
151
+
152
+ // Clear an item
153
+ kit.footer.clear("build");
154
+ kit.header.clear("branch");
155
+
156
+ // Hide a known item contributed by another plugin or built-in.
157
+ // The disposer restores it.
158
+ const showDefaultLocation = kit.footer.hide("VcsStatusPlugin:location");
159
+ const showDefaultModel = kit.header.hide("HeaderBar:model");
160
+ showDefaultLocation();
161
+ showDefaultModel();
162
+ ```
163
+
164
+ Header/footer item IDs passed to `set`/`clear` are scoped to the plugin and are cleaned up automatically when the plugin is disposed or reloaded. `hide` accepts the full item ID to support replacing known built-in contributions.
165
+
166
+ Use `kit.ui.text(text, style)` to style part or all of a contribution. Supported style fields are `fg`, `bg`, `bold`, `dim`, `italic`, `underline`, and `strikethrough`. Use `kit.ui.theme()` when setting or updating contributions to read the current resolved theme config (`name`, `tokens`, and `syntaxPalette`) and blend with Kit's colors. `onClick` is a whole-contribution action; Kit maps it to terminal mouse events and does not expose raw mouse events to plugins.
167
+
168
+ Built-in header item IDs are `HeaderBar:title`, `HeaderBar:model`, `HeaderBar:bell`, and `HeaderBar:speech`.
169
+
170
+ Built-in internal plugins may use additional app-owned capabilities that are not part of the public plugin SDK. For example, built-ins can read VCS state while the public SDK only exposes chrome contribution rendering.
127
171
 
128
172
  ## Tool approval hooks
129
173
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akonwi/kit",
3
- "version": "0.3.4",
3
+ "version": "0.4.0",
4
4
  "author": "Akonwi Ngoh <akonwi@gmail.com>",
5
5
  "description": "A TUI coding agent",
6
6
  "license": "MIT",