@showrun/core 0.1.6 → 0.1.8

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.
@@ -59,6 +59,11 @@ export interface LaunchBrowserConfig {
59
59
  * Pack directory path for profile persistence
60
60
  */
61
61
  packPath?: string;
62
+ /**
63
+ * Direct user data directory override.
64
+ * When set, bypasses persistence resolution (sessionId/packPath).
65
+ */
66
+ userDataDir?: string;
62
67
  }
63
68
  /**
64
69
  * Launches a browser with the specified configuration
@@ -1 +1 @@
1
- {"version":3,"file":"browserLauncher.d.ts","sourceRoot":"","sources":["../src/browserLauncher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAY,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAGpF,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,OAAO,EAAE,cAAc,CAAC;IACxB;;OAEG;IACH,IAAI,EAAE,IAAI,CAAC;IACX;;OAEG;IACH,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB;;OAEG;IACH,MAAM,EAAE,aAAa,CAAC;IACtB;;OAEG;IACH,WAAW,EAAE,kBAAkB,CAAC;IAChC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC,CAqCxF;AA4HD;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAgBtF"}
1
+ {"version":3,"file":"browserLauncher.d.ts","sourceRoot":"","sources":["../src/browserLauncher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAY,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAGpF,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,OAAO,EAAE,cAAc,CAAC;IACxB;;OAEG;IACH,IAAI,EAAE,IAAI,CAAC;IACX;;OAEG;IACH,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB;;OAEG;IACH,MAAM,EAAE,aAAa,CAAC;IACtB;;OAEG;IACH,WAAW,EAAE,kBAAkB,CAAC;IAChC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC,CA0CxF;AA6JD;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAgBtF"}
@@ -18,16 +18,23 @@ export async function launchBrowser(config) {
18
18
  const { browserSettings = {}, headless = true, sessionId, packPath, } = config;
19
19
  const engine = browserSettings.engine ?? 'camoufox';
20
20
  let persistence = browserSettings.persistence ?? 'none';
21
- // Auto-upgrade to profile persistence when packPath has an existing .browser-profile/
22
- if (persistence === 'none' && packPath && existsSync(join(packPath, '.browser-profile'))) {
23
- persistence = 'profile';
21
+ // Use explicit userDataDir if provided, otherwise resolve from persistence settings
22
+ let userDataDir;
23
+ if (config.userDataDir) {
24
+ userDataDir = config.userDataDir;
25
+ persistence = 'profile'; // Treat explicit dir as profile persistence
26
+ }
27
+ else {
28
+ // Auto-upgrade to profile persistence when packPath has an existing .browser-profile/
29
+ if (persistence === 'none' && packPath && existsSync(join(packPath, '.browser-profile'))) {
30
+ persistence = 'profile';
31
+ }
32
+ userDataDir = resolveBrowserDataDir({
33
+ persistence,
34
+ sessionId,
35
+ packPath,
36
+ });
24
37
  }
25
- // Resolve user data directory based on persistence mode
26
- const userDataDir = resolveBrowserDataDir({
27
- persistence,
28
- sessionId,
29
- packPath,
30
- });
31
38
  if (engine === 'camoufox') {
32
39
  return launchCamoufox({
33
40
  headless,
@@ -81,6 +88,33 @@ async function launchChromium(config) {
81
88
  },
82
89
  };
83
90
  }
91
+ /**
92
+ * Ensures the Camoufox browser binary is downloaded.
93
+ * Auto-fetches on first use so `npx showrun dashboard` works as a one-liner.
94
+ */
95
+ async function ensureCamoufoxBrowser() {
96
+ try {
97
+ const pkgman = await import('camoufox-js/dist/pkgman.js');
98
+ const installDir = pkgman.INSTALL_DIR.toString();
99
+ // Check if browser is installed with a valid version file
100
+ if (existsSync(installDir)) {
101
+ try {
102
+ pkgman.installedVerStr();
103
+ return; // Already installed
104
+ }
105
+ catch {
106
+ // version.json missing or corrupt — re-fetch
107
+ }
108
+ }
109
+ console.log('[ShowRun] Camoufox browser not found. Downloading automatically...');
110
+ const fetcher = new pkgman.CamoufoxFetcher();
111
+ await fetcher.install();
112
+ }
113
+ catch (error) {
114
+ throw new Error('Failed to auto-download Camoufox browser. Try "npx camoufox-js fetch" manually. ' +
115
+ `Error: ${error instanceof Error ? error.message : String(error)}`);
116
+ }
117
+ }
84
118
  /**
85
119
  * Launches Camoufox browser (Firefox-based anti-detection)
86
120
  *
@@ -91,6 +125,8 @@ async function launchCamoufox(config) {
91
125
  const { headless, userDataDir, persistence } = config;
92
126
  // Desktop-only screen constraints to prevent mobile fingerprints
93
127
  const screen = { minWidth: 1024, minHeight: 768 };
128
+ // Ensure the camoufox browser binary is downloaded before launching
129
+ await ensureCamoufoxBrowser();
94
130
  // Dynamic import to avoid loading Camoufox when not needed
95
131
  let Camoufox;
96
132
  try {
package/dist/config.d.ts CHANGED
@@ -42,6 +42,7 @@ export interface ShowRunConfig {
42
42
  };
43
43
  collectionName?: string;
44
44
  };
45
+ taskpacksDir?: string;
45
46
  }
46
47
  export interface ResolvedConfigPaths {
47
48
  config: ShowRunConfig;
@@ -70,6 +71,12 @@ export declare function loadConfig(): ResolvedConfigPaths;
70
71
  * Apply config values to `process.env`, only setting vars that are not already present.
71
72
  */
