@molecule/app-react-native 1.0.1 → 1.0.2

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.
Files changed (2) hide show
  1. package/README.md +168 -2
  2. package/package.json +4 -3
package/README.md CHANGED
@@ -3,7 +3,7 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
3
  Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
4
  Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
5
  To change this document, edit the module-level JSDoc in src/index.ts.
6
- Generated: 2026-08-04T01:52:27.270Z
6
+ Generated: 2026-09-15T13:40:29.572Z
7
7
  -->
8
8
 
9
9
  # @molecule/app-react-native
@@ -693,6 +693,16 @@ interface SendMessageOptions {
693
693
  * user-initiated one IS that re-engagement — it clears the stop and sends.
694
694
  */
695
695
  userInitiated?: boolean
696
+ /**
697
+ * Send on the SIDE CHANNEL: a human-to-human message (e.g. a team note) the
698
+ * server intercepts before running any agent turn. When the provider supports
699
+ * `sendSideMessage`, the send goes out IMMEDIATELY on an independent request —
700
+ * it never queues behind an active turn, never takes over the streaming
701
+ * state, and never tears down remote-turn tracking (a viewer's note while
702
+ * watching a teammate's turn must not stop the watching). Falls back to the
703
+ * normal send path on providers without side-channel support.
704
+ */
705
+ sideChannel?: boolean
696
706
  }
697
707
  ```
698
708
 
@@ -904,6 +914,15 @@ interface UseChatOptions {
904
914
  agentName?: string
905
915
  /** Load history on mount. */
906
916
  loadOnMount?: boolean
917
+ /**
918
+ * This client may only WATCH the conversation (e.g. a read-only project
919
+ * viewer): the hook never issues chat POSTs on its behalf — no resume
920
+ * request after a reload, no auto-retries. A live turn is followed through
921
+ * the remote-watch path instead: pushed broadcast frames (applyRemoteEvent)
922
+ * render it in real time and the history reconcile poll backstops gaps, with
923
+ * `isRemoteStreaming` driving the activity indicator.
924
+ */
925
+ readOnly?: boolean
907
926
  /** Called when a file is created or modified by a tool call (path + new content). */
908
927
  onFileChange?: (path: string, content: string) => void
909
928
  /** Called when the AI switches between plan and execute modes. */
@@ -940,10 +959,21 @@ interface UseChatResult {
940
959
  */
941
960
  noteRemoteStreamEvent: () => void
942
961
  error: string | null
943
- /** Metadata about a limit-related error (for contextual upgrade CTAs). */
962
+ /**
963
+ * Metadata about a limit-related error, for a contextual call-to-action.
964
+ * `limitType` names the RULE the backend enforced; `billingAction` names the
965
+ * REMEDY it resolved (e.g. `add_funds`, `add_payment_method`,
966
+ * `raise_spend_cap`, `upgrade`, `none`) and is what the button should be
967
+ * built from — the same limit needs a different button per account.
968
+ * `upgradeTier` is the plan an upgrade would move to, explicitly `null` when
969
+ * there is no higher tier. The backend owns these vocabularies, so the
970
+ * action/tier are plain strings here.
971
+ */
944
972
  errorMeta: {
945
973
  limitType?: string
946
974
  requiresSignup?: boolean
975
+ billingAction?: string
976
+ upgradeTier?: string | null
947
977
  } | null
948
978
  /** Current agent mode — plan (read-only research) or execute (full access). */
949
979
  mode: 'plan' | 'execute'
@@ -1006,6 +1036,35 @@ interface UseChatResult {
1006
1036
  timestamp: number,
1007
1037
  card: NonNullable<ChatMessage['cardEvent']>,
1008
1038
  ) => void
1039
+ /**
1040
+ * Append a COMPLETE, non-streaming chat message (a `message` stream event — e.g.
1041
+ * a teammate's human-only team note) to the ONE message store. Used by the host
1042
+ * (ChatPanel) to render a TEAMMATE's broadcast `message` event live — this
1043
+ * client's OWN `message` events arrive through the stream and are appended
1044
+ * internally. De-duped by the server-assigned message id.
1045
+ */
1046
+ appendCompleteMessage: (message: ChatMessage) => void
1047
+ /**
1048
+ * Ingest ONE pushed (broadcast) stream frame from a turn running elsewhere —
1049
+ * a teammate's send, another tab, a server-side continuation — into the ONE
1050
+ * message store, through the same content applier as an own SSE stream: text/
1051
+ * thinking deltas, tool events, verification, cards, complete messages, done.
1052
+ * The host (ChatPanel) calls this from its push-channel handler for every
1053
+ * broadcast frame of the OPEN conversation. Own echoes are dropped while a
1054
+ * local send is in flight (the SSE stream is authoritative for the sender);
1055
+ * complete id-carrying items (cards, team notes) always apply, de-duped.
1056
+ */
1057
+ applyRemoteEvent: (event: ChatStreamEvent) => void
1058
+ /**
1059
+ * Reload history and converge the local view on the server transcript (and
1060
+ * re-enter a still-streaming turn). The page-lifecycle events run this
1061
+ * automatically; the host should ALSO call it whenever its chat push channel
1062
+ * (re)connects — a broadcast sent while that socket was down (a teammate's
1063
+ * team note against a backgrounded tab or a slept laptop) is otherwise lost
1064
+ * until the next lifecycle event happens to fire. Cheap when nothing changed:
1065
+ * an identical transcript is never re-applied.
1066
+ */
1067
+ reconcileHistory: () => Promise<void>
1009
1068
  }
1010
1069
  ```
