@openharness/react 0.2.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 (41) hide show
  1. package/dist/__tests__/provider.test.d.ts +2 -0
  2. package/dist/__tests__/provider.test.d.ts.map +1 -0
  3. package/dist/__tests__/provider.test.js +217 -0
  4. package/dist/__tests__/provider.test.js.map +1 -0
  5. package/dist/__tests__/transport.test.d.ts +2 -0
  6. package/dist/__tests__/transport.test.d.ts.map +1 -0
  7. package/dist/__tests__/transport.test.js +17 -0
  8. package/dist/__tests__/transport.test.js.map +1 -0
  9. package/dist/context.d.ts +38 -0
  10. package/dist/context.d.ts.map +1 -0
  11. package/dist/context.js +25 -0
  12. package/dist/context.js.map +1 -0
  13. package/dist/hooks/use-open-harness.d.ts +21 -0
  14. package/dist/hooks/use-open-harness.d.ts.map +1 -0
  15. package/dist/hooks/use-open-harness.js +29 -0
  16. package/dist/hooks/use-open-harness.js.map +1 -0
  17. package/dist/hooks/use-sandbox-status.d.ts +12 -0
  18. package/dist/hooks/use-sandbox-status.d.ts.map +1 -0
  19. package/dist/hooks/use-sandbox-status.js +15 -0
  20. package/dist/hooks/use-sandbox-status.js.map +1 -0
  21. package/dist/hooks/use-session-status.d.ts +8 -0
  22. package/dist/hooks/use-session-status.d.ts.map +1 -0
  23. package/dist/hooks/use-session-status.js +11 -0
  24. package/dist/hooks/use-session-status.js.map +1 -0
  25. package/dist/hooks/use-subagent-status.d.ts +17 -0
  26. package/dist/hooks/use-subagent-status.d.ts.map +1 -0
  27. package/dist/hooks/use-subagent-status.js +21 -0
  28. package/dist/hooks/use-subagent-status.js.map +1 -0
  29. package/dist/index.d.ts +8 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +10 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/provider.d.ts +12 -0
  34. package/dist/provider.d.ts.map +1 -0
  35. package/dist/provider.js +127 -0
  36. package/dist/provider.js.map +1 -0
  37. package/dist/transport.d.ts +13 -0
  38. package/dist/transport.d.ts.map +1 -0
  39. package/dist/transport.js +15 -0
  40. package/dist/transport.js.map +1 -0
  41. package/package.json +35 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=provider.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/provider.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,217 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // @vitest-environment jsdom
