@rozenite/controls-plugin 1.7.0-rc.2 → 1.8.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.
@@ -0,0 +1,150 @@
1
+ import { AgentToolContract } from '@rozenite/agent-shared';
2
+ import { AgentToolDescriptor } from '@rozenite/agent-shared';
3
+
4
+ export declare const CONTROLS_AGENT_PLUGIN_ID = "@rozenite/controls-plugin";
5
+
6
+ declare type ControlsButtonItem = {
7
+ id: string;
8
+ type: 'button';
9
+ title: string;
10
+ actionLabel?: string;
11
+ description?: string;
12
+ disabled?: boolean;
13
+ onPress: () => void | Promise<void>;
14
+ };
15
+
16
+ export declare type ControlsButtonItemSnapshot = Omit<ControlsButtonItem, 'onPress'>;
17
+
18
+ export declare type ControlsGetItemArgs = ControlsSectionItemArgs;
19
+
20
+ export declare type ControlsGetItemResult = {
21
+ sectionId: string;
22
+ item: ControlsItemSnapshot;
23
+ };
24
+
25
+ declare type ControlsInputItem = ControlsMutableItemBase<string> & {
26
+ type: 'input';
27
+ placeholder?: string;
28
+ applyLabel?: string;
29
+ };
30
+
31
+ export declare type ControlsInputItemSnapshot = Omit<ControlsInputItem, 'validate' | 'onUpdate'>;
32
+
33
+ declare type ControlsItem = ControlsTextItem | ControlsToggleItem | ControlsButtonItem | ControlsSelectItem | ControlsInputItem;
34
+
35
+ export declare type ControlsItemSnapshot = ControlsTextItemSnapshot | ControlsToggleItemSnapshot | ControlsButtonItemSnapshot | ControlsSelectItemSnapshot | ControlsInputItemSnapshot;
36
+
37
+ export declare type ControlsListSectionItemSummary = {
38
+ id: string;
39
+ type: ControlsItem['type'];
40
+ title: string;
41
+ disabled?: boolean;
42
+ };
43
+
44
+ export declare type ControlsListSectionsArgs = undefined;
45
+
46
+ export declare type ControlsListSectionsResult = {
47
+ sections: ControlsListSectionSummary[];
48
+ };
49
+
50
+ export declare type ControlsListSectionSummary = {
51
+ id: string;
52
+ title: string;
53
+ description?: string;
54
+ items: ControlsListSectionItemSummary[];
55
+ };
56
+
57
+ declare type ControlsMutableItemBase<TValue> = {
58
+ id: string;
59
+ title: string;
60
+ value: TValue;
61
+ description?: string;
62
+ disabled?: boolean;
63
+ validate?: (nextValue: TValue) => ControlsValidationResult;
64
+ onUpdate: (nextValue: TValue) => void | Promise<void>;
65
+ };
66
+
67
+ export declare type ControlsPressButtonArgs = ControlsSectionItemArgs;
68
+
69
+ export declare type ControlsPressButtonResult = {
70
+ pressed: true;
71
+ sectionId: string;
72
+ itemId: string;
73
+ };
74
+
75
+ declare type ControlsSection = {
76
+ id: string;
77
+ title: string;
78
+ description?: string;
79
+ items: ControlsItem[];
80
+ };
81
+
82
+ export declare type ControlsSectionItemArgs = {
83
+ sectionId: string;
84
+ itemId: string;
85
+ };
86
+
87
+ export declare type ControlsSectionSnapshot = Omit<ControlsSection, 'items'> & {
88
+ items: ControlsItemSnapshot[];
89
+ };
90
+
91
+ declare type ControlsSelectItem = ControlsMutableItemBase<string> & {
92
+ type: 'select';
93
+ options: ControlsSelectOption[];
94
+ };
95
+
96
+ export declare type ControlsSelectItemSnapshot = Omit<ControlsSelectItem, 'validate' | 'onUpdate'>;
97
+
98
+ export declare type ControlsSelectOption = {
99
+ label: string;
100
+ value: string;
101
+ };
102
+
103
+ export declare type ControlsSetValueArgs = ControlsSectionItemArgs & {
104
+ value: boolean | string;
105
+ };
106
+
107
+ export declare type ControlsSetValueResult = {
108
+ applied: true;
109
+ sectionId: string;
110
+ itemId: string;
111
+ };
112
+
113
+ declare type ControlsTextItem = {
114
+ id: string;
115
+ type: 'text';
116
+ title: string;
117
+ value: string;
118
+ description?: string;
119
+ };
120
+
121
+ export declare type ControlsTextItemSnapshot = Omit<ControlsTextItem, never>;
122
+
123
+ declare type ControlsToggleItem = ControlsMutableItemBase<boolean> & {
124
+ type: 'toggle';
125
+ };
126
+
127
+ export declare type ControlsToggleItemSnapshot = Omit<ControlsToggleItem, 'validate' | 'onUpdate'>;
128
+
129
+ export declare const controlsToolDefinitions: {
130
+ readonly listSections: AgentToolContract<undefined, ControlsListSectionsResult>;
131
+ readonly getItem: AgentToolContract<ControlsSectionItemArgs, ControlsGetItemResult>;
132
+ readonly setValue: AgentToolContract<ControlsSetValueArgs, ControlsSetValueResult>;
133
+ readonly pressButton: AgentToolContract<ControlsSectionItemArgs, ControlsPressButtonResult>;
134
+ };
135
+
136
+ export declare const controlsTools: {
137
+ readonly listSections: AgentToolDescriptor<undefined, ControlsListSectionsResult>;
138
+ readonly getItem: AgentToolDescriptor<ControlsSectionItemArgs, ControlsGetItemResult>;
139
+ readonly setValue: AgentToolDescriptor<ControlsSetValueArgs, ControlsSetValueResult>;
140
+ readonly pressButton: AgentToolDescriptor<ControlsSectionItemArgs, ControlsPressButtonResult>;
141
+ };
142
+
143
+ declare type ControlsValidationResult = {
144
+ valid: true;
145
+ } | {
146
+ valid: false;
147
+ message: string;
148
+ };
149
+
150
+ export { }
@@ -0,0 +1,55 @@
1
+ import { defineAgentToolContract as e, defineAgentToolDescriptors as t } from "@rozenite/agent-shared";
2
+ const i = "@rozenite/controls-plugin", o = {
3
+ listSections: e({
4
+ name: "list-sections",
5
+ description: "List all controls sections with their item IDs, types, and titles. Does not include values — call get-item for that.",
6
+ inputSchema: { type: "object", properties: {} }
7
+ }),
8
+ getItem: e({
9
+ name: "get-item",
10
+ description: "Get full details of a single controls item including its current value. For select items this includes available options.",
11
+ inputSchema: {
12
+ type: "object",
13
+ properties: {
14
+ sectionId: { type: "string", description: "Section ID." },
15
+ itemId: { type: "string", description: "Item ID." }
16
+ },
17
+ required: ["sectionId", "itemId"]
18
+ }
19
+ }),
20
+ setValue: e({
21
+ name: "set-value",
22
+ description: "Update the value of a toggle, select, or input item. Runs the validate callback when present. Fails for text (read-only) and button items.",
23
+ inputSchema: {
24
+ type: "object",
25
+ properties: {
26
+ sectionId: { type: "string", description: "Section ID." },
27
+ itemId: { type: "string", description: "Item ID." },
28
+ value: {
29
+ description: "New value. Boolean for toggle items, string for select/input items."
30
+ }
31
+ },
32
+ required: ["sectionId", "itemId", "value"]
33
+ }
34
+ }),
35
+ pressButton: e({
36
+ name: "press-button",
37
+ description: "Trigger a button item's action. Fails if the item is not a button or is disabled.",
38
+ inputSchema: {
39
+ type: "object",
40
+ properties: {
41
+ sectionId: { type: "string", description: "Section ID." },
42
+ itemId: { type: "string", description: "Item ID." }
43
+ },
44
+ required: ["sectionId", "itemId"]
45
+ }
46
+ })
47
+ }, n = t(
48
+ i,
49
+ o
50
+ );
51
+ export {
52
+ i as CONTROLS_AGENT_PLUGIN_ID,
53
+ o as controlsToolDefinitions,
54
+ n as controlsTools
55
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rozenite/controls-plugin",
3
- "version": "1.7.0-rc.2",
3
+ "version": "1.8.0",
4
4
  "description": "A Rozenite plugin for exposing app-defined controls directly in React Native DevTools.",
5
5
  "type": "module",
6
6
  "main": "./dist/react-native/index.cjs",
@@ -15,8 +15,9 @@
15
15
  "url": "https://github.com/callstackincubator/rozenite.git"
16
16
  },
