@hasna/browser 0.3.8 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -6,60 +6,39 @@ var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- function __accessProp(key) {
10
- return this[key];
11
- }
12
- var __toESMCache_node;
13
- var __toESMCache_esm;
14
9
  var __toESM = (mod, isNodeMode, target) => {
15
- var canCache = mod != null && typeof mod === "object";
16
- if (canCache) {
17
- var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
18
- var cached = cache.get(mod);
19
- if (cached)
20
- return cached;
21
- }
22
10
  target = mod != null ? __create(__getProtoOf(mod)) : {};
23
11
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
24
12
  for (let key of __getOwnPropNames(mod))
25
13
  if (!__hasOwnProp.call(to, key))
26
14
  __defProp(to, key, {
27
- get: __accessProp.bind(mod, key),
15
+ get: () => mod[key],
28
16
  enumerable: true
29
17
  });
30
- if (canCache)
31
- cache.set(mod, to);
32
18
  return to;
33
19
  };
20
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
34
21
  var __toCommonJS = (from) => {
35
- var entry = (__moduleCache ??= new WeakMap).get(from), desc;
22
+ var entry = __moduleCache.get(from), desc;
36
23
  if (entry)
37
24
  return entry;
38
25
  entry = __defProp({}, "__esModule", { value: true });
39
- if (from && typeof from === "object" || typeof from === "function") {
40
- for (var key of __getOwnPropNames(from))
41
- if (!__hasOwnProp.call(entry, key))
42
- __defProp(entry, key, {
43
- get: __accessProp.bind(from, key),
44
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
45
- });
46
- }
26
+ if (from && typeof from === "object" || typeof from === "function")
27
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
28
+ get: () => from[key],
29
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
30
+ }));
47
31
  __moduleCache.set(from, entry);
48
32
  return entry;
49
33
  };
50
- var __moduleCache;
51
34
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
52
- var __returnValue = (v) => v;
53
- function __exportSetter(name, newValue) {
54
- this[name] = __returnValue.bind(null, newValue);
55
- }
56
35
  var __export = (target, all) => {
57
36
  for (var name in all)
58
37
  __defProp(target, name, {
59
38
  get: all[name],
60
39
  enumerable: true,
61
40
  configurable: true,
62
- set: __exportSetter.bind(all, name)
41
+ set: (newValue) => all[name] = () => newValue
63
42
  });
64
43
  };
65
44
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
@@ -2177,11 +2156,11 @@ import { homedir as homedir4 } from "os";
2177
2156
  import { join as join4 } from "path";
2178
2157
  import { join as join6, dirname } from "path";
2179
2158
  import { homedir as homedir5, platform } from "os";
