@opengeni/react 0.15.0 → 0.23.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 (103) hide show
  1. package/README.md +110 -10
  2. package/dist/{chunk-TOJR776I.js → chunk-6XUS5VFM.js} +45 -369
  3. package/dist/chunk-6XUS5VFM.js.map +1 -0
  4. package/dist/chunk-CATATY77.js +2393 -0
  5. package/dist/chunk-CATATY77.js.map +1 -0
  6. package/dist/chunk-I3BJZIG5.js +439 -0
  7. package/dist/chunk-I3BJZIG5.js.map +1 -0
  8. package/dist/chunk-TK7G6XLT.js +18 -0
  9. package/dist/chunk-TK7G6XLT.js.map +1 -0
  10. package/dist/chunk-UAHPKLB6.js +2237 -0
  11. package/dist/chunk-UAHPKLB6.js.map +1 -0
  12. package/dist/chunk-UQS7OQDE.js +591 -0
  13. package/dist/chunk-UQS7OQDE.js.map +1 -0
  14. package/dist/chunk-YDNWMKXO.js +102 -0
  15. package/dist/chunk-YDNWMKXO.js.map +1 -0
  16. package/dist/composer-CVm5uoUI.d.ts +585 -0
  17. package/dist/composer.d.ts +6 -0
  18. package/dist/composer.js +56 -0
  19. package/dist/composer.js.map +1 -0
  20. package/dist/index.d.ts +1288 -1785
  21. package/dist/index.js +7140 -8817
  22. package/dist/index.js.map +1 -1
  23. package/dist/machines.d.ts +412 -3
  24. package/dist/machines.js +3 -1
  25. package/dist/noto-sans-arabic-loader-IA2T4X2A.js +21 -0
  26. package/dist/noto-sans-arabic-loader-IA2T4X2A.js.map +1 -0
  27. package/dist/noto-sans-jp-loader.generated-HFGLYBR3.js +292 -0
  28. package/dist/noto-sans-jp-loader.generated-HFGLYBR3.js.map +1 -0
  29. package/dist/queue-surface-implementation-3UW3MIIR.js +890 -0
  30. package/dist/queue-surface-implementation-3UW3MIIR.js.map +1 -0
  31. package/dist/session-Db00TRwl.d.ts +446 -0
  32. package/dist/session-context-rgrfElMl.d.ts +58 -0
  33. package/dist/session.d.ts +4 -0
  34. package/dist/session.js +54 -0
  35. package/dist/session.js.map +1 -0
  36. package/dist/use-composer-By1wn3MM.d.ts +99 -0
  37. package/package.json +20 -4
  38. package/src/approvals.ts +5 -3
  39. package/src/client.ts +44 -0
  40. package/src/components/approval-surface.tsx +198 -0
  41. package/src/components/chat-composer.tsx +94 -993
  42. package/src/components/code-editor.tsx +104 -26
  43. package/src/components/command-palette.tsx +8 -2
  44. package/src/components/composer-transcription-control.tsx +211 -0
  45. package/src/components/composer.tsx +1536 -0
  46. package/src/components/desktop-viewer.tsx +3 -3
  47. package/src/components/enrollment-consent.tsx +2 -2
  48. package/src/components/file-browser.tsx +367 -29
  49. package/src/components/human-input-form.tsx +417 -0
  50. package/src/components/machine-card.tsx +1 -1
  51. package/src/components/machines-dashboard.tsx +3 -3
  52. package/src/components/message-timeline.tsx +205 -25
  53. package/src/components/model-picker.tsx +12 -3
  54. package/src/components/pierre-diff.tsx +32 -6
  55. package/src/components/queue-draft-policy.ts +18 -0
  56. package/src/components/queue-surface-implementation.tsx +1037 -0
  57. package/src/components/queue-surface-state.tsx +94 -0
  58. package/src/components/queue-surface.tsx +42 -559
  59. package/src/components/sandbox-files.tsx +138 -14
  60. package/src/components/sandbox-terminal.tsx +8 -2
  61. package/src/components/sandbox-workspace.tsx +339 -119
  62. package/src/components/workbench-changes.tsx +84 -33
  63. package/src/components/workspace-dock.tsx +188 -18
  64. package/src/composer.ts +60 -0
  65. package/src/hooks/internal.ts +115 -34
  66. package/src/hooks/use-composer.ts +385 -104
  67. package/src/hooks/use-human-input.ts +131 -0
  68. package/src/hooks/use-machine-chip.ts +2 -2
  69. package/src/hooks/use-machines.ts +27 -11
  70. package/src/hooks/use-sandbox-files.ts +310 -62
  71. package/src/hooks/use-sandbox-git.ts +154 -40
  72. package/src/hooks/use-sandbox-terminal.ts +28 -6
  73. package/src/hooks/use-session-capabilities.ts +38 -9
  74. package/src/hooks/use-session-control.ts +37 -8
  75. package/src/hooks/use-session-events.ts +522 -48
  76. package/src/hooks/use-session-mcp-approval-policy.ts +161 -0
  77. package/src/hooks/use-slash-commands.ts +38 -38
  78. package/src/hooks/use-transcription.ts +757 -0
  79. package/src/hooks/use-turn-queue.ts +134 -66
  80. package/src/hooks/use-windowed-sections.ts +2 -2
  81. package/src/hooks/use-workspace-capture.ts +146 -40
  82. package/src/hooks/use-workspace-edit.ts +50 -14
  83. package/src/hooks/use-workspace-sessions.ts +3 -0
  84. package/src/human-input.ts +72 -0
  85. package/src/index.ts +85 -6
  86. package/src/lib/noto-sans-arabic-loader.ts +21 -0
  87. package/src/lib/noto-sans-jp-loader.generated.ts +295 -0
  88. package/src/lib/use-portal-token-style.ts +51 -0
  89. package/src/lib/use-unicode-fonts.ts +57 -0
  90. package/src/provider.tsx +4 -69
  91. package/src/session-context.ts +160 -0
  92. package/src/session.ts +89 -0
  93. package/src/timeline/parsers.ts +35 -0
  94. package/src/timeline/projection.ts +12 -4
  95. package/src/timeline/tool-renderers.tsx +41 -0
  96. package/src/timeline/turn-summary.tsx +2 -2
  97. package/src/timeline/types.ts +10 -9
  98. package/styles/index.css +56 -0
  99. package/styles/index.d.ts +2 -0
  100. package/styles/tokens.css +11 -6
  101. package/styles/tokens.d.ts +2 -0
  102. package/dist/chunk-TOJR776I.js.map +0 -1
  103. package/dist/machines-BpdwuQcD.d.ts +0 -449