3
+ import { describe, it, expect } from "vitest";
4
+ import { renderHook, act } from "@testing-library/react";
5
+ import { OpenHarnessProvider } from "../provider.js";
6
+ import { useSubagentStatus } from "../hooks/use-subagent-status.js";
7
+ import { useSessionStatus } from "../hooks/use-session-status.js";
8
+ import { useSandboxStatus } from "../hooks/use-sandbox-status.js";
9
+ import { useOHContext } from "../context.js";
10
+ // ── Test wrapper ────────────────────────────────────────────────────
11
+ function wrapper({ children }) {
12
+ return _jsx(OpenHarnessProvider, { children: children });
13
+ }
14
+ // Helper hook to access dispatch directly for testing
15
+ function useDispatch() {
16
+ return useOHContext().dispatch;
17
+ }
18
+ // ── Provider ────────────────────────────────────────────────────────
19
+ describe("OpenHarnessProvider", () => {
20
+ it("provides initial context without errors", () => {
21
+ const { result } = renderHook(() => useSessionStatus(), { wrapper });
22
+ expect(result.current.currentTurn).toBe(0);
23
+ expect(result.current.isCompacting).toBe(false);
24
+ expect(result.current.isRetrying).toBe(false);
25
+ });
26
+ it("throws when hooks are used outside provider", () => {
27
+ expect(() => {
28
+ renderHook(() => useSessionStatus());
29
+ }).toThrow("useOpenHarness hooks must be used within an <OpenHarnessProvider>");
30
+ });
31
+ });
32
+ // ── useSubagentStatus ───────────────────────────────────────────────
33
+ describe("useSubagentStatus", () => {
34
+ it("starts with no subagents", () => {
35
+ const { result } = renderHook(() => useSubagentStatus(), { wrapper });
36
+ expect(result.current.activeSubagents).toHaveLength(0);
37
+ expect(result.current.recentSubagents).toHaveLength(0);
38
+ expect(result.current.hasActiveSubagents).toBe(false);
39
+ });
40
+ it("tracks subagent start", () => {
41
+ const { result } = renderHook(() => ({ sub: useSubagentStatus(), dispatch: useDispatch() }), { wrapper });
42
+ act(() => {
43
+ result.current.dispatch({
44
+ type: "data-oh:subagent.start",
45
+ data: { agentName: "explore", task: "search codebase" },
46
+ });
47
+ });
48
+ expect(result.current.sub.activeSubagents).toHaveLength(1);
49
+ expect(result.current.sub.activeSubagents[0].name).toBe("explore");
50
+ expect(result.current.sub.activeSubagents[0].task).toBe("search codebase");
51
+ expect(result.current.sub.activeSubagents[0].status).toBe("running");
52
+ expect(result.current.sub.hasActiveSubagents).toBe(true);
53
+ });
54
+ it("tracks subagent completion", () => {
55
+ const { result } = renderHook(() => ({ sub: useSubagentStatus(), dispatch: useDispatch() }), { wrapper });
56
+ act(() => {
57
+ result.current.dispatch({
58
+ type: "data-oh:subagent.start",
59
+ data: { agentName: "explore", task: "search" },
60
+ });
61
+ });
62
+ act(() => {
63
+ result.current.dispatch({
64
+ type: "data-oh:subagent.done",
65
+ data: { agentName: "explore", durationMs: 1500 },
66
+ });
67
+ });
68
+ expect(result.current.sub.activeSubagents).toHaveLength(0);
69
+ expect(result.current.sub.recentSubagents).toHaveLength(1);
70
+ expect(result.current.sub.recentSubagents[0].status).toBe("done");
71
+ expect(result.current.sub.recentSubagents[0].durationMs).toBe(1500);
72
+ expect(result.current.sub.hasActiveSubagents).toBe(false);
73
+ });
74
+ it("tracks subagent error", () => {
75
+ const { result } = renderHook(() => ({ sub: useSubagentStatus(), dispatch: useDispatch() }), { wrapper });
76
+ act(() => {
77
+ result.current.dispatch({
78
+ type: "data-oh:subagent.start",
79
+ data: { agentName: "explore", task: "search" },
80
+ });
81
+ });
82
+ act(() => {
83
+ result.current.dispatch({
84
+ type: "data-oh:subagent.error",
85
+ data: { agentName: "explore", error: "Agent crashed" },
86
+ });
87
+ });
88
+ expect(result.current.sub.activeSubagents).toHaveLength(0);
89
+ expect(result.current.sub.recentSubagents[0].status).toBe("error");
90
+ expect(result.current.sub.recentSubagents[0].error).toBe("Agent crashed");
91
+ });
92
+ it("tracks multiple concurrent subagents", () => {
93
+ const { result } = renderHook(() => ({ sub: useSubagentStatus(), dispatch: useDispatch() }), { wrapper });
94
+ act(() => {
95
+ result.current.dispatch({
96
+ type: "data-oh:subagent.start",
97
+ data: { agentName: "explore", task: "search" },
98
+ });
99
+ result.current.dispatch({
100
+ type: "data-oh:subagent.start",
101
+ data: { agentName: "code-writer", task: "implement feature" },
102
+ });
103
+ });
104
+ expect(result.current.sub.activeSubagents).toHaveLength(2);
105
+ expect(result.current.sub.hasActiveSubagents).toBe(true);
106
+ act(() => {
107
+ result.current.dispatch({
108
+ type: "data-oh:subagent.done",
109
+ data: { agentName: "explore", durationMs: 500 },
110
+ });
111
+ });
112
+ expect(result.current.sub.activeSubagents).toHaveLength(1);
113
+ expect(result.current.sub.activeSubagents[0].name).toBe("code-writer");
114
+ });
115
+ });
116
+ // ── useSessionStatus ────────────────────────────────────────────────
117
+ describe("useSessionStatus", () => {
118
+ it("starts with initial state", () => {
119
+ const { result } = renderHook(() => useSessionStatus(), { wrapper });
120
+ expect(result.current).toEqual({
121
+ isCompacting: false,
122
+ isRetrying: false,
123
+ retryAttempt: 0,
124
+ retryReason: null,
125
+ currentTurn: 0,
126
+ lastCompactionAt: null,
127
+ messagesRemovedByCompaction: 0,
128
+ });
129
+ });
130
+ it("tracks turn start", () => {
131
+ const { result } = renderHook(() => ({ session: useSessionStatus(), dispatch: useDispatch() }), { wrapper });
132
+ act(() => {
133
+ result.current.dispatch({
134
+ type: "data-oh:turn.start",
135
+ data: { turnIndex: 3 },
136
+ });
137
+ });
138
+ expect(result.current.session.currentTurn).toBe(3);
139
+ });
140
+ it("tracks compaction lifecycle", () => {
141
+ const { result } = renderHook(() => ({ session: useSessionStatus(), dispatch: useDispatch() }), { wrapper });
142
+ act(() => {
143
+ result.current.dispatch({ type: "data-oh:compaction.start" });
144
+ });
145
+ expect(result.current.session.isCompacting).toBe(true);
146
+ act(() => {
147
+ result.current.dispatch({
148
+ type: "data-oh:compaction.done",
149
+ data: { messagesRemoved: 5 },
150
+ });
151
+ });
152
+ expect(result.current.session.isCompacting).toBe(false);
153
+ expect(result.current.session.lastCompactionAt).toBeInstanceOf(Date);
154
+ expect(result.current.session.messagesRemovedByCompaction).toBe(5);
155
+ });
156
+ it("accumulates messages removed across compactions", () => {
157
+ const { result } = renderHook(() => ({ session: useSessionStatus(), dispatch: useDispatch() }), { wrapper });
158
+ act(() => {
159
+ result.current.dispatch({ type: "data-oh:compaction.start" });
160
+ result.current.dispatch({
161
+ type: "data-oh:compaction.done",
162
+ data: { messagesRemoved: 3 },
163
+ });
164
+ });
165
+ act(() => {
166
+ result.current.dispatch({ type: "data-oh:compaction.start" });
167
+ result.current.dispatch({
168
+ type: "data-oh:compaction.done",
169
+ data: { messagesRemoved: 7 },
170
+ });
171
+ });
172
+ expect(result.current.session.messagesRemovedByCompaction).toBe(10);
173
+ });
174
+ it("tracks retry state", () => {
175
+ const { result } = renderHook(() => ({ session: useSessionStatus(), dispatch: useDispatch() }), { wrapper });
176
+ act(() => {
177
+ result.current.dispatch({
178
+ type: "data-oh:retry",
179
+ data: { attempt: 2, reason: "rate limit", delayMs: 3000 },
180
+ });
181
+ });
182
+ expect(result.current.session.isRetrying).toBe(true);
183
+ expect(result.current.session.retryAttempt).toBe(2);
184
+ expect(result.current.session.retryReason).toBe("rate limit");
185
+ });
186
+ });
187
+ // ── useSandboxStatus ────────────────────────────────────────────────
188
+ describe("useSandboxStatus", () => {
189
+ it("starts with initial idle state", () => {
190
+ const { result } = renderHook(() => useSandboxStatus(), { wrapper });
191
+ expect(result.current).toEqual({
192
+ isProvisioning: false,
193
+ isWarm: false,
194
+ provisioningMessage: null,
195
+ provisionedAt: null,
196
+ });
197
+ });
198
+ it("tracks sandbox provisioning lifecycle", () => {
199
+ const { result } = renderHook(() => ({ sandbox: useSandboxStatus(), dispatch: useDispatch() }), { wrapper });
200
+ act(() => {
201
+ result.current.dispatch({
202
+ type: "data-oh:sandbox.provisioning",
203
+ data: { message: "Setting up workspace..." },
204
+ });
205
+ });
206
+ expect(result.current.sandbox.isProvisioning).toBe(true);
207
+ expect(result.current.sandbox.provisioningMessage).toBe("Setting up workspace...");
208
+ act(() => {
209
+ result.current.dispatch({ type: "data-oh:sandbox.ready" });
210
+ });
211
+ expect(result.current.sandbox.isProvisioning).toBe(false);
212
+ expect(result.current.sandbox.isWarm).toBe(true);
213
+ expect(result.current.sandbox.provisionedAt).toBeInstanceOf(Date);
214
+ expect(result.current.sandbox.provisioningMessage).toBeNull();
215
+ });
216
+ });
217
+ //# sourceMappingURL=provider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.test.js","sourceRoot":"","sources":["../../src/__tests__/provider.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=transport.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/transport.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { createOHTransport } from "../transport.js";
3
+ describe("createOHTransport", () => {
4
+ it("returns a transport object", () => {
5
+ const transport = createOHTransport("/api/chat");
6
+ expect(transport).toBeTruthy();
7
+ expect(typeof transport.sendMessages).toBe("function");
8
+ });
9
+ it("accepts custom options", () => {
10
+ const transport = createOHTransport("/api/agent/stream", {
11
+ headers: { Authorization: "Bearer test" },
12
+ credentials: "include",
13
+ });
14
+ expect(transport).toBeTruthy();
15
+ });
16
+ });
17
+ //# sourceMappingURL=transport.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.test.js","sourceRoot":"","sources":["../../src/__tests__/transport.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,SAAS,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;QACjD,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;QAC/B,MAAM,CAAC,OAAO,SAAS,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,SAAS,GAAG,iBAAiB,CAAC,mBAAmB,EAAE;YACvD,OAAO,EAAE,EAAE,aAAa,EAAE,aAAa,EAAE;YACzC,WAAW,EAAE,SAAS;SACvB,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,38 @@
1
+ export interface SubagentInfo {
2
+ name: string;
3
+ task: string;
4
+ status: "running" | "done" | "error";
5
+ parentAgent?: string;
6
+ startedAt: number;
7
+ durationMs?: number;
8
+ error?: string;
9
+ }
10
+ export interface SessionState {
11
+ isCompacting: boolean;
12
+ isRetrying: boolean;
13
+ retryAttempt: number;
14
+ retryReason: string | null;
15
+ currentTurn: number;
16
+ lastCompactionAt: Date | null;
17
+ messagesRemovedByCompaction: number;
18
+ }
19
+ export declare const initialSessionState: SessionState;
20
+ export interface SandboxState {
21
+ isProvisioning: boolean;
22
+ isWarm: boolean;
23
+ provisioningMessage: string | null;
24
+ provisionedAt: Date | null;
25
+ }
26
+ export declare const initialSandboxState: SandboxState;
27
+ export interface OHContextValue {
28
+ subagents: Map<string, SubagentInfo>;
29
+ sessionState: SessionState;
30
+ sandboxState: SandboxState;
31
+ dispatch: (part: {
32
+ type: string;
33
+ data?: unknown;
34
+ }) => void;
35
+ }
36
+ export declare const OHContext: import("react").Context<OHContextValue | null>;
37
+ export declare function useOHContext(): OHContextValue;
38
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,IAAI,GAAG,IAAI,CAAC;IAC9B,2BAA2B,EAAE,MAAM,CAAC;CACrC;AAED,eAAO,MAAM,mBAAmB,EAAE,YAQjC,CAAC;AAIF,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,aAAa,EAAE,IAAI,GAAG,IAAI,CAAC;CAC5B;AAED,eAAO,MAAM,mBAAmB,EAAE,YAKjC,CAAC;AAIF,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACrC,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC5D;AAED,eAAO,MAAM,SAAS,gDAA6C,CAAC;AAEpE,wBAAgB,YAAY,IAAI,cAAc,CAQ7C"}
@@ -0,0 +1,25 @@
1
+ import { createContext, useContext } from "react";
2
+ export const initialSessionState = {
3
+ isCompacting: false,
4
+ isRetrying: false,
5
+ retryAttempt: 0,
6
+ retryReason: null,
7
+ currentTurn: 0,
8
+ lastCompactionAt: null,
9
+ messagesRemovedByCompaction: 0,
10
+ };
11
+ export const initialSandboxState = {
12
+ isProvisioning: false,
13
+ isWarm: false,
14
+ provisioningMessage: null,
15
+ provisionedAt: null,
16
+ };
17
+ export const OHContext = createContext(null);
18
+ export function useOHContext() {
19
+ const ctx = useContext(OHContext);
20
+ if (!ctx) {
21
+ throw new Error("useOpenHarness hooks must be used within an <OpenHarnessProvider>");
22
+ }
23
+ return ctx;
24
+ }
25
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AA0BlD,MAAM,CAAC,MAAM,mBAAmB,GAAiB;IAC/C,YAAY,EAAE,KAAK;IACnB,UAAU,EAAE,KAAK;IACjB,YAAY,EAAE,CAAC;IACf,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,CAAC;IACd,gBAAgB,EAAE,IAAI;IACtB,2BAA2B,EAAE,CAAC;CAC/B,CAAC;AAWF,MAAM,CAAC,MAAM,mBAAmB,GAAiB;IAC/C,cAAc,EAAE,KAAK;IACrB,MAAM,EAAE,KAAK;IACb,mBAAmB,EAAE,IAAI;IACzB,aAAa,EAAE,IAAI;CACpB,CAAC;AAWF,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAwB,IAAI,CAAC,CAAC;AAEpE,MAAM,UAAU,YAAY;IAC1B,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IAClC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { type UseChatHelpers } from "@ai-sdk/react";
2
+ import type { OHUIMessage } from "@openharness/core";
3
+ import { type OHTransportOptions } from "../transport.js";
4
+ export interface UseOpenHarnessConfig extends OHTransportOptions {
5
+ /** Your SSE endpoint URL. */
6
+ endpoint: string;
7
+ /** Stable chat ID for sharing state across components. */
8
+ id?: string;
9
+ /** Called when the assistant message finishes streaming. */
10
+ onFinish?: (message: OHUIMessage) => void;
11
+ }
12
+ /**
13
+ * Primary hook for OpenHarness chat. Wraps AI SDK 5's `useChat` with:
14
+ * - `OHUIMessage` as the message type
15
+ * - Transport pre-wired to your endpoint
16
+ * - Data parts routed into the OpenHarnessProvider's event dispatcher
17
+ *
18
+ * Must be used within an `<OpenHarnessProvider>`.
19
+ */
20
+ export declare function useOpenHarness(config: UseOpenHarnessConfig): UseChatHelpers<OHUIMessage>;
21
+ //# sourceMappingURL=use-open-harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-open-harness.d.ts","sourceRoot":"","sources":["../../src/hooks/use-open-harness.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,cAAc,EAAQ,MAAM,eAAe,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE7E,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC9D,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;CAC3C;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,oBAAoB,GAC3B,cAAc,CAAC,WAAW,CAAC,CAiB7B"}
@@ -0,0 +1,29 @@
1
+ import { useRef } from "react";
2
+ import { useChat, Chat } from "@ai-sdk/react";
3
+ import { useOHContext } from "../context.js";
4
+ import { createOHTransport } from "../transport.js";
5
+ /**
6
+ * Primary hook for OpenHarness chat. Wraps AI SDK 5's `useChat` with:
7
+ * - `OHUIMessage` as the message type
8
+ * - Transport pre-wired to your endpoint
9
+ * - Data parts routed into the OpenHarnessProvider's event dispatcher
10
+ *
11
+ * Must be used within an `<OpenHarnessProvider>`.
12
+ */
13
+ export function useOpenHarness(config) {
14
+ const { dispatch } = useOHContext();
15
+ // Create a stable Chat instance so useChat doesn't recreate on every render
16
+ const chatRef = useRef(null);
17
+ if (!chatRef.current) {
18
+ chatRef.current = new Chat({
19
+ id: config.id,
20
+ transport: createOHTransport(config.endpoint, config),
21
+ onData: (part) => dispatch(part),
22
+ onFinish: config.onFinish
23
+ ? ({ message }) => config.onFinish(message)
24
+ : undefined,
25
+ });
26
+ }
27
+ return useChat({ chat: chatRef.current });
28
+ }
29
+ //# sourceMappingURL=use-open-harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-open-harness.js","sourceRoot":"","sources":["../../src/hooks/use-open-harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAuB,IAAI,EAAE,MAAM,eAAe,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAA2B,MAAM,iBAAiB,CAAC;AAW7E;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,MAA4B;IAE5B,MAAM,EAAE,QAAQ,EAAE,GAAG,YAAY,EAAE,CAAC;IAEpC,4EAA4E;IAC5E,MAAM,OAAO,GAAG,MAAM,CAA2B,IAAI,CAAC,CAAC;IACvD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,CAAC,OAAO,GAAG,IAAI,IAAI,CAAc;YACtC,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,SAAS,EAAE,iBAAiB,CAAc,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC;YAClE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;YAChC,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACvB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,QAAS,CAAC,OAAO,CAAC;gBAC5C,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAc,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type SandboxState } from "../context.js";
2
+ /**
3
+ * Derives sandbox provisioning state.
4
+ *
5
+ * This hook depends on the agent layer emitting `oh:sandbox.*` data parts.
6
+ * If your agent setup doesn't use a sandbox, this hook is a no-op —
7
+ * it will always return the initial (idle) state.
8
+ *
9
+ * Must be used within an `<OpenHarnessProvider>`.
10
+ */
11
+ export declare function useSandboxStatus(): SandboxState;
12
+ //# sourceMappingURL=use-sandbox-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-sandbox-status.d.ts","sourceRoot":"","sources":["../../src/hooks/use-sandbox-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEhE;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,CAG/C"}
@@ -0,0 +1,15 @@
1
+ import { useOHContext } from "../context.js";
2
+ /**
3
+ * Derives sandbox provisioning state.
4
+ *
5
+ * This hook depends on the agent layer emitting `oh:sandbox.*` data parts.
6
+ * If your agent setup doesn't use a sandbox, this hook is a no-op —
7
+ * it will always return the initial (idle) state.
8
+ *
9
+ * Must be used within an `<OpenHarnessProvider>`.
10
+ */
11
+ export function useSandboxStatus() {
12
+ const { sandboxState } = useOHContext();
13
+ return sandboxState;
14
+ }
15
+ //# sourceMappingURL=use-sandbox-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-sandbox-status.js","sourceRoot":"","sources":["../../src/hooks/use-sandbox-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAqB,MAAM,eAAe,CAAC;AAEhE;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAAC;IACxC,OAAO,YAAY,CAAC;AACtB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type SessionState } from "../context.js";
2
+ /**
3
+ * Derives session lifecycle state: compaction, retry, and turn info.
4
+ *
5
+ * Must be used within an `<OpenHarnessProvider>`.
6
+ */
7
+ export declare function useSessionStatus(): SessionState;
8
+ //# sourceMappingURL=use-session-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-session-status.d.ts","sourceRoot":"","sources":["../../src/hooks/use-session-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEhE;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,CAG/C"}
@@ -0,0 +1,11 @@
1
+ import { useOHContext } from "../context.js";
2
+ /**
3
+ * Derives session lifecycle state: compaction, retry, and turn info.
4
+ *
5
+ * Must be used within an `<OpenHarnessProvider>`.
6
+ */
7
+ export function useSessionStatus() {
8
+ const { sessionState } = useOHContext();
9
+ return sessionState;
10
+ }
11
+ //# sourceMappingURL=use-session-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-session-status.js","sourceRoot":"","sources":["../../src/hooks/use-session-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAqB,MAAM,eAAe,CAAC;AAEhE;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAAC;IACxC,OAAO,YAAY,CAAC;AACtB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type SubagentInfo } from "../context.js";
2
+ export interface UseSubagentStatusResult {
3
+ /** Currently running subagents. */
4
+ activeSubagents: SubagentInfo[];
5
+ /** All subagents (running, done, or errored) from the current session. */
6
+ recentSubagents: SubagentInfo[];
7
+ /** True when at least one subagent is running. */
8
+ hasActiveSubagents: boolean;
9
+ }
10
+ /**
11
+ * Derives real-time subagent state from the provider's event stream.
12
+ * No polling or manual `onData` wiring needed.
13
+ *
14
+ * Must be used within an `<OpenHarnessProvider>`.
15
+ */
16
+ export declare function useSubagentStatus(): UseSubagentStatusResult;
17
+ //# sourceMappingURL=use-subagent-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-subagent-status.d.ts","sourceRoot":"","sources":["../../src/hooks/use-subagent-status.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEhE,MAAM,WAAW,uBAAuB;IACtC,mCAAmC;IACnC,eAAe,EAAE,YAAY,EAAE,CAAC;IAChC,0EAA0E;IAC1E,eAAe,EAAE,YAAY,EAAE,CAAC;IAChC,kDAAkD;IAClD,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,uBAAuB,CAY3D"}
@@ -0,0 +1,21 @@
1
+ import { useMemo } from "react";
2
+ import { useOHContext } from "../context.js";
3
+ /**
4
+ * Derives real-time subagent state from the provider's event stream.
5
+ * No polling or manual `onData` wiring needed.
6
+ *
7
+ * Must be used within an `<OpenHarnessProvider>`.
8
+ */
9
+ export function useSubagentStatus() {
10
+ const { subagents } = useOHContext();
11
+ return useMemo(() => {
12
+ const all = Array.from(subagents.values());
13
+ const active = all.filter((s) => s.status === "running");
14
+ return {
15
+ activeSubagents: active,
16
+ recentSubagents: all,
17
+ hasActiveSubagents: active.length > 0,
18
+ };
19
+ }, [subagents]);
20
+ }
21
+ //# sourceMappingURL=use-subagent-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-subagent-status.js","sourceRoot":"","sources":["../../src/hooks/use-subagent-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,YAAY,EAAqB,MAAM,eAAe,CAAC;AAWhE;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,EAAE,CAAC;IAErC,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;QACzD,OAAO;YACL,eAAe,EAAE,MAAM;YACvB,eAAe,EAAE,GAAG;YACpB,kBAAkB,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC;SACtC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { OpenHarnessProvider, type OpenHarnessProviderProps, } from "./provider.js";
2
+ export { useOpenHarness, type UseOpenHarnessConfig, } from "./hooks/use-open-harness.js";
3
+ export { useSubagentStatus, type UseSubagentStatusResult, } from "./hooks/use-subagent-status.js";
4
+ export { useSessionStatus } from "./hooks/use-session-status.js";
5
+ export { useSandboxStatus } from "./hooks/use-sandbox-status.js";
6
+ export { createOHTransport, type OHTransportOptions, } from "./transport.js";
7
+ export { type SubagentInfo, type SessionState, type SandboxState, } from "./context.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,KAAK,wBAAwB,GAC9B,MAAM,eAAe,CAAC;AAIvB,OAAO,EACL,cAAc,EACd,KAAK,oBAAoB,GAC1B,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,iBAAiB,EACjB,KAAK,uBAAuB,GAC7B,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,OAAO,EACL,iBAAiB,EACjB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ // ── Provider ────────────────────────────────────────────────────────
2
+ export { OpenHarnessProvider, } from "./provider.js";
3
+ // ── Hooks ───────────────────────────────────────────────────────────
4
+ export { useOpenHarness, } from "./hooks/use-open-harness.js";
5
+ export { useSubagentStatus, } from "./hooks/use-subagent-status.js";
6
+ export { useSessionStatus } from "./hooks/use-session-status.js";
7
+ export { useSandboxStatus } from "./hooks/use-sandbox-status.js";
8
+ // ── Transport ───────────────────────────────────────────────────────
9
+ export { createOHTransport, } from "./transport.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,EACL,mBAAmB,GAEpB,MAAM,eAAe,CAAC;AAEvB,uEAAuE;AAEvE,OAAO,EACL,cAAc,GAEf,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,iBAAiB,GAElB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,uEAAuE;AAEvE,OAAO,EACL,iBAAiB,GAElB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type ReactNode } from "react";
2
+ export interface OpenHarnessProviderProps {
3
+ children: ReactNode;
4
+ }
5
+ /**
6
+ * Provides shared OpenHarness state (subagent, session, sandbox) to all
7
+ * child hooks. Place this at the root of your chat UI.
8
+ *
9
+ * The provider does NOT render any UI — it only manages state.
10
+ */
11
+ export declare function OpenHarnessProvider({ children }: OpenHarnessProviderProps): import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAWtE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAAE,EAAE,wBAAwB,2CAwIzE"}
@@ -0,0 +1,127 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState, useCallback, useRef } from "react";
3
+ import { OHContext, initialSessionState, initialSandboxState, } from "./context.js";
4
+ /**
5
+ * Provides shared OpenHarness state (subagent, session, sandbox) to all
6
+ * child hooks. Place this at the root of your chat UI.
7
+ *
8
+ * The provider does NOT render any UI — it only manages state.
9
+ */
10
+ export function OpenHarnessProvider({ children }) {
11
+ const [subagents, setSubagents] = useState(() => new Map());
12
+ const [sessionState, setSessionState] = useState(initialSessionState);
13
+ const [sandboxState, setSandboxState] = useState(initialSandboxState);
14
+ // Use a ref to avoid re-creating dispatch on every render
15
+ const subagentsRef = useRef(subagents);
16
+ subagentsRef.current = subagents;
17
+ const dispatch = useCallback((part) => {
18
+ const data = part.data;
19
+ switch (part.type) {
20
+ // ── Subagent events ──────────────────────────────────────
21
+ case "data-oh:subagent.start": {
22
+ const name = data?.agentName ?? "unknown";
23
+ const info = {
24
+ name,
25
+ task: data?.task ?? "",
26
+ status: "running",
27
+ parentAgent: data?.parentAgent,
28
+ startedAt: Date.now(),
29
+ };
30
+ setSubagents((prev) => {
31
+ const next = new Map(prev);
32
+ next.set(name, info);
33
+ return next;
34
+ });
35
+ break;
36
+ }
37
+ case "data-oh:subagent.done": {
38
+ const name = data?.agentName ?? "unknown";
39
+ setSubagents((prev) => {
40
+ const existing = prev.get(name);
41
+ if (!existing)
42
+ return prev;
43
+ const next = new Map(prev);
44
+ next.set(name, {
45
+ ...existing,
46
+ status: "done",
47
+ durationMs: data?.durationMs ?? Date.now() - existing.startedAt,
48
+ });
49
+ return next;
50
+ });
51
+ break;
52
+ }
53
+ case "data-oh:subagent.error": {
54
+ const name = data?.agentName ?? "unknown";
55
+ setSubagents((prev) => {
56
+ const existing = prev.get(name);
57
+ if (!existing)
58
+ return prev;
59
+ const next = new Map(prev);
60
+ next.set(name, {
61
+ ...existing,
62
+ status: "error",
63
+ error: data?.error ?? "Unknown error",
64
+ });
65
+ return next;
66
+ });
67
+ break;
68
+ }
69
+ // ── Session lifecycle events ─────────────────────────────
70
+ case "data-oh:turn.start":
71
+ setSessionState((prev) => ({
72
+ ...prev,
73
+ currentTurn: data?.turnIndex ?? prev.currentTurn + 1,
74
+ }));
75
+ break;
76
+ case "data-oh:turn.done":
77
+ // Turn completed — no special state change needed
78
+ break;
79
+ case "data-oh:session.compacting":
80
+ case "data-oh:compaction.start":
81
+ setSessionState((prev) => ({ ...prev, isCompacting: true }));
82
+ break;
83
+ case "data-oh:compaction.done":
84
+ setSessionState((prev) => ({
85
+ ...prev,
86
+ isCompacting: false,
87
+ lastCompactionAt: new Date(),
88
+ messagesRemovedByCompaction: prev.messagesRemovedByCompaction +
89
+ (data?.messagesRemoved ?? 0),
90
+ }));
91
+ break;
92
+ case "data-oh:retry":
93
+ setSessionState((prev) => ({
94
+ ...prev,
95
+ isRetrying: true,
96
+ retryAttempt: data?.attempt ?? prev.retryAttempt + 1,
97
+ retryReason: data?.reason ?? null,
98
+ }));
99
+ break;
100
+ // ── Sandbox events (future) ──────────────────────────────
101
+ case "data-oh:sandbox.provisioning":
102
+ setSandboxState((prev) => ({
103
+ ...prev,
104
+ isProvisioning: true,
105
+ provisioningMessage: data?.message ?? "Provisioning...",
106
+ }));
107
+ break;
108
+ case "data-oh:sandbox.ready":
109
+ setSandboxState((prev) => ({
110
+ ...prev,
111
+ isProvisioning: false,
112
+ isWarm: true,
113
+ provisionedAt: new Date(),
114
+ provisioningMessage: null,
115
+ }));
116
+ break;
117
+ }
118
+ }, []);
119
+ const value = {
120
+ subagents,
121
+ sessionState,
122
+ sandboxState,
123
+ dispatch,
124
+ };
125
+ return _jsx(OHContext.Provider, { value: value, children: children });
126
+ }
127
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type ChatTransport, type UIMessage } from "ai";
2
+ export interface OHTransportOptions {
3
+ headers?: Record<string, string>;
4
+ credentials?: RequestCredentials;
5
+ fetch?: typeof globalThis.fetch;
6
+ body?: Record<string, unknown>;
7
+ }
8
+ /**
9
+ * Create a pre-configured chat transport pointed at an OpenHarness SSE endpoint.
10
+ * Returns a `DefaultChatTransport` that parses the AI SDK 5 data stream protocol.
11
+ */
12
+ export declare function createOHTransport<UI_MESSAGE extends UIMessage = UIMessage>(endpoint: string, opts?: OHTransportOptions): ChatTransport<UI_MESSAGE>;
13
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,IAAI,CAAC;AAE9E,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,SAAS,SAAS,GAAG,SAAS,EACxE,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,kBAAkB,GACxB,aAAa,CAAC,UAAU,CAAC,CAQ3B"}
@@ -0,0 +1,15 @@
1
+ import { DefaultChatTransport } from "ai";
2
+ /**
3
+ * Create a pre-configured chat transport pointed at an OpenHarness SSE endpoint.
4
+ * Returns a `DefaultChatTransport` that parses the AI SDK 5 data stream protocol.
5
+ */
6
+ export function createOHTransport(endpoint, opts) {
7
+ return new DefaultChatTransport({
8
+ api: endpoint,
9
+ headers: opts?.headers,
10
+ credentials: opts?.credentials,
11
+ fetch: opts?.fetch,
12
+ body: opts?.body,
13
+ });
14
+ }
15
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAsC,MAAM,IAAI,CAAC;AAS9E;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAgB,EAChB,IAAyB;IAEzB,OAAO,IAAI,oBAAoB,CAAa;QAC1C,GAAG,EAAE,QAAQ;QACb,OAAO,EAAE,IAAI,EAAE,OAAO;QACtB,WAAW,EAAE,IAAI,EAAE,WAAW;QAC9B,KAAK,EAAE,IAAI,EAAE,KAAK;QAClB,IAAI,EAAE,IAAI,EAAE,IAAI;KACjB,CAAC,CAAC;AACL,CAAC"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@openharness/react",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "description": "React hooks and provider for OpenHarness AI SDK 5 integration",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ }
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "peerDependencies": {
16
+ "@ai-sdk/react": "^3.0.0",
17
+ "react": "^18.0.0 || ^19.0.0",
18
+ "@openharness/core": "0.3.0"
19
+ },
20
+ "devDependencies": {
21
+ "@ai-sdk/react": "^3.0.0",
22
+ "@testing-library/react": "^16.3.0",
23
+ "@types/react": "^19.0.0",
24
+ "ai": "^6.0.97",
25
+ "react": "^19.1.0",
26
+ "react-dom": "^19.1.0",
27
+ "typescript": "^5.9.3",
28
+ "@openharness/core": "0.3.0"
29
+ },
30
+ "license": "ISC",
31
+ "scripts": {
32
+ "build": "tsc",
33
+ "typecheck": "tsc --noEmit"
34
+ }
35
+ }