@kaptures/cli 0.9.0 → 0.10.0

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.
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Kapture — Visual Review</title>
7
- <script type="module" crossorigin src="./assets/index-Cu1qeajt.js"></script>
7
+ <script type="module" crossorigin src="./assets/index-9T0KHD4x.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="./assets/index-DwyrYFJS.css">
9
9
  </head>
10
10
  <body>
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import{createRequire as e}from"node:module";import{formatWithOptions as t,parseA
3
3
  `)}function Fe(e){return typeof e==`function`?e():e}function Ie(e=[],t={}){let r=new Set(t.boolean||[]),i=new Set(t.string||[]),a=t.alias||{},o=t.default||{},s=new Map,c=new Map;for(let[e,t]of Object.entries(a)){let n=t;for(let t of n)s.set(e,t),c.has(t)||c.set(t,[]),c.get(t).push(e),s.set(t,e),c.has(e)||c.set(e,[]),c.get(e).push(t)}let l={};function u(e){if(r.has(e))return`boolean`;let t=c.get(e)||[];for(let e of t)if(r.has(e))return`boolean`;return`string`}let d=new Set([...r,...i,...Object.keys(a),...Object.values(a).flat(),...Object.keys(o)]);for(let e of d)l[e]||(l[e]={type:u(e),default:o[e]});for(let[e,t]of s.entries())e.length===1&&l[t]&&!l[t].short&&(l[t].short=e);let f=[],p={};for(let t=0;t<e.length;t++){let n=e[t];if(n===`--`){f.push(...e.slice(t));break}if(n.startsWith(`--no-`)){let e=n.slice(5);p[e]=!0;continue}f.push(n)}let m;try{m=n({args:f,options:Object.keys(l).length>0?l:void 0,allowPositionals:!0,strict:!1})}catch{m={values:{},positionals:f}}let h={_:[]};h._=m.positionals;for(let[e,t]of Object.entries(m.values))h[e]=t;for(let[e]of Object.entries(p)){h[e]=!1;let t=s.get(e);t&&(h[t]=!1);let n=c.get(e);if(n)for(let e of n)h[e]=!1}for(let[e,t]of s.entries())h[e]!==void 0&&h[t]===void 0&&(h[t]=h[e]),h[t]!==void 0&&h[e]===void 0&&(h[e]=h[t]);return h}function Le(e,t){let n={boolean:[],string:[],alias:{},default:{}},r=Re(t);for(let e of r){if(e.type===`positional`)continue;e.type===`string`||e.type===`enum`?n.string.push(e.name):e.type===`boolean`&&n.boolean.push(e.name),e.default!==void 0&&(n.default[e.name]=e.default),e.alias&&(n.alias[e.name]=e.alias);let t=Oe(e.name),r=ke(e.name);if(t!==e.name||r!==e.name){let i=Ne(n.alias[e.name]||[]);t!==e.name&&!i.includes(t)&&i.push(t),r!==e.name&&!i.includes(r)&&i.push(r),i.length>0&&(n.alias[e.name]=i)}}let i=Ie(e,n),[...a]=i._,o=new Proxy(i,{get(e,t){return e[t]??e[Oe(t)]??e[ke(t)]}});for(let[,e]of r.entries())if(e.type===`positional`){let t=a.shift();if(t!==void 0)o[e.name]=t;else if(e.default===void 0&&e.required!==!1)throw new We(`Missing required positional argument: ${e.name.toUpperCase()}`,`EARG`);else o[e.name]=e.default}else if(e.type===`enum`){let t=o[e.name],n=e.options||[];if(t!==void 0&&n.length>0&&!n.includes(t))throw new We(`Invalid value for argument: ${Je(`--${e.name}`)} (${Je(t)}). Expected one of: ${n.map(e=>Je(e)).join(`, `)}.`,`EARG`)}else if(e.required&&o[e.name]===void 0)throw new We(`Missing required argument: --${e.name}`,`EARG`);return o}function Re(e){let t=[];for(let[n,r]of Object.entries(e||{}))t.push({...r,name:n,alias:Ne(r.alias)});return t}function k(e){return e}async function ze(e,t){let n=await Fe(e.args||{}),r=Le(t.rawArgs,n),i={rawArgs:t.rawArgs,args:r,data:t.data,cmd:e};typeof e.setup==`function`&&await e.setup(i);let a;try{let n=await Fe(e.subCommands);if(n&&Object.keys(n).length>0){let r=t.rawArgs.findIndex(e=>!e.startsWith(`-`)),i=t.rawArgs[r];if(i){if(!n[i])throw new We(`Unknown command ${Je(i)}`,`E_UNKNOWN_COMMAND`);let e=await Fe(n[i]);e&&await ze(e,{rawArgs:t.rawArgs.slice(r+1)})}else if(!e.run)throw new We(`No command specified.`,`E_NO_COMMAND`)}typeof e.run==`function`&&(a=await e.run(i))}finally{typeof e.cleanup==`function`&&await e.cleanup(i)}return{result:a}}async function Be(e,t,n){let r=await Fe(e.subCommands);if(r&&Object.keys(r).length>0){let n=t.findIndex(e=>!e.startsWith(`-`)),i=t[n],a=await Fe(r[i]);if(a)return Be(a,t.slice(n+1),e)}return[e,n]}async function Ve(e,t){try{console.log(await He(e,t)+`
4
4
  `)}catch(e){console.error(e)}}async function He(e,t){let n=await Fe(e.meta||{}),r=Re(await Fe(e.args||{})),i=await Fe(t?.meta||{}),a=`${i.name?`${i.name} `:``}`+(n.name||process.argv[1]),o=[],s=[],c=[],l=[];for(let e of r)if(e.type===`positional`){let t=e.name.toUpperCase(),n=e.required!==!1&&e.default===void 0,r=e.default?`="${e.default}"`:``;s.push([Je(t+r),e.description||``,e.valueHint?`<${e.valueHint}>`:``]),l.push(n?`<${t}>`:`[${t}]`)}else{let t=e.required===!0&&e.default===void 0,n=[...(e.alias||[]).map(e=>`-${e}`),`--${e.name}`].join(`, `)+(e.type===`string`&&(e.valueHint||e.default)?`=${e.valueHint?`<${e.valueHint}>`:`"${e.default||``}"`}`:``)+(e.type===`enum`&&e.options?`=<${e.options.join(`|`)}>`:``);if(o.push([Je(n+(t?` (required)`:``)),e.description||``]),e.type===`boolean`&&(e.default===!0||e.negativeDescription)&&!Ze.test(e.name)){let n=[...(e.alias||[]).map(e=>`--no-${e}`),`--no-${e.name}`].join(`, `);o.push([Je(n+(t?` (required)`:``)),e.negativeDescription||``])}t&&l.push(n)}if(e.subCommands){let t=[],n=await Fe(e.subCommands);for(let[e,r]of Object.entries(n)){let n=await Fe((await Fe(r))?.meta);n?.hidden||(c.push([Je(e),n?.description||``]),t.push(e))}l.push(t.join(`|`))}let u=[],d=n.version||i.version;u.push(Ye(`${n.description} (${a+(d?` v${d}`:``)})`),``);let f=o.length>0||s.length>0;return u.push(`${Xe(qe(`USAGE`))} ${Je(`${a}${f?` [OPTIONS]`:``} ${l.join(` `)}`)}`,``),s.length>0&&(u.push(Xe(qe(`ARGUMENTS`)),``),u.push(Pe(s,` `)),u.push(``)),o.length>0&&(u.push(Xe(qe(`OPTIONS`)),``),u.push(Pe(o,` `)),u.push(``)),c.length>0&&(u.push(Xe(qe(`COMMANDS`)),``),u.push(Pe(c,` `)),u.push(``,`Use ${Je(`${a} <command> --help`)} for more information about a command.`)),u.filter(e=>typeof e==`string`).join(`
5
5
  `)}async function Ue(e,t={}){let n=t.rawArgs||process.argv.slice(2),r=t.showUsage||Ve;try{if(n.includes(`--help`)||n.includes(`-h`))await r(...await Be(e,n)),process.exit(0);else if(n.length===1&&n[0]===`--version`){let t=typeof e.meta==`function`?await e.meta():await e.meta;if(!t?.version)throw new We(`No version specified`,`E_NO_VERSION`);console.log(t.version)}else await ze(e,{rawArgs:n})}catch(t){t instanceof We?(await r(...await Be(e,n)),console.error(t.message)):console.error(t,`
6
- `),process.exit(1)}}var We,Ge,Ke,qe,Je,Ye,Xe,Ze,A=E((()=>{Me(),We=class extends Error{code;constructor(e,t){super(e),this.name=`CLIError`,this.code=t}},Ge=(()=>{let e=globalThis.process?.env??{};return e.NO_COLOR===`1`||e.TERM===`dumb`||e.TEST||e.CI})(),Ke=(e,t=39)=>n=>Ge?n:`\u001B[${e}m${n}\u001B[${t}m`,qe=Ke(1,22),Je=Ke(36),Ye=Ke(90),Xe=Ke(4,24),Ze=/^no[-A-Z]/}));A();var Qe=`0.9.0`;const $e=e(import.meta.url);async function et(e=!1){let t=$e.resolve(`agent-browser/package.json`),n=[f(a(t),`bin`,`agent-browser.js`),`install`];e&&n.push(`--with-deps`);let i=await new Promise((e,t)=>{let i=r(process.execPath,n,{stdio:`inherit`});i.once(`error`,t),i.once(`exit`,(n,r)=>{r?t(Error(`agent-browser install stopped by ${r}`)):e(n??1)})});if(i!==0)throw Error(`agent-browser install exited with code ${i}`)}const tt=k({meta:{name:`browser`,description:`Manage the Kapture browser runtime`},subCommands:{install:k({meta:{name:`install`,description:`Install the Chrome runtime used by agent-browser`},args:{"with-deps":{type:`boolean`,default:!1,description:`Also install Linux system dependencies`}},async run({args:e}){await et(e[`with-deps`])}})}}),nt=[`npm`,`yarn`,`pnpm`,`bun`],rt={node:`actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38`,bun:`oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6`,checkout:`actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803`,upload:`actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f`,download:`actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53`},j=e=>`\${{ ${e} }}`,it=JSON.stringify,at=(e,t=10)=>e.split(`
6
+ `),process.exit(1)}}var We,Ge,Ke,qe,Je,Ye,Xe,Ze,A=E((()=>{Me(),We=class extends Error{code;constructor(e,t){super(e),this.name=`CLIError`,this.code=t}},Ge=(()=>{let e=globalThis.process?.env??{};return e.NO_COLOR===`1`||e.TERM===`dumb`||e.TEST||e.CI})(),Ke=(e,t=39)=>n=>Ge?n:`\u001B[${e}m${n}\u001B[${t}m`,qe=Ke(1,22),Je=Ke(36),Ye=Ke(90),Xe=Ke(4,24),Ze=/^no[-A-Z]/}));A();var Qe=`0.10.0`;const $e=e(import.meta.url);async function et(e=!1){let t=$e.resolve(`agent-browser/package.json`),n=[f(a(t),`bin`,`agent-browser.js`),`install`];e&&n.push(`--with-deps`);let i=await new Promise((e,t)=>{let i=r(process.execPath,n,{stdio:`inherit`});i.once(`error`,t),i.once(`exit`,(n,r)=>{r?t(Error(`agent-browser install stopped by ${r}`)):e(n??1)})});if(i!==0)throw Error(`agent-browser install exited with code ${i}`)}const tt=k({meta:{name:`browser`,description:`Manage the Kapture browser runtime`},subCommands:{install:k({meta:{name:`install`,description:`Install the Chrome runtime used by agent-browser`},args:{"with-deps":{type:`boolean`,default:!1,description:`Also install Linux system dependencies`}},async run({args:e}){await et(e[`with-deps`])}})}}),nt=[`npm`,`yarn`,`pnpm`,`bun`],rt={node:`actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38`,bun:`oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6`,checkout:`actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803`,upload:`actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f`,download:`actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53`},j=e=>`\${{ ${e} }}`,it=JSON.stringify,at=(e,t=10)=>e.split(`
7
7
  `).map(e=>`${` `.repeat(t)}${e}`).join(`
8
8
  `);function ot(e){let t=` - uses: ${rt.node}\n with: { node-version: "24" }\n`;return e===`bun`?`${t} - uses: ${rt.bun}\n`:e===`yarn`||e===`pnpm`?`${t} - run: corepack enable\n`:t}function st(e,t){if(!/^\d+\.\d+\.\d+(?:-[A-Za-z0-9.-]+)?$/.test(t))throw Error(`CLI version must be exact SemVer`);let n=`@kaptures/cli@${t}`;switch(e){case`npm`:return`npx --yes ${n}`;case`yarn`:return`yarn dlx --package ${n} kapture`;case`pnpm`:return`pnpm dlx ${n}`;case`bun`:return`bunx ${n}`}}function ct(e){let t=e.packageManager;if(!nt.includes(t))throw Error(`Unsupported package manager`);let n=st(`npm`,e.cliVersion),r=ot(`npm`),i=ot(t),a=e.baseBranch??`main`,o=e.storybookDirectory??`storybook-static`,s=e.adapterPackageJson;if(e.allowInitialAdoption&&!s)throw Error(`Initial adoption requires adapterPackageJson`);let c=e.allowInitialAdoption?` --allow-initial-adoption --adapter-package-json ${s}`:``;for(let e of[o,...s?[s]:[]])if(!/^[A-Za-z0-9._/-]+$/.test(e)||e.split(`/`).some(e=>!e||e===`.`||e===`..`))throw Error(`Expected safe project-relative paths`);if(!a||[...a].some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127))throw Error(`Expected a branch name`);let l=e.installCommand??{npm:`npm ci`,yarn:`case "$(yarn --version)" in
9
9
  1.*) yarn install --frozen-lockfile ;;
@@ -594,8 +594,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
594
594
  }
595
595
  await new Promise(resolve => setTimeout(resolve, 20));
596
596
  }
597
- })()`);if(i.kind===`timeout`)throw i.sawAdapter?Error(`Kapture Storybook adapter did not become ready for ${t} (last state: ${i.lastState??`unknown`}).`):Error(`Kapture Storybook adapter was not found for ${t}. Install @kaptures/storybook and register kapture() in .storybook/preview.`);let a;try{a=eu(i.value)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`${t}. Install matching versions of @kaptures/cli and @kaptures/storybook.`,{cause:e})}if(a.state===`error`){let e=a.error.kind===`configuration`?`configuration`:`lifecycle`;throw Error(`Kapture Storybook ${e} error for ${t}: ${a.error.message}`)}if(a.state!==`ready`||a.storyId!==t)throw Error(`Kapture Storybook returned invalid terminal state for ${t}`);if(a.adapterVersion!==n)throw Error(`Kapture adapter version mismatch for ${t}: CLI ${n}, Storybook ${a.adapterVersion}. Install matching exact versions of @kaptures/cli and @kaptures/storybook.`);return{adapterVersion:a.adapterVersion,generation:a.generation,parameters:a.parameters}}function wu(e,t){return e.adapterVersion===t.adapterVersion&&e.generation===t.generation}async function Tu(e,t=jd){let n=e.workers??4;if(!Number.isInteger(n)||n<1||n>8)throw Error(`Kapture workers must be between 1 and 8`);let r=f(e.outputDir);await y(r),await y(c(r,`images`));let i=await dl(e.headDir);try{let a=Zl(await Xl(i.url));if(!a.length)throw Error(`Initial adoption requires at least one story`);let[o,s]=await Promise.all([t.getBrowserVersion(),t.getFontsFingerprint()]),l=Gc({browserVersion:o,fontsFingerprint:s,frozenTime:e.frozenTime,randomSeed:e.randomSeed,locale:e.locale,timezone:e.timezone}),u=c(r,`hermetic-init.js`);await w(u,Zc(l));let d=Ou(e.headRevision,l);if(await Du({pairs:a.map(e=>({id:e.id,head:e})),requestedWorkers:n,namespace:`i-${process.pid.toString(36)}-${Date.now().toString(36)}`,initScriptPath:u,options:{...e,baseDir:e.headDir,baseRevision:e.headRevision},baseUrl:``,headUrl:i.url,baseOutput:r,headOutput:r,baseManifest:Ou(e.headRevision,l),headManifest:d,environment:l,captureBase:!1}),await hl(c(r,`manifest.json`),d),!Object.keys(d.snapshots).length)throw Error(`Initial adoption requires at least one enabled snapshot`);return d}finally{await i.close()}}async function Eu(e,t=jd){let n=f(e.outputDir),r=c(n,`capture`,`base`),i=c(n,`capture`,`head`),a=c(n,`report`);await re(n,{recursive:!0,force:!0}),await Promise.all([y(c(r,`images`),{recursive:!0}),y(c(i,`images`),{recursive:!0}),y(a,{recursive:!0})]);let[o,s]=await Promise.all([dl(e.baseDir),dl(e.headDir)]);try{let[l,u,d,f]=await Promise.all([Xl(o.url),Xl(s.url),xl(e.baseDir),xl(e.headDir)]),p=Zl(l),m=Zl(u),h=ju(p,m,e,{base:d.evidence,head:f.evidence}),g=Au(p,m,h.selectedStoryIds),[_,v]=g.length===0?[`not-launched:no-affected-stories-v1`,`not-inspected:no-affected-stories-v1`]:await Promise.all([t.getBrowserVersion(),t.getFontsFingerprint()]),b=Gc({browserVersion:_,fontsFingerprint:v,frozenTime:e.frozenTime,randomSeed:e.randomSeed,locale:e.locale,timezone:e.timezone}),ee=c(n,`hermetic-init.js`);await w(ee,Zc(b));let x=`k-${process.pid.toString(36)}-${Date.now().toString(36)}`,S=e.baseCaptureDir?await Bu(e.baseCaptureDir,r,e.baseRevision,b,g):void 0;if(!S&&e.captureCacheDir&&g.length>0)try{let t=await _l(e.baseDir,e.adapterVersion),n=await vl(e.captureCacheDir,t),i=await Bu(e.captureCacheDir,r,n.revision,b,g,!0);for(let e of Object.values(i.manifest.snapshots))e.sourceRevision??=n.revision;i.manifest.revision=e.baseRevision,S=i}catch(e){console.warn(`Kapture capture cache miss: ${e instanceof Error?e.message:String(e)}`)}S&&(h.baseline={mode:`reused`,revision:S.manifest.revision,manifestDigest:S.manifestDigest});let te=S?.manifest??Ou(e.baseRevision,b),ne=Ou(e.headRevision,b),C=e.workers??4;if(!Number.isInteger(C)||C<1||C>8)throw Error(`Kapture workers must be between 1 and 8`);await Du({pairs:g,requestedWorkers:C,namespace:x,initScriptPath:ee,options:e,baseUrl:o.url,headUrl:s.url,baseOutput:r,headOutput:i,baseManifest:te,headManifest:ne,environment:b,captureBase:!S||!!e.captureCacheDir,cachedBaseStoryIds:S?new Set(Object.values(S.manifest.snapshots).map(e=>e.storyId)):void 0}),S&&await Vu({baseline:S.manifest,baselineRoot:S.root,headManifest:ne,headOutput:i,selectedStoryIds:h.selectedStoryIds,removedStoryIds:h.removedStoryIds??[]}),await Promise.all([hl(c(r,`manifest.json`),te),hl(c(i,`manifest.json`),ne)]);let T={...ad,...e.threshold},ie=c(n,`stability-candidates`),ae=await sl({baseManifest:te,headManifest:ne,baseRoot:r,headRoot:i,outputDir:ie,threshold:T,coverage:h}),oe=new Set(Object.values(ae.entries).filter(e=>e.status===`changed`).map(e=>e.id)),se;if(oe.size>0){let t=new Set(Object.values(ae.entries).filter(e=>oe.has(e.id)).map(e=>e.storyId)),r=g.filter(e=>t.has(e.id)),i=c(n,`capture`,`base-repeat`),a=c(n,`capture`,`head-repeat`);await Promise.all([y(c(i,`images`),{recursive:!0}),y(c(a,`images`),{recursive:!0})]);let l=Ou(e.baseRevision,b),u=Ou(e.headRevision,b);await Du({pairs:r,requestedWorkers:C,namespace:`${x}-s`,initScriptPath:ee,options:e,baseUrl:o.url,headUrl:s.url,baseOutput:i,headOutput:a,baseManifest:l,headManifest:u,environment:b,captureBase:!0}),await Promise.all([hl(c(i,`manifest.json`),l),hl(c(a,`manifest.json`),u)]),se={baseManifest:l,headManifest:u,baseRoot:i,headRoot:a}}await re(ie,{recursive:!0,force:!0});let ce=await sl({baseManifest:te,headManifest:ne,baseRoot:r,headRoot:i,outputDir:a,threshold:T,coverage:h,stability:se});if(e.captureCacheOutput&&ce.summary.errors===0&&ce.summary.unstable===0)try{let t=await _l(e.headDir,e.adapterVersion);await yl(e.captureCacheOutput,i,t,ne)}catch(e){console.warn(`Kapture capture cache export unavailable: ${e instanceof Error?e.message:String(e)}`)}return{baseManifest:te,headManifest:ne,report:ce}}finally{await Promise.allSettled([o.close(),s.close()])}}async function Du(e){let t=Math.min(e.requestedWorkers,e.pairs.length),n=e.captureBase&&e.pairs.some(t=>!!t.base&&!e.cachedBaseStoryIds?.has(t.id)),r=e.pairs.some(e=>!!e.head),i=[...e.pairs],a=[],o=[];try{for(let i=0;i<t;i+=1){let t={};n&&(t.base=ku(i,`base`,e.options,{namespace:e.namespace,initScriptPath:e.initScriptPath,environment:e.environment}),o.push(t.base)),r&&(t.head=ku(i,`head`,e.options,{namespace:e.namespace,initScriptPath:e.initScriptPath,environment:e.environment}),o.push(t.head)),a.push(t)}await Promise.all(a.map(async t=>{for(;i.length>0;){let n=i.shift();if(!n)return;await Iu({workers:t,pair:n,baseUrl:e.baseUrl,headUrl:e.headUrl,baseOutput:e.baseOutput,headOutput:e.headOutput,baseManifest:e.baseManifest,headManifest:e.headManifest,environment:e.environment,adapterVersion:e.options.adapterVersion,captureBase:e.captureBase&&!e.cachedBaseStoryIds?.has(n.id)})}}))}finally{await Promise.allSettled(o.map(e=>Promise.resolve().then(()=>e.close())))}}function Ou(e,t){return{version:2,revision:e,environment:t,createdAt:new Date().toISOString(),snapshots:{}}}function ku(e,t,n,r){let i={...r,target:t};return n.workerFactory?n.workerFactory(e,i):new nd({id:`${r.namespace}-${t}-${e}`,namespace:r.namespace,initScriptPath:r.initScriptPath,timezone:r.environment.timezone,locale:r.environment.locale,deviceScaleFactor:r.environment.deviceScaleFactor,allowedDomains:r.environment.network.allowedDomains})}function Au(e,t,n){let r=new Map(e.map(e=>[e.id,e])),i=new Map(t.map(e=>[e.id,e])),a=[...new Set([...r.keys(),...i.keys()])].sort(),o=n?[...new Set(n)].sort():a,s=new Set(a),c=o.filter(e=>!s.has(e));if(c.length>0)throw Error(`Unknown Kapture story IDs: ${c.join(`, `)}`);return o.map(e=>({id:e,base:r.get(e),head:i.get(e)}))}function ju(e,t,n,r){if(n.selectionPlan&&n.storyIds)throw Error(`Kapture selectionPlan and storyIds cannot be provided together`);let i=[...new Set([...e,...t].map(e=>e.id))].sort(),a=new Set(e.map(e=>e.id)),o=new Set(t.map(e=>e.id)),s=i.filter(e=>!a.has(e)&&o.has(e)),c=i.filter(e=>a.has(e)&&!o.has(e)),l=Mu(r,n.baseRevision,n.headRevision),u=n.selectionPlan;if(u){if(Fu(u.totalStoryIds,i,`selection plan catalog`),Fu(u.addedStoryIds,s,`selection plan added stories`),Fu(u.removedStoryIds,c,`selection plan removed stories`),Nu(u.dependencyManifests,r),Pu(u.selectedStoryIds,u.skippedStoryIds,i),u.selectionMode===`full-fallback`&&u.fallbackReasons.length===0)throw Error(`Kapture full-fallback selection plan requires a fallback reason`);if(u.selectionMode===`affected`&&u.fallbackReasons.length>0)throw Error(`Kapture affected selection plan cannot contain fallback reasons`);return{plannerVersion:1,mode:u.selectionMode,...u.changedFilesEvidence?{changedFilesEvidence:{...u.changedFilesEvidence}}:{},dependencyManifests:l,storyIds:i,selectedStoryIds:[...u.selectedStoryIds],skippedStoryIds:[...u.skippedStoryIds],addedStoryIds:s,removedStoryIds:c,fallbackReasons:u.fallbackReasons.map(e=>({...e}))}}if(n.storyIds){let e=[...new Set(n.storyIds)].sort(),t=new Set(i),r=e.filter(e=>!t.has(e));if(r.length>0)throw Error(`Unknown Kapture story IDs: ${r.join(`, `)}`);let a=new Set(e);return{plannerVersion:1,mode:`affected`,dependencyManifests:l,storyIds:i,selectedStoryIds:e,skippedStoryIds:i.filter(e=>!a.has(e)),addedStoryIds:s,removedStoryIds:c,fallbackReasons:[]}}return{plannerVersion:1,mode:`full`,dependencyManifests:l,storyIds:i,selectedStoryIds:i,skippedStoryIds:[],addedStoryIds:s,removedStoryIds:c,fallbackReasons:[]}}function Mu(e,t,n){return{base:{...e.base,revision:t},head:{...e.head,revision:n}}}function Nu(e,t){if(JSON.stringify(e)!==JSON.stringify(t))throw Error(`Kapture selection plan dependency manifests do not match the built Storybook artifacts`)}function Pu(e,t,n){Fu(e,[...new Set(e)].sort(),`selected stories`),Fu(t,[...new Set(t)].sort(),`skipped stories`);let r=new Set(e),i=[...e,...t].sort();if(t.some(e=>r.has(e)))throw Error(`Kapture selection plan cannot select and skip the same story`);Fu(i,n,`selection plan partition`)}function Fu(e,t,n){if(e.length!==t.length||e.some((e,n)=>e!==t[n]))throw Error(`Kapture ${n} does not match the built Storybook catalog`)}async function Iu(e){let t={base:Lu(!!e.pair.base&&e.captureBase),head:Lu(!!e.pair.head)},n=[];e.pair.base&&e.captureBase&&n.push(Ru(e,`base`,t)),e.pair.head&&n.push(Ru(e,`head`,t)),await Promise.all(n)}function Lu(e){if(!e)return{promise:Promise.resolve(void 0),resolve:()=>void 0};let t=()=>void 0,n=!1;return{promise:new Promise(e=>{t=e}),resolve(e){n||(n=!0,t(e))}}}async function Ru(e,t,n){let r=e.pair[t];if(!r)return;let i=e.workers[t];if(!i)throw Error(`Kapture ${t} browser worker was not initialized`);let a=t===`base`?e.baseManifest:e.headManifest,o=t===`base`?e.baseUrl:e.headUrl,s=t===`base`?e.baseOutput:e.headOutput,c=t===`base`?`head`:`base`;try{await i.runAttempt({target:t,storyId:r.id},async i=>{let l=await Hu(i,o,r,e.environment,e.adapterVersion).catch(Yu);if(n[t].resolve(l),l instanceof Error){qu(a,r,l);return}let u=await n[c].promise;if(u instanceof Error)return;let d=t===`base`?l.parameters:u?.parameters,f=t===`head`?l.parameters:u?.parameters,p=e.captureBase?Uu(d,f,!!e.pair.base,!!e.pair.head):zu(e.baseManifest,e.pair.id,f,!!e.pair.head);for(let n of p){let c=n[t];!c||l.parameters.captureEnabled===!1||await Wu({driver:i,story:r,baseUrl:o,outputRoot:s,manifest:a,viewport:c,parameters:l.parameters,captureArea:l.parameters.captureArea,threshold:Gu(l.parameters.diff),adapterVersion:e.adapterVersion})}})}catch(e){let i=Yu(e);n[t].resolve(i),Ju(a,r,i)}}function zu(e,t,n,r=!0){let i=Object.values(e.snapshots).filter(e=>e.storyId===t).map(e=>e.viewport),a=!r||n?.captureEnabled===!1?[]:n?.captureViewports??[id],o=new Map(i.map(e=>[e.name,e])),s=new Map(a.map(e=>[e.name,e]));return[...new Set([...o.keys(),...s.keys()])].sort().map(e=>({base:o.get(e),head:s.get(e)}))}async function Bu(e,t,n,r,i,a=!1){let o=f(e),s=c(o,`manifest.json`),l=await gl(s);if(l.revision!==n)throw Error(`Kapture baseline revision ${l.revision} does not match requested base ${n}`);Jc(l.environment,r);let u=new Set(i.filter(e=>e.base).map(e=>e.id)),d={...l.snapshots};for(let e of u)if(!a&&!Object.values(d).some(t=>t.storyId===e))throw Error(`Kapture baseline does not contain selected base story ${e}`);return await Promise.all(Object.values(d).map(async e=>{if(e.error)return;let n=c(o,e.imageFile);if(await al(n)!==e.sha256)throw Error(`Kapture baseline image digest mismatch for ${e.id}`);await g(n,c(t,e.imageFile))})),{root:t,manifest:{...l,snapshots:d},manifestDigest:await al(s)}}async function Vu(e){let t=new Set(e.selectedStoryIds),n=new Set(e.removedStoryIds);await Promise.all(Object.values(e.baseline.snapshots).map(async r=>{t.has(r.storyId)||n.has(r.storyId)||(e.headManifest.snapshots[r.id]={...r,sourceRevision:r.sourceRevision??e.baseline.revision},!r.error&&await g(c(e.baselineRoot,r.imageFile),c(e.headOutput,r.imageFile)))}))}async function Hu(e,t,n,r,i){return await e.setViewport(id),await e.setMedia(r.colorScheme,r.reducedMotion===`reduce`),await e.open(Ql(t,n.id)),Cu(e,n.id,i)}function Uu(e,t,n=!0,r=!0){let i=!n||e?.captureEnabled===!1?[]:e?.captureViewports??[id],a=!r||t?.captureEnabled===!1?[]:t?.captureViewports??[id],o=new Map(i.map(e=>[e.name,e])),s=new Map(a.map(e=>[e.name,e]));return[...new Set([...o.keys(),...s.keys()])].sort().map(e=>({base:o.get(e),head:s.get(e)}))}async function Wu(e){let{driver:t,story:n,baseUrl:r,outputRoot:i,manifest:a,viewport:o,parameters:s,captureArea:l,threshold:u,adapterVersion:f}=e,p=`${n.id}@${o.name}`,m=c(`images`,ol(p)),h=c(i,m),g=performance.now();try{await t.setViewport(o),await t.setMedia(a.environment.colorScheme,a.environment.reducedMotion===`reduce`),await t.open(Ql(r,n.id));let e=await Cu(t,n.id,f);Ku(e,s,n.id);let c;for(let r=1;r<=3;r+=1){c=await Bc(t,a.environment,e.parameters);let i=await Cu(t,n.id,f);if(Ku(i,s,n.id),wu(e,i))break;if(r===3)throw Error(`Kapture story ${n.id} kept rerendering while the capture was stabilizing`);e=i,c=void 0}if(!c)throw Error(`Kapture could not stabilize ${n.id}`);await t.screenshot(h,{fullPage:l!==`viewport`}),a.snapshots[p]={id:p,storyId:n.id,title:n.title,name:n.name,viewport:o,imageFile:d(i,h),sha256:await al(h),capturedAt:new Date().toISOString(),durationMs:Math.round(performance.now()-g),ignoredRegions:c.ignoredRegions.length>0?c.ignoredRegions:void 0,threshold:u}}catch(e){a.snapshots[p]={id:p,storyId:n.id,title:n.title,name:n.name,viewport:o,imageFile:m,sha256:``,capturedAt:new Date().toISOString(),durationMs:Math.round(performance.now()-g),threshold:u,error:e instanceof Error?e.message:String(e)}}}function Gu(e){if(e)return{...e.pixelColorThreshold===void 0?{}:{pixelColorThreshold:e.pixelColorThreshold},...e.maxChangedPixelPercentage===void 0?{}:{maxChangedPixelRatio:e.maxChangedPixelPercentage/100}}}function Ku(e,t,n){if(JSON.stringify(e.parameters)!==JSON.stringify(t))throw Error(`Kapture parameters changed between metadata and capture for ${n}`)}function qu(e,t,n){let r=`${t.id}@metadata`;e.snapshots[r]={id:r,storyId:t.id,title:t.title,name:t.name,viewport:id,imageFile:``,sha256:``,capturedAt:new Date().toISOString(),durationMs:0,error:n.message}}function Ju(e,t,n){let r=`${t.id}@attempt`;e.snapshots[r]={id:r,storyId:t.id,title:t.title,name:t.name,viewport:id,imageFile:``,sha256:``,capturedAt:new Date().toISOString(),durationMs:0,error:n.message}}function Yu(e){return e instanceof Error?e:Error(String(e))}async function Xu(e,t){if(!(await C(e)).isDirectory())throw Error(`Dashboard build is not a directory: ${e}`);await _(e,t,{recursive:!0,force:!0});let n=f(t,`index.html`),r=f(t,`report.json`),[i,a]=await Promise.all([x(n,`utf8`),x(r,`utf8`)]),o=Zu(i,/<link\b[^>]*\brel=["']stylesheet["'][^>]*\bhref=["']([^"']+)["'][^>]*>/i,`stylesheet`),s=Zu(i,/<script\b[^>]*\bsrc=["']([^"']+)["'][^>]*><\/script>/i,`module script`),[c,l]=await Promise.all([Qu(t,o.url),Qu(t,s.url)]),u=$u(c,o.url),d=`<script id="kapture-report-data" type="application/json">${a.trim().replaceAll(`<`,`\\u003c`)}<\/script>\n<script data-kapture-dashboard>"use strict";\n${l.replace(/<\/script/gi,`<\\/script`)}<\/script>`,p=i.replace(o.tag,()=>`<style>${u}</style>`).replace(s.tag,``);if(!p.includes(`</body>`))throw Error(`Dashboard index is missing its closing body tag`);let m=p.replace(`</body>`,()=>`${d}\n</body>`);await w(n,m)}function Zu(e,t,n){let r=e.match(t);if(!r?.[1])throw Error(`Dashboard index is missing its ${n}`);return{tag:r[0],url:r[1]}}async function Qu(e,t){if(/^[a-z]+:/i.test(t)||t.startsWith(`/`)||t.includes(`?`))throw Error(`Dashboard asset must be a relative local path: ${t}`);let n=f(e),r=f(n,t);if(!r.startsWith(`${n}${p}`))throw Error(`Dashboard asset resolves outside the report directory: ${t}`);return x(r,`utf8`)}function $u(e,t){let n=u.dirname(t);return e.replace(/url\((["']?)(\.\/[^"')]+)\1\)/g,(e,t,r)=>{let i=u.join(n,r);return`url(${t}${i.startsWith(`.`)?i:`./${i}`}${t})`})}var ed,td,nd,rd,id,ad,od,sd,cd,ld,ud,dd,fd,pd,md,hd,gd,_d,vd,yd,bd,xd,Sd,Cd,wd,Td,Ed,Dd,Od,kd,Ad,jd,Md=E((()=>{_t(),ed=zt(),Fc(),td=class{session;isolation=`browser-process`;namespace;initScriptPath;timezone;locale;deviceScaleFactor;allowedDomains;timeoutMs;bin;commandStarted=!1;closePromise;constructor(e){this.session=e.session,this.namespace=e.namespace,this.initScriptPath=e.initScriptPath,this.timezone=e.timezone,this.locale=e.locale,this.deviceScaleFactor=e.deviceScaleFactor,this.allowedDomains=e.allowedDomains,this.timeoutMs=e.timeoutMs??3e4,this.bin=zc()}open(e){return this.execVoid([`open`,e])}setViewport(e){return this.execVoid([`set`,`viewport`,String(e.width),String(e.height)])}setMedia(e,t){let n=[`set`,`media`,e];return t&&n.push(`reduced-motion`),this.execVoid(n)}async evaluate(e){let t=await this.exec([`eval`,e]),n=JSON.parse(t);if(n.success===!1)throw Error(n.error??`agent-browser eval failed`);return n.data&&typeof n.data==`object`&&`result`in n.data?n.data.result:n.data===void 0?n.result===void 0?n:n.result:n.data}screenshot(e,t){return this.execVoid([`screenshot`,...t.fullPage?[`--full`]:[],e])}close(){return this.closePromise?this.closePromise:this.commandStarted?(this.closePromise=this.execVoid([`close`],!0),this.closePromise):(this.closePromise=Promise.resolve(),this.closePromise)}async execVoid(e,t=!1){let n=await this.exec(e,t);try{let t=JSON.parse(n);if(t.success===!1)throw Error(t.error??`agent-browser command failed: ${e.join(` `)}`)}catch(e){if(e instanceof SyntaxError)return;throw e}}exec(e,t=!1){if(this.closePromise&&!t)return Promise.reject(Error(`agent-browser session ${this.session} is closed`));t||(this.commandStarted=!0);let n=[`--session`,this.session,`--namespace`,this.namespace,`--init-script`,this.initScriptPath,`--allowed-domains`,this.allowedDomains.join(`,`),`--args`,`--force-device-scale-factor=${this.deviceScaleFactor},--lang=${this.locale}`,`--json`,...e];return new Promise((t,i)=>{let a=r(this.bin,n,{env:{...process.env,LANG:`${this.locale}.UTF-8`,TZ:this.timezone},stdio:[`ignore`,`pipe`,`pipe`]}),o=[],s=[];a.stdout.on(`data`,e=>o.push(e)),a.stderr.on(`data`,e=>s.push(e));let c=setTimeout(()=>{a.kill(),i(Error(`agent-browser timed out after ${this.timeoutMs}ms: ${e.join(` `)}`))},this.timeoutMs);a.once(`error`,e=>{clearTimeout(c),i(e)}),a.once(`close`,e=>{clearTimeout(c);let n=Buffer.concat(o).toString(`utf8`).trim(),r=Buffer.concat(s).toString(`utf8`).trim();if(e!==0){i(Error(`agent-browser failed (${e}): ${r||n}`));return}t(n)})})}},nd=class{id;options;attemptFactory;sessionPrefix;attemptNumber=0;activeAttempt;closed=!1;constructor(e,t=e=>new td(e)){this.id=e.id,this.sessionPrefix=`kw-${T(`sha256`).update(e.id).digest(`hex`).slice(0,8)}`;let{id:n,...r}=e;this.options=r,this.attemptFactory=t}async runAttempt(e,t){if(this.closed)throw Error(`Browser worker ${this.id} is closed`);if(this.activeAttempt)throw Error(`Browser worker ${this.id} already has an active attempt`);let n=++this.attemptNumber,r=new rd(e,this.attemptFactory({...this.options,session:`${this.sessionPrefix}-${e.target[0]}-${n.toString(36)}`}));this.activeAttempt=r;let i,a,o=!1;try{i=await t(r)}catch(e){o=!0,a=e}let s,c=!1;try{await r.close()}catch(e){c=!0,s=e}finally{this.activeAttempt===r&&(this.activeAttempt=void 0)}if(o&&c)throw AggregateError([a,s],`Browser attempt ${r.session} failed and could not be closed`);if(o)throw a;if(c)throw s;return i}async close(){if(this.closed)return;this.closed=!0;let e=this.activeAttempt;e&&(await e.close(),this.activeAttempt===e&&(this.activeAttempt=void 0))}},rd=class{scope;driver;isolation=`browser-process`;closePromise;constructor(e,t){this.scope=e,this.driver=t}get session(){return this.driver.session}open(e){return this.driver.open(e)}setViewport(e){return this.driver.setViewport(e)}setMedia(e,t){return this.driver.setMedia(e,t)}evaluate(e){return this.driver.evaluate(e)}screenshot(e,t){return this.driver.screenshot(e,t)}close(){return this.closePromise??=this.driver.close(),this.closePromise}},id={name:`default`,width:1280,height:800},ad={pixelColorThreshold:.2,maxChangedPixelRatio:0},od=[`baseImage`,`headImage`,`diffImage`],sd=/^[0-9a-f]{64}$/,cd={".css":`text/css; charset=utf-8`,".html":`text/html; charset=utf-8`,".ico":`image/x-icon`,".jpeg":`image/jpeg`,".jpg":`image/jpeg`,".js":`text/javascript; charset=utf-8`,".json":`application/json; charset=utf-8`,".mjs":`text/javascript; charset=utf-8`,".png":`image/png`,".svg":`image/svg+xml`,".woff":`font/woff`,".woff2":`font/woff2`},ld=B({name:R(),width:z(),height:z()}),ud=B({id:R(),browser:R(),browserVersion:R(),orchestratorRuntime:R(),operatingSystem:R(),architecture:R(),deviceScaleFactor:z(),locale:R(),timezone:R(),colorScheme:Os([`light`,`dark`]),reducedMotion:Os([`reduce`,`no-preference`]),frozenTime:R(),randomSeed:z(),fontsFingerprint:R(),stateIsolation:V(`fresh-browser-process-per-story-side-v1`).optional(),network:B({mode:V(`allowlist`),allowedDomains:Ss(R()),webRtc:V(`disabled`)})}),dd=B({id:R(),storyId:R(),title:R(),name:R(),viewport:ld,imageFile:R(),sha256:R(),capturedAt:R(),durationMs:z(),sourceRevision:R().optional(),ignoredRegions:Ss(B({x:z().int().nonnegative(),y:z().int().nonnegative(),width:z().int().positive(),height:z().int().positive()})).optional(),threshold:B({pixelColorThreshold:z().optional(),maxChangedPixelRatio:z().optional()}).optional(),error:R().optional()}).superRefine((e,t)=>{e.error||(/^images\/[A-Za-z0-9._-]+\.png$/.test(e.imageFile)||t.addIssue({code:`custom`,path:[`imageFile`],message:`must be a safe image path`}),/^[0-9a-f]{64}$/.test(e.sha256)||t.addIssue({code:`custom`,path:[`sha256`],message:`must be a SHA-256 digest`}))}),fd=B({version:V(2),revision:R(),environment:ud,createdAt:R(),snapshots:Ds(R(),dd)}),pd=B({version:V(1),buildDigest:R().regex(/^[a-f0-9]{64}$/),manifestDigest:R().regex(/^[a-f0-9]{64}$/)}),md=`kapture-dependencies.json`,hd=R().min(1).max(4096).refine(Dl,`must be a normalized project-relative path`),gd=R().max(4096).refine(e=>e===``||Dl(e),{message:`must be empty or a normalized project-relative path`}),_d=Ss(hd).max(1e5).refine(e=>new Set(e).size===e.length,`must not contain duplicates`),vd=R().regex(/^[0-9a-f]{64}$/),yd=Cs({type:Os([`asset`,`chunk`]),size:z().int().nonnegative().max(1e9),sha256:vd}).strict(),bd=R().max(4096).refine(e=>e===``||e.endsWith(`/`)&&Dl(e.slice(0,-1)),`must be empty or a normalized project-relative directory prefix`),xd=R().min(1).max(1024),Sd=Ss(xd).max(1e4).refine(e=>new Set(e).size===e.length,`must not contain duplicates`),Cd=Ds(hd,Ds(hd,Sd)),wd=Ds(hd,Ds(xd,Cs({module:hd,imported:xd}).strict())),Td=Cs({kind:V(`kapture-storybook-dependencies`),version:V(1),complete:ys(),storybookRoot:gd,globalInputs:_d,ignoredInputs:_d,fingerprintedInputs:_d.optional(),diagnostics:Ss(Os([`module-outside-project-root`,`module-fingerprint-missing`,`unresolved-virtual-module`,`unresolved-project-module`,`rendered-output-fingerprint-missing`,`global-output-fingerprint-missing`,`global-runtime-fingerprint-missing`,`unowned-output-chunk`,`output-inventory-mismatch`])).max(20).refine(e=>new Set(e).size===e.length,`must not contain duplicates`),modules:Ds(hd,_d),moduleFingerprints:Ds(hd,vd).optional(),globalOutputFingerprints:Ds(hd,vd),globalOutputStories:Ds(hd,_d),globalRuntimeFingerprint:vd,outputInventory:Ds(hd,yd),outputInventoryPrefixes:Ss(bd).max(100).refine(e=>new Set(e).size===e.length,`must not contain duplicates`),importBindings:Cd.optional(),reexportBindings:wd.optional(),renderedModules:Ds(hd,_d),renderedOutputFingerprints:Ds(hd,vd)}).strict().superRefine((e,t)=>{let n=Object.entries(e.modules),r=new Set(n.map(([e])=>e));n.length>1e5&&t.addIssue({code:`custom`,path:[`modules`],message:`contains too many modules`});for(let[i,a]of n)a.includes(i)||t.addIssue({code:`custom`,path:[`modules`,i],message:`must include the module itself`}),e.complete&&a.some(e=>!r.has(e))&&t.addIssue({code:`custom`,path:[`modules`,i],message:`must resolve every project dependency when the manifest is complete`});Object.keys(e.globalOutputFingerprints).length>1e5&&t.addIssue({code:`custom`,path:[`globalOutputFingerprints`],message:`contains too many global output fingerprints`});let i=new Set(Object.keys(e.globalOutputFingerprints)),a=Object.entries(e.globalOutputStories);a.length>1e5&&t.addIssue({code:`custom`,path:[`globalOutputStories`],message:`contains too many global output story lists`});for(let[e,n]of a){i.has(e)||t.addIssue({code:`custom`,path:[`globalOutputStories`,e],message:`must identify a fingerprinted global output`});for(let i of n)if(!r.has(i)){t.addIssue({code:`custom`,path:[`globalOutputStories`,e],message:`must contain only rendered story modules`});break}}for(let n of i)n in e.globalOutputStories||t.addIssue({code:`custom`,path:[`globalOutputStories`,n],message:`must cover every fingerprinted global output`});let o=Object.entries(e.outputInventory);o.length>1e5&&t.addIssue({code:`custom`,path:[`outputInventory`],message:`contains too many output files`}),`kapture-dependencies.json`in e.outputInventory&&t.addIssue({code:`custom`,path:[`outputInventory`,md],message:`must not inventory the manifest itself`});for(let n of e.outputInventoryPrefixes)o.some(([e])=>e.startsWith(n))||t.addIssue({code:`custom`,path:[`outputInventoryPrefixes`],message:`must cover at least one inventoried output`});let s=Object.entries(e.moduleFingerprints??{});s.length>1e5&&t.addIssue({code:`custom`,path:[`moduleFingerprints`],message:`contains too many module fingerprints`});for(let[e]of s)r.has(e)||t.addIssue({code:`custom`,path:[`moduleFingerprints`,e],message:`must identify a rendered module`});(e.fingerprintedInputs?.length??0)>0&&(e.moduleFingerprints?e.complete&&n.some(([t])=>!e.moduleFingerprints?.[t])&&t.addIssue({code:`custom`,path:[`moduleFingerprints`],message:`must cover every rendered module when the manifest is complete`}):t.addIssue({code:`custom`,path:[`moduleFingerprints`],message:`is required when fingerprintedInputs are configured`}));let c=0;for(let[n,i]of Object.entries(e.importBindings??{})){c+=Object.keys(i).length,r.has(n)||t.addIssue({code:`custom`,path:[`importBindings`,n],message:`must identify a rendered importer`});for(let r of Object.keys(i))e.modules[n]?.includes(r)||t.addIssue({code:`custom`,path:[`importBindings`,n,r],message:`must identify a direct project dependency`})}for(let[n,i]of Object.entries(e.reexportBindings??{})){c+=Object.keys(i).length,r.has(n)||t.addIssue({code:`custom`,path:[`reexportBindings`,n],message:`must identify a rendered barrel`});for(let[r,a]of Object.entries(i))e.modules[n]?.includes(a.module)||t.addIssue({code:`custom`,path:[`reexportBindings`,n,r],message:`must identify a direct project dependency`})}c>1e6&&t.addIssue({code:`custom`,path:[`importBindings`],message:`contains too many import and re-export bindings`});let l=Object.entries(e.renderedModules??{});l.length>1e5&&t.addIssue({code:`custom`,path:[`renderedModules`],message:`contains too many rendered module closures`});let u=0;for(let[e,n]of l){u+=n.length,r.has(e)||t.addIssue({code:`custom`,path:[`renderedModules`,e],message:`must identify a rendered entry module`}),n.includes(e)||t.addIssue({code:`custom`,path:[`renderedModules`,e],message:`must include the entry module itself`});for(let i of n)if(!r.has(i)){t.addIssue({code:`custom`,path:[`renderedModules`,e],message:`must contain only rendered project modules`});break}}u>5e6&&t.addIssue({code:`custom`,path:[`renderedModules`],message:`contains too many rendered module references`});let d=Object.entries(e.renderedOutputFingerprints);d.length>1e5&&t.addIssue({code:`custom`,path:[`renderedOutputFingerprints`],message:`contains too many rendered output fingerprints`});for(let[e]of d)r.has(e)||t.addIssue({code:`custom`,path:[`renderedOutputFingerprints`,e],message:`must identify a rendered entry module`});e.complete&&l.some(([t])=>e.renderedOutputFingerprints[t]===void 0)&&t.addIssue({code:`custom`,path:[`renderedOutputFingerprints`],message:`must cover every rendered entry module when the manifest is complete`}),e.complete!==(e.diagnostics.length===0)&&t.addIssue({code:`custom`,path:[`complete`],message:`must agree with diagnostics`})}),Ed=1e3,Dd=Cs({id:R().min(1),type:Os([`story`,`docs`]),importPath:R().min(1).optional()}).passthrough(),Od=Cs({entries:Ds(R(),Dd)}).passthrough(),kd=Cs({id:R().min(1),title:R(),name:R(),type:Os([`story`,`docs`])}),Ad=Cs({v:z(),entries:Ds(R(),kd)}),jd={getBrowserVersion:Ic,getFontsFingerprint:Yc}}));Md();const Nd={executionErrors:e=>`❌ **${e} execution error(s)** must be fixed.`,clean:`✅ No visual changes.`,changes:e=>`🔍 **${e} visual change(s)** require review.`,unstableWarning:e=>`⚠️ **${e} unstable snapshot(s)** changed between same-revision captures and do not block this build.`,comparison:(e,t)=>`**${e} stories · ${t} snapshots compared**`,coverage:(e,t,n,r,i,a)=>e===`affected`?`**${n} of ${t} affected stories selected · ${r} stories / ${i} snapshots compared · ${a} proven unaffected**`:`**${n} stories selected · ${r} stories / ${i} snapshots compared**`,fallback:e=>`- Safe full-capture fallback: ${e.join(`, `)}`,counts:e=>`- Unchanged ${e.unchanged} · Changed ${e.changed} · Unstable ${e.unstable} · Added ${e.added} · Removed ${e.removed} · Errors ${e.errors}`,branch:`Branch`,environment:`Environment`,reportDownload:`Download the full comparison report`,reportOpen:`Open the full comparison report`,storyOpen:`Open captured story`,sections:{error:`🚨 Execution errors`,removed:`⚠️ Removed snapshots`,changed:`🔍 Visual changes`,unstable:`⚠️ Unstable snapshots`,added:`➕ Added snapshots`},hidden:e=>`${e} more item(s) are available in the full comparison report.`,errorAdvice:`⚠️ Capture or comparison errors must be fixed before approval.`,approvalPrompt:`A reviewer with write permission can approve the full head build with:`,captureError:`Capture or comparison failed.`,removedEntry:`Not found in the head Storybook`,addedEntry:`New snapshot`,approval:(e,t)=>`✅ @${e} approved Kapture report \`${t.slice(0,12)}\`.`},Pd={executionErrors:e=>`❌ **${e}개의 실행 오류**를 해결해 주세요.`,clean:`✅ 시각적 변경이 없습니다.`,changes:e=>`🔍 **${e}개의 시각적 변경**을 검토해 주세요.`,unstableWarning:e=>`⚠️ **${e}개의 불안정한 스냅샷**이 동일 리비전 재캡처에서 달라졌습니다. 이 항목은 빌드를 막지 않습니다.`,comparison:(e,t)=>`**${e}개 스토리 · ${t}개 스냅샷 비교**`,coverage:(e,t,n,r,i,a)=>e===`affected`?`**전체 ${t}개 Story 중 영향받은 ${n}개 선택 · ${r}개 Story / ${i}개 스냅샷 비교 · ${a}개는 dependency graph로 제외**`:`**${n}개 Story 선택 · ${r}개 Story / ${i}개 스냅샷 비교**`,fallback:e=>`- 누락 방지를 위해 전체 캡처로 전환: ${e.join(`, `)}`,counts:e=>`- 동일 ${e.unchanged} · 변경 ${e.changed} · 불안정 ${e.unstable} · 추가 ${e.added} · 삭제 ${e.removed} · 오류 ${e.errors}`,branch:`브랜치`,environment:`환경`,reportDownload:`전체 비교 리포트 다운로드`,reportOpen:`전체 비교 리포트 열기`,storyOpen:`캡처한 Story 열기`,sections:{error:`🚨 실행 오류`,removed:`⚠️ 삭제된 스냅샷`,changed:`🔍 시각 변경`,unstable:`⚠️ 불안정한 스냅샷`,added:`➕ 추가된 스냅샷`},hidden:e=>`그 외 ${e}개 항목은 전체 비교 리포트에서 확인해 주세요.`,errorAdvice:`⚠️ 캡처 또는 비교 오류를 해결해야 합니다. 승인할 수 없습니다.`,approvalPrompt:`전체 head 빌드를 승인하려면 쓰기 권한이 있는 리뷰어가 다음 명령을 남겨 주세요.`,captureError:`캡처 또는 비교에 실패했습니다.`,removedEntry:`head Storybook에서 찾을 수 없음`,addedEntry:`새 스냅샷`,approval:(e,t)=>`✅ @${e} 님이 Kapture 리포트 \`${t.slice(0,12)}\`를 승인했습니다.`};function Fd(e){if(e===`en`||e===`ko`)return e;throw Error(`Comment language must be en or ko`)}function Id(e){return e===`ko`?Pd:Nd}const Ld=`<!-- kapture-report:`,Rd={error:0,removed:1,changed:2,unstable:3,added:4,unchanged:5};function zd(e){return e.contentDigest??$c(e)}function Bd(e){return`${Ld}${Buffer.from(JSON.stringify(e)).toString(`base64url`)} -->`}function Vd(e){let t=e.indexOf(Ld);if(t<0)return null;let n=t+20,r=e.indexOf(` -->`,n);if(r<0)return null;try{let t=JSON.parse(Buffer.from(e.slice(n,r),`base64url`).toString());return t.version!==3||!Wd(t.baseSha)||!Wd(t.headSha)||!/^[0-9a-f]{64}$/.test(t.digest)||!nf(t.captureRunId)||!nf(t.captureRunAttempt)||!nf(t.captureWorkflowId)||!rf(t.captureRunHeadBranch)||!nf(t.captureRunHeadRepositoryId)||![`clean`,`changed`,`error`].includes(t.status)||t.reportUrl!==void 0&&Gd(t.reportUrl)!==t.reportUrl?null:t}catch{return null}}function Hd(e,t,n=`Kapture Visual Review`,r=`en`){let{summary:i}=e,a=i.changed+i.added+i.removed,o=new Set(Object.values(e.entries).map(e=>e.storyId)).size,s=Zd(n,100),c=Id(r),l=[Bd(t),`## ${s}`,``,i.errors>0?c.executionErrors(i.errors):a===0?c.clean:c.changes(a),``,e.coverage?c.coverage(e.coverage.mode,e.coverage.storyIds.length,e.coverage.selectedStoryIds.length,o,i.total,e.coverage.skippedStoryIds.length):c.comparison(o,i.total),``,c.counts(i),`- ${c.branch} \`${$d(t.captureRunHeadBranch)}\` · ${c.environment} \`${$d(e.environment.id)}\` · base \`${tf(e.baseRevision)}\` → head \`${tf(e.headRevision)}\``];if(e.coverage?.mode===`full-fallback`&&l.push(c.fallback([...new Set(e.coverage.fallbackReasons.map(e=>e.code))])),i.unstable>0&&l.push(``,c.unstableWarning(i.unstable)),t.reportUrl){let e=ef(t.reportUrl)?c.reportDownload:c.reportOpen;l.push(``,`[${e}](${t.reportUrl})`)}let u=Object.values(e.entries).filter(e=>e.status!==`unchanged`).sort(Xd),d=u.slice(0,20);for(let n of[`error`,`removed`,`changed`,`unstable`,`added`]){let r=u.filter(e=>e.status===n),i=d.filter(e=>e.status===n);if(i.length!==0){l.push(``,`### ${c.sections[n]} (${r.length})`,``);for(let n of i)l.push(Jd(n,c,e.storybookUrl,t.reportUrl))}}let f=u.length-d.length;return f>0&&l.push(``,c.hidden(f)),i.errors>0?l.push(``,c.errorAdvice):a>0&&l.push(``,c.approvalPrompt,``,`\`/kapture approve ${e.headRevision} ${t.digest}\``),`${l.join(`
598
- `)}\n`}function Ud(e){let t=e.trim().match(/^\/kapture\s+approve\s+([0-9a-f]{40})\s+([0-9a-f]{64})$/i);return!t?.[1]||!t[2]?null:{headSha:t[1].toLowerCase(),reportDigest:t[2].toLowerCase()}}function Wd(e){return/^[0-9a-f]{40}$/i.test(e)}function Gd(e){if(!e)return;if(e.length>2048)throw Error(`Report URL is too long`);let t;try{t=new URL(e)}catch{throw Error(`Report URL must be a valid HTTPS URL`)}if(t.protocol!==`https:`||t.username||t.password)throw Error(`Report URL must be an HTTPS URL without credentials`);return t.toString().replace(/\(/g,`%28`).replace(/\)/g,`%29`).replace(/\[/g,`%5B`).replace(/\]/g,`%5D`)}function Kd(e){if(e){if(e===`./storybook/`)return e;try{return Gd(e)}catch{throw Error(`Storybook URL must be a valid HTTPS URL or ./storybook/`)}}}function qd(e){let t=Qd(e).replace(/\s+/g,` `).trim();if(!t||t.length>100)throw Error(`Status context must contain between 1 and 100 characters`);return t}function Jd(e,t,n,r){let i=`**${Zd(e.title)} / ${Zd(e.name)}** · ${Zd(e.viewport.name)}`,a=n?Yd(n,e.storyId,r):void 0,o=a?` · [${t.storyOpen}](${a})`:``;return e.status===`error`?`- ${i} — ${Zd(e.error??t.captureError,180)}${o}`:e.status===`removed`?`- ${i} — ${t.removedEntry}`:e.status===`added`?`- ${i} — ${t.addedEntry}${o}`:`- ${i}${o}`}function Yd(e,t,n){if(e===`./storybook/`&&!n)return;let r=new URL(e,n);return r.searchParams.set(`path`,`/story/${t}`),Gd(r.toString())}function Xd(e,t){let n=Rd[e.status]-Rd[t.status];return n===0?`${e.title}/${e.name}/${e.viewport.name}`.localeCompare(`${t.title}/${t.name}/${t.viewport.name}`):n}function Zd(e,t=240){let n=Qd(e).replace(/\s+/g,` `).trim();return(n.length>t?`${n.slice(0,t-3)}...`:n).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/\\/g,`\\\\`).replace(/([`*_[\]{}|])/g,`\\$1`).replace(/@/g,`@​`)}function Qd(e){return Array.from(e,e=>{let t=e.codePointAt(0)??0;return t<=31||t===127?` `:e}).join(``)}function $d(e){return e.replace(/`/g,`ˋ`).replace(/[\r\n]/g,` `).replace(/@/g,`@​`)}function ef(e){return e.includes(`/actions/runs/`)&&e.includes(`/artifacts/`)}function tf(e){return e.slice(0,8)}function nf(e){return typeof e==`number`&&Number.isInteger(e)&&e>0}function rf(e){return typeof e!=`string`||e.length<1||e.length>512?!1:Array.from(e).every(e=>{let t=e.codePointAt(0)??0;return t>31&&t!==127})}var af=class{#e;#t;#n;constructor(e,t){if(!e)throw Error(`GITHUB_TOKEN is required`);this.#e=e,this.#t=t,this.#n=of(process.env.GITHUB_API_URL)}async setReviewStatus(e,t,n,r,i){await this.#i(`POST`,`/statuses/${encodeURIComponent(e)}`,{state:t,description:n.slice(0,140),context:r,target_url:i})}async postOrUpdateReportComment(e,t,n=Ld){let r=(await this.#r(e)).find(e=>e.user?.login===`github-actions[bot]`&&e.body?.includes(n));return r?(await this.#i(`PATCH`,`/issues/comments/${r.id}`,{body:t})).id:this.createIssueComment(e,t)}async findCurrentReportMarker(e,t,n){let r=await this.#r(e);for(let e of r.reverse()){if(e.user?.login!==`github-actions[bot]`||!e.body)continue;let r=Vd(e.body);if(r?.baseSha===t&&r.headSha===n)return r}return null}async assertCurrentCaptureRun(e,t,n,r,i){let a=await this.#i(`GET`,`/actions/runs/${e}`);if(a.id!==e||a.run_attempt!==t||a.workflow_id!==n||a.head_branch!==r||a.head_repository.id!==i||a.status!==`completed`||a.conclusion!==`success`||a.event!==`pull_request`)throw Error(`Kapture report does not belong to the current successful capture run`);let o;for(let e=1;e<=10;e+=1){let t=await this.#i(`GET`,`/actions/workflows/${n}/runs?event=pull_request&branch=${encodeURIComponent(r)}&per_page=100&page=${e}`);for(let e of t.workflow_runs)e.head_repository.id===i&&(!o||e.run_number>o.run_number||e.run_number===o.run_number&&e.id>o.id)&&(o=e);if(t.workflow_runs.length<100)break}if(o?.id!==e)throw Error(`A newer Kapture capture run exists for this pull request`)}async getLatestReviewStatus(e,t){for(let n=1;n<=10;n+=1){let r=await this.#i(`GET`,`/commits/${encodeURIComponent(e)}/status?per_page=100&page=${n}`),i=r.statuses.find(e=>e.context===t);if(i)return sf(i.state)?{state:i.state,description:i.description??void 0,targetUrl:i.target_url??void 0}:null;if(r.statuses.length<100)break}return null}async assertWritePermission(e){let t=await this.#i(`GET`,`/collaborators/${encodeURIComponent(e)}/permission`);if(!t.permission||![`admin`,`maintain`,`write`].includes(t.permission))throw Error(`@${e} does not have write permission for this repository`)}async getPullRequest(e){return this.#i(`GET`,`/pulls/${e}`)}async readPackageManifest(e,t){if(!/^[0-9a-f]{40}$/.test(t)||!/^[A-Za-z0-9._/-]+$/.test(e)||e.split(`/`).some(e=>!e||e===`.`||e===`..`))throw Error(`Package manifest requires a project-relative path and exact revision`);let n=await this.#i(`GET`,`/contents/${e.split(`/`).map(encodeURIComponent).join(`/`)}?ref=${t}`);if(n.type!==`file`||n.encoding!==`base64`||typeof n.content!=`string`||!Number.isSafeInteger(n.size)||n.size<0||n.size>1048576||n.content.length>2097152)throw Error(`Expected a bounded package.json file at the exact base revision`);return JSON.parse(Buffer.from(n.content,`base64`).toString(`utf8`))}async getPullRequestForCapture(e){return this.#i(`GET`,`/pulls/${e}`)}async listPullRequestFilesPage(e,t,n){return this.#i(`GET`,`/pulls/${e}/files?per_page=${n}&page=${t}`)}async createIssueComment(e,t){return(await this.#i(`POST`,`/issues/${e}/comments`,{body:t})).id}async#r(e){let t=[];for(let n=1;n<=10;n+=1){let r=await this.#i(`GET`,`/issues/${e}/comments?per_page=100&page=${n}`);if(t.push(...r),r.length<100)break}return t}async#i(e,t,n){let{owner:r,repo:i}=this.#t,a=`/repos/${encodeURIComponent(r)}/${encodeURIComponent(i)}${t}`,o=await fetch(`${this.#n}${a}`,{method:e,headers:{Accept:`application/vnd.github+json`,Authorization:`Bearer ${this.#e}`,"X-GitHub-Api-Version":`2022-11-28`,"User-Agent":`kapture-cli`,...n?{"Content-Type":`application/json`}:{}},body:n?JSON.stringify(n):void 0});if(!o.ok)throw Error(`GitHub API ${e} ${t} failed with status ${o.status}`);return await o.json()}};function of(e){let t=e?.trim()||`https://api.github.com`,n;try{n=new URL(t)}catch{throw Error(`GITHUB_API_URL must be a valid absolute URL`)}let r=[`127.0.0.1`,`localhost`,`[::1]`].includes(n.hostname);if(n.protocol!==`https:`&&!(n.protocol===`http:`&&r))throw Error(`GITHUB_API_URL must use HTTPS (HTTP is allowed only for loopback tests)`);if(n.username||n.password||n.search||n.hash)throw Error(`GITHUB_API_URL must not contain credentials, a query, or a fragment`);return n.toString().replace(/\/+$/,``)}function sf(e){return[`error`,`failure`,`pending`,`success`].includes(e)}async function cf(){let e=process.env.GITHUB_EVENT_PATH;if(!e)throw Error(`GITHUB_EVENT_PATH is required`);let t=await C(e);if(!t.isFile()||t.size>10485760)throw Error(`GitHub event payload is missing or too large`);try{return JSON.parse(await x(e,`utf8`))}catch{throw Error(`GITHUB_EVENT_PATH does not contain valid JSON`)}}function lf(e){let t=gf(e,`GitHub event payload`);if(t.action!==`completed`)throw Error(`Kapture report requires a completed normalized event`);let n=gf(t.kapture,`kapture normalized event`);if(n.schemaVersion!==1)throw Error(`Kapture report requires normalized event schemaVersion 1`);let r=gf(n.pullRequest,`kapture.pullRequest`),i=gf(n.captureRun,`kapture.captureRun`),a=ff(r.headSha,`kapture.pullRequest.headSha`),o=mf(i.headBranch);if(!hf(o))throw Error(`kapture.captureRun.headBranch is invalid`);return{repository:df(t),issueNumber:pf(r.number,`pull request number`),headSha:a,captureRunId:pf(i.id,`capture run ID`),captureRunAttempt:pf(i.attempt,`capture run attempt`),captureWorkflowId:pf(i.workflowId,`capture workflow ID`),captureRunHeadBranch:o,captureRunHeadRepositoryId:pf(i.headRepositoryId,`capture run head repository ID`)}}function uf(e){let t=gf(e,`GitHub event payload`);if(t.action!==`created`)throw Error(`Kapture approval only accepts newly created issue comments`);let n=gf(t.issue,`issue`);if(!n.pull_request)throw Error(`Kapture approval must be posted on a pull request`);let r=Ud(mf(gf(t.comment,`comment`).body));if(!r)throw Error(`Expected /kapture approve <full-head-sha> <64-character-report-digest>`);let i=mf(gf(t.sender,`sender`).login);if(!/^[A-Za-z0-9](?:[A-Za-z0-9-]{0,38})$/.test(i))throw Error(`GitHub event contains an invalid sender login`);return{repository:df(t),issueNumber:pf(n.number,`pull request number`),headSha:r.headSha,reportDigest:r.reportDigest,sender:i}}function df(e){let t=mf(gf(e.repository,`repository`).full_name).match(/^([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)$/);if(!t?.[1]||!t[2])throw Error(`GitHub event contains an invalid repository`);return{owner:t[1],repo:t[2]}}function ff(e,t){let n=mf(e).toLowerCase();if(!Wd(n))throw Error(`${t} must be a full 40-character SHA`);return n}function pf(e,t){if(typeof e!=`number`||!Number.isInteger(e)||e<=0)throw Error(`${t} must be a positive integer`);return e}function mf(e){if(typeof e!=`string`)throw Error(`GitHub event contains an invalid string value`);return e}function hf(e){return e.length<1||e.length>512?!1:Array.from(e).every(e=>{let t=e.codePointAt(0)??0;return t>31&&t!==127})}function gf(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`${t} must be an object`);return e}const _f=`Publishing verified visual report`;async function vf(e,t,n){let r=bf(n.baseRevision,`Report base`),i=bf(n.headRevision,`Report head`);if(i!==t.headSha)throw Error(`Report head ${n.headRevision} does not match workflow head ${t.headSha}`);let a=await e.getPullRequest(t.issueNumber);if(a.number!==t.issueNumber)throw Error(`GitHub returned PR #${a.number} instead of requested PR #${t.issueNumber}`);if(a.state!==`open`)throw Error(`Pull request #${t.issueNumber} is not open`);let o=bf(a.head.sha,`Current PR head`),s=bf(a.base.sha,`Current PR base`);if(o!==i)throw Error(`Report head ${n.headRevision} is stale; current PR head is ${a.head.sha}`);if(s!==r)throw Error(`Report base ${n.baseRevision} is stale; current PR base is ${a.base.sha}`);return a}async function yf(e,t,n,r,i,a=`en`){if(await vf(e,t,n),!n.contentDigest)throw Error("GitHub report publishing requires an image-bound contentDigest; run `kapture report build` first");let o=zd(n),s=n.summary.changed+n.summary.added+n.summary.removed,c=n.summary.errors>0?`error`:s>0?`changed`:`clean`,l={version:3,baseSha:n.baseRevision.toLowerCase(),headSha:n.headRevision.toLowerCase(),digest:o,captureRunId:t.captureRunId,captureRunAttempt:t.captureRunAttempt,captureWorkflowId:t.captureWorkflowId,captureRunHeadBranch:t.captureRunHeadBranch,captureRunHeadRepositoryId:t.captureRunHeadRepositoryId,status:c,reportUrl:i},u=c===`error`?`failure`:c===`changed`?`pending`:`success`,d=c===`error`?`${n.summary.errors} visual capture error(s)`:c===`changed`?`Visual changes require approval`:n.summary.unstable>0?`${n.summary.unstable} unstable snapshot(s), non-blocking`:`No visual changes`;await e.assertCurrentCaptureRun(t.captureRunId,t.captureRunAttempt,t.captureWorkflowId,t.captureRunHeadBranch,t.captureRunHeadRepositoryId),await e.setReviewStatus(t.headSha,`pending`,_f,r,i);let f=await e.postOrUpdateReportComment(t.issueNumber,Hd(n,l,r,a));await vf(e,t,n),await e.assertCurrentCaptureRun(t.captureRunId,t.captureRunAttempt,t.captureWorkflowId,t.captureRunHeadBranch,t.captureRunHeadRepositoryId);let p=await e.getLatestReviewStatus(t.headSha,r);if(!p||p.state!==`pending`||p.description!==_f||p.targetUrl!==i)throw Error(`Kapture status changed while the report was being published; retry report`);return await e.setReviewStatus(t.headSha,u,d,r,i),{status:c,changedCount:s,commentId:f,reportDigest:o}}function bf(e,t){if(!Wd(e))throw Error(`${t} ${e} must be a full 40-character SHA`);return e.toLowerCase()}async function xf(e,t,n,r=`en`){await e.assertWritePermission(t.sender);let i=await e.getPullRequest(t.issueNumber);if(i.number!==t.issueNumber)throw Error(`GitHub returned PR #${i.number} instead of requested PR #${t.issueNumber}`);if(i.state!==`open`)throw Error(`Pull request #${t.issueNumber} is not open`);let a=bf(i.base.sha,`Current PR base`),o=bf(i.head.sha,`Current PR head`);if(o!==t.headSha)throw Error(`Approval SHA ${t.headSha} is stale; current PR head is ${i.head.sha}`);let s=await e.findCurrentReportMarker(t.issueNumber,a,o);if(!s)throw Error(`No Kapture report exists for current base ${a} and head ${o}`);if(s.status!==`changed`)throw Error(`Kapture report for ${t.headSha} is not eligible for approval (${s.status})`);if(s.digest!==t.reportDigest)throw Error(`Approval digest ${t.reportDigest} does not match current report ${s.digest}`);await e.assertCurrentCaptureRun(s.captureRunId,s.captureRunAttempt,s.captureWorkflowId,s.captureRunHeadBranch,s.captureRunHeadRepositoryId);let c=await e.getLatestReviewStatus(o,n);if(!c||c.state!==`pending`||c.description!==`Visual changes require approval`||c.targetUrl!==s.reportUrl)throw Error(`Current Kapture status is not awaiting approval for this report`);let l=await e.findCurrentReportMarker(t.issueNumber,a,o);if(!l||l.digest!==t.reportDigest||l.status!==`changed`||l.captureRunId!==s.captureRunId||l.captureRunAttempt!==s.captureRunAttempt||l.captureWorkflowId!==s.captureWorkflowId||l.captureRunHeadBranch!==s.captureRunHeadBranch||l.captureRunHeadRepositoryId!==s.captureRunHeadRepositoryId||l.reportUrl!==s.reportUrl)throw Error(`Kapture report changed while approval was being applied; retry approval`);await e.assertCurrentCaptureRun(s.captureRunId,s.captureRunAttempt,s.captureWorkflowId,s.captureRunHeadBranch,s.captureRunHeadRepositoryId);let u=await e.getLatestReviewStatus(o,n);if(!u||u.state!==`pending`||u.description!==`Visual changes require approval`||u.targetUrl!==s.reportUrl)throw Error(`Current Kapture status changed while approval was being applied; retry approval`);let d=await e.getPullRequest(t.issueNumber);if(d.number!==t.issueNumber||d.state!==`open`||bf(d.base.sha,`Current PR base`)!==a||bf(d.head.sha,`Current PR head`)!==o)throw Error(`Pull request changed while approval was being applied; retry approval`);return await e.setReviewStatus(t.headSha,`success`,`Approved by @${t.sender}`,n,s.reportUrl),await e.createIssueComment(t.issueNumber,Id(r).approval(t.sender,s.digest)),{status:`approved`,reportDigest:s.digest}}async function W(e){let t=process.env.GITHUB_OUTPUT;if(!t)return;let n=[];for(let[t,r]of Object.entries(e)){let e=String(r),i=`kapture_${ie()}`;n.push(`${t}<<${i}\n${e}\n${i}\n`)}await h(t,n.join(``),`utf8`)}A();const Sf=k({meta:{name:`approve`,description:`Approve the current full-SHA Kapture report`},args:{"status-context":{type:`string`,default:`Kapture Visual Review`,description:`GitHub commit status context`},"comment-language":{type:`string`,default:`en`,description:`Approval comment language (en or ko)`}},async run({args:e}){try{let t=process.env.GITHUB_TOKEN;if(!t)throw Error(`GITHUB_TOKEN is required`);let n=uf(await cf()),r=await xf(new af(t,n.repository),n,qd(e[`status-context`]),Fd(e[`comment-language`]));await W({status:r.status,"report-digest":r.reportDigest})}catch(e){throw await W({status:`error`}),e}}}),G={silent:-1/0,fatal:0,error:0,warn:1,log:2,info:3,success:3,fail:3,ready:3,start:3,box:3,debug:4,trace:5,verbose:1/0},Cf={silent:{level:-1},fatal:{level:G.fatal},error:{level:G.error},warn:{level:G.warn},log:{level:G.log},info:{level:G.info},success:{level:G.success},fail:{level:G.fail},ready:{level:G.info},start:{level:G.info},box:{level:G.info},debug:{level:G.debug},trace:{level:G.trace},verbose:{level:G.verbose}};function wf(e){if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return t!==null&&t!==Object.prototype&&Object.getPrototypeOf(t)!==null||Symbol.iterator in e?!1:Symbol.toStringTag in e?Object.prototype.toString.call(e)===`[object Module]`:!0}function Tf(e,t,n=`.`,r){if(!wf(t))return Tf(e,{},n,r);let i=Object.assign({},t);for(let t in e){if(t===`__proto__`||t===`constructor`)continue;let a=e[t];a!=null&&(r&&r(i,t,a,n)||(i[t]=Array.isArray(a)&&Array.isArray(i[t])?[...a,...i[t]]:wf(a)&&wf(i[t])?Tf(a,i[t],(n?`${n}.`:``)+t.toString(),r):a))}return i}function Ef(e){return(...t)=>t.reduce((t,n)=>Tf(t,n,``,e),{})}const Df=Ef();function Of(e){return Object.prototype.toString.call(e)===`[object Object]`}function kf(e){return!(!Of(e)||!e.message&&!e.args||e.stack)}let Af=!1;const jf=[];var Mf=class e{options;_lastLog;_mockFn;constructor(e={}){let t=e.types||Cf;this.options=Df({...e,defaults:{...e.defaults},level:Nf(e.level,t),reporters:[...e.reporters||[]]},{types:Cf,throttle:1e3,throttleMin:5,formatOptions:{date:!0,colors:!1,compact:!0}});for(let e in t){let n={type:e,...this.options.defaults,...t[e]};this[e]=this._wrapLogFn(n),this[e].raw=this._wrapLogFn(n,!0)}this.options.mockFn&&this.mockTypes(),this._lastLog={}}get level(){return this.options.level}set level(e){this.options.level=Nf(e,this.options.types,this.options.level)}prompt(e,t){if(!this.options.prompt)throw Error(`prompt is not supported!`);return this.options.prompt(e,t)}create(t){let n=new e({...this.options,...t});return this._mockFn&&n.mockTypes(this._mockFn),n}withDefaults(e){return this.create({...this.options,defaults:{...this.options.defaults,...e}})}withTag(e){return this.withDefaults({tag:this.options.defaults.tag?this.options.defaults.tag+`:`+e:e})}addReporter(e){return this.options.reporters.push(e),this}removeReporter(e){if(e){let t=this.options.reporters.indexOf(e);if(t!==-1)return this.options.reporters.splice(t,1)}else this.options.reporters.splice(0);return this}setReporters(e){return this.options.reporters=Array.isArray(e)?e:[e],this}wrapAll(){this.wrapConsole(),this.wrapStd()}restoreAll(){this.restoreConsole(),this.restoreStd()}wrapConsole(){for(let e in this.options.types)console[`__`+e]||(console[`__`+e]=console[e]),console[e]=this[e].raw}restoreConsole(){for(let e in this.options.types)console[`__`+e]&&(console[e]=console[`__`+e],delete console[`__`+e])}wrapStd(){this._wrapStream(this.options.stdout,`log`),this._wrapStream(this.options.stderr,`log`)}_wrapStream(e,t){e&&(e.__write||=e.write,e.write=e=>{this[t].raw(String(e).trim())})}restoreStd(){this._restoreStream(this.options.stdout),this._restoreStream(this.options.stderr)}_restoreStream(e){e&&e.__write&&(e.write=e.__write,delete e.__write)}pauseLogs(){Af=!0}resumeLogs(){Af=!1;let e=jf.splice(0);for(let t of e)t[0]._logFn(t[1],t[2])}mockTypes(e){let t=e||this.options.mockFn;if(this._mockFn=t,typeof t==`function`)for(let e in this.options.types)this[e]=t(e,this.options.types[e])||this[e],this[e].raw=this[e]}_wrapLogFn(e,t){return(...n)=>{if(Af){jf.push([this,e,n,t]);return}return this._logFn(e,n,t)}}_logFn(e,t,n){if((e.level||0)>this.level)return!1;let r={date:new Date,args:[],...e,level:Nf(e.level,this.options.types)};!n&&t.length===1&&kf(t[0])?Object.assign(r,t[0]):r.args=[...t],r.message&&(r.args.unshift(r.message),delete r.message),r.additional&&(Array.isArray(r.additional)||(r.additional=r.additional.split(`
597
+ })()`);if(i.kind===`timeout`)throw i.sawAdapter?Error(`Kapture Storybook adapter did not become ready for ${t} (last state: ${i.lastState??`unknown`}).`):Error(`Kapture Storybook adapter was not found for ${t}. Install @kaptures/storybook and register kapture() in .storybook/preview.`);let a;try{a=eu(i.value)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`${t}. Install matching versions of @kaptures/cli and @kaptures/storybook.`,{cause:e})}if(a.state===`error`){let e=a.error.kind===`configuration`?`configuration`:`lifecycle`;throw Error(`Kapture Storybook ${e} error for ${t}: ${a.error.message}`)}if(a.state!==`ready`||a.storyId!==t)throw Error(`Kapture Storybook returned invalid terminal state for ${t}`);if(a.adapterVersion!==n)throw Error(`Kapture adapter version mismatch for ${t}: CLI ${n}, Storybook ${a.adapterVersion}. Install matching exact versions of @kaptures/cli and @kaptures/storybook.`);return{adapterVersion:a.adapterVersion,generation:a.generation,parameters:a.parameters}}function wu(e,t){return e.adapterVersion===t.adapterVersion&&e.generation===t.generation}async function Tu(e,t=jd){let n=e.workers??4;if(!Number.isInteger(n)||n<1||n>8)throw Error(`Kapture workers must be between 1 and 8`);let r=f(e.outputDir);await y(r),await y(c(r,`images`));let i=await dl(e.headDir);try{let a=Zl(await Xl(i.url));if(!a.length)throw Error(`Initial adoption requires at least one story`);let[o,s]=await Promise.all([t.getBrowserVersion(),t.getFontsFingerprint()]),l=Gc({browserVersion:o,fontsFingerprint:s,frozenTime:e.frozenTime,randomSeed:e.randomSeed,locale:e.locale,timezone:e.timezone}),u=c(r,`hermetic-init.js`);await w(u,Zc(l));let d=Ou(e.headRevision,l);if(await Du({pairs:a.map(e=>({id:e.id,head:e})),requestedWorkers:n,namespace:`i-${process.pid.toString(36)}-${Date.now().toString(36)}`,initScriptPath:u,options:{...e,baseDir:e.headDir,baseRevision:e.headRevision},baseUrl:``,headUrl:i.url,baseOutput:r,headOutput:r,baseManifest:Ou(e.headRevision,l),headManifest:d,environment:l,captureBase:!1}),await hl(c(r,`manifest.json`),d),!Object.keys(d.snapshots).length)throw Error(`Initial adoption requires at least one enabled snapshot`);return d}finally{await i.close()}}async function Eu(e,t=jd){let n=f(e.outputDir),r=c(n,`capture`,`base`),i=c(n,`capture`,`head`),a=c(n,`report`);await re(n,{recursive:!0,force:!0}),await Promise.all([y(c(r,`images`),{recursive:!0}),y(c(i,`images`),{recursive:!0}),y(a,{recursive:!0})]);let[o,s]=await Promise.all([dl(e.baseDir),dl(e.headDir)]);try{let[l,u,d,f]=await Promise.all([Xl(o.url),Xl(s.url),xl(e.baseDir),xl(e.headDir)]),p=Zl(l),m=Zl(u),h=ju(p,m,e,{base:d.evidence,head:f.evidence}),g=Au(p,m,h.selectedStoryIds),[_,v]=g.length===0?[`not-launched:no-affected-stories-v1`,`not-inspected:no-affected-stories-v1`]:await Promise.all([t.getBrowserVersion(),t.getFontsFingerprint()]),b=Gc({browserVersion:_,fontsFingerprint:v,frozenTime:e.frozenTime,randomSeed:e.randomSeed,locale:e.locale,timezone:e.timezone}),ee=c(n,`hermetic-init.js`);await w(ee,Zc(b));let x=`k-${process.pid.toString(36)}-${Date.now().toString(36)}`,S=e.baseCaptureDir?await Bu(e.baseCaptureDir,r,e.baseRevision,b,g):void 0;if(!S&&e.captureCacheDir&&g.length>0)try{let t=await _l(e.baseDir,e.adapterVersion),n=await vl(e.captureCacheDir,t),i=await Bu(e.captureCacheDir,r,n.revision,b,g,!0);for(let e of Object.values(i.manifest.snapshots))e.sourceRevision??=n.revision;i.manifest.revision=e.baseRevision,S=i}catch(e){console.warn(`Kapture capture cache miss: ${e instanceof Error?e.message:String(e)}`)}S&&(h.baseline={mode:`reused`,revision:S.manifest.revision,manifestDigest:S.manifestDigest});let te=S?.manifest??Ou(e.baseRevision,b),ne=Ou(e.headRevision,b),C=e.workers??4;if(!Number.isInteger(C)||C<1||C>8)throw Error(`Kapture workers must be between 1 and 8`);await Du({pairs:g,requestedWorkers:C,namespace:x,initScriptPath:ee,options:e,baseUrl:o.url,headUrl:s.url,baseOutput:r,headOutput:i,baseManifest:te,headManifest:ne,environment:b,captureBase:!S||!!e.captureCacheDir,cachedBaseStoryIds:S?new Set(Object.values(S.manifest.snapshots).map(e=>e.storyId)):void 0}),S&&await Vu({baseline:S.manifest,baselineRoot:S.root,headManifest:ne,headOutput:i,selectedStoryIds:h.selectedStoryIds,removedStoryIds:h.removedStoryIds??[]}),await Promise.all([hl(c(r,`manifest.json`),te),hl(c(i,`manifest.json`),ne)]);let T={...ad,...e.threshold},ie=c(n,`stability-candidates`),ae=await sl({baseManifest:te,headManifest:ne,baseRoot:r,headRoot:i,outputDir:ie,threshold:T,coverage:h}),oe=new Set(Object.values(ae.entries).filter(e=>e.status===`changed`).map(e=>e.id)),se;if(oe.size>0){let t=new Set(Object.values(ae.entries).filter(e=>oe.has(e.id)).map(e=>e.storyId)),r=g.filter(e=>t.has(e.id)),i=c(n,`capture`,`base-repeat`),a=c(n,`capture`,`head-repeat`);await Promise.all([y(c(i,`images`),{recursive:!0}),y(c(a,`images`),{recursive:!0})]);let l=Ou(e.baseRevision,b),u=Ou(e.headRevision,b);await Du({pairs:r,requestedWorkers:C,namespace:`${x}-s`,initScriptPath:ee,options:e,baseUrl:o.url,headUrl:s.url,baseOutput:i,headOutput:a,baseManifest:l,headManifest:u,environment:b,captureBase:!0}),await Promise.all([hl(c(i,`manifest.json`),l),hl(c(a,`manifest.json`),u)]),se={baseManifest:l,headManifest:u,baseRoot:i,headRoot:a}}await re(ie,{recursive:!0,force:!0});let ce=await sl({baseManifest:te,headManifest:ne,baseRoot:r,headRoot:i,outputDir:a,threshold:T,coverage:h,stability:se});if(e.captureCacheOutput&&ce.summary.errors===0&&ce.summary.unstable===0)try{let t=await _l(e.headDir,e.adapterVersion);await yl(e.captureCacheOutput,i,t,ne)}catch(e){console.warn(`Kapture capture cache export unavailable: ${e instanceof Error?e.message:String(e)}`)}return{baseManifest:te,headManifest:ne,report:ce}}finally{await Promise.allSettled([o.close(),s.close()])}}async function Du(e){let t=Math.min(e.requestedWorkers,e.pairs.length),n=e.captureBase&&e.pairs.some(t=>!!t.base&&!e.cachedBaseStoryIds?.has(t.id)),r=e.pairs.some(e=>!!e.head),i=[...e.pairs],a=[],o=[];try{for(let i=0;i<t;i+=1){let t={};n&&(t.base=ku(i,`base`,e.options,{namespace:e.namespace,initScriptPath:e.initScriptPath,environment:e.environment}),o.push(t.base)),r&&(t.head=ku(i,`head`,e.options,{namespace:e.namespace,initScriptPath:e.initScriptPath,environment:e.environment}),o.push(t.head)),a.push(t)}await Promise.all(a.map(async t=>{for(;i.length>0;){let n=i.shift();if(!n)return;await Iu({workers:t,pair:n,baseUrl:e.baseUrl,headUrl:e.headUrl,baseOutput:e.baseOutput,headOutput:e.headOutput,baseManifest:e.baseManifest,headManifest:e.headManifest,environment:e.environment,adapterVersion:e.options.adapterVersion,captureBase:e.captureBase&&!e.cachedBaseStoryIds?.has(n.id)})}}))}finally{await Promise.allSettled(o.map(e=>Promise.resolve().then(()=>e.close())))}}function Ou(e,t){return{version:2,revision:e,environment:t,createdAt:new Date().toISOString(),snapshots:{}}}function ku(e,t,n,r){let i={...r,target:t};return n.workerFactory?n.workerFactory(e,i):new nd({id:`${r.namespace}-${t}-${e}`,namespace:r.namespace,initScriptPath:r.initScriptPath,timezone:r.environment.timezone,locale:r.environment.locale,deviceScaleFactor:r.environment.deviceScaleFactor,allowedDomains:r.environment.network.allowedDomains})}function Au(e,t,n){let r=new Map(e.map(e=>[e.id,e])),i=new Map(t.map(e=>[e.id,e])),a=[...new Set([...r.keys(),...i.keys()])].sort(),o=n?[...new Set(n)].sort():a,s=new Set(a),c=o.filter(e=>!s.has(e));if(c.length>0)throw Error(`Unknown Kapture story IDs: ${c.join(`, `)}`);return o.map(e=>({id:e,base:r.get(e),head:i.get(e)}))}function ju(e,t,n,r){if(n.selectionPlan&&n.storyIds)throw Error(`Kapture selectionPlan and storyIds cannot be provided together`);let i=[...new Set([...e,...t].map(e=>e.id))].sort(),a=new Set(e.map(e=>e.id)),o=new Set(t.map(e=>e.id)),s=i.filter(e=>!a.has(e)&&o.has(e)),c=i.filter(e=>a.has(e)&&!o.has(e)),l=Mu(r,n.baseRevision,n.headRevision),u=n.selectionPlan;if(u){if(Fu(u.totalStoryIds,i,`selection plan catalog`),Fu(u.addedStoryIds,s,`selection plan added stories`),Fu(u.removedStoryIds,c,`selection plan removed stories`),Nu(u.dependencyManifests,r),Pu(u.selectedStoryIds,u.skippedStoryIds,i),u.selectionMode===`full-fallback`&&u.fallbackReasons.length===0)throw Error(`Kapture full-fallback selection plan requires a fallback reason`);if(u.selectionMode===`affected`&&u.fallbackReasons.length>0)throw Error(`Kapture affected selection plan cannot contain fallback reasons`);return{plannerVersion:1,mode:u.selectionMode,...u.changedFilesEvidence?{changedFilesEvidence:{...u.changedFilesEvidence}}:{},dependencyManifests:l,storyIds:i,selectedStoryIds:[...u.selectedStoryIds],skippedStoryIds:[...u.skippedStoryIds],addedStoryIds:s,removedStoryIds:c,fallbackReasons:u.fallbackReasons.map(e=>({...e}))}}if(n.storyIds){let e=[...new Set(n.storyIds)].sort(),t=new Set(i),r=e.filter(e=>!t.has(e));if(r.length>0)throw Error(`Unknown Kapture story IDs: ${r.join(`, `)}`);let a=new Set(e);return{plannerVersion:1,mode:`affected`,dependencyManifests:l,storyIds:i,selectedStoryIds:e,skippedStoryIds:i.filter(e=>!a.has(e)),addedStoryIds:s,removedStoryIds:c,fallbackReasons:[]}}return{plannerVersion:1,mode:`full`,dependencyManifests:l,storyIds:i,selectedStoryIds:i,skippedStoryIds:[],addedStoryIds:s,removedStoryIds:c,fallbackReasons:[]}}function Mu(e,t,n){return{base:{...e.base,revision:t},head:{...e.head,revision:n}}}function Nu(e,t){if(JSON.stringify(e)!==JSON.stringify(t))throw Error(`Kapture selection plan dependency manifests do not match the built Storybook artifacts`)}function Pu(e,t,n){Fu(e,[...new Set(e)].sort(),`selected stories`),Fu(t,[...new Set(t)].sort(),`skipped stories`);let r=new Set(e),i=[...e,...t].sort();if(t.some(e=>r.has(e)))throw Error(`Kapture selection plan cannot select and skip the same story`);Fu(i,n,`selection plan partition`)}function Fu(e,t,n){if(e.length!==t.length||e.some((e,n)=>e!==t[n]))throw Error(`Kapture ${n} does not match the built Storybook catalog`)}async function Iu(e){let t={base:Lu(!!e.pair.base&&e.captureBase),head:Lu(!!e.pair.head)},n=[];e.pair.base&&e.captureBase&&n.push(Ru(e,`base`,t)),e.pair.head&&n.push(Ru(e,`head`,t)),await Promise.all(n)}function Lu(e){if(!e)return{promise:Promise.resolve(void 0),resolve:()=>void 0};let t=()=>void 0,n=!1;return{promise:new Promise(e=>{t=e}),resolve(e){n||(n=!0,t(e))}}}async function Ru(e,t,n){let r=e.pair[t];if(!r)return;let i=e.workers[t];if(!i)throw Error(`Kapture ${t} browser worker was not initialized`);let a=t===`base`?e.baseManifest:e.headManifest,o=t===`base`?e.baseUrl:e.headUrl,s=t===`base`?e.baseOutput:e.headOutput,c=t===`base`?`head`:`base`;try{await i.runAttempt({target:t,storyId:r.id},async i=>{let l=await Hu(i,o,r,e.environment,e.adapterVersion).catch(Yu);if(n[t].resolve(l),l instanceof Error){qu(a,r,l);return}let u=await n[c].promise;if(u instanceof Error)return;let d=t===`base`?l.parameters:u?.parameters,f=t===`head`?l.parameters:u?.parameters,p=e.captureBase?Uu(d,f,!!e.pair.base,!!e.pair.head):zu(e.baseManifest,e.pair.id,f,!!e.pair.head);for(let n of p){let c=n[t];!c||l.parameters.captureEnabled===!1||await Wu({driver:i,story:r,baseUrl:o,outputRoot:s,manifest:a,viewport:c,parameters:l.parameters,captureArea:l.parameters.captureArea,threshold:Gu(l.parameters.diff),adapterVersion:e.adapterVersion})}})}catch(e){let i=Yu(e);n[t].resolve(i),Ju(a,r,i)}}function zu(e,t,n,r=!0){let i=Object.values(e.snapshots).filter(e=>e.storyId===t).map(e=>e.viewport),a=!r||n?.captureEnabled===!1?[]:n?.captureViewports??[id],o=new Map(i.map(e=>[e.name,e])),s=new Map(a.map(e=>[e.name,e]));return[...new Set([...o.keys(),...s.keys()])].sort().map(e=>({base:o.get(e),head:s.get(e)}))}async function Bu(e,t,n,r,i,a=!1){let o=f(e),s=c(o,`manifest.json`),l=await gl(s);if(l.revision!==n)throw Error(`Kapture baseline revision ${l.revision} does not match requested base ${n}`);Jc(l.environment,r);let u=new Set(i.filter(e=>e.base).map(e=>e.id)),d={...l.snapshots};for(let e of u)if(!a&&!Object.values(d).some(t=>t.storyId===e))throw Error(`Kapture baseline does not contain selected base story ${e}`);return await Promise.all(Object.values(d).map(async e=>{if(e.error)return;let n=c(o,e.imageFile);if(await al(n)!==e.sha256)throw Error(`Kapture baseline image digest mismatch for ${e.id}`);await g(n,c(t,e.imageFile))})),{root:t,manifest:{...l,snapshots:d},manifestDigest:await al(s)}}async function Vu(e){let t=new Set(e.selectedStoryIds),n=new Set(e.removedStoryIds);await Promise.all(Object.values(e.baseline.snapshots).map(async r=>{t.has(r.storyId)||n.has(r.storyId)||(e.headManifest.snapshots[r.id]={...r,sourceRevision:r.sourceRevision??e.baseline.revision},!r.error&&await g(c(e.baselineRoot,r.imageFile),c(e.headOutput,r.imageFile)))}))}async function Hu(e,t,n,r,i){return await e.setViewport(id),await e.setMedia(r.colorScheme,r.reducedMotion===`reduce`),await e.open(Ql(t,n.id)),Cu(e,n.id,i)}function Uu(e,t,n=!0,r=!0){let i=!n||e?.captureEnabled===!1?[]:e?.captureViewports??[id],a=!r||t?.captureEnabled===!1?[]:t?.captureViewports??[id],o=new Map(i.map(e=>[e.name,e])),s=new Map(a.map(e=>[e.name,e]));return[...new Set([...o.keys(),...s.keys()])].sort().map(e=>({base:o.get(e),head:s.get(e)}))}async function Wu(e){let{driver:t,story:n,baseUrl:r,outputRoot:i,manifest:a,viewport:o,parameters:s,captureArea:l,threshold:u,adapterVersion:f}=e,p=`${n.id}@${o.name}`,m=c(`images`,ol(p)),h=c(i,m),g=performance.now();try{await t.setViewport(o),await t.setMedia(a.environment.colorScheme,a.environment.reducedMotion===`reduce`),await t.open(Ql(r,n.id));let e=await Cu(t,n.id,f);Ku(e,s,n.id);let c;for(let r=1;r<=3;r+=1){c=await Bc(t,a.environment,e.parameters);let i=await Cu(t,n.id,f);if(Ku(i,s,n.id),wu(e,i))break;if(r===3)throw Error(`Kapture story ${n.id} kept rerendering while the capture was stabilizing`);e=i,c=void 0}if(!c)throw Error(`Kapture could not stabilize ${n.id}`);await t.screenshot(h,{fullPage:l!==`viewport`}),a.snapshots[p]={id:p,storyId:n.id,title:n.title,name:n.name,viewport:o,imageFile:d(i,h),sha256:await al(h),capturedAt:new Date().toISOString(),durationMs:Math.round(performance.now()-g),ignoredRegions:c.ignoredRegions.length>0?c.ignoredRegions:void 0,threshold:u}}catch(e){a.snapshots[p]={id:p,storyId:n.id,title:n.title,name:n.name,viewport:o,imageFile:m,sha256:``,capturedAt:new Date().toISOString(),durationMs:Math.round(performance.now()-g),threshold:u,error:e instanceof Error?e.message:String(e)}}}function Gu(e){if(e)return{...e.pixelColorThreshold===void 0?{}:{pixelColorThreshold:e.pixelColorThreshold},...e.maxChangedPixelPercentage===void 0?{}:{maxChangedPixelRatio:e.maxChangedPixelPercentage/100}}}function Ku(e,t,n){if(JSON.stringify(e.parameters)!==JSON.stringify(t))throw Error(`Kapture parameters changed between metadata and capture for ${n}`)}function qu(e,t,n){let r=`${t.id}@metadata`;e.snapshots[r]={id:r,storyId:t.id,title:t.title,name:t.name,viewport:id,imageFile:``,sha256:``,capturedAt:new Date().toISOString(),durationMs:0,error:n.message}}function Ju(e,t,n){let r=`${t.id}@attempt`;e.snapshots[r]={id:r,storyId:t.id,title:t.title,name:t.name,viewport:id,imageFile:``,sha256:``,capturedAt:new Date().toISOString(),durationMs:0,error:n.message}}function Yu(e){return e instanceof Error?e:Error(String(e))}async function Xu(e,t){if(!(await C(e)).isDirectory())throw Error(`Dashboard build is not a directory: ${e}`);await _(e,t,{recursive:!0,force:!0});let n=f(t,`index.html`),r=f(t,`report.json`),[i,a]=await Promise.all([x(n,`utf8`),x(r,`utf8`)]),o=Zu(i,/<link\b[^>]*\brel=["']stylesheet["'][^>]*\bhref=["']([^"']+)["'][^>]*>/i,`stylesheet`),s=Zu(i,/<script\b[^>]*\bsrc=["']([^"']+)["'][^>]*><\/script>/i,`module script`),[c,l]=await Promise.all([Qu(t,o.url),Qu(t,s.url)]),u=$u(c,o.url),d=`<script id="kapture-report-data" type="application/json">${a.trim().replaceAll(`<`,`\\u003c`)}<\/script>\n<script data-kapture-dashboard>"use strict";\n${l.replace(/<\/script/gi,`<\\/script`)}<\/script>`,p=i.replace(o.tag,()=>`<style>${u}</style>`).replace(s.tag,``);if(!p.includes(`</body>`))throw Error(`Dashboard index is missing its closing body tag`);let m=p.replace(`</body>`,()=>`${d}\n</body>`);await w(n,m)}function Zu(e,t,n){let r=e.match(t);if(!r?.[1])throw Error(`Dashboard index is missing its ${n}`);return{tag:r[0],url:r[1]}}async function Qu(e,t){if(/^[a-z]+:/i.test(t)||t.startsWith(`/`)||t.includes(`?`))throw Error(`Dashboard asset must be a relative local path: ${t}`);let n=f(e),r=f(n,t);if(!r.startsWith(`${n}${p}`))throw Error(`Dashboard asset resolves outside the report directory: ${t}`);return x(r,`utf8`)}function $u(e,t){let n=u.dirname(t);return e.replace(/url\((["']?)(\.\/[^"')]+)\1\)/g,(e,t,r)=>{let i=u.join(n,r);return`url(${t}${i.startsWith(`.`)?i:`./${i}`}${t})`})}var ed,td,nd,rd,id,ad,od,sd,cd,ld,ud,dd,fd,pd,md,hd,gd,_d,vd,yd,bd,xd,Sd,Cd,wd,Td,Ed,Dd,Od,kd,Ad,jd,Md=E((()=>{_t(),ed=zt(),Fc(),td=class{session;isolation=`browser-process`;namespace;initScriptPath;timezone;locale;deviceScaleFactor;allowedDomains;timeoutMs;bin;commandStarted=!1;closePromise;constructor(e){this.session=e.session,this.namespace=e.namespace,this.initScriptPath=e.initScriptPath,this.timezone=e.timezone,this.locale=e.locale,this.deviceScaleFactor=e.deviceScaleFactor,this.allowedDomains=e.allowedDomains,this.timeoutMs=e.timeoutMs??3e4,this.bin=zc()}open(e){return this.execVoid([`open`,e])}setViewport(e){return this.execVoid([`set`,`viewport`,String(e.width),String(e.height)])}setMedia(e,t){let n=[`set`,`media`,e];return t&&n.push(`reduced-motion`),this.execVoid(n)}async evaluate(e){let t=await this.exec([`eval`,e]),n=JSON.parse(t);if(n.success===!1)throw Error(n.error??`agent-browser eval failed`);return n.data&&typeof n.data==`object`&&`result`in n.data?n.data.result:n.data===void 0?n.result===void 0?n:n.result:n.data}screenshot(e,t){return this.execVoid([`screenshot`,...t.fullPage?[`--full`]:[],e])}close(){return this.closePromise?this.closePromise:this.commandStarted?(this.closePromise=this.execVoid([`close`],!0),this.closePromise):(this.closePromise=Promise.resolve(),this.closePromise)}async execVoid(e,t=!1){let n=await this.exec(e,t);try{let t=JSON.parse(n);if(t.success===!1)throw Error(t.error??`agent-browser command failed: ${e.join(` `)}`)}catch(e){if(e instanceof SyntaxError)return;throw e}}exec(e,t=!1){if(this.closePromise&&!t)return Promise.reject(Error(`agent-browser session ${this.session} is closed`));t||(this.commandStarted=!0);let n=[`--session`,this.session,`--namespace`,this.namespace,`--init-script`,this.initScriptPath,`--allowed-domains`,this.allowedDomains.join(`,`),`--args`,`--force-device-scale-factor=${this.deviceScaleFactor},--lang=${this.locale}`,`--json`,...e];return new Promise((t,i)=>{let a=r(this.bin,n,{env:{...process.env,LANG:`${this.locale}.UTF-8`,TZ:this.timezone},stdio:[`ignore`,`pipe`,`pipe`]}),o=[],s=[];a.stdout.on(`data`,e=>o.push(e)),a.stderr.on(`data`,e=>s.push(e));let c=setTimeout(()=>{a.kill(),i(Error(`agent-browser timed out after ${this.timeoutMs}ms: ${e.join(` `)}`))},this.timeoutMs);a.once(`error`,e=>{clearTimeout(c),i(e)}),a.once(`close`,e=>{clearTimeout(c);let n=Buffer.concat(o).toString(`utf8`).trim(),r=Buffer.concat(s).toString(`utf8`).trim();if(e!==0){i(Error(`agent-browser failed (${e}): ${r||n}`));return}t(n)})})}},nd=class{id;options;attemptFactory;sessionPrefix;attemptNumber=0;activeAttempt;closed=!1;constructor(e,t=e=>new td(e)){this.id=e.id,this.sessionPrefix=`kw-${T(`sha256`).update(e.id).digest(`hex`).slice(0,8)}`;let{id:n,...r}=e;this.options=r,this.attemptFactory=t}async runAttempt(e,t){if(this.closed)throw Error(`Browser worker ${this.id} is closed`);if(this.activeAttempt)throw Error(`Browser worker ${this.id} already has an active attempt`);let n=++this.attemptNumber,r=new rd(e,this.attemptFactory({...this.options,session:`${this.sessionPrefix}-${e.target[0]}-${n.toString(36)}`}));this.activeAttempt=r;let i,a,o=!1;try{i=await t(r)}catch(e){o=!0,a=e}let s,c=!1;try{await r.close()}catch(e){c=!0,s=e}finally{this.activeAttempt===r&&(this.activeAttempt=void 0)}if(o&&c)throw AggregateError([a,s],`Browser attempt ${r.session} failed and could not be closed`);if(o)throw a;if(c)throw s;return i}async close(){if(this.closed)return;this.closed=!0;let e=this.activeAttempt;e&&(await e.close(),this.activeAttempt===e&&(this.activeAttempt=void 0))}},rd=class{scope;driver;isolation=`browser-process`;closePromise;constructor(e,t){this.scope=e,this.driver=t}get session(){return this.driver.session}open(e){return this.driver.open(e)}setViewport(e){return this.driver.setViewport(e)}setMedia(e,t){return this.driver.setMedia(e,t)}evaluate(e){return this.driver.evaluate(e)}screenshot(e,t){return this.driver.screenshot(e,t)}close(){return this.closePromise??=this.driver.close(),this.closePromise}},id={name:`default`,width:1280,height:800},ad={pixelColorThreshold:.2,maxChangedPixelRatio:0},od=[`baseImage`,`headImage`,`diffImage`],sd=/^[0-9a-f]{64}$/,cd={".css":`text/css; charset=utf-8`,".html":`text/html; charset=utf-8`,".ico":`image/x-icon`,".jpeg":`image/jpeg`,".jpg":`image/jpeg`,".js":`text/javascript; charset=utf-8`,".json":`application/json; charset=utf-8`,".mjs":`text/javascript; charset=utf-8`,".png":`image/png`,".svg":`image/svg+xml`,".woff":`font/woff`,".woff2":`font/woff2`},ld=B({name:R(),width:z(),height:z()}),ud=B({id:R(),browser:R(),browserVersion:R(),orchestratorRuntime:R(),operatingSystem:R(),architecture:R(),deviceScaleFactor:z(),locale:R(),timezone:R(),colorScheme:Os([`light`,`dark`]),reducedMotion:Os([`reduce`,`no-preference`]),frozenTime:R(),randomSeed:z(),fontsFingerprint:R(),stateIsolation:V(`fresh-browser-process-per-story-side-v1`).optional(),network:B({mode:V(`allowlist`),allowedDomains:Ss(R()),webRtc:V(`disabled`)})}),dd=B({id:R(),storyId:R(),title:R(),name:R(),viewport:ld,imageFile:R(),sha256:R(),capturedAt:R(),durationMs:z(),sourceRevision:R().optional(),ignoredRegions:Ss(B({x:z().int().nonnegative(),y:z().int().nonnegative(),width:z().int().positive(),height:z().int().positive()})).optional(),threshold:B({pixelColorThreshold:z().optional(),maxChangedPixelRatio:z().optional()}).optional(),error:R().optional()}).superRefine((e,t)=>{e.error||(/^images\/[A-Za-z0-9._-]+\.png$/.test(e.imageFile)||t.addIssue({code:`custom`,path:[`imageFile`],message:`must be a safe image path`}),/^[0-9a-f]{64}$/.test(e.sha256)||t.addIssue({code:`custom`,path:[`sha256`],message:`must be a SHA-256 digest`}))}),fd=B({version:V(2),revision:R(),environment:ud,createdAt:R(),snapshots:Ds(R(),dd)}),pd=B({version:V(1),buildDigest:R().regex(/^[a-f0-9]{64}$/),manifestDigest:R().regex(/^[a-f0-9]{64}$/)}),md=`kapture-dependencies.json`,hd=R().min(1).max(4096).refine(Dl,`must be a normalized project-relative path`),gd=R().max(4096).refine(e=>e===``||Dl(e),{message:`must be empty or a normalized project-relative path`}),_d=Ss(hd).max(1e5).refine(e=>new Set(e).size===e.length,`must not contain duplicates`),vd=R().regex(/^[0-9a-f]{64}$/),yd=Cs({type:Os([`asset`,`chunk`]),size:z().int().nonnegative().max(1e9),sha256:vd}).strict(),bd=R().max(4096).refine(e=>e===``||e.endsWith(`/`)&&Dl(e.slice(0,-1)),`must be empty or a normalized project-relative directory prefix`),xd=R().min(1).max(1024),Sd=Ss(xd).max(1e4).refine(e=>new Set(e).size===e.length,`must not contain duplicates`),Cd=Ds(hd,Ds(hd,Sd)),wd=Ds(hd,Ds(xd,Cs({module:hd,imported:xd}).strict())),Td=Cs({kind:V(`kapture-storybook-dependencies`),version:V(1),complete:ys(),storybookRoot:gd,globalInputs:_d,ignoredInputs:_d,fingerprintedInputs:_d.optional(),diagnostics:Ss(Os([`module-outside-project-root`,`module-fingerprint-missing`,`unresolved-virtual-module`,`unresolved-project-module`,`rendered-output-fingerprint-missing`,`global-output-fingerprint-missing`,`global-runtime-fingerprint-missing`,`unowned-output-chunk`,`output-inventory-mismatch`])).max(20).refine(e=>new Set(e).size===e.length,`must not contain duplicates`),modules:Ds(hd,_d),moduleFingerprints:Ds(hd,vd).optional(),globalOutputFingerprints:Ds(hd,vd),globalOutputStories:Ds(hd,_d),globalRuntimeFingerprint:vd,outputInventory:Ds(hd,yd),outputInventoryPrefixes:Ss(bd).max(100).refine(e=>new Set(e).size===e.length,`must not contain duplicates`),importBindings:Cd.optional(),reexportBindings:wd.optional(),renderedModules:Ds(hd,_d),renderedOutputFingerprints:Ds(hd,vd)}).strict().superRefine((e,t)=>{let n=Object.entries(e.modules),r=new Set(n.map(([e])=>e));n.length>1e5&&t.addIssue({code:`custom`,path:[`modules`],message:`contains too many modules`});for(let[i,a]of n)a.includes(i)||t.addIssue({code:`custom`,path:[`modules`,i],message:`must include the module itself`}),e.complete&&a.some(e=>!r.has(e))&&t.addIssue({code:`custom`,path:[`modules`,i],message:`must resolve every project dependency when the manifest is complete`});Object.keys(e.globalOutputFingerprints).length>1e5&&t.addIssue({code:`custom`,path:[`globalOutputFingerprints`],message:`contains too many global output fingerprints`});let i=new Set(Object.keys(e.globalOutputFingerprints)),a=Object.entries(e.globalOutputStories);a.length>1e5&&t.addIssue({code:`custom`,path:[`globalOutputStories`],message:`contains too many global output story lists`});for(let[e,n]of a){i.has(e)||t.addIssue({code:`custom`,path:[`globalOutputStories`,e],message:`must identify a fingerprinted global output`});for(let i of n)if(!r.has(i)){t.addIssue({code:`custom`,path:[`globalOutputStories`,e],message:`must contain only rendered story modules`});break}}for(let n of i)n in e.globalOutputStories||t.addIssue({code:`custom`,path:[`globalOutputStories`,n],message:`must cover every fingerprinted global output`});let o=Object.entries(e.outputInventory);o.length>1e5&&t.addIssue({code:`custom`,path:[`outputInventory`],message:`contains too many output files`}),`kapture-dependencies.json`in e.outputInventory&&t.addIssue({code:`custom`,path:[`outputInventory`,md],message:`must not inventory the manifest itself`});for(let n of e.outputInventoryPrefixes)o.some(([e])=>e.startsWith(n))||t.addIssue({code:`custom`,path:[`outputInventoryPrefixes`],message:`must cover at least one inventoried output`});let s=Object.entries(e.moduleFingerprints??{});s.length>1e5&&t.addIssue({code:`custom`,path:[`moduleFingerprints`],message:`contains too many module fingerprints`});for(let[e]of s)r.has(e)||t.addIssue({code:`custom`,path:[`moduleFingerprints`,e],message:`must identify a rendered module`});(e.fingerprintedInputs?.length??0)>0&&(e.moduleFingerprints?e.complete&&n.some(([t])=>!e.moduleFingerprints?.[t])&&t.addIssue({code:`custom`,path:[`moduleFingerprints`],message:`must cover every rendered module when the manifest is complete`}):t.addIssue({code:`custom`,path:[`moduleFingerprints`],message:`is required when fingerprintedInputs are configured`}));let c=0;for(let[n,i]of Object.entries(e.importBindings??{})){c+=Object.keys(i).length,r.has(n)||t.addIssue({code:`custom`,path:[`importBindings`,n],message:`must identify a rendered importer`});for(let r of Object.keys(i))e.modules[n]?.includes(r)||t.addIssue({code:`custom`,path:[`importBindings`,n,r],message:`must identify a direct project dependency`})}for(let[n,i]of Object.entries(e.reexportBindings??{})){c+=Object.keys(i).length,r.has(n)||t.addIssue({code:`custom`,path:[`reexportBindings`,n],message:`must identify a rendered barrel`});for(let[r,a]of Object.entries(i))e.modules[n]?.includes(a.module)||t.addIssue({code:`custom`,path:[`reexportBindings`,n,r],message:`must identify a direct project dependency`})}c>1e6&&t.addIssue({code:`custom`,path:[`importBindings`],message:`contains too many import and re-export bindings`});let l=Object.entries(e.renderedModules??{});l.length>1e5&&t.addIssue({code:`custom`,path:[`renderedModules`],message:`contains too many rendered module closures`});let u=0;for(let[e,n]of l){u+=n.length,r.has(e)||t.addIssue({code:`custom`,path:[`renderedModules`,e],message:`must identify a rendered entry module`}),n.includes(e)||t.addIssue({code:`custom`,path:[`renderedModules`,e],message:`must include the entry module itself`});for(let i of n)if(!r.has(i)){t.addIssue({code:`custom`,path:[`renderedModules`,e],message:`must contain only rendered project modules`});break}}u>5e6&&t.addIssue({code:`custom`,path:[`renderedModules`],message:`contains too many rendered module references`});let d=Object.entries(e.renderedOutputFingerprints);d.length>1e5&&t.addIssue({code:`custom`,path:[`renderedOutputFingerprints`],message:`contains too many rendered output fingerprints`});for(let[e]of d)r.has(e)||t.addIssue({code:`custom`,path:[`renderedOutputFingerprints`,e],message:`must identify a rendered entry module`});e.complete&&l.some(([t])=>e.renderedOutputFingerprints[t]===void 0)&&t.addIssue({code:`custom`,path:[`renderedOutputFingerprints`],message:`must cover every rendered entry module when the manifest is complete`}),e.complete!==(e.diagnostics.length===0)&&t.addIssue({code:`custom`,path:[`complete`],message:`must agree with diagnostics`})}),Ed=1e3,Dd=Cs({id:R().min(1),type:Os([`story`,`docs`]),importPath:R().min(1).optional()}).passthrough(),Od=Cs({entries:Ds(R(),Dd)}).passthrough(),kd=Cs({id:R().min(1),title:R(),name:R(),type:Os([`story`,`docs`])}),Ad=Cs({v:z(),entries:Ds(R(),kd)}),jd={getBrowserVersion:Ic,getFontsFingerprint:Yc}}));Md();const Nd={executionErrors:e=>`❌ **${e} execution error(s)** must be fixed.`,clean:`✅ No visual changes.`,changes:e=>`🔍 **${e} visual change(s)** require review.`,unstableWarning:e=>`⚠️ **${e} screen(s) could not be verified.** Capturing the same code again produced different images, so we cannot tell which differences came from your code changes. Fix the inconsistent rendering and rerun. Visual approval cannot bypass this check.`,comparison:(e,t)=>`**${e} stories · ${t} snapshots compared**`,coverage:(e,t,n,r,i,a)=>e===`affected`?`**${n} of ${t} affected stories selected · ${r} stories / ${i} snapshots compared · ${a} proven unaffected**`:`**${n} stories selected · ${r} stories / ${i} snapshots compared**`,fallback:e=>`- Safe full-capture fallback: ${e.join(`, `)}`,counts:e=>`- Unchanged ${e.unchanged} · Changed ${e.changed} · Unstable ${e.unstable} · Added ${e.added} · Removed ${e.removed} · Errors ${e.errors}`,branch:`Branch`,environment:`Environment`,reportDownload:`Download the full comparison report`,reportOpen:`Open the full comparison report`,storyOpen:`Open captured story`,sections:{error:`🚨 Execution errors`,removed:`⚠️ Removed snapshots`,changed:`🔍 Visual changes`,unstable:`⚠️ Unstable snapshots`,added:`➕ Added snapshots`},hidden:e=>`${e} more item(s) are available in the full comparison report.`,errorAdvice:`⚠️ Capture or comparison errors must be fixed before approval.`,approvalPrompt:`A reviewer with write permission can approve the full head build with:`,captureError:`Capture or comparison failed.`,removedEntry:`Not found in the head Storybook`,addedEntry:`New snapshot`,approval:(e,t)=>`✅ @${e} approved Kapture report \`${t.slice(0,12)}\`.`},Pd={executionErrors:e=>`❌ **${e}개의 실행 오류**를 해결해 주세요.`,clean:`✅ 시각적 변경이 없습니다.`,changes:e=>`🔍 **${e}개의 시각적 변경**을 검토해 주세요.`,unstableWarning:e=>`⚠️ **${e}개 화면의 검증을 통과하지 못했어요.** 같은 코드로 화면을 다시 찍었는데 결과가 달라졌어요. 코드 변경으로 생긴 차이를 확인할 수 없으니, 화면이 달라지는 원인을 수정한 뒤 다시 실행해 주세요. 시각 변경 승인으로는 이 검증을 통과시킬 수 없어요.`,comparison:(e,t)=>`**${e}개 스토리 · ${t}개 스냅샷 비교**`,coverage:(e,t,n,r,i,a)=>e===`affected`?`**전체 ${t}개 Story 중 영향받은 ${n}개 선택 · ${r}개 Story / ${i}개 스냅샷 비교 · ${a}개는 dependency graph로 제외**`:`**${n}개 Story 선택 · ${r}개 Story / ${i}개 스냅샷 비교**`,fallback:e=>`- 누락 방지를 위해 전체 캡처로 전환: ${e.join(`, `)}`,counts:e=>`- 동일 ${e.unchanged} · 변경 ${e.changed} · 불안정 ${e.unstable} · 추가 ${e.added} · 삭제 ${e.removed} · 오류 ${e.errors}`,branch:`브랜치`,environment:`환경`,reportDownload:`전체 비교 리포트 다운로드`,reportOpen:`전체 비교 리포트 열기`,storyOpen:`캡처한 Story 열기`,sections:{error:`🚨 실행 오류`,removed:`⚠️ 삭제된 스냅샷`,changed:`🔍 시각 변경`,unstable:`⚠️ 불안정한 스냅샷`,added:`➕ 추가된 스냅샷`},hidden:e=>`그 외 ${e}개 항목은 전체 비교 리포트에서 확인해 주세요.`,errorAdvice:`⚠️ 캡처 또는 비교 오류를 해결해야 합니다. 승인할 수 없습니다.`,approvalPrompt:`전체 head 빌드를 승인하려면 쓰기 권한이 있는 리뷰어가 다음 명령을 남겨 주세요.`,captureError:`캡처 또는 비교에 실패했습니다.`,removedEntry:`head Storybook에서 찾을 수 없음`,addedEntry:`새 스냅샷`,approval:(e,t)=>`✅ @${e} 님이 Kapture 리포트 \`${t.slice(0,12)}\`를 승인했습니다.`};function Fd(e){if(e===`en`||e===`ko`)return e;throw Error(`Comment language must be en or ko`)}function Id(e){return e===`ko`?Pd:Nd}const Ld=`<!-- kapture-report:`,Rd={error:0,removed:1,changed:2,unstable:3,added:4,unchanged:5};function zd(e){return e.contentDigest??$c(e)}function Bd(e){return`${Ld}${Buffer.from(JSON.stringify(e)).toString(`base64url`)} -->`}function Vd(e){let t=e.indexOf(Ld);if(t<0)return null;let n=t+20,r=e.indexOf(` -->`,n);if(r<0)return null;try{let t=JSON.parse(Buffer.from(e.slice(n,r),`base64url`).toString());return t.version!==4||!Wd(t.baseSha)||!Wd(t.headSha)||!/^[0-9a-f]{64}$/.test(t.digest)||!nf(t.captureRunId)||!nf(t.captureRunAttempt)||!nf(t.captureWorkflowId)||!rf(t.captureRunHeadBranch)||!nf(t.captureRunHeadRepositoryId)||![`clean`,`changed`,`unstable`,`error`].includes(t.status)||t.reportUrl!==void 0&&Gd(t.reportUrl)!==t.reportUrl?null:t}catch{return null}}function Hd(e,t,n=`Kapture Visual Review`,r=`en`){let{summary:i}=e,a=i.changed+i.added+i.removed,o=new Set(Object.values(e.entries).map(e=>e.storyId)).size,s=Zd(n,100),c=Id(r),l=[Bd(t),`## ${s}`,``,i.errors>0?c.executionErrors(i.errors):i.unstable>0?c.unstableWarning(i.unstable):a===0?c.clean:c.changes(a),``,e.coverage?c.coverage(e.coverage.mode,e.coverage.storyIds.length,e.coverage.selectedStoryIds.length,o,i.total,e.coverage.skippedStoryIds.length):c.comparison(o,i.total),``,c.counts(i),`- ${c.branch} \`${$d(t.captureRunHeadBranch)}\` · ${c.environment} \`${$d(e.environment.id)}\` · base \`${tf(e.baseRevision)}\` → head \`${tf(e.headRevision)}\``];if(e.coverage?.mode===`full-fallback`&&l.push(c.fallback([...new Set(e.coverage.fallbackReasons.map(e=>e.code))])),i.unstable>0&&i.errors>0&&l.push(``,c.unstableWarning(i.unstable)),t.reportUrl){let e=ef(t.reportUrl)?c.reportDownload:c.reportOpen;l.push(``,`[${e}](${t.reportUrl})`)}let u=Object.values(e.entries).filter(e=>e.status!==`unchanged`).sort(Xd),d=u.slice(0,20);for(let n of[`error`,`removed`,`changed`,`unstable`,`added`]){let r=u.filter(e=>e.status===n),i=d.filter(e=>e.status===n);if(i.length!==0){l.push(``,`### ${c.sections[n]} (${r.length})`,``);for(let n of i)l.push(Jd(n,c,e.storybookUrl,t.reportUrl))}}let f=u.length-d.length;return f>0&&l.push(``,c.hidden(f)),i.errors>0?l.push(``,c.errorAdvice):a>0&&i.unstable===0&&l.push(``,c.approvalPrompt,``,`\`/kapture approve ${e.headRevision} ${t.digest}\``),`${l.join(`
598
+ `)}\n`}function Ud(e){let t=e.trim().match(/^\/kapture\s+approve\s+([0-9a-f]{40})\s+([0-9a-f]{64})$/i);return!t?.[1]||!t[2]?null:{headSha:t[1].toLowerCase(),reportDigest:t[2].toLowerCase()}}function Wd(e){return/^[0-9a-f]{40}$/i.test(e)}function Gd(e){if(!e)return;if(e.length>2048)throw Error(`Report URL is too long`);let t;try{t=new URL(e)}catch{throw Error(`Report URL must be a valid HTTPS URL`)}if(t.protocol!==`https:`||t.username||t.password)throw Error(`Report URL must be an HTTPS URL without credentials`);return t.toString().replace(/\(/g,`%28`).replace(/\)/g,`%29`).replace(/\[/g,`%5B`).replace(/\]/g,`%5D`)}function Kd(e){if(e){if(e===`./storybook/`)return e;try{return Gd(e)}catch{throw Error(`Storybook URL must be a valid HTTPS URL or ./storybook/`)}}}function qd(e){let t=Qd(e).replace(/\s+/g,` `).trim();if(!t||t.length>100)throw Error(`Status context must contain between 1 and 100 characters`);return t}function Jd(e,t,n,r){let i=`**${Zd(e.title)} / ${Zd(e.name)}** · ${Zd(e.viewport.name)}`,a=n?Yd(n,e.storyId,r):void 0,o=a?` · [${t.storyOpen}](${a})`:``;return e.status===`error`?`- ${i} — ${Zd(e.error??t.captureError,180)}${o}`:e.status===`removed`?`- ${i} — ${t.removedEntry}`:e.status===`added`?`- ${i} — ${t.addedEntry}${o}`:`- ${i}${o}`}function Yd(e,t,n){if(e===`./storybook/`&&!n)return;let r=new URL(e,n);return r.searchParams.set(`path`,`/story/${t}`),Gd(r.toString())}function Xd(e,t){let n=Rd[e.status]-Rd[t.status];return n===0?`${e.title}/${e.name}/${e.viewport.name}`.localeCompare(`${t.title}/${t.name}/${t.viewport.name}`):n}function Zd(e,t=240){let n=Qd(e).replace(/\s+/g,` `).trim();return(n.length>t?`${n.slice(0,t-3)}...`:n).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/\\/g,`\\\\`).replace(/([`*_[\]{}|])/g,`\\$1`).replace(/@/g,`@​`)}function Qd(e){return Array.from(e,e=>{let t=e.codePointAt(0)??0;return t<=31||t===127?` `:e}).join(``)}function $d(e){return e.replace(/`/g,`ˋ`).replace(/[\r\n]/g,` `).replace(/@/g,`@​`)}function ef(e){return e.includes(`/actions/runs/`)&&e.includes(`/artifacts/`)}function tf(e){return e.slice(0,8)}function nf(e){return typeof e==`number`&&Number.isInteger(e)&&e>0}function rf(e){return typeof e!=`string`||e.length<1||e.length>512?!1:Array.from(e).every(e=>{let t=e.codePointAt(0)??0;return t>31&&t!==127})}var af=class{#e;#t;#n;constructor(e,t){if(!e)throw Error(`GITHUB_TOKEN is required`);this.#e=e,this.#t=t,this.#n=of(process.env.GITHUB_API_URL)}async setReviewStatus(e,t,n,r,i){await this.#i(`POST`,`/statuses/${encodeURIComponent(e)}`,{state:t,description:n.slice(0,140),context:r,target_url:i})}async postOrUpdateReportComment(e,t,n=Ld){let r=(await this.#r(e)).find(e=>e.user?.login===`github-actions[bot]`&&e.body?.includes(n));return r?(await this.#i(`PATCH`,`/issues/comments/${r.id}`,{body:t})).id:this.createIssueComment(e,t)}async findCurrentReportMarker(e,t,n){let r=await this.#r(e);for(let e of r.reverse()){if(e.user?.login!==`github-actions[bot]`||!e.body)continue;let r=Vd(e.body);if(r?.baseSha===t&&r.headSha===n)return r}return null}async assertCurrentCaptureRun(e,t,n,r,i){let a=await this.#i(`GET`,`/actions/runs/${e}`);if(a.id!==e||a.run_attempt!==t||a.workflow_id!==n||a.head_branch!==r||a.head_repository.id!==i||a.status!==`completed`||a.conclusion!==`success`||a.event!==`pull_request`)throw Error(`Kapture report does not belong to the current successful capture run`);let o;for(let e=1;e<=10;e+=1){let t=await this.#i(`GET`,`/actions/workflows/${n}/runs?event=pull_request&branch=${encodeURIComponent(r)}&per_page=100&page=${e}`);for(let e of t.workflow_runs)e.head_repository.id===i&&(!o||e.run_number>o.run_number||e.run_number===o.run_number&&e.id>o.id)&&(o=e);if(t.workflow_runs.length<100)break}if(o?.id!==e)throw Error(`A newer Kapture capture run exists for this pull request`)}async getLatestReviewStatus(e,t){for(let n=1;n<=10;n+=1){let r=await this.#i(`GET`,`/commits/${encodeURIComponent(e)}/status?per_page=100&page=${n}`),i=r.statuses.find(e=>e.context===t);if(i)return sf(i.state)?{state:i.state,description:i.description??void 0,targetUrl:i.target_url??void 0}:null;if(r.statuses.length<100)break}return null}async assertWritePermission(e){let t=await this.#i(`GET`,`/collaborators/${encodeURIComponent(e)}/permission`);if(!t.permission||![`admin`,`maintain`,`write`].includes(t.permission))throw Error(`@${e} does not have write permission for this repository`)}async getPullRequest(e){return this.#i(`GET`,`/pulls/${e}`)}async readPackageManifest(e,t){if(!/^[0-9a-f]{40}$/.test(t)||!/^[A-Za-z0-9._/-]+$/.test(e)||e.split(`/`).some(e=>!e||e===`.`||e===`..`))throw Error(`Package manifest requires a project-relative path and exact revision`);let n=await this.#i(`GET`,`/contents/${e.split(`/`).map(encodeURIComponent).join(`/`)}?ref=${t}`);if(n.type!==`file`||n.encoding!==`base64`||typeof n.content!=`string`||!Number.isSafeInteger(n.size)||n.size<0||n.size>1048576||n.content.length>2097152)throw Error(`Expected a bounded package.json file at the exact base revision`);return JSON.parse(Buffer.from(n.content,`base64`).toString(`utf8`))}async getPullRequestForCapture(e){return this.#i(`GET`,`/pulls/${e}`)}async listPullRequestFilesPage(e,t,n){return this.#i(`GET`,`/pulls/${e}/files?per_page=${n}&page=${t}`)}async createIssueComment(e,t){return(await this.#i(`POST`,`/issues/${e}/comments`,{body:t})).id}async#r(e){let t=[];for(let n=1;n<=10;n+=1){let r=await this.#i(`GET`,`/issues/${e}/comments?per_page=100&page=${n}`);if(t.push(...r),r.length<100)break}return t}async#i(e,t,n){let{owner:r,repo:i}=this.#t,a=`/repos/${encodeURIComponent(r)}/${encodeURIComponent(i)}${t}`,o=await fetch(`${this.#n}${a}`,{method:e,headers:{Accept:`application/vnd.github+json`,Authorization:`Bearer ${this.#e}`,"X-GitHub-Api-Version":`2022-11-28`,"User-Agent":`kapture-cli`,...n?{"Content-Type":`application/json`}:{}},body:n?JSON.stringify(n):void 0});if(!o.ok)throw Error(`GitHub API ${e} ${t} failed with status ${o.status}`);return await o.json()}};function of(e){let t=e?.trim()||`https://api.github.com`,n;try{n=new URL(t)}catch{throw Error(`GITHUB_API_URL must be a valid absolute URL`)}let r=[`127.0.0.1`,`localhost`,`[::1]`].includes(n.hostname);if(n.protocol!==`https:`&&!(n.protocol===`http:`&&r))throw Error(`GITHUB_API_URL must use HTTPS (HTTP is allowed only for loopback tests)`);if(n.username||n.password||n.search||n.hash)throw Error(`GITHUB_API_URL must not contain credentials, a query, or a fragment`);return n.toString().replace(/\/+$/,``)}function sf(e){return[`error`,`failure`,`pending`,`success`].includes(e)}async function cf(){let e=process.env.GITHUB_EVENT_PATH;if(!e)throw Error(`GITHUB_EVENT_PATH is required`);let t=await C(e);if(!t.isFile()||t.size>10485760)throw Error(`GitHub event payload is missing or too large`);try{return JSON.parse(await x(e,`utf8`))}catch{throw Error(`GITHUB_EVENT_PATH does not contain valid JSON`)}}function lf(e){let t=gf(e,`GitHub event payload`);if(t.action!==`completed`)throw Error(`Kapture report requires a completed normalized event`);let n=gf(t.kapture,`kapture normalized event`);if(n.schemaVersion!==1)throw Error(`Kapture report requires normalized event schemaVersion 1`);let r=gf(n.pullRequest,`kapture.pullRequest`),i=gf(n.captureRun,`kapture.captureRun`),a=ff(r.headSha,`kapture.pullRequest.headSha`),o=mf(i.headBranch);if(!hf(o))throw Error(`kapture.captureRun.headBranch is invalid`);return{repository:df(t),issueNumber:pf(r.number,`pull request number`),headSha:a,captureRunId:pf(i.id,`capture run ID`),captureRunAttempt:pf(i.attempt,`capture run attempt`),captureWorkflowId:pf(i.workflowId,`capture workflow ID`),captureRunHeadBranch:o,captureRunHeadRepositoryId:pf(i.headRepositoryId,`capture run head repository ID`)}}function uf(e){let t=gf(e,`GitHub event payload`);if(t.action!==`created`)throw Error(`Kapture approval only accepts newly created issue comments`);let n=gf(t.issue,`issue`);if(!n.pull_request)throw Error(`Kapture approval must be posted on a pull request`);let r=Ud(mf(gf(t.comment,`comment`).body));if(!r)throw Error(`Expected /kapture approve <full-head-sha> <64-character-report-digest>`);let i=mf(gf(t.sender,`sender`).login);if(!/^[A-Za-z0-9](?:[A-Za-z0-9-]{0,38})$/.test(i))throw Error(`GitHub event contains an invalid sender login`);return{repository:df(t),issueNumber:pf(n.number,`pull request number`),headSha:r.headSha,reportDigest:r.reportDigest,sender:i}}function df(e){let t=mf(gf(e.repository,`repository`).full_name).match(/^([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)$/);if(!t?.[1]||!t[2])throw Error(`GitHub event contains an invalid repository`);return{owner:t[1],repo:t[2]}}function ff(e,t){let n=mf(e).toLowerCase();if(!Wd(n))throw Error(`${t} must be a full 40-character SHA`);return n}function pf(e,t){if(typeof e!=`number`||!Number.isInteger(e)||e<=0)throw Error(`${t} must be a positive integer`);return e}function mf(e){if(typeof e!=`string`)throw Error(`GitHub event contains an invalid string value`);return e}function hf(e){return e.length<1||e.length>512?!1:Array.from(e).every(e=>{let t=e.codePointAt(0)??0;return t>31&&t!==127})}function gf(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`${t} must be an object`);return e}const _f=`Publishing verified visual report`;async function vf(e,t,n){let r=bf(n.baseRevision,`Report base`),i=bf(n.headRevision,`Report head`);if(i!==t.headSha)throw Error(`Report head ${n.headRevision} does not match workflow head ${t.headSha}`);let a=await e.getPullRequest(t.issueNumber);if(a.number!==t.issueNumber)throw Error(`GitHub returned PR #${a.number} instead of requested PR #${t.issueNumber}`);if(a.state!==`open`)throw Error(`Pull request #${t.issueNumber} is not open`);let o=bf(a.head.sha,`Current PR head`),s=bf(a.base.sha,`Current PR base`);if(o!==i)throw Error(`Report head ${n.headRevision} is stale; current PR head is ${a.head.sha}`);if(s!==r)throw Error(`Report base ${n.baseRevision} is stale; current PR base is ${a.base.sha}`);return a}async function yf(e,t,n,r,i,a=`en`){if(await vf(e,t,n),!n.contentDigest)throw Error("GitHub report publishing requires an image-bound contentDigest; run `kapture report build` first");let o=zd(n),s=n.summary.changed+n.summary.added+n.summary.removed,c=n.summary.errors>0?`error`:n.summary.unstable>0?`unstable`:s>0?`changed`:`clean`,l={version:4,baseSha:n.baseRevision.toLowerCase(),headSha:n.headRevision.toLowerCase(),digest:o,captureRunId:t.captureRunId,captureRunAttempt:t.captureRunAttempt,captureWorkflowId:t.captureWorkflowId,captureRunHeadBranch:t.captureRunHeadBranch,captureRunHeadRepositoryId:t.captureRunHeadRepositoryId,status:c,reportUrl:i},u=c===`error`||c===`unstable`?`failure`:c===`changed`?`pending`:`success`,d=c===`error`?`${n.summary.errors} visual capture error(s)`:c===`changed`?`Visual changes require approval`:n.summary.unstable>0?`${n.summary.unstable} snapshot(s) could not be verified; fix and rerun`:`No visual changes`;await e.assertCurrentCaptureRun(t.captureRunId,t.captureRunAttempt,t.captureWorkflowId,t.captureRunHeadBranch,t.captureRunHeadRepositoryId),await e.setReviewStatus(t.headSha,`pending`,_f,r,i);let f=await e.postOrUpdateReportComment(t.issueNumber,Hd(n,l,r,a));await vf(e,t,n),await e.assertCurrentCaptureRun(t.captureRunId,t.captureRunAttempt,t.captureWorkflowId,t.captureRunHeadBranch,t.captureRunHeadRepositoryId);let p=await e.getLatestReviewStatus(t.headSha,r);if(!p||p.state!==`pending`||p.description!==_f||p.targetUrl!==i)throw Error(`Kapture status changed while the report was being published; retry report`);return await e.setReviewStatus(t.headSha,u,d,r,i),{status:c,changedCount:s,commentId:f,reportDigest:o}}function bf(e,t){if(!Wd(e))throw Error(`${t} ${e} must be a full 40-character SHA`);return e.toLowerCase()}async function xf(e,t,n,r=`en`){await e.assertWritePermission(t.sender);let i=await e.getPullRequest(t.issueNumber);if(i.number!==t.issueNumber)throw Error(`GitHub returned PR #${i.number} instead of requested PR #${t.issueNumber}`);if(i.state!==`open`)throw Error(`Pull request #${t.issueNumber} is not open`);let a=bf(i.base.sha,`Current PR base`),o=bf(i.head.sha,`Current PR head`);if(o!==t.headSha)throw Error(`Approval SHA ${t.headSha} is stale; current PR head is ${i.head.sha}`);let s=await e.findCurrentReportMarker(t.issueNumber,a,o);if(!s)throw Error(`No Kapture report exists for current base ${a} and head ${o}`);if(s.version!==4||s.status!==`changed`)throw Error(`Kapture report for ${t.headSha} is not eligible for approval (${s.status})`);if(s.digest!==t.reportDigest)throw Error(`Approval digest ${t.reportDigest} does not match current report ${s.digest}`);await e.assertCurrentCaptureRun(s.captureRunId,s.captureRunAttempt,s.captureWorkflowId,s.captureRunHeadBranch,s.captureRunHeadRepositoryId);let c=await e.getLatestReviewStatus(o,n);if(!c||c.state!==`pending`||c.description!==`Visual changes require approval`||c.targetUrl!==s.reportUrl)throw Error(`Current Kapture status is not awaiting approval for this report`);let l=await e.findCurrentReportMarker(t.issueNumber,a,o);if(!l||l.digest!==t.reportDigest||l.status!==`changed`||l.captureRunId!==s.captureRunId||l.captureRunAttempt!==s.captureRunAttempt||l.captureWorkflowId!==s.captureWorkflowId||l.captureRunHeadBranch!==s.captureRunHeadBranch||l.captureRunHeadRepositoryId!==s.captureRunHeadRepositoryId||l.reportUrl!==s.reportUrl)throw Error(`Kapture report changed while approval was being applied; retry approval`);await e.assertCurrentCaptureRun(s.captureRunId,s.captureRunAttempt,s.captureWorkflowId,s.captureRunHeadBranch,s.captureRunHeadRepositoryId);let u=await e.getLatestReviewStatus(o,n);if(!u||u.state!==`pending`||u.description!==`Visual changes require approval`||u.targetUrl!==s.reportUrl)throw Error(`Current Kapture status changed while approval was being applied; retry approval`);let d=await e.getPullRequest(t.issueNumber);if(d.number!==t.issueNumber||d.state!==`open`||bf(d.base.sha,`Current PR base`)!==a||bf(d.head.sha,`Current PR head`)!==o)throw Error(`Pull request changed while approval was being applied; retry approval`);return await e.setReviewStatus(t.headSha,`success`,`Approved by @${t.sender}`,n,s.reportUrl),await e.createIssueComment(t.issueNumber,Id(r).approval(t.sender,s.digest)),{status:`approved`,reportDigest:s.digest}}async function W(e){let t=process.env.GITHUB_OUTPUT;if(!t)return;let n=[];for(let[t,r]of Object.entries(e)){let e=String(r),i=`kapture_${ie()}`;n.push(`${t}<<${i}\n${e}\n${i}\n`)}await h(t,n.join(``),`utf8`)}A();const Sf=k({meta:{name:`approve`,description:`Approve the current full-SHA Kapture report`},args:{"status-context":{type:`string`,default:`Kapture Visual Review`,description:`GitHub commit status context`},"comment-language":{type:`string`,default:`en`,description:`Approval comment language (en or ko)`}},async run({args:e}){try{let t=process.env.GITHUB_TOKEN;if(!t)throw Error(`GITHUB_TOKEN is required`);let n=uf(await cf()),r=await xf(new af(t,n.repository),n,qd(e[`status-context`]),Fd(e[`comment-language`]));await W({status:r.status,"report-digest":r.reportDigest})}catch(e){throw await W({status:`error`}),e}}}),G={silent:-1/0,fatal:0,error:0,warn:1,log:2,info:3,success:3,fail:3,ready:3,start:3,box:3,debug:4,trace:5,verbose:1/0},Cf={silent:{level:-1},fatal:{level:G.fatal},error:{level:G.error},warn:{level:G.warn},log:{level:G.log},info:{level:G.info},success:{level:G.success},fail:{level:G.fail},ready:{level:G.info},start:{level:G.info},box:{level:G.info},debug:{level:G.debug},trace:{level:G.trace},verbose:{level:G.verbose}};function wf(e){if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return t!==null&&t!==Object.prototype&&Object.getPrototypeOf(t)!==null||Symbol.iterator in e?!1:Symbol.toStringTag in e?Object.prototype.toString.call(e)===`[object Module]`:!0}function Tf(e,t,n=`.`,r){if(!wf(t))return Tf(e,{},n,r);let i=Object.assign({},t);for(let t in e){if(t===`__proto__`||t===`constructor`)continue;let a=e[t];a!=null&&(r&&r(i,t,a,n)||(i[t]=Array.isArray(a)&&Array.isArray(i[t])?[...a,...i[t]]:wf(a)&&wf(i[t])?Tf(a,i[t],(n?`${n}.`:``)+t.toString(),r):a))}return i}function Ef(e){return(...t)=>t.reduce((t,n)=>Tf(t,n,``,e),{})}const Df=Ef();function Of(e){return Object.prototype.toString.call(e)===`[object Object]`}function kf(e){return!(!Of(e)||!e.message&&!e.args||e.stack)}let Af=!1;const jf=[];var Mf=class e{options;_lastLog;_mockFn;constructor(e={}){let t=e.types||Cf;this.options=Df({...e,defaults:{...e.defaults},level:Nf(e.level,t),reporters:[...e.reporters||[]]},{types:Cf,throttle:1e3,throttleMin:5,formatOptions:{date:!0,colors:!1,compact:!0}});for(let e in t){let n={type:e,...this.options.defaults,...t[e]};this[e]=this._wrapLogFn(n),this[e].raw=this._wrapLogFn(n,!0)}this.options.mockFn&&this.mockTypes(),this._lastLog={}}get level(){return this.options.level}set level(e){this.options.level=Nf(e,this.options.types,this.options.level)}prompt(e,t){if(!this.options.prompt)throw Error(`prompt is not supported!`);return this.options.prompt(e,t)}create(t){let n=new e({...this.options,...t});return this._mockFn&&n.mockTypes(this._mockFn),n}withDefaults(e){return this.create({...this.options,defaults:{...this.options.defaults,...e}})}withTag(e){return this.withDefaults({tag:this.options.defaults.tag?this.options.defaults.tag+`:`+e:e})}addReporter(e){return this.options.reporters.push(e),this}removeReporter(e){if(e){let t=this.options.reporters.indexOf(e);if(t!==-1)return this.options.reporters.splice(t,1)}else this.options.reporters.splice(0);return this}setReporters(e){return this.options.reporters=Array.isArray(e)?e:[e],this}wrapAll(){this.wrapConsole(),this.wrapStd()}restoreAll(){this.restoreConsole(),this.restoreStd()}wrapConsole(){for(let e in this.options.types)console[`__`+e]||(console[`__`+e]=console[e]),console[e]=this[e].raw}restoreConsole(){for(let e in this.options.types)console[`__`+e]&&(console[e]=console[`__`+e],delete console[`__`+e])}wrapStd(){this._wrapStream(this.options.stdout,`log`),this._wrapStream(this.options.stderr,`log`)}_wrapStream(e,t){e&&(e.__write||=e.write,e.write=e=>{this[t].raw(String(e).trim())})}restoreStd(){this._restoreStream(this.options.stdout),this._restoreStream(this.options.stderr)}_restoreStream(e){e&&e.__write&&(e.write=e.__write,delete e.__write)}pauseLogs(){Af=!0}resumeLogs(){Af=!1;let e=jf.splice(0);for(let t of e)t[0]._logFn(t[1],t[2])}mockTypes(e){let t=e||this.options.mockFn;if(this._mockFn=t,typeof t==`function`)for(let e in this.options.types)this[e]=t(e,this.options.types[e])||this[e],this[e].raw=this[e]}_wrapLogFn(e,t){return(...n)=>{if(Af){jf.push([this,e,n,t]);return}return this._logFn(e,n,t)}}_logFn(e,t,n){if((e.level||0)>this.level)return!1;let r={date:new Date,args:[],...e,level:Nf(e.level,this.options.types)};!n&&t.length===1&&kf(t[0])?Object.assign(r,t[0]):r.args=[...t],r.message&&(r.args.unshift(r.message),delete r.message),r.additional&&(Array.isArray(r.additional)||(r.additional=r.additional.split(`
599
599
  `)),r.args.push(`
600
600
  `+r.additional.join(`
601
601
  `)),delete r.additional),r.type=typeof r.type==`string`?r.type.toLowerCase():`log`,r.tag=typeof r.tag==`string`?r.tag:``;let i=(e=!1)=>{let t=(this._lastLog.count||0)-this.options.throttleMin;if(this._lastLog.object&&t>0){let e=[...this._lastLog.object.args];t>1&&e.push(`(repeated ${t} times)`),this._log({...this._lastLog.object,args:e}),this._lastLog.count=1}e&&(this._lastLog.object=r,this._log(r))};clearTimeout(this._lastLog.timeout);let a=this._lastLog.time&&r.date?r.date.getTime()-this._lastLog.time.getTime():0;if(this._lastLog.time=r.date,a<this.options.throttle)try{let e=JSON.stringify([r.type,r.tag,r.args]),t=this._lastLog.serialized===e;if(this._lastLog.serialized=e,t&&(this._lastLog.count=(this._lastLog.count||0)+1,this._lastLog.count>this.options.throttleMin)){this._lastLog.timeout=setTimeout(i,this.options.throttle);return}}catch{}i(!0)}_log(e){for(let t of this.options.reporters)t.log(e,{options:this.options})}};function Nf(e,t={},n=3){return e===void 0?n:typeof e==`number`?e:t[e]&&t[e].level!==void 0?t[e].level:n}Mf.prototype.add=Mf.prototype.addReporter,Mf.prototype.remove=Mf.prototype.removeReporter,Mf.prototype.clear=Mf.prototype.removeReporter,Mf.prototype.withScope=Mf.prototype.withTag,Mf.prototype.mock=Mf.prototype.mockTypes,Mf.prototype.pause=Mf.prototype.pauseLogs,Mf.prototype.resume=Mf.prototype.resumeLogs;function Pf(e={}){return new Mf(e)}function Ff(e,t){let n=process.cwd()+p;return e.split(`
@@ -670,4 +670,4 @@ ${r}`)}formatType(e,t,n){let r=bh[e.type]||xh[e.level]||`gray`;if(t)return kh(r)
670
670
  **Comparison not performed. Visual approval is unavailable.**
671
671
 
672
672
  `;if(`error`in e)return`${t}Capture failed before a complete result was saved: ${Zd(e.error,500)}\n`;let{report:n}=e,r=n.snapshots.filter(e=>e.error!==void 0).length,i=[...n.snapshots].sort((e,t)=>Number(t.error!==void 0)-Number(e.error!==void 0));return[t,`Base: \`${n.baseRevision}\` → Head: \`${n.headRevision}\``,``,`Snapshots: ${i.length} · Captured: ${i.length-r} · Errors: ${r}`,``,`Head-only installation validation. Download this run's artifact for setup.json and PNGs; this is not a baseline or a visual review result.`,``,`| Story | Viewport | Capture result |`,`| --- | --- | --- |`,...i.slice(0,100).map(e=>`| ${Zd(`${e.title} / ${e.name}`)} | ${Zd(e.viewport.name)} (${e.viewport.width} × ${e.viewport.height}) | ${e.error===void 0?`Captured`:`Error: ${Zd(e.error)}`} |`),...i.length>100?[``,`Showing the first 100 snapshots (errors first). See setup.json for all snapshots.`]:[],``].join(`
673
- `)}async function Rb(e){let t=process.env.GITHUB_STEP_SUMMARY;t&&await h(t,Lb(e))}Fc();const zb=R().max(4096),Bb=R().regex(/^[a-f0-9]{40}$/),Vb=B({id:zb,title:zb,name:zb,viewport:B({name:zb,width:z().int().positive(),height:z().int().positive()}),image:R().regex(/^images\/[a-zA-Z0-9._-]+\.png$/).optional(),sha256:R().regex(/^[a-f0-9]{64}$/).optional(),error:zb.optional()}).superRefine((e,t)=>{(e.error===void 0?!e.image||!e.sha256:e.image||e.sha256)&&t.addIssue({code:`custom`,message:`Snapshot must contain an image digest or an error`})}),Hb=B({version:V(1),kind:V(`initial-adoption`),comparison:V(`not-performed`),baseRevision:Bb,headRevision:Bb,snapshots:Ss(Vb).min(1).max(rg)}).superRefine((e,t)=>{new Set(e.snapshots.map(e=>e.id)).size!==e.snapshots.length&&t.addIssue({code:`custom`,message:`Duplicate snapshot IDs`})});function Ub(e,t){return Hb.parse({version:1,kind:`initial-adoption`,comparison:`not-performed`,baseRevision:t,headRevision:e.revision,snapshots:Object.values(e.snapshots).sort((e,t)=>e.id.localeCompare(t.id)).map(e=>({id:e.id,title:e.title,name:e.name,viewport:e.viewport,...e.error===void 0?{image:e.imageFile,sha256:e.sha256}:{error:e.error}}))})}Md(),A();const Wb=k({meta:{name:`setup`,description:`Head-only installation validation without visual comparison or approval`},subCommands:{capture:k({meta:{name:`capture`,description:`Save head PNGs and setup.json, and write a GitHub Job Summary`},args:{"head-dir":{type:`string`,required:!0},"base-revision":{type:`string`,required:!0},"head-revision":{type:`string`,required:!0},output:{type:`string`,required:!0},workers:{type:`string`,default:`4`},locale:{type:`string`,default:`en-US`},timezone:{type:`string`,default:`UTC`},"install-browser":{type:`boolean`,default:!1},"browser-with-deps":{type:`boolean`,default:!1}},async run({args:e}){try{for(let t of[e[`base-revision`],e[`head-revision`]])if(!/^[a-f0-9]{40}$/.test(t))throw Error(`Setup requires full revision SHAs`);let t=Number(e.workers);if(!Number.isInteger(t)||t<1||t>8)throw Error(`Invalid workers`);e[`install-browser`]&&await et(e[`browser-with-deps`]);let n=f(e.output),r=Ub(await Tu({headDir:f(e[`head-dir`]),headRevision:e[`head-revision`],outputDir:n,adapterVersion:Qe,workers:t,locale:e.locale,timezone:e.timezone}),e[`base-revision`]);await w(c(n,`setup.json`),JSON.stringify(r),{flag:`wx`});let i=r.snapshots.filter(e=>e.error!==void 0).length;await Rb({report:r}),await W({"artifact-directory":n,"capture-errors":i,comparison:`not-performed`}),console.log(`Setup validation: ${r.snapshots.length} snapshots, ${i} errors. Comparison not performed.`),i&&(process.exitCode=2)}catch(e){throw await Rb({error:e instanceof Error?e.message:String(e)}),e}}})}});Md(),A();const Gb=k({meta:{name:`test`,description:`Capture and compare base/head Storybooks in one hermetic browser environment`},args:{"github-artifacts":{type:`boolean`,default:!1,description:`Validate downloaded builds, bind Actions artifact identities and preserve error reports for publication`},"base-dir":{type:`string`,required:!0,description:`Built base Storybook directory`},"head-dir":{type:`string`,required:!0,description:`Built head Storybook directory`},"base-capture-dir":{type:`string`,description:`Verified capture directory for the exact base revision; captures head only`},"capture-cache-dir":{type:`string`,description:`Optional verified content-addressed head cache to reuse as base; misses capture normally`},"capture-cache-output":{type:`string`,description:`Export stable head capture evidence for subsequent runs`},"base-revision":{type:`string`,required:!0,description:`Base Git revision`},"head-revision":{type:`string`,required:!0,description:`Head Git revision`},"changed-files":{type:`string`,description:`Versioned changed-files manifest used to capture only provably affected stories`},"install-browser":{type:`boolean`,default:!1,description:`Install the pinned Chrome runtime only when at least one story is selected`},"browser-with-deps":{type:`boolean`,default:!1,description:`Install Linux browser dependencies together with Chrome`},output:{type:`string`,default:`.kapture`,description:`Output directory`},workers:{type:`string`,default:`4`,description:`Concurrent isolated story lanes`},"pixel-color-threshold":{type:`string`,default:`0.2`,description:`Per-pixel perceptual color threshold`},"max-changed-pixel-percentage":{type:`string`,default:`0`,description:`Maximum percentage of changed pixels allowed without review (0 to 100)`},"frozen-time":{type:`string`,default:`2026-01-01T00:00:00.000Z`,description:`ISO time exposed to stories`},"random-seed":{type:`string`,default:`20260101`,description:`Math.random seed`},locale:{type:`string`,default:`en-US`,description:`BCP 47 browser locale`},timezone:{type:`string`,default:`UTC`,description:`IANA browser time zone`},"dashboard-dir":{type:`string`,description:`Dashboard build directory (defaults to the CLI embedded dashboard)`}},async run({args:e}){let t=Xb(e.workers),n=Zb(e[`pixel-color-threshold`],`pixel-color-threshold`),r=Qb(e[`max-changed-pixel-percentage`],`max-changed-pixel-percentage`),o=Yb(e[`random-seed`],`random-seed`),s=f(e[`base-dir`]),c=f(e[`head-dir`]),l=e[`github-artifacts`]?Av(process.env):void 0;if(l){let t=`-base-${e[`base-revision`]}-head-${e[`head-revision`]}`;if(!l.artifacts.context.name.endsWith(t))throw Error(`Artifact identities must match the requested base/head revisions`);await Promise.all([s,c].map(e=>Vy(a(e),i(e))))}let u=e[`changed-files`]?await Kb(s,c,f(e[`changed-files`]),e[`base-revision`],e[`head-revision`]):void 0;Jb(u),e[`install-browser`]&&qb(u)&&(X.start(`Installing the Kapture browser runtime…`),await et(e[`browser-with-deps`])),X.start(e[`base-capture-dir`]?`Reusing the verified base capture and capturing affected head stories…`:`Capturing base and head Storybooks in one hermetic environment…`);let d=await Eu({baseDir:s,headDir:c,...e[`base-capture-dir`]?{baseCaptureDir:f(e[`base-capture-dir`])}:{},...e[`capture-cache-dir`]?{captureCacheDir:f(e[`capture-cache-dir`])}:{},...e[`capture-cache-output`]?{captureCacheOutput:f(e[`capture-cache-output`])}:{},baseRevision:e[`base-revision`],headRevision:e[`head-revision`],outputDir:f(e.output),workers:t,threshold:{pixelColorThreshold:n,maxChangedPixelRatio:r/100},frozenTime:e[`frozen-time`],randomSeed:o,locale:e.locale,timezone:e.timezone,adapterVersion:Qe,selectionPlan:u});await Xu(e[`dashboard-dir`]?f(e[`dashboard-dir`]):f(a(fe(import.meta.url)),`dashboard`),f(e.output,`report`)),l&&(await w(f(e.output,`report`,`capture-boundary.json`),`${JSON.stringify(l)}\n`,{flag:`wx`,mode:384}),await W({"report-directory":f(e.output,`report`),"report-path":f(e.output,`report`,`report.json`),"capture-errors":d.report.summary.errors}));let{summary:p}=d.report;X.success(`${p.total} snapshots: ${p.changed} changed, ${p.unstable} unstable, ${p.added} added, ${p.removed} removed, ${p.unchanged} unchanged, ${p.errors} errors`),X.info(`Environment: ${d.report.environment.id}`),X.info(`Report: ${f(e.output,`report`,`report.json`)}`),p.errors>0&&!l&&(process.exitCode=2)}});async function Kb(e,t,n,r,i){let a=await Fb(n);if(a.evidence&&(a.evidence.baseSha!==r||a.evidence.headSha!==i))throw Error(`changed-files manifest base/head SHAs must match --base-revision and --head-revision`);return jl({baseDir:e,headDir:t,changedFiles:a.files,changedFilesComplete:a.complete,...a.evidence?{changedFilesEvidence:a.evidence}:{}})}function qb(e){return!e||e.selectedStoryIds.length>0}function Jb(e){if(!e){X.info(`Story coverage: full capture (no changed-files manifest)`);return}if(e.selectionMode===`affected`){X.info(`Story coverage: ${e.selectedStoryIds.length} affected, ${e.skippedStoryIds.length} proven unaffected`);return}X.warn(`Story coverage: full fallback (${e.fallbackReasons.map(e=>e.code).join(`, `)})`)}function Yb(e,t){let n=Number.parseInt(e,10);if(!Number.isInteger(n)||n<=0)throw Error(`${t} must be a positive integer`);return n}function Xb(e){let t=Yb(e,`workers`);if(t>8)throw Error(`workers must be between 1 and 8`);return t}function Zb(e,t){let n=Number.parseFloat(e);if(!Number.isFinite(n)||n<0||n>1)throw Error(`${t} must be between 0 and 1`);return n}function Qb(e,t){let n=Number(e);if(!Number.isFinite(n)||n<0||n>100)throw Error(`${t} must be between 0 and 100`);return n}A(),tg();const $b=k({meta:{name:`validate`,description:`Validate a Kapture report as a CI gate`},args:{report:{type:`string`,required:!0,description:`Path to report.json`},"fail-on-diff":{type:`boolean`,default:!1,description:`Exit 1 when visual changes require review`}},async run({args:e}){let t=f(e.report),n=await C(t);if(!n.isFile()||n.size>10485760)throw Error(`Kapture report must be a file no larger than ${Ih} bytes`);let r=Mh(JSON.parse(await x(t,`utf8`)));if(r.summary.errors>0){X.error(`${r.summary.errors} capture or comparison error(s)`),process.exitCode=2;return}let i=r.summary.changed+r.summary.added+r.summary.removed;if(r.summary.unstable>0&&X.warn(`${r.summary.unstable} unstable snapshot(s) are non-blocking`),i>0&&e[`fail-on-diff`]){X.warn(`${i} visual change(s) require human approval`),process.exitCode=1;return}X.success(i>0?`${i} visual change(s) detected`:`No visual changes`)}});A(),vb(),Ue(k({meta:{name:`kapture`,version:Qe,description:`Hermetic Storybook visual review`},subCommands:{setup:Wb,test:Gb,validate:$b,browser:tt,ci:lt,plan:Pb,report:Ib,github:lb,inspect:_b,mcp:Nb}}));export{};
673
+ `)}async function Rb(e){let t=process.env.GITHUB_STEP_SUMMARY;t&&await h(t,Lb(e))}Fc();const zb=R().max(4096),Bb=R().regex(/^[a-f0-9]{40}$/),Vb=B({id:zb,title:zb,name:zb,viewport:B({name:zb,width:z().int().positive(),height:z().int().positive()}),image:R().regex(/^images\/[a-zA-Z0-9._-]+\.png$/).optional(),sha256:R().regex(/^[a-f0-9]{64}$/).optional(),error:zb.optional()}).superRefine((e,t)=>{(e.error===void 0?!e.image||!e.sha256:e.image||e.sha256)&&t.addIssue({code:`custom`,message:`Snapshot must contain an image digest or an error`})}),Hb=B({version:V(1),kind:V(`initial-adoption`),comparison:V(`not-performed`),baseRevision:Bb,headRevision:Bb,snapshots:Ss(Vb).min(1).max(rg)}).superRefine((e,t)=>{new Set(e.snapshots.map(e=>e.id)).size!==e.snapshots.length&&t.addIssue({code:`custom`,message:`Duplicate snapshot IDs`})});function Ub(e,t){return Hb.parse({version:1,kind:`initial-adoption`,comparison:`not-performed`,baseRevision:t,headRevision:e.revision,snapshots:Object.values(e.snapshots).sort((e,t)=>e.id.localeCompare(t.id)).map(e=>({id:e.id,title:e.title,name:e.name,viewport:e.viewport,...e.error===void 0?{image:e.imageFile,sha256:e.sha256}:{error:e.error}}))})}Md(),A();const Wb=k({meta:{name:`setup`,description:`Head-only installation validation without visual comparison or approval`},subCommands:{capture:k({meta:{name:`capture`,description:`Save head PNGs and setup.json, and write a GitHub Job Summary`},args:{"head-dir":{type:`string`,required:!0},"base-revision":{type:`string`,required:!0},"head-revision":{type:`string`,required:!0},output:{type:`string`,required:!0},workers:{type:`string`,default:`4`},locale:{type:`string`,default:`en-US`},timezone:{type:`string`,default:`UTC`},"install-browser":{type:`boolean`,default:!1},"browser-with-deps":{type:`boolean`,default:!1}},async run({args:e}){try{for(let t of[e[`base-revision`],e[`head-revision`]])if(!/^[a-f0-9]{40}$/.test(t))throw Error(`Setup requires full revision SHAs`);let t=Number(e.workers);if(!Number.isInteger(t)||t<1||t>8)throw Error(`Invalid workers`);e[`install-browser`]&&await et(e[`browser-with-deps`]);let n=f(e.output),r=Ub(await Tu({headDir:f(e[`head-dir`]),headRevision:e[`head-revision`],outputDir:n,adapterVersion:Qe,workers:t,locale:e.locale,timezone:e.timezone}),e[`base-revision`]);await w(c(n,`setup.json`),JSON.stringify(r),{flag:`wx`});let i=r.snapshots.filter(e=>e.error!==void 0).length;await Rb({report:r}),await W({"artifact-directory":n,"capture-errors":i,comparison:`not-performed`}),console.log(`Setup validation: ${r.snapshots.length} snapshots, ${i} errors. Comparison not performed.`),i&&(process.exitCode=2)}catch(e){throw await Rb({error:e instanceof Error?e.message:String(e)}),e}}})}});Md(),A();const Gb=k({meta:{name:`test`,description:`Capture and compare base/head Storybooks in one hermetic browser environment`},args:{"github-artifacts":{type:`boolean`,default:!1,description:`Validate downloaded builds, bind Actions artifact identities and preserve error reports for publication`},"base-dir":{type:`string`,required:!0,description:`Built base Storybook directory`},"head-dir":{type:`string`,required:!0,description:`Built head Storybook directory`},"base-capture-dir":{type:`string`,description:`Verified capture directory for the exact base revision; captures head only`},"capture-cache-dir":{type:`string`,description:`Optional verified content-addressed head cache to reuse as base; misses capture normally`},"capture-cache-output":{type:`string`,description:`Export stable head capture evidence for subsequent runs`},"base-revision":{type:`string`,required:!0,description:`Base Git revision`},"head-revision":{type:`string`,required:!0,description:`Head Git revision`},"changed-files":{type:`string`,description:`Versioned changed-files manifest used to capture only provably affected stories`},"install-browser":{type:`boolean`,default:!1,description:`Install the pinned Chrome runtime only when at least one story is selected`},"browser-with-deps":{type:`boolean`,default:!1,description:`Install Linux browser dependencies together with Chrome`},output:{type:`string`,default:`.kapture`,description:`Output directory`},workers:{type:`string`,default:`4`,description:`Concurrent isolated story lanes`},"pixel-color-threshold":{type:`string`,default:`0.2`,description:`Per-pixel perceptual color threshold`},"max-changed-pixel-percentage":{type:`string`,default:`0`,description:`Maximum percentage of changed pixels allowed without review (0 to 100)`},"frozen-time":{type:`string`,default:`2026-01-01T00:00:00.000Z`,description:`ISO time exposed to stories`},"random-seed":{type:`string`,default:`20260101`,description:`Math.random seed`},locale:{type:`string`,default:`en-US`,description:`BCP 47 browser locale`},timezone:{type:`string`,default:`UTC`,description:`IANA browser time zone`},"dashboard-dir":{type:`string`,description:`Dashboard build directory (defaults to the CLI embedded dashboard)`}},async run({args:e}){let t=Xb(e.workers),n=Zb(e[`pixel-color-threshold`],`pixel-color-threshold`),r=Qb(e[`max-changed-pixel-percentage`],`max-changed-pixel-percentage`),o=Yb(e[`random-seed`],`random-seed`),s=f(e[`base-dir`]),c=f(e[`head-dir`]),l=e[`github-artifacts`]?Av(process.env):void 0;if(l){let t=`-base-${e[`base-revision`]}-head-${e[`head-revision`]}`;if(!l.artifacts.context.name.endsWith(t))throw Error(`Artifact identities must match the requested base/head revisions`);await Promise.all([s,c].map(e=>Vy(a(e),i(e))))}let u=e[`changed-files`]?await Kb(s,c,f(e[`changed-files`]),e[`base-revision`],e[`head-revision`]):void 0;Jb(u),e[`install-browser`]&&qb(u)&&(X.start(`Installing the Kapture browser runtime…`),await et(e[`browser-with-deps`])),X.start(e[`base-capture-dir`]?`Reusing the verified base capture and capturing affected head stories…`:`Capturing base and head Storybooks in one hermetic environment…`);let d=await Eu({baseDir:s,headDir:c,...e[`base-capture-dir`]?{baseCaptureDir:f(e[`base-capture-dir`])}:{},...e[`capture-cache-dir`]?{captureCacheDir:f(e[`capture-cache-dir`])}:{},...e[`capture-cache-output`]?{captureCacheOutput:f(e[`capture-cache-output`])}:{},baseRevision:e[`base-revision`],headRevision:e[`head-revision`],outputDir:f(e.output),workers:t,threshold:{pixelColorThreshold:n,maxChangedPixelRatio:r/100},frozenTime:e[`frozen-time`],randomSeed:o,locale:e.locale,timezone:e.timezone,adapterVersion:Qe,selectionPlan:u});await Xu(e[`dashboard-dir`]?f(e[`dashboard-dir`]):f(a(fe(import.meta.url)),`dashboard`),f(e.output,`report`)),l&&(await w(f(e.output,`report`,`capture-boundary.json`),`${JSON.stringify(l)}\n`,{flag:`wx`,mode:384}),await W({"report-directory":f(e.output,`report`),"report-path":f(e.output,`report`,`report.json`),"capture-errors":d.report.summary.errors}));let{summary:p}=d.report;X.success(`${p.total} snapshots: ${p.changed} changed, ${p.unstable} unstable, ${p.added} added, ${p.removed} removed, ${p.unchanged} unchanged, ${p.errors} errors`),X.info(`Environment: ${d.report.environment.id}`),X.info(`Report: ${f(e.output,`report`,`report.json`)}`),p.errors>0&&!l&&(process.exitCode=2)}});async function Kb(e,t,n,r,i){let a=await Fb(n);if(a.evidence&&(a.evidence.baseSha!==r||a.evidence.headSha!==i))throw Error(`changed-files manifest base/head SHAs must match --base-revision and --head-revision`);return jl({baseDir:e,headDir:t,changedFiles:a.files,changedFilesComplete:a.complete,...a.evidence?{changedFilesEvidence:a.evidence}:{}})}function qb(e){return!e||e.selectedStoryIds.length>0}function Jb(e){if(!e){X.info(`Story coverage: full capture (no changed-files manifest)`);return}if(e.selectionMode===`affected`){X.info(`Story coverage: ${e.selectedStoryIds.length} affected, ${e.skippedStoryIds.length} proven unaffected`);return}X.warn(`Story coverage: full fallback (${e.fallbackReasons.map(e=>e.code).join(`, `)})`)}function Yb(e,t){let n=Number.parseInt(e,10);if(!Number.isInteger(n)||n<=0)throw Error(`${t} must be a positive integer`);return n}function Xb(e){let t=Yb(e,`workers`);if(t>8)throw Error(`workers must be between 1 and 8`);return t}function Zb(e,t){let n=Number.parseFloat(e);if(!Number.isFinite(n)||n<0||n>1)throw Error(`${t} must be between 0 and 1`);return n}function Qb(e,t){let n=Number(e);if(!Number.isFinite(n)||n<0||n>100)throw Error(`${t} must be between 0 and 100`);return n}A(),tg();const $b=k({meta:{name:`validate`,description:`Validate a Kapture report as a CI gate`},args:{report:{type:`string`,required:!0,description:`Path to report.json`},"fail-on-diff":{type:`boolean`,default:!1,description:`Exit 1 when visual changes require review`}},async run({args:e}){let t=f(e.report),n=await C(t);if(!n.isFile()||n.size>10485760)throw Error(`Kapture report must be a file no larger than ${Ih} bytes`);let r=Mh(JSON.parse(await x(t,`utf8`)));if(r.summary.errors>0){X.error(`${r.summary.errors} capture or comparison error(s)`),process.exitCode=2;return}let i=r.summary.changed+r.summary.added+r.summary.removed;if(r.summary.unstable>0){X.error(`${r.summary.unstable} screen(s) could not be verified: capturing the same code again produced different images. Fix the inconsistent rendering and rerun.`),process.exitCode=3;return}if(i>0&&e[`fail-on-diff`]){X.warn(`${i} visual change(s) require human approval`),process.exitCode=1;return}X.success(i>0?`${i} visual change(s) detected`:`No visual changes`)}});A(),vb(),Ue(k({meta:{name:`kapture`,version:Qe,description:`Hermetic Storybook visual review`},subCommands:{setup:Wb,test:Gb,validate:$b,browser:tt,ci:lt,plan:Pb,report:Ib,github:lb,inspect:_b,mcp:Nb}}));export{};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaptures/cli",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Hermetic Storybook visual review from the command line",
5
5
  "type": "module",
6
6
  "license": "MIT",