{"version":3,"file":"packaging.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/plugins/packaging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAoB,KAAK,cAAc,EAA0B,MAAM,+BAA+B,CAAC;AAC9G,OAAO,EAAwC,KAAK,UAAU,EAAgC,MAAM,YAAY,CAAC;AAEjH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAKN,KAAK,YAAY,EAEjB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAK3D,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG;QAAE,MAAM,EAAE,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,MAAM,EAAE,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACrF;AAED,MAAM,WAAW,aAAa;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,gBAAgB,CAAC;IACxB,iEAAiE;IACjE,EAAE,EAAE,OAAO,CAAC;CACZ;AAED,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,cAAc,CAAC;IACzB,yEAAyE;IACzE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,gBAAgB,CAAC;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,uEAAuE;IACvE,YAAY,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,cAAc,CAQ/E;AA6GD,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAEjE;AAwBD;;;GAGG;AACH,wBAAsB,aAAa,CAClC,MAAM,EAAE,gBAAgB,EACxB,gBAAgB,CAAC,EAAE,cAAc,EACjC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,YAAY,CAAC;IAAC,WAAW,CAAC,EAAE,SAAS,aAAa,EAAE,CAAA;CAAO,GAC5E,OAAO,CAAC,aAAa,CAAC,CAwFxB;AAiBD,MAAM,WAAW,WAAW;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AAQD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,gBAAgB,EACxB,QAAQ,EAAE,cAAc,EACxB,cAAc,EAAE,MAAM,GACpB,WAAW,CAyDb;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAOxE","sourcesContent":["/**\n * Packaging — everything that has to happen before a plugin can be published,\n * and nothing that publishes it.\n *\n * The split is the point. Preparing a release is mechanical: run the gates at\n * their strictest, write a README, produce the marketplace index entry. All of\n * that is automated. *Publishing* — pushing an artifact into a marketplace that\n * other agents install from autonomously — stays a human act, because an agent\n * that can do it unattended is a supply-chain compromise primitive. See\n * docs/plugin-system-architecture.md §3.2–§3.3.\n *\n * Packaging works **in place**, in the plugin's production home. There is no\n * separate output location: by the time a plugin reaches here it is already in\n * its target platform's layout, and copying it somewhere else would just create\n * a fourth directory role to confuse with the other three (§8.3).\n *\n * The two platforms are not symmetric here, and the lane is built for the harder\n * one. A `claude` plugin is already live locally from `~/.claude/skills/<id>/`,\n * so publishing is optional and additive. For `github`, local installs are\n * deprecated — publishing is the *only* route into the ecosystem — so the\n * GitHub flow (a PR against a marketplace repo's index) is the primary case and\n * the Claude submission is the variant.\n */\n\nimport { execFileSync } from \"node:child_process\";\nimport { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { CapabilityDoc } from \"../../capabilities/registry.js\";\nimport { isPluginPlatform, type PluginPlatform, resolvePluginPlatforms } from \"./formats/platform-targets.js\";\nimport { formatGateFindings, type GateFinding, type GateResult, runStaticGates, withFindings } from \"./gates.js\";\nimport { productionRoot } from \"./locations.js\";\nimport type { NormalizedPlugin } from \"./manifest.js\";\nimport { runSmokeGate } from \"./smoke.js\";\nimport {\n\tdistractorCandidates,\n\tloadTriggerCases,\n\townCandidates,\n\trunTriggerEval,\n\ttype TriggerJudge,\n\ttriggerFindings,\n} from \"./trigger-eval.js\";\n\n/**\n * Where packaging records what it produced, at the plugin root.\n *\n * A dotfile beside the existing `.authored.json` provenance marker rather than a\n * visible `marketplace-entry.json`: the plugin directory is the thing that gets\n * copied into a marketplace repo, and a build record is not part of the artifact.\n */\nexport const PUBLISH_RECORD_FILE = \".hoocode-publish.json\";\n\n/** Placeholder `source` for a plugin that is not in a git checkout — deliberately unusable as-is. */\nconst SOURCE_PLACEHOLDER = \"<REPLACE: git URL, or path within the marketplace repo>\";\n\n/** A `marketplace.json` `plugins[]` entry, ready to paste into an index. */\nexport interface MarketplaceEntry {\n\tname: string;\n\tdescription?: string;\n\tversion?: string;\n\tsource: string | { source: \"git\"; url: string } | { source: \"github\"; repo: string };\n}\n\nexport interface PublishRecord {\n\tpackagedAt: string;\n\tplatform: PluginPlatform;\n\tentry: MarketplaceEntry;\n\t/** Whether the gates were green when this record was written. */\n\tok: boolean;\n}\n\nexport interface PackageResult {\n\tok: boolean;\n\tdir: string;\n\tplatform: PluginPlatform;\n\t/** Files packaging created or refreshed, relative to the plugin root. */\n\twritten: string[];\n\tentry: MarketplaceEntry;\n\tevaluation: GateResult;\n\t/** Human-facing next steps; deliberately instructions, not actions. */\n\tinstructions: string;\n}\n\n/**\n * Which ecosystem this plugin is being packaged for.\n *\n * Where it lives is the strongest evidence — the production homes are per\n * platform, so a plugin under `~/.agents/publish/github/` is a github artifact\n * whatever its manifests say. A plugin outside a production home (installed, or\n * authored by an older version) falls back to what it declares, then to the\n * session default.\n */\nexport function resolvePackagePlatform(plugin: NormalizedPlugin): PluginPlatform {\n\tconst root = path.resolve(plugin.root);\n\tfor (const platform of [\"claude\", \"github\"] as const) {\n\t\tconst home = path.resolve(productionRoot(platform));\n\t\tif (root === home || root.startsWith(`${home}${path.sep}`)) return platform;\n\t}\n\tconst declared = plugin.supportPlatform.filter(isPluginPlatform);\n\treturn declared[0] ?? resolvePluginPlatforms()[0];\n}\n\n/** Best-effort origin URL of the repo containing `dir`, if it is in one. */\nfunction gitOriginUrl(dir: string): string | undefined {\n\ttry {\n\t\tconst url = execFileSync(\"git\", [\"-C\", dir, \"remote\", \"get-url\", \"origin\"], {\n\t\t\tencoding: \"utf8\",\n\t\t\ttimeout: 5_000,\n\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t}).trim();\n\t\treturn url || undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction capabilityLines(plugin: NormalizedPlugin): string[] {\n\tconst lines: string[] = [];\n\tconst add = (label: string, present: unknown) => {\n\t\tif (present) lines.push(`- ${label}`);\n\t};\n\tadd(\"Skills\", plugin.skillsDir);\n\tadd(\"Slash commands\", plugin.commandsDir);\n\tadd(\"Subagents\", plugin.agentsDir);\n\tadd(\"Hooks\", plugin.hooks);\n\tadd(\"MCP servers\", plugin.mcpServers);\n\tadd(\"Canvases\", plugin.canvasExtensions?.length);\n\treturn lines;\n}\n\nfunction installSection(plugin: NormalizedPlugin, platform: PluginPlatform): string[] {\n\tif (platform === \"claude\") {\n\t\treturn [\n\t\t\t\"## Install\",\n\t\t\t\"\",\n\t\t\t\"```bash\",\n\t\t\t\"claude plugin marketplace add <marketplace-repo>\",\n\t\t\t`claude plugin install ${plugin.id}@<marketplace>`,\n\t\t\t\"```\",\n\t\t\t\"\",\n\t\t\t`Or copy this directory to \\`~/.claude/skills/${plugin.id}/\\` — a folder there`,\n\t\t\t\"carrying a `.claude-plugin/plugin.json` loads with no install step.\",\n\t\t];\n\t}\n\treturn [\n\t\t\"## Install\",\n\t\t\"\",\n\t\t\"```bash\",\n\t\t\"copilot plugin marketplace add <marketplace-repo>\",\n\t\t`copilot plugin install ${plugin.id}@<marketplace>`,\n\t\t\"```\",\n\t];\n}\n\n/**\n * Generate a README from what the plugin actually contains.\n *\n * Never overwrites: a hand-written README is the author's description of their\n * own plugin, and a generated one derived from the directory listing is strictly\n * worse. This only fills the gap where there is nothing at all.\n */\nfunction writeReadme(plugin: NormalizedPlugin, platform: PluginPlatform): string | undefined {\n\tconst file = path.join(plugin.root, \"README.md\");\n\tif (existsSync(file)) return undefined;\n\n\tconst capabilities = capabilityLines(plugin);\n\tconst body = [\n\t\t`# ${plugin.id}`,\n\t\t\"\",\n\t\tplugin.description ?? \"_No description provided._\",\n\t\t\"\",\n\t\t...(capabilities.length > 0 ? [\"## Provides\", \"\", ...capabilities, \"\"] : []),\n\t\t...installSection(plugin, platform),\n\t\t\"\",\n\t\t...(plugin.unsupportedSurfaces?.length\n\t\t\t? [\n\t\t\t\t\t\"## Notes\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t`This plugin ships surfaces hoocode does not load: ${plugin.unsupportedSurfaces.join(\", \")}.`,\n\t\t\t\t\t\"They are preserved as-is and are the target platform's concern.\",\n\t\t\t\t\t\"\",\n\t\t\t\t]\n\t\t\t: []),\n\t].join(\"\\n\");\n\n\twriteFileSync(file, `${body.trimEnd()}\\n`, \"utf8\");\n\treturn \"README.md\";\n}\n\n/**\n * Build the marketplace index entry.\n *\n * `source` is where the *published* plugin will live, which packaging cannot\n * know: the artifact is on this machine and has not been pushed anywhere. When\n * the plugin sits in a git checkout its origin is a plausible starting point;\n * otherwise the field is a clearly-marked placeholder for the human to fill.\n * Guessing here would produce an index entry that resolves to nothing, which is\n * worse than an obvious blank.\n */\nfunction buildEntry(plugin: NormalizedPlugin): MarketplaceEntry {\n\tconst origin = gitOriginUrl(plugin.root);\n\treturn {\n\t\tname: plugin.id,\n\t\t...(plugin.description ? { description: plugin.description } : {}),\n\t\t...(plugin.version ? { version: plugin.version } : {}),\n\t\tsource: origin ? { source: \"git\", url: origin } : SOURCE_PLACEHOLDER,\n\t};\n}\n\n/** True when the entry still needs a human to say where the plugin will be hosted. */\nexport function entryNeedsSource(entry: MarketplaceEntry): boolean {\n\treturn entry.source === SOURCE_PLACEHOLDER;\n}\n\nfunction publishSteps(plugin: NormalizedPlugin, platform: PluginPlatform): string[] {\n\tif (platform === \"github\") {\n\t\treturn [\n\t\t\t\"Publish (GitHub Copilot) — this is the only route into the ecosystem,\",\n\t\t\t\"local installs being deprecated:\",\n\t\t\t\"\",\n\t\t\t\"  1. Copy this directory into your marketplace repo.\",\n\t\t\t\"  2. Add the entry above to its `.github/marketplace.json` `plugins` array.\",\n\t\t\t\"  3. Open a pull request; the plugin is installable once it merges.\",\n\t\t];\n\t}\n\treturn [\n\t\t`Publish (Claude Code) — optional: the plugin is already live locally from`,\n\t\t`\\`~/.claude/skills/${plugin.id}/\\`. To share it:`,\n\t\t\"\",\n\t\t\"  1. Copy this directory into your marketplace repo.\",\n\t\t\"  2. Add the entry above to its `.claude-plugin/marketplace.json` `plugins` array.\",\n\t\t\"  3. Open a pull request, or submit to the community directory for review\",\n\t\t\"     (approved plugins are pinned to a commit SHA).\",\n\t];\n}\n\n/**\n * Package a plugin for publication: gate it at full strictness, write a README,\n * produce its marketplace entry, and record what it produced. Touches no remote.\n */\nexport async function packagePlugin(\n\tplugin: NormalizedPlugin,\n\tplatformOverride?: PluginPlatform,\n\toptions: { judge?: TriggerJudge; distractors?: readonly CapabilityDoc[] } = {},\n): Promise<PackageResult> {\n\tconst platform = platformOverride ?? resolvePackagePlatform(plugin);\n\n\t// A plugin can only be published into an ecosystem whose manifest it carries.\n\t// `claude plugin validate` says so too, but as a wall of validator output about\n\t// a missing file; a plugin in the native layout has simply been authored for\n\t// the wrong target, and that is worth saying in one sentence. Nothing is\n\t// written — there is no artifact to package.\n\tif (!plugin.supportPlatform.includes(platform)) {\n\t\tconst finding: GateFinding = {\n\t\t\tgate: \"G1\",\n\t\t\tseverity: \"error\",\n\t\t\tmessage:\n\t\t\t\t`Plugin \"${plugin.id}\" carries no ${platform} manifest (it offers: ${plugin.supportPlatform.join(\", \")}), ` +\n\t\t\t\t`so it cannot be published to that ecosystem. Re-author it with --platform ${platform}.`,\n\t\t};\n\t\tconst evaluation: GateResult = { ok: false, findings: [finding], conformance: \"round-trip\", plugin };\n\t\treturn {\n\t\t\tok: false,\n\t\t\tdir: plugin.root,\n\t\t\tplatform,\n\t\t\twritten: [],\n\t\t\tentry: buildEntry(plugin),\n\t\t\tevaluation,\n\t\t\tinstructions: `Plugin \"${plugin.id}\" cannot be packaged for ${platform}.\\n\\n${formatGateFindings(evaluation)}`,\n\t\t};\n\t}\n\n\t// Strict: warnings that are tolerable in a local plugin — an unresolvable\n\t// binary, a vendor-validator nit — are not tolerable in something other people\n\t// will install on the strength of the marketplace vouching for it.\n\tlet evaluation = runStaticGates(plugin.root, { platform, strict: true });\n\tif (evaluation.plugin) {\n\t\tevaluation = withFindings(evaluation, await runSmokeGate(evaluation.plugin), true);\n\t}\n\n\t// G4 is the publish path's gate (§4.3) and nothing else's: it costs a model\n\t// call, and the question it asks — is this description actually worth the\n\t// context it occupies — only becomes other people's problem at publication.\n\t// With no judge or no gold set it reports `not-run`, which is `info`, so a\n\t// machine without a model is never blocked from publishing by a check it\n\t// could not perform.\n\tconst own = ownCandidates(plugin);\n\tif (own.length > 0) {\n\t\tconst outcome = await runTriggerEval(\n\t\t\tplugin.id,\n\t\t\t[...own, ...distractorCandidates(plugin.id, options.distractors ?? [])],\n\t\t\tloadTriggerCases(plugin.root),\n\t\t\toptions.judge,\n\t\t);\n\t\tevaluation = withFindings(evaluation, triggerFindings(outcome), true);\n\t}\n\n\tconst written: string[] = [];\n\tconst readme = writeReadme(plugin, platform);\n\tif (readme) written.push(readme);\n\n\tconst entry = buildEntry(plugin);\n\tconst record: PublishRecord = {\n\t\tpackagedAt: new Date().toISOString(),\n\t\tplatform,\n\t\tentry,\n\t\tok: evaluation.ok,\n\t};\n\twriteFileSync(path.join(plugin.root, PUBLISH_RECORD_FILE), `${JSON.stringify(record, null, 2)}\\n`, \"utf8\");\n\twritten.push(PUBLISH_RECORD_FILE);\n\n\tconst instructions = [\n\t\tevaluation.ok\n\t\t\t? `Plugin \"${plugin.id}\" is ready to publish (${platform}). The remaining step is yours.`\n\t\t\t: `Plugin \"${plugin.id}\" is NOT ready to publish — these must pass first:`,\n\t\t\"\",\n\t\tformatGateFindings(evaluation),\n\t\t\"\",\n\t\t\"Marketplace entry:\",\n\t\t\"```json\",\n\t\tJSON.stringify(entry, null, 2),\n\t\t\"```\",\n\t\t...(entryNeedsSource(entry) ? [\"\", \"Replace `source` with where the plugin will be hosted.\"] : []),\n\t\t\"\",\n\t\t...publishSteps(plugin, platform),\n\t\t\"\",\n\t\t\"Publishing is deliberately not automated: an agent that can push executable\",\n\t\t\"code into a marketplace other agents install from unattended is a supply-chain\",\n\t\t\"risk, so the last step stays with you.\",\n\t].join(\"\\n\");\n\n\treturn { ok: evaluation.ok, dir: plugin.root, platform, written, entry, evaluation, instructions };\n}\n\n// ── Staging into a local marketplace checkout ────────────────────────────────\n\n/**\n * Files that exist for hoocode's benefit and have no business in a published\n * artifact: the provenance marker and packaging's own build record.\n */\nconst INTERNAL_FILES = new Set([PUBLISH_RECORD_FILE, \".authored.json\"]);\n\n/** Where each platform's marketplace index lives, and the subdirectory plugins are vendored into. */\nconst INDEX_FILE: Record<PluginPlatform, string> = {\n\tclaude: path.join(\".claude-plugin\", \"marketplace.json\"),\n\tgithub: path.join(\".github\", \"marketplace.json\"),\n};\nconst VENDOR_DIR = \"plugins\";\n\nexport interface StageResult {\n\tok: boolean;\n\tmessage: string;\n\t/** Path the plugin was copied to, relative to the marketplace root. */\n\tpluginPath?: string;\n\t/** The index that was written, relative to the marketplace root. */\n\tindexPath?: string;\n\t/** True when the marketplace had no index for this platform and one was created. */\n\tcreatedIndex?: boolean;\n}\n\ninterface RawIndex {\n\tname?: string;\n\tplugins?: Array<Record<string, unknown>>;\n\t[key: string]: unknown;\n}\n\n/**\n * Copy a packaged plugin into a **local** marketplace checkout and add its index\n * entry, leaving the result uncommitted.\n *\n * This is the far side of the automation line drawn in §3.3, and it is where the\n * line actually falls. Everything here is local, reversible, and shows up in\n * `git status` — the human reviews a diff and decides. What stays manual is the\n * step that leaves the machine: no commit, no push, no PR. Those are what make a\n * plugin installable by other people's agents, and that is the act install is\n * trusting a human to have performed.\n *\n * Only reachable from `/plugin publish`, never from a tool: a human typed the\n * command, which is the whole point.\n */\nexport function stageIntoMarketplace(\n\tplugin: NormalizedPlugin,\n\tplatform: PluginPlatform,\n\tmarketplaceDir: string,\n): StageResult {\n\tconst root = path.resolve(marketplaceDir);\n\tif (!existsSync(root)) {\n\t\treturn { ok: false, message: `Marketplace directory not found: ${root}` };\n\t}\n\tconst pluginRoot = path.resolve(plugin.root);\n\tif (pluginRoot === root || pluginRoot.startsWith(`${root}${path.sep}`)) {\n\t\treturn { ok: false, message: `Plugin \"${plugin.id}\" already lives inside ${root}; nothing to stage.` };\n\t}\n\n\tconst indexRel = INDEX_FILE[platform];\n\tconst indexAbs = path.join(root, indexRel);\n\tlet index: RawIndex;\n\tlet createdIndex = false;\n\tif (existsSync(indexAbs)) {\n\t\ttry {\n\t\t\tindex = JSON.parse(readFileSync(indexAbs, \"utf8\")) as RawIndex;\n\t\t} catch (error) {\n\t\t\treturn { ok: false, message: `${indexRel} is not valid JSON (${(error as Error).message}); fix it first.` };\n\t\t}\n\t} else {\n\t\t// A marketplace repo that does not have an index yet is a normal starting\n\t\t// point, and refusing here would mean the first plugin can never be staged.\n\t\tindex = { name: path.basename(root), plugins: [] };\n\t\tcreatedIndex = true;\n\t}\n\tif (!Array.isArray(index.plugins)) index.plugins = [];\n\n\tconst dest = path.join(root, VENDOR_DIR, plugin.id);\n\trmSync(dest, { recursive: true, force: true });\n\tmkdirSync(path.dirname(dest), { recursive: true });\n\tcpSync(pluginRoot, dest, {\n\t\trecursive: true,\n\t\tfilter: (src) => !INTERNAL_FILES.has(path.basename(src)),\n\t});\n\n\t// Vendored in the repo, so the source is a path relative to it — not the\n\t// git origin `packagePlugin` guessed, which points at wherever the plugin was\n\t// authored rather than at the marketplace.\n\tconst entry: MarketplaceEntry = { ...buildEntry(plugin), source: `./${VENDOR_DIR}/${plugin.id}` };\n\tconst existingAt = index.plugins.findIndex((p) => p?.name === plugin.id);\n\tif (existingAt >= 0) index.plugins[existingAt] = { ...index.plugins[existingAt], ...entry };\n\telse index.plugins.push(entry as unknown as Record<string, unknown>);\n\n\tmkdirSync(path.dirname(indexAbs), { recursive: true });\n\twriteFileSync(indexAbs, `${JSON.stringify(index, null, 2)}\\n`, \"utf8\");\n\n\tconst verb = existingAt >= 0 ? \"Updated\" : \"Added\";\n\treturn {\n\t\tok: true,\n\t\tmessage:\n\t\t\t`${verb} \"${plugin.id}\" in ${path.basename(root)}: copied to ${VENDOR_DIR}/${plugin.id}/ and ` +\n\t\t\t`${createdIndex ? \"created\" : \"updated\"} ${indexRel}. Nothing was committed or pushed.`,\n\t\tpluginPath: `${VENDOR_DIR}/${plugin.id}`,\n\t\tindexPath: indexRel,\n\t\tcreatedIndex,\n\t};\n}\n\n/** Read back the record packaging left, for callers that want to show it. */\nexport function readPublishRecord(dir: string): PublishRecord | undefined {\n\ttry {\n\t\tconst file = path.join(dir, PUBLISH_RECORD_FILE);\n\t\treturn existsSync(file) ? (JSON.parse(readFileSync(file, \"utf8\")) as PublishRecord) : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}