@telepath-computer/television 1.4.15 → 1.4.17

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.
@@ -422,13 +422,16 @@
422
422
  --text-4xl: round(calc(var(--text-base) * 30 / 14), 1px);
423
423
 
424
424
  /* The control lines: the line-height a control's label uses, and the one
425
- input its height derives from — the line, plus the space-2 padding step
425
+ input its height derives from — the line, plus the size's padding step
426
426
  top and bottom, plus a 1px border each side, gives every control the
427
- same height: 18 + 4 + 2 = 24px (14 + 4 + 2 = 20px at the small step).
427
+ same height at each size: 18 + 4 + 2 = 24px at the default size (the
428
+ space-2 step), 14 + 4 + 2 = 20px at the small step (space-2), and
429
+ 22 + 16 + 2 = 40px at the large step (space-8).
428
430
  Stated in pixels, not a ratio: a control's cell is tighter than prose,
429
431
  immune to the leading around it, and lands on even pixels in any font. */
430
432
  --line-control: 18px;
431
433
  --line-control-sm: 14px;
434
+ --line-control-lg: 22px;
432
435
  }
433
436
 
434
437
  :where(:root) {
@@ -855,6 +858,16 @@
855
858
  padding: var(--space-2);
856
859
  }
857
860
 
861
+ :where(button[size="lg"]) {
862
+ font-size: var(--text-lg);
863
+ line-height: var(--line-control-lg);
864
+ padding: var(--space-8) var(--space-20);
865
+ }
866
+
867
+ :where(button[size="lg"][icon]) {
868
+ padding: var(--space-8);
869
+ }
870
+
858
871
  /* A sized control sizes the icon it holds: whatever size the composer put on
859
872
  the icon, the control's own wins — `tv-icon[size]` names a fixed pixel
860
873
  size, so left alone the icon would ignore the control shrinking around it.
@@ -900,6 +913,15 @@
900
913
  resize: vertical;
901
914
  }
902
915
 
916
+ /* The large size matches a large button beside the field
917
+ ([[ui/foundation/button/button.css]]): the same text step, line and
918
+ vertical padding step, so the two are the same height. */
919
+ :where(:is(input:not([type]), input[type=""], input[type="text"], input[type="email"], input[type="url"], input[type="tel"], input[type="password"], input[type="number"], textarea)[data-size="lg"]) {
920
+ font-size: var(--text-lg);
921
+ line-height: var(--line-control-lg);
922
+ padding: var(--space-8) var(--space-12);
923
+ }
924
+
903
925
  /* Shared error-message styling; validation and announcement belong to the surface. */
