@gfdelarue/testkit 0.3.1 → 0.3.3

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.
Files changed (60) hide show
  1. package/README.md +1 -1
  2. package/bin/testkit-windows-owner-arm64.exe +0 -0
  3. package/bin/testkit-windows-owner-x64.exe +0 -0
  4. package/dist/app/cloud/control.js +2 -2
  5. package/dist/app/cloud/login.d.ts +4 -4
  6. package/dist/app/inspect/artifacts.d.ts +4 -4
  7. package/dist/app/run/engine-failure-stack.d.ts +1 -0
  8. package/dist/app/run/engine-failure-stack.js +2 -0
  9. package/dist/app/run/worker-loop.js +1 -1
  10. package/dist/app/setup/playwright.js +1 -1
  11. package/dist/app/typecheck/index.js +4 -4
  12. package/dist/cli/command-catalog.d.ts +24 -24
  13. package/dist/cli/command-flags.d.ts +3 -3
  14. package/dist/cli/commands/artifacts.d.ts +16 -16
  15. package/dist/cli/commands/cleanup.d.ts +1 -1
  16. package/dist/cli/commands/cloud/login.d.ts +1 -1
  17. package/dist/cli/commands/cloud/status.d.ts +3 -3
  18. package/dist/config/loader/discover-tests.d.ts +5 -0
  19. package/dist/config/loader/discover-tests.js +1 -1
  20. package/dist/config/loader/file-metadata.d.ts +1 -1
  21. package/dist/config/loader/file-metadata.js +1 -1
  22. package/dist/config/loader/index.d.ts +1 -1
  23. package/dist/config/loader/index.js +1 -1
  24. package/dist/database/docker-metadata.d.ts +3 -0
  25. package/dist/database/docker-metadata.js +3 -0
  26. package/dist/database/docker.js +5 -5
  27. package/dist/database/index.js +1 -1
  28. package/dist/database/local-postgres.js +1 -1
  29. package/dist/database/postgres/index.js +2 -2
  30. package/dist/database/runtime-config.d.ts +5 -5
  31. package/dist/database/schema-source.d.ts +4 -1
  32. package/dist/database/schema-source.js +3 -3
  33. package/dist/database/template-steps.d.ts +4 -0
  34. package/dist/database/template-steps.js +4 -4
  35. package/dist/engines/managed-module-resolution.js +5 -3
  36. package/dist/engines/node-vitest/adapter/consumer-typescript-paths.js +2 -2
  37. package/dist/engines/node-vitest/runtime/runtime-input.js +1 -1
  38. package/dist/engines/playwright/runtime/runtime-input.js +1 -1
  39. package/dist/environment/template.d.ts +20 -20
  40. package/dist/process/execa-bundle-licenses.txt +411 -0
  41. package/dist/process/execa-bundle.json +874 -0
  42. package/dist/process/files/json-file.js +1 -1
  43. package/dist/process/host-process.d.ts +6 -1
  44. package/dist/process/host-process.js +1 -1
  45. package/dist/process/index.d.ts +2 -2
  46. package/dist/process/locks.js +3 -3
  47. package/dist/process/process-contracts.d.ts +10 -2
  48. package/dist/process/process-identity.js +1 -1
  49. package/dist/process/process.d.ts +3 -2
  50. package/dist/process/process.js +46 -1
  51. package/dist/repo/metadata.js +1 -1
  52. package/dist/repo/state.d.ts +1 -0
  53. package/dist/repo/state.js +4 -4
  54. package/dist/steps/configured-step-testkit-modules.d.ts +1 -1
  55. package/dist/steps/run.js +2 -2
  56. package/dist/toolchains/archive.js +1 -1
  57. package/dist/toolchains/node-integrity.d.ts +2 -0
  58. package/dist/toolchains/node-integrity.js +1 -1
  59. package/dist/toolchains/node-provisioning.js +2 -2
  60. package/package.json +4 -3
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="assets/logo.png" alt="AI Testkit logo" width="600">
2
+ <img src="https://testkit.cloud/assets/social-card.png" alt="AI Testkit logo" width="600">
3
3
  </p>
4
4
 
5
5
  # @gfdelarue/testkit