1011
1070
 
@@ -1386,6 +1445,57 @@ interface UseTranslationResult {
1386
1445
  }
1387
1446
  ```
1388
1447
 
1448
+ #### `UseVerifyPaymentReturnOptions`
1449
+
1450
+ Options for {@link useVerifyPaymentReturn}.
1451
+
1452
+ ```typescript
1453
+ interface UseVerifyPaymentReturnOptions {
1454
+ /**
1455
+ * Provider name to verify with, when the return URL carries no `provider`
1456
+ * query parameter. Leave unset to verify only what the URL names.
1457
+ */
1458
+ provider?: string
1459
+ /** Set `false` to skip verification entirely (e.g. behind a feature flag). */
1460
+ enabled?: boolean
1461
+ /**
1462
+ * Remove the provider's query parameters from the address bar once the
1463
+ * purchase is verified, so a reload (or a shared link) cannot replay the
1464
+ * verification. Defaults to `true`.
1465
+ */
1466
+ cleanUrl?: boolean
1467
+ /** Called once, after the purchase verifies. */
1468
+ onVerified?: () => void
1469
+ /** Called when verification fails. */
1470
+ onError?: (error: Error) => void
1471
+ }
1472
+ ```
1473
+
1474
+ #### `UseVerifyPaymentReturnResult`
1475
+
1476
+ State of the post-checkout verification.
1477
+
1478
+ ```typescript
1479
+ interface UseVerifyPaymentReturnResult {
1480
+ /**
1481
+ * `idle` when this page load is not a checkout return (no transaction id in
1482
+ * the URL) or auth is still hydrating; `verifying` while the API call is in
1483
+ * flight; then `verified` or `failed`.
1484
+ */
1485
+ status: VerifyPaymentReturnStatus
1486
+ /** `true` when the URL identifies a purchase to verify. */
1487
+ isReturn: boolean
1488
+ /** The provider named by the URL (or the `provider` option). */
1489
+ provider: string | null
1490
+ /** The provider transaction/session id read from the URL. */
1491
+ transactionId: string | null
1492
+ /** Why verification failed, when it did. */
1493
+ error: Error | null
1494
+ /** Re-run the verification — wire this to a retry button. */
1495
+ retry: () => void
1496
+ }
1497
+ ```
1498
+
1389
1499
  #### `UseVersionResult`
1390
1500
 
1391
1501
  Hook return type.
@@ -1461,6 +1571,14 @@ type UseCapacitorAppResult = CapacitorAppState & {
1461
1571
  }
1462
1572
  ```
1463
1573
 
1574
+ #### `VerifyPaymentReturnStatus`
1575
+
1576
+ How far the return-page verification has got.
1577
+
1578
+ ```typescript
1579
+ type VerifyPaymentReturnStatus = 'idle' | 'verifying' | 'verified' | 'failed'
1580
+ ```
1581
+
1464
1582
  ### Functions