package/src/session.ts ADDED
@@ -0,0 +1,89 @@
1
+ // @opengeni/react/session — session state and pure timeline projection.
2
+ //
3
+ // This entry deliberately excludes styled components, workbench surfaces, CSS,
4
+ // and their optional peers. Hosts keep OpenGeni's session semantics while
5
+ // rendering their own product UI.
6
+
7
+ export type {
8
+ EmbeddedHumanInputSessionClientLike as HumanInputSessionClientLike,
9
+ EmbeddedSessionMcpApprovalPolicyClientLike as SessionMcpApprovalPolicyClientLike,
10
+ EmbeddedSessionClientLike as SessionClientLike,
11
+ } from "./client";
12
+ export type {
13
+ EmbeddedHumanInputClientOverride as HumanInputClientOverride,
14
+ EmbeddedSessionMcpApprovalPolicyClientOverride as SessionMcpApprovalPolicyClientOverride,
15
+ EmbeddedSessionClientOverride as ClientOverride,
16
+ } from "./session-context";
17
+
18
+ export { useSessionEvents } from "./hooks/use-session-events";
19
+ export type {
20
+ SessionEventsConnectionState,
21
+ UseSessionEventsOptions,
22
+ UseSessionEventsResult,
23
+ } from "./hooks/use-session-events";
24
+ export {
25
+ useComposer,
26
+ composeSendInput,
27
+ shouldSteerOnKey,
28
+ shouldSubmitOnKey,
29
+ FILE_ONLY_MESSAGE_TEXT,
30
+ } from "./hooks/use-composer";
31
+ export type { ComposerSendExtras, ComposerState, UseComposerOptions } from "./hooks/use-composer";
32
+ export { useTurnQueue, isTurnQueueEvent } from "./hooks/use-turn-queue";
33
+ export type {
34
+ QueueMutationKind,
35
+ UseTurnQueueOptions,
36
+ UseTurnQueueResult,
37
+ } from "./hooks/use-turn-queue";
38
+ export { useSessionControl } from "./hooks/use-session-control";
39
+ export type {
40
+ UseSessionControlOptions,
41
+ UseSessionControlResult,
42
+ } from "./hooks/use-session-control";
43
+ export {
44
+ isSessionMcpApprovalPolicyEvent,
45
+ useSessionMcpApprovalPolicy,
46
+ } from "./hooks/use-session-mcp-approval-policy";
47
+ export type {
48
+ UseSessionMcpApprovalPolicyOptions,
49
+ UseSessionMcpApprovalPolicyResult,
50
+ } from "./hooks/use-session-mcp-approval-policy";
51
+
52
+ export { approvalsFromRequiresAction, projectPendingApprovals } from "./approvals";
53
+ export type { PendingApproval } from "./approvals";
54
+
55
+ export { humanInputRequestFromEvent, projectPendingHumanInputRequests } from "./human-input";
56
+ export type { PendingHumanInputRequest } from "./human-input";
57
+ export { isHumanInputEvent, useHumanInputRequests } from "./hooks/use-human-input";
58
+ export type {
59
+ UseHumanInputRequestsOptions,
60
+ UseHumanInputRequestsResult,
61
+ } from "./hooks/use-human-input";
62
+
63
+ export {
64
+ buildTimeline,
65
+ creditExhaustedFromEvents,
66
+ extractSessionRef,
67
+ groupTimeline,
68
+ sessionStatusFromEvents,
69
+ toolDisplayName,
70
+ } from "./timeline/projection";
71
+ export type {
72
+ ActivityItem,
73
+ AgentMessageItem,
74
+ AuthNeededItem,
75
+ GoalItem,
76
+ MemoryItem,
77
+ NoticeItem,
78
+ ReasoningItem,
79
+ SandboxItem,
80
+ SessionStatusItem,
81
+ TimelineGroup,
82
+ TimelineItem,
83
+ TurnOutcome,
84
+ ToolCallItem,
85
+ TurnEndItem,
86
+ UserMessageItem,
87
+ WorkerCompletionItem,
88
+ WorkerItem,
89
+ } from "./timeline/types";
@@ -387,6 +387,41 @@ export function screenshotDataUrl(out: unknown): string | null {
387
387
  return null;
388
388
  }