17
17
  "dependencies": {
18
- "@rozenite/agent-bridge": "1.7.0-rc.2",
19
- "@rozenite/plugin-bridge": "1.7.0-rc.2"
18
+ "@rozenite/agent-shared": "1.8.0",
19
+ "@rozenite/agent-bridge": "1.8.0",
20
+ "@rozenite/plugin-bridge": "1.8.0"
20
21
  },
21
22
  "devDependencies": {
22
23
  "@types/react": "~19.2.2",
@@ -31,8 +32,8 @@
31
32
  "tailwindcss-animate": "^1.0.7",
32
33
  "typescript": "~5.9.3",
33
34
  "vite": "^7.3.1",
34
- "@rozenite/vite-plugin": "1.7.0-rc.2",
35
- "rozenite": "1.7.0-rc.2"
35
+ "@rozenite/vite-plugin": "1.8.0",
36
+ "rozenite": "1.8.0"
36
37
  },
37
38
  "peerDependencies": {
38
39
  "react": "*",
@@ -45,7 +46,13 @@
45
46
  "import": "./dist/react-native/index.js",
46
47
  "require": "./dist/react-native/index.cjs"
47
48
  },
48
- "./package.json": "./package.json"
49
+ "./package.json": "./package.json",
50
+ "./sdk": {
51
+ "development": "./sdk.ts",
52
+ "types": "./dist/sdk/index.d.ts",
53
+ "import": "./dist/sdk/index.js",
54
+ "require": "./dist/sdk/index.cjs"
55
+ }
49
56
  },