1465
1583
 
1466
1584
  #### `AuthProvider(props)`
@@ -1538,6 +1656,25 @@ function I18nProvider({
1538
1656
 
1539
1657
  **Returns:** The rendered i18n provider element.
1540
1658
 
1659
+ #### `localOnlyMessages(prev, history)`
1660
+
1661
+ The messages only the local store holds, given a server history: optimistic
1662
+ bubbles and session-local cards, minus the optimistic ECHO of a send the
1663
+ server already persisted. A local user message carries a local id
1664
+ (`user-N`), the server's copy a server id, so ids never match — content does.
1665
+ Without this, the dashboard's first prompt (auto-sent by the workspace,
1666
+ then merged back in from history by the remote-stream poll) rendered as two
1667
+ identical user bubbles in every new project (2026-09-08).
1668
+
1669
+ ```typescript
1670
+ function localOnlyMessages(prev: ChatMessage[], history: ChatMessage[]): ChatMessage[]
1671
+ ```
1672
+
1673
+ - `prev` — The store's current messages.
1674
+ - `history` — The server's history.
1675
+
1676
+ **Returns:** The local-only messages to keep after the merged history.
1677
+
1541
1678
  #### `LoggerProvider(props)`
1542
1679
 
1543
1680
  Provider for logging.
@@ -2428,6 +2565,35 @@ function useUser(): T | null
2428
2565
 
2429
2566
  **Returns:** The authenticated user or null
2430
2567
 
2568
+ #### `useVerifyPaymentReturn(options)`
2569
+
2570
+ Reads the payment id a provider put in the return URL and confirms the
2571
+ purchase server-side with `POST /users/:id/verify-payment/:provider`.
2572
+
2573
+ **This is why a hosted checkout returns the buyer to the APP and not the
2574
+ API.** Session cookies are host-only on the app's origin, so a top-level
2575
+ redirect from the provider straight to an authenticated API callback on a
2576
+ different host arrives with NO credentials — it answers 401 and the paid plan
2577
+ is never granted. The request this hook makes is a same-origin call from a
2578
+ loaded app page, so the credentials apply. It waits for auth to hydrate
2579
+ first: after the redirect the page is a cold load, and the session is
2580
+ restored from the httpOnly cookie via `GET /users/me`.
2581
+
2582
+ Verification is idempotent server-side (first-claim-wins on the transaction),
2583
+ and this hook additionally runs at most once per transaction id per page.
2584
+ Safe on pages that are also reached normally: with no id in the URL it stays
2585
+ `idle` and issues no request.
2586
+
2587
+ ```typescript
2588
+ function useVerifyPaymentReturn(
2589
+ options?: UseVerifyPaymentReturnOptions,
2590
+ ): UseVerifyPaymentReturnResult
2591
+ ```
2592
+
2593
+ - `options` — Provider fallback + lifecycle callbacks (see {@link UseVerifyPaymentReturnOptions}).
2594
+
2595
+ **Returns:** The verification state (see {@link UseVerifyPaymentReturnResult}).
2596
+
2431
2597
  #### `useVersion()`
2432
2598
 
2433
2599
  Hook for version state and update actions.
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@molecule/app-react-native",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "React Native framework bindings for molecule.dev",
5
+ "homepage": "https://www.molecule.dev/packages/app-react-native",
5
6
  "type": "module",
6
7
  "main": "dist/index.js",
7
8
  "types": "dist/index.d.ts",
@@ -32,11 +33,11 @@
32
33
  "directory": "packages/app/frameworks/react-native"
33
34
  },
34
35
  "devDependencies": {
35
- "@molecule/app-react": "1.0.1",
36
+ "@molecule/app-react": "1.5.1",
36
37
  "@types/node": "26.1.2",
37
38
  "react": "19.2.8",
38
39
  "typescript": "6.0.3",
39
- "vitest": "4.1.10"
40
+ "vitest": "4.1.11"
40
41
  },
41
42
  "peerDependencies": {
42
43
  "@molecule/app-keyboard": "^1.0.1",