389
389
 
390
+ export type TimelineMediaPreview = {
391
+ type: "media_preview";
392
+ mediaType: string;
393
+ inlineBytes: number | null;
394
+ fullOutputAvailable: false;
395
+ preview: string;
396
+ };
397
+
398
+ /** Find the explicit non-retained inline-media fact in a tool output. */
399
+ export function mediaPreviewFact(out: unknown): TimelineMediaPreview | null {
400
+ if (typeof out === "string" && (out.startsWith("{") || out.startsWith("["))) {
401
+ const parsed = tryParseJson(out);
402
+ if (parsed !== undefined && parsed !== out) return mediaPreviewFact(parsed);
403
+ }
404
+ if (Array.isArray(out)) {
405
+ for (const entry of out) {
406
+ const preview = mediaPreviewFact(entry);
407
+ if (preview) return preview;
408
+ }
409
+ return null;
410
+ }
411
+ if (!out || typeof out !== "object") return null;
412
+ const record = out as Record<string, unknown>;
413
+ if (
414
+ record.type !== "media_preview" ||
415
+ typeof record.mediaType !== "string" ||
416
+ record.fullOutputAvailable !== false ||
417
+ typeof record.preview !== "string" ||
418
+ (record.inlineBytes !== null && typeof record.inlineBytes !== "number")
419
+ ) {
420
+ return null;
421
+ }
422
+ return record as TimelineMediaPreview;
423
+ }
424
+
390
425
  /** Serialize whatever a Uint8Array became in JSON (number[], {"0":n,…} index
391
426
  * map, or Buffer-JSON {type:"Buffer",data:[…]}) back into base64. */
