@zakstam/codex-local-component 0.8.0 → 0.9.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.
Files changed (97) hide show
  1. package/LLMS.md +8 -1
  2. package/README.md +2 -0
  3. package/dist/component/threads.d.ts +1 -0
  4. package/dist/component/threads.d.ts.map +1 -1
  5. package/dist/component/threads.js +2 -0
  6. package/dist/component/threads.js.map +1 -1
  7. package/dist/errors.d.ts +13 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +42 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/host/convex-entry.d.ts +2 -1
  12. package/dist/host/convex-entry.d.ts.map +1 -1
  13. package/dist/host/convex-entry.js +2 -1
  14. package/dist/host/convex-entry.js.map +1 -1
  15. package/dist/host/convexPreset.d.ts +14 -0
  16. package/dist/host/convexPreset.d.ts.map +1 -1
  17. package/dist/host/convexPreset.js +8 -1
  18. package/dist/host/convexPreset.js.map +1 -1
  19. package/dist/host/convexSlice.d.ts +1 -0
  20. package/dist/host/convexSlice.d.ts.map +1 -1
  21. package/dist/host/convexSlice.js +15 -0
  22. package/dist/host/convexSlice.js.map +1 -1
  23. package/dist/host/index.d.ts +2 -1
  24. package/dist/host/index.d.ts.map +1 -1
  25. package/dist/host/index.js +2 -1
  26. package/dist/host/index.js.map +1 -1
  27. package/dist/host/runtime.d.ts.map +1 -1
  28. package/dist/host/runtime.js +9 -0
  29. package/dist/host/runtime.js.map +1 -1
  30. package/dist/host/surfaceManifest.d.ts +2 -2
  31. package/dist/host/surfaceManifest.d.ts.map +1 -1
  32. package/dist/host/surfaceManifest.js +2 -0
  33. package/dist/host/surfaceManifest.js.map +1 -1
  34. package/dist/index.d.ts +1 -0
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +1 -0
  37. package/dist/index.js.map +1 -1
  38. package/dist/react/branchActivity.d.ts +16 -0
  39. package/dist/react/branchActivity.d.ts.map +1 -0
  40. package/dist/react/branchActivity.js +70 -0
  41. package/dist/react/branchActivity.js.map +1 -0
  42. package/dist/react/dynamicTools.d.ts +34 -0
  43. package/dist/react/dynamicTools.d.ts.map +1 -0
  44. package/dist/react/dynamicTools.js +56 -0
  45. package/dist/react/dynamicTools.js.map +1 -0
  46. package/dist/react/index.d.ts +16 -0
  47. package/dist/react/index.d.ts.map +1 -1
  48. package/dist/react/index.js +12 -0
  49. package/dist/react/index.js.map +1 -1
  50. package/dist/react/ingestHealth.d.ts +35 -0
  51. package/dist/react/ingestHealth.d.ts.map +1 -0
  52. package/dist/react/ingestHealth.js +102 -0
  53. package/dist/react/ingestHealth.js.map +1 -0
  54. package/dist/react/threadActivity.d.ts +35 -0
  55. package/dist/react/threadActivity.d.ts.map +1 -0
  56. package/dist/react/threadActivity.js +148 -0
  57. package/dist/react/threadActivity.js.map +1 -0
  58. package/dist/react/useCodexAccountAuth.d.ts +43 -0
  59. package/dist/react/useCodexAccountAuth.d.ts.map +1 -0
  60. package/dist/react/useCodexAccountAuth.js +59 -0
  61. package/dist/react/useCodexAccountAuth.js.map +1 -0
  62. package/dist/react/useCodexBranchActivity.d.ts +7 -0
  63. package/dist/react/useCodexBranchActivity.d.ts.map +1 -0
  64. package/dist/react/useCodexBranchActivity.js +9 -0
  65. package/dist/react/useCodexBranchActivity.js.map +1 -0
  66. package/dist/react/useCodexConversationController.d.ts +83 -0
  67. package/dist/react/useCodexConversationController.d.ts.map +1 -0
  68. package/dist/react/useCodexConversationController.js +152 -0
  69. package/dist/react/useCodexConversationController.js.map +1 -0
  70. package/dist/react/useCodexDynamicTools.d.ts +26 -0
  71. package/dist/react/useCodexDynamicTools.d.ts.map +1 -0
  72. package/dist/react/useCodexDynamicTools.js +91 -0
  73. package/dist/react/useCodexDynamicTools.js.map +1 -0
  74. package/dist/react/useCodexIngestHealth.d.ts +6 -0
  75. package/dist/react/useCodexIngestHealth.d.ts.map +1 -0
  76. package/dist/react/useCodexIngestHealth.js +9 -0
  77. package/dist/react/useCodexIngestHealth.js.map +1 -0
  78. package/dist/react/useCodexRuntimeBridge.d.ts +28 -0
  79. package/dist/react/useCodexRuntimeBridge.d.ts.map +1 -0
  80. package/dist/react/useCodexRuntimeBridge.js +78 -0
  81. package/dist/react/useCodexRuntimeBridge.js.map +1 -0
  82. package/dist/react/useCodexThreadActivity.d.ts +6 -0
  83. package/dist/react/useCodexThreadActivity.d.ts.map +1 -0
  84. package/dist/react/useCodexThreadActivity.js +9 -0
  85. package/dist/react/useCodexThreadActivity.js.map +1 -0
  86. package/dist/react/useCodexThreads.d.ts +30 -0
  87. package/dist/react/useCodexThreads.d.ts.map +1 -0
  88. package/dist/react/useCodexThreads.js +65 -0
  89. package/dist/react/useCodexThreads.js.map +1 -0
  90. package/dist/react-integration/index.d.ts +101 -0
  91. package/dist/react-integration/index.d.ts.map +1 -0
  92. package/dist/react-integration/index.js +62 -0
  93. package/dist/react-integration/index.js.map +1 -0
  94. package/docs/CLIENT_AND_REACT_HOOKS.md +63 -0
  95. package/docs/HOST_PRESET_MATRIX.md +1 -0
  96. package/docs/OPERATIONS_AND_ERRORS.md +8 -0
  97. package/package.json +9 -1
