shiplightai 0.1.49 → 0.1.51

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.
@@ -877,6 +877,6 @@ Shiplight cloud report: ${f.data.reportUrl}`)}var C,N,ze,Ve,G,Je=ct(()=>{"use st
877
877
  </html>`}var Yt={before:0,main:1,teardown:2,after:3};function Xe(e){let t=e.split(".")[0];return Yt[t]??1}function qe(e){return e.split(".").map(t=>{let r=Number(t);return Number.isNaN(r)?0:r})}function Jt(e){return[...e].sort(([t],[r])=>{let i=Xe(t),o=Xe(r);if(i!==o)return i-o;let n=qe(t),s=qe(r);for(let c=0;c<Math.max(n.length,s.length);c++){let d=n[c]??-1,p=s[c]??-1;if(d!==p)return d-p}return 0})}function Xt(e){let t=new Set;for(let r of e)if(t.add(r.category),r.category==="hook")for(let i of r.steps)t.add(i.category);return t}function qt(e,t){let r=e.toLowerCase();return r.includes("before")?"before":r.includes("after")?"after":t}function de(e,t="main",r,i,o){r===void 0&&(r=!Xt(e).has("test.step")),o||(o=new Map);let n=[];for(let s of e){if(s.category==="fixture"||s.category==="test.attach")continue;if(s.category==="hook"){let d=qt(s.title,t);n.push(...de(s.steps,d,r,i,o));continue}if(s.category==="test.step"||r&&(s.category==="expect"||s.category==="pw:api")){let d=o.get(t)??0;o.set(t,d+1);let p=`${t}.${d}`,m={stepId:p,description:s.title,status:s.error?"failure":s.duration===-1?"skipped":"success",duration:s.duration>=0?s.duration:void 0};s.error&&(m.error=s.error.message??s.error.stack),i&&s.location&&i.set(p,s.location),n.push(m),s.steps.length>0&&n.push(...de(s.steps,p,r,i,o))}}return n}var ue=class{outputFolder;openMode;reportToCloud;apiKey;collected=[];config;runStartTime;constructor(t={}){this.outputFolder=t.outputFolder||"shiplight-report",this.openMode=t.open||"on-failure",this.reportToCloud=t.reportToCloud??!1,this.apiKey=t.apiKey||process.env.__SHIPLIGHT_API_KEY}onBegin(t,r){this.config=t,this.runStartTime=new Date().toISOString()}onTestEnd(t,r){this.collected.push({test:t,result:r})}async onEnd(t){if(this.collected.length===0)return;let r=new Map;for(let p of this.collected){let m=p.test.titlePath().join(" > "),b=r.get(m);b||(b=[],r.set(m,b)),b.push(p)}let i=[];for(let[,p]of r.entries()){let m=p[0].test.location.file,b=[],u,h,f;for(let v=0;v<p.length;v++){let{test:T,result:_}=p[v],k=await this.buildReportTest(T,_,m);u=k,h||(h=k.startTime),f=k.endTime,b.push({attemptNumber:v+1,status:_.status,duration:_.duration,steps:k.steps,error:k.error,videoPath:k.videoPath,tracePath:k.tracePath})}let a=b[b.length-1],{test:S}=p[p.length-1],y={title:S.title,baseTitle:u?.baseTitle,file:x.relative(process.cwd(),m),status:a.status,duration:a.duration,steps:a.steps,error:a.error,videoPath:a.videoPath,tracePath:a.tracePath,actionStepsMap:u?.actionStepsMap,tags:u?.tags,baseUrl:u?.baseUrl,skip:u?.skip,slow:u?.slow,timeout:u?.timeout,parameterSetName:u?.parameterSetName,startTime:h,endTime:f,suiteName:u?.suiteName},w=b.some(v=>v.status==="failed"||v.status==="timedOut");b.length>1&&w&&a.status==="passed"&&(y.flaky=!0,y.retries=b.length-1,y.attempts=b),i.push(y)}let o={tests:i,totalDuration:t.duration,timestamp:new Date().toISOString()},n=x.isAbsolute(this.outputFolder)?this.outputFolder:x.join(process.cwd(),this.outputFolder);E.mkdirSync(n,{recursive:!0});let s=x.join(n,"screenshots");for(let p=0;p<o.tests.length;p++){let m=o.tests[p],b=m.attempts&&m.attempts.length>0,u=[{obj:m,prefix:b?`test-${p}-attempt-0`:`test-${p}`,screenshotSubDir:`test-${p}`}];if(m.attempts)for(let h=0;h<m.attempts.length;h++)u.push({obj:m.attempts[h],prefix:`test-${p}-attempt-${h+1}`,screenshotSubDir:`test-${p}/attempt-${h}`});for(let{obj:h,prefix:f,screenshotSubDir:a}of u){let S=x.join(s,a),y=!1;for(let w of h.steps)if(w.screenshot&&x.isAbsolute(w.screenshot))try{y||(E.mkdirSync(S,{recursive:!0}),y=!0);let v=`${w.stepId.replace(/\./g,"-")}.png`;E.copyFileSync(w.screenshot,x.join(S,v)),w.screenshot=`screenshots/${a}/${v}`}catch(v){console.warn(`[reporter] Failed to copy screenshot for ${w.stepId}:`,v)}if(h.videoPath&&x.isAbsolute(h.videoPath)){let w=x.extname(h.videoPath)||".webm",v=`${f}-video${w}`;try{E.copyFileSync(h.videoPath,x.join(n,v)),h.videoPath=v}catch{h.videoPath=void 0}}if(h.tracePath&&x.isAbsolute(h.tracePath)){let w=x.extname(h.tracePath)||".zip",v=`${f}-trace${w}`;try{E.copyFileSync(h.tracePath,x.join(n,v)),h.tracePath=v}catch{h.tracePath=void 0}}}}let c=x.join(n,"report-data.json");E.writeFileSync(c,JSON.stringify(o,null,2),"utf-8");let d=x.join(n,"index.html");if(E.writeFileSync(d,He(o),"utf-8"),console.log(`
878
878
  Shiplight report written to: ${d}`),this.openMode==="always"||this.openMode==="on-failure"&&t.status!=="passed")try{let p=(await import("open")).default;await p(d)}catch{}if(this.reportToCloud){if(!this.apiKey){console.warn("[reporter] reportToCloud is enabled but no apiKey found, skipping cloud upload.");return}try{let{uploadToCloud:p}=await Promise.resolve().then(()=>(Je(),Ye));await p(o,n,this.runStartTime,this.apiKey)}catch(p){console.warn("[reporter] Cloud upload failed:",p)}}}printsToStdio(){return!1}async buildReportTest(t,r,i){let o={title:t.title,file:x.relative(process.cwd(),i),status:r.status,duration:r.duration,steps:[],startTime:new Date(r.startTime).toISOString(),endTime:new Date(r.startTime.getTime()+r.duration).toISOString()};r.errors.length>0&&(o.error=r.errors.map(u=>u.message||u.stack||String(u)).join(`
879
879
 
880
- `)),r.stdout.length>0&&(o.stdout=r.stdout.map(u=>typeof u=="string"?u:u.toString()).join("")),r.stderr.length>0&&(o.stderr=r.stderr.map(u=>typeof u=="string"?u:u.toString()).join(""));for(let u of r.attachments)u.name==="video"&&u.path&&(o.videoPath=u.path),u.name==="trace"&&u.path&&(o.tracePath=u.path);let n=r.attachments.find(u=>u.name==="shiplight-results"),s=null;if(n)try{if(n.body)s=JSON.parse(n.body.toString("utf-8"));else if(n.path){let u=E.readFileSync(n.path,"utf-8");s=JSON.parse(u)}}catch{}let c=i.replace(/\.yaml\.spec\.ts$/,".test.yaml"),d={},p=t.title.match(/^(.*)\s+\[([^\]]+)\]$/),m=p?p[1]:t.title,b=p?p[2]:void 0;if(b&&(o.parameterSetName=b),E.existsSync(c))try{let u=E.readFileSync(c,"utf-8"),h=Ue(u,c);if(h.suite){let f=h.suite.tests.find(a=>a.name===m);f&&(d=ee(f.testFlow),f.tags?.length&&(o.tags=f.tags),f.skip!==void 0&&(o.skip=f.skip),f.slow&&(o.slow=f.slow),f.timeout!==void 0&&(o.timeout=f.timeout),o.baseTitle=f.name||f.testFlow?.goal),o.suiteName=h.name,h.tags?.length&&(o.suiteTags=h.tags),h.use?.baseURL&&(o.baseUrl=h.use.baseURL)}else h.testFlow&&(d=ee(h.testFlow),o.baseTitle=h.name||h.testFlow?.goal,h.tags?.length&&(o.tags=h.tags),h.use?.baseURL&&(o.baseUrl=h.use.baseURL))}catch{}if(s||Object.keys(d).length>0){let u=new Set([...Object.keys(d),...Object.keys(s||{})]),h=Array.from(u).map(a=>[a,null]),f=Jt(h);for(let[a]of f){let S=d[a],y=s?.[a],w=S?.description;if(!w||w==="Action"||w==="Draft"){let T=S?.action_entity;w=T?.action_description||T?.action_data?.kwargs?.description||y?.description||a}let v={stepId:a,description:w,status:y?.status||"pending",duration:y?.duration};if(y?.message){let T=typeof y.message=="string"?y.message:JSON.stringify(y.message,null,2);y.status==="failure"?v.error=T:v.message=T}if(y?.screenshot){let T=y.screenshot,_=n?.path?x.dirname(n.path):"",k=x.isAbsolute(T)?T:x.join(_,T);E.existsSync(k)&&(v.screenshot=k)}v.code=y.code,o.steps.push(v)}}if(s===null&&Object.keys(d).length===0&&!i.endsWith(".yaml.spec.ts")){let u=new Map;if(o.steps=de(r.steps,"main",void 0,u),o.steps.length>0){let h=new Map;o.actionStepsMap=Object.fromEntries(o.steps.map(f=>{let a=u.get(f.stepId),S;if(a?.file){if(!h.has(a.file))try{h.set(a.file,E.readFileSync(a.file,"utf-8").split(`
880
+ `)),r.stdout.length>0&&(o.stdout=r.stdout.map(u=>typeof u=="string"?u:u.toString()).join("")),r.stderr.length>0&&(o.stderr=r.stderr.map(u=>typeof u=="string"?u:u.toString()).join(""));for(let u of r.attachments)u.name==="video"&&u.path&&(o.videoPath=u.path),u.name==="trace"&&u.path&&(o.tracePath=u.path);let n=r.attachments.find(u=>u.name==="shiplight-results"),s=null;if(n)try{if(n.body)s=JSON.parse(n.body.toString("utf-8"));else if(n.path){let u=E.readFileSync(n.path,"utf-8");s=JSON.parse(u)}}catch{}let c=i.replace(/\.yaml\.spec\.ts$/,".test.yaml"),d={},p=t.title.match(/^(.*)\s+\[([^\]]+)\]$/),m=p?p[1]:t.title,b=p?p[2]:void 0;if(b&&(o.parameterSetName=b),E.existsSync(c))try{let u=E.readFileSync(c,"utf-8"),h=Ue(u,c);if(h.suite){let f=h.suite.tests.find(a=>a.name===m);f&&(d=ee(f.testFlow),f.tags?.length&&(o.tags=f.tags),f.skip!==void 0&&(o.skip=f.skip),f.slow&&(o.slow=f.slow),f.timeout!==void 0&&(o.timeout=f.timeout),o.baseTitle=f.name||f.testFlow?.goal),o.suiteName=h.name,h.tags?.length&&(o.suiteTags=h.tags),h.use?.baseURL&&(o.baseUrl=h.use.baseURL)}else h.testFlow&&(d=ee(h.testFlow),o.baseTitle=h.name||h.testFlow?.goal,h.tags?.length&&(o.tags=h.tags),h.use?.baseURL&&(o.baseUrl=h.use.baseURL))}catch{}if(s||Object.keys(d).length>0){let u=new Set([...Object.keys(d),...Object.keys(s||{})]),h=Array.from(u).map(a=>[a,null]),f=Jt(h);for(let[a]of f){let S=d[a],y=s?.[a],w=S?.description;if(!w||w==="Action"||w==="Draft"){let T=S?.action_entity;w=T?.action_description||T?.action_data?.kwargs?.description||y?.description||a}let v={stepId:a,description:w,status:y?.status||"pending",duration:y?.duration};if(y?.message){let T=typeof y.message=="string"?y.message:JSON.stringify(y.message,null,2);y.status==="failure"?v.error=T:v.message=T}if(y?.screenshot){let T=y.screenshot,_=n?.path?x.dirname(n.path):"",k=x.isAbsolute(T)?T:x.join(_,T);E.existsSync(k)&&(v.screenshot=k)}y?.code&&(v.code=y.code),o.steps.push(v)}}if(s===null&&Object.keys(d).length===0&&!i.endsWith(".yaml.spec.ts")){let u=new Map;if(o.steps=de(r.steps,"main",void 0,u),o.steps.length>0){let h=new Map;o.actionStepsMap=Object.fromEntries(o.steps.map(f=>{let a=u.get(f.stepId),S;if(a?.file){if(!h.has(a.file))try{h.set(a.file,E.readFileSync(a.file,"utf-8").split(`
881
881
  `))}catch{h.set(a.file,[])}let w=h.get(a.file);S=w[a.line-1]?.trim();let v=a.line-2,T=a.line,_=[],k=a.line;v>=0&&(_.push(w[v]??""),k=a.line-1),_.push(w[a.line-1]??""),T<w.length&&_.push(w[T]??""),f.code=_.join(`
882
882
  `),f.codeStartLine=k,f.codeLine=a.line}let y={description:f.description,...S&&{action_entity:{action_description:f.description,action_data:{action_name:"js_code",args:[],kwargs:{code:S}}}}};return[f.stepId,y]}))}}return Object.keys(d).length>0?o.actionStepsMap=d:s&&o.steps.length>0&&(o.actionStepsMap=Object.fromEntries(o.steps.map(u=>{let h=s[u.stepId],f=h?.type,a={description:u.description,...f&&{action_entity:{action_description:u.description,action_data:{action_name:f==="step"?"js_code":f,args:[],kwargs:f==="step"?{code:h?.code??u.description}:{statement:u.description}}}}};return[u.stepId,a]}))),o}},Ze=ue;
package/dist/cli.js CHANGED
@@ -1019,9 +1019,9 @@ Merged ${c.length} tests from ${p} shards into: ${g}`),await so(u,o),r&&En(c),t)
1019
1019
  `;for(let c of a)s+=`- ${c}
1020
1020
  `;s+=`
1021
1021
  </details>
1022
- `}return s}function En(e){let t=process.env.GITHUB_STEP_SUMMARY;if(!t){console.warn("Warning: $GITHUB_STEP_SUMMARY not set, skipping GitHub summary.");return}T.appendFileSync(t,ao(e)),console.log("GitHub step summary written.")}var lo=_(()=>{"use strict";Qr();oo()});var po,uo=_(()=>{"use strict";po="0.1.49"});var ho={};te(ho,{runTranspile:()=>$n});import*as Be from"path";import{glob as Pn}from"glob";async function $n(e){(e.includes("--help")||e.includes("-h"))&&(console.log("Usage: shiplight transpile [glob]"),console.log(""),console.log("Transpiles YAML test files to Playwright spec files (.yaml.spec.ts)."),console.log("Validates syntax and reports action coverage warnings."),console.log("Default glob: **/*.test.yaml"),console.log(""),console.log("Examples:"),console.log(" shiplight transpile # transpile all YAML tests"),console.log(' shiplight transpile "tests/**/*.test.yaml" # transpile specific directory'),console.log(" shiplight transpile tests/login.test.yaml # transpile a single file"),process.exit(0));let t=e[0]||"**/*.test.yaml",r=process.cwd(),o=await Pn(t,{cwd:r,ignore:["node_modules/**","*.yaml.spec.ts"]});o.length===0&&(console.log(`No files matched: ${t}`),process.exit(0));let i=0,n=0,s=0;for(let a of o.sort()){let c=Be.resolve(r,a),l=Or(c,{version:po});if(!l.valid){i++,console.log(`
1022
+ `}return s}function En(e){let t=process.env.GITHUB_STEP_SUMMARY;if(!t){console.warn("Warning: $GITHUB_STEP_SUMMARY not set, skipping GitHub summary.");return}T.appendFileSync(t,ao(e)),console.log("GitHub step summary written.")}var lo=_(()=>{"use strict";Qr();oo()});var po,uo=_(()=>{"use strict";po="0.1.51"});var ho={};te(ho,{runTranspile:()=>$n});import*as Be from"path";import{glob as Pn}from"glob";async function $n(e){(e.includes("--help")||e.includes("-h"))&&(console.log("Usage: shiplight transpile [glob]"),console.log(""),console.log("Transpiles YAML test files to Playwright spec files (.yaml.spec.ts)."),console.log("Validates syntax and reports action coverage warnings."),console.log("Default glob: **/*.test.yaml"),console.log(""),console.log("Examples:"),console.log(" shiplight transpile # transpile all YAML tests"),console.log(' shiplight transpile "tests/**/*.test.yaml" # transpile specific directory'),console.log(" shiplight transpile tests/login.test.yaml # transpile a single file"),process.exit(0));let t=e[0]||"**/*.test.yaml",r=process.cwd(),o=await Pn(t,{cwd:r,ignore:["node_modules/**","*.yaml.spec.ts"]});o.length===0&&(console.log(`No files matched: ${t}`),process.exit(0));let i=0,n=0,s=0;for(let a of o.sort()){let c=Be.resolve(r,a),l=Or(c,{version:po});if(!l.valid){i++,console.log(`
1023
1023
  \u2717 ${a}`);for(let u of l.errors)console.log(` ERROR: ${u}`);continue}s++;let p=Be.basename(l.specFile);if(l.warnings.length>0){n++,console.log(`\u26A0 ${a} \u2192 ${p}`);for(let u of l.warnings)console.log(` WARNING: ${u}`)}else console.log(`\u2713 ${a} \u2192 ${p}`)}console.log(`
1024
- ${o.length} file(s): ${s} transpiled, ${i} error(s), ${n} warning(s)`),process.exit(i>0?1:0)}var fo=_(()=>{"use strict";ct();uo()});var yo={};te(yo,{runInspect:()=>Mn});import*as Ge from"fs";import*as go from"path";async function Mn(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(console.log("Usage: shiplight inspect <file.test.yaml> [options]"),console.log(""),console.log("Parse a YAML test file and output the resulting TestFlow JSON."),console.log("Useful for verifying YAML \u2192 JSON conversion."),console.log(""),console.log("Options:"),console.log(" --pretty Pretty-print JSON (default)"),console.log(" --compact Compact JSON output"),console.log(" --stats Show statement statistics only"),console.log(""),console.log("Examples:"),console.log(" shiplight inspect tests/login.test.yaml"),console.log(" shiplight inspect tests/suite.test.yaml --stats"),console.log(" shiplight inspect tests/login.test.yaml --compact | jq ."),process.exit(e.length===0?1:0));let t=e.includes("--compact"),r=e.includes("--stats"),o=e.find(s=>!s.startsWith("--"));o||(console.error("Error: no file specified"),process.exit(1));let i=go.resolve(process.cwd(),o);Ge.existsSync(i)||(console.error(`Error: file not found: ${i}`),process.exit(1));let n=Ge.readFileSync(i,"utf-8");try{let s=we(n),a=L(n);if(r)In(a,s);else{let c={...s.test_case_id!==void 0?{test_case_id:s.test_case_id}:{},...s.name?{name:s.name}:{},testFlow:a};console.log(JSON.stringify(c,null,t?0:2))}}catch(s){console.error(`Error parsing ${o}: ${s.message}`),process.exit(1)}}function In(e,t){if(console.log(`File: ${t.name||"(unnamed)"}`),t.test_case_id!==void 0&&console.log(`Cloud ID: ${t.test_case_id}`),console.log(`Version: ${e.version||"unknown"}`),e.testGroup){let r=e.testGroup;console.log("Type: suite (testGroup)"),console.log(`Tests: ${r.tests.length}`);for(let o of r.tests){let i=o.skip?` [SKIP${typeof o.skip=="string"?`: ${o.skip}`:""}]`:"";console.log(` - ${o.name}: ${o.statements.length} statements${o.teardown?`, ${o.teardown.length} teardown`:""}${i}`)}r.beforeAll?.length&&console.log(`Hooks: beforeAll (${r.beforeAll.length})`),r.afterAll?.length&&console.log(`Hooks: afterAll (${r.afterAll.length})`),r.beforeEach?.length&&console.log(`Hooks: beforeEach (${r.beforeEach.length})`),r.afterEach?.length&&console.log(`Hooks: afterEach (${r.afterEach.length})`)}else{console.log("Type: single test"),console.log(`Goal: ${e.goal}`),e.url&&console.log(`URL: ${e.url}`),e.baseURL&&console.log(`Base URL: ${e.baseURL}`),console.log(`Statements: ${e.statements?.length??0}`),e.teardown?.length&&console.log(`Teardown: ${e.teardown.length}`);let r=mo(e.statements??[]);console.log(` DRAFT: ${r.drafts}, ACTION: ${r.actions}, STEP: ${r.steps}`)}}function mo(e){let t={drafts:0,actions:0,steps:0};for(let r of e)if(r.type==="DRAFT")t.drafts++;else if(r.type==="ACTION")t.actions++;else if(r.type==="STEP"){t.steps++;let o=mo(r.statements??[]);t.drafts+=o.drafts,t.actions+=o.actions,t.steps+=o.steps}return t}var wo=_(()=>{"use strict";se()});var bo=ko((hl,On)=>{On.exports={name:"shiplightai",version:"0.1.49",type:"module",description:"Shiplight CLI for running and debugging .test.yaml files",main:"dist/index.js",types:"dist/index.d.ts",bin:{shiplight:"dist/cli.js"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/cjs/index.cjs",default:"./dist/index.js"},"./fixture":{types:"./dist/fixture.d.ts",import:"./dist/fixture.js",require:"./dist/cjs/fixture.cjs",default:"./dist/fixture.js"},"./debugger-pw":{types:"./dist/debugger-pw.d.ts",import:"./dist/debugger-pw.js",require:"./dist/cjs/debugger-pw.cjs",default:"./dist/debugger-pw.js"},"./reporter":{types:"./dist/reporter.d.ts",import:"./dist/reporter.js",require:"./dist/cjs/reporter.cjs",default:"./dist/reporter.js"}},files:["dist","!dist/**/*.map","README.md"],publishConfig:{registry:"https://registry.npmjs.org",access:"public"},scripts:{prebuild:"pnpm typecheck",build:"tsup",pack:"pnpm build && pnpm pack",clean:"rm -rf dist",dev:"tsup --watch",test:"playwright test","test:unit":"tsx --test 'src/**/*.test.ts'",typecheck:"tsc --noEmit"},dependencies:{"@ai-sdk/anthropic":"^3.0.1","@ai-sdk/google":"^3.0.1","@ai-sdk/google-vertex":"^4.0.1","@ai-sdk/openai":"^3.0.1","@ai-sdk/provider":"^3.0.1","@anthropic-ai/claude-agent-sdk":"^0.1.72","@babel/parser":"^7.28.5","@babel/plugin-transform-typescript":"^7.27.0","@google/genai":"^1.34.0","google-auth-library":"^10.0.0","@babel/preset-env":"^7.26.9","@babel/preset-typescript":"^7.27.0","@modelcontextprotocol/sdk":"^1.29.0",ai:"^6.0.3",axios:"^1.15.0",chalk:"^4.1.2",commander:"^11.0.0",dotenv:"^16.0.3",express:"^5.2.1","fs-extra":"^11.2.0",glob:"^13.0.0","html-to-text":"^9.0.5",open:"^10.1.0",openai:"^6.25.0",ora:"^5.4.1",otplib:"^13.4.0","p-retry":"^6.2.1",sharp:"^0.34.5",uuid:"^11.1.0",yaml:"^2.8.3",zod:"^3.22.0","zod-to-json-schema":"^3.24.6"},devDependencies:{"@playwright/test":"1.58.2","@types/express":"^4.17.21","@types/node":"^24.0.0","mcp-tools":"workspace:*","sdk-core":"workspace:*","sdk-internal":"workspace:*","shiplight-tools":"workspace:*","shiplight-types":"workspace:*","@loggia/common":"workspace:*",tsup:"^8.3.5",typescript:"5.5.4"},peerDependencies:{"@playwright/test":"1.58.2"},engines:{node:">=22.0.0"},keywords:["playwright","yaml","testing","automation","ai","shiplight","mcp"],author:"Shiplight",license:"MIT"}});import Ln from"dotenv";import*as M from"fs";import*as W from"path";import*as We from"os";import{execFileSync as Ao}from"child_process";var Eo="0.1.49",Po="https://registry.npmjs.org/shiplightai/latest",$o=3600*1e3,Mo=10080*60*1e3;function Ke(){return W.join(We.homedir(),".shiplight","version-check.json")}function Io(){return W.join(We.homedir(),".shiplight","npm-prefix.json")}function Oo(e=Io()){try{let r=M.readFileSync(e,"utf-8"),o=JSON.parse(r);if(typeof o.prefix=="string"&&typeof o.fetchedAt=="number"&&Date.now()-o.fetchedAt<Mo)return o.prefix}catch{}let t;try{t=Ao("npm",["config","get","prefix"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}if(!t)return null;try{M.mkdirSync(W.dirname(e),{recursive:!0}),M.writeFileSync(e,JSON.stringify({prefix:t,fetchedAt:Date.now()}))}catch{}return t}function Tt(e={}){let t=e.scriptPath??process.argv[1],r=e.getPrefix??(()=>Oo()),o=e.warn??(s=>console.warn(s)),i=e.error??(s=>console.error(s)),n=e.exit??(s=>process.exit(s));try{if(!t)return;let s=r();if(!s)return;let a,c;try{a=M.realpathSync(t),c=M.realpathSync(s)}catch{return}if(a.startsWith(c+W.sep)){i(`
1024
+ ${o.length} file(s): ${s} transpiled, ${i} error(s), ${n} warning(s)`),process.exit(i>0?1:0)}var fo=_(()=>{"use strict";ct();uo()});var yo={};te(yo,{runInspect:()=>Mn});import*as Ge from"fs";import*as go from"path";async function Mn(e){(e.includes("--help")||e.includes("-h")||e.length===0)&&(console.log("Usage: shiplight inspect <file.test.yaml> [options]"),console.log(""),console.log("Parse a YAML test file and output the resulting TestFlow JSON."),console.log("Useful for verifying YAML \u2192 JSON conversion."),console.log(""),console.log("Options:"),console.log(" --pretty Pretty-print JSON (default)"),console.log(" --compact Compact JSON output"),console.log(" --stats Show statement statistics only"),console.log(""),console.log("Examples:"),console.log(" shiplight inspect tests/login.test.yaml"),console.log(" shiplight inspect tests/suite.test.yaml --stats"),console.log(" shiplight inspect tests/login.test.yaml --compact | jq ."),process.exit(e.length===0?1:0));let t=e.includes("--compact"),r=e.includes("--stats"),o=e.find(s=>!s.startsWith("--"));o||(console.error("Error: no file specified"),process.exit(1));let i=go.resolve(process.cwd(),o);Ge.existsSync(i)||(console.error(`Error: file not found: ${i}`),process.exit(1));let n=Ge.readFileSync(i,"utf-8");try{let s=we(n),a=L(n);if(r)In(a,s);else{let c={...s.test_case_id!==void 0?{test_case_id:s.test_case_id}:{},...s.name?{name:s.name}:{},testFlow:a};console.log(JSON.stringify(c,null,t?0:2))}}catch(s){console.error(`Error parsing ${o}: ${s.message}`),process.exit(1)}}function In(e,t){if(console.log(`File: ${t.name||"(unnamed)"}`),t.test_case_id!==void 0&&console.log(`Cloud ID: ${t.test_case_id}`),console.log(`Version: ${e.version||"unknown"}`),e.testGroup){let r=e.testGroup;console.log("Type: suite (testGroup)"),console.log(`Tests: ${r.tests.length}`);for(let o of r.tests){let i=o.skip?` [SKIP${typeof o.skip=="string"?`: ${o.skip}`:""}]`:"";console.log(` - ${o.name}: ${o.statements.length} statements${o.teardown?`, ${o.teardown.length} teardown`:""}${i}`)}r.beforeAll?.length&&console.log(`Hooks: beforeAll (${r.beforeAll.length})`),r.afterAll?.length&&console.log(`Hooks: afterAll (${r.afterAll.length})`),r.beforeEach?.length&&console.log(`Hooks: beforeEach (${r.beforeEach.length})`),r.afterEach?.length&&console.log(`Hooks: afterEach (${r.afterEach.length})`)}else{console.log("Type: single test"),console.log(`Goal: ${e.goal}`),e.url&&console.log(`URL: ${e.url}`),e.baseURL&&console.log(`Base URL: ${e.baseURL}`),console.log(`Statements: ${e.statements?.length??0}`),e.teardown?.length&&console.log(`Teardown: ${e.teardown.length}`);let r=mo(e.statements??[]);console.log(` DRAFT: ${r.drafts}, ACTION: ${r.actions}, STEP: ${r.steps}`)}}function mo(e){let t={drafts:0,actions:0,steps:0};for(let r of e)if(r.type==="DRAFT")t.drafts++;else if(r.type==="ACTION")t.actions++;else if(r.type==="STEP"){t.steps++;let o=mo(r.statements??[]);t.drafts+=o.drafts,t.actions+=o.actions,t.steps+=o.steps}return t}var wo=_(()=>{"use strict";se()});var bo=ko((hl,On)=>{On.exports={name:"shiplightai",version:"0.1.51",type:"module",description:"Shiplight CLI for running and debugging .test.yaml files",main:"dist/index.js",types:"dist/index.d.ts",bin:{shiplight:"dist/cli.js"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/cjs/index.cjs",default:"./dist/index.js"},"./fixture":{types:"./dist/fixture.d.ts",import:"./dist/fixture.js",require:"./dist/cjs/fixture.cjs",default:"./dist/fixture.js"},"./debugger-pw":{types:"./dist/debugger-pw.d.ts",import:"./dist/debugger-pw.js",require:"./dist/cjs/debugger-pw.cjs",default:"./dist/debugger-pw.js"},"./reporter":{types:"./dist/reporter.d.ts",import:"./dist/reporter.js",require:"./dist/cjs/reporter.cjs",default:"./dist/reporter.js"}},files:["dist","!dist/**/*.map","README.md"],publishConfig:{registry:"https://registry.npmjs.org",access:"public"},scripts:{prebuild:"pnpm typecheck",build:"tsup",pack:"pnpm build && pnpm pack",clean:"rm -rf dist",dev:"tsup --watch",test:"playwright test","test:unit":"tsx --test 'src/**/*.test.ts'",typecheck:"tsc --noEmit"},dependencies:{"@ai-sdk/anthropic":"^3.0.1","@ai-sdk/google":"^3.0.1","@ai-sdk/google-vertex":"^4.0.1","@ai-sdk/openai":"^3.0.1","@ai-sdk/provider":"^3.0.1","@anthropic-ai/claude-agent-sdk":"^0.1.72","@babel/parser":"^7.28.5","@babel/plugin-transform-typescript":"^7.27.0","@google/genai":"^1.34.0","google-auth-library":"^10.0.0","@babel/preset-env":"^7.26.9","@babel/preset-typescript":"^7.27.0","@modelcontextprotocol/sdk":"^1.29.0",ai:"^6.0.3",axios:"^1.15.0",chalk:"^4.1.2",commander:"^11.0.0",dotenv:"^16.0.3",express:"^5.2.1","fs-extra":"^11.2.0",glob:"^13.0.0","html-to-text":"^9.0.5",open:"^10.1.0",openai:"^6.25.0",ora:"^5.4.1",otplib:"^13.4.0","p-retry":"^6.2.1",sharp:"^0.34.5",uuid:"^11.1.0",yaml:"^2.8.3",zod:"^3.22.0","zod-to-json-schema":"^3.24.6"},devDependencies:{"@playwright/test":"1.58.2","@types/express":"^4.17.21","@types/node":"^24.0.0","mcp-tools":"workspace:*","sdk-core":"workspace:*","sdk-internal":"workspace:*","shiplight-tools":"workspace:*","shiplight-types":"workspace:*","@loggia/common":"workspace:*",tsup:"^8.3.5",typescript:"5.5.4"},peerDependencies:{"@playwright/test":"1.58.2"},engines:{node:">=22.0.0"},keywords:["playwright","yaml","testing","automation","ai","shiplight","mcp"],author:"Shiplight",license:"MIT"}});import Ln from"dotenv";import*as M from"fs";import*as W from"path";import*as We from"os";import{execFileSync as Ao}from"child_process";var Eo="0.1.51",Po="https://registry.npmjs.org/shiplightai/latest",$o=3600*1e3,Mo=10080*60*1e3;function Ke(){return W.join(We.homedir(),".shiplight","version-check.json")}function Io(){return W.join(We.homedir(),".shiplight","npm-prefix.json")}function Oo(e=Io()){try{let r=M.readFileSync(e,"utf-8"),o=JSON.parse(r);if(typeof o.prefix=="string"&&typeof o.fetchedAt=="number"&&Date.now()-o.fetchedAt<Mo)return o.prefix}catch{}let t;try{t=Ao("npm",["config","get","prefix"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}if(!t)return null;try{M.mkdirSync(W.dirname(e),{recursive:!0}),M.writeFileSync(e,JSON.stringify({prefix:t,fetchedAt:Date.now()}))}catch{}return t}function Tt(e={}){let t=e.scriptPath??process.argv[1],r=e.getPrefix??(()=>Oo()),o=e.warn??(s=>console.warn(s)),i=e.error??(s=>console.error(s)),n=e.exit??(s=>process.exit(s));try{if(!t)return;let s=r();if(!s)return;let a,c;try{a=M.realpathSync(t),c=M.realpathSync(s)}catch{return}if(a.startsWith(c+W.sep)){i(`
1025
1025
  shiplightai cannot be run from a global install.
1026
1026
  Global installs don't auto-update and cause version skew.
1027
1027