72
73
  export declare function applyConfigToEnv(config: ShowRunConfig): void;
74
+ /**
75
+ * Update the global config.json with a set of env-var-name → value pairs.
76
+ * Creates the config directory and file if they don't exist.
77
+ * Only writes non-empty string values.
78
+ */
79
+ export declare function updateGlobalConfig(values: Record<string, string>): void;
73
80
  /**
74
81
  * Resolve a filename by searching local paths first (cwd, then ancestors),
75
82
  * then config directories (highest priority first).
@@ -81,6 +88,14 @@ export declare function resolveFilePath(filename: string): string | null;
81
88
  * Get the global config directory path for the current platform.
82
89
  */
83
90
  export declare function getGlobalConfigDir(): string;
91
+ /**
92
+ * Get the global data directory path for the current platform.
93
+ * Used for databases, run logs, and default taskpacks.
94
+ *
95
+ * Linux/macOS: $XDG_DATA_HOME/showrun (default ~/.local/share/showrun)
96
+ * Windows: %LOCALAPPDATA%\showrun (fallback %APPDATA%\showrun)
97
+ */
98
+ export declare function getGlobalDataDir(): string;
84
99
  /**
85
100
  * Ensure a system prompt file exists in a config directory.
86
101
  * If the prompt was found outside config dirs (e.g. repo root), copy it
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE;QACJ,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,iBAAiB,CAAC;QAC9B,MAAM,CAAC,EAAE,iBAAiB,CAAC;KAC5B,CAAC;IACF,KAAK,CAAC,EAAE;QACN,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC7B,CAAC;IACF,OAAO,CAAC,EAAE;QACR,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,0BAA0B,CAAC,EAAE,MAAM,CAAC;KACrC,CAAC;IACF,UAAU,CAAC,EAAE;QACX,WAAW,CAAC,EAAE;YACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,GAAG,CAAC,EAAE,MAAM,CAAC;YACb,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,UAAU,CAAC,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,SAAS,CAAC,EAAE;YACV,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;QACF,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,aAAa,CAAC;IACtB,sEAAsE;IACtE,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,yCAAyC;IACzC,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAID;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CA0BpD;AA0BD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CA4B7C;AAMD;;;GAGG;AACH,wBAAgB,UAAU,IAAI,mBAAmB,CAmBhD;AAqCD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAQ5D;AAID;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsB/D;AAID;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAS3C;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAmB1F;AAID;;;GAGG;AACH,wBAAgB,UAAU,IAAI,mBAAmB,CAShD;AAID,eAAO,MAAM,uBAAuB,EAAE,aAoBrC,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE;QACJ,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,iBAAiB,CAAC;QAC9B,MAAM,CAAC,EAAE,iBAAiB,CAAC;KAC5B,CAAC;IACF,KAAK,CAAC,EAAE;QACN,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC7B,CAAC;IACF,OAAO,CAAC,EAAE;QACR,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,0BAA0B,CAAC,EAAE,MAAM,CAAC;KACrC,CAAC;IACF,UAAU,CAAC,EAAE;QACX,WAAW,CAAC,EAAE;YACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,GAAG,CAAC,EAAE,MAAM,CAAC;YACb,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,UAAU,CAAC,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,SAAS,CAAC,EAAE;YACV,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;QACF,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,aAAa,CAAC;IACtB,sEAAsE;IACtE,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,yCAAyC;IACzC,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAID;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CA0BpD;AA0BD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CA4B7C;AAMD;;;GAGG;AACH,wBAAgB,UAAU,IAAI,mBAAmB,CAmBhD;AAqDD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAQ5D;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CA0BvE;AAID;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsB/D;AAID;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAS3C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAWzC;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAmB1F;AAID;;;GAGG;AACH,wBAAgB,UAAU,IAAI,mBAAmB,CAShD;AAID,eAAO,MAAM,uBAAuB,EAAE,aAoBrC,CAAC"}
package/dist/config.js CHANGED
@@ -12,7 +12,7 @@ import { existsSync, copyFileSync } from 'fs';
12
12
  import { resolve, join, parse as parsePath } from 'path';
13
13
  import { platform, homedir } from 'os';
14
14
  import { cwd } from 'process';
15
- import { ensureDir, readJsonFile } from './packUtils.js';
15
+ import { ensureDir, readJsonFile, atomicWrite } from './packUtils.js';
16
16
  // ── Deep merge helper ──────────────────────────────────────────────────────
17
17
  /**
18
18
  * Recursively merge `override` into `base`, returning a new object.
@@ -141,6 +141,7 @@ const CONFIG_TO_ENV = [
141
141
  { path: ['techniques', 'embedding', 'model'], envVar: 'EMBEDDING_MODEL' },
142
142
  { path: ['techniques', 'embedding', 'baseUrl'], envVar: 'EMBEDDING_BASE_URL' },
143
143
  { path: ['techniques', 'collectionName'], envVar: 'TECHNIQUES_COLLECTION' },
144
+ { path: ['taskpacksDir'], envVar: 'SHOWRUN_TASKPACKS_DIR' },
144
145
  ];
145
146
  function getNestedValue(obj, path) {
146
147
  let current = obj;
@@ -151,6 +152,20 @@ function getNestedValue(obj, path) {
151
152
  }
152
153
  return current;
153
154
  }
155
+ /**
156
+ * Set a value at a nested path in an object, creating intermediate objects as needed.
157
+ */
158
+ function setNestedValue(obj, path, value) {
159
+ let current = obj;
160
+ for (let i = 0; i < path.length - 1; i++) {
161
+ const key = path[i];
162
+ if (current[key] === undefined || current[key] === null || typeof current[key] !== 'object') {
163
+ current[key] = {};
164
+ }
165
+ current = current[key];
166
+ }
167
+ current[path[path.length - 1]] = value;
168
+ }
154
169
  /**
155
170
  * Apply config values to `process.env`, only setting vars that are not already present.
156
171
  */