@@ -0,0 +1,65 @@
1
+ "use client";
2
+ import { useQuery } from "convex/react";
3
+ import { useCallback, useMemo, useState } from "react";
4
+ export function useCodexThreads(config) {
5
+ const listQueryArgs = config.list.args === "skip"
6
+ ? ["skip"]
7
+ : [config.list.args];
8
+ const listArgs = listQueryArgs;
9
+ const listed = useQuery(config.list.query, ...listArgs);
10
+ const [selectedThreadId, setSelectedThreadId] = useState(config.initialSelectedThreadId ?? null);
11
+ const [busyAction, setBusyAction] = useState(null);
12
+ const [error, setError] = useState(null);
13
+ const run = useCallback(async (action, fn) => {
14
+ setBusyAction(action);
15
+ setError(null);
16
+ try {
17
+ return await fn();
18
+ }
19
+ catch (nextError) {
20
+ const message = nextError instanceof Error ? nextError.message : String(nextError);
21
+ setError(message);
22
+ throw nextError;
23
+ }
24
+ finally {
25
+ setBusyAction((current) => (current === action ? null : current));
26
+ }
27
+ }, []);
28
+ const create = useCallback(async (args) => {
29
+ const createThread = config.controls?.createThread;
30
+ if (!createThread) {
31
+ return null;
32
+ }
33
+ return run("create", () => createThread(args));
34
+ }, [config.controls, run]);
35
+ const resolve = useCallback(async (localThreadId) => {
36
+ const resolveThread = config.controls?.resolveThread;
37
+ if (!resolveThread) {
38
+ return null;
39
+ }
40
+ const result = await run("resolve", () => resolveThread({ localThreadId }));
41
+ setSelectedThreadId(localThreadId);
42
+ return result;
43
+ }, [config.controls, run]);
44
+ const resume = useCallback(async (threadId) => {
45
+ const resumeThread = config.controls?.resumeThread;
46
+ if (!resumeThread) {
47
+ return null;
48
+ }
49
+ const result = await run("resume", () => resumeThread({ threadId }));
50
+ setSelectedThreadId(threadId);
51
+ return result;
52
+ }, [config.controls, run]);
53
+ return useMemo(() => ({
54
+ threads: listed,
55
+ selectedThreadId,
56
+ setSelectedThreadId,
57
+ busyAction,
58
+ isBusy: busyAction !== null,
59
+ error,
60
+ create,
61
+ resolve,
62
+ resume,
63
+ }), [busyAction, create, error, listed, resolve, resume, selectedThreadId]);
64
+ }
65
+ //# sourceMappingURL=useCodexThreads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCodexThreads.js","sourceRoot":"","sources":["../../src/react/useCodexThreads.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ import type { CodexDynamicToolHandler, CodexDynamicToolsQuery, CodexDynamicToolsRespond } from "../react/useCodexDynamicTools.js";
2
+ import type { CodexMessagesQuery } from "../react/types.js";
3
+ import type { CodexThreadActivityQuery } from "../react/useCodexThreadActivity.js";
4
+ import type { CodexThreadActivity, CodexThreadActivityThreadState } from "../react/threadActivity.js";
5
+ import type { CodexBranchActivityOptions } from "../react/branchActivity.js";
6
+ import type { CodexConversationApprovalDecision, CodexConversationApprovalItem } from "../react/useCodexConversationController.js";
7
+ export type CodexThreadScopeArgs<Actor extends Record<string, unknown>> = {
8
+ actor: Actor;
9
+ threadId: string;
10
+ };
11
+ export type CodexThreadTurnScopeArgs<Actor extends Record<string, unknown>> = CodexThreadScopeArgs<Actor> & {
12
+ turnId: string;
13
+ };
14
+ export type CodexReactHostHooks<Actor extends Record<string, unknown>> = {
15
+ listThreadMessagesForHooks: CodexMessagesQuery<{
16
+ actor: Actor;
17
+ }>;
18
+ threadSnapshotSafe: CodexThreadActivityQuery<{
19
+ actor: Actor;
20
+ }, CodexThreadActivityThreadState>;
21
+ listPendingServerRequestsForHooks?: CodexDynamicToolsQuery<{
22
+ actor: Actor;
23
+ threadId: string;
24
+ limit?: number;
25
+ }>;
26
+ };
27
+ export type CodexReactConversationControllerOptions = {
28
+ initialNumItems: number;
29
+ stream?: boolean;
30
+ branchOptions?: CodexBranchActivityOptions;
31
+ composer?: {
32
+ initialValue?: string;
33
+ onSend: (text: string) => Promise<unknown>;
34
+ };
35
+ approvals?: {
36
+ onResolve: (approval: CodexConversationApprovalItem, decision: CodexConversationApprovalDecision) => Promise<unknown>;
37
+ };
38
+ dynamicTools?: {
39
+ respond?: CodexDynamicToolsRespond;
40
+ handlers?: Record<string, CodexDynamicToolHandler>;
41
+ autoHandle?: boolean;
42
+ enabled?: boolean;
43
+ limit?: number;
44
+ };
45
+ interrupt?: {
46
+ onInterrupt: (activity: CodexThreadActivity) => Promise<unknown>;
47
+ };
48
+ };
49
+ export declare function codexThreadScopeArgs<Actor extends Record<string, unknown>>(actor: Actor, threadId: string | null | undefined): CodexThreadScopeArgs<Actor> | "skip";
50
+ export declare function codexThreadTurnScopeArgs<Actor extends Record<string, unknown>>(actor: Actor, threadId: string | null | undefined, turnId: string | null | undefined): CodexThreadTurnScopeArgs<Actor> | "skip";
51
+ export declare function createCodexReactConvexAdapter<Actor extends Record<string, unknown>>(config: {
52
+ actor: Actor;
53
+ hooks: CodexReactHostHooks<Actor>;
54
+ }): {
55
+ threadArgs: (threadId: string | null | undefined) => "skip" | CodexThreadScopeArgs<Actor>;
56
+ threadTurnArgs: (threadId: string | null | undefined, turnId: string | null | undefined) => "skip" | CodexThreadTurnScopeArgs<Actor>;
57
+ useThreadMessages: (threadId: string | null | undefined, options: {
58
+ initialNumItems: number;
59
+ stream?: boolean;
60
+ }) => import("convex/react").UsePaginatedQueryResult<import("../index.js").CodexUIMessage>;
61
+ useThreadActivity: (threadId: string | null | undefined) => CodexThreadActivity;
62
+ useBranchActivity: (threadId: string | null | undefined, options?: CodexBranchActivityOptions) => CodexThreadActivity;
63
+ useIngestHealth: (threadId: string | null | undefined) => import("../react/ingestHealth.js").CodexIngestHealth;
64
+ useConversationController: (threadId: string | null | undefined, options: CodexReactConversationControllerOptions) => {
65
+ messages: import("convex/react").UsePaginatedQueryResult<import("../index.js").CodexUIMessage>;
66
+ activity: CodexThreadActivity;
67
+ ingestHealth: import("../react/ingestHealth.js").CodexIngestHealth;
68
+ branchActivity: CodexThreadActivity;
69
+ approvals: {
70
+ pending: CodexConversationApprovalItem[];
71
+ pendingCount: number;
72
+ approvingItemId: string | null;
73
+ error: string | null;
74
+ canResolve: boolean;
75
+ resolve: (approval: CodexConversationApprovalItem, decision: CodexConversationApprovalDecision) => Promise<void>;
76
+ accept: (approval: CodexConversationApprovalItem) => Promise<void>;
77
+ decline: (approval: CodexConversationApprovalItem) => Promise<void>;
78
+ };
79
+ dynamicTools: {
80
+ requests: never[] | import("../react/dynamicTools.js").CodexDynamicToolServerRequest[];
81
+ calls: import("../react/dynamicTools.js").CodexDynamicToolCall[];
82
+ pendingCount: number;
83
+ runningRequestIds: string[];
84
+ lastError: string | null;
85
+ runCall: (call: import("../react/dynamicTools.js").CodexDynamicToolCall) => Promise<boolean>;
86
+ respond: (call: import("../react/dynamicTools.js").CodexDynamicToolCall, result: import("../react/dynamicTools.js").CodexDynamicToolResponse) => Promise<void>;
87
+ };
88
+ composer: {
89
+ value: string;
90
+ setValue: import("react").Dispatch<import("react").SetStateAction<string>>;
91
+ error: string | null;
92
+ isSending: boolean;
93
+ canSend: boolean;
94
+ send: (overrideText?: string) => Promise<void>;
95
+ };
96
+ interrupt: () => Promise<void>;
97
+ canInterrupt: boolean;
98
+ isInterrupting: boolean;
99
+ };
100
+ };
101
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react-integration/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ "use client";
2
+ import { useCodexMessages } from "../react/useCodexMessages.js";
3
+ import { useCodexBranchActivity } from "../react/useCodexBranchActivity.js";
4
+ import { useCodexConversationController } from "../react/useCodexConversationController.js";
5
+ import { useCodexIngestHealth } from "../react/useCodexIngestHealth.js";
6
+ import { useCodexThreadActivity } from "../react/useCodexThreadActivity.js";
7
+ export function codexThreadScopeArgs(actor, threadId) {
8
+ if (!threadId) {
9
+ return "skip";
10
+ }
11
+ return { actor, threadId };
12
+ }
13
+ export function codexThreadTurnScopeArgs(actor, threadId, turnId) {
14
+ if (!threadId || !turnId) {
15
+ return "skip";
16
+ }
17
+ return { actor, threadId, turnId };
18
+ }
19
+ export function createCodexReactConvexAdapter(config) {
20
+ return {
21
+ threadArgs: (threadId) => codexThreadScopeArgs(config.actor, threadId),
22
+ threadTurnArgs: (threadId, turnId) => codexThreadTurnScopeArgs(config.actor, threadId, turnId),
23
+ useThreadMessages: (threadId, options) => {
24
+ const args = codexThreadScopeArgs(config.actor, threadId);
25
+ return useCodexMessages(config.hooks.listThreadMessagesForHooks, args, options);
26
+ },
27
+ useThreadActivity: (threadId) => useCodexThreadActivity(config.hooks.threadSnapshotSafe, codexThreadScopeArgs(config.actor, threadId)),
28
+ useBranchActivity: (threadId, options) => useCodexBranchActivity(config.hooks.threadSnapshotSafe, codexThreadScopeArgs(config.actor, threadId), options),
29
+ useIngestHealth: (threadId) => useCodexIngestHealth(config.hooks.threadSnapshotSafe, codexThreadScopeArgs(config.actor, threadId)),
30
+ useConversationController: (threadId, options) => useCodexConversationController({
31
+ messages: {
32
+ query: config.hooks.listThreadMessagesForHooks,
33
+ args: codexThreadScopeArgs(config.actor, threadId),
34
+ initialNumItems: options.initialNumItems,
35
+ ...(options.stream !== undefined ? { stream: options.stream } : {}),
36
+ },
37
+ threadState: {
38
+ query: config.hooks.threadSnapshotSafe,
39
+ args: codexThreadScopeArgs(config.actor, threadId),
40
+ ...(options.branchOptions !== undefined ? { branchOptions: options.branchOptions } : {}),
41
+ },
42
+ ...(options.approvals !== undefined ? { approvals: options.approvals } : {}),
43
+ ...(options.dynamicTools !== undefined && config.hooks.listPendingServerRequestsForHooks !== undefined
44
+ ? {
45
+ dynamicTools: {
46
+ query: config.hooks.listPendingServerRequestsForHooks,
47
+ args: threadId
48
+ ? { actor: config.actor, threadId, ...(options.dynamicTools.limit !== undefined ? { limit: options.dynamicTools.limit } : {}) }
49
+ : "skip",
50
+ ...(options.dynamicTools.respond !== undefined ? { respond: options.dynamicTools.respond } : {}),
51
+ ...(options.dynamicTools.handlers !== undefined ? { handlers: options.dynamicTools.handlers } : {}),
52
+ ...(options.dynamicTools.autoHandle !== undefined ? { autoHandle: options.dynamicTools.autoHandle } : {}),
53
+ ...(options.dynamicTools.enabled !== undefined ? { enabled: options.dynamicTools.enabled } : {}),
54
+ },
55
+ }
56
+ : {}),
57
+ ...(options.composer !== undefined ? { composer: options.composer } : {}),
58
+ ...(options.interrupt !== undefined ? { interrupt: options.interrupt } : {}),
59
+ }),
60
+ };
61
+ }
62
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react-integration/index.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  # Client Helpers and React Hooks
2
2
 