Binary file
Binary file
@@ -1,5 +1,5 @@
1
1
  import{setTimeout as v}from"node:timers/promises";import c from"node:fs";import $ from"node:path";import{randomUUID as I}from"node:crypto";import{execFileSync as R}from"node:child_process";import{CloudAccountClient as E}from"../../cloud/account.js";import{invalidResponse as u}from"../../cloud/transport.js";import{isUnknownRecord as p}from"../../kernel/unknown-values.js";import{cloudToken as k}from"./credentials.js";import{openBrowser as C,selectedCloudOrigin as S}from"./login.js";import{allItems as l,createdResourceDashboardLink as x}from"./control-links.js";export async function controlClient(o={},r=!0){const e=S(o);return new E(e,await k(e,o.env??process.env,r))}async function m(o,r,e,n){const t=r?o.filter(a=>a.id===r||a.slug===r||a.name===r):o;if(t.length>1&&!r&&n){const a=t.map(s=>{if(typeof s.id!="string"||!s.id)throw u(`${e} identity`);return{id:s.id,name:typeof s.name=="string"?s.name:s.id}}),d=await n(e,a);if(!a.some(s=>s.id===d))throw new Error(`Invalid ${e} selection`);return d}if(t.length!==1)throw new Error(`${e} ${r?`"${r}" `:""}${t.length?"is ambiguous":"was not found"}. Select an explicit ID from cloud list ${e==="organisation"?"organisations":"projects"}.`);const i=t[0]?.id;if(typeof i!="string"||!i)throw u(`${e} identity`);return i}export async function resolveOrganisation(o,r,e){const n=await l(o,"/api/v1/organisations");return m(n.map(t=>{if(!p(t.organisation))throw u("organisation");return t.organisation}),r,"organisation",e)}export async function resolveProject(o,r){const e=r.project??(r.env??process.env).TESTKIT_CLOUD_PROJECT_ID;if(e?.startsWith("prj_"))return e;const n=r.organisation?`?organisationId=${encodeURIComponent(await resolveOrganisation(o,r.organisation,r.choose))}`:"",t=await l(o,`/api/v1/projects${n}`),i=e?void 0:g(),a=i?projectsForRepository(t,i):[];return m(a.length?a:t,e,"project",r.choose)}function g(){try{return R("git",["remote","get-url","origin"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return}}export function projectsForRepository(o,r){let e;try{e=parseRepository(r)}catch{return[]}return o.filter(n=>{const t=n.repository;return p(t)&&t.host===e.host&&`${String(t.owner)}/${String(t.name)}`===e.repository})}export async function applyAccountCommand(o,r={}){const e=o.operation==="token.create";if(r.secretOutput!==void 0&&!e)throw new Error("--secret-output is only supported for token.create.");const n=r.secretOutput?$.resolve(r.secretOutput):void 0;if(e&&!n)throw new Error("Credential creation requires --secret-output <new-file> to save the issued token privately.");const t=n?c.openSync(n,"wx",384):void 0;let i=!1,a=!1,d=!1;try{const s=await controlClient(r);d=e;const f=await s.request("POST","/api/v1/account/commands",o);if(e&&t!==void 0&&n!==void 0){if(i=!0,!p(f)||typeof f.value!="string")throw u("issued credential");c.writeFileSync(t,`${f.value}
2
- `),c.fsyncSync(t);const y=c.fstatSync(t),h=c.lstatSync(n);if(!h.isFile()||h.ino!==y.ino||h.dev!==y.dev)throw new Error("Credential output was replaced while the command was running");c.closeSync(t),a=!0;const w={...f};return delete w.value,{...w,secretFile:n}}return await waitForConnection(s,f,r)}catch(s){throw d&&n!==void 0?new Error(`Cloud ${i?"issued the credential, but saving it failed":"may have issued the credential before the request failed"}. Retry the same command and idempotency key with --secret-output pointing to a new file to recover it. Output path: ${n}.`,{cause:s}):s}finally{if(t!==void 0&&!a){const s=c.fstatSync(t);c.closeSync(t),!i&&s.size===0&&n!==void 0&&O(n,s)}}}function O(o,r){try{const e=c.lstatSync(o);e.isFile()&&e.size===0&&e.ino===r.ino&&e.dev===r.dev&&c.unlinkSync(o)}catch(e){if(!p(e)||e.code!=="ENOENT")throw e}}export async function waitForConnection(o,r,e){if(!p(r)||typeof r.operationId!="string"||r.status==="complete")return r;let n=!1;for(;;){e.signal?.throwIfAborted();const t=await j(o,r.operationId);if(t.status==="complete")return t;if(t.status!=="pending"&&t.status!=="processing")throw new Error(`Repository connection ${r.operationId} is ${String(t.status)}. Inspect with cloud show connection ${r.operationId}; retry the create command with a new request key after checking access.`);if(t.status==="pending"&&!n){if(typeof t.verificationUrl!="string")throw u("repository approval link");const i=new URL(t.verificationUrl);if(i.origin!==o.origin||i.username||i.password||i.pathname!==`/cli/projects/${r.operationId}/authorize`)throw u("repository approval link");if(e.notify?.(`Open ${i.href}
2
+ `),c.fsyncSync(t);const y=c.fstatSync(t,{bigint:!0}),h=c.lstatSync(n,{bigint:!0});if(!h.isFile()||h.ino!==y.ino||h.dev!==y.dev)throw new Error("Credential output was replaced while the command was running");c.closeSync(t),a=!0;const w={...f};return delete w.value,{...w,secretFile:n}}return await waitForConnection(s,f,r)}catch(s){throw d&&n!==void 0?new Error(`Cloud ${i?"issued the credential, but saving it failed":"may have issued the credential before the request failed"}. Retry the same command and idempotency key with --secret-output pointing to a new file to recover it. Output path: ${n}.`,{cause:s}):s}finally{if(t!==void 0&&!a){const s=c.fstatSync(t,{bigint:!0});c.closeSync(t),!i&&s.size===0n&&n!==void 0&&b(n,s)}}}function b(o,r){try{const e=c.lstatSync(o,{bigint:!0});e.isFile()&&e.size===0n&&e.ino===r.ino&&e.dev===r.dev&&c.unlinkSync(o)}catch(e){if(!p(e)||e.code!=="ENOENT")throw e}}export async function waitForConnection(o,r,e){if(!p(r)||typeof r.operationId!="string"||r.status==="complete")return r;let n=!1;for(;;){e.signal?.throwIfAborted();const t=await O(o,r.operationId);if(t.status==="complete")return t;if(t.status!=="pending"&&t.status!=="processing")throw new Error(`Repository connection ${r.operationId} is ${String(t.status)}. Inspect with cloud show connection ${r.operationId}; retry the create command with a new request key after checking access.`);if(t.status==="pending"&&!n){if(typeof t.verificationUrl!="string")throw u("repository approval link");const i=new URL(t.verificationUrl);if(i.origin!==o.origin||i.username||i.password||i.pathname!==`/cli/projects/${r.operationId}/authorize`)throw u("repository approval link");if(e.notify?.(`Open ${i.href}
3
3
  Waiting for repository authorization. Operation: ${r.operationId}
4
- `),(e.env??process.env).CI)throw new Error(`Repository authorization requires a person. Open ${i.href}, then retry the same request key. Operation: ${r.operationId}`);e.browser!==!1&&C(i.href),n=!0}if((e.env??process.env).CI)throw new Error(`Repository connection ${r.operationId} is processing. Inspect with cloud show connection ${r.operationId}, then retry the same request key to resume.`);if(typeof t.expiresAt!="string"||!Number.isFinite(Date.parse(t.expiresAt)))throw u("connection expiry");if(Date.now()>=Date.parse(t.expiresAt))throw new Error(`Repository connection ${r.operationId} expired. Start a new request.`);await v(2e3,void 0,{signal:e.signal})}}async function j(o,r){const e=await o.request("GET",`/api/v1/project-connections/${encodeURIComponent(r)}`);if(!p(e)||e.operationId!==r||typeof e.status!="string")throw u("repository connection");return e}export async function createCloudProject(o){const r=o.repository??g();if(!r)throw new Error("Pass --repository owner/repo when outside Git or when origin is unavailable.");const e=parseRepository(r,o.host),n=await controlClient(o),t=await resolveOrganisation(n,o.organisation,o.choose),i=o.requestKey??I();o.notify?.(`Request key: ${i}. Reuse --request-key ${i} to resume this operation.
4
+ `),(e.env??process.env).CI)throw new Error(`Repository authorization requires a person. Open ${i.href}, then retry the same request key. Operation: ${r.operationId}`);e.browser!==!1&&C(i.href),n=!0}if((e.env??process.env).CI)throw new Error(`Repository connection ${r.operationId} is processing. Inspect with cloud show connection ${r.operationId}, then retry the same request key to resume.`);if(typeof t.expiresAt!="string"||!Number.isFinite(Date.parse(t.expiresAt)))throw u("connection expiry");if(Date.now()>=Date.parse(t.expiresAt))throw new Error(`Repository connection ${r.operationId} expired. Start a new request.`);await v(2e3,void 0,{signal:e.signal})}}async function O(o,r){const e=await o.request("GET",`/api/v1/project-connections/${encodeURIComponent(r)}`);if(!p(e)||e.operationId!==r||typeof e.status!="string")throw u("repository connection");return e}export async function createCloudProject(o){const r=o.repository??g();if(!r)throw new Error("Pass --repository owner/repo when outside Git or when origin is unavailable.");const e=parseRepository(r,o.host),n=await controlClient(o),t=await resolveOrganisation(n,o.organisation,o.choose),i=o.requestKey??I();o.notify?.(`Request key: ${i}. Reuse --request-key ${i} to resume this operation.
5
5
  `);const a=await applyAccountCommand({schemaVersion:1,idempotencyKey:i,operation:"project.create",organisationId:t,input:{name:o.name??e.repository.split("/")[1],repository:e.repository,host:e.host,provider:o.provider??(e.host==="github.com"?"github":"gitea"),publishDecisions:o.publishDecisions??!1}},o);return x(n,"project",a,o.env??process.env)}export function parseRepository(o,r){let e=o.trim(),n="github.com";if(e.includes("://")){const t=new URL(e);if(!["https:","http:","ssh:","git:"].includes(t.protocol)||t.search||t.hash)throw new Error("Repository must be owner/repo or a Git remote URL.");n=t.protocol==="ssh:"||t.protocol==="git:"?t.hostname:t.host,e=t.pathname.replace(/^\//u,"")}else{const t=/^(?:[^@/]+@)?([^/:]+):(.+)$/.exec(e);t?.[1]&&t[2]&&(n=t[1].toLowerCase(),e=t[2])}if(e=e.replace(/\/+$/u,"").replace(/\.git$/u,""),!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(e)||e.split("/").some(t=>t==="."||t===".."))throw new Error("Repository must be owner/repo or a Git remote URL.");return{host:r??n,repository:e}}
@@ -11,7 +11,6 @@ export declare function selectedCloudOrigin(options: {
11
11
  env?: NodeJS.ProcessEnv;
12
12
  }): string;
13
13
  export declare function loginToCloud(options: LoginOptions): Promise<{
14
- reused: boolean;
15
14
  user: {
16
15
  id: string;
17
16
  email: string;
@@ -20,6 +19,7 @@ export declare function loginToCloud(options: LoginOptions): Promise<{
20
19
  expiresAt: string;
21
20
  maximumExpiresAt: string;
22
21
  origin: string;
22
+ reused: boolean;
23
23
  }>;
24
24
  export declare function cloudLoginStatus(options: {
25
25
  origin?: string;
@@ -30,10 +30,10 @@ export declare function cloudLoginStatus(options: {
30
30
  authenticated: null;
31
31
  message: string;
32
32
  } | {
33
+ message?: undefined;
33
34
  origin: string;
34
35
  source: "none";
35
36
  authenticated: boolean;
36
- message?: undefined;
37
37
  } | {
38
38
  user: {
39
39
  id: string;
@@ -42,15 +42,15 @@ export declare function cloudLoginStatus(options: {
42
42
  };
43
43
  expiresAt: string;
44
44
  maximumExpiresAt: string;
45
+ message?: undefined;
45
46
  origin: string;
46
47
  source: "account";
47
48
  authenticated: boolean;
48
- message?: undefined;
49
49
  } | {
50
+ message?: undefined;
50
51
  origin: string;
51
52
  source: "account";
52
53
  authenticated: boolean;
53
- message?: undefined;
54
54
  }>;
55
55
  export declare function logoutOfCloud(options: {
56
56
  origin?: string;
@@ -8,21 +8,21 @@ export declare function inspectArtifacts(options: Readonly<{
8
8
  }>): {
9
9
  mode: "runs";
10
10
  runs: import("../../evidence/contracts.js").RunBundleSummary[];
11
- runId?: undefined;
12
11
  verification?: undefined;
12
+ runId?: undefined;
13
13
  entries?: undefined;
14
14
  } | {
15
+ runs?: undefined;
15
16
  mode: "verify";
16
17
  runId: string | null;
17
18
  verification: import("../../evidence/contracts.js").RunBundleVerification;
18
- runs?: undefined;
19
19
  entries?: undefined;
20
20
  } | {
21
+ runs?: undefined;
22
+ verification?: undefined;
21
23
  mode: "artifacts";
22
24
  runId: string | null;
23
25
  entries: import("../../evidence/reading.js").CollectedArtifactEntry[];
24
- runs?: undefined;
25
- verification?: undefined;
26
26
  };
27
27
  export type ArtifactInspectionEntry = Extract<ReturnType<typeof inspectArtifacts>, {
28
28
  mode: "artifacts";
@@ -0,0 +1 @@
1
+ export declare function formatEngineInvocationStack(error: unknown): string | undefined;
@@ -0,0 +1,2 @@
1
+ import{sanitizeErrorMessage as M}from"../../kernel/error-serialization.js";import{redactSensitiveText as _}from"../../kernel/redaction.js";const S=6,d=12,b=4096,T=16384,c="[diagnostic limit reached]";export function formatEngineInvocationStack(n){if(!A(n))return;const f=new WeakSet,e=[],p=[];let g=0,m=0;function r(t){const o=T-c.length-m;if(o<=0)return;const a=`${e.length?`
2
+ `:""}${t}`;e.push(a.slice(0,o)),m+=Math.min(a.length,o)}function h(t,o,a){if(a>S||g>=d){r(`${o}${c}`);return}if(!A(t)){r(`${o}[non-Error cause omitted]`);return}if(f.has(t)){r(`${o}[error already shown]`);return}f.add(t),g+=1;const $=u(t,"cause");$!==void 0&&h($,"Caused by: ",a+1);const y=u(t,"errors");if(x(y)){const s=u(y,"length");if(typeof s=="number"){for(let i=0;i<Math.min(s,d);i+=1){if(g>=d){r(c);break}h(u(y,i.toString()),`Aggregate member ${i.toString()}: `,a+1)}s>d&&r(c)}}r(`${o}${l(t,"name")??"Error"}`);for(const s of["code","errno","syscall","path","dest"]){const i=u(t,s);typeof i=="string"?r(`${s}=${k(i)}`):typeof i=="number"&&Number.isFinite(i)&&r(`${s}=${i.toString()}`)}r(l(t,"message")??"[message unavailable]");const E=l(t,"stack");E!==void 0&&p.push(E)}h(n,"",0);for(const t of p)r(t);return e.join("")+(m>=T-c.length?c:"")}function k(n){return n.length>b?c:_(M(n))}function l(n,f){const e=u(n,f);return typeof e=="string"&&e.length>0?k(e):void 0}function u(n,f){try{const e=Object.getOwnPropertyDescriptor(n,f);return e&&"value"in e?e.value:void 0}catch{return}}function A(n){try{return n instanceof Error}catch{return!1}}function x(n){try{return Array.isArray(n)}catch{return!1}}
@@ -1 +1 @@
1
- import{EngineExecutionBridgeError as I,executeEngineTask as W}from"./engine-execution.js";import{formatError as L}from"../../kernel/error-serialization.js";import{DEFAULT_ENGINE_REPORTER_CALLBACK_TIMEOUT_MS as q,invokeBoundedReporterCallback as P}from"./engine-execution-reporting.js";import{taskNeedsLocalRuntime as j}from"./planning.js";import{drainRuntimeFailedTasks as U}from"./runtime-failures.js";import{buildTimingObservation as z}from"./scheduler/observations.js";import{buildTaskBatch as J,claimCompatibleTaskBatch as H,expandTaskResultOutcomes as Q}from"./task-batches.js";export function createWorker(e,t){return{workerId:e,productDir:t,currentGraphKey:null,graphSwitches:0,taskCount:0}}export async function runWorker(e,t,i,r,n,u,c,h,p,f=null){const _=Date.now(),y=[],G=[];try{for(;!i.isStopRequested();){const d=c(t,e.currentGraphKey,a=>i.canAcquire(a));if(!d){const a=U(t,i);if(a.length>0){const o=Date.now(),s=new Set;for(const m of a)h(n,m.task,{status:"not_run",reason:m.reason,durationMs:0,startedAt:o,finishedAt:o,error:null,infraFailed:m.infraFailed,blockedByRuntime:m.blockedByRuntime,failureDetails:m.failureDetails}),s.has(m.graph.key)||(p(n,m.graph,m.message,o,{classification:"infra"}),s.add(m.graph.key));e.taskCount+=a.length;continue}if(t.length===0)break;await ae(10);continue}let k=null,w=[d],T=d,v=!1,K=null,O="acquire",E=[],b=null;try{w=H(t,d),T=J(w)??d,e.currentGraphKey!==null&&e.currentGraphKey!==d.graphKey&&(e.graphSwitches+=1),e.currentGraphKey=d.graphKey,k=await i.acquire({...T,startApplicationServices:j(T)}),O="execute";const a=await W(r,k,T,i,f);O="mapping";const o=Q(a);E=resolveWorkerOutcomeMappings(w,o),E.some(({outcome:s})=>s.infraFailed&&s.blockedByRuntime)&&(v=!0)}catch(a){const o=O==="acquire"?te(a,i):ee(a);K={disposition:o,error:a},v=k!==null&&o.runtimeImpact!=="none"}finally{b=await Y(i,k,v)}const l=[];let R=null;const F=()=>{if(R!==null)return R;try{R=ie(i,k,d)}catch(a){l.push(C("Runtime failure graph resolution failed",a)),R=X(k,d)}return R};if(K===null){for(const{outcome:o,task:s}of E)await A({operationErrors:l,outcome:o,recordTaskOutcome:h,recordTiming:!0,reporter:f,reportTaskFinished:!1,task:s,timingUpdates:u,trackers:n});e.taskCount+=E.length;const a=E.filter(({outcome:o})=>o.infraFailed&&o.blockedByRuntime);if(a.length>0){const o=a.map(({outcome:s})=>s.reason??s.error??"Runtime readiness failed before engine execution").join("; ");y.push(o),await S(l,"Runtime error reporter failed",()=>f?.runtimeError?.(d,o)),await g(l,"Runtime graph failure recording failed",()=>{i.markGraphFailed(d.graphKey,o)}),await g(l,"Result graph error recording failed",()=>{p(n,F(),o,Date.now(),{classification:"infra"})})}}else{const{disposition:a,error:o}=K,s=L(o),m=V(w,o);a.status!=="cancelled"&&y.push(s),a.notifyRuntimeError&&await S(l,"Runtime error reporter failed",()=>f?.runtimeError?.(m,s)),a.status!=="cancelled"&&(a.runtimeImpact==="fail-graph"&&await g(l,"Runtime graph failure recording failed",()=>{i.markGraphFailed(d.graphKey,s)}),await g(l,"Result graph error recording failed",()=>{p(n,F(),s,Date.now(),{classification:a.classification??"product"})}));const N=Date.now();for(const B of w){const x=o instanceof I&&o.completedOutcomesByTaskId.has(String(B.id)),M=Z(B,T,o,a,s,N);await A({operationErrors:l,outcome:M,recordTaskOutcome:h,recordTiming:x,reporter:f,reportTaskFinished:!x,task:B,timingUpdates:u,trackers:n})}e.taskCount+=w.length}if(b!==null){const a=b.message;y.push(a),await S(l,"Runtime error reporter failed",()=>f?.runtimeError?.(d,a)),b.recovered||await g(l,"Runtime graph failure recording failed",()=>{i.markGraphFailed(d.graphKey,a)}),await g(l,"Result graph error recording failed",()=>{p(n,F(),a,Date.now(),{classification:"infra"})})}if(l.length>0){const a=[...l];for(const s of a)y.push(s.message);const o=a.map(s=>s.message).join("; ");await g(l,"Result graph error recording failed while reporting a Testkit operation failure",()=>{p(n,F(),o,Date.now(),{classification:"infra"})});for(const s of l.slice(a.length))y.push(s.message);l.length>a.length&&G.push(...a.map(s=>s.message),...l.slice(a.length).map(s=>s.message))}}}finally{e.currentGraphKey=null}return{workerId:e.workerId,failed:y.length>0,durationMs:Date.now()-_,taskCount:e.taskCount,graphSwitches:e.graphSwitches,errors:y,unpersistedErrors:G}}async function A({operationErrors:e,outcome:t,recordTaskOutcome:i,recordTiming:r,reporter:n,reportTaskFinished:u,task:c,timingUpdates:h,trackers:p}){await g(e,`Task outcome recording failed for ${c.file}`,()=>{i(p,c,t)}),u&&await S(e,`Task-finished reporter failed for ${c.file}`,()=>n?.taskFinished?.(c,t)),r&&await g(e,`Task timing recording failed for ${c.file}`,()=>{const f=z(c,t);f&&h.push(f)})}async function g(e,t,i){try{await i()}catch(r){e.push(C(t,r))}}async function S(e,t,i){await g(e,t,()=>P(t,i,{timeoutMs:q}))}function C(e,t){const i=$(t);return new Error(`${e}: ${i.message}`,{cause:i})}function V(e,t){const i=e[0];if(!(t instanceof I))return i;if(t.failingTaskId!==null){const r=e.find(n=>String(n.id)===t.failingTaskId);if(r!==void 0)return r}return e.find(r=>!t.completedOutcomesByTaskId.has(String(r.id)))??i}function X(e,t){return{key:e?.graphKey??t.graphKey,targetNames:e?.targetNames??[t.targetName]}}async function Y(e,t,i){if(t===null)return null;try{return await e.release(t.leaseId,{invalidate:i}),null}catch(r){const n=$(r);try{return await e.release(t.leaseId,{invalidate:!0}),{message:`Runtime lease release failed but recovered on idempotent retry: ${n.message}`,recovered:!0}}catch(u){const c=$(u);return{message:`Runtime lease release failed: ${n.message}; idempotent retry also failed: ${c.message}`,recovered:!1}}}}function Z(e,t,i,r,n,u){const c={kind:"engine-invocation",key:"engine_invocation_failed",title:"Engine invocation failed",count:1,...r.classification===void 0?{}:{classification:r.classification},message:n,...i instanceof Error&&i.stack?{stack:i.stack}:{}},h=i instanceof I?i.completedOutcomesByTaskId.get(String(e.id)):void 0;if(h!==void 0)return h;const p=i instanceof I?i.artifactReferencesByTaskId.get(String(e.id))??[]:[];return{task:e,status:r.status,error:r.status==="failed"?n:null,reason:r.status==="failed"?null:n,infraFailed:r.classification==="infra",blockedByRuntime:r.status==="not_run",durationMs:0,startedAt:u,finishedAt:u,artifacts:[...p],failureDetails:r.status==="cancelled"?[]:[c],checkDetails:[],..."batchTasks"in t?{runtimeBatch:{id:t.batchId,index:t.batchTasks.findIndex(f=>f.id===e.id&&f.file===e.file),fileCount:t.batchTasks.length,files:t.batchTasks.map(f=>f.file)}}:{}}}function ee(e){return e instanceof I?e.disposition:{classification:"infra",notifyRuntimeError:!0,runtimeImpact:"none",status:"not_run"}}function te(e,t){return t.signal.aborted&&e===t.signal.reason?{classification:void 0,notifyRuntimeError:!1,runtimeImpact:"none",status:"cancelled"}:{classification:"infra",notifyRuntimeError:!0,runtimeImpact:"fail-graph",status:"not_run"}}export function resolveWorkerOutcomeMappings(e,t){const i=new Map;for(const n of e){const u=D(n);if(i.has(u))throw new Error(`Worker claimed duplicate task ${n.id.toString()} (${n.file})`);i.set(u,n)}const r=new Map;for(const n of t){const u=D(n.task),c=i.get(u);if(!c)throw new Error(`Task runner returned an outcome for unclaimed task ${n.task.id.toString()} (${n.task.file})`);if(r.has(u))throw new Error(`Task runner returned duplicate outcomes for claimed task ${c.id.toString()} (${c.file})`);r.set(u,{outcome:n,task:c})}for(const n of e)if(!r.has(D(n)))throw new Error(`Task runner did not return an outcome for claimed task ${n.id.toString()} (${n.file})`);return[...r.values()]}function D(e){return JSON.stringify([typeof e.id,e.id,e.file])}function ie(e,t,i){return e.getGraph(i.graphKey)??{key:t?.graphKey??i.graphKey,targetNames:t?.targetNames??[i.targetName]}}function ae(e){return new Promise(t=>setTimeout(t,e))}function $(e){return e instanceof Error?e:new Error(String(e))}
1
+ import{EngineExecutionBridgeError as b,executeEngineTask as W}from"./engine-execution.js";import{formatError as L}from"../../kernel/error-serialization.js";import{formatEngineInvocationStack as q}from"./engine-failure-stack.js";import{DEFAULT_ENGINE_REPORTER_CALLBACK_TIMEOUT_MS as P,invokeBoundedReporterCallback as j}from"./engine-execution-reporting.js";import{taskNeedsLocalRuntime as U}from"./planning.js";import{drainRuntimeFailedTasks as z}from"./runtime-failures.js";import{buildTimingObservation as J}from"./scheduler/observations.js";import{buildTaskBatch as H,claimCompatibleTaskBatch as Q,expandTaskResultOutcomes as V}from"./task-batches.js";export function createWorker(e,t){return{workerId:e,productDir:t,currentGraphKey:null,graphSwitches:0,taskCount:0}}export async function runWorker(e,t,i,r,a,u,l,h,g,d=null){const k=Date.now(),y=[],x=[];try{for(;!i.isStopRequested();){const f=l(t,e.currentGraphKey,n=>i.canAcquire(n));if(!f){const n=z(t,i);if(n.length>0){const o=Date.now(),s=new Set;for(const m of n)h(a,m.task,{status:"not_run",reason:m.reason,durationMs:0,startedAt:o,finishedAt:o,error:null,infraFailed:m.infraFailed,blockedByRuntime:m.blockedByRuntime,failureDetails:m.failureDetails}),s.has(m.graph.key)||(g(a,m.graph,m.message,o,{classification:"infra"}),s.add(m.graph.key));e.taskCount+=n.length;continue}if(t.length===0)break;await ae(10);continue}let w=null,T=[f],E=f,K=!1,O=null,B="acquire",R=[],F=null;try{T=Q(t,f),E=H(T)??f,e.currentGraphKey!==null&&e.currentGraphKey!==f.graphKey&&(e.graphSwitches+=1),e.currentGraphKey=f.graphKey,w=await i.acquire({...E,startApplicationServices:U(E)}),B="execute";const n=await W(r,w,E,i,d);B="mapping";const o=V(n);R=resolveWorkerOutcomeMappings(T,o),R.some(({outcome:s})=>s.infraFailed&&s.blockedByRuntime)&&(K=!0)}catch(n){const o=B==="acquire"?ie(n,i):te(n);O={disposition:o,error:n},K=w!==null&&o.runtimeImpact!=="none"}finally{F=await Z(i,w,K)}const c=[];let I=null;const S=()=>{if(I!==null)return I;try{I=ne(i,w,f)}catch(n){c.push(_("Runtime failure graph resolution failed",n)),I=Y(w,f)}return I};if(O===null){for(const{outcome:o,task:s}of R)await C({operationErrors:c,outcome:o,recordTaskOutcome:h,recordTiming:!0,reporter:d,reportTaskFinished:!1,task:s,timingUpdates:u,trackers:a});e.taskCount+=R.length;const n=R.filter(({outcome:o})=>o.infraFailed&&o.blockedByRuntime);if(n.length>0){const o=n.map(({outcome:s})=>s.reason??s.error??"Runtime readiness failed before engine execution").join("; ");y.push(o),await v(c,"Runtime error reporter failed",()=>d?.runtimeError?.(f,o)),await p(c,"Runtime graph failure recording failed",()=>{i.markGraphFailed(f.graphKey,o)}),await p(c,"Result graph error recording failed",()=>{g(a,S(),o,Date.now(),{classification:"infra"})})}}else{const{disposition:n,error:o}=O,s=L(o),m=X(T,o);n.status!=="cancelled"&&y.push(s),n.notifyRuntimeError&&await v(c,"Runtime error reporter failed",()=>d?.runtimeError?.(m,s)),n.status!=="cancelled"&&(n.runtimeImpact==="fail-graph"&&await p(c,"Runtime graph failure recording failed",()=>{i.markGraphFailed(f.graphKey,s)}),await p(c,"Result graph error recording failed",()=>{g(a,S(),s,Date.now(),{classification:n.classification??"product"})}));const N=Date.now();for(const D of T){const A=o instanceof b&&o.completedOutcomesByTaskId.has(String(D.id)),M=ee(D,E,o,n,s,N);await C({operationErrors:c,outcome:M,recordTaskOutcome:h,recordTiming:A,reporter:d,reportTaskFinished:!A,task:D,timingUpdates:u,trackers:a})}e.taskCount+=T.length}if(F!==null){const n=F.message;y.push(n),await v(c,"Runtime error reporter failed",()=>d?.runtimeError?.(f,n)),F.recovered||await p(c,"Runtime graph failure recording failed",()=>{i.markGraphFailed(f.graphKey,n)}),await p(c,"Result graph error recording failed",()=>{g(a,S(),n,Date.now(),{classification:"infra"})})}if(c.length>0){const n=[...c];for(const s of n)y.push(s.message);const o=n.map(s=>s.message).join("; ");await p(c,"Result graph error recording failed while reporting a Testkit operation failure",()=>{g(a,S(),o,Date.now(),{classification:"infra"})});for(const s of c.slice(n.length))y.push(s.message);c.length>n.length&&x.push(...n.map(s=>s.message),...c.slice(n.length).map(s=>s.message))}}}finally{e.currentGraphKey=null}return{workerId:e.workerId,failed:y.length>0,durationMs:Date.now()-k,taskCount:e.taskCount,graphSwitches:e.graphSwitches,errors:y,unpersistedErrors:x}}async function C({operationErrors:e,outcome:t,recordTaskOutcome:i,recordTiming:r,reporter:a,reportTaskFinished:u,task:l,timingUpdates:h,trackers:g}){await p(e,`Task outcome recording failed for ${l.file}`,()=>{i(g,l,t)}),u&&await v(e,`Task-finished reporter failed for ${l.file}`,()=>a?.taskFinished?.(l,t)),r&&await p(e,`Task timing recording failed for ${l.file}`,()=>{const d=J(l,t);d&&h.push(d)})}async function p(e,t,i){try{await i()}catch(r){e.push(_(t,r))}}async function v(e,t,i){await p(e,t,()=>j(t,i,{timeoutMs:P}))}function _(e,t){const i=G(t);return new Error(`${e}: ${i.message}`,{cause:i})}function X(e,t){const i=e[0];if(!(t instanceof b))return i;if(t.failingTaskId!==null){const r=e.find(a=>String(a.id)===t.failingTaskId);if(r!==void 0)return r}return e.find(r=>!t.completedOutcomesByTaskId.has(String(r.id)))??i}function Y(e,t){return{key:e?.graphKey??t.graphKey,targetNames:e?.targetNames??[t.targetName]}}async function Z(e,t,i){if(t===null)return null;try{return await e.release(t.leaseId,{invalidate:i}),null}catch(r){const a=G(r);try{return await e.release(t.leaseId,{invalidate:!0}),{message:`Runtime lease release failed but recovered on idempotent retry: ${a.message}`,recovered:!0}}catch(u){const l=G(u);return{message:`Runtime lease release failed: ${a.message}; idempotent retry also failed: ${l.message}`,recovered:!1}}}}function ee(e,t,i,r,a,u){const l=q(i),h={kind:"engine-invocation",key:"engine_invocation_failed",title:"Engine invocation failed",count:1,...r.classification===void 0?{}:{classification:r.classification},message:a,...l===void 0?{}:{stack:l}},g=i instanceof b?i.completedOutcomesByTaskId.get(String(e.id)):void 0;if(g!==void 0)return g;const d=i instanceof b?i.artifactReferencesByTaskId.get(String(e.id))??[]:[];return{task:e,status:r.status,error:r.status==="failed"?a:null,reason:r.status==="failed"?null:a,infraFailed:r.classification==="infra",blockedByRuntime:r.status==="not_run",durationMs:0,startedAt:u,finishedAt:u,artifacts:[...d],failureDetails:r.status==="cancelled"?[]:[h],checkDetails:[],..."batchTasks"in t?{runtimeBatch:{id:t.batchId,index:t.batchTasks.findIndex(k=>k.id===e.id&&k.file===e.file),fileCount:t.batchTasks.length,files:t.batchTasks.map(k=>k.file)}}:{}}}function te(e){return e instanceof b?e.disposition:{classification:"infra",notifyRuntimeError:!0,runtimeImpact:"none",status:"not_run"}}function ie(e,t){return t.signal.aborted&&e===t.signal.reason?{classification:void 0,notifyRuntimeError:!1,runtimeImpact:"none",status:"cancelled"}:{classification:"infra",notifyRuntimeError:!0,runtimeImpact:"fail-graph",status:"not_run"}}export function resolveWorkerOutcomeMappings(e,t){const i=new Map;for(const a of e){const u=$(a);if(i.has(u))throw new Error(`Worker claimed duplicate task ${a.id.toString()} (${a.file})`);i.set(u,a)}const r=new Map;for(const a of t){const u=$(a.task),l=i.get(u);if(!l)throw new Error(`Task runner returned an outcome for unclaimed task ${a.task.id.toString()} (${a.task.file})`);if(r.has(u))throw new Error(`Task runner returned duplicate outcomes for claimed task ${l.id.toString()} (${l.file})`);r.set(u,{outcome:a,task:l})}for(const a of e)if(!r.has($(a)))throw new Error(`Task runner did not return an outcome for claimed task ${a.id.toString()} (${a.file})`);return[...r.values()]}function $(e){return JSON.stringify([typeof e.id,e.id,e.file])}function ne(e,t,i){return e.getGraph(i.graphKey)??{key:t?.graphKey??i.graphKey,targetNames:t?.targetNames??[i.targetName]}}function ae(e){return new Promise(t=>setTimeout(t,e))}function G(e){return e instanceof Error?e:new Error(String(e))}
@@ -1 +1 @@
1
- import{resolveProductDir as c}from"../../config/loader/index.js";import u from"node:os";import{runManagedProcess as m}from"../../process/index.js";import{currentLinuxLibc as s,currentPlatformTarget as n}from"../../process/host/platform.js";import{RootPackageResolver as d}from"../../engines/installations/package-resolution.js";import{playwrightRegistryEnvironment as g,requireSupportedPlaywrightHost as f,resolvePlaywrightInstallation as h,resolvePlaywrightPackageFamily as p,resolvePlaywrightRegistry as w,throwIfPlaywrightProcessAborted as P}from"../../engines/installations/playwright.js";export const PLAYWRIGHT_SETUP_TIMEOUT_MS=1200*1e3;export class PlaywrightSetupError extends Error{code="TESTKIT_PLAYWRIGHT_SETUP_FAILED";constructor(e,t){super(`Playwright setup failed: ${e}`,t),this.name="PlaywrightSetupError"}}export function playwrightSetupArguments(r,e){return Object.freeze([r,"install","chromium","--no-shell",...e.withDeps?["--with-deps"]:[],...e.force?["--force"]:[]])}export async function executePlaywrightSetup(r){r.signal.throwIfAborted(),f({linuxLibc:s(),target:n()});const e=Object.freeze({...r.ambientEnvironment??process.env}),t=r.configuredRegistry??e.PLAYWRIGHT_BROWSERS_PATH,a=p(new d),l=w({ambientEnvironment:e,configuredValue:t,homeDirectory:u.homedir(),platform:n().platform,productRoot:r.productRoot}),o=await m({args:playwrightSetupArguments(a.cli,r),cwd:r.productRoot,displayLabel:"Playwright Chromium setup",env:g(e,l),executable:process.execPath,signal:r.signal,timeoutMs:PLAYWRIGHT_SETUP_TIMEOUT_MS}),i=y(o);if(P(r.signal,o,i),i!==null)throw new PlaywrightSetupError(i.message,{cause:i});return h({productRoot:r.productRoot,signal:r.signal},{ambientEnvironment:e,configuredRegistry:t})}function y(r){if(r.terminationError!==null)return r.terminationError;if(r.error!==null)return r.error;if(r.timedOut)return new Error(`Chromium installer exceeded ${PLAYWRIGHT_SETUP_TIMEOUT_MS.toString()} milliseconds`);if(r.cancelled)return new Error("Chromium installer was cancelled");if(r.outputLimitExceeded)return new Error("Chromium installer exceeded the managed output limit");if(r.exitCode!==0){const e=r.stderr.trim();return new Error(`Chromium installer ${r.exitCode===null?`terminated by ${String(r.exitSignal)}`:`exited with code ${r.exitCode.toString()}`}${e.length===0?"":`: ${e}`}`)}return null}export function setupPlaywright(r){return executePlaywrightSetup({...r,productRoot:c(process.cwd(),r.dir)})}
1
+ import{resolveProductDir as c}from"../../config/loader/paths.js";import u from"node:os";import{runManagedProcess as m}from"../../process/index.js";import{currentLinuxLibc as s,currentPlatformTarget as n}from"../../process/host/platform.js";import{RootPackageResolver as d}from"../../engines/installations/package-resolution.js";import{playwrightRegistryEnvironment as g,requireSupportedPlaywrightHost as f,resolvePlaywrightInstallation as h,resolvePlaywrightPackageFamily as p,resolvePlaywrightRegistry as w,throwIfPlaywrightProcessAborted as P}from"../../engines/installations/playwright.js";export const PLAYWRIGHT_SETUP_TIMEOUT_MS=1200*1e3;export class PlaywrightSetupError extends Error{code="TESTKIT_PLAYWRIGHT_SETUP_FAILED";constructor(e,t){super(`Playwright setup failed: ${e}`,t),this.name="PlaywrightSetupError"}}export function playwrightSetupArguments(r,e){return Object.freeze([r,"install","chromium","--no-shell",...e.withDeps?["--with-deps"]:[],...e.force?["--force"]:[]])}export async function executePlaywrightSetup(r){r.signal.throwIfAborted(),f({linuxLibc:s(),target:n()});const e=Object.freeze({...r.ambientEnvironment??process.env}),t=r.configuredRegistry??e.PLAYWRIGHT_BROWSERS_PATH,a=p(new d),l=w({ambientEnvironment:e,configuredValue:t,homeDirectory:u.homedir(),platform:n().platform,productRoot:r.productRoot}),o=await m({args:playwrightSetupArguments(a.cli,r),cwd:r.productRoot,displayLabel:"Playwright Chromium setup",env:g(e,l),executable:process.execPath,signal:r.signal,timeoutMs:PLAYWRIGHT_SETUP_TIMEOUT_MS}),i=y(o);if(P(r.signal,o,i),i!==null)throw new PlaywrightSetupError(i.message,{cause:i});return h({productRoot:r.productRoot,signal:r.signal},{ambientEnvironment:e,configuredRegistry:t})}function y(r){if(r.terminationError!==null)return r.terminationError;if(r.error!==null)return r.error;if(r.timedOut)return new Error(`Chromium installer exceeded ${PLAYWRIGHT_SETUP_TIMEOUT_MS.toString()} milliseconds`);if(r.cancelled)return new Error("Chromium installer was cancelled");if(r.outputLimitExceeded)return new Error("Chromium installer exceeded the managed output limit");if(r.exitCode!==0){const e=r.stderr.trim();return new Error(`Chromium installer ${r.exitCode===null?`terminated by ${String(r.exitSignal)}`:`exited with code ${r.exitCode.toString()}`}${e.length===0?"":`: ${e}`}`)}return null}export function setupPlaywright(r){return executePlaywrightSetup({...r,productRoot:c(process.cwd(),r.dir)})}
@@ -1,4 +1,4 @@
1
- import{attachErrorDiagnostics as w}from"../../kernel/error-serialization.js";import{isPathWithin as E}from"../../process/files/paths.js";import d from"fs";import r from"path";import{createHash as S}from"crypto";import{createRequire as j}from"module";import{fileURLToPath as _}from"url";import m from"typescript";import{NODE_VITEST_PACKAGE_REQUIREMENTS as O}from"../../engines/installations/node-vitest.js";import{PLAYWRIGHT_PACKAGE_FAMILY_REQUIREMENTS as C}from"../../engines/installations/playwright.js";import{detectNextApp as A,discoverTests as $,loadConfigContext as R,resolveServiceCwd as M}from"../../config/loader/index.js";import{K6_POSTGRES_DRIVER_SPECIFIER as I,K6_POSTGRES_DRIVER_TYPE_FILE as F,K6_RUNTIME_GLOBAL_TYPE_FILE as N}from"../../engines/k6/authoring-type-paths.js";import{managedHostProcessInfrastructureError as L,runManagedHostProcess as D}from"../../process/index.js";import{CONFIGURED_STEP_TESTKIT_MODULE_DIST_PATHS as G}from"../../steps/configured-step-testkit-modules.js";import{findPlaywrightConfigFile as U}from"../../engines/playwright/runtime/config-file.js";const K=600*1e3,y=r.resolve(r.dirname(_(import.meta.url)),"..","..",".."),b=j(r.join(y,"package.json")),z={...J(["@gfdelarue/testkit","@gfdelarue/testkit/config","@gfdelarue/testkit/config/build-assets","@gfdelarue/testkit/config/next-runtime-tsconfig","@gfdelarue/testkit/config/database-steps","@gfdelarue/testkit/drizzle","@gfdelarue/testkit/env","@gfdelarue/testkit/tooling/vitest"]),"@gfdelarue/testkit/k6":["engines","k6","runtime","index.d.ts"],"@gfdelarue/testkit/playwright":["engines","playwright","runtime","index.d.ts"],"@gfdelarue/testkit/node-vitest/data":["engines","node-vitest","runtime","data","index.d.ts"],"@gfdelarue/testkit/node-vitest/contract":["engines","node-vitest","runtime","contract","index.d.ts"],"@gfdelarue/testkit/workspace":["app","inspect","index.d.ts"]};function J(e){return Object.fromEntries(e.map(n=>{const t=G[n],s=t[t.length-1];return[n,[...t.slice(0,-1),`${s}.d.ts`]]}))}export class TestkitTypecheckError extends Error{result;results;constructor(n,t,s){super(`testkit typecheck failed for ${n}`),this.result=t,this.results=s,w(this,{result:t,results:s})}}export async function runTestkitTypecheck(e={}){const n=te(e.timeoutMs),t=await R({dir:e.dir}),s=t.productDir,o=r.join(s,".testkit","_typecheck");d.mkdirSync(o,{recursive:!0});const i=[];if(t.configFile){const p=q({productDir:s,configFile:t.configFile,outputDir:o});i.push({label:"config",cwd:s,tsconfigPath:p})}const a=await $({dir:s,diagnostics:"error"}),c=a.files.map(p=>({engineId:p.engineId,path:p.path})),u=new Set(a.files.filter(p=>p.engineId==="playwright").map(p=>p.service));for(const p of t.configs){if(!u.has(p.name))continue;const k=U(M(s,p.testkit.local?.cwd));k&&c.push({engineId:"playwright",path:k})}const g=H(s,c);for(const p of g){const k=B({...p,outputDir:o,productDir:s});i.push({label:Q(p.engineId,p.scopeName),cwd:p.cwd,tsconfigPath:k})}const f=[];for(const p of i){const k=await ee(p,n,e.signal);if(f.push(k),!k.ok)throw new TestkitTypecheckError(p.label,k,f)}return{ok:!0,productDir:s,results:f}}function q({productDir:e,configFile:n,outputDir:t}){const s=r.join(t,"config.tsconfig.json"),o=P(e),i={...o?{extends:l(s,o)}:{},compilerOptions:buildTypecheckCompilerOptions({tsconfigPath:s,extendsPath:o,libs:["ES2022"],rootDir:l(s,e),types:["node"]}),files:[l(s,n)],include:[],exclude:[h(s,e,"node_modules"),h(s,e,"dist"),h(s,e,".testkit")]};return d.writeFileSync(s,`${JSON.stringify(i,null,2)}
2
- `),s}function B({productDir:e,cwd:n,engineId:t,extendsPath:s,files:o,outputDir:i,scopeName:a}){const c=r.join(i,`${t}.${X(a)}.tsconfig.json`),u=t==="playwright",g=u&&A(n),f={...s?{extends:l(c,s)}:{},compilerOptions:{...buildTypecheckCompilerOptions({engineId:t,tsconfigPath:c,extendsPath:s,libs:V(t),...g?{extraPaths:nextRuntimeTypePaths({tsconfigPath:c,serviceDir:n})}:{},types:W(t)}),...u?{allowJs:!0,checkJs:!1}:{}},files:[...ce(t,c),...o.map(p=>l(c,p))],include:g?[...d.existsSync(r.join(n,"next-env.d.ts"))?[l(c,r.join(n,"next-env.d.ts"))]:[],h(c,n,"tests/playwright-fixtures/**/*.ts"),h(c,n,"tests/playwright-fixtures/**/*.tsx"),h(c,n,"tests/playwright-fixtures/**/*.mts"),h(c,n,".next/types/**/*.ts"),h(c,n,".next/dev/types/**/*.ts"),h(c,e,".next-testkit/**/dist/types/**/*.ts"),h(c,e,".next-testkit/**/dist/dev/types/**/*.ts")]:[],exclude:["node_modules",".next/cache",".next/dev"]};return d.writeFileSync(c,`${JSON.stringify(f,null,2)}
3
- `),c}function H(e,n){const t=new Map,s=new Map;for(const o of n){const i=r.resolve(e,o.path),a=[o.engineId,i].join("\0");s.set(a,{...o,path:i})}for(const o of s.values()){const i=o.path,a=o.engineId==="playwright"?v(r.dirname(i),e,["tsconfig.playwright.json"]):null,c=a??v(r.dirname(i),e),u=c?r.dirname(c):e,g=Z(e,u),f=`${o.engineId}\0${c??""}\0${g}`,p=t.get(f);if(p){p.files.push(i);continue}t.set(f,{cwd:u,engineId:o.engineId,extendsPath:c,files:[i,...a?Y(a):[]],scopeName:g})}return[...t.values()].map(o=>({...o,files:[...new Set(o.files)].sort((i,a)=>i.localeCompare(a))})).sort((o,i)=>T(o.engineId)-T(i.engineId)||o.scopeName.localeCompare(i.scopeName))}function Y(e){const n=s=>{throw new Error(`${e}: ${m.flattenDiagnosticMessageText(s.messageText,`
4
- `)}`)},t=m.getParsedCommandLineOfConfigFile(e,{},{...m.sys,onUnRecoverableConfigFileDiagnostic:n});for(const s of t?.errors??[])s.code!==18002&&s.code!==18003&&n(s);return t?.fileNames??[]}function W(e){switch(e){case"k6":return["k6","xk6-sql"];case"node-vitest":case"playwright":return["node"]}}function V(e){return e==="playwright"?["ES2022","DOM","DOM.Iterable"]:["ES2022"]}function T(e){return["k6","node-vitest","playwright"].indexOf(e)}function Q(e,n){return n==="repo"?e:`${e}:${n}`}function Z(e,n){const t=r.relative(e,n);return t===""?"repo":t.split(r.sep).join("/")}function X(e){const n=e.replace(/[^a-zA-Z0-9_-]+/g,"-");if(n===e)return e;const t=S("sha256").update(e).digest("hex").slice(0,12);return`${n}-${t}`}function ee({label:e,cwd:n,tsconfigPath:t},s,o){const i=ne(n);return D({args:[...i.args,"--noEmit","-p",t],cwd:n,displayLabel:`Testkit typecheck ${e}`,env:process.env,executable:i.command,signal:o,timeoutMs:s}).then(a=>{const c=L(`Testkit typecheck ${e}`,a);if(c)throw c;return{label:e,tsconfigPath:t,ok:a.exitCode===0,exitCode:a.exitCode,stdout:a.stdout,stderr:a.stderr}})}function te(e){const n=e??K;if(!Number.isSafeInteger(n)||n<=0)throw new Error("Testkit typecheck timeout must be a positive safe integer in milliseconds");return n}function ne(e){let n=e;for(;;){const s=r.join(n,"node_modules","typescript","bin","tsc");if(d.existsSync(s))return{command:process.execPath,args:[s]};const o=r.dirname(n);if(o===n)break;n=o}const t=r.join(y,"node_modules","typescript","bin","tsc");if(d.existsSync(t))return{command:process.execPath,args:[t]};throw new Error(`TypeScript compiler not found from ${e} upward`)}function P(e,n=["tsconfig.json","tsconfig.build.json"]){for(const t of n){const s=r.join(e,t);if(d.existsSync(s))return s}return null}function v(e,n,t){const s=r.resolve(n);let o=r.resolve(e);for(;;){if(!E(s,o))return null;const i=P(o,t);if(i)return i;if(o===s)return null;const a=r.dirname(o);if(a===o)return null;o=a}}function l(e,n){const t=r.relative(r.dirname(e),n).split(r.sep).join("/");return t.startsWith("../")||r.isAbsolute(t)?t:`./${t}`}function h(e,n,t){return r.join(l(e,n),t).split(r.sep).join("/")}function se(e){const n={};for(const[t,s]of Object.entries(z))n[t]=[l(e,r.join(y,"dist",...s))];return n}const oe=Object.freeze({packages:Object.freeze(O.filter(({authoringResolution:e})=>e==="package-exports").map(({packageName:e})=>Object.freeze({name:e}))),supportedExports:"exact-manifest-exports"}),re=Object.freeze({packages:Object.freeze(C.map(({packageName:e})=>Object.freeze({name:e}))),supportedExports:"exact-manifest-exports"});function ie(e,n){const t=pe(e);if(t===null)return{};const s={},o=l(n,r.join(y,"dist","app","typecheck","unavailable.d.ts"));for(const i of t.packages){const a=ue(i.name),c=de(i.name,a);s[`${i.name}/*`]=[o];for(const u of Object.keys(c).sort()){if(u!=="."&&!u.startsWith("./")||u.includes("*"))continue;const g=u==="."?i.name:`${i.name}${u.slice(1)}`,f=fe(g,i.name,a);s[g]=[f===null?o:l(n,f)]}}return s}function ce(e,n){return e==="k6"?[l(n,r.join(y,"dist",...N))]:[]}function ae(e,n){return e==="k6"?{[I]:[l(n,r.join(y,"dist",...F))]}:{}}function pe(e){switch(e){case"node-vitest":return oe;case"playwright":return re;case"k6":case void 0:return null}}function ue(e){const n=le(e);let t;try{t=b.resolve(`${e}/package.json`)}catch(i){throw new Error(`Testkit typecheck requires managed public package ${e}`,{cause:i})}const s=d.realpathSync.native(r.dirname(t)),o=JSON.parse(d.readFileSync(r.join(s,"package.json"),"utf8"));return requireManagedPublicPackageIdentity(o,e,n),s}export function requireManagedPublicPackageIdentity(e,n,t){if(!x(e)||e.name!==n||e.version!==t)throw new Error(`Testkit managed public package has invalid identity: expected ${n}@${t}`)}function le(e){const n=JSON.parse(d.readFileSync(r.join(y,"package.json"),"utf8"));if(!x(n)||!x(n.dependencies))throw new Error("Testkit package has invalid dependency metadata");const t=n.dependencies[e];if(typeof t!="string"||!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(t))throw new Error(`Testkit managed public package ${e} must be an exact root dependency`);return t}function x(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function de(e,n){const t=JSON.parse(d.readFileSync(r.join(n,"package.json"),"utf8"));if(typeof t!="object"||t===null||Array.isArray(t)||!("name"in t)||t.name!==e||!("exports"in t)||typeof t.exports!="object"||t.exports===null||Array.isArray(t.exports))throw new Error(`Testkit managed public package has invalid exports: ${e}`);return t.exports}function fe(e,n,t){const s=m.resolveModuleName(e,r.join(y,"__testkit_managed_public_types__.ts"),{module:m.ModuleKind.ESNext,moduleResolution:m.ModuleResolutionKind.Bundler,resolveJsonModule:!0,target:m.ScriptTarget.ES2022},m.sys).resolvedModule;if(s===void 0)return null;const o=d.realpathSync.native(s.resolvedFileName);if(!E(t,o))throw new Error(`Managed public package type ${e} resolved outside ${n}`);return o}export function buildTypecheckCompilerOptions({engineId:e,tsconfigPath:n,extendsPath:t,rootDir:s,extraPaths:o={},libs:i,types:a}){const u={...t?he({tsconfigPath:n,extendsPath:t}):{},...o,...se(n),...ie(e,n),...ae(e,n)};return{baseUrl:null,lib:[...i],module:"ESNext",moduleResolution:"Bundler",noEmit:!0,...s?{rootDir:s}:{},target:"ES2022",typeRoots:ge(a,n),types:[...a],paths:u}}function ge(e,n){const t=new Set;for(const s of e){if(s==="k6"||s==="xk6-sql"){const c=r.join(y,"dist","engines","k6","runtime","ambient-types");if(!d.existsSync(r.join(c,s,"index.d.ts")))throw new Error(`Testkit typecheck requires bundled ${s} authoring types; rebuild the installed Testkit package`);t.add(c);continue}const o=me(s);let i;try{i=b.resolve(`${o}/package.json`)}catch(c){throw new Error(`Testkit typecheck requires installed type package ${o}`,{cause:c})}const a=r.dirname(i);t.add(r.dirname(a))}return[...t].map(s=>l(n,s))}function me(e){return e==="node"||e==="k6"?`@types/${e}`:e}function he({tsconfigPath:e,extendsPath:n}){const t=m.getParsedCommandLineOfConfigFile(n,{},{...m.sys,onUnRecoverableConfigFileDiagnostic:()=>{}}),s=t?.options.paths;if(!s||Object.keys(s).length===0)return{};const o=t.options.baseUrl||(typeof t.options.pathsBasePath=="string"?t.options.pathsBasePath:r.dirname(n)),i={};for(const[a,c]of Object.entries(s))i[a]=c.map(u=>l(e,r.resolve(o,u)));return i}export function nextRuntimeTypePaths({tsconfigPath:e,serviceDir:n}){const t=ye(n,[r.join("next","types.d.ts"),r.join("next","types.js")]);if(!t)return{};const s=l(e,t);return{"next/types":[s],"next/types.js":[s]}}function ye(e,n){let t=r.resolve(e);for(;;){for(const o of n){const i=r.join(t,"node_modules",o);if(d.existsSync(i))return i}const s=r.dirname(t);if(s===t)return null;t=s}}
1
+ import{attachErrorDiagnostics as S}from"../../kernel/error-serialization.js";import{isPathWithin as E}from"../../process/files/paths.js";import d from"fs";import r from"path";import{createHash as w}from"crypto";import{createRequire as j}from"module";import{fileURLToPath as _}from"url";import m from"typescript";import{NODE_VITEST_PACKAGE_REQUIREMENTS as O}from"../../engines/installations/node-vitest.js";import{PLAYWRIGHT_PACKAGE_FAMILY_REQUIREMENTS as C}from"../../engines/installations/playwright.js";import{detectNextApp as A,loadDiscoveredConfigContext as $,resolveServiceCwd as R}from"../../config/loader/index.js";import{K6_POSTGRES_DRIVER_SPECIFIER as M,K6_POSTGRES_DRIVER_TYPE_FILE as I,K6_RUNTIME_GLOBAL_TYPE_FILE as F}from"../../engines/k6/authoring-type-paths.js";import{managedHostProcessInfrastructureError as N,runManagedHostProcess as D}from"../../process/index.js";import{CONFIGURED_STEP_TESTKIT_MODULE_DIST_PATHS as L}from"../../steps/configured-step-testkit-modules.js";import{findPlaywrightConfigFile as G}from"../../engines/playwright/runtime/config-file.js";const U=600*1e3,y=r.resolve(r.dirname(_(import.meta.url)),"..","..",".."),b=j(r.join(y,"package.json")),K={...z(["@gfdelarue/testkit","@gfdelarue/testkit/config","@gfdelarue/testkit/config/build-assets","@gfdelarue/testkit/config/next-runtime-tsconfig","@gfdelarue/testkit/config/database-steps","@gfdelarue/testkit/drizzle","@gfdelarue/testkit/env","@gfdelarue/testkit/tooling/vitest"]),"@gfdelarue/testkit/k6":["engines","k6","runtime","index.d.ts"],"@gfdelarue/testkit/playwright":["engines","playwright","runtime","index.d.ts"],"@gfdelarue/testkit/node-vitest/data":["engines","node-vitest","runtime","data","index.d.ts"],"@gfdelarue/testkit/node-vitest/contract":["engines","node-vitest","runtime","contract","index.d.ts"],"@gfdelarue/testkit/workspace":["app","inspect","index.d.ts"]};function z(e){return Object.fromEntries(e.map(n=>{const t=L[n],s=t[t.length-1];return[n,[...t.slice(0,-1),`${s}.d.ts`]]}))}export class TestkitTypecheckError extends Error{result;results;constructor(n,t,s){super(`testkit typecheck failed for ${n}`),this.result=t,this.results=s,S(this,{result:t,results:s})}}export async function runTestkitTypecheck(e={}){const n=ee(e.timeoutMs),{context:t,discovery:s}=await $({dir:e.dir}),o=t.productDir,i=r.join(o,".testkit","_typecheck");d.mkdirSync(i,{recursive:!0});const a=[];if(t.configFile){const p=J({productDir:o,configFile:t.configFile,outputDir:i});a.push({label:"config",cwd:o,tsconfigPath:p})}const c=s.files.map(p=>({engineId:p.engineId,path:p.path})),u=new Set(s.files.filter(p=>p.engineId==="playwright").map(p=>p.service));for(const p of t.configs){if(!u.has(p.name))continue;const k=G(R(o,p.testkit.local?.cwd));k&&c.push({engineId:"playwright",path:k})}const g=B(o,c);for(const p of g){const k=q({...p,outputDir:i,productDir:o});a.push({label:V(p.engineId,p.scopeName),cwd:p.cwd,tsconfigPath:k})}const f=[];for(const p of a){const k=await X(p,n,e.signal);if(f.push(k),!k.ok)throw new TestkitTypecheckError(p.label,k,f)}return{ok:!0,productDir:o,results:f}}function J({productDir:e,configFile:n,outputDir:t}){const s=r.join(t,"config.tsconfig.json"),o=P(e),i={...o?{extends:l(s,o)}:{},compilerOptions:buildTypecheckCompilerOptions({tsconfigPath:s,extendsPath:o,libs:["ES2022"],rootDir:l(s,e),types:["node"]}),files:[l(s,n)],include:[],exclude:[h(s,e,"node_modules"),h(s,e,"dist"),h(s,e,".testkit")]};return d.writeFileSync(s,`${JSON.stringify(i,null,2)}
2
+ `),s}function q({productDir:e,cwd:n,engineId:t,extendsPath:s,files:o,outputDir:i,scopeName:a}){const c=r.join(i,`${t}.${Z(a)}.tsconfig.json`),u=t==="playwright",g=u&&A(n),f={...s?{extends:l(c,s)}:{},compilerOptions:{...buildTypecheckCompilerOptions({engineId:t,tsconfigPath:c,extendsPath:s,libs:W(t),...g?{extraPaths:nextRuntimeTypePaths({tsconfigPath:c,serviceDir:n})}:{},types:Y(t)}),...u?{allowJs:!0,checkJs:!1}:{}},files:[...ie(t,c),...o.map(p=>l(c,p))],include:g?[...d.existsSync(r.join(n,"next-env.d.ts"))?[l(c,r.join(n,"next-env.d.ts"))]:[],h(c,n,"tests/playwright-fixtures/**/*.ts"),h(c,n,"tests/playwright-fixtures/**/*.tsx"),h(c,n,"tests/playwright-fixtures/**/*.mts"),h(c,n,".next/types/**/*.ts"),h(c,n,".next/dev/types/**/*.ts"),h(c,e,".next-testkit/**/dist/types/**/*.ts"),h(c,e,".next-testkit/**/dist/dev/types/**/*.ts")]:[],exclude:["node_modules",".next/cache",".next/dev"]};return d.writeFileSync(c,`${JSON.stringify(f,null,2)}
3
+ `),c}function B(e,n){const t=new Map,s=new Map;for(const o of n){const i=r.resolve(e,o.path),a=[o.engineId,i].join("\0");s.set(a,{...o,path:i})}for(const o of s.values()){const i=o.path,a=o.engineId==="playwright"?v(r.dirname(i),e,["tsconfig.playwright.json"]):null,c=a??v(r.dirname(i),e),u=c?r.dirname(c):e,g=Q(e,u),f=`${o.engineId}\0${c??""}\0${g}`,p=t.get(f);if(p){p.files.push(i);continue}t.set(f,{cwd:u,engineId:o.engineId,extendsPath:c,files:[i,...a?H(a):[]],scopeName:g})}return[...t.values()].map(o=>({...o,files:[...new Set(o.files)].sort((i,a)=>i.localeCompare(a))})).sort((o,i)=>T(o.engineId)-T(i.engineId)||o.scopeName.localeCompare(i.scopeName))}function H(e){const n=s=>{throw new Error(`${e}: ${m.flattenDiagnosticMessageText(s.messageText,`
4
+ `)}`)},t=m.getParsedCommandLineOfConfigFile(e,{},{...m.sys,onUnRecoverableConfigFileDiagnostic:n});for(const s of t?.errors??[])s.code!==18002&&s.code!==18003&&n(s);return t?.fileNames??[]}function Y(e){switch(e){case"k6":return["k6","xk6-sql"];case"node-vitest":case"playwright":return["node"]}}function W(e){return e==="playwright"?["ES2022","DOM","DOM.Iterable"]:["ES2022"]}function T(e){return["k6","node-vitest","playwright"].indexOf(e)}function V(e,n){return n==="repo"?e:`${e}:${n}`}function Q(e,n){const t=r.relative(e,n);return t===""?"repo":t.split(r.sep).join("/")}function Z(e){const n=e.replace(/[^a-zA-Z0-9_-]+/g,"-");if(n===e)return e;const t=w("sha256").update(e).digest("hex").slice(0,12);return`${n}-${t}`}function X({label:e,cwd:n,tsconfigPath:t},s,o){const i=te(n);return D({args:[...i.args,"--noEmit","-p",t],cwd:n,displayLabel:`Testkit typecheck ${e}`,env:process.env,executable:i.command,signal:o,timeoutMs:s}).then(a=>{const c=N(`Testkit typecheck ${e}`,a);if(c)throw c;return{label:e,tsconfigPath:t,ok:a.exitCode===0,exitCode:a.exitCode,stdout:a.stdout,stderr:a.stderr}})}function ee(e){const n=e??U;if(!Number.isSafeInteger(n)||n<=0)throw new Error("Testkit typecheck timeout must be a positive safe integer in milliseconds");return n}function te(e){let n=e;for(;;){const s=r.join(n,"node_modules","typescript","bin","tsc");if(d.existsSync(s))return{command:process.execPath,args:[s]};const o=r.dirname(n);if(o===n)break;n=o}const t=r.join(y,"node_modules","typescript","bin","tsc");if(d.existsSync(t))return{command:process.execPath,args:[t]};throw new Error(`TypeScript compiler not found from ${e} upward`)}function P(e,n=["tsconfig.json","tsconfig.build.json"]){for(const t of n){const s=r.join(e,t);if(d.existsSync(s))return s}return null}function v(e,n,t){const s=r.resolve(n);let o=r.resolve(e);for(;;){if(!E(s,o))return null;const i=P(o,t);if(i)return i;if(o===s)return null;const a=r.dirname(o);if(a===o)return null;o=a}}function l(e,n){const t=r.relative(r.dirname(e),n).split(r.sep).join("/");return t.startsWith("../")||r.isAbsolute(t)?t:`./${t}`}function h(e,n,t){return r.join(l(e,n),t).split(r.sep).join("/")}function ne(e){const n={};for(const[t,s]of Object.entries(K))n[t]=[l(e,r.join(y,"dist",...s))];return n}const se=Object.freeze({packages:Object.freeze(O.filter(({authoringResolution:e})=>e==="package-exports").map(({packageName:e})=>Object.freeze({name:e}))),supportedExports:"exact-manifest-exports"}),oe=Object.freeze({packages:Object.freeze(C.map(({packageName:e})=>Object.freeze({name:e}))),supportedExports:"exact-manifest-exports"});function re(e,n){const t=ae(e);if(t===null)return{};const s={},o=l(n,r.join(y,"dist","app","typecheck","unavailable.d.ts"));for(const i of t.packages){const a=pe(i.name),c=le(i.name,a);s[`${i.name}/*`]=[o];for(const u of Object.keys(c).sort()){if(u!=="."&&!u.startsWith("./")||u.includes("*"))continue;const g=u==="."?i.name:`${i.name}${u.slice(1)}`,f=de(g,i.name,a);s[g]=[f===null?o:l(n,f)]}}return s}function ie(e,n){return e==="k6"?[l(n,r.join(y,"dist",...F))]:[]}function ce(e,n){return e==="k6"?{[M]:[l(n,r.join(y,"dist",...I))]}:{}}function ae(e){switch(e){case"node-vitest":return se;case"playwright":return oe;case"k6":case void 0:return null}}function pe(e){const n=ue(e);let t;try{t=b.resolve(`${e}/package.json`)}catch(i){throw new Error(`Testkit typecheck requires managed public package ${e}`,{cause:i})}const s=d.realpathSync.native(r.dirname(t)),o=JSON.parse(d.readFileSync(r.join(s,"package.json"),"utf8"));return requireManagedPublicPackageIdentity(o,e,n),s}export function requireManagedPublicPackageIdentity(e,n,t){if(!x(e)||e.name!==n||e.version!==t)throw new Error(`Testkit managed public package has invalid identity: expected ${n}@${t}`)}function ue(e){const n=JSON.parse(d.readFileSync(r.join(y,"package.json"),"utf8"));if(!x(n)||!x(n.dependencies))throw new Error("Testkit package has invalid dependency metadata");const t=n.dependencies[e];if(typeof t!="string"||!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(t))throw new Error(`Testkit managed public package ${e} must be an exact root dependency`);return t}function x(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function le(e,n){const t=JSON.parse(d.readFileSync(r.join(n,"package.json"),"utf8"));if(typeof t!="object"||t===null||Array.isArray(t)||!("name"in t)||t.name!==e||!("exports"in t)||typeof t.exports!="object"||t.exports===null||Array.isArray(t.exports))throw new Error(`Testkit managed public package has invalid exports: ${e}`);return t.exports}function de(e,n,t){const s=m.resolveModuleName(e,r.join(y,"__testkit_managed_public_types__.ts"),{module:m.ModuleKind.ESNext,moduleResolution:m.ModuleResolutionKind.Bundler,resolveJsonModule:!0,target:m.ScriptTarget.ES2022},m.sys).resolvedModule;if(s===void 0)return null;const o=d.realpathSync.native(s.resolvedFileName);if(!E(t,o))throw new Error(`Managed public package type ${e} resolved outside ${n}`);return o}export function buildTypecheckCompilerOptions({engineId:e,tsconfigPath:n,extendsPath:t,rootDir:s,extraPaths:o={},libs:i,types:a}){const u={...t?me({tsconfigPath:n,extendsPath:t}):{},...o,...ne(n),...re(e,n),...ce(e,n)};return{baseUrl:null,lib:[...i],module:"ESNext",moduleResolution:"Bundler",noEmit:!0,...s?{rootDir:s}:{},target:"ES2022",typeRoots:fe(a,n),types:[...a],paths:u}}function fe(e,n){const t=new Set;for(const s of e){if(s==="k6"||s==="xk6-sql"){const c=r.join(y,"dist","engines","k6","runtime","ambient-types");if(!d.existsSync(r.join(c,s,"index.d.ts")))throw new Error(`Testkit typecheck requires bundled ${s} authoring types; rebuild the installed Testkit package`);t.add(c);continue}const o=ge(s);let i;try{i=b.resolve(`${o}/package.json`)}catch(c){throw new Error(`Testkit typecheck requires installed type package ${o}`,{cause:c})}const a=r.dirname(i);t.add(r.dirname(a))}return[...t].map(s=>l(n,s))}function ge(e){return e==="node"||e==="k6"?`@types/${e}`:e}function me({tsconfigPath:e,extendsPath:n}){const t=m.getParsedCommandLineOfConfigFile(n,{},{...m.sys,onUnRecoverableConfigFileDiagnostic:()=>{}}),s=t?.options.paths;if(!s||Object.keys(s).length===0)return{};const o=t.options.baseUrl||(typeof t.options.pathsBasePath=="string"?t.options.pathsBasePath:r.dirname(n)),i={};for(const[a,c]of Object.entries(s))i[a]=c.map(u=>l(e,r.resolve(o,u)));return i}export function nextRuntimeTypePaths({tsconfigPath:e,serviceDir:n}){const t=he(n,[r.join("next","types.d.ts"),r.join("next","types.js")]);if(!t)return{};const s=l(e,t);return{"next/types":[s],"next/types.js":[s]}}function he(e,n){let t=r.resolve(e);for(;;){for(const o of n){const i=r.join(t,"node_modules",o);if(d.existsSync(i))return i}const s=r.dirname(t);if(s===t)return null;t=s}}
@@ -1,22 +1,22 @@
1
1
  import { type CommandContext as FrameworkCommandContext } from "./framework/command.js";
2
2
  export declare const commandCatalog: Readonly<{
3
3
  artifacts: import("./framework/command.js").CommandDefinition<{
4
+ readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
5
+ readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
4
6
  readonly kind: import("./framework/definitions.js").FlagDefinition<string | undefined>;
5
- readonly format: import("./framework/definitions.js").FlagDefinition<"text" | "list">;
7
+ readonly format: import("./framework/definitions.js").FlagDefinition<"list" | "text">;
6
8
  readonly run: import("./framework/definitions.js").FlagDefinition<string | undefined>;
7
9
  readonly list: import("./framework/definitions.js").FlagDefinition<boolean>;
8
10
  readonly verify: import("./framework/definitions.js").FlagDefinition<boolean>;
9
- readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
10
- readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
11
11
  }, {
12
12
  readonly file: import("./framework/definitions.js").ArgumentDefinition<string | undefined>;
13
13
  }>;
14
14
  cleanup: import("./framework/command.js").CommandDefinition<{
15
- readonly "dry-run": import("./framework/definitions.js").FlagDefinition<boolean>;
16
- readonly cache: import("./framework/definitions.js").FlagDefinition<("runtime" | "all" | "bundles")[] | undefined>;
17
- readonly resources: import("./framework/definitions.js").FlagDefinition<boolean>;
18
15
  readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
19
16
  readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
17
+ readonly "dry-run": import("./framework/definitions.js").FlagDefinition<boolean>;
18
+ readonly cache: import("./framework/definitions.js").FlagDefinition<("all" | "bundles" | "runtime")[] | undefined>;
19
+ readonly resources: import("./framework/definitions.js").FlagDefinition<boolean>;
20
20
  }, undefined>;
21
21
  "cloud campaign create": import("./framework/command.js").CommandDefinition<{
22
22
  readonly url: import("./framework/definitions.js").FlagDefinition<string | undefined>;
@@ -59,7 +59,7 @@ export declare const commandCatalog: Readonly<{
59
59
  readonly "root-cause-key": import("./framework/definitions.js").FlagDefinition<string | undefined>;
60
60
  readonly "issue-reference": import("./framework/definitions.js").FlagDefinition<string | undefined>;
61
61
  readonly view: import("./framework/definitions.js").FlagDefinition<"all" | "counted" | "secondary" | undefined>;
62
- readonly order: import("./framework/definitions.js").FlagDefinition<"verified" | "created" | undefined>;
62
+ readonly order: import("./framework/definitions.js").FlagDefinition<"created" | "verified" | undefined>;
63
63
  }, {
64
64
  readonly resource: import("./framework/definitions.js").ArgumentDefinition<string>;
65
65
  }>;
@@ -69,7 +69,7 @@ export declare const commandCatalog: Readonly<{
69
69
  readonly project: import("./framework/definitions.js").FlagDefinition<string | undefined>;
70
70
  readonly campaign: import("./framework/definitions.js").FlagDefinition<string | undefined>;
71
71
  }, {
72
- readonly resource: import("./framework/definitions.js").ArgumentDefinition<"run" | "performance" | "connection" | "project" | "policy" | "campaign" | "finding" | "case" | "receipt" | "account" | "organisation" | "test-file" | "project-policy">;
72
+ readonly resource: import("./framework/definitions.js").ArgumentDefinition<"account" | "campaign" | "case" | "connection" | "finding" | "organisation" | "performance" | "policy" | "project" | "project-policy" | "receipt" | "run" | "test-file">;
73
73
  readonly id: import("./framework/definitions.js").ArgumentDefinition<string | undefined>;
74
74
  }>;
75
75
  "cloud project create": import("./framework/command.js").CommandDefinition<{
@@ -77,7 +77,7 @@ export declare const commandCatalog: Readonly<{
77
77
  readonly org: import("./framework/definitions.js").FlagDefinition<string | undefined>;
78
78
  readonly name: import("./framework/definitions.js").FlagDefinition<string | undefined>;
79
79
  readonly repository: import("./framework/definitions.js").FlagDefinition<string | undefined>;
80
- readonly provider: import("./framework/definitions.js").FlagDefinition<"github" | "gitea" | undefined>;
80
+ readonly provider: import("./framework/definitions.js").FlagDefinition<"gitea" | "github" | undefined>;
81
81
  readonly host: import("./framework/definitions.js").FlagDefinition<string | undefined>;
82
82
  readonly "publish-decisions": import("./framework/definitions.js").FlagDefinition<boolean>;
83
83
  readonly "request-key": import("./framework/definitions.js").FlagDefinition<string | undefined>;
@@ -150,24 +150,24 @@ export declare const commandCatalog: Readonly<{
150
150
  service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
151
151
  }, undefined>;
152
152
  "db schema verify": import("./framework/command.js").CommandDefinition<{
153
- readonly "skip-schema-source-verify": import("./framework/definitions.js").FlagDefinition<boolean>;
154
153
  readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
155
154
  readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
155
+ readonly "skip-schema-source-verify": import("./framework/definitions.js").FlagDefinition<boolean>;
156
156
  }, undefined>;
157
157
  destroy: import("./framework/command.js").CommandDefinition<{
158
158
  dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
159
159
  service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
160
160
  }, undefined>;
161
161
  discover: import("./framework/command.js").CommandDefinition<{
162
+ readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
163
+ readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
162
164
  readonly type: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
163
165
  readonly suite: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
164
166
  readonly file: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
165
167
  readonly "runnable-only": import("./framework/definitions.js").FlagDefinition<boolean>;
166
168
  readonly strict: import("./framework/definitions.js").FlagDefinition<boolean>;
167
169
  readonly output: import("./framework/definitions.js").FlagDefinition<string | undefined>;
168
- readonly "output-mode": import("./framework/definitions.js").FlagDefinition<"verbose" | "compact">;
169
- readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
170
- readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
170
+ readonly "output-mode": import("./framework/definitions.js").FlagDefinition<"compact" | "verbose">;
171
171
  }, undefined>;
172
172
  doctor: import("./framework/command.js").CommandDefinition<{
173
173
  readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
@@ -181,19 +181,21 @@ export declare const commandCatalog: Readonly<{
181
181
  readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
182
182
  }, undefined>;
183
183
  "run status": import("./framework/command.js").CommandDefinition<{
184
- readonly run: import("./framework/definitions.js").FlagDefinition<string | undefined>;
185
- readonly full: import("./framework/definitions.js").FlagDefinition<boolean | undefined>;
186
184
  readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
187
185
  readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
186
+ readonly run: import("./framework/definitions.js").FlagDefinition<string | undefined>;
187
+ readonly full: import("./framework/definitions.js").FlagDefinition<boolean | undefined>;
188
188
  }, undefined>;
189
189
  "run stop": import("./framework/command.js").CommandDefinition<{
190
+ readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
191
+ readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
190
192
  readonly run: import("./framework/definitions.js").FlagDefinition<string | undefined>;
191
193
  readonly all: import("./framework/definitions.js").FlagDefinition<boolean>;
192
194
  readonly reason: import("./framework/definitions.js").FlagDefinition<string | undefined>;
193
- readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
194
- readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
195
195
  }, undefined>;
196
196
  run: import("./framework/command.js").CommandDefinition<{
197
+ dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
198
+ service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
197
199
  type: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
198
200
  suite: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
199
201
  file: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
@@ -203,12 +205,10 @@ export declare const commandCatalog: Readonly<{
203
205
  "allow-empty": import("./framework/definitions.js").FlagDefinition<boolean>;
204
206
  "ignore-skip-rules": import("./framework/definitions.js").FlagDefinition<boolean>;
205
207
  "skip-schema-source-verify": import("./framework/definitions.js").FlagDefinition<boolean>;
206
- "output-mode": import("./framework/definitions.js").FlagDefinition<"debug" | "events" | "compact" | undefined>;
208
+ "output-mode": import("./framework/definitions.js").FlagDefinition<"compact" | "debug" | "events" | undefined>;
207
209
  debug: import("./framework/definitions.js").FlagDefinition<boolean>;
208
- dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
209
- service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
210
210
  }, {
211
- readonly type: import("./framework/definitions.js").ArgumentDefinition<"contract" | "data" | "ui" | "e2e" | "int" | "dal" | "load" | "all" | undefined>;
211
+ readonly type: import("./framework/definitions.js").ArgumentDefinition<"all" | "contract" | "dal" | "data" | "e2e" | "int" | "load" | "ui" | undefined>;
212
212
  }>;
213
213
  "setup playwright": import("./framework/command.js").CommandDefinition<{
214
214
  readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
@@ -220,18 +220,18 @@ export declare const commandCatalog: Readonly<{
220
220
  service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
221
221
  }, undefined>;
222
222
  stop: import("./framework/command.js").CommandDefinition<{
223
- readonly reason: import("./framework/definitions.js").FlagDefinition<string | undefined>;
224
223
  readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
225
224
  readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
225
+ readonly reason: import("./framework/definitions.js").FlagDefinition<string | undefined>;
226
226
  }, undefined>;
227
227
  typecheck: import("./framework/command.js").CommandDefinition<{
228
228
  readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
229
229
  }, undefined>;
230
230
  workspace: import("./framework/command.js").CommandDefinition<{
231
- readonly "target-limit": import("./framework/definitions.js").FlagDefinition<number>;
232
- readonly "no-status": import("./framework/definitions.js").FlagDefinition<boolean>;
233
231
  readonly dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
234
232
  readonly service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
233
+ readonly "target-limit": import("./framework/definitions.js").FlagDefinition<number>;
234
+ readonly "no-status": import("./framework/definitions.js").FlagDefinition<boolean>;
235
235
  }, undefined>;
236
236
  }>;
237
237
  export type CommandId = keyof typeof commandCatalog;
@@ -3,6 +3,8 @@ export declare const sharedFlags: {
3
3
  service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
4
4
  };
5
5
  export declare const runFlags: {
6
+ dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
7
+ service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
6
8
  type: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
7
9
  suite: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
8
10
  file: import("./framework/definitions.js").FlagDefinition<string[] | undefined>;
@@ -12,8 +14,6 @@ export declare const runFlags: {
12
14
  "allow-empty": import("./framework/definitions.js").FlagDefinition<boolean>;
13
15
  "ignore-skip-rules": import("./framework/definitions.js").FlagDefinition<boolean>;
14
16
  "skip-schema-source-verify": import("./framework/definitions.js").FlagDefinition<boolean>;
15
- "output-mode": import("./framework/definitions.js").FlagDefinition<"debug" | "events" | "compact" | undefined>;
17
+ "output-mode": import("./framework/definitions.js").FlagDefinition<"compact" | "debug" | "events" | undefined>;
16
18
  debug: import("./framework/definitions.js").FlagDefinition<boolean>;
17
- dir: import("./framework/definitions.js").FlagDefinition<string | undefined>;
18
- service: import("./framework/definitions.js").FlagDefinition<string | undefined>;
19
19
  };
@@ -1,48 +1,48 @@
1
1
  import type { CommandContext } from "../command-catalog.js";
2
2
  export default function run({ args, flags, json, log }: CommandContext<"artifacts">): {
3
- ok: boolean;
4
- runs: import("../../evidence/contracts.js").RunBundleSummary[];
5
- count?: undefined;
6
3
  verification?: undefined;
7
4
  runId?: undefined;
5
+ ok: boolean;
6
+ runs: import("../../evidence/contracts.js").RunBundleSummary[];
8
7
  artifacts?: undefined;
8
+ count?: undefined;
9
9
  } | {
10
- ok: boolean;
11
- count: number;
12
10
  runs?: undefined;
13
11
  verification?: undefined;
14
12
  runId?: undefined;
13
+ ok: boolean;
14
+ count: number;
15
15
  artifacts?: undefined;
16
16
  } | {
17
- ok: boolean;
18
- verification: import("../../evidence/contracts.js").RunBundleVerification;
19
17
  runs?: undefined;
20
- count?: undefined;
21
18
  runId?: undefined;
19
+ ok: boolean;
20
+ verification: import("../../evidence/contracts.js").RunBundleVerification;
22
21
  artifacts?: undefined;
22
+ count?: undefined;
23
23
  } | {
24
+ runs?: undefined;
25
+ verification?: undefined;
24
26
  ok: boolean;
25
27
  runId: string | null;
26
28
  artifacts: {
27
29
  file: string;
28
30
  service: string;
29
31
  suite: {
30
- engineId: "node-vitest" | "playwright" | "k6";
32
+ engineId: "k6" | "node-vitest" | "playwright";
31
33
  name: string;
32
- profileId: "k6-http" | "k6-dal" | "node-vitest-data" | "node-vitest-contract" | "playwright-ui";
33
- testType: "contract" | "data" | "ui" | "e2e" | "int" | "dal" | "load" | "scenario";
34
+ profileId: "k6-dal" | "k6-http" | "node-vitest-contract" | "node-vitest-data" | "playwright-ui";
35
+ testType: "contract" | "dal" | "data" | "e2e" | "int" | "load" | "scenario" | "ui";
34
36
  };
35
37
  ref: import("../../evidence/reporting-types.js").ReportingArtifactReference;
36
38
  payload: import("../../evidence/reading.js").RunArtifactPayload | null;
37
39
  }[];
38
- runs?: undefined;
39
40
  count?: undefined;
40
- verification?: undefined;
41
41
  } | {
42
- ok: boolean;
43
- runId: string | null;
44
- count: number;
45
42
  runs?: undefined;
46
43
  verification?: undefined;
47
44
  artifacts?: undefined;
45
+ ok: boolean;
46
+ runId: string | null;
47
+ count: number;
48
48
  };
@@ -1,6 +1,5 @@
1
1
  import type { CommandContext } from "../command-catalog.js";
2
2
  export default function run({ flags, json, log }: CommandContext<"cleanup">): Promise<{
3
- lines: string[];
4
3
  bundleCleaned: import("../../engines/bundle-cache.js").BundleCleanupTarget[];
5
4
  cleaned: import("../../environment/lifecycle.js").RunManifest[];
6
5
  dryRun: boolean;
@@ -10,4 +9,5 @@ export default function run({ flags, json, log }: CommandContext<"cleanup">): Pr
10
9
  stoppedActive: import("../../environment/lifecycle.js").RunManifest[];
11
10
  targets: import("../../app/cleanup/index.js").CleanupTargets;
12
11
  ok: boolean;
12
+ lines: string[];
13
13
  }>;
@@ -1,6 +1,5 @@
1
1
  import type { CommandContext } from "../../command-catalog.js";
2
2
  export default function run({ flags, json, log }: CommandContext<"cloud login">): Promise<{
3
- reused: boolean;
4
3
  user: {
5
4
  id: string;
6
5
  email: string;
@@ -9,5 +8,6 @@ export default function run({ flags, json, log }: CommandContext<"cloud login">)
9
8
  expiresAt: string;
10
9
  maximumExpiresAt: string;
11
10
  origin: string;
11
+ reused: boolean;
12
12
  ok: boolean;
13
13
  }>;
@@ -6,10 +6,10 @@ export default function run({ flags, json, log }: CommandContext<"cloud status">
6
6
  message: string;
7
7
  ok: boolean;
8
8
  } | {
9
+ message?: undefined;
9
10
  origin: string;
10
11
  source: "none";
11
12
  authenticated: boolean;
12
- message?: undefined;
13
13
  ok: boolean;
14
14
  } | {
15
15
  user: {
@@ -19,15 +19,15 @@ export default function run({ flags, json, log }: CommandContext<"cloud status">
19
19
  };
20
20
  expiresAt: string;
21
21
  maximumExpiresAt: string;
22
+ message?: undefined;
22
23
  origin: string;
23
24
  source: "account";
24
25
  authenticated: boolean;
25
- message?: undefined;
26
26
  ok: boolean;
27
27
  } | {
28
+ message?: undefined;
28
29
  origin: string;
29
30
  source: "account";
30
31
  authenticated: boolean;
31
- message?: undefined;
32
32
  ok: boolean;
33
33
  }>;
@@ -1,4 +1,5 @@
1
1
  import type { EngineId, RunnerProfileId } from "../../domain/identifiers.js";
2
+ import { type NormalizedConfigContext } from "./load.js";
2
3
  import { type RunType } from "../../domain/test-types.js";
3
4
  import { type PublicTestType } from "../../domain/identifiers.js";
4
5
  import { type RuntimeIsolationPolicy as ConfigRuntimeIsolationPolicy } from "./runtime-isolation.js";
@@ -96,6 +97,10 @@ export interface DiscoverTestsOptions {
96
97
  type?: null | string | readonly string[];
97
98
  }
98
99
  export declare function discoverTests(options?: Readonly<DiscoverTestsOptions>): Promise<DiscoveryResult>;
100
+ export declare function loadDiscoveredConfigContext(options?: Readonly<Pick<DiscoverTestsOptions, "dir">>): Promise<{
101
+ context: NormalizedConfigContext;
102
+ discovery: DiscoveryResult;
103
+ }>;
99
104
  export declare function formatDisplayName(value: unknown): string;
100
105
  export declare function testTypeContract(testType: DiscoveryTestType, engineId: EngineId, profileId: RunnerProfileId): DiscoveryTestContract;
101
106
  export declare function fileDisplayName(filePath: string): string;