@zenbu-labs/pixel 0.0.0 → 0.0.13

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 (153) hide show
  1. package/dist/bin.d.ts +2 -0
  2. package/dist/bin.js +161 -0
  3. package/dist/bootstrap.d.ts +1 -0
  4. package/dist/bootstrap.js +75 -0
  5. package/dist/context-menu.d.ts +20 -0
  6. package/dist/context-menu.js +57 -0
  7. package/dist/debug.d.ts +1 -0
  8. package/dist/debug.js +9 -0
  9. package/dist/devtools-layout.d.ts +21 -0
  10. package/dist/devtools-layout.js +45 -0
  11. package/dist/devtools.d.ts +33 -0
  12. package/dist/devtools.js +125 -0
  13. package/dist/electron/index.d.ts +3 -0
  14. package/dist/electron/index.js +4 -0
  15. package/dist/host/guest.d.ts +5 -0
  16. package/dist/host/guest.js +178 -0
  17. package/dist/host/server.d.ts +91 -0
  18. package/dist/host/server.js +296 -0
  19. package/dist/host/shell.d.ts +35 -0
  20. package/dist/host/shell.js +113 -0
  21. package/dist/host/strip.d.ts +6 -0
  22. package/dist/host/strip.js +63 -0
  23. package/dist/icons.d.ts +30 -0
  24. package/dist/icons.js +58 -0
  25. package/dist/index.d.ts +17 -0
  26. package/dist/index.js +39 -0
  27. package/dist/instances.d.ts +30 -0
  28. package/dist/instances.js +177 -0
  29. package/dist/layout.d.ts +5 -0
  30. package/dist/layout.js +34 -0
  31. package/dist/popup.d.ts +21 -0
  32. package/dist/popup.js +47 -0
  33. package/dist/preload/index.d.ts +15 -0
  34. package/dist/preload/index.js +3 -0
  35. package/dist/react/colors.d.ts +3 -0
  36. package/dist/react/colors.js +25 -0
  37. package/dist/react/components.d.ts +21 -0
  38. package/dist/react/components.js +45 -0
  39. package/dist/react/devtools/app.d.ts +3 -0
  40. package/dist/react/devtools/app.js +89 -0
  41. package/dist/react/devtools/console-capture.d.ts +1 -0
  42. package/dist/react/devtools/console-capture.js +41 -0
  43. package/dist/react/devtools/controller.d.ts +45 -0
  44. package/dist/react/devtools/controller.js +252 -0
  45. package/dist/react/devtools/elements.d.ts +4 -0
  46. package/dist/react/devtools/elements.js +152 -0
  47. package/dist/react/devtools/export-profile.d.ts +2 -0
  48. package/dist/react/devtools/export-profile.js +225 -0
  49. package/dist/react/devtools/fiber-hook.d.ts +1 -0
  50. package/dist/react/devtools/fiber-hook.js +89 -0
  51. package/dist/react/devtools/log-panel.d.ts +4 -0
  52. package/dist/react/devtools/log-panel.js +113 -0
  53. package/dist/react/devtools/profiler.d.ts +11 -0
  54. package/dist/react/devtools/profiler.js +374 -0
  55. package/dist/react/devtools/store.d.ts +27 -0
  56. package/dist/react/devtools/store.js +61 -0
  57. package/dist/react/devtools/stores.d.ts +92 -0
  58. package/dist/react/devtools/stores.js +41 -0
  59. package/dist/react/devtools/theme.d.ts +35 -0
  60. package/dist/react/devtools/theme.js +77 -0
  61. package/dist/react/devtools/ui.d.ts +24 -0
  62. package/dist/react/devtools/ui.js +59 -0
  63. package/dist/react/index.d.ts +110 -0
  64. package/dist/react/index.js +538 -0
  65. package/dist/react/markdown.d.ts +25 -0
  66. package/dist/react/markdown.js +270 -0
  67. package/dist/react/native.d.ts +116 -0
  68. package/dist/react/native.js +56 -0
  69. package/dist/react/reconciler-config.d.ts +241 -0
  70. package/dist/react/reconciler-config.js +412 -0
  71. package/dist/react/styles.d.ts +88 -0
  72. package/dist/react/styles.js +85 -0
  73. package/dist/react/surface.d.ts +55 -0
  74. package/dist/react/surface.js +74 -0
  75. package/dist/registry.d.ts +53 -0
  76. package/dist/registry.js +193 -0
  77. package/dist/root.d.ts +19 -0
  78. package/dist/root.js +342 -0
  79. package/dist/sandbox.d.ts +4 -0
  80. package/dist/sandbox.js +84 -0
  81. package/dist/scale.d.ts +7 -0
  82. package/dist/scale.js +31 -0
  83. package/dist/ssh/index.d.ts +58 -0
  84. package/dist/ssh/index.js +445 -0
  85. package/dist/terminal/applescript.d.ts +2 -0
  86. package/dist/terminal/applescript.js +20 -0
  87. package/dist/terminal/detect.d.ts +10 -0
  88. package/dist/terminal/detect.js +34 -0
  89. package/dist/terminal/graphics.d.ts +9 -0
  90. package/dist/terminal/graphics.js +142 -0
  91. package/dist/terminal/index.d.ts +12 -0
  92. package/dist/terminal/index.js +23 -0
  93. package/dist/terminal/run.d.ts +2 -0
  94. package/dist/terminal/run.js +15 -0
  95. package/dist/terminal/shared.d.ts +20 -0
  96. package/dist/terminal/shared.js +88 -0
  97. package/dist/terminal/terminal.d.ts +66 -0
  98. package/dist/terminal/terminal.js +6 -0
  99. package/dist/terminal/terminals/cmux.d.ts +2 -0
  100. package/dist/terminal/terminals/cmux.js +98 -0
  101. package/dist/terminal/terminals/ghostty-script.d.ts +1 -0
  102. package/dist/terminal/terminals/ghostty-script.js +179 -0
  103. package/dist/terminal/terminals/ghostty.d.ts +2 -0
  104. package/dist/terminal/terminals/ghostty.js +336 -0
  105. package/dist/terminal/terminals/herdr.d.ts +2 -0
  106. package/dist/terminal/terminals/herdr.js +141 -0
  107. package/dist/terminal/terminals/index.d.ts +5 -0
  108. package/dist/terminal/terminals/index.js +26 -0
  109. package/dist/terminal/terminals/kitty.d.ts +2 -0
  110. package/dist/terminal/terminals/kitty.js +209 -0
  111. package/dist/terminal/terminals/supacode.d.ts +2 -0
  112. package/dist/terminal/terminals/supacode.js +79 -0
  113. package/dist/terminal/terminals/tmux.d.ts +2 -0
  114. package/dist/terminal/terminals/tmux.js +132 -0
  115. package/dist/terminal/terminals/tty7.d.ts +2 -0
  116. package/dist/terminal/terminals/tty7.js +58 -0
  117. package/dist/terminal/terminals/vscode.d.ts +2 -0
  118. package/dist/terminal/terminals/vscode.js +13 -0
  119. package/dist/terminal/terminals/wezterm.d.ts +2 -0
  120. package/dist/terminal/terminals/wezterm.js +59 -0
  121. package/dist/theme.d.ts +22 -0
  122. package/dist/theme.js +40 -0
  123. package/dist/web/browser-session.d.ts +13 -0
  124. package/dist/web/browser-session.js +186 -0
  125. package/dist/web/cursor.d.ts +1 -0
  126. package/dist/web/cursor.js +24 -0
  127. package/dist/web/devtools.d.ts +39 -0
  128. package/dist/web/devtools.js +300 -0
  129. package/dist/web/favicon.d.ts +7 -0
  130. package/dist/web/favicon.js +73 -0
  131. package/dist/web/frame-rate.d.ts +1 -0
  132. package/dist/web/frame-rate.js +12 -0
  133. package/dist/web/host.d.ts +123 -0
  134. package/dist/web/host.js +573 -0
  135. package/dist/web/input.d.ts +49 -0
  136. package/dist/web/input.js +468 -0
  137. package/dist/web/offscreen.d.ts +2 -0
  138. package/dist/web/offscreen.js +23 -0
  139. package/dist/web/paint.d.ts +11 -0
  140. package/dist/web/paint.js +128 -0
  141. package/dist/web/popup.d.ts +40 -0
  142. package/dist/web/popup.js +144 -0
  143. package/dist/web/session.d.ts +20 -0
  144. package/dist/web/session.js +110 -0
  145. package/dist/web/types.d.ts +38 -0
  146. package/dist/web/types.js +39 -0
  147. package/dist/web/zoom.d.ts +5 -0
  148. package/dist/web/zoom.js +36 -0
  149. package/dist/webview.d.ts +55 -0
  150. package/dist/webview.js +481 -0
  151. package/package.json +69 -3
  152. package/scripts/apparmor.sh +71 -0
  153. package/scripts/postinstall.mjs +150 -0