3
3
  Canonical default: runtime-owned host integration (`dispatchManaged: false`).
4
+ Official recommendation: prefer React hooks over app-defined state composition.
4
5
 
5
6
  This doc defines client and hook contracts for the canonical path in `../LLMS.md`.
6
7
 
@@ -15,6 +16,7 @@ All hook/query/mutation args use `actor: { userId?: string }`.
15
16
 
16
17
  - `@zakstam/codex-local-component/client`
17
18
  - `@zakstam/codex-local-component/react`
19
+ - `@zakstam/codex-local-component/react-integration`
18
20
 
19
21
  Host Convex wrappers should come from generated runtime-owned host surfaces (`convex/chat.generated.ts`) plus app-owned extensions (`convex/chat.extensions.ts`).
20
22
 
@@ -46,6 +48,14 @@ Common helpers used by consumers:
46
48
  - `useCodexStreamingReasoning`
47
49
  - `useCodexTurn`
48
50
  - `useCodexThreadState`
51
+ - `useCodexThreadActivity`
52
+ - `useCodexIngestHealth`
53
+ - `useCodexBranchActivity`
54
+ - `useCodexConversationController`
55
+ - `useCodexDynamicTools`
56
+ - `useCodexRuntimeBridge`
57
+ - `useCodexAccountAuth`
58
+ - `useCodexThreads`
49
59
  - `useCodexApprovals`
