@opengeni/react 0.12.0 → 0.15.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 +20 -14
- package/dist/chunk-TOJR776I.js +2280 -0
- package/dist/chunk-TOJR776I.js.map +1 -0
- package/dist/index.d.ts +1040 -363
- package/dist/index.js +10938 -6281
- package/dist/index.js.map +1 -1
- package/dist/{machines-BeZ3bD3t.d.ts → machines-BpdwuQcD.d.ts} +134 -14
- package/dist/machines.d.ts +1 -1
- package/dist/machines.js +23 -1
- package/package.json +20 -12
- package/src/approvals.ts +16 -4
- package/src/client.ts +41 -5
- package/src/commands/index.ts +1 -7
- package/src/commands/registry.ts +46 -12
- package/src/components/chat-composer.tsx +417 -69
- package/src/components/code-editor.tsx +28 -36
- package/src/components/command-palette.tsx +26 -5
- package/src/components/desktop-viewer.tsx +29 -16
- package/src/components/diff-view.tsx +27 -189
- package/src/components/enrollment-consent.tsx +28 -10
- package/src/components/enrollment-device-flow.tsx +8 -5
- package/src/components/file-browser.tsx +190 -56
- package/src/components/fleet-tile.tsx +13 -4
- package/src/components/machine-card.tsx +93 -15
- package/src/components/machine-dock-bar.tsx +20 -8
- package/src/components/machine-health-pill.tsx +68 -0
- package/src/components/machine-metrics.tsx +28 -19
- package/src/components/machine-status-pill.tsx +26 -5
- 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 +21 -3
- package/src/components/markdown.tsx +39 -9
- package/src/components/message-timeline.tsx +633 -109
- package/src/components/pierre-diff.tsx +83 -15
- package/src/components/pierre-file.tsx +10 -9
- package/src/components/queue-surface.tsx +578 -0
- package/src/components/sandbox-files.tsx +193 -225
- package/src/components/sandbox-terminal.tsx +256 -88
- package/src/components/sandbox-workspace.tsx +957 -0
- package/src/components/session-status.tsx +22 -2
- package/src/components/workbench-changes.tsx +585 -0
- package/src/components/workspace-dock.tsx +213 -59
- package/src/hooks/internal.ts +5 -2
- package/src/hooks/use-available-models.ts +7 -2
- package/src/hooks/use-billing-usage.ts +4 -1
- package/src/hooks/use-codex-accounts.ts +74 -44
- package/src/hooks/use-composer.ts +414 -63
- package/src/hooks/use-environments.ts +92 -47
- package/src/hooks/use-file-attachments.ts +101 -55
- package/src/hooks/use-goal.ts +52 -16
- package/src/hooks/use-machine-chip.ts +134 -0
- package/src/hooks/use-machines.ts +34 -16
- package/src/hooks/use-packs.ts +24 -19
- package/src/hooks/use-relay-frame-stream.ts +5 -2
- package/src/hooks/use-rigs.ts +335 -0
- package/src/hooks/use-sandbox-files.ts +213 -39
- package/src/hooks/use-sandbox-git.ts +188 -11
- package/src/hooks/use-sandbox-terminal.ts +18 -14
- package/src/hooks/use-scheduled-tasks.ts +10 -2
- package/src/hooks/use-session-capabilities.ts +77 -20
- package/src/hooks/use-session-control.ts +50 -23
- package/src/hooks/use-session-events.ts +50 -21
- package/src/hooks/use-session-lineage.ts +128 -0
- package/src/hooks/use-session.ts +53 -30
- package/src/hooks/use-slash-commands.ts +6 -4
- package/src/hooks/use-turn-queue.ts +202 -147
- package/src/hooks/use-windowed-sections.ts +204 -0
- package/src/hooks/use-workspace-capture.ts +233 -0
- package/src/hooks/use-workspace-edit.ts +231 -0
- package/src/hooks/use-workspace-sessions.ts +48 -5
- package/src/hooks/use-workspaces.ts +18 -15
- package/src/index.ts +133 -23
- package/src/lib/format.ts +3 -3
- package/src/lib/xterm-renderer.ts +65 -0
- package/src/lib/xterm-theme.ts +224 -18
- package/src/machines.ts +29 -3
- package/src/provider.tsx +195 -6
- package/src/timeline/activity-rail.tsx +213 -54
- package/src/timeline/disclosure-context.tsx +12 -2
- package/src/timeline/index.ts +21 -2
- package/src/timeline/parsers.ts +87 -16
- package/src/timeline/projection.ts +412 -87
- package/src/timeline/shared.tsx +111 -24
- package/src/timeline/tool-diff.tsx +24 -20
- package/src/timeline/tool-renderers.tsx +98 -21
- package/src/timeline/turn-summary.tsx +76 -23
- package/src/timeline/types.ts +96 -12
- package/styles/index.css +22 -0
- package/styles/tokens.css +2 -2
- package/dist/chunk-5TIXRCSI.js +0 -1291
- package/dist/chunk-5TIXRCSI.js.map +0 -1
|
@@ -36,11 +36,26 @@ export type TurnSummaryProps = {
|
|
|
36
36
|
durationMs?: number | undefined;
|
|
37
37
|
/** Start expanded. */
|
|
38
38
|
defaultOpen?: boolean | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* A nested fold — a cluster or sub-turn INSIDE an already-expanded turn. It
|
|
41
|
+
* drops the bordered/filled chip and renders as a plain disclosure node on the
|
|
42
|
+
* parent's rail (chevron + glyph + facets), so expanding a turn reveals a thread
|
|
43
|
+
* of nodes, never a stack of boxes-in-boxes. The top-level fold stays a chip.
|
|
44
|
+
*/
|
|
45
|
+
bare?: boolean | undefined;
|
|
39
46
|
/** The rendered activity rail revealed on expand. */
|
|
40
47
|
children: React.ReactNode;
|
|
41
48
|
};
|
|
42
49
|
|
|
43
|
-
export function TurnSummary({
|
|
50
|
+
export function TurnSummary({
|
|
51
|
+
items,
|
|
52
|
+
outcome,
|
|
53
|
+
failureText,
|
|
54
|
+
durationMs,
|
|
55
|
+
defaultOpen,
|
|
56
|
+
bare,
|
|
57
|
+
children,
|
|
58
|
+
}: TurnSummaryProps) {
|
|
44
59
|
// An explicit `defaultOpen` always wins; otherwise an ancestor may seed it
|
|
45
60
|
// (screenshot instrumentation); otherwise the turn starts folded.
|
|
46
61
|
const forcedDefaultOpen = useForcedDefaultOpen();
|
|
@@ -49,34 +64,46 @@ export function TurnSummary({ items, outcome, failureText, durationMs, defaultOp
|
|
|
49
64
|
const facets = summarizeTurn(items, durationMs);
|
|
50
65
|
|
|
51
66
|
return (
|
|
52
|
-
<Collapsible.Root
|
|
67
|
+
<Collapsible.Root
|
|
68
|
+
open={open}
|
|
69
|
+
onOpenChange={setOpen}
|
|
70
|
+
className={enter && !bare ? "animate-og-enter" : undefined}
|
|
71
|
+
>
|
|
53
72
|
<Collapsible.Trigger
|
|
54
73
|
className={cn(
|
|
55
|
-
|
|
56
|
-
//
|
|
57
|
-
//
|
|
74
|
+
// Both the top-level turn fold and a nested cluster fold render as a
|
|
75
|
+
// FLAT rail row — chevron + glyph + facets on the page background, no
|
|
76
|
+
// border, no fill. Only a hover tint hints the row is expandable, so a
|
|
77
|
+
// collapsed turn never reads as a boxed card. The top-level row is a
|
|
78
|
+
// touch larger (base text, size-5 glyph, wider gap) so it still reads
|
|
79
|
+
// as a turn landmark above the nested cluster rows it groups.
|
|
80
|
+
"group flex w-full items-center rounded-og-sm text-left transition-colors",
|
|
81
|
+
// A folded turn is a touch target on coarse pointers: grow the row so it
|
|
82
|
+
// clears the 40px minimum without disturbing the calm desktop rhythm.
|
|
58
83
|
"pointer-coarse:py-2.5",
|
|
59
|
-
|
|
60
|
-
|
|
84
|
+
bare
|
|
85
|
+
? "gap-2 px-1.5 py-1.5 text-og-sm text-og-fg-muted"
|
|
86
|
+
: "-mx-2 gap-2.5 px-2 py-1.5 text-og-base text-og-fg-muted",
|
|
87
|
+
// A failed fold keeps its red accent (glyph + inline reason below) and a
|
|
88
|
+
// faint red hover wash so attention still lands there; every other
|
|
89
|
+
// outcome gets the neutral surface hover.
|
|
61
90
|
outcome === "failed"
|
|
62
|
-
? "
|
|
63
|
-
: "
|
|
91
|
+
? "hover:bg-og-status-failed/[0.06] hover:text-og-fg"
|
|
92
|
+
: "hover:bg-og-surface-1 hover:text-og-fg",
|
|
64
93
|
)}
|
|
65
94
|
>
|
|
66
95
|
{/* Disclosure grammar matches the rows: chevron leads (far left), then the
|
|
67
96
|
outcome glyph, then the facets — one expand affordance side everywhere. */}
|
|
68
97
|
<ChevronRightIcon className="size-3.5 shrink-0 text-og-fg-subtle transition-transform duration-150 group-data-[state=open]:rotate-90" />
|
|
69
|
-
{/*
|
|
70
|
-
(complete) run draws a bare muted check
|
|
71
|
-
|
|
98
|
+
{/* The outcome glyph carries the state by hue alone — no filled circle, no
|
|
99
|
+
card. A clean (complete) run draws a bare muted check; a failed one a
|
|
100
|
+
red triangle; a cancelled one a muted slash; a still-running cluster a
|
|
101
|
+
quiet pulse dot in the glyph's place so alignment holds. */}
|
|
72
102
|
<span
|
|
73
103
|
className={cn(
|
|
74
|
-
"inline-flex
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
: outcome === "cancelled"
|
|
78
|
-
? "bg-og-fg-subtle/15 text-og-fg-subtle"
|
|
79
|
-
: "text-og-fg-subtle",
|
|
104
|
+
"inline-flex shrink-0 items-center justify-center",
|
|
105
|
+
bare ? "size-3.5" : "size-5",
|
|
106
|
+
outcome === "failed" ? "text-og-status-failed" : "text-og-fg-subtle",
|
|
80
107
|
)}
|
|
81
108
|
>
|
|
82
109
|
{outcome === "failed" ? (
|
|
@@ -84,17 +111,19 @@ export function TurnSummary({ items, outcome, failureText, durationMs, defaultOp
|
|
|
84
111
|
) : outcome === "cancelled" ? (
|
|
85
112
|
<CircleSlashIcon className="size-3" />
|
|
86
113
|
) : outcome === "complete" ? (
|
|
87
|
-
<CheckIcon className="size-3.5" />
|
|
114
|
+
<CheckIcon className={bare ? "size-3" : "size-3.5"} />
|
|
88
115
|
) : (
|
|
89
116
|
<span className="size-1.5 animate-og-pulse rounded-full bg-og-fg-subtle" />
|
|
90
117
|
)}
|
|
91
118
|
</span>
|
|
92
|
-
<span className="min-w-0 flex-1 truncate text-og-fg-muted">
|
|
119
|
+
<span className={cn("min-w-0 flex-1 truncate", bare ? "text-og-sm" : "text-og-fg-muted")}>
|
|
93
120
|
{facets}
|
|
94
121
|
{outcome === "failed" && failureText ? (
|
|
95
122
|
<span className="text-og-status-failed"> · {failureText}</span>
|
|
96
123
|
) : null}
|
|
97
|
-
{outcome === "cancelled" ?
|
|
124
|
+
{outcome === "cancelled" ? (
|
|
125
|
+
<span className="text-og-fg-subtle"> · interrupted</span>
|
|
126
|
+
) : null}
|
|
98
127
|
</span>
|
|
99
128
|
{/* The disclosure hint. Calm at rest on fine pointers (revealed on hover
|
|
100
129
|
and keyboard focus), but always present on coarse pointers where there
|
|
@@ -113,7 +142,9 @@ export function TurnSummary({ items, outcome, failureText, durationMs, defaultOp
|
|
|
113
142
|
</span>
|
|
114
143
|
</Collapsible.Trigger>
|
|
115
144
|
<Collapsible.Content className="overflow-hidden data-[state=closed]:animate-og-collapse data-[state=open]:animate-og-expand">
|
|
116
|
-
|
|
145
|
+
{/* A nested node indents its revealed rows under the glyph (thread nesting
|
|
146
|
+
off the parent rail); the top-level turn body owns its own rail. */}
|
|
147
|
+
<div className={bare ? "pt-1 pl-5" : "pt-2"}>{children}</div>
|
|
117
148
|
</Collapsible.Content>
|
|
118
149
|
</Collapsible.Root>
|
|
119
150
|
);
|
|
@@ -124,7 +155,19 @@ function summarizeTurn(items: ActivityItem[], durationMs?: number): string {
|
|
|
124
155
|
let files = 0;
|
|
125
156
|
let commands = 0;
|
|
126
157
|
let screenshots = 0;
|
|
158
|
+
let memoriesSaved = 0;
|
|
159
|
+
let memoriesUpdated = 0;
|
|
127
160
|
for (const item of items) {
|
|
161
|
+
if (item.kind === "memory") {
|
|
162
|
+
// A memory write is a first-class facet — the "wrote 1 memory" signal the
|
|
163
|
+
// fold should make prominent — counted saved vs updated separately.
|
|
164
|
+
if (item.variant === "corrected") {
|
|
165
|
+
memoriesUpdated += 1;
|
|
166
|
+
} else {
|
|
167
|
+
memoriesSaved += 1;
|
|
168
|
+
}
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
128
171
|
if (item.kind !== "tool-call") {
|
|
129
172
|
continue;
|
|
130
173
|
}
|
|
@@ -133,7 +176,11 @@ function summarizeTurn(items: ActivityItem[], durationMs?: number): string {
|
|
|
133
176
|
files += applyPatchOps(item.raw).length;
|
|
134
177
|
} else if (item.name === "exec_command") {
|
|
135
178
|
commands += 1;
|
|
136
|
-
} else if (
|
|
179
|
+
} else if (
|
|
180
|
+
rawTypeOf(item) === "computer_call" ||
|
|
181
|
+
item.name === "computer_call" ||
|
|
182
|
+
item.name === "computer_screenshot"
|
|
183
|
+
) {
|
|
137
184
|
if (screenshotDataUrl(item.output) !== null) {
|
|
138
185
|
screenshots += 1;
|
|
139
186
|
}
|
|
@@ -149,6 +196,12 @@ function summarizeTurn(items: ActivityItem[], durationMs?: number): string {
|
|
|
149
196
|
if (screenshots) {
|
|
150
197
|
parts.push(`${screenshots} ${screenshots === 1 ? "screenshot" : "screenshots"}`);
|
|
151
198
|
}
|
|
199
|
+
if (memoriesSaved) {
|
|
200
|
+
parts.push(`${memoriesSaved} ${memoriesSaved === 1 ? "memory" : "memories"} saved`);
|
|
201
|
+
}
|
|
202
|
+
if (memoriesUpdated) {
|
|
203
|
+
parts.push(`${memoriesUpdated} ${memoriesUpdated === 1 ? "memory" : "memories"} updated`);
|
|
204
|
+
}
|
|
152
205
|
const duration = formatDurationFacet(durationMs);
|
|
153
206
|
if (duration) {
|
|
154
207
|
parts.push(duration);
|
package/src/timeline/types.ts
CHANGED
|
@@ -13,8 +13,6 @@ export type UserMessageItem = {
|
|
|
13
13
|
kind: "user-message";
|
|
14
14
|
id: string;
|
|
15
15
|
text: string;
|
|
16
|
-
/** Queued for a future turn whose start has not appeared in the event log. */
|
|
17
|
-
pending?: boolean;
|
|
18
16
|
/** Resources attached to this message (file uploads, repositories). */
|
|
19
17
|
resources: ResourceRef[];
|
|
20
18
|
/** Tools requested for the turn this message starts. */
|
|
@@ -71,20 +69,29 @@ export type WorkerItem = {
|
|
|
71
69
|
id: string;
|
|
72
70
|
turnId: string | null;
|
|
73
71
|
callId: string | null;
|
|
74
|
-
action: "spawn" | "message"
|
|
72
|
+
action: "spawn" | "message";
|
|
75
73
|
/** The worker's initial message / the message sent to it, when parseable. */
|
|
76
74
|
prompt: string | null;
|
|
77
75
|
/** The target/spawned worker session id, when parseable from args/output. */
|
|
78
76
|
workerSessionId: string | null;
|
|
79
|
-
/**
|
|
80
|
-
* For an `interrupt` action, whether it stops the target (default) or steers
|
|
81
|
-
* it (cancel the current turn, keep the goal). Absent on spawn/message.
|
|
82
|
-
*/
|
|
83
|
-
mode?: "stop" | "steer";
|
|
84
77
|
status: "running" | "complete" | "failed" | "cancelled";
|
|
85
78
|
occurredAt: string;
|
|
86
79
|
};
|
|
87
80
|
|
|
81
|
+
export type WorkerCompletionItem = {
|
|
82
|
+
kind: "worker-completion";
|
|
83
|
+
id: string;
|
|
84
|
+
turnId: string | null;
|
|
85
|
+
occurredAt: string;
|
|
86
|
+
childSessionId: string;
|
|
87
|
+
childStatus: string;
|
|
88
|
+
goalStatus: string | null;
|
|
89
|
+
goalText: string | null;
|
|
90
|
+
evidence: string | null;
|
|
91
|
+
pausedReason: string | null;
|
|
92
|
+
text: string;
|
|
93
|
+
};
|
|
94
|
+
|
|
88
95
|
export type SandboxItem = {
|
|
89
96
|
kind: "sandbox";
|
|
90
97
|
id: string;
|
|
@@ -92,10 +99,47 @@ export type SandboxItem = {
|
|
|
92
99
|
name: string;
|
|
93
100
|
command: string | null;
|
|
94
101
|
output: string;
|
|
102
|
+
origin?: "created" | "restored" | "resumed" | null;
|
|
95
103
|
status: "running" | "complete" | "failed" | "cancelled";
|
|
96
104
|
occurredAt: string;
|
|
97
105
|
};
|
|
98
106
|
|
|
107
|
+
/**
|
|
108
|
+
* A first-party workspace-memory write the agent made mid-turn — a `memory.saved`
|
|
109
|
+
* (it committed a new preference / fact / procedure / decision / history) or a
|
|
110
|
+
* `memory.corrected` (it updated or archived an existing one). A settled save is
|
|
111
|
+
* ordinary progress, not an exceptional state, so it renders as a calm NEUTRAL
|
|
112
|
+
* step on the rail (never accent/color). When the host app supplies an
|
|
113
|
+
* `onMemoryClick` handler the row also deep-links to the record in its memory
|
|
114
|
+
* pane; without one it is non-interactive rich content.
|
|
115
|
+
*/
|
|
116
|
+
export type MemoryItem = {
|
|
117
|
+
kind: "memory";
|
|
118
|
+
id: string;
|
|
119
|
+
turnId: string | null;
|
|
120
|
+
variant: "saved" | "corrected";
|
|
121
|
+
/** The memory's kind enum (`"preference" | "semantic" | …`); mapped to a human label at render. */
|
|
122
|
+
memoryKind: string;
|
|
123
|
+
/** The memory text, ellipsized to ≤120 chars server-side. For a supersede this is the OLD text. */
|
|
124
|
+
preview: string;
|
|
125
|
+
/** The save collapsed into an existing memory (no new row was written). Saved variant only. */
|
|
126
|
+
deduped?: boolean;
|
|
127
|
+
/** The NEW text when a correction superseded the memory with a replacement; absent = updated-in-place or archived. */
|
|
128
|
+
replacementPreview?: string;
|
|
129
|
+
/**
|
|
130
|
+
* What a `memory.corrected` did: `"superseded"` (replaced by a new record, see
|
|
131
|
+
* `replacementPreview`), `"updated"` (edited in place — the record lives on), or
|
|
132
|
+
* `"archived"` (retired). Distinguishes updated-in-place from archived when there
|
|
133
|
+
* is no replacement. Corrected variant only; read defensively (may be absent).
|
|
134
|
+
*/
|
|
135
|
+
action?: string;
|
|
136
|
+
/** The saved / corrected memory's id — the deep-link target for a save. */
|
|
137
|
+
memoryId: string;
|
|
138
|
+
/** The replacement memory's id when a correction produced one — the LIVE record the deep-link targets. */
|
|
139
|
+
replacementMemoryId?: string;
|
|
140
|
+
occurredAt: string;
|
|
141
|
+
};
|
|
142
|
+
|
|
99
143
|
export type SessionStatusItem = {
|
|
100
144
|
kind: "session-status";
|
|
101
145
|
id: string;
|
|
@@ -106,7 +150,7 @@ export type SessionStatusItem = {
|
|
|
106
150
|
export type GoalItem = {
|
|
107
151
|
kind: "goal";
|
|
108
152
|
id: string;
|
|
109
|
-
action: "set" | "updated" | "completed" | "paused" | "resumed" | "continuation";
|
|
153
|
+
action: "set" | "updated" | "completed" | "paused" | "resumed" | "cleared" | "continuation";
|
|
110
154
|
text: string | null;
|
|
111
155
|
occurredAt: string;
|
|
112
156
|
};
|
|
@@ -116,10 +160,41 @@ export type NoticeItem = {
|
|
|
116
160
|
id: string;
|
|
117
161
|
tone: "waiting" | "cancelled" | "failed";
|
|
118
162
|
text: string;
|
|
163
|
+
/** Optional evidence kept inspectable without overwhelming the main rail. */
|
|
164
|
+
details?: { label: string; value: unknown };
|
|
119
165
|
action?: { label: string; url: string };
|
|
120
166
|
occurredAt: string;
|
|
121
167
|
};
|
|
122
168
|
|
|
169
|
+
/**
|
|
170
|
+
* A tool call hit a connection whose credential lapsed — the broker asked the
|
|
171
|
+
* user to reconnect the provider before the turn can continue. Carries the
|
|
172
|
+
* structured `tool.auth_needed` payload so the renderer can draw a clean inline
|
|
173
|
+
* reconnect affordance (provider logo + one human line + a Reconnect button)
|
|
174
|
+
* and the app can start the right recovery flow (OAuth reconnect for the
|
|
175
|
+
* surviving connection, or credential re-entry for an api-key one). The `reason`
|
|
176
|
+
* shapes the human copy but is never shown raw.
|
|
177
|
+
*/
|
|
178
|
+
export type AuthNeededItem = {
|
|
179
|
+
kind: "auth-needed";
|
|
180
|
+
id: string;
|
|
181
|
+
turnId: string | null;
|
|
182
|
+
/** The connection's registrable domain, e.g. "linear.app". */
|
|
183
|
+
providerDomain: string;
|
|
184
|
+
/** The lapsed connection to reconnect, when the row survived. */
|
|
185
|
+
connectionId: string | null;
|
|
186
|
+
reason: "missing_connection" | "expired" | "insufficient_scope" | "refresh_failed" | null;
|
|
187
|
+
/** Scopes the provider now needs; may inform the copy, never shown as a raw label. */
|
|
188
|
+
scopes: string[];
|
|
189
|
+
/** The OAuth `resource` (RFC 8707) the reconnect should target, when supplied. */
|
|
190
|
+
resource: string | null;
|
|
191
|
+
/** The tool whose call triggered the reauth, for context. */
|
|
192
|
+
toolName: string | null;
|
|
193
|
+
/** A pre-minted authorization URL, when the broker already produced one. */
|
|
194
|
+
authorizationUrl: string | null;
|
|
195
|
+
occurredAt: string;
|
|
196
|
+
};
|
|
197
|
+
|
|
123
198
|
export type TurnOutcome = "complete" | "failed" | "cancelled";
|
|
124
199
|
|
|
125
200
|
export type TurnEndItem = {
|
|
@@ -137,18 +212,27 @@ export type TimelineItem =
|
|
|
137
212
|
| ReasoningItem
|
|
138
213
|
| ToolCallItem
|
|
139
214
|
| WorkerItem
|
|
215
|
+
| WorkerCompletionItem
|
|
140
216
|
| SandboxItem
|
|
141
217
|
| SessionStatusItem
|
|
142
218
|
| GoalItem
|
|
143
219
|
| NoticeItem
|
|
220
|
+
| AuthNeededItem
|
|
221
|
+
| MemoryItem
|
|
144
222
|
| TurnEndItem;
|
|
145
223
|
|
|
146
|
-
/** Activity items cluster between chat messages (reasoning, tools, workers, sandbox). */
|
|
147
|
-
export type ActivityItem = ReasoningItem | ToolCallItem | WorkerItem | SandboxItem;
|
|
224
|
+
/** Activity items cluster between chat messages (reasoning, tools, workers, sandbox, memory). */
|
|
225
|
+
export type ActivityItem = ReasoningItem | ToolCallItem | WorkerItem | SandboxItem | MemoryItem;
|
|
148
226
|
|
|
149
227
|
export type TimelineGroup =
|
|
150
228
|
| { kind: "item"; item: TimelineItem }
|
|
151
|
-
| {
|
|
229
|
+
| {
|
|
230
|
+
kind: "activity";
|
|
231
|
+
id: string;
|
|
232
|
+
items: ActivityItem[];
|
|
233
|
+
outcome?: TurnOutcome;
|
|
234
|
+
failureText?: string;
|
|
235
|
+
}
|
|
152
236
|
| {
|
|
153
237
|
kind: "turn";
|
|
154
238
|
id: string;
|
package/styles/index.css
CHANGED
|
@@ -165,6 +165,28 @@
|
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
/* Metric-history line draw-in. The chart path carries `pathLength={1}`, so the
|
|
169
|
+
dash math is resolution-independent: one full-length dash whose offset animates
|
|
170
|
+
from 1 (hidden) to 0 (drawn). Degrades to a solid line if animations are off. */
|
|
171
|
+
@keyframes og-mh-draw {
|
|
172
|
+
from {
|
|
173
|
+
stroke-dashoffset: 1;
|
|
174
|
+
}
|
|
175
|
+
to {
|
|
176
|
+
stroke-dashoffset: 0;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
.og-mh-draw {
|
|
180
|
+
stroke-dasharray: 1;
|
|
181
|
+
animation: og-mh-draw 900ms var(--og-ease-out) forwards;
|
|
182
|
+
}
|
|
183
|
+
@media (prefers-reduced-motion: reduce) {
|
|
184
|
+
.og-mh-draw {
|
|
185
|
+
animation: none;
|
|
186
|
+
stroke-dasharray: none;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
168
190
|
/* Shimmer helper: gradient text the keyframe scrolls through. */
|
|
169
191
|
.og-shimmer-text {
|
|
170
192
|
background: linear-gradient(
|
package/styles/tokens.css
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
--og-color-border-strong: oklch(0.42 0.016 260);
|
|
46
46
|
--og-color-fg: oklch(0.955 0.005 260);
|
|
47
47
|
--og-color-fg-muted: oklch(0.73 0.012 260);
|
|
48
|
-
--og-color-fg-subtle: oklch(0.
|
|
48
|
+
--og-color-fg-subtle: oklch(0.62 0.013 260);
|
|
49
49
|
|
|
50
50
|
/* Accent — one brand hue, used sparingly ----------------------------------- */
|
|
51
51
|
--og-color-accent: oklch(0.72 0.15 255);
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
--og-color-border-strong: oklch(0.8 0.01 260);
|
|
93
93
|
--og-color-fg: oklch(0.21 0.015 260);
|
|
94
94
|
--og-color-fg-muted: oklch(0.46 0.014 260);
|
|
95
|
-
--og-color-fg-subtle: oklch(0.
|
|
95
|
+
--og-color-fg-subtle: oklch(0.5 0.012 260);
|
|
96
96
|
|
|
97
97
|
--og-color-accent: oklch(0.55 0.18 255);
|
|
98
98
|
--og-color-accent-strong: oklch(0.48 0.19 255);
|