package/dist/bin.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/bin.js ADDED
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const node_child_process_1 = require("node:child_process");
8
+ const node_fs_1 = __importDefault(require("node:fs"));
9
+ const node_os_1 = __importDefault(require("node:os"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const instances_1 = require("./instances");
12
+ const sandbox_1 = require("./sandbox");
13
+ const terminal_1 = require("./terminal");
14
+ function fail(message) {
15
+ process.stderr.write(`pixel: ${message}\n`);
16
+ process.exit(1);
17
+ }
18
+ function resolveEntry(given) {
19
+ const target = node_path_1.default.resolve(given);
20
+ if (node_fs_1.default.existsSync(target) && node_fs_1.default.statSync(target).isDirectory()) {
21
+ const manifest = node_path_1.default.join(target, "package.json");
22
+ let main = "index.js";
23
+ if (node_fs_1.default.existsSync(manifest)) {
24
+ const parsed = JSON.parse(node_fs_1.default.readFileSync(manifest, "utf8"));
25
+ if (parsed.main)
26
+ main = parsed.main;
27
+ }
28
+ const entry = node_path_1.default.join(target, main);
29
+ if (!node_fs_1.default.existsSync(entry)) {
30
+ fail(`[placeholder copy: ${entry} does not exist. Build your app or point "main" in package.json at the built entry.]`);
31
+ }
32
+ return entry;
33
+ }
34
+ if (!node_fs_1.default.existsSync(target))
35
+ fail(`[placeholder copy: no such file ${target}]`);
36
+ return target;
37
+ }
38
+ function appName(dir) {
39
+ try {
40
+ const parsed = JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.join(dir, "package.json"), "utf8"));
41
+ if (parsed.name)
42
+ return parsed.name.replace(/^@/, "").replace("/", "-");
43
+ }
44
+ catch { }
45
+ return node_path_1.default.basename(dir);
46
+ }
47
+ function appDir(entry) {
48
+ for (let dir = node_path_1.default.dirname(entry);; dir = node_path_1.default.dirname(dir)) {
49
+ if (node_fs_1.default.existsSync(node_path_1.default.join(dir, "package.json")))
50
+ return dir;
51
+ if (node_path_1.default.dirname(dir) === dir)
52
+ return node_path_1.default.dirname(entry);
53
+ }
54
+ }
55
+ function electronBinary() {
56
+ const dist = node_path_1.default.resolve(__dirname, "..", "electron", "dist");
57
+ if (!node_fs_1.default.existsSync(node_path_1.default.join(dist, ".zenbu-electron-sha256"))) {
58
+ fail("[placeholder copy: the patched electron build is not installed. Run `node node_modules/@zenbu-labs/pixel/scripts/postinstall.mjs` (npm normally runs it for you on install).]");
59
+ }
60
+ return process.platform === "darwin"
61
+ ? node_path_1.default.join(dist, "Electron.app", "Contents", "MacOS", "pixel")
62
+ : node_path_1.default.join(dist, "pixel");
63
+ }
64
+ function logFile(appDir) {
65
+ const state = process.env.XDG_STATE_HOME ?? node_path_1.default.join(node_os_1.default.homedir(), ".local", "state");
66
+ const dir = node_path_1.default.join(state, "pixel", "logs");
67
+ node_fs_1.default.mkdirSync(dir, { recursive: true });
68
+ return node_path_1.default.join(dir, `${node_path_1.default.basename(appDir)}.stderr.log`);
69
+ }
70
+ function ownTty() {
71
+ try {
72
+ const out = (0, node_child_process_1.execFileSync)("tty", { stdio: ["inherit", "pipe", "ignore"], encoding: "utf8" }).trim();
73
+ if (out.startsWith("/dev/"))
74
+ return out;
75
+ }
76
+ catch { }
77
+ return fail("[placeholder copy: could not work out which tty this shell is on]");
78
+ }
79
+ async function main() {
80
+ const args = process.argv.slice(2);
81
+ const passthrough = args.indexOf("--");
82
+ const own = passthrough < 0 ? args : args.slice(0, passthrough);
83
+ const appArgs = passthrough < 0 ? [] : args.slice(passthrough + 1);
84
+ if (own.includes("--help") || own.includes("-h")) {
85
+ process.stdout.write("[placeholder copy: usage: pixel [entry|dir] [-- app args]\n Runs an app's main file inside the pixel runtime, in this terminal pane.]\n");
86
+ return 0;
87
+ }
88
+ const stray = own.slice(1).find((arg) => arg.startsWith("-")) ?? own.find((arg) => arg.startsWith("-"));
89
+ if (stray) {
90
+ fail(`[placeholder copy: unknown option ${stray}. pixel takes an entry and nothing else; put your app's arguments after --]`);
91
+ }
92
+ if (own.length > 1)
93
+ fail(`[placeholder copy: unexpected ${own[1]}; put your app's arguments after --]`);
94
+ const entry = resolveEntry(own[0] ?? ".");
95
+ const tty = process.env.PIXEL_TTY ?? ownTty();
96
+ const owner = (0, instances_1.findOwner)(tty);
97
+ const announced = owner ? (0, instances_1.announceGuest)(owner, appName(appDir(entry))) : null;
98
+ if (!owner && !process.env.PIXEL_EMBED) {
99
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
100
+ fail("[placeholder copy: pixel draws into the terminal, so it needs to run on a tty]");
101
+ }
102
+ const check = await (0, terminal_1.checkTerminal)((0, terminal_1.detect)());
103
+ if (check.graphics === "unsupported") {
104
+ process.stderr.write((0, terminal_1.unsupportedGraphicsMessage)(process.stderr.isTTY === true));
105
+ return 1;
106
+ }
107
+ }
108
+ const electron = electronBinary();
109
+ const chromiumArgs = [];
110
+ if (process.platform === "linux") {
111
+ let sandboxError = (0, sandbox_1.linuxSandboxError)(electron);
112
+ if (sandboxError) {
113
+ (0, sandbox_1.apparmorSetup)(electron);
114
+ sandboxError = (0, sandbox_1.linuxSandboxError)(electron);
115
+ }
116
+ if (sandboxError)
117
+ fail(sandboxError);
118
+ // headless ozone reports a 1x1 screen unless told otherwise:
119
+ // https://source.chromium.org/chromium/chromium/src/+/refs/tags/150.0.7871.212:ui/ozone/platform/headless/headless_screen.cc;l=37-46
120
+ if (!process.env.DISPLAY && !process.env.WAYLAND_DISPLAY) {
121
+ chromiumArgs.push("--ozone-platform=headless", "--screen-info={8192x8192}");
122
+ }
123
+ }
124
+ const bootstrap = node_path_1.default.join(__dirname, "bootstrap.js");
125
+ const env = { ...process.env };
126
+ delete env.ELECTRON_RUN_AS_NODE;
127
+ env.PIXEL_TTY = tty;
128
+ if (announced)
129
+ env.PIXEL_PANE = announced.pane;
130
+ else
131
+ delete env.PIXEL_PANE;
132
+ const stderr = node_fs_1.default.openSync(logFile(appDir(entry)), "a");
133
+ const child = (0, node_child_process_1.spawn)(electron, [bootstrap, entry, ...chromiumArgs, ...appArgs], {
134
+ stdio: ["inherit", "inherit", stderr],
135
+ env,
136
+ });
137
+ const forward = (signal) => () => {
138
+ try {
139
+ child.kill(signal);
140
+ }
141
+ catch { }
142
+ setTimeout(() => {
143
+ try {
144
+ child.kill("SIGKILL");
145
+ }
146
+ catch { }
147
+ }, 2000).unref();
148
+ };
149
+ for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"])
150
+ process.on(signal, forward(signal));
151
+ const exited = await new Promise((resolve) => {
152
+ child.on("error", (error) => {
153
+ process.stderr.write(`pixel: could not start electron: ${error.message}\n`);
154
+ resolve(1);
155
+ });
156
+ child.on("exit", (code, signal) => resolve(code ?? (signal ? 128 : 0)));
157
+ });
158
+ await (0, instances_1.waitForOwners)(tty);
159
+ return exited;
160
+ }
161
+ void main().then((code) => process.exit(code), (error) => fail(error instanceof Error ? error.message : String(error)));
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_fs_1 = __importDefault(require("node:fs"));
7
+ const node_net_1 = __importDefault(require("node:net"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const electron_1 = require("electron");
10
+ const debug_1 = require("./debug");
11
+ const entry = process.argv[2];
12
+ if (!entry) {
13
+ process.stderr.write("pixel bootstrap: missing entry path\n");
14
+ electron_1.app.exit(2);
15
+ }
16
+ function appName() {
17
+ for (let dir = node_path_1.default.dirname(node_path_1.default.resolve(entry));; dir = node_path_1.default.dirname(dir)) {
18
+ const candidate = node_path_1.default.join(dir, "package.json");
19
+ if (node_fs_1.default.existsSync(candidate)) {
20
+ try {
21
+ const name = JSON.parse(node_fs_1.default.readFileSync(candidate, "utf8")).name;
22
+ if (name)
23
+ return name.replace(/^@/, "").replace("/", "-");
24
+ }
25
+ catch { }
26
+ }
27
+ if (node_path_1.default.dirname(dir) === dir)
28
+ return "pixel-app";
29
+ }
30
+ }
31
+ function freePort() {
32
+ return new Promise((resolve) => {
33
+ const probe = node_net_1.default.createServer();
34
+ probe.once("error", () => resolve(null));
35
+ probe.listen(0, "127.0.0.1", () => {
36
+ const address = probe.address();
37
+ probe.close(() => resolve(address && typeof address === "object" ? address.port : null));
38
+ });
39
+ });
40
+ }
41
+ process.on("uncaughtException", (error) => {
42
+ process.stderr.write(`pixel: uncaught exception: ${error instanceof Error ? error.stack : String(error)}\n`);
43
+ electron_1.app.exit(1);
44
+ });
45
+ process.on("unhandledRejection", (reason) => {
46
+ process.stderr.write(`pixel: unhandled rejection: ${reason instanceof Error ? reason.stack : String(reason)}\n`);
47
+ });
48
+ electron_1.app.setName(appName());
49
+ electron_1.app.commandLine.appendSwitch("disable-renderer-backgrounding");
50
+ electron_1.app.commandLine.appendSwitch("disable-background-timer-throttling");
51
+ electron_1.app.commandLine.appendSwitch("disable-backgrounding-occluded-windows");
52
+ if (process.env.PIXEL_DISABLE_GPU === "1")
53
+ electron_1.app.commandLine.appendSwitch("disable-gpu");
54
+ try {
55
+ const logs = electron_1.app.getPath("logs");
56
+ node_fs_1.default.mkdirSync(logs, { recursive: true });
57
+ electron_1.app.commandLine.appendSwitch("enable-logging", "file");
58
+ electron_1.app.commandLine.appendSwitch("log-file", node_path_1.default.join(logs, "chromium.log"));
59
+ }
60
+ catch { }
61
+ void (async () => {
62
+ const port = await freePort();
63
+ if (port != null)
64
+ electron_1.app.commandLine.appendSwitch("remote-debugging-port", String(port));
65
+ await electron_1.app.whenReady();
66
+ (0, debug_1.debug)("bootstrap", { entry, tty: process.env.PIXEL_TTY ?? null });
67
+ if (process.platform === "darwin")
68
+ electron_1.app.dock?.hide();
69
+ const chromiumSwitch = (arg) => arg.startsWith("--ozone-platform=") || arg.startsWith("--screen-info=");
70
+ process.argv = [process.argv[0], node_path_1.default.resolve(entry), ...process.argv.slice(3).filter((arg) => !chromiumSwitch(arg))];
71
+ require(node_path_1.default.resolve(entry));
72
+ })().catch((error) => {
73
+ process.stderr.write(`${error instanceof Error ? error.stack : String(error)}\n`);
74
+ electron_1.app.exit(1);
75
+ });
@@ -0,0 +1,20 @@
1
+ import type { Theme } from "./theme";
2
+ export interface MenuItem {
3
+ id: string;
4
+ label: string;
5
+ enabled: boolean;
6
+ shortcut: string;
7
+ }
8
+ export declare function ContextMenu({ x, y, bounds, items, rem, theme, onAction, onClose, }: {
9
+ x: number;
10
+ y: number;
11
+ bounds: {
12
+ width: number;
13
+ height: number;
14
+ };
15
+ items: MenuItem[];
16
+ rem: number;
17
+ theme: Theme;
18
+ onAction(id: string): void;
19
+ onClose(): void;
20
+ }): import("react").JSX.Element;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContextMenu = ContextMenu;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("./react");
6
+ function ContextMenu({ x, y, bounds, items, rem, theme, onAction, onClose, }) {
7
+ const rowH = Math.round(rem * 1.55);
8
+ const charW = rem * 0.82 * 0.6;
9
+ const shortcutW = rem * 0.72 * 0.6;
10
+ const width = Math.round(items.reduce((widest, item) => {
11
+ let row = rem * 1.4 + item.label.length * charW;
12
+ if (item.shortcut)
13
+ row += rem * 0.6 + item.shortcut.length * shortcutW;
14
+ return Math.max(widest, row);
15
+ }, rem * 9));
16
+ const height = items.length * rowH;
17
+ const left = Math.max(2, Math.min(x, bounds.width - width - 4));
18
+ const top = Math.max(2, Math.min(y, bounds.height - height - 4));
19
+ return ((0, jsx_runtime_1.jsx)(react_1.Box, { style: {
20
+ position: "absolute",
21
+ inset: { top, left },
22
+ width,
23
+ flexDirection: "column",
24
+ background: theme.field,
25
+ cornerRadius: rem * 0.45,
26
+ border: { width: 1, color: theme.fieldBorder },
27
+ overflow: "hidden",
28
+ }, onClickOutside: onClose, children: items.map((item, i) => ((0, jsx_runtime_1.jsx)(MenuRow, { item: item, rowH: rowH, rem: rem, theme: theme, onAction: onAction, first: i === 0, last: i === items.length - 1 }, item.id))) }));
29
+ }
30
+ function MenuRow({ item, rowH, rem, theme, onAction, first, last, }) {
31
+ const radius = Math.max(2, rem * 0.45 - 1);
32
+ return ((0, jsx_runtime_1.jsxs)(react_1.Box, { style: {
33
+ height: rowH,
34
+ alignItems: "center",
35
+ padding: { left: rem * 0.7, right: rem * 0.7 },
36
+ hoverBackground: item.enabled ? theme.hover : undefined,
37
+ cornerRadius: {
38
+ topLeft: first ? radius : 0,
39
+ topRight: first ? radius : 0,
40
+ bottomLeft: last ? radius : 0,
41
+ bottomRight: last ? radius : 0,
42
+ },
43
+ flexShrink: 0,
44
+ }, onClick: item.enabled ? () => onAction(item.id) : undefined, children: [(0, jsx_runtime_1.jsx)(react_1.Text, { style: {
45
+ flexGrow: 1,
46
+ flexBasis: 0,
47
+ fontSize: rem * 0.82,
48
+ color: item.enabled ? theme.fg : theme.disabled,
49
+ wrap: false,
50
+ selectable: false,
51
+ }, children: item.label }), item.shortcut && ((0, jsx_runtime_1.jsx)(react_1.Text, { style: {
52
+ fontSize: rem * 0.72,
53
+ color: item.enabled ? theme.muted : theme.disabled,
54
+ wrap: false,
55
+ selectable: false,
56
+ }, children: item.shortcut }))] }));
57
+ }
@@ -0,0 +1 @@
1
+ export declare function debug(...parts: unknown[]): void;
package/dist/debug.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.debug = debug;
4
+ const enabled = process.env.PIXEL_DEBUG === "1";
5
+ function debug(...parts) {
6
+ if (!enabled)
7
+ return;
8
+ process.stderr.write(`[pixel] ${parts.map((p) => (typeof p === "string" ? p : JSON.stringify(p))).join(" ")}\n`);
9
+ }
@@ -0,0 +1,21 @@
1
+ import type { DevtoolsDock } from "./web/types";
2
+ export interface Rect {
3
+ x: number;
4
+ y: number;
5
+ width: number;
6
+ height: number;
7
+ }
8
+ export interface DevtoolsPlacement {
9
+ dock: DevtoolsDock;
10
+ fraction: number;
11
+ }
12
+ export declare function clampDevtoolsFraction(value: number): number;
13
+ export declare function dividerFraction(page: Rect, devtools: Rect & {
14
+ dock: DevtoolsDock;
15
+ }, x: number, y: number): number;
16
+ export declare function splitForDevtools(page: Rect, placement: DevtoolsPlacement | null, gap: number): {
17
+ page: Rect;
18
+ devtools: (Rect & {
19
+ dock: DevtoolsDock;
20
+ }) | null;
21
+ };
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clampDevtoolsFraction = clampDevtoolsFraction;
4
+ exports.dividerFraction = dividerFraction;
5
+ exports.splitForDevtools = splitForDevtools;
6
+ function clampDevtoolsFraction(value) {
7
+ return Math.max(0.15, Math.min(0.85, value));
8
+ }
9
+ function dividerFraction(page, devtools, x, y) {
10
+ const fraction = devtools.dock === "bottom"
11
+ ? (devtools.y + devtools.height - y) / (devtools.y + devtools.height - page.y)
12
+ : (devtools.x + devtools.width - x) / (devtools.x + devtools.width - page.x);
13
+ return clampDevtoolsFraction(fraction);
14
+ }
15
+ function splitForDevtools(page, placement, gap) {
16
+ if (!placement)
17
+ return { page, devtools: null };
18
+ const fraction = clampDevtoolsFraction(placement.fraction);
19
+ if (placement.dock === "bottom") {
20
+ const devtoolsHeight = Math.round(page.height * fraction);
21
+ const pageHeight = Math.max(1, page.height - devtoolsHeight - gap);
22
+ return {
23
+ page: { ...page, height: pageHeight },
24
+ devtools: {
25
+ x: page.x,
26
+ y: page.y + pageHeight + gap,
27
+ width: page.width,
28
+ height: Math.max(1, devtoolsHeight),
29
+ dock: "bottom",
30
+ },
31
+ };
32
+ }
33
+ const devtoolsWidth = Math.round(page.width * fraction);
34
+ const pageWidth = Math.max(1, page.width - devtoolsWidth - gap);
35
+ return {
36
+ page: { ...page, width: pageWidth },
37
+ devtools: {
38
+ x: page.x + pageWidth + gap,
39
+ y: page.y,
40
+ width: Math.max(1, devtoolsWidth),
41
+ height: page.height,
42
+ dock: "right",
43
+ },
44
+ };
45
+ }
@@ -0,0 +1,33 @@
1
+ import type { RefObject } from "react";
2
+ import type { Rect } from "./devtools-layout";
3
+ import type { DragEvent, PointerEvent, Style, Surface, WheelEvent } from "./react";
4
+ import type { Theme } from "./theme";
5
+ import type { DevtoolsDock } from "./web/types";
6
+ import type { WebViewHandle } from "./webview";
7
+ export declare function DevtoolsDockPane({ rect, dock, rem, theme, surface, dividerEngaged, onPointer, onWheel, onHover, onDividerDrag, onDividerHover, }: {
8
+ rect: Rect;
9
+ dock: DevtoolsDock;
10
+ rem: number;
11
+ theme: Theme;
12
+ surface: Surface;
13
+ dividerEngaged: boolean;
14
+ onPointer(event: PointerEvent): void;
15
+ onWheel(event: WheelEvent): void;
16
+ onHover(hovering: boolean): void;
17
+ onDividerDrag(event: DragEvent): void;
18
+ onDividerHover(hovering: boolean): void;
19
+ }): import("react").JSX.Element;
20
+ export interface DevToolsProps {
21
+ /** [placeholder copy: The WebView to inspect, as the ref you gave it or the handle itself.] */
22
+ target: RefObject<WebViewHandle | null> | WebViewHandle;
23
+ style?: Style;
24
+ dock?: DevtoolsDock;
25
+ /** [placeholder copy: Devtools panel to show once open, for example "console" or "elements".] */
26
+ panel?: string;
27
+ /** [placeholder copy: The devtools toolbar asked to close or to dock elsewhere. Unmount or change dock in response.] */
28
+ onAction?(action: "close" | "dock-bottom" | "dock-right"): void;
29
+ /** [placeholder copy: Keep showing the last frame, stretched, while the pane changes size instead of clearing until devtools repaint. Defaults to true.] */
30
+ keepFrame?: boolean;
31
+ }
32
+ /** [placeholder copy: Renders a WebView's devtools wherever this sits in the tree. Mounting opens them, unmounting closes them.] */
33
+ export declare function DevTools({ target, style, dock, panel, onAction, keepFrame }: DevToolsProps): import("react").JSX.Element;
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DevtoolsDockPane = DevtoolsDockPane;
4
+ exports.DevTools = DevTools;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const layout_1 = require("./layout");
8
+ const react_2 = require("./react");
9
+ const registry_1 = require("./registry");
10
+ const types_1 = require("./web/types");
11
+ const DIVIDER_ACTIVE = [58, 96, 168, 255];
12
+ const DIVIDER_GRIP = [118, 122, 132, 255];
13
+ function DevtoolsDockPane({ rect, dock, rem, theme, surface, dividerEngaged, onPointer, onWheel, onHover, onDividerDrag, onDividerHover, }) {
14
+ const horizontal = dock === "bottom";
15
+ const grab = Math.max(8, Math.round(rem * 0.5));
16
+ const divider = horizontal
17
+ ? { x: rect.x, y: rect.y - grab + 2, width: rect.width, height: grab }
18
+ : { x: rect.x - grab + 2, y: rect.y, width: grab, height: rect.height };
19
+ const gripAlong = (offset) => horizontal
20
+ ? { top: Math.round(divider.height / 2) - 1, left: Math.round(divider.width / 2) + offset - 1 }
21
+ : { top: Math.round(divider.height / 2) + offset - 1, left: Math.round(divider.width / 2) - 1 };
22
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_2.Box, { surface: surface, style: {
23
+ position: "absolute",
24
+ inset: { top: rect.y, left: rect.x },
25
+ width: rect.width,
26
+ height: rect.height,
27
+ background: theme.bg,
28
+ }, onPointer: onPointer, onWheel: onWheel, onMouseEnter: () => onHover(true), onMouseLeave: () => onHover(false) }), (0, jsx_runtime_1.jsx)(react_2.Box, { style: {
29
+ position: "absolute",
30
+ inset: { top: divider.y, left: divider.x },
31
+ width: divider.width,
32
+ height: divider.height,
33
+ background: dividerEngaged ? [...DIVIDER_ACTIVE] : undefined,
34
+ cornerRadius: 2,
35
+ }, onDrag: onDividerDrag, onMouseEnter: () => onDividerHover(true), onMouseLeave: () => onDividerHover(false), children: [-7, 0, 7].map((offset) => ((0, jsx_runtime_1.jsx)(react_2.Box, { style: {
36
+ position: "absolute",
37
+ inset: gripAlong(offset),
38
+ width: 2,
39
+ height: 2,
40
+ cornerRadius: 1,
41
+ background: dividerEngaged ? [235, 238, 245, 255] : [...DIVIDER_GRIP],
42
+ } }, offset))) })] }));
43
+ }
44
+ function resolveEntry(target) {
45
+ const handle = "current" in target ? target.current : target;
46
+ return handle ? registry_1.handleEntries.get(handle) ?? null : null;
47
+ }
48
+ /** [placeholder copy: Renders a WebView's devtools wherever this sits in the tree. Mounting opens them, unmounting closes them.] */
49
+ function DevTools({ target, style, dock = "right", panel, onAction, keepFrame = true }) {
50
+ const registry = (0, react_1.useContext)(registry_1.RootContext);
51
+ if (!registry) {
52
+ throw new Error("[placeholder copy: <DevTools> has to be rendered by a root from pixel's createRoot()]");
53
+ }
54
+ const boxRef = (0, react_1.useRef)(null);
55
+ const rect = (0, layout_1.useNodeRect)(boxRef, registry);
56
+ const surface = (0, react_1.useRef)(null);
57
+ const opened = (0, react_1.useRef)(null);
58
+ const scale = registry.displayScale;
59
+ (0, react_1.useLayoutEffect)(() => {
60
+ surface.current = registry.root.createSurface();
61
+ return () => {
62
+ const entry = opened.current;
63
+ if (entry?.externalDevtools) {
64
+ entry.externalDevtools = false;
65
+ entry.externalDevtoolsAction = null;
66
+ entry.host?.closeDevtools();
67
+ }
68
+ opened.current = null;
69
+ surface.current?.close();
70
+ surface.current = null;
71
+ };
72
+ }, [registry]);
73
+ const size = rect ? (0, types_1.snapToCssGrid)(rect.width, rect.height, scale) : null;
74
+ (0, react_1.useEffect)(() => {
75
+ const entry = resolveEntry(target);
76
+ const host = entry?.host;
77
+ if (!entry || !host || !size || !surface.current)
78
+ return;
79
+ const layout = { x: 0, y: 0, width: size.width, height: size.height, scale };
80
+ if (opened.current !== entry && opened.current?.externalDevtools) {
81
+ opened.current.externalDevtools = false;
82
+ opened.current.host?.closeDevtools();
83
+ }
84
+ opened.current = entry;
85
+ entry.externalDevtoolsAction = (action) => onAction?.(action);
86
+ if (!host.devtools) {
87
+ entry.externalDevtools = true;
88
+ host.openDevtools(surface.current, layout, dock);
89
+ const opened = () => host.devtools;
90
+ if (panel)
91
+ opened()?.showPanel(panel);
92
+ return;
93
+ }
94
+ if (entry.externalDevtools)
95
+ host.devtools.resize(layout, { keepFrame });
96
+ });
97
+ (0, react_1.useEffect)(() => {
98
+ const host = resolveEntry(target)?.host;
99
+ if (panel && host?.devtools)
100
+ host.devtools.showPanel(panel);
101
+ }, [panel, target]);
102
+ (0, react_1.useEffect)(() => {
103
+ resolveEntry(target)?.host?.devtools?.setDock(dock);
104
+ }, [dock, target]);
105
+ const entry = resolveEntry(target);
106
+ return ((0, jsx_runtime_1.jsx)(react_2.Box, { ref: boxRef, style: { ...style, overflow: "hidden" }, children: size && surface.current && ((0, jsx_runtime_1.jsx)(react_2.Box, { surface: surface.current, style: {
107
+ position: "absolute",
108
+ inset: { top: 0, left: 0 },
109
+ width: size.width,
110
+ height: size.height,
111
+ cornerRadius: style?.cornerRadius,
112
+ }, onPointer: (event) => {
113
+ const host = entry?.host;
114
+ if (!entry || !host?.devtools)
115
+ return;
116
+ registry.focus(entry, "devtools");
117
+ host.devtools.input.pointer(event);
118
+ }, onWheel: (event) => {
119
+ const host = entry?.host;
120
+ if (!entry || !host?.devtools)
121
+ return;
122
+ registry.focus(entry, "devtools");
123
+ host.devtools.input.wheel(event);
124
+ }, onMouseEnter: () => registry.setPointerShape(entry?.host?.devtools?.cursorShape ?? "default"), onMouseLeave: () => registry.setPointerShape("default") })) }));
125
+ }
@@ -0,0 +1,3 @@
1
+ /// <reference path="../../electron/electron.d.ts" preserve="true" />
2
+ import electron = require("electron");
3
+ export = electron;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ /// <reference path="../../electron/electron.d.ts" preserve="true" />
3
+ const electron = require("electron");
4
+ module.exports = electron;
@@ -0,0 +1,5 @@
1
+ import type { Guest } from "./server";
2
+ export declare function GuestView({ guest, active }: {
3
+ guest: Guest;
4
+ active: boolean;
5
+ }): import("react").JSX.Element;