392
427
  function bytesToBase64(data: unknown): string | null {
@@ -393,7 +393,7 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
393
393
  tone: "waiting",
394
394
  text:
395
395
  before && after
396
- ? `Context compacted from approximately ${before} to ${after} tokens.`
396
+ ? `Active conversation history compacted from approximately ${before} to ${after} tokens.`
397
397
  : "Context compacted so the turn could continue.",
398
398
  occurredAt: event.occurredAt,
399
399
  });
@@ -406,13 +406,17 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
406
406
  items.push({
407
407
  kind: "notice",
408
408
  id: event.id,
409
- tone: "waiting",
409
+ tone: reason === "summarization_failed" ? "failed" : "waiting",
410
410
  text:
411
411
  reason === "no_history"
412
412
  ? "Context compaction skipped because there is no active history to compact."
413
413
  : reason === "replacement_not_smaller"
414
414
  ? "Context compaction skipped because the generated checkpoint would not reduce the context."
415
- : "Context compaction was not needed.",
415
+ : reason === "replacement_unchanged"
416
+ ? "Context compaction stopped because it reproduced the same checkpoint without making progress."
417
+ : reason === "summarization_failed"
418
+ ? "Context compaction failed without replacing the active conversation history. Request it again to retry."
419
+ : "Context compaction was not needed.",
416
420
  occurredAt: event.occurredAt,
417
421
  });
418
422
  break;
@@ -432,7 +436,8 @@ export function buildTimeline(events: SessionEvent[]): TimelineItem[] {
432
436
  break;
433
437
  }
434
438
 
