@qulib/core 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-summary.d.ts +52 -0
- package/dist/agent-summary.d.ts.map +1 -0
- package/dist/agent-summary.js +187 -0
- package/dist/cli/index.js +15 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { AnalyzeResult } from './analyze.js';
|
|
2
|
+
import type { CostIntelligence } from './schemas/cost-intelligence.schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* Agent-readable summary of an AnalyzeResult. Intended for orchestrators
|
|
5
|
+
* (CI gates, external agent loops) that need a small, stable JSON shape.
|
|
6
|
+
*
|
|
7
|
+
* QLIB-001 spec: see docs/agent-summary-output.md.
|
|
8
|
+
* C02 helper; exposed via CLI (`--agent-summary`) and MCP (`agentSummary: true`).
|
|
9
|
+
* Field names below are the v1 contract for `toAgentSummary`.
|
|
10
|
+
*/
|
|
11
|
+
export type AgentGate = 'pass' | 'warn' | 'fail';
|
|
12
|
+
export type CoverageStatus = 'ok' | 'thin' | 'blocked-by-auth' | 'budget-exceeded' | 'navigation-failures' | 'unknown';
|
|
13
|
+
export interface AgentSummaryCostSummary {
|
|
14
|
+
maxOutputTokensPerLlmCall: number;
|
|
15
|
+
totalInputTokens: number;
|
|
16
|
+
totalOutputTokens: number;
|
|
17
|
+
budgetWarningCount: number;
|
|
18
|
+
dataQuality: CostIntelligence['usageSummary']['dataQuality'];
|
|
19
|
+
maturityLevel: number;
|
|
20
|
+
maturityLabel: string;
|
|
21
|
+
}
|
|
22
|
+
export interface AgentSummary {
|
|
23
|
+
schemaVersion: 1;
|
|
24
|
+
gate: AgentGate;
|
|
25
|
+
releaseConfidence: number | null;
|
|
26
|
+
coverageStatus: CoverageStatus;
|
|
27
|
+
topRisks: string[];
|
|
28
|
+
recommendedNextChecks: string[];
|
|
29
|
+
honestyNotes: string[];
|
|
30
|
+
costSummary: AgentSummaryCostSummary | null;
|
|
31
|
+
deterministicFollowUps: string[];
|
|
32
|
+
}
|
|
33
|
+
export interface AgentSummaryPolicy {
|
|
34
|
+
/** Confidence at or above this number is required for `pass`. Default 80. */
|
|
35
|
+
passConfidenceThreshold?: number;
|
|
36
|
+
/** Confidence below this triggers `fail` (when no harder failure already applies). Default 30. */
|
|
37
|
+
failConfidenceThreshold?: number;
|
|
38
|
+
/** Max risks/checks/notes to include in each list. Default 5. */
|
|
39
|
+
maxListLength?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Treat `mode === 'auth-required'` as `fail` (default) or `warn`.
|
|
42
|
+
* Honest default: a deployment that was never exercised past auth cannot pass.
|
|
43
|
+
*/
|
|
44
|
+
authRequiredGate?: 'fail' | 'warn';
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Convert an `AnalyzeResult` into a small agent-facing summary.
|
|
48
|
+
*
|
|
49
|
+
* Pure function. No I/O. CLI / MCP wiring belongs to QLIB-001-C03 and -C04.
|
|
50
|
+
*/
|
|
51
|
+
export declare function toAgentSummary(result: AnalyzeResult, policy?: AgentSummaryPolicy): AgentSummary;
|
|
52
|
+
//# sourceMappingURL=agent-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-summary.d.ts","sourceRoot":"","sources":["../src/agent-summary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAE9E;;;;;;;GAOG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjD,MAAM,MAAM,cAAc,GACtB,IAAI,GACJ,MAAM,GACN,iBAAiB,GACjB,iBAAiB,GACjB,qBAAqB,GACrB,SAAS,CAAC;AAEd,MAAM,WAAW,uBAAuB;IACtC,yBAAyB,EAAE,MAAM,CAAC;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC,aAAa,CAAC,CAAC;IAC7D,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,CAAC,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC5C,sBAAsB,EAAE,MAAM,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,kGAAkG;IAClG,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACpC;AAmLD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EACrB,MAAM,CAAC,EAAE,kBAAkB,GAC1B,YAAY,CAiBd"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
const DEFAULT_POLICY = {
|
|
2
|
+
passConfidenceThreshold: 80,
|
|
3
|
+
failConfidenceThreshold: 30,
|
|
4
|
+
maxListLength: 5,
|
|
5
|
+
authRequiredGate: 'fail',
|
|
6
|
+
};
|
|
7
|
+
const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
8
|
+
function resolvePolicy(p) {
|
|
9
|
+
return {
|
|
10
|
+
passConfidenceThreshold: p?.passConfidenceThreshold ?? DEFAULT_POLICY.passConfidenceThreshold,
|
|
11
|
+
failConfidenceThreshold: p?.failConfidenceThreshold ?? DEFAULT_POLICY.failConfidenceThreshold,
|
|
12
|
+
maxListLength: p?.maxListLength ?? DEFAULT_POLICY.maxListLength,
|
|
13
|
+
authRequiredGate: p?.authRequiredGate ?? DEFAULT_POLICY.authRequiredGate,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function countBySeverity(gaps) {
|
|
17
|
+
const counts = { critical: 0, high: 0, medium: 0, low: 0 };
|
|
18
|
+
for (const g of gaps)
|
|
19
|
+
counts[g.severity]++;
|
|
20
|
+
return counts;
|
|
21
|
+
}
|
|
22
|
+
function deriveCoverageStatus(result) {
|
|
23
|
+
const g = result.gapAnalysis;
|
|
24
|
+
if (g.mode === 'auth-required' || g.coverageWarning === 'auth-required') {
|
|
25
|
+
return 'blocked-by-auth';
|
|
26
|
+
}
|
|
27
|
+
if (g.coverageWarning === 'budget-exceeded' || g.coverageBudgetExceeded) {
|
|
28
|
+
return 'budget-exceeded';
|
|
29
|
+
}
|
|
30
|
+
if (g.coverageWarning === 'navigation-failures') {
|
|
31
|
+
return 'navigation-failures';
|
|
32
|
+
}
|
|
33
|
+
if (g.coverageWarning === 'low-coverage') {
|
|
34
|
+
return 'thin';
|
|
35
|
+
}
|
|
36
|
+
if (g.coveragePagesScanned === 0) {
|
|
37
|
+
return 'unknown';
|
|
38
|
+
}
|
|
39
|
+
return 'ok';
|
|
40
|
+
}
|
|
41
|
+
function buildTopRisks(result, limit) {
|
|
42
|
+
const risks = [];
|
|
43
|
+
const status = deriveCoverageStatus(result);
|
|
44
|
+
if (status === 'blocked-by-auth') {
|
|
45
|
+
risks.push('Auth blocked the scan; protected routes were not exercised.');
|
|
46
|
+
}
|
|
47
|
+
else if (status === 'thin') {
|
|
48
|
+
risks.push('Crawl coverage was below the confidence floor.');
|
|
49
|
+
}
|
|
50
|
+
else if (status === 'budget-exceeded') {
|
|
51
|
+
risks.push('Crawl budget exceeded; coverage is partial.');
|
|
52
|
+
}
|
|
53
|
+
else if (status === 'navigation-failures') {
|
|
54
|
+
risks.push('Navigation errors limited what could be scanned.');
|
|
55
|
+
}
|
|
56
|
+
const sorted = [...result.gaps].sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
|
|
57
|
+
for (const g of sorted) {
|
|
58
|
+
if (risks.length >= limit)
|
|
59
|
+
break;
|
|
60
|
+
risks.push(`[${g.severity}] ${g.category} — ${g.path}`);
|
|
61
|
+
}
|
|
62
|
+
return risks.slice(0, limit);
|
|
63
|
+
}
|
|
64
|
+
function buildRecommendedNextChecks(result, limit) {
|
|
65
|
+
const out = [];
|
|
66
|
+
const status = deriveCoverageStatus(result);
|
|
67
|
+
if (status === 'blocked-by-auth') {
|
|
68
|
+
out.push('Provide auth (form login or storage state) and re-run, or use explore_auth.');
|
|
69
|
+
}
|
|
70
|
+
if (status === 'thin') {
|
|
71
|
+
out.push('Increase crawl budget or supply deeper entry URLs to raise coverage above the floor.');
|
|
72
|
+
}
|
|
73
|
+
if (status === 'budget-exceeded') {
|
|
74
|
+
out.push('Increase maxPagesToScan or narrow scope to bring the crawl under budget.');
|
|
75
|
+
}
|
|
76
|
+
const byCat = new Map();
|
|
77
|
+
for (const g of result.gaps)
|
|
78
|
+
byCat.set(g.category, (byCat.get(g.category) ?? 0) + 1);
|
|
79
|
+
const topCats = [...byCat.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3);
|
|
80
|
+
for (const [cat, n] of topCats) {
|
|
81
|
+
if (out.length >= limit)
|
|
82
|
+
break;
|
|
83
|
+
out.push(`Add or tighten deterministic coverage for ${cat} (${n} gap(s) this scan).`);
|
|
84
|
+
}
|
|
85
|
+
return out.slice(0, limit);
|
|
86
|
+
}
|
|
87
|
+
function buildHonestyNotes(result) {
|
|
88
|
+
const notes = ['This scan does not guarantee production readiness.'];
|
|
89
|
+
const g = result.gapAnalysis;
|
|
90
|
+
if (g.mode === 'auth-required' || g.coverageWarning === 'auth-required') {
|
|
91
|
+
notes.push('Authenticated surface was not exercised: confidence does not reflect protected routes.');
|
|
92
|
+
}
|
|
93
|
+
if (g.coverageWarning === 'low-coverage') {
|
|
94
|
+
notes.push('Coverage was below the confidence threshold; treat the score as a ceiling.');
|
|
95
|
+
}
|
|
96
|
+
if (g.coverageBudgetExceeded || g.coverageWarning === 'budget-exceeded') {
|
|
97
|
+
notes.push('Crawl budget was exceeded; some routes were not scanned.');
|
|
98
|
+
}
|
|
99
|
+
if (g.coverageWarning === 'navigation-failures') {
|
|
100
|
+
notes.push('Navigation failures reduced effective coverage.');
|
|
101
|
+
}
|
|
102
|
+
if (result.status === 'partial') {
|
|
103
|
+
notes.push('Scan completed only partially; signals are derived from a subset of intended work.');
|
|
104
|
+
}
|
|
105
|
+
if (result.status === 'blocked') {
|
|
106
|
+
notes.push('Scan was blocked before producing a meaningful evaluation.');
|
|
107
|
+
}
|
|
108
|
+
return notes;
|
|
109
|
+
}
|
|
110
|
+
function buildCostSummary(ci) {
|
|
111
|
+
if (!ci)
|
|
112
|
+
return null;
|
|
113
|
+
return {
|
|
114
|
+
maxOutputTokensPerLlmCall: ci.maxOutputTokensPerLlmCall,
|
|
115
|
+
totalInputTokens: ci.usageSummary.totalInputTokens,
|
|
116
|
+
totalOutputTokens: ci.usageSummary.totalOutputTokens,
|
|
117
|
+
budgetWarningCount: ci.budgetWarnings.length,
|
|
118
|
+
dataQuality: ci.usageSummary.dataQuality,
|
|
119
|
+
maturityLevel: ci.deterministicMaturity.level,
|
|
120
|
+
maturityLabel: ci.deterministicMaturity.label,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function buildDeterministicFollowUps(ci, limit) {
|
|
124
|
+
if (!ci)
|
|
125
|
+
return [];
|
|
126
|
+
return ci.conversionRecommendations.slice(0, limit);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Default gate policy:
|
|
130
|
+
* - fail when: any critical gap, status === 'blocked', releaseConfidence is null,
|
|
131
|
+
* releaseConfidence < failConfidenceThreshold, or mode === 'auth-required'
|
|
132
|
+
* under the default authRequiredGate.
|
|
133
|
+
* - warn when: any high-severity gap, status === 'partial', coverage is thin /
|
|
134
|
+
* budget-exceeded / navigation-failures, or confidence is below
|
|
135
|
+
* passConfidenceThreshold (but at or above failConfidenceThreshold).
|
|
136
|
+
* - pass when: confidence >= passConfidenceThreshold AND no blocking conditions.
|
|
137
|
+
*
|
|
138
|
+
* Honesty rule: an `auth-required` scan never silently `pass`es under defaults.
|
|
139
|
+
*/
|
|
140
|
+
function deriveGate(result, policy) {
|
|
141
|
+
const g = result.gapAnalysis;
|
|
142
|
+
const counts = countBySeverity(result.gaps);
|
|
143
|
+
if (counts.critical > 0)
|
|
144
|
+
return 'fail';
|
|
145
|
+
if (result.status === 'blocked')
|
|
146
|
+
return 'fail';
|
|
147
|
+
if (g.mode === 'auth-required' || g.coverageWarning === 'auth-required') {
|
|
148
|
+
return policy.authRequiredGate;
|
|
149
|
+
}
|
|
150
|
+
if (result.releaseConfidence === null)
|
|
151
|
+
return 'fail';
|
|
152
|
+
if (result.releaseConfidence < policy.failConfidenceThreshold)
|
|
153
|
+
return 'fail';
|
|
154
|
+
const hasCoverageIssue = g.coverageWarning === 'low-coverage' ||
|
|
155
|
+
g.coverageWarning === 'budget-exceeded' ||
|
|
156
|
+
g.coverageWarning === 'navigation-failures' ||
|
|
157
|
+
g.coverageBudgetExceeded;
|
|
158
|
+
if (counts.high > 0)
|
|
159
|
+
return 'warn';
|
|
160
|
+
if (result.status === 'partial')
|
|
161
|
+
return 'warn';
|
|
162
|
+
if (hasCoverageIssue)
|
|
163
|
+
return 'warn';
|
|
164
|
+
if (result.releaseConfidence < policy.passConfidenceThreshold)
|
|
165
|
+
return 'warn';
|
|
166
|
+
return 'pass';
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Convert an `AnalyzeResult` into a small agent-facing summary.
|
|
170
|
+
*
|
|
171
|
+
* Pure function. No I/O. CLI / MCP wiring belongs to QLIB-001-C03 and -C04.
|
|
172
|
+
*/
|
|
173
|
+
export function toAgentSummary(result, policy) {
|
|
174
|
+
const resolved = resolvePolicy(policy);
|
|
175
|
+
const limit = resolved.maxListLength;
|
|
176
|
+
return {
|
|
177
|
+
schemaVersion: 1,
|
|
178
|
+
gate: deriveGate(result, resolved),
|
|
179
|
+
releaseConfidence: result.releaseConfidence,
|
|
180
|
+
coverageStatus: deriveCoverageStatus(result),
|
|
181
|
+
topRisks: buildTopRisks(result, limit),
|
|
182
|
+
recommendedNextChecks: buildRecommendedNextChecks(result, limit),
|
|
183
|
+
honestyNotes: buildHonestyNotes(result),
|
|
184
|
+
costSummary: buildCostSummary(result.gapAnalysis.costIntelligence),
|
|
185
|
+
deterministicFollowUps: buildDeterministicFollowUps(result.gapAnalysis.costIntelligence, limit),
|
|
186
|
+
};
|
|
187
|
+
}
|
package/dist/cli/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const requirePkg = createRequire(import.meta.url);
|
|
|
8
8
|
const pkg = requirePkg('../../package.json');
|
|
9
9
|
import { HarnessConfigSchema } from '../schemas/config.schema.js';
|
|
10
10
|
import { analyzeApp } from '../analyze.js';
|
|
11
|
+
import { toAgentSummary } from '../agent-summary.js';
|
|
11
12
|
import { detectAuth } from '../tools/auth/detect.js';
|
|
12
13
|
import { exploreAuth } from '../tools/auth/explore.js';
|
|
13
14
|
import { assertExactlyOneCredentialSource, parseCredentialsJsonString, resolveAuthLoginConfig, } from './auth-login-resolve.js';
|
|
@@ -80,15 +81,22 @@ function mergeAuthFromCli(config, options) {
|
|
|
80
81
|
return config;
|
|
81
82
|
}
|
|
82
83
|
async function runAnalyze(options) {
|
|
84
|
+
if (options.ephemeral && options.agentSummary) {
|
|
85
|
+
throw new Error('Use either --agent-summary or --ephemeral, not both — pick one stdout output mode.');
|
|
86
|
+
}
|
|
83
87
|
const validatedUrl = AnalyzeUrlSchema.parse(options.url);
|
|
84
88
|
const mode = options.repo ? 'url-repo' : 'url-only';
|
|
85
89
|
const baseConfig = await loadConfigFile(options.configFile ?? 'qulib.config.ts');
|
|
86
90
|
const config = mergeAuthFromCli(baseConfig, options);
|
|
87
91
|
const ephemeral = options.ephemeral ?? false;
|
|
88
|
-
const
|
|
92
|
+
const agentSummary = options.agentSummary ?? false;
|
|
93
|
+
const writeArtifacts = !ephemeral && !agentSummary;
|
|
89
94
|
if (ephemeral) {
|
|
90
95
|
console.error('[qulib] Ephemeral mode: no disk writes; full result JSON on stdout');
|
|
91
96
|
}
|
|
97
|
+
else if (agentSummary) {
|
|
98
|
+
console.error('[qulib] Agent-summary mode: no disk writes; agent gate JSON on stdout');
|
|
99
|
+
}
|
|
92
100
|
else {
|
|
93
101
|
console.log('[qulib] Detected mode:', mode);
|
|
94
102
|
console.log('[qulib] Active config:', redactConfigForLog(config));
|
|
@@ -100,6 +108,10 @@ async function runAnalyze(options) {
|
|
|
100
108
|
writeArtifacts,
|
|
101
109
|
skipAuthDetection: options.skipAuthDetection,
|
|
102
110
|
});
|
|
111
|
+
if (agentSummary) {
|
|
112
|
+
console.log(JSON.stringify(toAgentSummary(result), null, 2));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
103
115
|
if (ephemeral) {
|
|
104
116
|
console.log(JSON.stringify({
|
|
105
117
|
status: result.status,
|
|
@@ -158,6 +170,7 @@ program
|
|
|
158
170
|
.option('--config <file>', 'Path to config file (relative to cwd)', 'qulib.config.ts')
|
|
159
171
|
.option('--adapter <type>', 'Override default test adapter (playwright, cypress-e2e, cypress-component, api)', 'playwright')
|
|
160
172
|
.option('--ephemeral', 'Do not write to disk — return full report as JSON on stdout (use for MCP/CI)', false)
|
|
173
|
+
.option('--agent-summary', 'Do not write to disk — return the compact agent-summary gate JSON on stdout (pass/warn/fail with honesty notes). Mutually exclusive with --ephemeral.', false)
|
|
161
174
|
.option('--skip-auth-detection', 'Crawl the public surface even if auth is detected (useful for sites with sign-in CTAs on public pages)', false)
|
|
162
175
|
.option('--auth-storage-state <path>', 'Path to a storage state JSON file (use after `qulib auth init`)')
|
|
163
176
|
.option('--auth-form-login', 'Use form-login; requires --login-url, credentials, and selectors', false)
|
|
@@ -181,6 +194,7 @@ program
|
|
|
181
194
|
repo: options.repo,
|
|
182
195
|
configFile: options.config,
|
|
183
196
|
ephemeral: options.ephemeral,
|
|
197
|
+
agentSummary: options.agentSummary,
|
|
184
198
|
skipAuthDetection: Boolean(options.skipAuthDetection),
|
|
185
199
|
authStorageState: options.authStorageState,
|
|
186
200
|
authFormLogin,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { analyzeApp } from './analyze.js';
|
|
2
|
+
export { toAgentSummary } from './agent-summary.js';
|
|
3
|
+
export type { AgentSummary, AgentSummaryPolicy, AgentGate, CoverageStatus, AgentSummaryCostSummary, } from './agent-summary.js';
|
|
2
4
|
export { detectAuth, validateStorageState, evaluateStorageStateValidity, preflightStorageStateFile, waitForReturnToOrigin, } from './tools/auth/detect.js';
|
|
3
5
|
export type { StorageStateInvalidReason, StorageStateValidationResult, } from './tools/auth/detect.js';
|
|
4
6
|
export { exploreAuth } from './tools/auth/explore.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,yBAAyB,EACzB,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1G,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACvF,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACjF,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,YAAY,EACV,aAAa,EACb,cAAc,EACd,kBAAkB,GACnB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC9E,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,YAAY,EACV,aAAa,EACb,UAAU,EACV,cAAc,EACd,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,2BAA2B,EAC3B,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,YAAY,EACV,YAAY,EACZ,kBAAkB,EAClB,SAAS,EACT,cAAc,EACd,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,yBAAyB,EACzB,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1G,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACvF,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACjF,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,YAAY,EACV,aAAa,EACb,cAAc,EACd,kBAAkB,GACnB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC9E,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,YAAY,EACV,aAAa,EACb,UAAU,EACV,cAAc,EACd,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,2BAA2B,EAC3B,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { analyzeApp } from './analyze.js';
|
|
2
|
+
export { toAgentSummary } from './agent-summary.js';
|
|
2
3
|
export { detectAuth, validateStorageState, evaluateStorageStateValidity, preflightStorageStateFile, waitForReturnToOrigin, } from './tools/auth/detect.js';
|
|
3
4
|
export { exploreAuth } from './tools/auth/explore.js';
|
|
4
5
|
export { addUserProvider, removeUserProvider, listUserProviders } from './tools/auth/custom-providers.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qulib/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Qulib — analyze deployed web apps for honest quality gaps (CLI + programmatic API)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Tapesh Nagarwal",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"analyze": "tsx src/cli/index.ts analyze",
|
|
49
49
|
"clean": "tsx src/cli/index.ts clean",
|
|
50
50
|
"build": "tsc",
|
|
51
|
-
"test": "node --import tsx/esm --test src/llm/__tests__/cost-intelligence.test.ts src/llm/__tests__/context-builder.test.ts src/tools/scoring/__tests__/gaps.test.ts src/tools/auth/__tests__/gaps.test.ts src/tools/auth/__tests__/detect.test.ts src/tools/scoring/__tests__/automation-maturity.test.ts src/harness/__tests__/state-manager.test.ts src/telemetry/__tests__/redact-url.test.ts src/cli/__tests__/auth-login.test.ts src/cli/__tests__/cli-version.test.ts src/__tests__/analyze.storage-state-invalid.test.ts src/__tests__/analyze.fixtures.test.ts",
|
|
51
|
+
"test": "node --import tsx/esm --test src/llm/__tests__/cost-intelligence.test.ts src/llm/__tests__/context-builder.test.ts src/tools/scoring/__tests__/gaps.test.ts src/tools/auth/__tests__/gaps.test.ts src/tools/auth/__tests__/detect.test.ts src/tools/scoring/__tests__/automation-maturity.test.ts src/harness/__tests__/state-manager.test.ts src/telemetry/__tests__/redact-url.test.ts src/cli/__tests__/auth-login.test.ts src/cli/__tests__/cli-version.test.ts src/__tests__/agent-summary.test.ts src/__tests__/cli-agent-summary.test.ts src/__tests__/analyze.storage-state-invalid.test.ts src/__tests__/analyze.fixtures.test.ts",
|
|
52
52
|
"test:integration": "node --import tsx/esm --test src/__tests__/analyze.integration.test.ts",
|
|
53
53
|
"smoke": "tsx src/cli/index.ts analyze --url https://example.com --ephemeral",
|
|
54
54
|
"cost-doctor": "tsx src/cli/index.ts cost doctor"
|