2180
- function __accessProp2(key) {
2159
+ function __accessProp(key) {
2181
2160
  return this[key];
2182
2161
  }
2183
- function __exportSetter2(name, newValue) {
2184
- this[name] = __returnValue2.bind(null, newValue);
2162
+ function __exportSetter(name, newValue) {
2163
+ this[name] = __returnValue.bind(null, newValue);
2185
2164
  }
2186
2165
  function translateSql(sql, dialect) {
2187
2166
  if (dialect === "sqlite")
@@ -3211,10 +3190,10 @@ class SyncProgressTracker {
3211
3190
  }
3212
3191
  }
3213
3192
  }
3214
- var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __toESMCache_node2, __toESMCache_esm2, __toESM2 = (mod, isNodeMode, target) => {
3193
+ var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __toESMCache_node, __toESMCache_esm, __toESM2 = (mod, isNodeMode, target) => {
3215
3194
  var canCache = mod != null && typeof mod === "object";
3216
3195
  if (canCache) {
3217
- var cache = isNodeMode ? __toESMCache_node2 ??= new WeakMap : __toESMCache_esm2 ??= new WeakMap;
3196
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
3218
3197
  var cached = cache.get(mod);
3219
3198
  if (cached)
3220
3199
  return cached;
@@ -3224,19 +3203,19 @@ var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __t
3224
3203
  for (let key of __getOwnPropNames2(mod))
3225
3204
  if (!__hasOwnProp2.call(to, key))
3226
3205
  __defProp2(to, key, {
3227
- get: __accessProp2.bind(mod, key),
3206
+ get: __accessProp.bind(mod, key),
3228
3207
  enumerable: true
3229
3208
  });
3230
3209
  if (canCache)
3231
3210
  cache.set(mod, to);
3232
3211
  return to;
3233
- }, __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue2 = (v) => v, __export2 = (target, all) => {
3212
+ }, __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue = (v) => v, __export2 = (target, all) => {
3234
3213
  for (var name in all)
3235
3214
  __defProp2(target, name, {
3236
3215
  get: all[name],
3237
3216
  enumerable: true,
3238
3217
  configurable: true,
3239
- set: __exportSetter2.bind(all, name)
3218
+ set: __exportSetter.bind(all, name)
3240
3219
  });
3241
3220
  }, __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), __require2, require_postgres_array, require_arrayParser, require_postgres_date, require_mutable, require_postgres_interval, require_postgres_bytea, require_textParsers, require_pg_int8, require_binaryParsers, require_builtins, require_pg_types, require_defaults, require_utils, require_utils_legacy, require_utils_webcrypto, require_utils2, require_cert_signatures, require_sasl, require_type_overrides, require_pg_connection_string, require_connection_parameters, require_result, require_query, require_messages, require_buffer_writer, require_serializer, require_buffer_reader, require_parser, require_dist, require_empty, require_stream, require_connection, require_split2, require_helper, require_lib, require_client, require_pg_pool, require_query2, require_client2, require_lib2, import_lib, Client, Pool, Connection, types, Query, DatabaseError, escapeIdentifier, escapeLiteral, Result, TypeOverrides, defaults, esm_default, init_esm, init_adapter, util, objectUtil, ZodParsedType, getParsedType = (data) => {
3242
3221
  const t = typeof data;
@@ -12653,6 +12632,89 @@ var init_bun_webview = __esm(() => {
12653
12632
  };
12654
12633
  });
12655
12634
 
12635
+ // src/engines/tui.ts
12636
+ import { execSync as execSync2, spawn as spawn2 } from "child_process";
12637
+ function isTuiAvailable() {
12638
+ try {
12639
+ execSync2("which ttyd", { stdio: "ignore" });
12640
+ return true;
12641
+ } catch {
12642
+ return false;
12643
+ }
12644
+ }
12645
+ async function findAvailablePort(startPort) {
12646
+ let port = startPort;
12647
+ for (let i = 0;i < 100; i++) {
12648
+ try {
12649
+ const resp = await fetch(`http://localhost:${port}`);
12650
+ port++;
12651
+ } catch {
12652
+ return port;
12653
+ }
12654
+ }
12655
+ throw new BrowserError("No available port found for ttyd", "TUI_PORT_EXHAUSTED");
12656
+ }
12657
+ async function waitForTtyd(port, timeoutMs = 1e4) {
12658
+ const start = Date.now();
12659
+ while (Date.now() - start < timeoutMs) {
12660
+ try {
12661
+ const resp = await fetch(`http://localhost:${port}`);
12662
+ if (resp.ok || resp.status === 200)
12663
+ return;
12664
+ } catch {}
12665
+ await new Promise((r) => setTimeout(r, 150));
12666
+ }
12667
+ throw new BrowserError(`ttyd did not start within ${timeoutMs}ms`, "TUI_TIMEOUT");
12668
+ }
12669
+ async function launchTui(command, options = {}) {
12670
+ if (!isTuiAvailable()) {
12671
+ throw new BrowserError("ttyd not found \u2014 install with: brew install ttyd", "TUI_NOT_AVAILABLE");
12672
+ }
12673
+ const port = await findAvailablePort(nextPort);
12674
+ nextPort = port + 1;
12675
+ const ttydProcess = spawn2("ttyd", ["--writable", "--port", String(port), "/bin/sh", "-c", command], {
12676
+ stdio: "ignore",
12677
+ detached: false
12678
+ });
12679
+ ttydProcess.on("error", (err) => {
12680
+ console.error(`[tui] ttyd process error: ${err.message}`);
12681
+ });
12682
+ try {
12683
+ await waitForTtyd(port);
12684
+ const viewport = options.viewport ?? { width: 1280, height: 720 };
12685
+ const browser = await launchPlaywright({
12686
+ headless: options.headless ?? true,
12687
+ viewport
12688
+ });
12689
+ const page = await getPage(browser, { viewport });
12690
+ await page.goto(`http://localhost:${port}`, {
12691
+ waitUntil: "domcontentloaded"
12692
+ });
12693
+ await page.waitForSelector(".xterm-screen", { timeout: 1e4 });
12694
+ return { ttydProcess, port, browser, page };
12695
+ } catch (err) {
12696
+ ttydProcess.kill();
12697
+ throw err;
12698
+ }
12699
+ }
12700
+ async function closeTui(session) {
12701
+ try {
12702
+ await session.page.close();
12703
+ } catch {}
12704
+ try {
12705
+ await session.browser.close();
12706
+ } catch {}
12707
+ try {
12708
+ session.ttydProcess.kill("SIGTERM");
12709
+ } catch {}
12710
+ }
12711
+ var DEFAULT_TTYD_PORT_START = 7780, nextPort;
12712
+ var init_tui = __esm(() => {
12713
+ init_types();
12714
+ init_playwright();
12715
+ nextPort = DEFAULT_TTYD_PORT_START;
12716
+ });
12717
+
12656
12718
  // src/engines/selector.ts
12657
12719
  function selectEngine(useCase, explicit) {
12658
12720
  if (explicit && explicit !== "auto")
@@ -12676,6 +12738,7 @@ var init_selector = __esm(() => {
12676
12738
  init_types();
12677
12739
  init_lightpanda();
12678
12740
  init_bun_webview();
12741
+ init_tui();
12679
12742
  ENGINE_MAP = {
12680
12743
  ["scrape" /* SCRAPE */]: "bun",
12681
12744
  ["extract_links" /* EXTRACT_LINKS */]: "bun",
@@ -12686,6 +12749,7 @@ var init_selector = __esm(() => {
12686
12749
  ["auth_flow" /* AUTH_FLOW */]: "playwright",
12687
12750
  ["multi_tab" /* MULTI_TAB */]: "playwright",
12688
12751
  ["record_replay" /* RECORD_REPLAY */]: "playwright",
12752
+ ["terminal_test" /* TERMINAL_TEST */]: "tui",
12689
12753
  ["network_monitor" /* NETWORK_MONITOR */]: "cdp",
12690
12754
  ["har_capture" /* HAR_CAPTURE */]: "cdp",
12691
12755
  ["perf_profile" /* PERF_PROFILE */]: "cdp",
@@ -14055,7 +14119,7 @@ async function createSession2(opts = {}) {
14055
14119
  try {
14056
14120
  cleanups2.push(setupDialogHandler(page2, session2.id));
14057
14121
  } catch {}
14058
- handles.set(session2.id, { browser: cdpBrowser, bunView: null, page: page2, engine: "cdp", cleanups: cleanups2, tokenBudget: { total: 0, used: 0 }, lastActivity: Date.now(), autoGallery: opts.autoGallery ?? false });
14122
+ handles.set(session2.id, { browser: cdpBrowser, bunView: null, tuiSession: null, page: page2, engine: "cdp", cleanups: cleanups2, tokenBudget: { total: 0, used: 0 }, lastActivity: Date.now(), autoGallery: opts.autoGallery ?? false });
14059
14123
  return { session: session2, page: page2 };
14060
14124
  }
14061
14125
  const engine = opts.engine === "auto" || !opts.engine ? selectEngine(opts.useCase ?? "spa_navigate" /* SPA_NAVIGATE */, opts.engine) : opts.engine;
@@ -14081,6 +14145,38 @@ async function createSession2(opts = {}) {
14081
14145
  browser = await connectLightpanda();
14082
14146
  const context = await browser.newContext({ viewport: opts.viewport ?? { width: 1280, height: 720 } });
14083
14147
  page = await context.newPage();
14148
+ } else if (resolvedEngine === "tui") {
14149
+ const command = opts.startUrl ?? "bash";
14150
+ const tuiSess = await launchTui(command, {
14151
+ headless: opts.headless ?? true,
14152
+ viewport: opts.viewport
14153
+ });
14154
+ browser = tuiSess.browser;
14155
+ page = tuiSess.page;
14156
+ const session2 = createSession({
14157
+ engine: "tui",
14158
+ projectId: opts.projectId,
14159
+ agentId: opts.agentId,
14160
+ startUrl: opts.startUrl,
14161
+ name: opts.name ?? "tui"
14162
+ });
14163
+ const cleanups2 = [];
14164
+ cleanups2.push(() => closeTui(tuiSess));
14165
+ if (opts.captureNetwork !== false) {
14166
+ try {
14167
+ cleanups2.push(enableNetworkLogging(page, session2.id));
14168
+ } catch {}
14169
+ }
14170
+ if (opts.captureConsole !== false) {
14171
+ try {
14172
+ cleanups2.push(enableConsoleCapture(page, session2.id));
14173
+ } catch {}
14174
+ }
14175
+ try {
14176
+ cleanups2.push(setupDialogHandler(page, session2.id));
14177
+ } catch {}
14178
+ handles.set(session2.id, { browser, bunView: null, tuiSession: tuiSess, page, engine: "tui", cleanups: cleanups2, tokenBudget: { total: 0, used: 0 }, lastActivity: Date.now(), autoGallery: opts.autoGallery ?? false });
14179
+ return { session: session2, page };
14084
14180
  } else {
14085
14181
  browser = await pool.acquire(opts.headless ?? true);
14086
14182
  if (opts.storageState) {
@@ -14151,7 +14247,7 @@ async function createSession2(opts = {}) {
14151
14247
  } catch {}
14152
14248
  }
14153
14249
  }
14154
- handles.set(session.id, { browser, bunView, page, engine: bunView ? "bun" : resolvedEngine, cleanups, tokenBudget: { total: 0, used: 0 }, lastActivity: Date.now(), autoGallery: opts.autoGallery ?? false });
14250
+ handles.set(session.id, { browser, bunView, tuiSession: null, page, engine: bunView ? "bun" : resolvedEngine, cleanups, tokenBudget: { total: 0, used: 0 }, lastActivity: Date.now(), autoGallery: opts.autoGallery ?? false });
14155
14251
  if (opts.startUrl) {
14156
14252
  try {
14157
14253
  if (bunView) {
@@ -14221,7 +14317,7 @@ async function closeSession2(sessionId) {
14221
14317
  try {
14222
14318
  await handle.bunView.close();
14223
14319
  } catch {}
14224
- } else {
14320
+ } else if (handle.tuiSession) {} else {
14225
14321
  try {
14226
14322
  await handle.page.context().close();
14227
14323
  } catch {}
@@ -14321,6 +14417,7 @@ var init_session = __esm(() => {
14321
14417
  init_lightpanda();
14322
14418
  init_bun_webview();
14323
14419
  init_selector();
14420
+ init_tui();
14324
14421
  init_network();
14325
14422
  init_console();
14326
14423
  init_stealth();
@@ -27481,7 +27578,7 @@ var init_helpers = __esm(() => {
27481
27578
  // src/mcp/sessions.ts
27482
27579
  function register4(server) {
27483
27580
  server.tool("browser_session_create", "Create a new browser session. If agent_id is set and already has an active session, returns the existing one (use force_new to override). If session_id is omitted on other tools, the single active session is auto-selected. Use cdp_url to attach to an already-running Chrome instance.", {
27484
- engine: exports_external2.enum(["playwright", "cdp", "lightpanda", "bun", "auto"]).optional().default("auto"),
27581
+ engine: exports_external2.enum(["playwright", "cdp", "lightpanda", "bun", "tui", "auto"]).optional().default("auto"),
27485
27582
  use_case: exports_external2.string().optional(),
27486
27583
  project_id: exports_external2.string().optional(),
27487
27584
  agent_id: exports_external2.string().optional(),
@@ -32218,7 +32315,7 @@ function register8(server) {
32218
32315
  max_pages: exports_external2.number().optional().default(50),
32219
32316
  same_domain: exports_external2.boolean().optional().default(true),
32220
32317
  project_id: exports_external2.string().optional(),
32221
- engine: exports_external2.enum(["playwright", "cdp", "lightpanda", "bun", "auto"]).optional().default("auto")
32318
+ engine: exports_external2.enum(["playwright", "cdp", "lightpanda", "bun", "tui", "auto"]).optional().default("auto")
32222
32319
  }, async ({ url, max_depth, max_pages, same_domain, project_id, engine }) => {
32223
32320
  try {
32224
32321
  const result = await crawl(url, {
@@ -32386,7 +32483,7 @@ function register9(server) {
32386
32483
  server.tool("browser_script_run", "Run a saved script asynchronously. Returns run_id immediately \u2014 poll with browser_script_status for step-by-step progress. Scripts combine browser actions + connector calls + AI reasoning. Works with any engine (Bun.WebView, Playwright, CDP).", {
32387
32484
  name: exports_external2.string().describe("Script name"),
32388
32485
  session_id: exports_external2.string().optional(),
32389
- engine: exports_external2.enum(["playwright", "cdp", "lightpanda", "bun", "auto"]).optional().default("auto"),
32486
+ engine: exports_external2.enum(["playwright", "cdp", "lightpanda", "bun", "tui", "auto"]).optional().default("auto"),
32390
32487
  variables: exports_external2.record(exports_external2.string()).optional().describe("Override script variables")
32391
32488
  }, async ({ name, session_id, engine, variables }) => {
32392
32489
  try {
@@ -32641,8 +32738,8 @@ import { join as join33 } from "path";
32641
32738
  import { existsSync as existsSync43, mkdirSync as mkdirSync4, readFileSync as readFileSync33, writeFileSync as writeFileSync33 } from "fs";
32642
32739
  import { homedir as homedir33 } from "os";
32643
32740
  import { join as join43 } from "path";
32644
- function __exportSetter3(name, newValue) {
32645
- this[name] = __returnValue3.bind(null, newValue);
32741
+ function __exportSetter2(name, newValue) {
32742
+ this[name] = __returnValue2.bind(null, newValue);
32646
32743
  }
32647
32744
  function isInMemoryDb(path) {
32648
32745
  return path === ":memory:" || path.startsWith("file::memory:");
@@ -35756,13 +35853,13 @@ function clearActiveModel() {
35756
35853
  delete config.activeModel;
35757
35854
  writeConfig(config);
35758
35855
  }
35759
- var __defProp3, __returnValue3 = (v) => v, __export3 = (target, all) => {
35856
+ var __defProp3, __returnValue2 = (v) => v, __export3 = (target, all) => {
35760
35857
  for (var name in all)
35761
35858
  __defProp3(target, name, {
35762
35859
  get: all[name],
35763
35860
  enumerable: true,
35764
35861
  configurable: true,
35765
- set: __exportSetter3.bind(all, name)
35862
+ set: __exportSetter2.bind(all, name)
35766
35863
  });
35767
35864
  }, __esm3 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), exports_database, MIGRATIONS, _db2 = null, init_database, AgentConflictError, EntityNotFoundError, MemoryNotFoundError, DuplicateMemoryError, MemoryExpiredError, InvalidScopeError, VersionConflictError, MemoryConflictError, OPENAI_EMBED_URL = "https://api.openai.com/v1/embeddings", EMBED_MODEL = "text-embedding-3-small", EMBED_DIMENSIONS = 1536, REDACTED = "[REDACTED]", SECRET_PATTERNS, _idCounter = 0, hookRegistry, INSTRUCTION_PATTERNS, PROMOTIONAL_PATTERNS, RECALL_PROMOTE_THRESHOLD = 3, CONFLICT_WINDOW_MS, MEMORY_WRITE_TTL = 30, MemoryLockConflictError, sessionFocus, STOP_WORDS, DEFAULT_CONFIG, VALID_SCOPES, VALID_CATEGORIES, defaultSyncAgents, DEFAULT_AUTO_MEMORY_CONFIG, MEMORY_EXTRACTION_SYSTEM_PROMPT = `You are a precise memory extraction engine for an AI agent.
35768
35865
  Given text, extract facts worth remembering as structured JSON.
@@ -37285,11 +37382,11 @@ import { randomUUID as randomUUID22 } from "crypto";
37285
37382
  import { readFileSync as readFileSync24, writeFileSync as writeFileSync7, mkdirSync as mkdirSync34 } from "fs";
37286
37383
  import { join as join44, dirname as dirname24 } from "path";
37287
37384
  import { homedir as homedir42 } from "os";
37288
- function __accessProp3(key) {
37385
+ function __accessProp2(key) {
37289
37386
  return this[key];
37290
37387
  }
37291
- function __exportSetter4(name, newValue) {
37292
- this[name] = __returnValue4.bind(null, newValue);
37388
+ function __exportSetter3(name, newValue) {
37389
+ this[name] = __returnValue3.bind(null, newValue);
37293
37390
  }
37294
37391
  function getDbPath3() {
37295
37392
  if (process.env.CONVERSATIONS_DB_PATH)
@@ -39274,10 +39371,10 @@ function getGraphStats() {
39274
39371
  map[r.relation] = r.c;
39275
39372
  return { total_edges: total, by_relation: map };
39276
39373
  }
39277
- var __create3, __getProtoOf3, __defProp4, __getOwnPropNames3, __getOwnPropDesc2, __hasOwnProp3, __toESMCache_node3, __toESMCache_esm3, __toESM3 = (mod, isNodeMode, target) => {
39374
+ var __create3, __getProtoOf3, __defProp4, __getOwnPropNames3, __getOwnPropDesc2, __hasOwnProp3, __toESMCache_node2, __toESMCache_esm2, __toESM3 = (mod, isNodeMode, target) => {
39278
39375
  var canCache = mod != null && typeof mod === "object";
39279
39376
  if (canCache) {
39280
- var cache = isNodeMode ? __toESMCache_node3 ??= new WeakMap : __toESMCache_esm3 ??= new WeakMap;
39377
+ var cache = isNodeMode ? __toESMCache_node2 ??= new WeakMap : __toESMCache_esm2 ??= new WeakMap;
39281
39378
  var cached = cache.get(mod);
39282
39379
  if (cached)
39283
39380
  return cached;
@@ -39287,7 +39384,7 @@ var __create3, __getProtoOf3, __defProp4, __getOwnPropNames3, __getOwnPropDesc2,
39287
39384
  for (let key of __getOwnPropNames3(mod))
39288
39385
  if (!__hasOwnProp3.call(to, key))
39289
39386
  __defProp4(to, key, {
39290
- get: __accessProp3.bind(mod, key),
39387
+ get: __accessProp2.bind(mod, key),
39291
39388
  enumerable: true
39292
39389
  });
39293
39390
  if (canCache)
@@ -39302,19 +39399,19 @@ var __create3, __getProtoOf3, __defProp4, __getOwnPropNames3, __getOwnPropDesc2,
39302
39399
  for (var key of __getOwnPropNames3(from))
39303
39400
  if (!__hasOwnProp3.call(entry, key))
39304
39401
  __defProp4(entry, key, {
39305
- get: __accessProp3.bind(from, key),
39402
+ get: __accessProp2.bind(from, key),
39306
39403
  enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable
39307
39404
  });
39308
39405
  }
39309
39406
  __moduleCache2.set(from, entry);
39310
39407
  return entry;
39311
- }, __moduleCache2, __commonJS3 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue4 = (v) => v, __export4 = (target, all) => {
39408
+ }, __moduleCache2, __commonJS3 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue3 = (v) => v, __export4 = (target, all) => {
39312
39409
  for (var name in all)
39313
39410
  __defProp4(target, name, {
39314
39411
  get: all[name],
39315
39412
  enumerable: true,
39316
39413
  configurable: true,
39317
- set: __exportSetter4.bind(all, name)
39414
+ set: __exportSetter3.bind(all, name)
39318
39415
  });
39319
39416
  }, exports_db, db = null, init_db = () => {}, require_react_development, require_react, cachedConfig = null, configLoadedAt = 0, CONFIG_CACHE_MS = 1e4, import_react, AGENT_NAMES, AGENT_ID_FILE, cachedAutoName = null, ONLINE_THRESHOLD_SECONDS = 60, CONFLICT_THRESHOLD_SECONDS, DEFAULT_LOCK_EXPIRY_MS, STALE_HEARTBEAT_SECONDS, STOPWORDS;
39320
39417
  var init_dist4 = __esm(() => {
@@ -41928,7 +42025,7 @@ import { existsSync as existsSync62 } from "fs";
41928
42025
  import { join as join62 } from "path";
41929
42026
  import { readFileSync as readFileSync43, statSync as statSync22 } from "fs";
41930
42027
  import { relative as relative2, resolve as resolve23, join as join72 } from "path";
41931
- import { execSync as execSync2 } from "child_process";
42028
+ import { execSync as execSync3 } from "child_process";
41932
42029
 
41933
42030
  class TodosClient {
41934
42031
  baseUrl;
@@ -46276,7 +46373,7 @@ function parseGitHubUrl(url) {
46276
46373
  return { owner: match[1], repo: match[2], number: parseInt(match[3], 10) };
46277
46374
  }
46278
46375
  function fetchGitHubIssue(owner, repo, number) {
46279
- const json2 = execSync2(`gh api repos/${owner}/${repo}/issues/${number}`, { encoding: "utf-8", timeout: 15000 });
46376
+ const json2 = execSync3(`gh api repos/${owner}/${repo}/issues/${number}`, { encoding: "utf-8", timeout: 15000 });
46280
46377
  const data = JSON.parse(json2);
46281
46378
  return {
46282
46379
  number: data.number,
@@ -49506,9 +49603,9 @@ ${entries.length} entries`));
49506
49603
  });
49507
49604
  program2.command("install-browser").description("Install a browser engine").option("--engine <engine>", "Engine to install: lightpanda|chromium", "chromium").action(async (opts) => {
49508
49605
  if (opts.engine === "chromium") {
49509
- const { execSync: execSync3 } = await import("child_process");
49606
+ const { execSync: execSync4 } = await import("child_process");
49510
49607
  console.log(chalk4.gray("Installing Chromium via Playwright..."));
49511
- execSync3("bunx playwright install chromium", { stdio: "inherit" });
49608
+ execSync4("bunx playwright install chromium", { stdio: "inherit" });
49512
49609
  console.log(chalk4.green("\u2713 Chromium installed"));
49513
49610
  } else if (opts.engine === "lightpanda") {
49514
49611
  console.log(chalk4.yellow("Lightpanda must be installed manually."));
@@ -49528,12 +49625,12 @@ ${entries.length} entries`));
49528
49625
  console.log(chalk4.gray(` PID: ${status.pid}, Port: ${status.port}, Sessions: ${status.sessions ?? "?"}`));
49529
49626
  return;
49530
49627
  }
49531
- const { spawn: spawn2 } = await import("child_process");
49628
+ const { spawn: spawn3 } = await import("child_process");
49532
49629
  const { writeFileSync: writeFileSync9, mkdirSync: mkdirSync17 } = await import("fs");
49533
49630
  const { dirname: dirname6 } = await import("path");
49534
49631
  const pidFile = getDaemonPidFile2();
49535
49632
  mkdirSync17(dirname6(pidFile), { recursive: true });
49536
- const child = spawn2(process.execPath, [import.meta.dir + "/../../server/index.js"], {
49633
+ const child = spawn3(process.execPath, [import.meta.dir + "/../../server/index.js"], {
49537
49634
  detached: true,
49538
49635
  stdio: "ignore",
49539
49636
  env: { ...process.env, BROWSER_SERVER_PORT: opts.port }
@@ -1 +1 @@
1
- {"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../../src/engines/selector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AA+B5C;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EAAE,aAAa,GACvB,aAAa,CAqBf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAOhE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CA0BnD"}
1
+ {"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../../src/engines/selector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAkC5C;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EAAE,aAAa,GACvB,aAAa,CAqBf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAQhE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CA4BnD"}
@@ -0,0 +1,49 @@
1
+ import { type ChildProcess } from "node:child_process";
2
+ import type { Browser, Page } from "playwright";
3
+ export interface TuiSession {
4
+ ttydProcess: ChildProcess;
5
+ port: number;
6
+ browser: Browser;
7
+ page: Page;
8
+ }
9
+ /**
10
+ * Check if ttyd is installed on this system.
11
+ */
12
+ export declare function isTuiAvailable(): boolean;
13
+ /**
14
+ * Launch a terminal app via ttyd and connect Playwright to it.
15
+ *
16
+ * @param command - The shell command to run (e.g. "htop", "npm start", "python app.py")
17
+ * @param options - Viewport and headless options
18
+ * @returns TuiSession with Playwright page connected to the ttyd web UI
19
+ */
20
+ export declare function launchTui(command: string, options?: {
21
+ headless?: boolean;
22
+ viewport?: {
23
+ width: number;
24
+ height: number;
25
+ };
26
+ }): Promise<TuiSession>;
27
+ /**
28
+ * Send keystrokes to the TUI app via the Playwright page.
29
+ * Types into the terminal's xterm.js input.
30
+ */
31
+ export declare function sendKeys(page: Page, keys: string): Promise<void>;
32
+ /**
33
+ * Send a special key (Enter, Escape, ArrowUp, etc.) to the TUI.
34
+ */
35
+ export declare function sendSpecialKey(page: Page, key: string): Promise<void>;
36
+ /**
37
+ * Get the visible text content from the terminal.
38
+ * Works with both canvas-based and DOM-based xterm.js renderers.
39
+ */
40
+ export declare function getTerminalText(page: Page): Promise<string>;
41
+ /**
42
+ * Wait for specific text to appear in the terminal output.
43
+ */
44
+ export declare function waitForTerminalText(page: Page, text: string, timeoutMs?: number): Promise<boolean>;
45
+ /**
46
+ * Close TUI session — kill ttyd and close Playwright.
47
+ */
48
+ export declare function closeTui(session: TuiSession): Promise<void>;
49
+ //# sourceMappingURL=tui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../../src/engines/tui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAYhD,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,YAAY,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAOxC;AAqCD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC,GACL,OAAO,CAAC,UAAU,CAAC,CAqDrB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAStE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3E;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBjE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,MAAe,GACzB,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAUjE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tui.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui.test.d.ts","sourceRoot":"","sources":["../../src/engines/tui.test.ts"],"names":[],"mappings":""}