435
- case "tool.auth_needed": {
439
+ case "tool.auth_needed":
440
+ case "credential.auth_needed": {
436
441
  // Keep the whole structured payload — the renderer turns it into a clean
437
442
  // inline reconnect card, and the app starts the recovery flow off the
438
443
  // connectionId/resource. Losing it to a plain-text notice was the ugly
@@ -814,6 +819,7 @@ function isTurnExecutionEvidence(type: string): boolean {
814
819
  type === "turn.capacity_waiting" ||
815
820
  type === "session.requiresAction" ||
816
821
  type === "tool.auth_needed" ||
822
+ type === "credential.auth_needed" ||
817
823
  type.startsWith("rig.setup.") ||
818
824
  type === "codex.capacity.waiting" ||
819
825
  type === "codex.capacity.resumed"
@@ -1193,6 +1199,8 @@ const AUTH_NEEDED_REASONS: ReadonlySet<string> = new Set([
1193
1199
  "expired",
1194
1200
  "insufficient_scope",
1195
1201
  "refresh_failed",
1202
+ "unsupported_auth",
1203
+ "resource_scope_unavailable",
1196
1204
  ]);
1197
1205
 
1198
1206
  function authNeededReason(value: unknown): AuthNeededItem["reason"] {
@@ -22,6 +22,7 @@ import {
22
22
  execTruncated,
23
23
  isExecSessionLostBanner,
24
24
  looksBinary,
25
+ mediaPreviewFact,
25
26
  parseExecBannerSessionId,
26
27
  parseToolArgs,
27
28
  redactSecrets,
@@ -555,6 +556,7 @@ function ComputerCallRenderer({ item }: ToolRendererProps) {
555
556
  const rejected = raw.providerData?.approvalStatus === "rejected";
556
557
  const readOnly = typeof out === "string" && out.includes("read-only");
557
558
  const shotUrl = screenshotDataUrl(out);
559
+ const omittedMedia = mediaPreviewFact(out);
558
560
  const empty = out === "" || out == null;
559
561
  const batched = actions.length > 1 ? actions.map((a) => computerVerb(a)).join(" · ") : null;
560
562
  // Fold the batched-action count into the title (one media affordance per row),
@@ -635,6 +637,26 @@ function ComputerCallRenderer({ item }: ToolRendererProps) {
635
637
  );
636
638
  }
637
639
 
640
+ if (omittedMedia) {
641
+ return (
642
+ <ActivityDisclosure
643
+ icon={<CameraOffIcon className={ICON_SIZE} />}
644
+ iconTone={isFailed ? "failed" : "muted"}
645
+ title={`${verb}${countSuffix} · image omitted · not retained`}
646
+ failed={isFailed}
647
+ cancelled={isCancelled}
648
+ preview="inline image omitted · not retained"
649
+ media={<MediaEmpty />}
650
+ >
651
+ <BodyNote>
652
+ The inline {omittedMedia.mediaType} output was omitted from the audit timeline and its
653
+ source bytes were not retained.
654
+ </BodyNote>
655
+ {batched ? <BodyNote>batched: {batched}</BodyNote> : null}
656
+ </ActivityDisclosure>
657
+ );
658
+ }
659
+
638
660
  if (empty) {
639
661
  return (
640
662
  <ActivityDisclosure
@@ -759,6 +781,7 @@ function ViewImageRenderer({ item }: ToolRendererProps) {
759
781
  const path = typeof args.path === "string" ? args.path : "";
760
782
  const out = item.output;
761
783
  const text = typeof out === "string" ? out : "";
784
+ const omittedMedia = mediaPreviewFact(out);
762
785
 
763
786
  if (item.status === "running") {
764
787
  return (
@@ -807,6 +830,24 @@ function ViewImageRenderer({ item }: ToolRendererProps) {
807
830
  </ActivityDisclosure>
808
831
  );
809
832
  }
833
+ if (omittedMedia) {
834
+ return (
835
+ <ActivityDisclosure
836
+ icon={<ImageIcon className={ICON_SIZE} />}
837
+ iconTone={viewFailed ? "failed" : "muted"}
838
+ title={`Viewed ${basename(path)} · image omitted · not retained`}
839
+ failed={viewFailed}
840
+ cancelled={viewCancelled}
841
+ preview="inline image omitted · not retained"
842
+ media={<MediaEmpty />}
843
+ >
844
+ <BodyNote>
845
+ The inline {omittedMedia.mediaType} output was omitted from the audit timeline and its
846
+ source bytes were not retained.
847
+ </BodyNote>
848
+ </ActivityDisclosure>
849
+ );
850
+ }
810
851
  if (text.includes("No image data")) {
811
852
  return (
812
853
  <ActivityDisclosure
@@ -4,7 +4,7 @@ import { Collapsible } from "radix-ui";
4
4
  import { cn } from "../lib/cn";
5
5
  import { useForcedDefaultOpen } from "./disclosure-context";
6
6
  import { useEntranceAnimation } from "./entrance";
7
- import { applyPatchOps, isApplyPatch, screenshotDataUrl } from "./parsers";
7
+ import { applyPatchOps, isApplyPatch, mediaPreviewFact, screenshotDataUrl } from "./parsers";
8
8
  import { rawTypeOf } from "./registry";
9
9
  import type { ActivityItem, TurnOutcome } from "./types";
10
10
  export type { TurnOutcome } from "./types";
@@ -181,7 +181,7 @@ function summarizeTurn(items: ActivityItem[], durationMs?: number): string {
181
181
  item.name === "computer_call" ||
182
182
  item.name === "computer_screenshot"
183
183
  ) {
184
- if (screenshotDataUrl(item.output) !== null) {
184
+ if (screenshotDataUrl(item.output) !== null || mediaPreviewFact(item.output) !== null) {
185
185
  screenshots += 1;
186
186
  }
187
187
  }
@@ -1,4 +1,4 @@
1
- import type { ResourceRef, SessionStatus, ToolRef } from "@opengeni/sdk";
1
+ import type { ResourceRef, SessionStatus, ToolAuthNeededPayload, ToolRef } from "@opengeni/sdk";
2
2
 
3
3
  /* ----------------------------------------------------------------------------
4
4
  Timeline item types
@@ -167,13 +167,14 @@ export type NoticeItem = {
167
167
  };
168
168
 
169
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.
170
+ * A tool call hit a missing or lapsed connection. The broker reports that
171
+ * condition as a tool error and the turn continues; reconnecting never resumes
172
+ * or replays the original call. Carries the structured `tool.auth_needed`
173
+ * payload so the renderer can draw a clean inline recovery affordance (provider
174
+ * logo + one human line + a Connect/Reconnect button) and the app can start the
175
+ * right flow (OAuth reconnect for the surviving connection, or credential
176
+ * re-entry for an api-key one). The `reason` shapes the human copy but is never
177
+ * shown raw.
177
178
  */
178
179
  export type AuthNeededItem = {
179
180
  kind: "auth-needed";
@@ -183,7 +184,7 @@ export type AuthNeededItem = {
183
184
  providerDomain: string;
184
185
  /** The lapsed connection to reconnect, when the row survived. */
185
186
  connectionId: string | null;
186
- reason: "missing_connection" | "expired" | "insufficient_scope" | "refresh_failed" | null;
187
+ reason: ToolAuthNeededPayload["reason"] | null;
187
188
  /** Scopes the provider now needs; may inform the copy, never shown as a raw label. */
188
189
  scopes: string[];
189
190
  /** The OAuth `resource` (RFC 8707) the reconnect should target, when supplied. */
package/styles/index.css CHANGED
@@ -216,6 +216,17 @@
216
216
  scrollbar-color: var(--og-color-border-strong) transparent;
217
217
  }
218
218
 
219
+ /* The machine popover stays mounted so its trigger's `aria-controls` always
220
+ resolves. Keep Radix's positioning wrapper measurable while closed, but
221
+ remove the entire fixed layer from painting, hit testing, and the a11y tree.
222
+ Hiding only the content leaves the wrapper able to intercept pointer input. */
223
+ [data-radix-popper-content-wrapper]:has(
224
+ > [data-machine-state-popover][data-state="closed"]
225
+ ) {
226
+ visibility: hidden;
227
+ pointer-events: none;
228
+ }
229
+
219
230
  @media (prefers-reduced-motion: reduce) {
220
231
  .og-root *,
221
232
  .og-root *::before,
@@ -228,6 +239,51 @@
228
239
  }
229
240
  }
230
241
 
242
+ @media (forced-colors: active) {
243
+ /* Forced-colors can replace a painted background with Canvas while custom
244
+ properties retain their authored dark/light values. That combination is
245
+ dangerous: descendants may resolve a pale dark-theme foreground against a
246
+ light system canvas. Collapse the whole component palette onto guaranteed
247
+ system colors. Meaning in status/diff UI is also carried by text, icons,
248
+ and +/- markers, so it never depends on these colors alone. */
249
+ .og-root {
250
+ --og-color-bg: Canvas;
251
+ --og-color-surface-1: Canvas;
252
+ --og-color-surface-2: Canvas;
253
+ --og-color-surface-3: Canvas;
254
+ --og-color-border: CanvasText;
255
+ --og-color-border-strong: CanvasText;
256
+ --og-color-fg: CanvasText;
257
+ --og-color-fg-muted: CanvasText;
258
+ --og-color-fg-subtle: CanvasText;
259
+ --og-color-accent: CanvasText;
260
+ --og-color-accent-strong: CanvasText;
261
+ --og-color-accent-deep: CanvasText;
262
+ --og-color-accent-fg: CanvasText;
263
+ --og-color-accent-soft: Canvas;
264
+ --og-color-status-queued: CanvasText;
265
+ --og-color-status-running: CanvasText;
266
+ --og-color-status-idle: CanvasText;
267
+ --og-color-status-waiting: CanvasText;
268
+ --og-color-status-failed: CanvasText;
269
+ --og-color-status-cancelled: CanvasText;
270
+ --og-color-danger: CanvasText;
271
+ --og-color-diff-add-bg: Canvas;
272
+ --og-color-diff-del-bg: Canvas;
273
+ --og-shadow-sm: none;
274
+ --og-shadow-md: none;
275
+ --og-shadow-lg: none;
276
+ --og-shadow-glow: none;
277
+ }
278
+
279
+ /* Selected fills are flattened by the OS palette. Preserve a visible,
280
+ non-color-only tab selection affordance in every high-contrast theme. */
281
+ .og-root [role="tab"][aria-selected="true"] {
282
+ outline: 2px solid Highlight;
283
+ outline-offset: -2px;
284
+ }
285
+ }
286
+
231
287
  /* ----------------------------------------------------------------------------
232
288
  xterm.js hardening (SandboxTerminal)
233
289
 
@@ -0,0 +1,2 @@
1
+ declare const stylesheet: string;
2
+ export default stylesheet;
package/styles/tokens.css CHANGED
@@ -14,8 +14,8 @@
14
14
 
15
15
  :root {
16
16
  /* Typography ------------------------------------------------------------- */
17
- --og-font-sans: "Inter Variable", "Inter", ui-sans-serif, system-ui, sans-serif;
18
- --og-font-mono: "JetBrains Mono Variable", "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
17
+ --og-font-sans: "Inter Variable", "Inter", "Noto Sans JP Variable", "Noto Sans Arabic Variable", ui-sans-serif, system-ui, sans-serif;
18
+ --og-font-mono: "JetBrains Mono Variable", "JetBrains Mono", "Noto Sans JP Variable", "Noto Sans Arabic Variable", ui-monospace, SFMono-Regular, Menlo, monospace;
19
19
  --og-font-features: "cv11", "ss01", "ss03";
20
20
  --og-code-font-size: 12px;
21
21
  --og-code-line-height: 18px;
@@ -50,7 +50,9 @@
50
50
  /* Accent — one brand hue, used sparingly ----------------------------------- */
51
51
  --og-color-accent: oklch(0.72 0.15 255);
52
52
  --og-color-accent-strong: oklch(0.78 0.14 255);
53
- --og-color-accent-deep: oklch(0.62 0.18 255);
53
+ /* Primary actions render ordinary 14 px accent-foreground text on this
54
+ token. Keep the blue dark enough to preserve WCAG AA contrast. */
55
+ --og-color-accent-deep: oklch(0.54 0.18 255);
54
56
  --og-color-accent-fg: oklch(0.985 0.005 260);
55
57
  --og-color-accent-soft: color-mix(in oklch, var(--og-color-accent) 16%, transparent);
56
58
 
@@ -101,10 +103,13 @@
101
103
  --og-color-accent-soft: color-mix(in oklch, var(--og-color-accent) 11%, transparent);
102
104
 
103
105
  --og-color-status-queued: oklch(0.55 0.03 260);
104
- --og-color-status-running: oklch(0.6 0.13 80);
105
- --og-color-status-idle: oklch(0.56 0.13 155);
106
+ /* Status letters are ordinary 11 px text, including over selected rows. */
107
+ --og-color-status-running: oklch(0.48 0.13 80);
108
+ /* Used as 11–12 px diff/status text, including on the pale addition tint.
109
+ Keep enough headroom above 4.5:1 on both Surface 1 and the tinted row. */
110
+ --og-color-status-idle: oklch(0.49 0.13 155);
106
111
  --og-color-status-waiting: oklch(0.54 0.15 305);
107
- --og-color-status-failed: oklch(0.55 0.19 22);
112
+ --og-color-status-failed: oklch(0.5 0.19 22);
108
113
  --og-color-status-cancelled: oklch(0.55 0.025 260);
109
114
  --og-color-danger: oklch(0.55 0.2 22);
110
115
  --og-color-diff-add-bg: color-mix(in oklch, var(--og-color-status-idle) 12%, transparent);
@@ -0,0 +1,2 @@
1
+ declare const stylesheet: string;
2
+ export default stylesheet;