@@ -164,6 +179,37 @@ export function applyConfigToEnv(config) {
164
179
  }
165
180
  }
166
181
  }
182
+ /**
183
+ * Update the global config.json with a set of env-var-name → value pairs.
184
+ * Creates the config directory and file if they don't exist.
185
+ * Only writes non-empty string values.
186
+ */
187
+ export function updateGlobalConfig(values) {
188
+ const globalDir = getGlobalConfigDir();
189
+ const configPath = join(globalDir, 'config.json');
190
+ ensureDir(globalDir);
191
+ let config;
192
+ if (existsSync(configPath)) {
193
+ try {
194
+ config = readJsonFile(configPath);
195
+ }
196
+ catch {
197
+ config = JSON.parse(JSON.stringify(DEFAULT_CONFIG_TEMPLATE));
198
+ }
199
+ }
200
+ else {
201
+ config = JSON.parse(JSON.stringify(DEFAULT_CONFIG_TEMPLATE));
202
+ }
203
+ for (const [envVar, value] of Object.entries(values)) {
204
+ if (!value)
205
+ continue;
206
+ const mapping = CONFIG_TO_ENV.find(m => m.envVar === envVar);
207
+ if (mapping) {
208
+ setNestedValue(config, mapping.path, value);
209
+ }
210
+ }
211
+ atomicWrite(configPath, JSON.stringify(config, null, 2) + '\n');
212
+ }
167
213
  // ── File resolution ────────────────────────────────────────────────────────
