@volter/supercode-terminal 0.2.42 → 0.2.43

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 CHANGED
@@ -107,15 +107,17 @@ attachments; read-only mirrors never offer a control that could reflow the sourc
107
107
  evidence-scoped parity boundary is recorded in [CAPABILITIES.md](CAPABILITIES.md).
108
108
 
109
109
  The terminal canvas and internal layout layers are transparent over one
110
- `--sctui-terminal-background` backing layer (the Volter brand's `surface.media` by default). Embedders
110
+ `--sctui-terminal-background` backing layer (the Volter brand's `terminal.background` by default). Embedders
111
111
  can set that token to any valid transparent or opaque CSS color without forking the component; the
112
112
  color is intentionally applied once so nested alpha does not compound back into an opaque card.
113
113
 
114
114
  Colours and fonts default to the [Volter brand's roles](https://brand.volter.ai/tokens), read as
115
115
  `var(--volter-<role>, <brand value>)`: a host that sets `--volter-*` (the brand's `tokens.css`)
116
- governs them, and `--sctui-*` or `--scui-*` overrides the one it sets. The terminal is a dark media
117
- surface in either page scheme, so its inks (the ANSI palette, foreground, cursor and the viewer's
118
- own controls) use the brand's dark values. `styles.css` is generated from `src/styles.css`, which
116
+ governs them, and `--sctui-*` or `--scui-*` overrides the one it sets. The terminal looks like
117
+ Apple's Terminal.app with its Basic profile (the brand's `terminal.*` roles, `font.terminal` and
118
+ `fontSize.terminal`: SF Mono 11 where the platform has it, Terminal.app's palette, a steady block
119
+ cursor), and like Terminal.app it follows the system's appearance whatever the page's scheme.
120
+ `styles.css` is generated from `src/styles.css`, which
119
121
  names each role as `brand(<role>)`; `npm run build` resolves them.
120
122
 
121
123
  Safety properties:
@@ -153,8 +155,9 @@ xterm, fit, search, and web-links peer packages for this surface.
153
155
  `connect` returns synchronously and must keep its function identity stable for
154
156
  one attachment. Unmount closes the attachment; the host retains ownership of
155
157
  process termination. Use `convertEol` for streams without PTY newline processing;
156
- the default preserves terminal bytes. Theme foreground and cursor through
157
- `--sctui-terminal-foreground` and `--sctui-terminal-cursor`, and the ANSI palette through
158
+ the default preserves terminal bytes. Theme foreground, cursor and selection through
159
+ `--sctui-terminal-foreground`, `--sctui-terminal-cursor` and `--sctui-terminal-selection-background`,
160
+ the face and size through `--sctui-terminal-font` and `--sctui-terminal-font-size`, and the ANSI palette through
158
161
  `--sctui-terminal-black`, `-red`, `-green`, `-yellow`, `-blue`, `-magenta`, `-cyan`, `-white` and
159
162
  their `-bright-*` forms (defaults: the brand's `terminal.*` roles). xterm reads the resolved colours
160
163
  when the viewer mounts. `/stream` does not
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-terminal",
3
- "version": "0.2.42",
3
+ "version": "0.2.43",
4
4
  "type": "module",
5
5
  "description": "Optional leak-safe terminal and tmux host adapter for Volter Harness frontends",
6
6
  "exports": {
package/react/stream.mjs CHANGED
@@ -28,8 +28,8 @@ var WORKSPACE_LABELS = Object.freeze({
28
28
  stop: "Stop session",
29
29
  terminal: "Terminal"
30
30
  });
31
- var TERMINAL_THEME_SLOTS = ["foreground", "cursor", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "brightBlack", "brightRed", "brightGreen", "brightYellow", "brightBlue", "brightMagenta", "brightCyan", "brightWhite"];
32
- function terminalTheme(element) {
31
+ var TERMINAL_THEME_SLOTS = ["foreground", "cursor", "selectionBackground", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "brightBlack", "brightRed", "brightGreen", "brightYellow", "brightBlue", "brightMagenta", "brightCyan", "brightWhite"];
32
+ function terminalLook(element) {
33
33
  const probe = element.ownerDocument.createElement("span");
34
34
  probe.hidden = true;
35
35
  element.append(probe);
@@ -39,8 +39,10 @@ function terminalTheme(element) {
39
39
  probe.style.color = `var(${name}, var(${name}-default))`;
40
40
  theme[slot] = getComputedStyle(probe).color;
41
41
  }
42
+ probe.style.font = "var(--sctui-terminal-font-size, var(--sctui-terminal-font-size-default)) var(--sctui-terminal-font, var(--sctui-terminal-font-default))";
43
+ const { fontFamily, fontSize } = getComputedStyle(probe);
42
44
  probe.remove();
43
- return theme;
45
+ return { fontFamily, fontSize: Number.parseFloat(fontSize), theme };
44
46
  }
45
47
  function TerminalStreamViewer({ active = true, attachment, connect, convertEol = false, onReady, onActivity, onBell, onOpenLink, onRetry, onStatus, onTitle }) {
46
48
  const root = useRef(null);
@@ -126,12 +128,9 @@ function TerminalStreamViewer({ active = true, attachment, connect, convertEol =
126
128
  const terminal = new Terminal({
127
129
  allowTransparency: true,
128
130
  convertEol,
129
- cursorBlink: attachment.mode === "control",
130
131
  disableStdin: attachment.mode !== "control",
131
- fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
132
- fontSize: 12,
133
132
  scrollback: 5e3,
134
- theme: terminalTheme(root.current)
133
+ ...terminalLook(root.current)
135
134
  });
136
135
  const fit = new FitAddon();
137
136
  const search = new SearchAddon();
package/react/ui.mjs CHANGED
@@ -78,8 +78,8 @@ function TerminalPath({ value }) {
78
78
  path.trailing ? /* @__PURE__ */ jsx("b", { children: path.trailing }) : null
79
79
  ] });
80
80
  }
81
- var TERMINAL_THEME_SLOTS = ["foreground", "cursor", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "brightBlack", "brightRed", "brightGreen", "brightYellow", "brightBlue", "brightMagenta", "brightCyan", "brightWhite"];
82
- function terminalTheme(element) {
81
+ var TERMINAL_THEME_SLOTS = ["foreground", "cursor", "selectionBackground", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "brightBlack", "brightRed", "brightGreen", "brightYellow", "brightBlue", "brightMagenta", "brightCyan", "brightWhite"];
82
+ function terminalLook(element) {
83
83
  const probe = element.ownerDocument.createElement("span");
84
84
  probe.hidden = true;
85
85
  element.append(probe);
@@ -89,8 +89,10 @@ function terminalTheme(element) {
89
89
  probe.style.color = `var(${name}, var(${name}-default))`;
90
90
  theme[slot] = getComputedStyle(probe).color;
91
91
  }
92
+ probe.style.font = "var(--sctui-terminal-font-size, var(--sctui-terminal-font-size-default)) var(--sctui-terminal-font, var(--sctui-terminal-font-default))";
93
+ const { fontFamily, fontSize } = getComputedStyle(probe);
92
94
  probe.remove();
93
- return theme;
95
+ return { fontFamily, fontSize: Number.parseFloat(fontSize), theme };
94
96
  }
95
97
  function TerminalViewer(props) {
96
98
  const [connector, setConnector] = useState(() => props.connect ?? null);
@@ -196,12 +198,9 @@ function TerminalStreamViewer({ active = true, attachment, connect, convertEol =
196
198
  const terminal = new Terminal({
197
199
  allowTransparency: true,
198
200
  convertEol,
199
- cursorBlink: attachment.mode === "control",
200
201
  disableStdin: attachment.mode !== "control",
201
- fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
202
- fontSize: 12,
203
202
  scrollback: 5e3,
204
- theme: terminalTheme(root.current)
203
+ ...terminalLook(root.current)
205
204
  });
206
205
  const fit = new FitAddon();
207
206
  const search = new SearchAddon();
package/stream.mjs CHANGED
@@ -28,8 +28,8 @@ var WORKSPACE_LABELS = Object.freeze({
28
28
  stop: "Stop session",
29
29
  terminal: "Terminal"
30
30
  });
31
- var TERMINAL_THEME_SLOTS = ["foreground", "cursor", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "brightBlack", "brightRed", "brightGreen", "brightYellow", "brightBlue", "brightMagenta", "brightCyan", "brightWhite"];
32
- function terminalTheme(element) {
31
+ var TERMINAL_THEME_SLOTS = ["foreground", "cursor", "selectionBackground", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "brightBlack", "brightRed", "brightGreen", "brightYellow", "brightBlue", "brightMagenta", "brightCyan", "brightWhite"];
32
+ function terminalLook(element) {
33
33
  const probe = element.ownerDocument.createElement("span");
34
34
  probe.hidden = true;
35
35
  element.append(probe);
@@ -39,8 +39,10 @@ function terminalTheme(element) {
39
39
  probe.style.color = `var(${name}, var(${name}-default))`;
40
40
  theme[slot] = getComputedStyle(probe).color;
41
41
  }
42
+ probe.style.font = "var(--sctui-terminal-font-size, var(--sctui-terminal-font-size-default)) var(--sctui-terminal-font, var(--sctui-terminal-font-default))";
43
+ const { fontFamily, fontSize } = getComputedStyle(probe);
42
44
  probe.remove();
43
- return theme;
45
+ return { fontFamily, fontSize: Number.parseFloat(fontSize), theme };
44
46
  }
45
47
  function TerminalStreamViewer({ active = true, attachment, connect, convertEol = false, onReady, onActivity, onBell, onOpenLink, onRetry, onStatus, onTitle }) {
46
48
  const root = useRef(null);
@@ -126,12 +128,9 @@ function TerminalStreamViewer({ active = true, attachment, connect, convertEol =
126
128
  const terminal = new Terminal({
127
129
  allowTransparency: true,
128
130
  convertEol,
129
- cursorBlink: attachment.mode === "control",
130
131
  disableStdin: attachment.mode !== "control",
131
- fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
132
- fontSize: 12,
133
132
  scrollback: 5e3,
134
- theme: terminalTheme(root.current)
133
+ ...terminalLook(root.current)
135
134
  });
136
135
  const fit = new FitAddon();
137
136
  const search = new SearchAddon();
package/styles.css CHANGED
@@ -1,6 +1,6 @@
1
1
  /* Generated from src/styles.css by scripts/build-styles.mjs. Edit that file. */
2
2
  .sctui-panel {
3
- --sctui-terminal-background: var(--volter-surface-media, light-dark(#0f1a1f, #070d10));
3
+ --sctui-terminal-background: var(--volter-terminal-background, light-dark(#ffffff, #1e1e1e));
4
4
  --sctui-bg-default: var(--volter-surface-page, light-dark(#f7f6f1, #0f1a1f));
5
5
  --sctui-bg-raised-default: var(--volter-surface-raised, light-dark(#fbfaf7, #16252c));
6
6
  --sctui-fill-default: var(--volter-surface-subtle, light-dark(#f2f1eb, #1d2d34));
@@ -43,21 +43,24 @@
43
43
  .sctui-list .sctui-danger { color:var(--sctui-danger,var(--scui-danger,var(--sctui-danger-default))); background:transparent }
44
44
  .sctui-error,.sctui-empty { margin:10px; padding:9px; border:1px solid var(--sctui-border,var(--scui-border,var(--sctui-border-default))); border-radius:8px; color:var(--sctui-muted,var(--scui-muted,var(--sctui-muted-default))); background:var(--sctui-bg-raised,var(--scui-bg-raised,var(--sctui-bg-raised-default))); font-size:11px; line-height:1.4 }
45
45
  .sctui-error { color:var(--sctui-danger,var(--scui-danger,var(--sctui-danger-default))) }
46
- .sctui-live { display:flex; min-height:0; flex:1; flex-direction:column; padding:5px 7px 7px; gap:4px; background:var(--sctui-terminal-background) }
46
+ .sctui-live { color-scheme:light dark; display:flex; min-height:0; flex:1; flex-direction:column; padding:5px 7px 7px; gap:4px; background:var(--sctui-terminal-background) }
47
47
  .sctui-viewer {
48
- /* The terminal is a dark media surface in either page scheme, so its inks
49
- (ANSI palette, foreground, chrome) resolve in the dark scheme. xterm reads
50
- the resolved colours from these tokens when it mounts (src/ui.jsx). */
51
- --sctui-terminal-foreground-default:var(--volter-terminal-white, light-dark(#808b8f, #f3f2ec)); --sctui-terminal-cursor-default:var(--volter-terminal-white, light-dark(#808b8f, #f3f2ec));
52
- --sctui-terminal-black-default:var(--volter-terminal-black, light-dark(#16252c, #2c3d45)); --sctui-terminal-red-default:var(--volter-terminal-red, light-dark(#d24a1f, #f07650));
53
- --sctui-terminal-green-default:var(--volter-terminal-green, light-dark(#3f7a55, #6fbf8e)); --sctui-terminal-yellow-default:var(--volter-terminal-yellow, light-dark(#c7641a, #ec9a52));
54
- --sctui-terminal-blue-default:var(--volter-terminal-blue, light-dark(#3b5f8a, #7ea6d8)); --sctui-terminal-magenta-default:var(--volter-terminal-magenta, light-dark(#6a5a92, #aa98d8));
55
- --sctui-terminal-cyan-default:var(--volter-terminal-cyan, light-dark(#2f7a74, #6cc1b8)); --sctui-terminal-white-default:var(--volter-terminal-white, light-dark(#808b8f, #f3f2ec));
56
- --sctui-terminal-bright-black-default:var(--volter-terminal-bright-black, light-dark(#5d6970, #a9b0ad)); --sctui-terminal-bright-red-default:var(--volter-terminal-bright-red, light-dark(#ff6a1f, #ff8a5c));
57
- --sctui-terminal-bright-green-default:var(--volter-terminal-bright-green, light-dark(#6a9a3a, #9bcf62)); --sctui-terminal-bright-yellow-default:var(--volter-terminal-bright-yellow, light-dark(#c98a12, #f3c26b));
58
- --sctui-terminal-bright-blue-default:var(--volter-terminal-bright-blue, light-dark(#4f78a8, #9ec0ea)); --sctui-terminal-bright-magenta-default:var(--volter-terminal-bright-magenta, light-dark(#8a78c0, #c4b7e6));
59
- --sctui-terminal-bright-cyan-default:var(--volter-terminal-bright-cyan, light-dark(#3f948d, #8ad6cd)); --sctui-terminal-bright-white-default:var(--volter-terminal-bright-white, light-dark(#b8bab5, #ffffff));
60
- color-scheme:dark;
48
+ /* The terminal is Terminal.app's Basic profile (the brand's terminal roles):
49
+ like Terminal.app it follows the system's appearance, whatever the page's
50
+ scheme. xterm reads the resolved colours, face and size from these tokens
51
+ when it mounts (src/ui.jsx). */
52
+ --sctui-terminal-foreground-default:var(--volter-terminal-foreground, light-dark(#000000, #ffffff)); --sctui-terminal-cursor-default:var(--volter-terminal-cursor, light-dark(#9d9d9d, #9d9d9d));
53
+ --sctui-terminal-selection-background-default:var(--volter-terminal-selection, light-dark(#b3d7ff, #3f638b));
54
+ --sctui-terminal-font-default:var(--volter-font-terminal, "SF Mono", SFMono-Regular, ui-monospace, Menlo, Consolas, monospace); --sctui-terminal-font-size-default:var(--volter-font-size-terminal, 11px);
55
+ --sctui-terminal-black-default:var(--volter-terminal-black, light-dark(#000000, #000000)); --sctui-terminal-red-default:var(--volter-terminal-red, light-dark(#990000, #990000));
56
+ --sctui-terminal-green-default:var(--volter-terminal-green, light-dark(#00a600, #00a600)); --sctui-terminal-yellow-default:var(--volter-terminal-yellow, light-dark(#999900, #999900));
57
+ --sctui-terminal-blue-default:var(--volter-terminal-blue, light-dark(#0000b3, #0000b3)); --sctui-terminal-magenta-default:var(--volter-terminal-magenta, light-dark(#b300b3, #b300b3));
58
+ --sctui-terminal-cyan-default:var(--volter-terminal-cyan, light-dark(#00a6b3, #00a6b3)); --sctui-terminal-white-default:var(--volter-terminal-white, light-dark(#bfbfbf, #bfbfbf));
59
+ --sctui-terminal-bright-black-default:var(--volter-terminal-bright-black, light-dark(#666666, #666666)); --sctui-terminal-bright-red-default:var(--volter-terminal-bright-red, light-dark(#e60000, #e60000));
60
+ --sctui-terminal-bright-green-default:var(--volter-terminal-bright-green, light-dark(#00d900, #00d900)); --sctui-terminal-bright-yellow-default:var(--volter-terminal-bright-yellow, light-dark(#e6e600, #e6e600));
61
+ --sctui-terminal-bright-blue-default:var(--volter-terminal-bright-blue, light-dark(#0000ff, #0000ff)); --sctui-terminal-bright-magenta-default:var(--volter-terminal-bright-magenta, light-dark(#e600e6, #e600e6));
62
+ --sctui-terminal-bright-cyan-default:var(--volter-terminal-bright-cyan, light-dark(#00e6e6, #00e6e6)); --sctui-terminal-bright-white-default:var(--volter-terminal-bright-white, light-dark(#e6e6e6, #e6e6e6));
63
+ color-scheme:light dark;
61
64
  position:relative; display:flex; min-width:0; min-height:0; flex:1; flex-direction:column; background:transparent }
62
65
  .sctui-viewer[data-bell="true"] .sctui-screen { box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--volter-status-danger-base, light-dark(#d24a1f, #f07650)) 72%, transparent) }
63
66
  .sctui-viewerbar { display:flex; min-width:0; min-height:18px; flex:none; align-items:center }
@@ -67,7 +70,7 @@
67
70
  .sctui-screen .xterm .xterm-viewport { overflow-y:auto; background:transparent }
68
71
 
69
72
  .sctui-workspace {
70
- --sctui-terminal-background:var(--volter-surface-media, light-dark(#0f1a1f, #070d10));
73
+ --sctui-terminal-background:var(--volter-terminal-background, light-dark(#ffffff, #1e1e1e));
71
74
  --sctui-bg-default:var(--volter-surface-page, light-dark(#f7f6f1, #0f1a1f)); --sctui-bg-raised-default:var(--volter-surface-raised, light-dark(#fbfaf7, #16252c)); --sctui-fill-default:var(--volter-surface-subtle, light-dark(#f2f1eb, #1d2d34));
72
75
  --sctui-fill-strong-default:var(--volter-surface-inset, light-dark(#e7e6df, #22343c)); --sctui-fg-default:var(--volter-text-primary, light-dark(#16252c, #f3f2ec)); --sctui-muted-default:var(--volter-text-muted, light-dark(#5d6970, #a9b0ad));
73
76
  --sctui-border-default:var(--volter-border-default, light-dark(#d9dad3, #2c3d45)); --sctui-border-strong-default:var(--volter-border-strong, light-dark(#c4c5bc, #3d5059)); --sctui-danger-default:var(--volter-status-danger-base, light-dark(#d24a1f, #f07650));
@@ -116,7 +119,7 @@
116
119
  .sctui-toolbar-action.sctui-danger { color:var(--sctui-danger,var(--scui-danger,var(--sctui-danger-default))) }
117
120
  .sctui-viewport-action { display:grid; width:32px; flex:none; padding:0; place-items:center }
118
121
  .sctui-viewport-action svg { width:14px; height:14px; fill:none; stroke:currentColor; stroke-linecap:round; stroke-linejoin:round; stroke-width:1.35 }
119
- .sctui-terminals { color-scheme:dark; position:relative; min-width:0; min-height:0; flex:1; background:transparent }
122
+ .sctui-terminals { color-scheme:light dark; position:relative; min-width:0; min-height:0; flex:1; background:var(--sctui-terminal-background) }
120
123
  .sctui-terminal { position:absolute; inset:0; display:none; min-width:0; min-height:0; flex-direction:column; padding:4px 7px 7px; background:transparent }
121
124
  .sctui-terminal[data-active="true"] { display:flex }
122
125
  .sctui-terminal > .sctui-screen,.sctui-terminal > .sctui-viewer { min-height:0; flex:1; overflow:hidden }
package/ui.mjs CHANGED
@@ -78,8 +78,8 @@ function TerminalPath({ value }) {
78
78
  path.trailing ? /* @__PURE__ */ jsx("b", { children: path.trailing }) : null
79
79
  ] });
80
80
  }
81
- var TERMINAL_THEME_SLOTS = ["foreground", "cursor", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "brightBlack", "brightRed", "brightGreen", "brightYellow", "brightBlue", "brightMagenta", "brightCyan", "brightWhite"];
82
- function terminalTheme(element) {
81
+ var TERMINAL_THEME_SLOTS = ["foreground", "cursor", "selectionBackground", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "brightBlack", "brightRed", "brightGreen", "brightYellow", "brightBlue", "brightMagenta", "brightCyan", "brightWhite"];
82
+ function terminalLook(element) {
83
83
  const probe = element.ownerDocument.createElement("span");
84
84
  probe.hidden = true;
85
85
  element.append(probe);
@@ -89,8 +89,10 @@ function terminalTheme(element) {
89
89
  probe.style.color = `var(${name}, var(${name}-default))`;
90
90
  theme[slot] = getComputedStyle(probe).color;
91
91
  }
92
+ probe.style.font = "var(--sctui-terminal-font-size, var(--sctui-terminal-font-size-default)) var(--sctui-terminal-font, var(--sctui-terminal-font-default))";
93
+ const { fontFamily, fontSize } = getComputedStyle(probe);
92
94
  probe.remove();
93
- return theme;
95
+ return { fontFamily, fontSize: Number.parseFloat(fontSize), theme };
94
96
  }
95
97
  function TerminalViewer(props) {
96
98
  const [connector, setConnector] = useState(() => props.connect ?? null);
@@ -196,12 +198,9 @@ function TerminalStreamViewer({ active = true, attachment, connect, convertEol =
196
198
  const terminal = new Terminal({
197
199
  allowTransparency: true,
198
200
  convertEol,
199
- cursorBlink: attachment.mode === "control",
200
201
  disableStdin: attachment.mode !== "control",
201
- fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
202
- fontSize: 12,
203
202
  scrollback: 5e3,
204
- theme: terminalTheme(root.current)
203
+ ...terminalLook(root.current)
205
204
  });
206
205
  const fit = new FitAddon();
207
206
  const search = new SearchAddon();