99import * as fs from 'node:fs' ;
1010import * as path from 'node:path' ;
1111import { DEFAULT_BROWSER_EXPLORE_TIMEOUT , browserSession , runWithTimeout } from './runtime.js' ;
12+ import type { IBrowserFactory } from './runtime.js' ;
1213import { VOLATILE_PARAMS , SEARCH_PARAMS , PAGINATION_PARAMS , LIMIT_PARAMS , FIELD_ROLES } from './constants.js' ;
1314import { detectFramework } from './scripts/framework.js' ;
1415import { discoverStores } from './scripts/store.js' ;
1516import { interactFuzz } from './scripts/interact.js' ;
17+ import type { IPage } from './types.js' ;
1618
1719// ── Site name detection ────────────────────────────────────────────────────
1820
@@ -68,7 +70,61 @@ interface InferredCapability {
6870 name : string ; description : string ; strategy : string ; confidence : number ;
6971 endpoint : string ; itemPath : string | null ;
7072 recommendedColumns : string [ ] ;
71- recommendedArgs : Array < { name : string ; type : string ; required : boolean ; default ?: any } > ;
73+ recommendedArgs : Array < { name : string ; type : string ; required : boolean ; default ?: unknown } > ;
74+ storeHint ?: { store : string ; action : string } ;
75+ }
76+
77+ export interface ExploreManifest {
78+ site : string ;
79+ target_url : string ;
80+ final_url : string ;
81+ title : string ;
82+ framework : Record < string , boolean > ;
83+ stores : Array < { type : DiscoveredStore [ 'type' ] ; id : string ; actions : string [ ] } > ;
84+ top_strategy : string ;
85+ explored_at ?: string ;
86+ }
87+
88+ export interface ExploreAuthSummary {
89+ top_strategy : string ;
90+ indicators : string [ ] ;
91+ framework : Record < string , boolean > ;
92+ }
93+
94+ export interface ExploreEndpointArtifact {
95+ pattern : string ;
96+ method : string ;
97+ url : string ;
98+ status : number | null ;
99+ contentType : string ;
100+ score : number ;
101+ queryParams : string [ ] ;
102+ itemPath : string | null ;
103+ itemCount : number ;
104+ detectedFields : Record < string , string > ;
105+ authIndicators : string [ ] ;
106+ }
107+
108+ export interface ExploreResult {
109+ site : string ;
110+ target_url : string ;
111+ final_url : string ;
112+ title : string ;
113+ framework : Record < string , boolean > ;
114+ stores : DiscoveredStore [ ] ;
115+ top_strategy : string ;
116+ endpoint_count : number ;
117+ api_endpoint_count : number ;
118+ capabilities : InferredCapability [ ] ;
119+ auth_indicators : string [ ] ;
120+ out_dir : string ;
121+ }
122+
123+ export interface ExploreBundle {
124+ manifest : ExploreManifest ;
125+ endpoints : ExploreEndpointArtifact [ ] ;
126+ capabilities : InferredCapability [ ] ;
127+ auth : ExploreAuthSummary ;
72128}
73129
74130/**
@@ -167,7 +223,7 @@ function flattenFields(obj: unknown, prefix: string, maxDepth: number): string[]
167223 return names ;
168224}
169225
170- function scoreEndpoint ( ep : { contentType : string ; responseAnalysis : any ; pattern : string ; status : number | null ; hasSearchParam : boolean ; hasPaginationParam : boolean ; hasLimitParam : boolean } ) : number {
226+ function scoreEndpoint ( ep : { contentType : string ; responseAnalysis : AnalyzedEndpoint [ 'responseAnalysis' ] ; pattern : string ; status : number | null ; hasSearchParam : boolean ; hasPaginationParam : boolean ; hasLimitParam : boolean } ) : number {
171227 let s = 0 ;
172228 if ( ep . contentType . includes ( 'json' ) ) s += 10 ;
173229 if ( ep . responseAnalysis ) { s += 5 ; s += Math . min ( ep . responseAnalysis . itemCount , 10 ) ; s += Object . keys ( ep . responseAnalysis . detectedFields ) . length * 2 ; }
@@ -321,7 +377,7 @@ function inferCapabilitiesFromEndpoints(
321377/** Write explore artifacts (manifest, endpoints, capabilities, auth, stores) to disk. */
322378async function writeExploreArtifacts (
323379 targetDir : string ,
324- result : Record < string , any > ,
380+ result : Omit < ExploreResult , 'out_dir' > ,
325381 analyzedEndpoints : AnalyzedEndpoint [ ] ,
326382 stores : DiscoveredStore [ ] ,
327383) : Promise < void > {
@@ -354,12 +410,12 @@ async function writeExploreArtifacts(
354410export async function exploreUrl (
355411 url : string ,
356412 opts : {
357- BrowserFactory : new ( ) => any ;
413+ BrowserFactory : new ( ) => IBrowserFactory ;
358414 site ?: string ; goal ?: string ; authenticated ?: boolean ;
359415 outDir ?: string ; waitSeconds ?: number ; query ?: string ;
360416 clickLabels ?: string [ ] ; auto ?: boolean ; workspace ?: string ;
361417 } ,
362- ) : Promise < Record < string , any > > {
418+ ) : Promise < ExploreResult > {
363419 const waitSeconds = opts . waitSeconds ?? 3.0 ;
364420 const exploreTimeout = Math . max ( DEFAULT_BROWSER_EXPLORE_TIMEOUT , 45.0 + waitSeconds * 8.0 ) ;
365421
@@ -467,7 +523,7 @@ export async function exploreUrl(
467523 } , { workspace : opts . workspace } ) ;
468524}
469525
470- export function renderExploreSummary ( result : Record < string , any > ) : string {
526+ export function renderExploreSummary ( result : ExploreResult ) : string {
471527 const lines = [
472528 'opencli probe: OK' , `Site: ${ result . site } ` , `URL: ${ result . target_url } ` ,
473529 `Title: ${ result . title || '(none)' } ` , `Strategy: ${ result . top_strategy } ` ,
@@ -492,7 +548,7 @@ export function renderExploreSummary(result: Record<string, any>): string {
492548 return lines . join ( '\n' ) ;
493549}
494550
495- async function readPageMetadata ( page : any /* IPage */ ) : Promise < { url : string ; title : string } > {
551+ async function readPageMetadata ( page : IPage ) : Promise < { url : string ; title : string } > {
496552 try {
497553 const result = await page . evaluate ( `() => ({ url: window.location.href, title: document.title || '' })` ) ;
498554 if ( result && typeof result === 'object' ) return { url : String ( result . url ?? '' ) , title : String ( result . title ?? '' ) } ;
0 commit comments