50
57
  "publishConfig": {
51
58
  "access": "public"
package/sdk.ts ADDED
@@ -0,0 +1,40 @@
1
+ import { defineAgentToolDescriptors } from '@rozenite/agent-shared';
2
+ import {
3
+ CONTROLS_AGENT_PLUGIN_ID,
4
+ controlsToolDefinitions,
5
+ } from './src/shared/agent-tools.js';
6
+
7
+ export {
8
+ CONTROLS_AGENT_PLUGIN_ID,
9
+ controlsToolDefinitions,
10
+ };
11
+
12
+ export const controlsTools = defineAgentToolDescriptors(
13
+ CONTROLS_AGENT_PLUGIN_ID,
14
+ controlsToolDefinitions,
15
+ );
16
+
17
+ export type {
18
+ ControlsGetItemArgs,
19
+ ControlsGetItemResult,
20
+ ControlsListSectionItemSummary,
21
+ ControlsListSectionSummary,
22
+ ControlsListSectionsArgs,
23
+ ControlsListSectionsResult,
24
+ ControlsPressButtonArgs,
25
+ ControlsPressButtonResult,
26
+ ControlsSectionItemArgs,
27
+ ControlsSetValueArgs,
28
+ ControlsSetValueResult,
29
+ } from './src/shared/agent-tools.js';
30
+
31
+ export type {
32
+ ControlsButtonItemSnapshot,
33
+ ControlsInputItemSnapshot,
34
+ ControlsItemSnapshot,
35
+ ControlsSectionSnapshot,
36
+ ControlsSelectItemSnapshot,
37
+ ControlsSelectOption,
38
+ ControlsTextItemSnapshot,
39
+ ControlsToggleItemSnapshot,
40
+ } from './src/shared/types.js';
@@ -1,69 +1,10 @@
1
- import { useRozenitePluginAgentTool, type AgentTool } from '@rozenite/agent-bridge';
1
+ import { useRozenitePluginAgentTool } from '@rozenite/agent-bridge';
2
+ import {
3
+ CONTROLS_AGENT_PLUGIN_ID,
4
+ controlsToolDefinitions,
5
+ } from '../shared/agent-tools';
2
6
  import type { ControlsSection } from '../shared/types';
3
7
 
4
- type SectionItemInput = {
5
- sectionId: string;
6
- itemId: string;
7
- };
8
-
9
- type SetValueInput = SectionItemInput & {
10
- value: boolean | string;
11
- };
12
-
13
- const pluginId = '@rozenite/controls-plugin';
14
-
15
- const listSectionsTool: AgentTool = {
16
- name: 'list-sections',
17
- description:
18
- 'List all controls sections with their item IDs, types, and titles. Does not include values — call get-item for that.',
19
- inputSchema: { type: 'object', properties: {} },
20
- };
21
-
22
- const getItemTool: AgentTool = {
23
- name: 'get-item',
24
- description:
25
- 'Get full details of a single controls item including its current value. For select items this includes available options.',
26
- inputSchema: {
27
- type: 'object',
28
- properties: {
29
- sectionId: { type: 'string', description: 'Section ID.' },
30
- itemId: { type: 'string', description: 'Item ID.' },
31
- },
32
- required: ['sectionId', 'itemId'],
33
- },
34
- };
35
-
36
- const setValueTool: AgentTool = {
37
- name: 'set-value',
38
- description:
39
- 'Update the value of a toggle, select, or input item. Runs the validate callback when present. Fails for text (read-only) and button items.',
40
- inputSchema: {
41
- type: 'object',
42
- properties: {
43
- sectionId: { type: 'string', description: 'Section ID.' },
44
- itemId: { type: 'string', description: 'Item ID.' },
45
- value: {
46
- description:
47
- 'New value. Boolean for toggle items, string for select/input items.',
48
- },
49
- },
50
- required: ['sectionId', 'itemId', 'value'],
51
- },
52
- };
53
-
54
- const pressButtonTool: AgentTool = {
55
- name: 'press-button',
56
- description: "Trigger a button item's action. Fails if the item is not a button or is disabled.",
57
- inputSchema: {
58
- type: 'object',
59
- properties: {
60
- sectionId: { type: 'string', description: 'Section ID.' },
61
- itemId: { type: 'string', description: 'Item ID.' },
62
- },
63
- required: ['sectionId', 'itemId'],
64
- },
65
- };
66
-
67
8
  const resolveItem = (
68
9
  sections: ControlsSection[],
69
10
  sectionId: string,
@@ -92,8 +33,8 @@ const resolveItem = (
92
33
 
93
34
  export const useControlsAgentTools = (sections: ControlsSection[]) => {
94
35
  useRozenitePluginAgentTool({
95
- pluginId,
96
- tool: listSectionsTool,
36
+ pluginId: CONTROLS_AGENT_PLUGIN_ID,
37
+ tool: controlsToolDefinitions.listSections,
97
38
  handler: () => ({
98
39
  sections: sections.map((section) => ({
99
40
  id: section.id,
@@ -109,9 +50,9 @@ export const useControlsAgentTools = (sections: ControlsSection[]) => {
109
50
  }),
110
51
  });
111
52
 
112
- useRozenitePluginAgentTool<SectionItemInput>({
113
- pluginId,
114
- tool: getItemTool,
53
+ useRozenitePluginAgentTool({
54
+ pluginId: CONTROLS_AGENT_PLUGIN_ID,
55
+ tool: controlsToolDefinitions.getItem,
115
56
  handler: ({ sectionId, itemId }) => {
116
57
  const { item } = resolveItem(sections, sectionId, itemId);
117
58
 
@@ -187,9 +128,9 @@ export const useControlsAgentTools = (sections: ControlsSection[]) => {
187
128
  },
188
129
  });
189
130
 
190
- useRozenitePluginAgentTool<SetValueInput>({
191
- pluginId,
192
- tool: setValueTool,
131
+ useRozenitePluginAgentTool({
132
+ pluginId: CONTROLS_AGENT_PLUGIN_ID,
133
+ tool: controlsToolDefinitions.setValue,
193
134
  handler: async ({ sectionId, itemId, value }) => {
194
135
  const { item } = resolveItem(sections, sectionId, itemId);
195
136
 
@@ -224,7 +165,7 @@ export const useControlsAgentTools = (sections: ControlsSection[]) => {
224
165
  }
225
166
 
226
167
  await item.onUpdate(value);
227
- return { applied: true, sectionId, itemId };
168
+ return { applied: true as const, sectionId, itemId };
228
169
  }
229
170
 
230
171
  if (typeof value !== 'string') {
@@ -250,13 +191,13 @@ export const useControlsAgentTools = (sections: ControlsSection[]) => {
250
191
  }
251
192
 
252
193
  await item.onUpdate(value);
253
- return { applied: true, sectionId, itemId };
194
+ return { applied: true as const, sectionId, itemId };
254
195
  },
255
196
  });
256
197
 
257
- useRozenitePluginAgentTool<SectionItemInput>({
258
- pluginId,
259
- tool: pressButtonTool,
198
+ useRozenitePluginAgentTool({
199
+ pluginId: CONTROLS_AGENT_PLUGIN_ID,
200
+ tool: controlsToolDefinitions.pressButton,
260
201
  handler: async ({ sectionId, itemId }) => {
261
202
  const { item } = resolveItem(sections, sectionId, itemId);
262
203
 
@@ -271,7 +212,7 @@ export const useControlsAgentTools = (sections: ControlsSection[]) => {
271
212
  }
272
213
 
273
214
  await item.onPress();
274
- return { pressed: true, sectionId, itemId };
215
+ return { pressed: true as const, sectionId, itemId };
275
216
  },
276
217
  });
277
218
  };
@@ -0,0 +1,121 @@
1
+ import {
2
+ defineAgentToolContract,
3
+ type AgentToolContract,
4
+ } from '@rozenite/agent-shared';
5
+ import type {
6
+ ControlsItem,
7
+ ControlsItemSnapshot,
8
+ } from './types';
9
+
10
+ export const CONTROLS_AGENT_PLUGIN_ID = '@rozenite/controls-plugin';
11
+
12
+ export type ControlsSectionItemArgs = {
13
+ sectionId: string;
14
+ itemId: string;
15
+ };
16
+
17
+ export type ControlsListSectionsArgs = undefined;
18
+
19
+ export type ControlsListSectionItemSummary = {
20
+ id: string;
21
+ type: ControlsItem['type'];
22
+ title: string;
23
+ disabled?: boolean;
24
+ };
25
+
26
+ export type ControlsListSectionSummary = {
27
+ id: string;
28
+ title: string;
29
+ description?: string;
30
+ items: ControlsListSectionItemSummary[];
31
+ };
32
+
33
+ export type ControlsListSectionsResult = {
34
+ sections: ControlsListSectionSummary[];
35
+ };
36
+
37
+ export type ControlsGetItemArgs = ControlsSectionItemArgs;
38
+
39
+ export type ControlsGetItemResult = {
40
+ sectionId: string;
41
+ item: ControlsItemSnapshot;
42
+ };
43
+
44
+ export type ControlsSetValueArgs = ControlsSectionItemArgs & {
45
+ value: boolean | string;
46
+ };
47
+
48
+ export type ControlsSetValueResult = {
49
+ applied: true;
50
+ sectionId: string;
51
+ itemId: string;
52
+ };
53
+
54
+ export type ControlsPressButtonArgs = ControlsSectionItemArgs;
55
+
56
+ export type ControlsPressButtonResult = {
57
+ pressed: true;
58
+ sectionId: string;
59
+ itemId: string;
60
+ };
61
+
62
+ export const controlsToolDefinitions = {
63
+ listSections: defineAgentToolContract<
64
+ ControlsListSectionsArgs,
65
+ ControlsListSectionsResult
66
+ >({
67
+ name: 'list-sections',
68
+ description:
69
+ 'List all controls sections with their item IDs, types, and titles. Does not include values — call get-item for that.',
70
+ inputSchema: { type: 'object', properties: {} },
71
+ }),
72
+ getItem: defineAgentToolContract<ControlsGetItemArgs, ControlsGetItemResult>({
73
+ name: 'get-item',
74
+ description:
75
+ 'Get full details of a single controls item including its current value. For select items this includes available options.',
76
+ inputSchema: {
77
+ type: 'object',
78
+ properties: {
79
+ sectionId: { type: 'string', description: 'Section ID.' },
80
+ itemId: { type: 'string', description: 'Item ID.' },
81
+ },
82
+ required: ['sectionId', 'itemId'],
83
+ },
84
+ }),
85
+ setValue: defineAgentToolContract<
86
+ ControlsSetValueArgs,
87
+ ControlsSetValueResult
88
+ >({
89
+ name: 'set-value',
90
+ description:
91
+ 'Update the value of a toggle, select, or input item. Runs the validate callback when present. Fails for text (read-only) and button items.',
92
+ inputSchema: {
93
+ type: 'object',
94
+ properties: {
95
+ sectionId: { type: 'string', description: 'Section ID.' },
96
+ itemId: { type: 'string', description: 'Item ID.' },
97
+ value: {
98
+ description:
99
+ 'New value. Boolean for toggle items, string for select/input items.',
100
+ },
101
+ },
102
+ required: ['sectionId', 'itemId', 'value'],
103
+ },
104
+ }),
105
+ pressButton: defineAgentToolContract<
106
+ ControlsPressButtonArgs,
107
+ ControlsPressButtonResult
108
+ >({
109
+ name: 'press-button',
110
+ description:
111
+ "Trigger a button item's action. Fails if the item is not a button or is disabled.",
112
+ inputSchema: {
113
+ type: 'object',
114
+ properties: {
115
+ sectionId: { type: 'string', description: 'Section ID.' },
116
+ itemId: { type: 'string', description: 'Item ID.' },
117
+ },
118
+ required: ['sectionId', 'itemId'],
119
+ },
120
+ }),
121
+ } as const satisfies Record<string, AgentToolContract<unknown, unknown>>;
package/tsconfig.json CHANGED
@@ -13,6 +13,7 @@
13
13
  "moduleResolution": "bundler",
14
14
  "baseUrl": ".",
15
15
  "paths": {
16
+ "@rozenite/agent-shared": ["../agent-shared/src/index.ts"],
16
17
  "@rozenite/plugin-bridge": ["../plugin-bridge/src/index.ts"]
17
18
  },
18
19
  "resolveJsonModule": true,
@@ -20,7 +21,7 @@
20
21
  "noEmit": true,
21
22
  "jsx": "react-jsx"
22
23
  },
23
- "include": ["src/**/*", "react-native.ts", "rozenite.config.ts"],
24
+ "include": ["src/**/*", "react-native.ts", "sdk.ts", "rozenite.config.ts"],
24
25
  "exclude": ["node_modules", "dist", "build"],
25
26
  "references": [
26
27
  {
package/vite.config.ts CHANGED
@@ -18,6 +18,7 @@ export default defineConfig({
18
18
  open: true,
19
19
  },
20
20
  test: {
21
+ passWithNoTests: true,
21
22
  environment: 'node',
22
23
  },
23
24
  });