Update to Yaps Background Remover
Snapshot Nov 12, 2026 · 06:08 UTC · version 0.1.12
Package or technical metadata updated
Package or technical metadata updated
Observed in package metadata. These changes alone do not establish a new customer-facing feature.
Up to 3 plugins free · no card required.
All fields and original values.
These are saved file metadata. Open a changed file to read its text edits.
Package file
Sep 30, 2026 · 23:13 UTC
Not present
Nov 12, 2026 · 06:08 UTC
{"sha256":"cb5059cab8f88822aa8484ecebd5488dfe148145faa1990da96e10a619550165","size":499}
Package file
Sep 30, 2026 · 23:13 UTC
{"sha256":"d693f4e16e2a73d7f8765d97642fa8f01c2fbb8e29bb383fcf1ecd797afb0b18","size":7865}
Nov 12, 2026 · 06:08 UTC
Not present
Package file
Sep 30, 2026 · 23:13 UTC
{"sha256":"d693f4e16e2a73d7f8765d97642fa8f01c2fbb8e29bb383fcf1ecd797afb0b18","size":7865}
Nov 12, 2026 · 06:08 UTC
Not present
Package file
Sep 30, 2026 · 23:13 UTC
{"sha256":"d693f4e16e2a73d7f8765d97642fa8f01c2fbb8e29bb383fcf1ecd797afb0b18","size":7865}
Nov 12, 2026 · 06:08 UTC
Not present
Compare saved observations
Download comparison JSONChanged files
Choose a file to see its text changes. Binary or large files show metadata only.
.codex-plugin/assets/composer-icon.png →
.codex-plugin/assets/logo-dark.png →
.codex-plugin/assets/logo.png →
scripts/yaps-cli-discovery.mjs →
scripts/yaps-cli-discovery.mjs
− removed · + added
--- before +++ after @@ -1,15 +1,60 @@ -import { constants, accessSync, readFileSync, realpathSync, statSync } from "node:fs"; +import { constants, accessSync, closeSync, openSync, readFileSync, readSync, realpathSync, statSync } from "node:fs"; import { homedir } from "node:os"; import { basename, delimiter, join, posix, win32 } from "node:path"; import { fileURLToPath } from "node:url"; import { spawn } from "node:child_process"; +// Read only named non-secret settings by default. Callers can supply their own +// explicit environment; discovery never needs an agent provider credential. +export function defaultYapsEnvironment() { + return Object.fromEntries(Object.entries({ + "PATH": process.env["PATH"], + "Path": process.env["Path"], + "PATHEXT": process.env["PATHEXT"], + "HOME": process.env["HOME"], + "USERPROFILE": process.env["USERPROFILE"], + "HOMEDRIVE": process.env["HOMEDRIVE"], + "HOMEPATH": process.env["HOMEPATH"], + "APPDATA": process.env["APPDATA"], + "LOCALAPPDATA": process.env["LOCALAPPDATA"], + "ProgramFiles": process.env["ProgramFiles"], + "ProgramFiles(x86)": process.env["ProgramFiles(x86)"], + "ProgramW6432": process.env["ProgramW6432"], + "SystemRoot": process.env["SystemRoot"], + "SYSTEMROOT": process.env["SYSTEMROOT"], + "WINDIR": process.env["WINDIR"], + "COMSPEC": process.env["COMSPEC"], + "ComSpec": process.env["ComSpec"], + "TMPDIR": process.env["TMPDIR"], + "TMP": process.env["TMP"], + "TEMP": process.env["TEMP"], + "LANG": process.env["LANG"], + "LANGUAGE": process.env["LANGUAGE"], + "LC_ALL": process.env["LC_ALL"], + "LC_CTYPE": process.env["LC_CTYPE"], + "TZ": process.env["TZ"], + "XDG_CONFIG_HOME": process.env["XDG_CONFIG_HOME"], + "XDG_DATA_HOME": process.env["XDG_DATA_HOME"], + "XDG_CACHE_HOME": process.env["XDG_CACHE_HOME"], + "XDG_RUNTIME_DIR": process.env["XDG_RUNTIME_DIR"], + "DISPLAY": process.env["DISPLAY"], + "WAYLAND_DISPLAY": process.env["WAYLAND_DISPLAY"], + "DBUS_SESSION_BUS_ADDRESS": process.env["DBUS_SESSION_BUS_ADDRESS"], + "YAPS_CLI_BINARY": process.env["YAPS_CLI_BINARY"], + "YAPS_INSTALL_DIR": process.env["YAPS_INSTALL_DIR"], + "YAPS_MCP_BINARY": process.env["YAPS_MCP_BINARY"], + "YAPS_SETTINGS_PATH": process.env["YAPS_SETTINGS_PATH"], + "YAPS_CLI_PROGRESS": process.env["YAPS_CLI_PROGRESS"], + }).filter(([, value]) => typeof value === "string")); +} + export const DEFAULT_PROBE_TIMEOUT_MS = 5_000; export const DEFAULT_AUTH_TIMEOUT_MS = 2_000; export const DEFAULT_AUTH_RECOVERY_TIMEOUT_MS = 8_000; export const MIN_SAFE_AUTH_STATUS_VERSION = "2.3.124"; const MAX_PROBE_BYTES = 64 * 1024; const MAX_VERSION_BYTES = 4 * 1024; +const MAX_PE_RESOURCE_BYTES = 2 * 1024 * 1024; const MAX_PLIST_BYTES = 64 * 1024; const MAX_WINDOWS_SHIM_BYTES = 4 * 1024; const RUNNING_YAPS_PROCESS_NAMES = new Set(["yaps.exe", "yaps_mcp.exe", "yaps_cli.exe"]); @@ -145,7 +190,7 @@ async function defaultListRunningYapsExecutables({ platform = process.platform, - env = process.env, + env = defaultYapsEnvironment(), } = {}) { // Only enumerate processes on a real Windows host. Tests that pass // `platform: "win32"` on Linux/macOS stay inert unless they inject @@ -168,7 +213,7 @@ export function cliCandidates({ override, platform = process.platform, - env = process.env, + env = defaultYapsEnvironment(), home = env.HOME || env.USERPROFILE || homedir(), runningExecutables = [], } = {}) { @@ -179,8 +224,14 @@ env.YAPS_CLI_BINARY?.trim(), env.YAPS_INSTALL_DIR?.trim() ? path.join(env.YAPS_INSTALL_DIR.trim(), executable) : "", ].find(Boolean); + // A PATH shim can survive an upgrade and still point to a credential-free + // helper from a different installation. Start with the running desktop's + // sidecar. A running CLI or MCP helper alone is not a desktop install signal. + const runningDesktop = (runningExecutables || []).filter((executablePath) => + typeof executablePath === "string" && win32.basename(executablePath).toLowerCase() === "yaps.exe"); return uniqueCandidates([ ...(explicit ? [{ path: explicit, source: "override" }] : []), + ...runningAppCliCandidates({ platform, runningExecutables: runningDesktop }), ...pathCandidates("yaps", { platform, env }), ...pathCandidates("yaps_cli", { platform, env }), ...runningAppCliCandidates({ platform, runningExecutables }), @@ -196,7 +247,7 @@ export function connectorCandidates({ platform = process.platform, - env = process.env, + env = defaultYapsEnvironment(), home = env.HOME || env.USERPROFILE || homedir(), } = {}) { const path = pathApi(platform); @@ -246,7 +297,7 @@ function runJsonCommand(candidate, args, { timeoutMs, spawnImpl = spawn, - env = process.env, + env = defaultYapsEnvironment(), } = {}) { return new Promise((resolve) => { let settled = false; @@ -305,7 +356,7 @@ function runTextCommand(candidate, args, { timeoutMs = DEFAULT_AUTH_TIMEOUT_MS, spawnImpl = spawn, - env = process.env, + env = defaultYapsEnvironment(), } = {}) { return new Promise((resolve) => { let settled = false; @@ -383,7 +434,7 @@ function knownInstallationVariant(cli, { platform = process.platform, - env = process.env, + env = defaultYapsEnvironment(), home = env.HOME || env.USERPROFILE || homedir(), canonicalize = realpathSync, } = {}) { @@ -397,6 +448,82 @@ return setappApplications.has(application) ? "setapp" : null; } +function peResourceEntry(resources, directory, id) { + const count = resources.readUInt16LE(directory + 12) + resources.readUInt16LE(directory + 14); + const start = directory + 16; + if (start + count * 8 > resources.length) return null; + for (let entry = start; entry < start + count * 8; entry += 8) { + if (id === undefined || resources.readUInt32LE(entry) === id) { + return resources.readUInt32LE(entry + 4); + } + } + return null; +} + +// Read the numeric PRODUCTVERSION in the PE RT_VERSION resource. The shipped +// helper stamps this alongside the display string. No PowerShell startup or +// execution of the binary is needed to decide whether auth status is safe. +function readWindowsProductVersion(executable) { + let fd; + try { + fd = openSync(executable, "r"); + const readAt = (length, position) => { + const bytes = Buffer.alloc(length); + if (readSync(fd, bytes, 0, length, position) !== length) throw new Error("Truncated PE data"); + return bytes; + }; + const dos = readAt(64, 0); + if (dos.readUInt16LE(0) !== 0x5a4d) return null; + const peOffset = dos.readUInt32LE(0x3c); + const coff = readAt(24, peOffset); + if (coff.readUInt32LE(0) !== 0x00004550) return null; + const sectionCount = coff.readUInt16LE(6); + const optionalSize = coff.readUInt16LE(20); + if (sectionCount === 0 || sectionCount > 96) return null; + const headers = readAt(optionalSize + sectionCount * 40, peOffset + 24); + const magic = headers.readUInt16LE(0); + const directories = magic === 0x20b ? 112 : magic === 0x10b ? 96 : 0; + if (!directories || optionalSize < directories + 24 || headers.readUInt32LE(directories - 4) < 3) return null; + const resourceRva = headers.readUInt32LE(directories + 16); + const resourceSize = headers.readUInt32LE(directories + 20); + if (!resourceRva || !resourceSize || resourceSize > MAX_PE_RESOURCE_BYTES) return null; + + let resources; + for (let section = optionalSize; section < headers.length; section += 40) { + const offset = resourceRva - headers.readUInt32LE(section + 12); + if (offset >= 0 && offset + resourceSize <= headers.readUInt32LE(section + 16)) { + resources = readAt(resourceSize, headers.readUInt32LE(section + 20) + offset); + break; + } + } + if (!resources) return null; + const directoryFlag = 0x80000000; + const type = peResourceEntry(resources, 0, 16); + if (type === null || type < directoryFlag) return null; + const name = peResourceEntry(resources, type - directoryFlag); + if (name === null || name < directoryFlag) return null; + const data = peResourceEntry(resources, name - directoryFlag); + if (data === null || data >= directoryFlag || data + 16 > resources.length) return null; + const offset = resources.readUInt32LE(data) - resourceRva; + const size = resources.readUInt32LE(data + 4); + if (offset < 0 || size < 92 || offset + size > resources.length) return null; + + const version = resources.subarray(offset, offset + size); + const fixedOffset = 40; + if (version.readUInt16LE(0) < fixedOffset + 52 || version.readUInt16LE(0) > size + || version.readUInt16LE(2) !== 52 || version.toString("utf16le", 6, 38) !== "VS_VERSION_INFO\0" + || version.readUInt32LE(fixedOffset) !== 0xfeef04bd) return null; + const majorMinor = version.readUInt32LE(fixedOffset + 16); + const buildRevision = version.readUInt32LE(fixedOffset + 20); + if (!majorMinor && !buildRevision) return null; + return `${majorMinor >>> 16}.${majorMinor & 0xffff}.${buildRevision >>> 16}`; + } catch { + return null; + } finally { + if (fd !== undefined) closeSync(fd); + } +} + /** * Read only version metadata from verified package locations. This never runs * the app or CLI, never scans the filesystem, and never interpolates a path @@ -404,7 +531,7 @@ */ export async function readInstalledYapsVersion(cli, { platform = process.platform, - env = process.env, + env = defaultYapsEnvironment(), canAccess = (candidate) => defaultCanAccess(candidate, platform), pathExists = defaultPathExists, canonicalize = realpathSync, @@ -444,9 +571,11 @@ } if (platform === "win32") { const path = win32; - if (path.basename(cli.path).toLowerCase() !== "yaps_cli.exe") return null; + if (path.basename(cli.path).toLowerCase() !== "yaps_cli.exe" || !canAccess(cli.path)) return null; + const productVersion = readWindowsProductVersion(cli.path); + if (productVersion) return productVersion; const systemRoot = env.SystemRoot || env.WINDIR; - if (!systemRoot || !canAccess(cli.path)) return null; + if (!systemRoot) return null; const powershell = path.join(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe"); if (!canAccess(powershell)) return null; const result = await readText(powershell, [ @@ -565,6 +694,7 @@ const now = options.now || Date.now; const deadline = now() + (options.totalTimeoutMs || 15_000); const rejected = []; + let provisional = null; const runningExecutables = options.runningExecutables ?? (options.listRunning ? await options.listRunning() : await defaultListRunningYapsExecutables(options)); const candidates = cliCandidates({ ...options, runningExecutables }); @@ -611,21 +741,34 @@ continue; } const resolved = { ...candidate, path: resolvedPath, rejected }; - // An explicit override stays authoritative even if it is older than 2.3.124. + // An explicit override stays authoritative even if it is older than + // 2.3.124 or its version is unreadable. Return it after a successful + // status probe. if (authoritativeOverride) return resolved; - // A leftover Program Files 2.1.4 CLI still answers `status --pretty`. - // Skip proven-old helpers and keep looking for a current sidecar beside a - // running yaps.exe / yaps_mcp.exe. If every remaining candidate is - // skip-stale rejected, do not bind the rejected path (do not execute - // leftover 2.1.4). Diagnosis stays a distinct stale/unsafe account - // signal — never cli_missing, cli_invalid, or local_yaps_unreachable - // for a helper that was found. - if (await candidateAuthStatusSafety(resolvedPath, readAppVersion) === "unsafe") { + const safety = await candidateAuthStatusSafety(resolvedPath, readAppVersion); + // The finder already probed `status --pretty`. A leftover helper is + // therefore executed for that probe. Then reject a proven-old helper + // (older than MIN_SAFE_AUTH_STATUS_VERSION 2.3.124, the credential-free + // account-check floor — not a claim the helper is current or supports + // every tool) before account checks or the requested operation. + if (safety === "unsafe") { rejected.push({ source: candidate.source, reason: "stale_cli" }); continue; } + // Unknown versions (including a Windows PATH yaps.exe, because version + // metadata is only read for a filename of yaps_cli.exe) stay provisional. + // Do not bind yet and do not treat unknown as stale_cli. Keep searching + // for a verified >= 2.3.124 candidate; the first verified helper wins + // even if it is later in the list (running_app sidecar after PATH). + if (safety === "unknown") { + if (!provisional) provisional = resolved; + continue; + } return resolved; } + // If nothing verified, bind the first provisional unknown that passed + // status. Do not turn a lone unknown PATH hit into a miss. + if (provisional) return { ...provisional, rejected }; return { path: null, source: null, rejected }; } @@ -659,11 +802,23 @@ function sanitizedAuthStatus(value, platform) { if (!value || typeof value !== "object" || Array.isArray(value)) return null; if (typeof value.authenticated !== "boolean" || typeof value.status !== "string") return null; + // Older helpers report a missing or inaccessible auth store as signed out. + // Keep a readable sign-out receipt distinct from a host that cannot see it. + const missingDesktopAccount = value.status === "unauthenticated" + && value.diagnostic_code === "signed_out" && value.auth_store_exists === false; + const diagnosticCode = missingDesktopAccount + ? "desktop_account_unavailable" + : typeof value.diagnostic_code === "string" ? value.diagnostic_code : null; + const followedSettingsPath = diagnosticCode === "followed_desktop_account" + ? normalizedRecommendedSettingsPath(value.settings_path, platform) + : null; + if (diagnosticCode === "followed_desktop_account" && !followedSettingsPath) return null; return { authenticated: value.authenticated, - status: value.status, - diagnosticCode: typeof value.diagnostic_code === "string" ? value.diagnostic_code : null, + status: missingDesktopAccount ? "verification_unavailable" : value.status, + diagnosticCode, recommendedSettingsPath: normalizedRecommendedSettingsPath(value.recommended_settings_path, platform), + followedSettingsPath, }; } @@ -686,7 +841,7 @@ } function refreshableAccount(auth) { - return Boolean(auth) && ( + return Boolean(auth) && auth.diagnosticCode !== "desktop_account_unavailable" && ( REFRESHABLE_ACCOUNT_STATES.has(auth.status) || REFRESHABLE_ACCOUNT_DIAGNOSTICS.has(auth.diagnosticCode) ); @@ -755,7 +910,7 @@ export function launchInstalledYaps(cli, { platform = process.platform, - env = process.env, + env = defaultYapsEnvironment(), home = env.HOME || env.USERPROFILE || homedir(), spawnImpl = spawn, canAccess = (candidate) => defaultCanAccess(candidate, platform), @@ -776,6 +931,7 @@ }; try { const child = spawnImpl(launch.command, launch.args, { + env, detached: launch.detached, stdio: "ignore", windowsHide: true, @@ -800,8 +956,20 @@ }); } -export function applyResolvedSettings(args, settingsPath, { env = process.env } = {}) { - if (!settingsPath || explicitSettingsSelected(args, env)) return [...args]; +export function applyResolvedSettings(args, settingsPath, { env = defaultYapsEnvironment(), followDesktopAccount = false } = {}) { + if (!settingsPath) return [...args]; + if (followDesktopAccount) { + const withoutOldPath = []; + for (let index = 0; index < args.length; index += 1) { + if (args[index] === "--settings-path") { + index += 1; + } else if (!args[index].startsWith("--settings-path=")) { + withoutOldPath.push(args[index]); + } + } + return ["--settings-path", settingsPath, ...withoutOldPath]; + } + if (explicitSettingsSelected(args, env)) return [...args]; return ["--settings-path", settingsPath, ...args]; } @@ -821,8 +989,9 @@ } export function isAuthStatusCommand(args) { - const command = normalizedCliCommand(args); - return command[0] === "auth" && command[1] === "status" && command.length === 2; + const [group, action, ...flags] = normalizedCliCommand(args); + return group === "auth" && action === "status" + && (flags.length === 0 || (flags.length === 1 && flags[0] === "--redact")); } export function commandRequiresActiveAccount(args) { @@ -830,12 +999,15 @@ if (command.includes("--help") || command.includes("-h")) return false; if (!command.length || ["status", "settings", "auth"].includes(command[0])) return false; if (command[0] === "features" && command[1] === "list") return false; + // Reading, waiting on or cancelling already-queued background jobs must keep + // working if access lapses mid-job; only `jobs retry` queues new work. + if (command[0] === "jobs" && command[1] !== "retry") return false; return true; } export async function resolveYapsSession(options = {}) { const platform = options.platform || process.platform; - const env = options.env || process.env; + const env = options.env || defaultYapsEnvironment(); const commandArguments = options.commandArguments || []; const cli = options.cli || await resolveYapsCli(options); if (!cli.path) { @@ -894,12 +1066,14 @@ let settingsPath = null; const authResult = await readAuth(explicitSettingsPath, DEFAULT_AUTH_TIMEOUT_MS); let auth = authResult.ok ? authResult.auth : null; + if (auth?.followedSettingsPath) settingsPath = auth.followedSettingsPath; if (!explicitSettings && auth?.recommendedSettingsPath && auth.status === "settings_path_mismatch") { const retry = await readAuth(auth.recommendedSettingsPath, DEFAULT_AUTH_TIMEOUT_MS); if (retry.ok) { settingsPath = auth.recommendedSettingsPath; auth = retry.auth; + if (auth.followedSettingsPath) settingsPath = auth.followedSettingsPath; } } @@ -926,6 +1100,7 @@ ); if (!retry.ok) continue; auth = retry.auth; + if (auth.followedSettingsPath) settingsPath = auth.followedSettingsPath; if (!refreshableAccount(auth)) break; } } @@ -962,18 +1137,18 @@ if (cli?.rejected?.length) { return { code: "cli_invalid", - message: "A Yaps CLI candidate was found, but it did not pass the safe status check. If you set YAPS_CLI_BINARY, correct or remove that override. Otherwise update or reinstall Yaps, open it once, then start a new local ChatGPT or Codex task. Do not install a separate CLI or edit PATH.", + message: "A Yaps CLI candidate was found, but it did not pass the safe status check. If you set YAPS_CLI_BINARY, correct or remove that override. Otherwise update or reinstall Yaps, open it once, then start a new agent task on this computer. Do not install a separate CLI or edit PATH.", }; } return { code: "cli_missing", - message: "The Yaps CLI could not be found from this local session. Install or update Yaps from https://yaps.ai/download, open it once, then start a new local ChatGPT or Codex task. The CLI is included with Yaps; no separate CLI or PATH setup is needed.", + message: "The Yaps CLI could not be found from this local session. Install or update Yaps using the official download link in the plugin README, open it once, then start a new agent task on this computer. The CLI is included with Yaps; no separate CLI or PATH setup is needed.", }; } if (needsConnector && !connector?.path) { return { code: "vault_connector_unavailable", - message: "The Yaps CLI is installed and working, but the private-vault connector is unavailable. Update or reinstall Yaps from https://yaps.ai/download, open it once, then start a new local ChatGPT or Codex task. Do not reinstall the plugin, install a separate CLI, or edit PATH.", + message: "The Yaps CLI is installed and working, but the private-vault connector is unavailable. Update or reinstall Yaps using the official download link in the plugin README, open it once, then start a new agent task on this computer. Do not reinstall the plugin, install a separate CLI, or edit PATH.", }; } return { code: "ready", message: "Yaps is ready." }; @@ -988,7 +1163,7 @@ } const auth = session?.auth; if (!auth) { - if (session?.authStatusSafety === "unsafe" || rejectedHasStaleCli(session?.rejected)) { + if (session?.authStatusSafety === "unsafe" || (!session?.path && rejectedHasStaleCli(session?.rejected))) { return accountStatusUnsafeDiagnosis(session?.appVersion); } if (session?.authStatusSafety === "unknown") { @@ -1026,6 +1201,12 @@ message: "This installed Yaps helper uses an older credential-based account check. Update Yaps and retry. Do not approve a Keychain prompt or create a separate plugin account.", }; } + if (auth.diagnosticCode === "desktop_account_unavailable") { + return { + code: "desktop_account_unavailable", + message: "This session could not read the Yaps desktop account. Open Yaps and use a local session under the same operating system account.", + }; + } if (refreshableAccount(auth)) { const attempted = session.appLaunchSucceeded ? "The plugin opened the installed Yaps app automatically, but the account cache did not refresh in time. "
Full technical diff · 13 changed fields
added /files/.claude-plugin~1plugin.json
Field was absent
{
"sha256": "cb5059cab8f88822aa8484ecebd5488dfe148145faa1990da96e10a619550165",
"size": 499
}removed /files/.codex-plugin~1assets~1composer-icon.png
{
"sha256": "d693f4e16e2a73d7f8765d97642fa8f01c2fbb8e29bb383fcf1ecd797afb0b18",
"size": 7865
}Field is absent
removed /files/.codex-plugin~1assets~1logo-dark.png
{
"sha256": "d693f4e16e2a73d7f8765d97642fa8f01c2fbb8e29bb383fcf1ecd797afb0b18",
"size": 7865
}Field is absent
removed /files/.codex-plugin~1assets~1logo.png
{
"sha256": "d693f4e16e2a73d7f8765d97642fa8f01c2fbb8e29bb383fcf1ecd797afb0b18",
"size": 7865
}Field is absent
changed /files/.codex-plugin~1plugin.json/sha256
"c8480186b56d17c135fcc317a9cac513dbae205a4a59870245eb125217c660db"
"e6337758779d65dc57ca0db201a648846c7e9d862e38cb56b41da5f5a75592be"
changed /files/.codex-plugin~1plugin.json/size
2649
2616
added /files/plugin.json
Field was absent
{
"sha256": "c896282eb5718b4d05459325fffd0874869bb1c192c79e571a2fc8a975b80763",
"size": 2830
}changed /files/scripts~1yaps-cli-discovery.mjs/sha256
"2264b812911bf5275f31d1f27f24f483269577a213fc97be7f36fc91a6b1bfc8"
"1d3808134d03a4d19f2b2eac3acea2d6af4b7538bcc0da84afe43bce09eca257"
changed /files/scripts~1yaps-cli-discovery.mjs/size
41185
50423
changed /files/scripts~1yaps-plugin-runner.mjs/sha256
"c5959de172d2c855d7edb39c433dd117dd1946719fe217486483d7b445a9619d"
"af9fc263e016cb959379f68fea158891d65e774b0457ed475f0a156f12ce34c9"
changed /files/scripts~1yaps-plugin-runner.mjs/size
10993
12836
changed /files/skills~1yaps-background-removal~1SKILL.md/sha256
"2fc4ab830f04c4e424954218fb51306d408dd0a59e5fdafd0ef3301b174b157c"
"924b2189a0c90fe09a3293bbfff5e2c65c33178bb5bfdfdbcd64a29972ef657a"
changed /files/skills~1yaps-background-removal~1SKILL.md/size
12382
12072
Full snapshot data
{
"files": {
".claude-plugin/plugin.json": {
"sha256": "cb5059cab8f88822aa8484ecebd5488dfe148145faa1990da96e10a619550165",
"size": 499
},
".codex-plugin/plugin.json": {
"sha256": "e6337758779d65dc57ca0db201a648846c7e9d862e38cb56b41da5f5a75592be",
"size": 2616
},
"README.md": {
"sha256": "003db95c89124f0633210dc427c65780e86c5e766ce9ed164cbe6405fadc6c14",
"size": 1896
},
"assets/yaps-icon.png": {
"sha256": "d693f4e16e2a73d7f8765d97642fa8f01c2fbb8e29bb383fcf1ecd797afb0b18",
"size": 7865
},
"plugin.json": {
"sha256": "c896282eb5718b4d05459325fffd0874869bb1c192c79e571a2fc8a975b80763",
"size": 2830
},
"scripts/yaps-cli-discovery.mjs": {
"sha256": "1d3808134d03a4d19f2b2eac3acea2d6af4b7538bcc0da84afe43bce09eca257",
"size": 50423
},
"scripts/yaps-plugin-runner.mjs": {
"sha256": "af9fc263e016cb959379f68fea158891d65e774b0457ed475f0a156f12ce34c9",
"size": 12836
},
"skills/yaps-background-removal/SKILL.md": {
"sha256": "924b2189a0c90fe09a3293bbfff5e2c65c33178bb5bfdfdbcd64a29972ef657a",
"size": 12072
},
"skills/yaps-background-removal/agents/openai.yaml": {
"sha256": "96125fd5e7c5b8316e8bb2b36b79076fa75b5b1e7bafa10cffc02def969deeef",
"size": 192
}
}
}SHA-256 of public snapshot: a675169d0816b02236f3ba106ab2fa3d54cfefd6b1412cefc8070829cfd816ac