904
926
  :where(.tv-error) {
905
927
  margin: 0;
package/dist/cli.cjs CHANGED
@@ -53345,7 +53345,7 @@ function disabledTelemetryRuntime() {
53345
53345
 
53346
53346
  // ../server/src/updates/version.ts
53347
53347
  function readVersionStamp() {
53348
- if ("1.4.15".length > 0) return "1.4.15";
53348
+ if ("1.4.17".length > 0) return "1.4.17";
53349
53349
  return void 0;
53350
53350
  }
53351
53351
  function resolveUpdateReleaseVersion(env = process.env, stamp = readVersionStamp()) {
@@ -53887,8 +53887,8 @@ var Server = class {
53887
53887
  };
53888
53888
  };
53889
53889
  function readServerPackageVersion() {
53890
- if ("1.4.15".length > 0) {
53891
- return telemetryVersion("1.4.15");
53890
+ if ("1.4.17".length > 0) {
53891
+ return telemetryVersion("1.4.17");
53892
53892
  }
53893
53893
  const packageJsonPath = import_node_path13.default.resolve(import_node_path13.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url)), "..", "package.json");
53894
53894
  if (!(0, import_node_fs11.existsSync)(packageJsonPath)) return telemetryVersion("0.0.0");
@@ -56073,15 +56073,15 @@ function writeLine(output, line) {
56073
56073
  output.write(`${line}
56074
56074
  `);
56075
56075
  }
56076
- function terminalHyperlink(url2, text = url2) {
56077
- return `\x1B]8;;${url2}\x1B\\${text}\x1B]8;;\x1B\\`;
56076
+ function formatConnectURL(output, serverURL, token) {
56077
+ const url2 = buildConnectURL(serverURL, token);
56078
+ return output.isTTY === true ? `\x1B]8;;${url2}\x1B\\${url2}\x1B]8;;\x1B\\` : url2;
56078
56079
  }
56079
56080
  function writeConnectURLs(output, urls, options = {}) {
56080
56081
  writeLine(output, options.installed ? "Television service installed." : "Television server running.");
56081
56082
  writeLine(output, "Open Television:");
56082
56083
  for (const url2 of urls) {
56083
- const connectURL = buildConnectURL(url2, options.token ?? null);
56084
- writeLine(output, ` ${terminalHyperlink(connectURL)}`);
56084
+ writeLine(output, ` ${formatConnectURL(output, url2, options.token)}`);
56085
56085
  }
56086
56086
  }
56087
56087
  async function bestEffortWithinTimeout2(operation, timeoutMs) {
@@ -56119,8 +56119,8 @@ function resolveVercelSkillsInstallerBin() {
56119
56119
  return localRequire.resolve("skills/bin/cli.mjs");
56120
56120
  }
56121
56121
  function readCLIVersion() {
56122
- if ("1.4.15".length > 0) {
56123
- return "1.4.15";
56122
+ if ("1.4.17".length > 0) {
56123
+ return "1.4.17";
56124
56124
  }
56125
56125
  const devPackageJsonPath = import_node_path20.default.join(getDevPackageDir(), "package.json");
56126
56126
  if (!(0, import_node_fs18.existsSync)(devPackageJsonPath)) {
@@ -57041,6 +57041,23 @@ function createProgram(env, invocation = { argv: [] }) {
57041
57041
  program2.command("stop").description("Stop the Television system service").action(async () => {
57042
57042
  await uninstallPersistedService(resolveHome());
57043
57043
  });
57044
+ program2.command("links").description("Print connect links for the running Television server").option("--port <number>", "Server port; required when the config file sets port 0", parseClientPortOption).action(async (opts) => {
57045
+ const serverURL = resolveServerURL(opts.port);
57046
+ const token = readAuthToken(resolveHome());
57047
+ const client = env.createClient(serverURL, token);
57048
+ const health = await client.health();
57049
+ await client.display.get();
57050
+ let requiresToken = false;
57051
+ try {
57052
+ await env.createClient(serverURL, void 0).display.get();
57053
+ } catch (error48) {
57054
+ if (typeof error48 !== "object" || error48 === null || !("status" in error48) || error48.status !== HTTP_UNAUTHORIZED_STATUS2) throw error48;
57055
+ requiresToken = true;
57056
+ }
57057
+ for (const address of health.bindAddresses) {
57058
+ writeLine(env.stdout, formatConnectURL(env.stdout, buildServerURL(address, health.port), requiresToken ? token : null));
57059
+ }
57060
+ });
57044
57061
  program2.command("status").description("Print the selected home, server health, version, telemetry state, and service status as JSON").option("--port <number>", "Server port; required when the config file sets port 0", parseClientPortOption).action(async (opts) => {
57045
57062
  const home = resolveHome();
57046
57063
  const serverURL = resolveServerURL(opts.port);
@@ -577,7 +577,7 @@ documented token with a literal fallback where appropriate.
577
577
 
578
578
  ### Type
579
579
 
580
- `--control-font-size`, `--text-base`, `--text-sm`, `--text-md`, `--text-lg`, `--text-xl`, `--text-2xl`, `--text-3xl`, `--text-4xl`, `--line-control`, `--line-control-sm`.
580
+ `--control-font-size`, `--text-base`, `--text-sm`, `--text-md`, `--text-lg`, `--text-xl`, `--text-2xl`, `--text-3xl`, `--text-4xl`, `--line-control`, `--line-control-sm`, `--line-control-lg`.
581
581
 
582
582
  ### Spacing and radii
583
583
 
@@ -593,6 +593,13 @@ documented token with a literal fallback where appropriate.
593
593
 
594
594
  ## Canonical components
595
595
 
596
+ ### Large controls
597
+
598
+ Use `<button size="lg">Connect</button>` for a large button and
599
+ `<input data-size="lg" aria-label="Server link">` for a matching text field.
600
+ The same `data-size="lg"` applies to textareas. Their line height comes from
601
+ `--line-control-lg`; an ordinary control omits the size attribute.
602
+
596
603
  ### Native inputs and errors
597
604
 
598
605
  Native text-entry inputs and textareas receive shared styling automatically.
@@ -460,13 +460,16 @@ These four tokens are enough to replace the main surfaces and text, but they do
460
460
  --text-4xl: round(calc(var(--text-base) * 30 / 14), 1px);
461
461
 
462
462
  /* The control lines: the line-height a control's label uses, and the one
463
- input its height derives from — the line, plus the space-2 padding step
463
+ input its height derives from — the line, plus the size's padding step
464
464
  top and bottom, plus a 1px border each side, gives every control the
465
- same height: 18 + 4 + 2 = 24px (14 + 4 + 2 = 20px at the small step).
465
+ same height at each size: 18 + 4 + 2 = 24px at the default size (the
466
+ space-2 step), 14 + 4 + 2 = 20px at the small step (space-2), and
467
+ 22 + 16 + 2 = 40px at the large step (space-8).
466
468
  Stated in pixels, not a ratio: a control's cell is tighter than prose,
467
469
  immune to the leading around it, and lands on even pixels in any font. */
468
470
  --line-control: 18px;
469
471
  --line-control-sm: 14px;
472
+ --line-control-lg: 22px;
470
473
  }
471
474
 
472
475
  /* Foundation tokens — spacing and corners */
@@ -729,6 +732,8 @@ An artifact frame belongs to the application document. The document inside its i
729
732
 
730
733
  `#app` owns the application layout and suppresses ordinary text selection in its contents; readable regions can explicitly restore selection. `.app-sidebar` holds the channel list. The sidebar defaults to 260 pixels wide, resizes between 160 and 350 pixels, and remembers the chosen width per browser; it can also collapse entirely, the navbar then opening with an expand control and — while a channel is open — a channel-switcher popover, with the collapsed state remembered per browser. `.app-main` holds the wallpaper, navbar and stage. `.app-main > .top-bar` supplies the horizontal control inset; stage padding is separate. Preserve the shell width constraints so overflowing tabs and pages scroll inside their regions without widening the document. `#app:focus` suppresses a ring on the container itself. The wallpaper region establishes a backdrop boundary so overlay blur samples the wallpaper rather than adjacent content, while fixed popovers retain viewport positioning.
731
734
 
735
+ While Television cannot use its server, one connection dialog is shown. Disconnected and unreachable states keep an established shell and its artifact documents mounted; first connection, authorization and upgrade-gate states have no shell behind them. Three failed unreachable reconnects change Disconnected to Can’t connect with server; the displayed upgrade gate stays until reload.
736
+
732
737
  During collapse or expansion, `#app[data-sidebar-motion]` contains both resting layouts and one travelling control:
733
738
 
734
739
  ```html
@@ -852,7 +857,7 @@ An empty channel adds `.stage-empty`, containing an artifact `tv-icon` and a par
852
857
  </div>
853
858
  ```
854
859
 
855
- `.artifact-frame` owns the border, curve, surface and broad shadow. Its `::before` paints the sharp rim and its `::after` paints a pointer-transparent masked inner highlight over document and titlebar. Background pages suppress the broad shadow while retaining the exterior rim. `.artifact-frame-clip > :is(iframe, webview)` fills the document area through the one-pixel padding track. `.artifact-frame-clip` clips the document and titlebar while the outer frame lets both shadows extend outward. `.artifact-title-bar` paints the lower band, `.artifact-title-bar .artifact-title` takes the remaining width and truncates, and `.artifact-bar-divider` separates navigation from the menu trigger. The two direction buttons use `disabled` to show unavailable history. In browser demo mode, the frame of an external web page wraps its artifact `tv-icon` in `button.artifact-return` (`icon`, ghost, `sm`) and shows no direction controls. The document repeats the top clipping radius where required for composited iframe/webview rendering.
860
+ `.artifact-frame` owns the border, curve, surface and broad shadow. Its `::before` paints the sharp rim and its `::after` paints a pointer-transparent masked inner highlight over document and titlebar. Background pages suppress the broad shadow while retaining the exterior rim. `.artifact-frame-clip > :is(iframe, webview)` fills the document area through the one-pixel padding track. `.artifact-frame-clip` clips the document and titlebar while the outer frame lets both shadows extend outward. `.artifact-title-bar` paints the lower band, `.artifact-title-bar .artifact-title` takes the remaining width and truncates, and `.artifact-bar-divider` separates navigation from the menu trigger. The two direction buttons use `disabled` to show unavailable history. In browser demo mode, the frame of an external web page wraps its artifact `tv-icon` in `button.artifact-return` (`icon`, ghost, `sm`) and shows no direction controls. The document repeats the top clipping radius where required for composited iframe/webview rendering. A frame can also hold static `.artifact-frame-content` in place of a document and omit its menu when it has no artifact to act on. That content fills the clipping region above the title bar.
856
861
 
857
862
  The artifact menu uses the same shared menu elements and placement as channel menus. Deletion uses the shared dialog outline below.
858
863
 
@@ -903,7 +908,7 @@ An executable active theme adds `.settings-javascript-consent`, with `.settings-
903
908
 
904
909
  The update control is `button.update-bell#update-bell[icon][intent="alert"]` paired with `tv-popover.update-popover[manual][trigger="update-bell"][role="status"]`. `.update-popover` contains readable notice text and `.update-actions` with `button.update-later` and an optional primary copy action. The desktop self-update notice has `button.update-restart[size="sm"][intent="primary"]` in place of the copy action; it carries `[disabled]` while the app restarts. The manual panel stays open until the composing surface closes it.
905
910
 
906
- The reusable copy control is `button.copy-button[size="sm"][prompt]`, optionally carrying `intent`, containing `.copy-button-idle` and `.copy-button-done`. Both contain an icon and label. `.copy-button[copied] .copy-button-idle` hides the idle content without changing its occupied space; `.copy-button[copied] .copy-button-done` overlays the confirmation. `.copy-button-status` is a separate visually hidden live announcement. Preserve that status region and stable button size when restyling confirmation.
911
+ The reusable copy control is `button.copy-button[prompt]`, optionally carrying `intent` and `size`, containing `.copy-button-idle` and `.copy-button-done`. Both contain an icon and label. The default Copy size is `sm`; callers can omit the rendered size attribute for a standard button or request `size="lg"`. `.copy-button[copied] .copy-button-idle` hides the idle content without changing its occupied space; `.copy-button[copied] .copy-button-done` overlays the confirmation. `.copy-button-status` is a separate visually hidden live announcement. Preserve that status region and stable button size when restyling confirmation.
907
912
 
908
913
  ### Dialogs, connection states and upgrade gate
909
914
 
@@ -922,19 +927,19 @@ The reusable copy control is `button.copy-button[size="sm"][prompt]`, optionally
922
927
 
923
928
  The scrolling `.dialog-content` wrapper may contain ordinary content instead of an alert. Ambient selectors `:where(.dialog-overlay)`, `:where(dialog)`, and `:where(dialog:focus-visible)` define dimming, centering, panel chrome and container focus treatment. `:where(.dialog-alert)`, `:where(.dialog-alert h2)`, `:where(.dialog-alert p)`, and `:where(.dialog-actions)` define the shared confirmation interior. Keep the modal input boundary and focus behavior intact.
924
929
 
925
- Connection and authorization states reuse the dialog with `.system-modal`: an icon, heading and optional supporting paragraph. `.system-modal h2` and `.system-modal p:not(.tv-error)` set their hierarchy. Connecting and disconnected states use a spinning `tv-icon`; an error adds `.system-modal .server-url`. Authorization uses `form.system-modal.auth-form`. The field uses shared native-input styling; `.auth-form .auth-token` and `.auth-form .auth-submit` stretch the field and submit control. Rejection adds `aria-invalid="true"` and associates the shared error paragraph through `aria-describedby`; the alert communicates the failure. The rejected state is:
930
+ Connection dialogs use `.system-modal`, with a heading and supporting text where applicable. `.system-modal h2` and `.system-modal p:not(.tv-error)` set their hierarchy. Connecting has a spinning icon and title; Disconnected adds the reconnect countdown or in-flight line. Can’t connect with server has no icon, adds `.server-url` and recovery guidance, and keeps the reconnect line. Access token required uses the lock icon and guidance for obtaining a current link. The browser directs the person to its address bar; the desktop's served interface directs them to Disconnect from Server in the app menu.
931
+
932
+ Only the local desktop page adds `button.system-modal-disconnect[intent="danger"]` to unauthorized and error dialogs:
926
933
 
927
934
  ```html
928
- <form class="system-modal auth-form">
935
+ <div class="system-modal">
929
936
  <tv-icon name="locked" size="xl"></tv-icon>
930
937
  <h2>…</h2><p>…</p>
931
- <input class="auth-token" type="password" name="token" placeholder="…" aria-label="…" autofocus required aria-invalid="true" aria-describedby="auth-token-error">
932
- <p id="auth-token-error" class="tv-error" role="alert">…</p>
933
- <button class="auth-submit" intent="primary">…</button>
934
- </form>
938
+ <button class="system-modal-disconnect" intent="danger">…</button>
939
+ </div>
935
940
  ```
936
941
 
937
- The ordinary authorization state omits the invalid attribute, error association and error paragraph.
942
+ Connection dialogs leave only when their owner's state changes. Served dialogs wear the server's theme; local dialogs wear Clouds. In the desktop app a `.window-drag-strip[electron-draggable]` spans the top 36 pixels while no shell is rendered, including on the local page. It sits inside `dialog`, outside `.dialog-content`, so native modality leaves it interactive. A retained shell supplies its own drag areas, including with its sidebar collapsed.
938
943
 
939
944
  Upgrade instructions use `.desktop-upgrade-gate > .dialog-overlay > dialog > .dialog-content > .upgrade-gate-body`. The gate fills the halted page; the body scrolls within the panel. `.upgrade-gate-body h1`, `.upgrade-gate-body p`, `.upgrade-gate-body pre`, and `.upgrade-gate-body :last-child` restore local reading rhythm and command formatting. When the app has downloaded an update, `.upgrade-gate-actions` follows the body inside `.dialog-content` and places `button.upgrade-gate-restart[intent="primary"]` trailing below the message; the button carries `[disabled]` while the app restarts.
940
945
 
@@ -949,7 +954,7 @@ Upgrade instructions use `.desktop-upgrade-gate > .dialog-overlay > dialog > .di
949
954
  </main>
950
955
  ```
951
956
 
952
- `.artifact-error` paints the document ground; `.artifact-error-body` limits the reading column. `.artifact-error h1`, `.artifact-error p`, and `.artifact-error-block` arrange its text. A missing artifact can include a path chip. An unsupported URL can include a link or `.plain-address`, followed by a link to the admin guide. `.artifact-error a`, `.artifact-error .plain-address`, and `.artifact-error code` wrap long content; the path chip is selected whole for copying. Optional host-supplied content may carry `[hidden]`.
957
+ `.artifact-error` paints the document ground; `.artifact-error-body` limits the reading column. `.artifact-error h1`, `.artifact-error p`, and `.artifact-error-block` arrange its text. A missing artifact can include a path chip. An unsupported URL can include a link or `.plain-address`, followed by a link to the admin guide for installing the Mac desktop app. `.artifact-error a`, `.artifact-error .plain-address`, and `.artifact-error code` wrap long content; the path chip is selected whole for copying. Optional host-supplied content may carry `[hidden]`.
953
958
 
954
959
  ## Panels and surface edges
955
960