50
60
  - `useCodexInterruptTurn`
51
61
  - `useCodexAutoResume`
@@ -75,10 +85,63 @@ Return shape:
75
85
 
76
86
  - `useCodexMessages` -> `chat.listThreadMessagesForHooks`
77
87
  - `useCodexTurn` -> `chat.listTurnMessagesForHooks`
88
+ - `useCodexThreadActivity` -> `chat.threadSnapshotSafe`
89
+ - `useCodexIngestHealth` -> `chat.threadSnapshotSafe`
90
+ - `useCodexBranchActivity` -> `chat.threadSnapshotSafe`
78
91
  - `useCodexApprovals` -> `chat.listPendingApprovalsForHooks` + `chat.respondApprovalForHooks`
92
+ - `useCodexDynamicTools` -> `chat.listPendingServerRequestsForHooks` + host runtime `respondDynamicToolCall(...)`
93
+ - `useCodexThreads` -> app thread-list query + thread lifecycle mutations
79
94
  - `useCodexInterruptTurn` -> `chat.interruptTurnForHooks`
80
95
  - `useCodexComposer` -> `chat.enqueueTurnDispatch`
81
96
 
97
+ ## Reference React Integration Adapter
98
+
99
+ Use `@zakstam/codex-local-component/react-integration` to centralize endpoint mapping and actor/thread arg shaping.
100
+
101
+ ```tsx
102
+ import { createCodexReactConvexAdapter } from "@zakstam/codex-local-component/react-integration";
103
+ import { api } from "../convex/_generated/api";
104
+
105
+ const actor = { userId: "demo-user" };
106
+ const codex = createCodexReactConvexAdapter({
107
+ actor,
108
+ hooks: api.chat,
109
+ });
110
+
111
+ const messages = codex.useThreadMessages(threadId, { initialNumItems: 30, stream: true });
112
+ const activity = codex.useThreadActivity(threadId);
113
+ const ingestHealth = codex.useIngestHealth(threadId);
114
+ const branchActivity = codex.useBranchActivity(threadId, { turnId: activeTurnId });
115
+ const conversation = codex.useConversationController(threadId, {
116
+ initialNumItems: 30,
117
+ stream: true,
118
+ approvals: {
119
+ onResolve: async (approval, decision) =>
120
+ respondApproval({ actor, threadId: approval.threadId, turnId: approval.turnId, itemId: approval.itemId, decision }),
121
+ },
122
+ composer: { onSend: async (text) => sendUserTurn(text) },
123
+ interrupt: { onInterrupt: async () => interruptTurn() },
124
+ });
125
+ ```
126
+
127
+ ## Blessed Example App
128
+
129
+ The blessed production wiring reference is:
130
+
131
+ - `apps/examples/tauri-app`
132
+
133
+ It demonstrates generated host wrappers plus React-first hook composition (`useCodexConversationController` and thread snapshot hooks).
134
+
135
+ ## Strict State Authority Table
136
+
137
+ | UI Signal | Source of truth | Ignore for this signal | Why |
138
+ | --- | --- | --- | --- |
139
+ | Thread activity badge (`idle/streaming/awaiting_approval/failed/interrupted`) | `useCodexThreadActivity(chat.threadSnapshotSafe, ...)` | Raw `messages`, `dispatches`, `turns`, `streamStats` stitching in app code | Prevents precedence bugs and "stuck streaming" regressions. |
140
+ | Show "needs approval" UI | `activity.phase === "awaiting_approval"` (or `pendingApprovals` count if not using activity hook) | Dispatch status alone | Dispatch lifecycle does not encode approval waits. |
141
+ | Render assistant text deltas | `useCodexMessages(..., { stream: true })` | `dispatches` and `turns` | Dispatch/turn state tracks orchestration, not message text continuity. |
142
+ | Enable cancel/interruption affordance | `activity.phase === "streaming"` with `activity.activeTurnId` | `threadStatus`, `dispatches` alone | Active turn identity should come from normalized activity. |
143
+ | Show terminal failure/interruption banner | `activity.phase === "failed"` / `"interrupted"` | Any single terminal row without recency precedence | Multiple terminal signals can coexist across turns. Use canonical merge logic. |
144
+
82
145
  ## Minimal Usage
