@opengeni/react 0.13.0 → 0.20.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/README.md +129 -23
- package/dist/chunk-6BXBGJ3B.js +1956 -0
- package/dist/chunk-6BXBGJ3B.js.map +1 -0
- package/dist/chunk-6UT5OC3P.js +2133 -0
- package/dist/chunk-6UT5OC3P.js.map +1 -0
- package/dist/chunk-EBTT3MYN.js +92 -0
- package/dist/chunk-EBTT3MYN.js.map +1 -0
- package/dist/chunk-HHFA4AFX.js +425 -0
- package/dist/chunk-HHFA4AFX.js.map +1 -0
- package/dist/chunk-LAZ2A743.js +2393 -0
- package/dist/chunk-LAZ2A743.js.map +1 -0
- package/dist/chunk-MRSECXRP.js +563 -0
- package/dist/chunk-MRSECXRP.js.map +1 -0
- package/dist/chunk-TK7G6XLT.js +18 -0
- package/dist/chunk-TK7G6XLT.js.map +1 -0
- package/dist/composer-DvUaa5ki.d.ts +585 -0
- package/dist/composer.d.ts +6 -0
- package/dist/composer.js +56 -0
- package/dist/composer.js.map +1 -0
- package/dist/index.d.ts +642 -1080
- package/dist/index.js +7672 -8005
- package/dist/index.js.map +1 -1
- package/dist/machines.d.ts +412 -3
- package/dist/machines.js +25 -1
- package/dist/noto-sans-arabic-loader-IA2T4X2A.js +21 -0
- package/dist/noto-sans-arabic-loader-IA2T4X2A.js.map +1 -0
- package/dist/noto-sans-jp-loader.generated-HFGLYBR3.js +292 -0
- package/dist/noto-sans-jp-loader.generated-HFGLYBR3.js.map +1 -0
- package/dist/queue-surface-implementation-NQMV2ML3.js +890 -0
- package/dist/queue-surface-implementation-NQMV2ML3.js.map +1 -0
- package/dist/session-Gd4iVPYw.d.ts +425 -0
- package/dist/session-context-DIFFlXKc.d.ts +52 -0
- package/dist/session.d.ts +4 -0
- package/dist/session.js +50 -0
- package/dist/session.js.map +1 -0
- package/dist/use-composer-BCfm4mzX.d.ts +112 -0
- package/package.json +23 -4
- package/src/approvals.ts +5 -3
- package/src/client.ts +50 -1
- package/src/components/approval-surface.tsx +198 -0
- package/src/components/chat-composer.tsx +104 -751
- package/src/components/code-editor.tsx +104 -26
- package/src/components/command-palette.tsx +8 -2
- package/src/components/composer-transcription-control.tsx +211 -0
- package/src/components/composer.tsx +1536 -0
- package/src/components/desktop-viewer.tsx +3 -3
- package/src/components/enrollment-consent.tsx +2 -2
- package/src/components/file-browser.tsx +367 -29
- package/src/components/human-input-form.tsx +417 -0
- package/src/components/machine-card.tsx +82 -16
- package/src/components/machine-health-pill.tsx +68 -0
- package/src/components/machine-metrics.tsx +10 -24
- package/src/components/machines/health.ts +146 -0
- package/src/components/machines/machine-detail.tsx +220 -0
- package/src/components/machines/metric-history-chart.tsx +298 -0
- package/src/components/machines/metric-sparkline.tsx +76 -0
- package/src/components/machines/series.ts +113 -0
- package/src/components/machines-dashboard.tsx +16 -4
- package/src/components/message-timeline.tsx +15 -7
- package/src/components/model-picker.tsx +12 -3
- package/src/components/pierre-diff.tsx +32 -6
- package/src/components/queue-surface-implementation.tsx +1041 -0
- package/src/components/queue-surface-state.tsx +94 -0
- package/src/components/queue-surface.tsx +60 -0
- package/src/components/sandbox-files.tsx +230 -21
- package/src/components/sandbox-terminal.tsx +8 -2
- package/src/components/sandbox-workspace.tsx +489 -135
- package/src/components/session-status.tsx +0 -6
- package/src/components/workbench-changes.tsx +145 -50
- package/src/components/workspace-dock.tsx +329 -68
- package/src/composer.ts +60 -0
- package/src/hooks/internal.ts +115 -34
- package/src/hooks/use-composer.ts +635 -74
- package/src/hooks/use-human-input.ts +131 -0
- package/src/hooks/use-machine-chip.ts +2 -2
- package/src/hooks/use-machines.ts +27 -11
- package/src/hooks/use-sandbox-files.ts +310 -62
- package/src/hooks/use-sandbox-git.ts +154 -40
- package/src/hooks/use-sandbox-terminal.ts +28 -6
- package/src/hooks/use-session-capabilities.ts +38 -9
- package/src/hooks/use-session-control.ts +43 -15
- package/src/hooks/use-session-events.ts +523 -48
- package/src/hooks/use-session-lineage.ts +15 -6
- package/src/hooks/use-session.ts +10 -2
- package/src/hooks/use-slash-commands.ts +38 -38
- package/src/hooks/use-transcription.ts +757 -0
- package/src/hooks/use-turn-queue.ts +273 -77
- package/src/hooks/use-windowed-sections.ts +2 -2
- package/src/hooks/use-workspace-capture.ts +146 -40
- package/src/hooks/use-workspace-edit.ts +50 -14
- package/src/hooks/use-workspace-sessions.ts +3 -0
- package/src/human-input.ts +72 -0
- package/src/index.ts +88 -12
- package/src/lib/noto-sans-arabic-loader.ts +21 -0
- package/src/lib/noto-sans-jp-loader.generated.ts +295 -0
- package/src/lib/use-portal-token-style.ts +51 -0
- package/src/lib/use-unicode-fonts.ts +57 -0
- package/src/machines.ts +16 -0
- package/src/provider.tsx +163 -41
- package/src/session-context.ts +135 -0
- package/src/session.ts +79 -0
- package/src/timeline/parsers.ts +78 -6
- package/src/timeline/projection.ts +36 -6
- package/src/timeline/tool-renderers.tsx +41 -0
- package/src/timeline/turn-summary.tsx +2 -2
- package/src/timeline/types.ts +16 -8
- package/styles/index.css +78 -0
- package/styles/index.d.ts +2 -0
- package/styles/tokens.css +11 -6
- package/styles/tokens.d.ts +2 -0
- package/dist/chunk-NFYVQWIB.js +0 -1377
- package/dist/chunk-NFYVQWIB.js.map +0 -1
- package/dist/machines-CnlMb7E-.d.ts +0 -329
|
@@ -57,7 +57,8 @@ export function useSessionLineage(
|
|
|
57
57
|
sessionId: string | null | undefined,
|
|
58
58
|
options: UseSessionLineageOptions = {},
|
|
59
59
|
): UseSessionLineageResult {
|
|
60
|
-
const { client, workspaceId } =
|
|
60
|
+
const { client, workspaceId, workspaceControlEvent, registerSessionReconciler } =
|
|
61
|
+
useOpenGeni(options);
|
|
61
62
|
const enabled = (options.enabled ?? true) && Boolean(sessionId);
|
|
62
63
|
const load = useCallback(
|
|
63
64
|
async () =>
|
|
@@ -67,7 +68,15 @@ export function useSessionLineage(
|
|
|
67
68
|
[client, workspaceId, sessionId],
|
|
68
69
|
);
|
|
69
70
|
const state = usePolledValue(load, { pollIntervalMs: options.pollIntervalMs, enabled });
|
|
70
|
-
const
|
|
71
|
+
const refresh = state.refresh;
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (enabled && workspaceControlEvent) void refresh();
|
|
74
|
+
}, [enabled, refresh, workspaceControlEvent]);
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (!sessionId || !enabled) return;
|
|
77
|
+
return registerSessionReconciler(sessionId, "lineage", refresh);
|
|
78
|
+
}, [enabled, refresh, registerSessionReconciler, sessionId]);
|
|
79
|
+
const refreshSoon = useDebouncedCallback(() => void refresh(), 150);
|
|
71
80
|
const delayedChildRefreshRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
72
81
|
// Clear a pending delayed refresh on session/workspace SWITCH (not just
|
|
73
82
|
// unmount): otherwise a timer scheduled for the previous session can fire
|
|
@@ -81,15 +90,15 @@ export function useSessionLineage(
|
|
|
81
90
|
};
|
|
82
91
|
}, [sessionId, workspaceId]);
|
|
83
92
|
const refreshAfterChildCreate = useCallback(() => {
|
|
84
|
-
void
|
|
93
|
+
void refresh();
|
|
85
94
|
if (delayedChildRefreshRef.current !== null) {
|
|
86
95
|
clearTimeout(delayedChildRefreshRef.current);
|
|
87
96
|
}
|
|
88
97
|
delayedChildRefreshRef.current = setTimeout(() => {
|
|
89
98
|
delayedChildRefreshRef.current = null;
|
|
90
|
-
void
|
|
99
|
+
void refresh();
|
|
91
100
|
}, 2500);
|
|
92
|
-
}, [
|
|
101
|
+
}, [refresh]);
|
|
93
102
|
useSessionEventTrigger(
|
|
94
103
|
client,
|
|
95
104
|
workspaceId,
|
|
@@ -114,6 +123,6 @@ export function useSessionLineage(
|
|
|
114
123
|
lineage: state.data,
|
|
115
124
|
loading: state.loading,
|
|
116
125
|
error: state.error,
|
|
117
|
-
refresh
|
|
126
|
+
refresh,
|
|
118
127
|
};
|
|
119
128
|
}
|
package/src/hooks/use-session.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Session, SessionEvent } from "@opengeni/sdk";
|
|
2
|
-
import { useCallback, useState } from "react";
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
3
|
import { useOpenGeni, type ClientOverride } from "../provider";
|
|
4
4
|
import {
|
|
5
5
|
useMutationRunner,
|
|
@@ -37,7 +37,8 @@ export function useSession(
|
|
|
37
37
|
sessionId: string | null | undefined,
|
|
38
38
|
options: UseSessionOptions = {},
|
|
39
39
|
): UseSessionResult {
|
|
40
|
-
const { client, workspaceId } =
|
|
40
|
+
const { client, workspaceId, workspaceControlEvent, registerSessionReconciler } =
|
|
41
|
+
useOpenGeni(options);
|
|
41
42
|
const enabled = (options.enabled ?? true) && Boolean(sessionId);
|
|
42
43
|
const [override, setOverride] = useState<Session | null>(null);
|
|
43
44
|
const { run, mutating, mutationError, clearMutationError } = useMutationRunner();
|
|
@@ -54,6 +55,13 @@ export function useSession(
|
|
|
54
55
|
pollIntervalMs: options.pollIntervalMs,
|
|
55
56
|
enabled,
|
|
56
57
|
});
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (enabled && workspaceControlEvent) void refresh();
|
|
60
|
+
}, [enabled, refresh, workspaceControlEvent]);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (!sessionId || !enabled) return;
|
|
63
|
+
return registerSessionReconciler(sessionId, "session", refresh);
|
|
64
|
+
}, [enabled, refresh, registerSessionReconciler, sessionId]);
|
|
57
65
|
|
|
58
66
|
const base = data ?? null;
|
|
59
67
|
// The override only ever carries title/titleSource patches; it is reset on
|
|
@@ -194,6 +194,10 @@ export function useSlashCommands(options: UseSlashCommandsOptions): UseSlashComm
|
|
|
194
194
|
}
|
|
195
195
|
}, [items, clampedHighlight, autocomplete]);
|
|
196
196
|
|
|
197
|
+
// Pointer and keyboard activation share this synchronous fence. React state
|
|
198
|
+
// cannot disable a command row before a second same-tick activation arrives.
|
|
199
|
+
const runningRef = useRef(false);
|
|
200
|
+
|
|
197
201
|
// Resolve a SPECIFIC, already-chosen command against the current draft, then
|
|
198
202
|
// either autocomplete (name-only / required arg missing) or execute. This is
|
|
199
203
|
// the shared core for both Enter (which first resolves WHICH command via the
|
|
@@ -201,39 +205,44 @@ export function useSlashCommands(options: UseSlashCommandsOptions): UseSlashComm
|
|
|
201
205
|
// command — the clicked row — and must not re-resolve to a near-match).
|
|
202
206
|
const runResolved = useCallback(
|
|
203
207
|
async (command: SlashCommand, executionOptions?: { explicit?: boolean }): Promise<void> => {
|
|
204
|
-
if (!parsed) {
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
const explicit = executionOptions?.explicit ?? false;
|
|
208
|
-
// Token-vs-command equality is case-insensitive (matching the registry's
|
|
209
|
-
// matchCommand/filterCommands), so a fully-typed "/Clear" counts as having
|
|
210
|
-
// named `clear` and runs rather than autocompleting.
|
|
211
|
-
const nameMatchesToken =
|
|
212
|
-
command.name === parsed.name.toLowerCase() ||
|
|
213
|
-
(command.aliases?.includes(parsed.name.toLowerCase()) ?? false);
|
|
214
|
-
// A name-only token whose name doesn't yet equal the resolved command (e.g.
|
|
215
|
-
// "/cl" -> clear) first autocompletes so the operator sees the full name.
|
|
216
|
-
// An EXPLICIT pointer click skips this: the operator already chose the row,
|
|
217
|
-
// so clicking "/clear-view" (while the token is "clear") runs it outright
|
|
218
|
-
// rather than merely filling the name and waiting for a second Enter.
|
|
219
|
-
if (!explicit && !activeCommand && !nameMatchesToken && !parsed.hasTrailingSpace) {
|
|
220
|
-
autocomplete(command);
|
|
208
|
+
if (!parsed || runningRef.current) {
|
|
221
209
|
return;
|
|
222
210
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
211
|
+
runningRef.current = true;
|
|
212
|
+
try {
|
|
213
|
+
const explicit = executionOptions?.explicit ?? false;
|
|
214
|
+
// Token-vs-command equality is case-insensitive (matching the registry's
|
|
215
|
+
// matchCommand/filterCommands), so a fully-typed "/Clear" counts as having
|
|
216
|
+
// named `clear` and runs rather than autocompleting.
|
|
217
|
+
const nameMatchesToken =
|
|
218
|
+
command.name === parsed.name.toLowerCase() ||
|
|
219
|
+
(command.aliases?.includes(parsed.name.toLowerCase()) ?? false);
|
|
220
|
+
// A name-only token whose name doesn't yet equal the resolved command (e.g.
|
|
221
|
+
// "/cl" -> clear) first autocompletes so the operator sees the full name.
|
|
222
|
+
// An EXPLICIT pointer click skips this: the operator already chose the row,
|
|
223
|
+
// so clicking "/clear-view" (while the token is "clear") runs it outright
|
|
224
|
+
// rather than merely filling the name and waiting for a second Enter.
|
|
225
|
+
if (!explicit && !activeCommand && !nameMatchesToken && !parsed.hasTrailingSpace) {
|
|
232
226
|
autocomplete(command);
|
|
227
|
+
return;
|
|
233
228
|
}
|
|
234
|
-
|
|
229
|
+
// When the click resolves a different command than the typed token, the
|
|
230
|
+
// typed token's tail isn't this command's args — run with no positional
|
|
231
|
+
// args and let the required-arg guard below prompt for them via autocomplete.
|
|
232
|
+
const args = nameMatchesToken || parsed.hasTrailingSpace ? parsed.args : [];
|
|
233
|
+
const missing = firstMissingRequiredArg(command, args);
|
|
234
|
+
if (missing) {
|
|
235
|
+
// A required arg is absent: keep the palette open at the arg hint rather
|
|
236
|
+
// than firing a half-formed command.
|
|
237
|
+
if (!parsed.hasTrailingSpace) {
|
|
238
|
+
autocomplete(command);
|
|
239
|
+
}
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
await execute(command, args);
|
|
243
|
+
} finally {
|
|
244
|
+
runningRef.current = false;
|
|
235
245
|
}
|
|
236
|
-
await execute(command, args);
|
|
237
246
|
},
|
|
238
247
|
[parsed, activeCommand, autocomplete, execute],
|
|
239
248
|
);
|
|
@@ -286,9 +295,6 @@ export function useSlashCommands(options: UseSlashCommandsOptions): UseSlashComm
|
|
|
286
295
|
[items, runResolved],
|
|
287
296
|
);
|
|
288
297
|
|
|
289
|
-
// Track an in-flight run so Enter can't double-fire.
|
|
290
|
-
const runningRef = useRef(false);
|
|
291
|
-
|
|
292
298
|
const onKeyDown = useCallback(
|
|
293
299
|
(event: KeyboardEvent<HTMLTextAreaElement>): boolean => {
|
|
294
300
|
if (!open) {
|
|
@@ -322,13 +328,7 @@ export function useSlashCommands(options: UseSlashCommandsOptions): UseSlashComm
|
|
|
322
328
|
return false;
|
|
323
329
|
}
|
|
324
330
|
event.preventDefault();
|
|
325
|
-
|
|
326
|
-
return true;
|
|
327
|
-
}
|
|
328
|
-
runningRef.current = true;
|
|
329
|
-
void runHighlighted().finally(() => {
|
|
330
|
-
runningRef.current = false;
|
|
331
|
-
});
|
|
331
|
+
void runHighlighted();
|
|
332
332
|
return true;
|
|
333
333
|
}
|
|
334
334
|
case "Escape": {
|