New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

@cli4ai/lib

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cli4ai/lib - npm Package Compare versions

Comparing version
1.0.6
to
1.0.7
+131
browser.ts
/**
* Shared browser utilities for packages that depend on @cli4ai/chrome
* Auto-launches managed browser if not running
*/
import puppeteer, { Browser, Page } from 'puppeteer';
import { readFileSync, writeFileSync, existsSync, unlinkSync, mkdirSync } from 'fs';
import { join } from 'path';
import { homedir } from 'os';
// Persistent storage paths (same as chrome package)
const CLI4AI_DIR = join(homedir(), '.cli4ai');
const CHROME_DIR = join(CLI4AI_DIR, 'chrome');
const PROFILE_DIR = join(CHROME_DIR, 'profile');
const WS_FILE = join(CHROME_DIR, 'ws-endpoint');
const PID_FILE = join(CHROME_DIR, 'pid');
function ensureDirs() {
if (!existsSync(CLI4AI_DIR)) mkdirSync(CLI4AI_DIR, { recursive: true });
if (!existsSync(CHROME_DIR)) mkdirSync(CHROME_DIR, { recursive: true });
}
function isBrowserRunning(): boolean {
if (!existsSync(PID_FILE)) return false;
const pid = parseInt(readFileSync(PID_FILE, 'utf-8').trim(), 10);
try {
process.kill(pid, 0);
return true;
} catch {
cleanup();
return false;
}
}
function cleanup() {
if (existsSync(WS_FILE)) unlinkSync(WS_FILE);
if (existsSync(PID_FILE)) unlinkSync(PID_FILE);
}
async function launchBrowser(headless: boolean): Promise<Browser> {
ensureDirs();
const browser = await puppeteer.launch({
headless: headless ? 'shell' : false,
userDataDir: PROFILE_DIR,
args: [
'--no-first-run',
'--no-default-browser-check',
'--disable-infobars',
],
defaultViewport: null,
});
const wsEndpoint = browser.wsEndpoint();
writeFileSync(WS_FILE, wsEndpoint);
const browserProcess = browser.process();
if (browserProcess?.pid) {
writeFileSync(PID_FILE, String(browserProcess.pid));
}
return browser;
}
/**
* Get or create browser instance
* Auto-launches if not running
*/
export async function getBrowser(headless = false): Promise<Browser> {
if (isBrowserRunning() && existsSync(WS_FILE)) {
try {
const ws = readFileSync(WS_FILE, 'utf-8').trim();
return await puppeteer.connect({ browserWSEndpoint: ws });
} catch {
cleanup();
}
}
return launchBrowser(headless);
}
/**
* Get a page from the browser
*/
export async function getPage(browser: Browser, newTab = false): Promise<Page> {
if (newTab) {
return browser.newPage();
}
const pages = await browser.pages();
return pages[pages.length - 1] || browser.newPage();
}
/**
* Execute a function with a page, handling browser connection
*/
export async function withPage<T>(
fn: (page: Page) => Promise<T>,
options: { headless?: boolean; newTab?: boolean } = {}
): Promise<T> {
const browser = await getBrowser(options.headless ?? false);
const page = await getPage(browser, options.newTab ?? false);
try {
return await fn(page);
} finally {
browser.disconnect();
}
}
/**
* Execute a function with a new tab
*/
export async function withNewPage<T>(
fn: (page: Page) => Promise<T>,
headless = false
): Promise<T> {
const browser = await getBrowser(headless);
const page = await browser.newPage();
try {
return await fn(page);
} finally {
await page.close();
browser.disconnect();
}
}
/**
* Check if browser is currently running
*/
export function isRunning(): boolean {
return isBrowserRunning();
}
export { Browser, Page };
/**
* Shared browser utilities for packages that depend on @cli4ai/chrome
* Auto-launches managed browser if not running
*/
import { Browser, Page } from 'puppeteer';
/**
* Get or create browser instance
* Auto-launches if not running
*/
export declare function getBrowser(headless?: boolean): Promise<Browser>;
/**
* Get a page from the browser
*/
export declare function getPage(browser: Browser, newTab?: boolean): Promise<Page>;
/**
* Execute a function with a page, handling browser connection
*/
export declare function withPage<T>(fn: (page: Page) => Promise<T>, options?: {
headless?: boolean;
newTab?: boolean;
}): Promise<T>;
/**
* Execute a function with a new tab
*/
export declare function withNewPage<T>(fn: (page: Page) => Promise<T>, headless?: boolean): Promise<T>;
/**
* Check if browser is currently running
*/
export declare function isRunning(): boolean;
export { Browser, Page };
//# sourceMappingURL=browser.d.ts.map
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAkB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA2DrD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,QAAQ,UAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAUnE;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7E;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9B,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACrD,OAAO,CAAC,CAAC,CAAC,CAQZ;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9B,QAAQ,UAAQ,GACf,OAAO,CAAC,CAAC,CAAC,CASZ;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC"}
/**
* Shared browser utilities for packages that depend on @cli4ai/chrome
* Auto-launches managed browser if not running
*/
import puppeteer, { Browser, Page } from 'puppeteer';
import { readFileSync, writeFileSync, existsSync, unlinkSync, mkdirSync } from 'fs';
import { join } from 'path';
import { homedir } from 'os';
// Persistent storage paths (same as chrome package)
const CLI4AI_DIR = join(homedir(), '.cli4ai');
const CHROME_DIR = join(CLI4AI_DIR, 'chrome');
const PROFILE_DIR = join(CHROME_DIR, 'profile');
const WS_FILE = join(CHROME_DIR, 'ws-endpoint');
const PID_FILE = join(CHROME_DIR, 'pid');
function ensureDirs() {
if (!existsSync(CLI4AI_DIR))
mkdirSync(CLI4AI_DIR, { recursive: true });
if (!existsSync(CHROME_DIR))
mkdirSync(CHROME_DIR, { recursive: true });
}
function isBrowserRunning() {
if (!existsSync(PID_FILE))
return false;
const pid = parseInt(readFileSync(PID_FILE, 'utf-8').trim(), 10);
try {
process.kill(pid, 0);
return true;
}
catch {
cleanup();
return false;
}
}
function cleanup() {
if (existsSync(WS_FILE))
unlinkSync(WS_FILE);
if (existsSync(PID_FILE))
unlinkSync(PID_FILE);
}
async function launchBrowser(headless) {
ensureDirs();
const browser = await puppeteer.launch({
headless: headless ? 'shell' : false,
userDataDir: PROFILE_DIR,
args: [
'--no-first-run',
'--no-default-browser-check',
'--disable-infobars',
],
defaultViewport: null,
});
const wsEndpoint = browser.wsEndpoint();
writeFileSync(WS_FILE, wsEndpoint);
const browserProcess = browser.process();
if (browserProcess?.pid) {
writeFileSync(PID_FILE, String(browserProcess.pid));
}
return browser;
}
/**
* Get or create browser instance
* Auto-launches if not running
*/
export async function getBrowser(headless = false) {
if (isBrowserRunning() && existsSync(WS_FILE)) {
try {
const ws = readFileSync(WS_FILE, 'utf-8').trim();
return await puppeteer.connect({ browserWSEndpoint: ws });
}
catch {
cleanup();
}
}
return launchBrowser(headless);
}
/**
* Get a page from the browser
*/
export async function getPage(browser, newTab = false) {
if (newTab) {
return browser.newPage();
}
const pages = await browser.pages();
return pages[pages.length - 1] || browser.newPage();
}
/**
* Execute a function with a page, handling browser connection
*/
export async function withPage(fn, options = {}) {
const browser = await getBrowser(options.headless ?? false);
const page = await getPage(browser, options.newTab ?? false);
try {
return await fn(page);
}
finally {
browser.disconnect();
}
}
/**
* Execute a function with a new tab
*/
export async function withNewPage(fn, headless = false) {
const browser = await getBrowser(headless);
const page = await browser.newPage();
try {
return await fn(page);
}
finally {
await page.close();
browser.disconnect();
}
}
/**
* Check if browser is currently running
*/
export function isRunning() {
return isBrowserRunning();
}
export { Browser, Page };
+10
-3
{
"name": "@cli4ai/lib",
"version": "1.0.6",
"version": "1.0.7",
"description": "Shared CLI framework for cli4ai tools",
"author": "cliforai",
"license": "MIT",
"license": "BUSL-1.1",
"type": "module",

@@ -20,2 +20,7 @@ "main": "dist/cli.js",

"default": "./dist/cli.js"
},
"./browser.ts": {
"types": "./dist/browser.d.ts",
"import": "./dist/browser.js",
"default": "./dist/browser.js"
}

@@ -43,3 +48,4 @@ },

"dependencies": {
"commander": "^14.0.0"
"commander": "^14.0.0",
"puppeteer": "^24.0.0"
},

@@ -52,2 +58,3 @@ "devDependencies": {

"cli.ts",
"browser.ts",
"dist"

@@ -54,0 +61,0 @@ ],