168
214
  /**
169
215
  * Resolve a filename by searching local paths first (cwd, then ancestors),
@@ -209,6 +255,27 @@ export function getGlobalConfigDir() {
209
255
  const xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');
210
256
  return join(xdgConfig, 'showrun');
211
257
  }
258
+ /**
259
+ * Get the global data directory path for the current platform.
260
+ * Used for databases, run logs, and default taskpacks.
261
+ *
262
+ * Linux/macOS: $XDG_DATA_HOME/showrun (default ~/.local/share/showrun)
263
+ * Windows: %LOCALAPPDATA%\showrun (fallback %APPDATA%\showrun)
264
+ */
265
+ export function getGlobalDataDir() {
266
+ const os = platform();
267
+ if (os === 'win32') {
268
+ const localAppData = process.env.LOCALAPPDATA;
269
+ if (localAppData)
270
+ return join(localAppData, 'showrun');
271
+ const appData = process.env.APPDATA;
272
+ if (appData)
273
+ return join(appData, 'showrun');
274
+ return join(homedir(), 'AppData', 'Local', 'showrun');
275
+ }
276
+ const xdgData = process.env.XDG_DATA_HOME || join(homedir(), '.local', 'share');
277
+ return join(xdgData, 'showrun');
278
+ }
212
279
  /**
213
280
  * Ensure a system prompt file exists in a config directory.
214
281
  * If the prompt was found outside config dirs (e.g. repo root), copy it
@@ -227,8 +294,8 @@ export function ensureSystemPromptInConfigDir(filename, sourcePath) {
227
294
  const destPath = join(globalDir, filename);
228
295
  ensureDir(globalDir);
229
296
  copyFileSync(sourcePath, destPath);
230
- console.log(`[Config] Created config directory at ${globalDir}`);
231
- console.log(`[Config] Copied ${filename} to ${destPath}`);
297
+ console.error(`[Config] Created config directory at ${globalDir}`);
298
+ console.error(`[Config] Copied ${filename} to ${destPath}`);
232
299
  return destPath;
233
300
  }
234
301
  // ── Main entry point ───────────────────────────────────────────────────────
@@ -240,7 +307,7 @@ export function initConfig() {
240
307
  const result = loadConfig();
241
308
  applyConfigToEnv(result.config);
242
309
  if (result.loadedFiles.length > 0) {
243
- console.log(`[Config] Loaded: ${result.loadedFiles.join(', ')}`);
310
+ console.error(`[Config] Loaded: ${result.loadedFiles.join(', ')}`);
244
311
  }
245
312
  return result;
246
313
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAc,MAAM,YAAY,CAAC;AAElE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAWzC;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CAmQ5B"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAc,MAAM,YAAY,CAAC;AAElE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAWzC;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CAqQ5B"}
package/dist/runner.js CHANGED
@@ -15,12 +15,14 @@ export async function runTaskPack(taskPack, inputs, options) {
15
15
  // Ensure directories exist
16
16
  mkdirSync(runDir, { recursive: true });
17
17
  mkdirSync(artifactsDir, { recursive: true });
18
- // Auto-detect if we can run headful (check for DISPLAY)
19
- // If headful was requested but no DISPLAY is available, fall back to headless
20
- const hasDisplay = !!process.env.DISPLAY;
18
+ // Auto-detect if we can run headful
19
+ // On Linux, a DISPLAY (X11) or WAYLAND_DISPLAY is required for headful mode.
20
+ // On macOS/Windows, native window management handles it — no env var needed.
21
+ const isLinux = process.platform === 'linux';
22
+ const hasDisplay = !isLinux || !!process.env.DISPLAY || !!process.env.WAYLAND_DISPLAY;
21
23
  const headless = requestedHeadless || !hasDisplay;
22
24
  if (!requestedHeadless && !hasDisplay) {
23
- console.error('[Warning] Headful mode requested but no DISPLAY environment variable found. ' +
25
+ console.error('[Warning] Headful mode requested but no DISPLAY/WAYLAND_DISPLAY environment variable found. ' +
24
26
  'Falling back to headless mode. Set DISPLAY or use xvfb-run to enable headful mode.');
25
27
  }
26
28
  const startTime = Date.now();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@showrun/core",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Core types and utilities for Task Pack framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",