83
146
 
84
147
  ```tsx
@@ -19,6 +19,7 @@ All focused preset builders include:
19
19
  - `getTurnDispatchState`
20
20
  - `getDispatchObservability`
21
21
  - `threadSnapshot`
22
+ - `threadSnapshotSafe`
22
23
  - `persistenceStats`
23
24
  - `durableHistoryStats`
24
25
  - `listThreadMessagesForHooks`
@@ -30,6 +30,14 @@ This is an operations/runbook companion to `../LLMS.md`.
30
30
 
31
31
  Use `sync.ingestSafe` in host wrappers so recoverable conditions return structured status instead of hard-failing the loop.
32
32
 
33
+ Public classifier utilities are available for consistent host/app fallback handling:
34
+
35
+ - `parseErrorCode(error)`
36
+ - `isThreadMissing(error)`
37
+ - `isThreadForbidden(error)`
38
+ - `isSessionForbidden(error)`
39
+ - `isRecoverableIngestError(errorOrSafeEntry)`
40
+
33
41
  ## Terminal Status Parsing Errors
34
42
 
35
43
  - `E_TERMINAL_PAYLOAD_PARSE_FAILED`: could not decode terminal event payload.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zakstam/codex-local-component",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -17,6 +17,14 @@
17
17
  "types": "./dist/react/index.d.ts",
18
18
  "import": "./dist/react/index.js"
19
19
  },
20
+ "./react-integration": {
21
+ "types": "./dist/react-integration/index.d.ts",
22
+ "import": "./dist/react-integration/index.js"
23
+ },
24
+ "./errors": {
25
+ "types": "./dist/errors.d.ts",
26
+ "import": "./dist/errors.js"
27
+ },
20
28
  "./convex.config": {
21
29
  "types": "./dist/component/convex.config.d.ts",
22
30
  "import": "./dist/component/convex.config.js"