@mihe-dev/react 0.0.0-stage → 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Neek Digital Solutions Ltd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,69 @@
1
- # Temporary Holding Version
1
+ # @mihe-dev/react
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Mihe is an assistant you embed in your React app. It knows your screens,
4
+ components and actions, and it operates the app for your users, under your
5
+ own permission model: it finds things, opens screens, fills in and points
6
+ at forms, and runs actions, asking for approval wherever you say it must.
7
+ Users can type or talk to it.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @mihe-dev/react
13
+ ```
14
+
15
+ React 18 or later. The package is ES modules with TypeScript types, and it
16
+ marks itself `"use client"`, so it works in Next.js App Router, Vite and
17
+ other bundlers without extra configuration.
18
+
19
+ ## A first integration
20
+
21
+ ```tsx
22
+ import { AssistantProvider, AssistantWidget, useAssistantScreen } from "@mihe-dev/react";
23
+
24
+ export function Root({ children }: { children: React.ReactNode }) {
25
+ return (
26
+ <AssistantProvider
27
+ url="wss://runtime.mihe.dev/v1/ws"
28
+ publicKey={process.env.NEXT_PUBLIC_MIHE_PUBLIC_KEY!}
29
+ // Your server mints this token for the signed-in user, signed with
30
+ // your app secret. It carries who they are and what they may do.
31
+ getUserToken={() => fetch("/api/mihe/token").then((r) => r.text())}
32
+ navigate={(route) => router.push(route)}
33
+ >
34
+ {children}
35
+ <AssistantWidget />
36
+ </AssistantProvider>
37
+ );
38
+ }
39
+
40
+ function OrdersPage() {
41
+ // Tell the assistant where the user is and what they can see.
42
+ useAssistantScreen({
43
+ screenId: "orders.list",
44
+ route: "/orders",
45
+ title: "Orders",
46
+ visibleData: { pending: 16 },
47
+ });
48
+ // …
49
+ }
50
+ ```
51
+
52
+ Create an app and its keys in the [dashboard](https://app.mihe.dev), then
53
+ follow the [quickstart](https://mihe.dev/docs/quickstart).
54
+
55
+ ## Documentation
56
+
57
+ - [Quickstart](https://mihe.dev/docs/quickstart)
58
+ - [Screens and components](https://mihe.dev/docs/screens-and-components):
59
+ what the assistant can see and point at
60
+ - [Actions](https://mihe.dev/docs/actions) and
61
+ [permissions and risk](https://mihe.dev/docs/permissions-and-risk):
62
+ what it can do, and what needs approval
63
+ - [User tokens](https://mihe.dev/docs/user-tokens)
64
+ - [The widget](https://mihe.dev/docs/widget) and [voice](https://mihe.dev/docs/voice)
65
+ - [SDK reference](https://mihe.dev/docs/sdk-reference)
66
+
67
+ ## License
68
+
69
+ MIT © Neek Digital Solutions Ltd
package/dist/card.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The approval surface for a proposed action, shared by the panel and the orb.
3
+ *
4
+ * It renders `label`, `description` and `input` from the proposal payload,
5
+ * which the runtime copies from its registry, never from the assistant's
6
+ * prose. Text smuggled into a product name or a document therefore cannot
7
+ * change what a user is shown they are about to approve.
8
+ */
9
+ import { formatValue, humanizeKey, type ProposalPayload } from "@mihe-dev/js";
10
+ export { formatValue, humanizeKey };
11
+ /**
12
+ * The approval surface for a proposed action.
13
+ *
14
+ * High-risk actions require this tap — the runtime refuses a spoken or typed
15
+ * "yes" for them — so this component is a security boundary, not decoration.
16
+ */
17
+ export declare function ConfirmationCard({ proposal, onRespond, }: {
18
+ proposal: ProposalPayload;
19
+ onRespond: (proposalId: string, confirmed: boolean) => void;
20
+ }): import("react").JSX.Element;
21
+ //# sourceMappingURL=card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../../react/src/card.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAE9E,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AAIpC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7D,+BAiDA"}
package/dist/card.js ADDED
@@ -0,0 +1,74 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { formatValue, humanizeKey } from "@mihe-dev/js";
3
+ export { formatValue, humanizeKey };
4
+ const FONT = "system-ui, -apple-system, 'Segoe UI', sans-serif";
5
+ /**
6
+ * The approval surface for a proposed action.
7
+ *
8
+ * High-risk actions require this tap — the runtime refuses a spoken or typed
9
+ * "yes" for them — so this component is a security boundary, not decoration.
10
+ */
11
+ export function ConfirmationCard({ proposal, onRespond, }) {
12
+ const entries = Object.entries(proposal.input ?? {});
13
+ return (_jsxs("div", { style: styles.card, role: "group", "aria-label": `Confirm: ${proposal.label}`, children: [_jsxs("div", { style: styles.cardHeader, children: [_jsx("strong", { children: proposal.label }), _jsx("span", { style: {
14
+ ...styles.riskBadge,
15
+ background: proposal.risk === "high" ? "#fee2e2" : "#fef3c7",
16
+ color: proposal.risk === "high" ? "#991b1b" : "#92400e",
17
+ }, children: proposal.risk === "high" ? "Needs care" : "Confirm" })] }), _jsx("p", { style: styles.cardDescription, children: proposal.description }), entries.length > 0 && (_jsx("dl", { style: styles.cardInput, children: entries.map(([key, value]) => (_jsxs("div", { style: styles.cardRow, children: [_jsx("dt", { style: styles.cardKey, children: humanizeKey(key) }), _jsx("dd", { style: styles.cardValue, children: _jsx(InputValue, { value: value }) })] }, key))) })), _jsxs("div", { style: styles.cardActions, children: [_jsx("button", { type: "button", onClick: () => onRespond(proposal.proposalId, false), style: styles.secondaryButton, children: "Cancel" }), _jsx("button", { type: "button", onClick: () => onRespond(proposal.proposalId, true), style: styles.primaryButton, children: "Confirm" })] })] }));
18
+ }
19
+ /** Lists stay separate so a user can check each line before approving. */
20
+ function InputValue({ value }) {
21
+ if (Array.isArray(value) && value.length > 0) {
22
+ return (_jsx("ol", { style: styles.inputList, children: value.map((item, index) => (_jsx("li", { children: _jsx(InputValue, { value: item }) }, index))) }));
23
+ }
24
+ return _jsx("span", { style: styles.inputText, children: formatValue(value) });
25
+ }
26
+ const styles = {
27
+ card: {
28
+ border: "1px solid #e2e8f0",
29
+ borderRadius: 10,
30
+ padding: 12,
31
+ background: "#fff",
32
+ boxShadow: "0 2px 8px rgba(15,23,42,0.06)",
33
+ },
34
+ cardHeader: {
35
+ display: "flex",
36
+ alignItems: "center",
37
+ justifyContent: "space-between",
38
+ gap: 8,
39
+ marginBottom: 6,
40
+ },
41
+ riskBadge: {
42
+ fontSize: 11,
43
+ fontWeight: 600,
44
+ padding: "2px 8px",
45
+ borderRadius: 999,
46
+ whiteSpace: "nowrap",
47
+ },
48
+ cardDescription: { margin: "0 0 10px", color: "#475569", fontSize: 13 },
49
+ cardInput: { margin: "0 0 12px", display: "flex", flexDirection: "column", gap: 8, maxHeight: "40vh", overflowY: "auto" },
50
+ cardRow: { display: "flex", flexWrap: "wrap", gap: 8, fontSize: 13 },
51
+ cardKey: { color: "#64748b", minWidth: 90, margin: 0 },
52
+ cardValue: { margin: 0, fontWeight: 500, overflowWrap: "anywhere", minWidth: 0, flex: "1 1 160px" },
53
+ inputList: { margin: 0, paddingLeft: 20, display: "grid", gap: 8 },
54
+ inputText: { whiteSpace: "pre-wrap" },
55
+ cardActions: { display: "flex", gap: 8, justifyContent: "flex-end" },
56
+ secondaryButton: {
57
+ padding: "7px 14px",
58
+ borderRadius: 8,
59
+ border: "1px solid #cbd5e1",
60
+ background: "#fff",
61
+ cursor: "pointer",
62
+ font: `500 13px ${FONT}`,
63
+ },
64
+ primaryButton: {
65
+ padding: "7px 14px",
66
+ borderRadius: 8,
67
+ border: "none",
68
+ background: "#4f7cff",
69
+ color: "#fff",
70
+ cursor: "pointer",
71
+ font: `600 13px ${FONT}`,
72
+ },
73
+ };
74
+ //# sourceMappingURL=card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.js","sourceRoot":"","sources":["../../../react/src/card.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,189 @@
1
+ /**
2
+ * The three registration hooks (spec §8.3–8.5).
3
+ *
4
+ * All three are declarative: a screen or component is registered while it is
5
+ * mounted and gone when it unmounts, so the assistant's picture of the app can
6
+ * never describe something the user is no longer looking at.
7
+ */
8
+ import { COMPONENT_ATTRIBUTE, type ActionHandler, type AssistantChart, type AssistantTable, type AssistantTabs, type ComponentDeclaration, type ScreenDeclaration } from "@mihe-dev/js";
9
+ export type { AssistantChart, AssistantQueryParam, AssistantTable, AssistantTableColumn, AssistantTableQuery, AssistantTabs, } from "@mihe-dev/js";
10
+ /**
11
+ * Declare the screen the user is on.
12
+ *
13
+ * Call once per page or view. `visibleData` is what makes answers concrete —
14
+ * "you have 7 low-stock products" rather than "check your stock levels" — so
15
+ * include the summary values already on screen, and only those.
16
+ */
17
+ export declare function useAssistantScreen(screen: ScreenDeclaration): void;
18
+ /**
19
+ * Declare a component the assistant can talk about or point at, and get back
20
+ * the props that make it findable.
21
+ *
22
+ * ```tsx
23
+ * const props = useAssistantComponent("products.addButton", {
24
+ * type: "button",
25
+ * label: "Add Product",
26
+ * description: "Opens the form to create a new product",
27
+ * });
28
+ * return <button {...props}>Add Product</button>;
29
+ * ```
30
+ *
31
+ * The returned props must be spread onto a real DOM element. Without them the
32
+ * component is described to the assistant but cannot be highlighted, which
33
+ * produces the confusing case of an assistant confidently pointing at nothing.
34
+ */
35
+ export declare function useAssistantComponent(componentKey: string, meta: ComponentDeclaration): {
36
+ [COMPONENT_ATTRIBUTE]: string;
37
+ };
38
+ /**
39
+ * Register a handler for an action the assistant may run in the browser.
40
+ *
41
+ * The action itself — its risk tier, permissions, and whether it needs
42
+ * confirmation — is configured in the dashboard, not here. This only supplies
43
+ * the code that runs once the runtime has decided it may.
44
+ *
45
+ * Whatever the handler returns becomes the tool result the model sees, so
46
+ * return something descriptive: `{ shown: 7 }` tells it more than `undefined`.
47
+ * Throwing is fine and reports honestly — the assistant will tell the user it
48
+ * failed rather than claiming success.
49
+ */
50
+ export declare function useAssistantAction(action: ActionHandler): void;
51
+ /**
52
+ * Let the assistant see which tab is open and switch to another.
53
+ *
54
+ * ```tsx
55
+ * const [tab, setTab] = useState("sales");
56
+ * useAssistantTabs({
57
+ * id: "reports.tabs",
58
+ * label: "Report",
59
+ * tabs: [{ value: "sales", label: "Sales" }, { value: "stock", label: "Stock" }],
60
+ * value: tab,
61
+ * onChange: setTab,
62
+ * });
63
+ * ```
64
+ *
65
+ * Tabs are built a dozen ways — a UI library's component, a route segment, a
66
+ * query parameter, plain state — so the SDK never touches them. It reports
67
+ * what you declare and calls your `onChange`, and the runtime only ever asks
68
+ * for a value you listed (amendment 67).
69
+ *
70
+ * Pass the tab that is really showing as `value`. The assistant is told it,
71
+ * and a switch is not reported done until `value` matches what was asked.
72
+ */
73
+ export declare function useAssistantTabs(tabs: AssistantTabs): void;
74
+ /**
75
+ * Let the assistant read a table on the screen.
76
+ *
77
+ * ```tsx
78
+ * useAssistantTable({
79
+ * id: "orders.table",
80
+ * label: "Orders",
81
+ * columns: [
82
+ * { key: "orderNumber", label: "Order" },
83
+ * { key: "total", label: "Total" },
84
+ * ],
85
+ * rows: orders,
86
+ * rowId: (order) => order.id,
87
+ * rowIdName: "orderId",
88
+ * total,
89
+ * });
90
+ * ```
91
+ *
92
+ * The rows are not sent with the screen. The model is told the table and its
93
+ * columns, and reads rows with `read_table` when a question needs them, so a
94
+ * table costs a line per answer rather than its contents (amendment 67).
95
+ * Only the declared columns ever leave the browser, and cell text is treated
96
+ * as data, never instructions.
97
+ */
98
+ export declare function useAssistantTable<Row>(table: AssistantTable<Row>): void;
99
+ /**
100
+ * Add the figures a component shows to the screen's `visibleData`, under
101
+ * `key`.
102
+ *
103
+ * For values that live below the page that calls `useAssistantScreen`: the
104
+ * stat cards inside a tab, a summary panel. They are dropped when the
105
+ * component unmounts or the screen changes, and held back while the screen
106
+ * says it is loading, as `visibleData` is.
107
+ *
108
+ * ```tsx
109
+ * useAssistantValues("stockSummary", { currentStockValue, periodInflow });
110
+ * ```
111
+ */
112
+ export declare function useAssistantValues(key: string, values: Record<string, unknown>): void;
113
+ /**
114
+ * Let the assistant explain a chart.
115
+ *
116
+ * ```tsx
117
+ * useAssistantChart({
118
+ * id: "stock.trend",
119
+ * title: "Stock trend",
120
+ * data: series,
121
+ * x: { key: "bucket", label: "Month", format: (v) => monthLabel(String(v)) },
122
+ * series: [
123
+ * { key: "inflowValue", name: "Stock in", unit: "NGN" },
124
+ * { key: "outflowValue", name: "Stock out", unit: "NGN" },
125
+ * ],
126
+ * });
127
+ * ```
128
+ *
129
+ * Each series is summarised here, in the browser, and the summary is what
130
+ * the model gets with the screen: start, end, high, low, total and the
131
+ * largest steps. That answers most questions about a trend in a few dozen
132
+ * tokens a series. The points are read with `read_chart` when an exact value
133
+ * is wanted (amendment 67). A picture of the chart is never sent.
134
+ */
135
+ export declare function useAssistantChart<Datum>(chart: AssistantChart<Datum>): void;
136
+ /** Props that turn any element into an assistant trigger. */
137
+ export interface AssistantTriggerProps {
138
+ onClick: () => void;
139
+ onKeyDown: (event: {
140
+ key: string;
141
+ preventDefault: () => void;
142
+ }) => void;
143
+ role: "button";
144
+ tabIndex: 0;
145
+ "aria-expanded": boolean;
146
+ "aria-controls": string;
147
+ "aria-haspopup": "dialog";
148
+ }
149
+ /**
150
+ * Make anything open the assistant — a nav button, a menu item, a card, a
151
+ * plain div.
152
+ *
153
+ * ```tsx
154
+ * const trigger = useAssistantTrigger();
155
+ * return <div {...trigger}>Ask the assistant</div>;
156
+ * ```
157
+ *
158
+ * The `role`, `tabIndex`, and `onKeyDown` are why this is a hook rather than
159
+ * advice to call `toggle()` yourself: a `div` with only an `onClick` is
160
+ * invisible to keyboards and screen readers, and that is the most common way
161
+ * a custom trigger ships broken. On a real `<button>` they are harmless.
162
+ *
163
+ * **Returns `null` when there is no assistant**, so the caller can render
164
+ * nothing rather than a control that does not work. Triggers live in shared
165
+ * chrome — a command palette, a nav item, a help link — which is exactly the
166
+ * code that renders whether or not a host app has configured the assistant.
167
+ * Throwing there would make the whole surface conditional on something it has
168
+ * no reason to know about.
169
+ */
170
+ export declare function useAssistantTrigger(): AssistantTriggerProps | null;
171
+ /**
172
+ * A one-tap "ask this" trigger, for suggestion chips and contextual help
173
+ * links.
174
+ *
175
+ * ```tsx
176
+ * <button onClick={useAssistantPrompt("How do I add a product?")}>
177
+ * How do I add a product?
178
+ * </button>
179
+ * ```
180
+ *
181
+ * Sending opens the assistant, so the reply is visible without the host app
182
+ * having to coordinate two calls.
183
+ *
184
+ * `null` when there is no assistant, for the same reason as
185
+ * [`useAssistantTrigger`]: a chip that silently does nothing is worse than one
186
+ * that was never rendered.
187
+ */
188
+ export declare function useAssistantPrompt(text: string): (() => void) | null;
189
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../react/src/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EACL,mBAAmB,EAOnB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACvB,MAAM,cAAc,CAAC;AAItB,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,GACd,MAAM,cAAc,CAAC;AAEtB;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAalE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,oBAAoB,GACzB;IAAE,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAE,CAiBnC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAgB9D;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAsB1D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,IAAI,CAoBvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAarF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAiB3E;AAED,6DAA6D;AAC7D,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;IACxE,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,CAAC,CAAC;IACZ,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,QAAQ,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,IAAI,qBAAqB,GAAG,IAAI,CAuBlE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAKpE"}