| /** GitHub repository that publishes signed macbeth releases. */ | ||
| export declare const DEFAULT_REPO = "wende/macbeth"; | ||
| /** npm package name, used as the install fallback when no tarball asset exists. */ | ||
| export declare const PACKAGE_NAME = "macbeth"; | ||
| export interface ReleaseAsset { | ||
| name: string; | ||
| browser_download_url: string; | ||
| } | ||
| export interface ReleaseInfo { | ||
| /** Raw git tag, e.g. "v0.3.0". */ | ||
| tag: string; | ||
| /** Version with any leading "v" stripped, e.g. "0.3.0". */ | ||
| version: string; | ||
| /** Download URL of the packed npm tarball attached to the release, if any. */ | ||
| tarballUrl: string | null; | ||
| /** Human-facing release page. */ | ||
| htmlUrl: string; | ||
| } | ||
| /** | ||
| * Parse a version string into comparable numeric components. Any leading "v" | ||
| * and any pre-release/build suffix (`-beta.1`, `+meta`) are ignored — release | ||
| * tags in this repo are plain `vMAJOR.MINOR.PATCH`. | ||
| */ | ||
| export declare function parseVersion(input: string): number[]; | ||
| /** | ||
| * Compare two versions. Returns a negative number if `a < b`, zero if equal, | ||
| * and a positive number if `a > b`. Missing components are treated as 0 | ||
| * (`1.2` == `1.2.0`). | ||
| */ | ||
| export declare function compareVersions(a: string, b: string): number; | ||
| /** Read the installed package version from the bundled package.json. */ | ||
| export declare function readInstalledVersion(packageRoot?: string): string; | ||
| /** | ||
| * Fetch the most recent published (non-draft, non-prerelease) release for the | ||
| * repository from the GitHub REST API. | ||
| */ | ||
| export declare function fetchLatestRelease(repo?: string, fetchImpl?: typeof fetch): Promise<ReleaseInfo>; | ||
| /** | ||
| * Pick what to hand to `npm install -g`. Prefer the exact tarball published on | ||
| * the GitHub release (signed + notarized binaries); fall back to the npm | ||
| * registry pinned to the release version so the two sources stay in lockstep. | ||
| */ | ||
| export declare function resolveInstallSpec(release: ReleaseInfo): string; | ||
| export interface UpdateOptions { | ||
| repo?: string; | ||
| /** Report availability without installing. */ | ||
| check?: boolean; | ||
| /** Reinstall even when already on the latest version. */ | ||
| force?: boolean; | ||
| fetchImpl?: typeof fetch; | ||
| install?: (spec: string) => Promise<void>; | ||
| /** Override how the installed version is read (injectable for tests). */ | ||
| readVersion?: () => string; | ||
| } | ||
| /** | ||
| * Check GitHub for the newest release and, unless it is already installed, | ||
| * self-update via a global npm install of the release tarball. | ||
| * | ||
| * Returns the process exit code. | ||
| */ | ||
| export declare function runUpdate(argv?: string[], options?: UpdateOptions): Promise<number>; | ||
| //# sourceMappingURL=update.d.ts.map |
| {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AASA,gEAAgE;AAChE,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAC5C,mFAAmF;AACnF,eAAO,MAAM,YAAY,YAAY,CAAC;AAEtC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAMpD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAS5D;AAED,wEAAwE;AACxE,wBAAgB,oBAAoB,CAAC,WAAW,SAAe,GAAG,MAAM,CAOvE;AASD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,SAAe,EACnB,SAAS,GAAE,OAAO,KAAa,GAC9B,OAAO,CAAC,WAAW,CAAC,CAkCtB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAE/D;AA2BD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yDAAyD;IACzD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,IAAI,GAAE,MAAM,EAAO,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0DjG"} |
+171
| import { spawn } from "node:child_process"; | ||
| import { readFileSync } from "node:fs"; | ||
| import { dirname, resolve } from "node:path"; | ||
| import { fileURLToPath } from "node:url"; | ||
| const MODULE_DIR = dirname(fileURLToPath(import.meta.url)); | ||
| // dist/update.js lives one level below the package root (dist/ → package root). | ||
| const PACKAGE_ROOT = resolve(MODULE_DIR, ".."); | ||
| /** GitHub repository that publishes signed macbeth releases. */ | ||
| export const DEFAULT_REPO = "wende/macbeth"; | ||
| /** npm package name, used as the install fallback when no tarball asset exists. */ | ||
| export const PACKAGE_NAME = "macbeth"; | ||
| /** | ||
| * Parse a version string into comparable numeric components. Any leading "v" | ||
| * and any pre-release/build suffix (`-beta.1`, `+meta`) are ignored — release | ||
| * tags in this repo are plain `vMAJOR.MINOR.PATCH`. | ||
| */ | ||
| export function parseVersion(input) { | ||
| const core = input.trim().replace(/^v/i, "").split(/[-+]/, 1)[0]; | ||
| return core.split(".").map((part) => { | ||
| const n = Number.parseInt(part, 10); | ||
| return Number.isFinite(n) ? n : 0; | ||
| }); | ||
| } | ||
| /** | ||
| * Compare two versions. Returns a negative number if `a < b`, zero if equal, | ||
| * and a positive number if `a > b`. Missing components are treated as 0 | ||
| * (`1.2` == `1.2.0`). | ||
| */ | ||
| export function compareVersions(a, b) { | ||
| const pa = parseVersion(a); | ||
| const pb = parseVersion(b); | ||
| const len = Math.max(pa.length, pb.length); | ||
| for (let i = 0; i < len; i++) { | ||
| const diff = (pa[i] ?? 0) - (pb[i] ?? 0); | ||
| if (diff !== 0) | ||
| return diff < 0 ? -1 : 1; | ||
| } | ||
| return 0; | ||
| } | ||
| /** Read the installed package version from the bundled package.json. */ | ||
| export function readInstalledVersion(packageRoot = PACKAGE_ROOT) { | ||
| const pkgPath = resolve(packageRoot, "package.json"); | ||
| const pkg = JSON.parse(readFileSync(pkgPath, "utf8")); | ||
| if (!pkg.version) { | ||
| throw new Error(`No version field in ${pkgPath}`); | ||
| } | ||
| return pkg.version; | ||
| } | ||
| /** | ||
| * Fetch the most recent published (non-draft, non-prerelease) release for the | ||
| * repository from the GitHub REST API. | ||
| */ | ||
| export async function fetchLatestRelease(repo = DEFAULT_REPO, fetchImpl = fetch) { | ||
| const url = `https://api.github.com/repos/${repo}/releases/latest`; | ||
| const headers = { | ||
| Accept: "application/vnd.github+json", | ||
| "User-Agent": `${PACKAGE_NAME}-cli`, | ||
| "X-GitHub-Api-Version": "2022-11-28", | ||
| }; | ||
| // An optional token lifts the low unauthenticated rate limit and lets the | ||
| // update work against private forks. | ||
| const token = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN; | ||
| if (token) | ||
| headers.Authorization = `Bearer ${token}`; | ||
| const res = await fetchImpl(url, { headers }); | ||
| if (!res.ok) { | ||
| throw new Error(`GitHub API request failed: ${res.status} ${res.statusText} (${url})`); | ||
| } | ||
| const data = (await res.json()); | ||
| const tag = data.tag_name; | ||
| if (!tag) { | ||
| throw new Error(`No tag_name in latest release for ${repo}`); | ||
| } | ||
| const assets = data.assets ?? []; | ||
| const tarball = assets.find((a) => a.name.endsWith(".tgz")); | ||
| return { | ||
| tag, | ||
| version: tag.replace(/^v/i, ""), | ||
| tarballUrl: tarball?.browser_download_url ?? null, | ||
| htmlUrl: data.html_url ?? `https://github.com/${repo}/releases/tag/${tag}`, | ||
| }; | ||
| } | ||
| /** | ||
| * Pick what to hand to `npm install -g`. Prefer the exact tarball published on | ||
| * the GitHub release (signed + notarized binaries); fall back to the npm | ||
| * registry pinned to the release version so the two sources stay in lockstep. | ||
| */ | ||
| export function resolveInstallSpec(release) { | ||
| return release.tarballUrl ?? `${PACKAGE_NAME}@${release.version}`; | ||
| } | ||
| function log(message) { | ||
| process.stdout.write(`${message}\n`); | ||
| } | ||
| /** Run `npm install -g <spec>`, streaming npm's output through to the user. */ | ||
| function npmInstallGlobal(spec) { | ||
| return new Promise((resolvePromise, reject) => { | ||
| const npm = process.platform === "win32" ? "npm.cmd" : "npm"; | ||
| const child = spawn(npm, ["install", "-g", spec], { | ||
| stdio: "inherit", | ||
| }); | ||
| child.on("error", (err) => { | ||
| reject(new Error(`Failed to run npm (${err.message}). Install manually with: npm install -g ${spec}`)); | ||
| }); | ||
| child.on("exit", (code) => { | ||
| if (code === 0) | ||
| resolvePromise(); | ||
| else | ||
| reject(new Error(`npm install -g ${spec} exited with code ${code ?? "unknown"}`)); | ||
| }); | ||
| }); | ||
| } | ||
| /** | ||
| * Check GitHub for the newest release and, unless it is already installed, | ||
| * self-update via a global npm install of the release tarball. | ||
| * | ||
| * Returns the process exit code. | ||
| */ | ||
| export async function runUpdate(argv = [], options = {}) { | ||
| const repo = options.repo ?? process.env.MACBETH_UPDATE_REPO ?? DEFAULT_REPO; | ||
| const check = options.check ?? argv.includes("--check"); | ||
| const force = options.force ?? argv.includes("--force"); | ||
| const install = options.install ?? npmInstallGlobal; | ||
| const readVersion = options.readVersion ?? (() => readInstalledVersion()); | ||
| let current; | ||
| try { | ||
| current = readVersion(); | ||
| } | ||
| catch (err) { | ||
| const detail = err instanceof Error ? err.message : String(err); | ||
| process.stderr.write(`Could not determine the installed version: ${detail}\n`); | ||
| return 1; | ||
| } | ||
| log(`Current version: v${current}`); | ||
| log(`Checking ${repo} for the latest release...`); | ||
| let release; | ||
| try { | ||
| release = await fetchLatestRelease(repo, options.fetchImpl ?? fetch); | ||
| } | ||
| catch (err) { | ||
| const detail = err instanceof Error ? err.message : String(err); | ||
| process.stderr.write(`Could not check for updates: ${detail}\n`); | ||
| return 1; | ||
| } | ||
| log(`Latest release: ${release.tag}`); | ||
| const cmp = compareVersions(current, release.version); | ||
| if (cmp >= 0 && !force) { | ||
| log(cmp === 0 | ||
| ? "You are already on the latest version." | ||
| : `Your version (v${current}) is newer than the latest release. Nothing to do.`); | ||
| return 0; | ||
| } | ||
| if (check) { | ||
| log(`An update is available: v${current} -> ${release.tag}`); | ||
| log(`Release notes: ${release.htmlUrl}`); | ||
| log(`Run "macbeth update" to install it.`); | ||
| return 0; | ||
| } | ||
| const spec = resolveInstallSpec(release); | ||
| log(`Updating to ${release.tag} via: npm install -g ${spec}`); | ||
| try { | ||
| await install(spec); | ||
| } | ||
| catch (err) { | ||
| const detail = err instanceof Error ? err.message : String(err); | ||
| process.stderr.write(`Update failed: ${detail}\n`); | ||
| return 1; | ||
| } | ||
| log(`Updated to ${release.tag}.`); | ||
| return 0; | ||
| } | ||
| //# sourceMappingURL=update.js.map |
| {"version":3,"file":"update.js","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"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"} |
+68
-1
| #!/usr/bin/env node | ||
| import "../dist/mcp.js"; | ||
| import { readFileSync } from "node:fs"; | ||
| import { dirname, resolve } from "node:path"; | ||
| import { fileURLToPath } from "node:url"; | ||
| const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), ".."); | ||
| function readVersion() { | ||
| try { | ||
| const pkg = JSON.parse( | ||
| readFileSync(resolve(PACKAGE_ROOT, "package.json"), "utf8") | ||
| ); | ||
| return pkg.version ?? "unknown"; | ||
| } catch { | ||
| return "unknown"; | ||
| } | ||
| } | ||
| function printHelp() { | ||
| process.stdout.write( | ||
| `macbeth — Playwright for macOS native apps (Accessibility API)\n\n` + | ||
| `Usage:\n` + | ||
| ` macbeth Start the MCP server (default; used by LLM agents)\n` + | ||
| ` macbeth update Update to the latest GitHub release\n` + | ||
| ` macbeth update --check Report whether an update is available, without installing\n` + | ||
| ` macbeth version Print the installed version\n` + | ||
| ` macbeth help Show this help\n` | ||
| ); | ||
| } | ||
| const [command, ...rest] = process.argv.slice(2); | ||
| try { | ||
| switch (command) { | ||
| case "update": | ||
| case "self-update": | ||
| case "upgrade": { | ||
| const { runUpdate } = await import("../dist/update.js"); | ||
| process.exit(await runUpdate(rest)); | ||
| } | ||
| case "version": | ||
| case "--version": | ||
| case "-v": { | ||
| process.stdout.write(`${readVersion()}\n`); | ||
| break; | ||
| } | ||
| case "help": | ||
| case "--help": | ||
| case "-h": { | ||
| printHelp(); | ||
| break; | ||
| } | ||
| default: { | ||
| if (command && !command.startsWith("-")) { | ||
| // An unrecognized bare word is almost certainly a typo; surface help | ||
| // rather than silently starting the MCP server. | ||
| process.stderr.write(`Unknown command: ${command}\n\n`); | ||
| printHelp(); | ||
| process.exit(1); | ||
| } | ||
| // No command (or leading-dash flags meant for the server): start the MCP | ||
| // server. This is the entry point invoked by `npx macbeth` in MCP configs. | ||
| await import("../dist/mcp.js"); | ||
| } | ||
| } | ||
| } catch (err) { | ||
| process.stderr.write(`${err instanceof Error ? err.message : err}\n`); | ||
| process.exit(1); | ||
| } |
+2
-1
| { | ||
| "name": "macbeth", | ||
| "version": "0.2.0", | ||
| "version": "0.2.1", | ||
| "description": "Playwright for macOS native apps — automation via the Accessibility API", | ||
@@ -35,2 +35,3 @@ "repository": { | ||
| "test:gui": "vitest run src/__tests__/test-harness.e2e.test.ts", | ||
| "test:gui:foreground": "vitest run src/__tests__/mcp-demo-foreground.e2e.test.ts", | ||
| "test:watch": "vitest" | ||
@@ -37,0 +38,0 @@ }, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 2 instances
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 2 instances
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
3099039
2.14%113
3.67%3434
9.33%13
62.5%13
44.44%