@qulib/core 0.4.1 → 0.4.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.
- package/README.md +56 -8
- package/dist/analyze.d.ts.map +1 -1
- package/dist/analyze.js +86 -7
- package/dist/cli/auth-login-resolve.d.ts +14 -0
- package/dist/cli/auth-login-resolve.d.ts.map +1 -0
- package/dist/cli/auth-login-resolve.js +68 -0
- package/dist/cli/auth-login-run.d.ts +13 -0
- package/dist/cli/auth-login-run.d.ts.map +1 -0
- package/dist/cli/auth-login-run.js +152 -0
- package/dist/cli/index.js +60 -7
- package/dist/harness/state-manager.d.ts +10 -0
- package/dist/harness/state-manager.d.ts.map +1 -1
- package/dist/harness/state-manager.js +15 -0
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -6
- package/dist/phases/act.js +3 -3
- package/dist/phases/observe.js +5 -5
- package/dist/phases/think.js +1 -1
- package/dist/schemas/automation-maturity.schema.d.ts +40 -0
- package/dist/schemas/automation-maturity.schema.d.ts.map +1 -1
- package/dist/schemas/automation-maturity.schema.js +27 -0
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +1 -1
- package/dist/schemas/repo-analysis.schema.d.ts +22 -0
- package/dist/schemas/repo-analysis.schema.d.ts.map +1 -1
- package/dist/schemas/repo-analysis.schema.js +1 -0
- package/dist/telemetry/emit.d.ts +22 -0
- package/dist/telemetry/emit.d.ts.map +1 -1
- package/dist/telemetry/emit.js +37 -0
- package/dist/telemetry/telemetry.interface.d.ts +1 -1
- package/dist/telemetry/telemetry.interface.d.ts.map +1 -1
- package/dist/tools/apply-auth.d.ts +4 -0
- package/dist/tools/apply-auth.d.ts.map +1 -0
- package/dist/tools/apply-auth.js +35 -0
- package/dist/tools/auth/apply.d.ts +4 -0
- package/dist/tools/auth/apply.d.ts.map +1 -0
- package/dist/tools/auth/apply.js +35 -0
- package/dist/tools/auth/block-gap.d.ts +9 -0
- package/dist/tools/auth/block-gap.d.ts.map +1 -0
- package/dist/tools/auth/block-gap.js +52 -0
- package/dist/tools/auth/custom-providers.d.ts +15 -0
- package/dist/tools/auth/custom-providers.d.ts.map +1 -0
- package/dist/tools/auth/custom-providers.js +62 -0
- package/dist/tools/auth/detect.d.ts +23 -0
- package/dist/tools/auth/detect.d.ts.map +1 -0
- package/dist/tools/auth/detect.js +526 -0
- package/dist/tools/auth/detector.d.ts +23 -0
- package/dist/tools/auth/detector.d.ts.map +1 -0
- package/dist/tools/auth/detector.js +526 -0
- package/dist/tools/auth/explore.d.ts +4 -0
- package/dist/tools/auth/explore.d.ts.map +1 -0
- package/dist/tools/auth/explore.js +346 -0
- package/dist/tools/auth/explorer.d.ts +4 -0
- package/dist/tools/auth/explorer.d.ts.map +1 -0
- package/dist/tools/auth/explorer.js +346 -0
- package/dist/tools/auth/gaps.d.ts +9 -0
- package/dist/tools/auth/gaps.d.ts.map +1 -0
- package/dist/tools/auth/gaps.js +52 -0
- package/dist/tools/auth/oauth-providers.d.ts +7 -0
- package/dist/tools/auth/oauth-providers.d.ts.map +1 -0
- package/dist/tools/auth/oauth-providers.js +21 -0
- package/dist/tools/auth/providers.d.ts +7 -0
- package/dist/tools/auth/providers.d.ts.map +1 -0
- package/dist/tools/auth/providers.js +21 -0
- package/dist/tools/auth/surface-analyzer.d.ts +4 -0
- package/dist/tools/auth/surface-analyzer.d.ts.map +1 -0
- package/dist/tools/auth/surface-analyzer.js +170 -0
- package/dist/tools/auth/surface.d.ts +4 -0
- package/dist/tools/auth/surface.d.ts.map +1 -0
- package/dist/tools/auth/surface.js +170 -0
- package/dist/tools/auth/user-providers.d.ts +15 -0
- package/dist/tools/auth/user-providers.d.ts.map +1 -0
- package/dist/tools/auth/user-providers.js +62 -0
- package/dist/tools/auth-block-gap.d.ts +6 -0
- package/dist/tools/auth-block-gap.d.ts.map +1 -1
- package/dist/tools/auth-block-gap.js +42 -9
- package/dist/tools/auth-detector.d.ts +19 -0
- package/dist/tools/auth-detector.d.ts.map +1 -1
- package/dist/tools/auth-detector.js +186 -8
- package/dist/tools/automation-maturity.d.ts.map +1 -1
- package/dist/tools/automation-maturity.js +76 -20
- package/dist/tools/explorers/browser.d.ts +3 -0
- package/dist/tools/explorers/browser.d.ts.map +1 -0
- package/dist/tools/explorers/browser.js +13 -0
- package/dist/tools/explorers/cypress-explorer.d.ts +8 -0
- package/dist/tools/explorers/cypress-explorer.d.ts.map +1 -0
- package/dist/tools/explorers/cypress-explorer.js +5 -0
- package/dist/tools/explorers/cypress.d.ts +8 -0
- package/dist/tools/explorers/cypress.d.ts.map +1 -0
- package/dist/tools/explorers/cypress.js +5 -0
- package/dist/tools/explorers/explorer.interface.d.ts +7 -0
- package/dist/tools/explorers/explorer.interface.d.ts.map +1 -0
- package/dist/tools/explorers/explorer.interface.js +1 -0
- package/dist/tools/explorers/factory.d.ts +4 -0
- package/dist/tools/explorers/factory.d.ts.map +1 -0
- package/dist/tools/explorers/factory.js +12 -0
- package/dist/tools/explorers/playwright-explorer.d.ts +8 -0
- package/dist/tools/explorers/playwright-explorer.d.ts.map +1 -0
- package/dist/tools/explorers/playwright-explorer.js +172 -0
- package/dist/tools/explorers/playwright.d.ts +8 -0
- package/dist/tools/explorers/playwright.d.ts.map +1 -0
- package/dist/tools/explorers/playwright.js +172 -0
- package/dist/tools/explorers/types.d.ts +7 -0
- package/dist/tools/explorers/types.d.ts.map +1 -0
- package/dist/tools/explorers/types.js +1 -0
- package/dist/tools/playwright-explorer.js +1 -1
- package/dist/tools/repo/detect-framework.d.ts +15 -0
- package/dist/tools/repo/detect-framework.d.ts.map +1 -0
- package/dist/tools/repo/detect-framework.js +153 -0
- package/dist/tools/repo/framework-detector.d.ts +15 -0
- package/dist/tools/repo/framework-detector.d.ts.map +1 -0
- package/dist/tools/repo/framework-detector.js +153 -0
- package/dist/tools/repo/scan.d.ts +19 -0
- package/dist/tools/repo/scan.d.ts.map +1 -0
- package/dist/tools/repo/scan.js +181 -0
- package/dist/tools/repo/scanner.d.ts +19 -0
- package/dist/tools/repo/scanner.d.ts.map +1 -0
- package/dist/tools/repo/scanner.js +181 -0
- package/dist/tools/repo-scanner.d.ts.map +1 -1
- package/dist/tools/repo-scanner.js +7 -2
- package/dist/tools/scoring/automation-maturity.d.ts +4 -0
- package/dist/tools/scoring/automation-maturity.d.ts.map +1 -0
- package/dist/tools/scoring/automation-maturity.js +219 -0
- package/dist/tools/scoring/gap-engine.d.ts +8 -0
- package/dist/tools/scoring/gap-engine.d.ts.map +1 -0
- package/dist/tools/scoring/gap-engine.js +138 -0
- package/dist/tools/scoring/gaps.d.ts +8 -0
- package/dist/tools/scoring/gaps.d.ts.map +1 -0
- package/dist/tools/scoring/gaps.js +138 -0
- package/dist/tools/scoring/public-surface.d.ts +5 -0
- package/dist/tools/scoring/public-surface.d.ts.map +1 -0
- package/dist/tools/scoring/public-surface.js +13 -0
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
export { analyzeApp } from './analyze.js';
|
|
2
|
-
export { detectAuth } from './tools/auth
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
2
|
+
export { detectAuth, validateStorageState, evaluateStorageStateValidity, preflightStorageStateFile, waitForReturnToOrigin, } from './tools/auth/detect.js';
|
|
3
|
+
export type { StorageStateInvalidReason, StorageStateValidationResult, } from './tools/auth/detect.js';
|
|
4
|
+
export { exploreAuth } from './tools/auth/explore.js';
|
|
5
|
+
export { addUserProvider, removeUserProvider, listUserProviders } from './tools/auth/custom-providers.js';
|
|
6
|
+
export { scanRepo } from './tools/repo/scan.js';
|
|
7
|
+
export { computeAutomationMaturity } from './tools/scoring/automation-maturity.js';
|
|
7
8
|
export { createProvider } from './llm/provider-registry.js';
|
|
8
9
|
export { resolveMaxOutputTokensPerLlmCall } from './schemas/config.schema.js';
|
|
9
|
-
export { resolveScanStateBaseDir } from './harness/state-manager.js';
|
|
10
|
+
export { resolveScanStateBaseDir, resolveReportDir } from './harness/state-manager.js';
|
|
10
11
|
export type { AnalyzeOptions, AnalyzeResult, AnalyzeStatus } from './analyze.js';
|
|
11
12
|
export type { AnalyzeProgressSink } from './harness/progress-log.js';
|
|
12
13
|
export type { TelemetrySink, TelemetryEvent, TelemetryEventKind, } from './telemetry/telemetry.interface.js';
|
|
13
14
|
export { NoopTelemetrySink } from './telemetry/telemetry.interface.js';
|
|
15
|
+
export { redactUrlForTelemetry } from './telemetry/emit.js';
|
|
14
16
|
export type { LlmCallResult, LlmProvider } from './llm/provider.interface.js';
|
|
15
17
|
export type { CallLlmConfigSlice } from './llm/provider.js';
|
|
16
18
|
export type { HarnessConfig, AuthConfig, RouteInventory, GapAnalysis, RepoAnalysis, DetectedAuth, AuthExploration, AuthPath, AuthPathRequirements, CostIntelligence, LlmUsageRecord, RepeatedAiPattern, DeterministicMaturity, PublicSurface, AutomationMaturity, AutomationMaturityDimension, FrameworkDetectionResult, DetectedFrameworkPrimary, } from './schemas/index.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,
|
|
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"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export { analyzeApp } from './analyze.js';
|
|
2
|
-
export { detectAuth } from './tools/auth
|
|
3
|
-
export { exploreAuth } from './tools/auth
|
|
4
|
-
export { addUserProvider, removeUserProvider, listUserProviders } from './tools/
|
|
5
|
-
export { scanRepo } from './tools/repo
|
|
6
|
-
export { computeAutomationMaturity } from './tools/automation-maturity.js';
|
|
2
|
+
export { detectAuth, validateStorageState, evaluateStorageStateValidity, preflightStorageStateFile, waitForReturnToOrigin, } from './tools/auth/detect.js';
|
|
3
|
+
export { exploreAuth } from './tools/auth/explore.js';
|
|
4
|
+
export { addUserProvider, removeUserProvider, listUserProviders } from './tools/auth/custom-providers.js';
|
|
5
|
+
export { scanRepo } from './tools/repo/scan.js';
|
|
6
|
+
export { computeAutomationMaturity } from './tools/scoring/automation-maturity.js';
|
|
7
7
|
export { createProvider } from './llm/provider-registry.js';
|
|
8
8
|
export { resolveMaxOutputTokensPerLlmCall } from './schemas/config.schema.js';
|
|
9
|
-
export { resolveScanStateBaseDir } from './harness/state-manager.js';
|
|
9
|
+
export { resolveScanStateBaseDir, resolveReportDir } from './harness/state-manager.js';
|
|
10
10
|
export { NoopTelemetrySink } from './telemetry/telemetry.interface.js';
|
|
11
|
+
export { redactUrlForTelemetry } from './telemetry/emit.js';
|
package/dist/phases/act.js
CHANGED
|
@@ -3,10 +3,10 @@ import { writeJsonReport } from '../reporters/json-reporter.js';
|
|
|
3
3
|
import { writeMarkdownReport } from '../reporters/markdown-reporter.js';
|
|
4
4
|
import { logDecision } from '../harness/decision-logger.js';
|
|
5
5
|
import { emitTelemetry } from '../telemetry/emit.js';
|
|
6
|
-
import { resolveScanStateBaseDir } from '../harness/state-manager.js';
|
|
6
|
+
import { resolveReportDir, resolveScanStateBaseDir } from '../harness/state-manager.js';
|
|
7
7
|
export async function act(analysis, config, artifacts = { writeArtifacts: true }) {
|
|
8
8
|
const sessionId = artifacts.telemetrySessionId ?? 'none';
|
|
9
|
-
const reportDir =
|
|
9
|
+
const reportDir = resolveReportDir(config.outputDir);
|
|
10
10
|
const logOpts = {
|
|
11
11
|
persist: artifacts.writeArtifacts,
|
|
12
12
|
memory: artifacts.decisionMemory,
|
|
@@ -48,7 +48,7 @@ export async function act(analysis, config, artifacts = { writeArtifacts: true }
|
|
|
48
48
|
if (config.requireHumanReview) {
|
|
49
49
|
log('\n[qulib] Human review required before applying any generated output.');
|
|
50
50
|
if (artifacts.writeArtifacts) {
|
|
51
|
-
log(
|
|
51
|
+
log(` Reports: ${join(reportDir, 'report.json')} and ${join(reportDir, 'report.md')}`);
|
|
52
52
|
log(` Decisions: ${join(resolveScanStateBaseDir(config.outputDir), 'decision-log.json')}`);
|
|
53
53
|
}
|
|
54
54
|
else {
|
package/dist/phases/observe.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { RouteInventorySchema } from '../schemas/route-inventory.schema.js';
|
|
2
2
|
import { RepoAnalysisSchema } from '../schemas/repo-analysis.schema.js';
|
|
3
|
-
import { createExplorer } from '../tools/
|
|
4
|
-
import { scanRepo } from '../tools/repo
|
|
3
|
+
import { createExplorer } from '../tools/explorers/factory.js';
|
|
4
|
+
import { scanRepo } from '../tools/repo/scan.js';
|
|
5
5
|
import { StateManager } from '../harness/state-manager.js';
|
|
6
6
|
import { logDecision } from '../harness/decision-logger.js';
|
|
7
|
-
import { emitTelemetry } from '../telemetry/emit.js';
|
|
7
|
+
import { emitTelemetry, redactUrlForTelemetry } from '../telemetry/emit.js';
|
|
8
8
|
export async function observe(baseUrl, repoPath, config, artifacts = { writeArtifacts: true }) {
|
|
9
9
|
const sessionId = artifacts.telemetrySessionId ?? 'none';
|
|
10
10
|
const explorer = createExplorer(config.explorer);
|
|
@@ -15,7 +15,7 @@ export async function observe(baseUrl, repoPath, config, artifacts = { writeArti
|
|
|
15
15
|
outputDir: config.outputDir,
|
|
16
16
|
};
|
|
17
17
|
emitTelemetry(artifacts.telemetry, 'phase.observe.started', sessionId, {
|
|
18
|
-
baseUrl,
|
|
18
|
+
baseUrl: redactUrlForTelemetry(baseUrl),
|
|
19
19
|
hasRepoPath: Boolean(repoPath),
|
|
20
20
|
});
|
|
21
21
|
const rawRoutes = await explorer.explore(baseUrl, config, artifacts);
|
|
@@ -29,7 +29,7 @@ export async function observe(baseUrl, repoPath, config, artifacts = { writeArti
|
|
|
29
29
|
decision: 'exploration-complete',
|
|
30
30
|
reason: `Discovered ${routes.routes.length} routes; budgetExceeded=${routes.budgetExceeded}`,
|
|
31
31
|
metadata: {
|
|
32
|
-
baseUrl,
|
|
32
|
+
baseUrl: redactUrlForTelemetry(baseUrl),
|
|
33
33
|
scannedRoutes: routes.routes.length,
|
|
34
34
|
budgetExceeded: routes.budgetExceeded,
|
|
35
35
|
pagesSkipped: routes.pagesSkipped,
|
package/dist/phases/think.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GapAnalysisSchema } from '../schemas/gap-analysis.schema.js';
|
|
2
|
-
import { analyzeGaps } from '../tools/
|
|
2
|
+
import { analyzeGaps } from '../tools/scoring/gaps.js';
|
|
3
3
|
import { logDecision } from '../harness/decision-logger.js';
|
|
4
4
|
import { finalizeGapAnalysisFromDraft } from './think-finalize.js';
|
|
5
5
|
import { emitTelemetry } from '../telemetry/emit.js';
|
|
@@ -1,22 +1,48 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
export declare const AutomationMaturityApplicabilitySchema: z.ZodEnum<["applicable", "not_applicable", "unknown"]>;
|
|
3
|
+
/**
|
|
4
|
+
* Maturity dimension with explicit applicability so absent capabilities are not silently
|
|
5
|
+
* awarded partial credit.
|
|
6
|
+
*
|
|
7
|
+
* - `applicable` — Qulib has enough signal to compute a real `score`.
|
|
8
|
+
* - `not_applicable` — The capability does not apply to this repo (e.g. component-test-ratio
|
|
9
|
+
* with no Cypress detected, auth-test-coverage when no auth signal exists).
|
|
10
|
+
* `score` is reported but excluded from the overall calculation.
|
|
11
|
+
* - `unknown` — Qulib could not collect enough signal to score honestly (e.g. zero
|
|
12
|
+
* interactive elements scanned for test-id hygiene). Excluded from overall.
|
|
13
|
+
*
|
|
14
|
+
* Overall score formula (in `computeAutomationMaturity`):
|
|
15
|
+
* numerator = Σ score_i * weight_i for i ∈ applicable dimensions
|
|
16
|
+
* denominator = Σ weight_i for i ∈ applicable dimensions
|
|
17
|
+
* overallScore = round(numerator / denominator) when denominator > 0, else 0
|
|
18
|
+
*
|
|
19
|
+
* Schema fields stay backward compatible: both `applicability` and `reason` are optional.
|
|
20
|
+
* Existing consumers that don't read them keep working; honest reports populate them.
|
|
21
|
+
*/
|
|
2
22
|
export declare const AutomationMaturityDimensionSchema: z.ZodObject<{
|
|
3
23
|
dimension: z.ZodEnum<["test-coverage-breadth", "framework-adoption", "test-id-hygiene", "ci-integration", "auth-test-coverage", "component-test-ratio"]>;
|
|
4
24
|
score: z.ZodNumber;
|
|
5
25
|
weight: z.ZodNumber;
|
|
6
26
|
evidence: z.ZodArray<z.ZodString, "many">;
|
|
7
27
|
recommendations: z.ZodArray<z.ZodString, "many">;
|
|
28
|
+
applicability: z.ZodOptional<z.ZodEnum<["applicable", "not_applicable", "unknown"]>>;
|
|
29
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
8
30
|
}, "strip", z.ZodTypeAny, {
|
|
9
31
|
recommendations: string[];
|
|
10
32
|
dimension: "test-coverage-breadth" | "framework-adoption" | "test-id-hygiene" | "ci-integration" | "auth-test-coverage" | "component-test-ratio";
|
|
11
33
|
score: number;
|
|
12
34
|
weight: number;
|
|
13
35
|
evidence: string[];
|
|
36
|
+
reason?: string | undefined;
|
|
37
|
+
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
14
38
|
}, {
|
|
15
39
|
recommendations: string[];
|
|
16
40
|
dimension: "test-coverage-breadth" | "framework-adoption" | "test-id-hygiene" | "ci-integration" | "auth-test-coverage" | "component-test-ratio";
|
|
17
41
|
score: number;
|
|
18
42
|
weight: number;
|
|
19
43
|
evidence: string[];
|
|
44
|
+
reason?: string | undefined;
|
|
45
|
+
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
20
46
|
}>;
|
|
21
47
|
export declare const AutomationMaturitySchema: z.ZodObject<{
|
|
22
48
|
computedAt: z.ZodString;
|
|
@@ -30,20 +56,27 @@ export declare const AutomationMaturitySchema: z.ZodObject<{
|
|
|
30
56
|
weight: z.ZodNumber;
|
|
31
57
|
evidence: z.ZodArray<z.ZodString, "many">;
|
|
32
58
|
recommendations: z.ZodArray<z.ZodString, "many">;
|
|
59
|
+
applicability: z.ZodOptional<z.ZodEnum<["applicable", "not_applicable", "unknown"]>>;
|
|
60
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
33
61
|
}, "strip", z.ZodTypeAny, {
|
|
34
62
|
recommendations: string[];
|
|
35
63
|
dimension: "test-coverage-breadth" | "framework-adoption" | "test-id-hygiene" | "ci-integration" | "auth-test-coverage" | "component-test-ratio";
|
|
36
64
|
score: number;
|
|
37
65
|
weight: number;
|
|
38
66
|
evidence: string[];
|
|
67
|
+
reason?: string | undefined;
|
|
68
|
+
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
39
69
|
}, {
|
|
40
70
|
recommendations: string[];
|
|
41
71
|
dimension: "test-coverage-breadth" | "framework-adoption" | "test-id-hygiene" | "ci-integration" | "auth-test-coverage" | "component-test-ratio";
|
|
42
72
|
score: number;
|
|
43
73
|
weight: number;
|
|
44
74
|
evidence: string[];
|
|
75
|
+
reason?: string | undefined;
|
|
76
|
+
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
45
77
|
}>, "many">;
|
|
46
78
|
topRecommendations: z.ZodArray<z.ZodString, "many">;
|
|
79
|
+
scoreFormula: z.ZodOptional<z.ZodString>;
|
|
47
80
|
}, "strip", z.ZodTypeAny, {
|
|
48
81
|
label: string;
|
|
49
82
|
level: number;
|
|
@@ -56,8 +89,11 @@ export declare const AutomationMaturitySchema: z.ZodObject<{
|
|
|
56
89
|
score: number;
|
|
57
90
|
weight: number;
|
|
58
91
|
evidence: string[];
|
|
92
|
+
reason?: string | undefined;
|
|
93
|
+
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
59
94
|
}[];
|
|
60
95
|
topRecommendations: string[];
|
|
96
|
+
scoreFormula?: string | undefined;
|
|
61
97
|
}, {
|
|
62
98
|
label: string;
|
|
63
99
|
level: number;
|
|
@@ -70,9 +106,13 @@ export declare const AutomationMaturitySchema: z.ZodObject<{
|
|
|
70
106
|
score: number;
|
|
71
107
|
weight: number;
|
|
72
108
|
evidence: string[];
|
|
109
|
+
reason?: string | undefined;
|
|
110
|
+
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
73
111
|
}[];
|
|
74
112
|
topRecommendations: string[];
|
|
113
|
+
scoreFormula?: string | undefined;
|
|
75
114
|
}>;
|
|
115
|
+
export type AutomationMaturityApplicability = z.infer<typeof AutomationMaturityApplicabilitySchema>;
|
|
76
116
|
export type AutomationMaturityDimension = z.infer<typeof AutomationMaturityDimensionSchema>;
|
|
77
117
|
export type AutomationMaturity = z.infer<typeof AutomationMaturitySchema>;
|
|
78
118
|
//# sourceMappingURL=automation-maturity.schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automation-maturity.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/automation-maturity.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"automation-maturity.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/automation-maturity.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,qCAAqC,wDAIhD,CAAC;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;EAe5C,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASnC,CAAC;AAEH,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AACpG,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAC5F,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
|
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
export const AutomationMaturityApplicabilitySchema = z.enum([
|
|
3
|
+
'applicable',
|
|
4
|
+
'not_applicable',
|
|
5
|
+
'unknown',
|
|
6
|
+
]);
|
|
7
|
+
/**
|
|
8
|
+
* Maturity dimension with explicit applicability so absent capabilities are not silently
|
|
9
|
+
* awarded partial credit.
|
|
10
|
+
*
|
|
11
|
+
* - `applicable` — Qulib has enough signal to compute a real `score`.
|
|
12
|
+
* - `not_applicable` — The capability does not apply to this repo (e.g. component-test-ratio
|
|
13
|
+
* with no Cypress detected, auth-test-coverage when no auth signal exists).
|
|
14
|
+
* `score` is reported but excluded from the overall calculation.
|
|
15
|
+
* - `unknown` — Qulib could not collect enough signal to score honestly (e.g. zero
|
|
16
|
+
* interactive elements scanned for test-id hygiene). Excluded from overall.
|
|
17
|
+
*
|
|
18
|
+
* Overall score formula (in `computeAutomationMaturity`):
|
|
19
|
+
* numerator = Σ score_i * weight_i for i ∈ applicable dimensions
|
|
20
|
+
* denominator = Σ weight_i for i ∈ applicable dimensions
|
|
21
|
+
* overallScore = round(numerator / denominator) when denominator > 0, else 0
|
|
22
|
+
*
|
|
23
|
+
* Schema fields stay backward compatible: both `applicability` and `reason` are optional.
|
|
24
|
+
* Existing consumers that don't read them keep working; honest reports populate them.
|
|
25
|
+
*/
|
|
2
26
|
export const AutomationMaturityDimensionSchema = z.object({
|
|
3
27
|
dimension: z.enum([
|
|
4
28
|
'test-coverage-breadth',
|
|
@@ -12,6 +36,8 @@ export const AutomationMaturityDimensionSchema = z.object({
|
|
|
12
36
|
weight: z.number().min(0).max(1),
|
|
13
37
|
evidence: z.array(z.string()),
|
|
14
38
|
recommendations: z.array(z.string()),
|
|
39
|
+
applicability: AutomationMaturityApplicabilitySchema.optional(),
|
|
40
|
+
reason: z.string().optional(),
|
|
15
41
|
});
|
|
16
42
|
export const AutomationMaturitySchema = z.object({
|
|
17
43
|
computedAt: z.string().datetime(),
|
|
@@ -21,4 +47,5 @@ export const AutomationMaturitySchema = z.object({
|
|
|
21
47
|
label: z.string(),
|
|
22
48
|
dimensions: z.array(AutomationMaturityDimensionSchema),
|
|
23
49
|
topRecommendations: z.array(z.string()),
|
|
50
|
+
scoreFormula: z.string().optional(),
|
|
24
51
|
});
|
package/dist/schemas/index.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ export { RouteInventorySchema, RouteSchema, A11yViolationSchema, BrokenLinkSchem
|
|
|
4
4
|
export { GapAnalysisSchema, GapSchema, NeutralScenarioSchema, GeneratedTestSchema, TestStepSchema, FrameworkRecommendationSchema, type GapAnalysis, type Gap, type NeutralScenario, type GeneratedTest, type TestStep, type FrameworkRecommendation, } from './gap-analysis.schema.js';
|
|
5
5
|
export { CostIntelligenceSchema, LlmUsageRecordSchema, LlmDataQualitySchema, LlmOperationTypeSchema, RepeatedAiPatternSchema, DeterministicMaturitySchema, type CostIntelligence, type LlmUsageRecord, type LlmDataQuality, type LlmOperationType, type RepeatedAiPattern, type DeterministicMaturity, } from './cost-intelligence.schema.js';
|
|
6
6
|
export { RepoAnalysisSchema, FrameworkDetectionSchema, DetectedFrameworkPrimarySchema, FrameworkDetectionConfidenceSchema, TestFrameworkDetectedSchema, type RepoAnalysis, type FrameworkDetectionResult, type DetectedFrameworkPrimary, } from './repo-analysis.schema.js';
|
|
7
|
-
export { AutomationMaturitySchema, AutomationMaturityDimensionSchema, type AutomationMaturity, type AutomationMaturityDimension, } from './automation-maturity.schema.js';
|
|
7
|
+
export { AutomationMaturitySchema, AutomationMaturityDimensionSchema, AutomationMaturityApplicabilitySchema, type AutomationMaturity, type AutomationMaturityDimension, type AutomationMaturityApplicability, } from './automation-maturity.schema.js';
|
|
8
8
|
export { PublicSurfaceSchema, PublicSurfaceViolationSchema, PublicSurfaceBrokenLinkSchema, type PublicSurface, type PublicSurfaceViolation, type PublicSurfaceBrokenLink, } from './public-surface.schema.js';
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,gCAAgC,EAChC,gBAAgB,EAChB,kBAAkB,EAClB,0BAA0B,EAC1B,cAAc,EACd,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,QAAQ,EACb,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,sBAAsB,EACtB,KAAK,gBAAgB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,KAAK,GACX,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,6BAA6B,EAC7B,KAAK,WAAW,EAChB,KAAK,GAAG,EACR,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,KAAK,uBAAuB,GAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,EAC3B,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,GAC3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,8BAA8B,EAC9B,kCAAkC,EAClC,2BAA2B,EAC3B,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,GAC9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,wBAAwB,EACxB,iCAAiC,EACjC,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,gCAAgC,EAChC,gBAAgB,EAChB,kBAAkB,EAClB,0BAA0B,EAC1B,cAAc,EACd,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,QAAQ,EACb,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,sBAAsB,EACtB,KAAK,gBAAgB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,KAAK,GACX,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,6BAA6B,EAC7B,KAAK,WAAW,EAChB,KAAK,GAAG,EACR,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,KAAK,uBAAuB,GAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,EAC3B,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,GAC3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,8BAA8B,EAC9B,kCAAkC,EAClC,2BAA2B,EAC3B,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,GAC9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,wBAAwB,EACxB,iCAAiC,EACjC,qCAAqC,EACrC,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,+BAA+B,GACrC,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,6BAA6B,EAC7B,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,GAC7B,MAAM,4BAA4B,CAAC"}
|
package/dist/schemas/index.js
CHANGED
|
@@ -4,5 +4,5 @@ export { RouteInventorySchema, RouteSchema, A11yViolationSchema, BrokenLinkSchem
|
|
|
4
4
|
export { GapAnalysisSchema, GapSchema, NeutralScenarioSchema, GeneratedTestSchema, TestStepSchema, FrameworkRecommendationSchema, } from './gap-analysis.schema.js';
|
|
5
5
|
export { CostIntelligenceSchema, LlmUsageRecordSchema, LlmDataQualitySchema, LlmOperationTypeSchema, RepeatedAiPatternSchema, DeterministicMaturitySchema, } from './cost-intelligence.schema.js';
|
|
6
6
|
export { RepoAnalysisSchema, FrameworkDetectionSchema, DetectedFrameworkPrimarySchema, FrameworkDetectionConfidenceSchema, TestFrameworkDetectedSchema, } from './repo-analysis.schema.js';
|
|
7
|
-
export { AutomationMaturitySchema, AutomationMaturityDimensionSchema, } from './automation-maturity.schema.js';
|
|
7
|
+
export { AutomationMaturitySchema, AutomationMaturityDimensionSchema, AutomationMaturityApplicabilitySchema, } from './automation-maturity.schema.js';
|
|
8
8
|
export { PublicSurfaceSchema, PublicSurfaceViolationSchema, PublicSurfaceBrokenLinkSchema, } from './public-surface.schema.js';
|
|
@@ -104,6 +104,7 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
104
104
|
coveredPaths: string[];
|
|
105
105
|
}>, "many">;
|
|
106
106
|
missingTestIds: z.ZodArray<z.ZodString, "many">;
|
|
107
|
+
interactiveTsxFilesScanned: z.ZodOptional<z.ZodNumber>;
|
|
107
108
|
cypressStructure: z.ZodObject<{
|
|
108
109
|
detected: z.ZodBoolean;
|
|
109
110
|
e2eFolder: z.ZodOptional<z.ZodString>;
|
|
@@ -160,20 +161,27 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
160
161
|
weight: z.ZodNumber;
|
|
161
162
|
evidence: z.ZodArray<z.ZodString, "many">;
|
|
162
163
|
recommendations: z.ZodArray<z.ZodString, "many">;
|
|
164
|
+
applicability: z.ZodOptional<z.ZodEnum<["applicable", "not_applicable", "unknown"]>>;
|
|
165
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
163
166
|
}, "strip", z.ZodTypeAny, {
|
|
164
167
|
recommendations: string[];
|
|
165
168
|
dimension: "test-coverage-breadth" | "framework-adoption" | "test-id-hygiene" | "ci-integration" | "auth-test-coverage" | "component-test-ratio";
|
|
166
169
|
score: number;
|
|
167
170
|
weight: number;
|
|
168
171
|
evidence: string[];
|
|
172
|
+
reason?: string | undefined;
|
|
173
|
+
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
169
174
|
}, {
|
|
170
175
|
recommendations: string[];
|
|
171
176
|
dimension: "test-coverage-breadth" | "framework-adoption" | "test-id-hygiene" | "ci-integration" | "auth-test-coverage" | "component-test-ratio";
|
|
172
177
|
score: number;
|
|
173
178
|
weight: number;
|
|
174
179
|
evidence: string[];
|
|
180
|
+
reason?: string | undefined;
|
|
181
|
+
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
175
182
|
}>, "many">;
|
|
176
183
|
topRecommendations: z.ZodArray<z.ZodString, "many">;
|
|
184
|
+
scoreFormula: z.ZodOptional<z.ZodString>;
|
|
177
185
|
}, "strip", z.ZodTypeAny, {
|
|
178
186
|
label: string;
|
|
179
187
|
level: number;
|
|
@@ -186,8 +194,11 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
186
194
|
score: number;
|
|
187
195
|
weight: number;
|
|
188
196
|
evidence: string[];
|
|
197
|
+
reason?: string | undefined;
|
|
198
|
+
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
189
199
|
}[];
|
|
190
200
|
topRecommendations: string[];
|
|
201
|
+
scoreFormula?: string | undefined;
|
|
191
202
|
}, {
|
|
192
203
|
label: string;
|
|
193
204
|
level: number;
|
|
@@ -200,8 +211,11 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
200
211
|
score: number;
|
|
201
212
|
weight: number;
|
|
202
213
|
evidence: string[];
|
|
214
|
+
reason?: string | undefined;
|
|
215
|
+
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
203
216
|
}[];
|
|
204
217
|
topRecommendations: string[];
|
|
218
|
+
scoreFormula?: string | undefined;
|
|
205
219
|
}>>;
|
|
206
220
|
}, "strip", z.ZodTypeAny, {
|
|
207
221
|
scannedAt: string;
|
|
@@ -227,6 +241,7 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
227
241
|
fixturesFolder?: string | undefined;
|
|
228
242
|
supportFolder?: string | undefined;
|
|
229
243
|
};
|
|
244
|
+
interactiveTsxFilesScanned?: number | undefined;
|
|
230
245
|
framework?: {
|
|
231
246
|
confidence: "high" | "medium" | "low";
|
|
232
247
|
evidence: string[];
|
|
@@ -245,8 +260,11 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
245
260
|
score: number;
|
|
246
261
|
weight: number;
|
|
247
262
|
evidence: string[];
|
|
263
|
+
reason?: string | undefined;
|
|
264
|
+
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
248
265
|
}[];
|
|
249
266
|
topRecommendations: string[];
|
|
267
|
+
scoreFormula?: string | undefined;
|
|
250
268
|
} | undefined;
|
|
251
269
|
}, {
|
|
252
270
|
scannedAt: string;
|
|
@@ -272,6 +290,7 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
272
290
|
fixturesFolder?: string | undefined;
|
|
273
291
|
supportFolder?: string | undefined;
|
|
274
292
|
};
|
|
293
|
+
interactiveTsxFilesScanned?: number | undefined;
|
|
275
294
|
framework?: {
|
|
276
295
|
confidence: "high" | "medium" | "low";
|
|
277
296
|
evidence: string[];
|
|
@@ -290,8 +309,11 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
290
309
|
score: number;
|
|
291
310
|
weight: number;
|
|
292
311
|
evidence: string[];
|
|
312
|
+
reason?: string | undefined;
|
|
313
|
+
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
293
314
|
}[];
|
|
294
315
|
topRecommendations: string[];
|
|
316
|
+
scoreFormula?: string | undefined;
|
|
295
317
|
} | undefined;
|
|
296
318
|
}>;
|
|
297
319
|
export type RepoAnalysis = z.infer<typeof RepoAnalysisSchema>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo-analysis.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/repo-analysis.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,8BAA8B,8HAUzC,CAAC;AAEH,eAAO,MAAM,kCAAkC,sCAAoC,CAAC;AAEpF,eAAO,MAAM,2BAA2B,0FAOtC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;EAKnC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AACtF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEhF,eAAO,MAAM,eAAe;;;;;;;;;;;;EAI1B,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;EAIzB,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;EASjC,CAAC;AAEH,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"repo-analysis.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/repo-analysis.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,8BAA8B,8HAUzC,CAAC;AAEH,eAAO,MAAM,kCAAkC,sCAAoC,CAAC;AAEpF,eAAO,MAAM,2BAA2B,0FAOtC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;EAKnC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AACtF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEhF,eAAO,MAAM,eAAe;;;;;;;;;;;;EAI1B,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;EAIzB,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;EASjC,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
|
|
@@ -52,6 +52,7 @@ export const RepoAnalysisSchema = z.object({
|
|
|
52
52
|
routes: z.array(RepoRouteSchema),
|
|
53
53
|
testFiles: z.array(TestFileSchema),
|
|
54
54
|
missingTestIds: z.array(z.string()),
|
|
55
|
+
interactiveTsxFilesScanned: z.number().int().min(0).optional(),
|
|
55
56
|
cypressStructure: CypressStructureSchema,
|
|
56
57
|
framework: FrameworkDetectionSchema.optional(),
|
|
57
58
|
automationMaturity: AutomationMaturitySchema.optional(),
|
package/dist/telemetry/emit.d.ts
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
1
|
import type { TelemetryEvent, TelemetryEventKind, TelemetrySink } from './telemetry.interface.js';
|
|
2
2
|
export declare function emitTelemetry(sink: TelemetrySink | undefined, kind: TelemetryEventKind, sessionId: string, metadata: TelemetryEvent['metadata'], durationMs?: number): void;
|
|
3
|
+
/**
|
|
4
|
+
* Strip the query string and fragment from a URL before emitting it in telemetry.
|
|
5
|
+
*
|
|
6
|
+
* Telemetry must not carry credentials, share tokens, or any other secret-shaped
|
|
7
|
+
* material that callers may embed in query strings (e.g. `?token=...`, `?key=...`).
|
|
8
|
+
* Returns `origin + pathname` only for valid `http:` / `https:` URLs, and additionally
|
|
9
|
+
* strips any `user:pass@` userinfo from the origin.
|
|
10
|
+
*
|
|
11
|
+
* If the input is not a valid `http(s)` URL, this helper returns the literal string
|
|
12
|
+
* `'[redacted-non-url]'` rather than echoing the original input. Two reasons:
|
|
13
|
+
*
|
|
14
|
+
* 1. `new URL(...)` parses many `scheme:rest` shapes that are not real URLs
|
|
15
|
+
* (e.g. `mailto:`, custom `user:pass@host`, `data:`). Those still produce a
|
|
16
|
+
* non-empty `origin + pathname` and would echo the right-hand side back.
|
|
17
|
+
* 2. The exported helper makes no assumption about caller provenance: a non-URL
|
|
18
|
+
* string passed in may itself be secret-shaped (a raw token, a path with
|
|
19
|
+
* embedded credentials, etc.), so the only safe fallback is to discard the
|
|
20
|
+
* value entirely.
|
|
21
|
+
*
|
|
22
|
+
* Telemetry never throws on malformed input.
|
|
23
|
+
*/
|
|
24
|
+
export declare function redactUrlForTelemetry(url: string): string;
|
|
3
25
|
//# sourceMappingURL=emit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/telemetry/emit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAElG,wBAAgB,aAAa,CAC3B,IAAI,EAAE,aAAa,GAAG,SAAS,EAC/B,IAAI,EAAE,kBAAkB,EACxB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,IAAI,CASN"}
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/telemetry/emit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAElG,wBAAgB,aAAa,CAC3B,IAAI,EAAE,aAAa,GAAG,SAAS,EAC/B,IAAI,EAAE,kBAAkB,EACxB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,IAAI,CASN;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAczD"}
|
package/dist/telemetry/emit.js
CHANGED
|
@@ -9,3 +9,40 @@ export function emitTelemetry(sink, kind, sessionId, metadata, durationMs) {
|
|
|
9
9
|
...(durationMs !== undefined && { durationMs }),
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Strip the query string and fragment from a URL before emitting it in telemetry.
|
|
14
|
+
*
|
|
15
|
+
* Telemetry must not carry credentials, share tokens, or any other secret-shaped
|
|
16
|
+
* material that callers may embed in query strings (e.g. `?token=...`, `?key=...`).
|
|
17
|
+
* Returns `origin + pathname` only for valid `http:` / `https:` URLs, and additionally
|
|
18
|
+
* strips any `user:pass@` userinfo from the origin.
|
|
19
|
+
*
|
|
20
|
+
* If the input is not a valid `http(s)` URL, this helper returns the literal string
|
|
21
|
+
* `'[redacted-non-url]'` rather than echoing the original input. Two reasons:
|
|
22
|
+
*
|
|
23
|
+
* 1. `new URL(...)` parses many `scheme:rest` shapes that are not real URLs
|
|
24
|
+
* (e.g. `mailto:`, custom `user:pass@host`, `data:`). Those still produce a
|
|
25
|
+
* non-empty `origin + pathname` and would echo the right-hand side back.
|
|
26
|
+
* 2. The exported helper makes no assumption about caller provenance: a non-URL
|
|
27
|
+
* string passed in may itself be secret-shaped (a raw token, a path with
|
|
28
|
+
* embedded credentials, etc.), so the only safe fallback is to discard the
|
|
29
|
+
* value entirely.
|
|
30
|
+
*
|
|
31
|
+
* Telemetry never throws on malformed input.
|
|
32
|
+
*/
|
|
33
|
+
export function redactUrlForTelemetry(url) {
|
|
34
|
+
let parsed;
|
|
35
|
+
try {
|
|
36
|
+
parsed = new URL(url);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return '[redacted-non-url]';
|
|
40
|
+
}
|
|
41
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
42
|
+
return '[redacted-non-url]';
|
|
43
|
+
}
|
|
44
|
+
// Strip any user:pass@ from the origin. `URL.origin` already omits userinfo,
|
|
45
|
+
// but rebuilding from `protocol + host` makes the intent explicit and removes
|
|
46
|
+
// any chance of credentials leaking through future Node URL changes.
|
|
47
|
+
return `${parsed.protocol}//${parsed.host}${parsed.pathname}`;
|
|
48
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type TelemetryEventKind = 'scan.started' | 'scan.completed' | 'scan.blocked' | 'phase.observe.started' | 'phase.observe.completed' | 'phase.think.started' | 'phase.think.completed' | 'phase.act.started' | 'phase.act.completed' | 'llm.call.started' | 'llm.call.completed' | 'llm.call.failed' | 'gap.detected' | 'auth.detected' | 'repo.scanned';
|
|
1
|
+
export type TelemetryEventKind = 'scan.started' | 'scan.completed' | 'scan.blocked' | 'phase.observe.started' | 'phase.observe.completed' | 'phase.think.started' | 'phase.think.completed' | 'phase.act.started' | 'phase.act.completed' | 'llm.call.started' | 'llm.call.completed' | 'llm.call.failed' | 'gap.detected' | 'auth.detected' | 'auth.storage-state.validated' | 'repo.scanned';
|
|
2
2
|
export interface TelemetryEvent {
|
|
3
3
|
kind: TelemetryEventKind;
|
|
4
4
|
timestamp: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry.interface.d.ts","sourceRoot":"","sources":["../../src/telemetry/telemetry.interface.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC1B,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,uBAAuB,GACvB,yBAAyB,GACzB,qBAAqB,GACrB,uBAAuB,GACvB,mBAAmB,GACnB,qBAAqB,GACrB,kBAAkB,GAClB,oBAAoB,GACpB,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,cAAc,CAAC;AAEnB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;CACnC;AAED,eAAO,MAAM,iBAAiB,EAAE,aAE/B,CAAC"}
|
|
1
|
+
{"version":3,"file":"telemetry.interface.d.ts","sourceRoot":"","sources":["../../src/telemetry/telemetry.interface.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC1B,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,uBAAuB,GACvB,yBAAyB,GACzB,qBAAqB,GACrB,uBAAuB,GACvB,mBAAmB,GACnB,qBAAqB,GACrB,kBAAkB,GAClB,oBAAoB,GACpB,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,8BAA8B,GAC9B,cAAc,CAAC;AAEnB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;CACnC;AAED,eAAO,MAAM,iBAAiB,EAAE,aAE/B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Browser, BrowserContext } from '@playwright/test';
|
|
2
|
+
import type { AuthConfig } from '../schemas/config.schema.js';
|
|
3
|
+
export declare function createAuthenticatedContext(browser: Browser, auth: AuthConfig | undefined, timeoutMs: number): Promise<BrowserContext>;
|
|
4
|
+
//# sourceMappingURL=apply-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-auth.d.ts","sourceRoot":"","sources":["../../src/tools/apply-auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CAsCzB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
export async function createAuthenticatedContext(browser, auth, timeoutMs) {
|
|
3
|
+
if (!auth) {
|
|
4
|
+
return browser.newContext();
|
|
5
|
+
}
|
|
6
|
+
if (auth.type === 'storage-state') {
|
|
7
|
+
const storagePath = resolve(process.cwd(), auth.path);
|
|
8
|
+
return browser.newContext({ storageState: storagePath });
|
|
9
|
+
}
|
|
10
|
+
const context = await browser.newContext();
|
|
11
|
+
const page = await context.newPage();
|
|
12
|
+
try {
|
|
13
|
+
await page.goto(auth.loginUrl, { timeout: timeoutMs, waitUntil: 'domcontentloaded' });
|
|
14
|
+
await page.fill(auth.selectors.username, auth.credentials.username);
|
|
15
|
+
await page.fill(auth.selectors.password, auth.credentials.password);
|
|
16
|
+
await page.click(auth.selectors.submit);
|
|
17
|
+
const urlFragment = auth.successIndicator.urlContains;
|
|
18
|
+
if (urlFragment) {
|
|
19
|
+
await page.waitForURL((url) => url.toString().includes(urlFragment), {
|
|
20
|
+
timeout: timeoutMs,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
const visibleSelector = auth.successIndicator.selectorVisible;
|
|
24
|
+
if (visibleSelector) {
|
|
25
|
+
await page.waitForSelector(visibleSelector, {
|
|
26
|
+
timeout: timeoutMs,
|
|
27
|
+
state: 'visible',
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
await page.close();
|
|
33
|
+
}
|
|
34
|
+
return context;
|
|
35
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Browser, BrowserContext } from '@playwright/test';
|
|
2
|
+
import type { AuthConfig } from '../../schemas/config.schema.js';
|
|
3
|
+
export declare function createAuthenticatedContext(browser: Browser, auth: AuthConfig | undefined, timeoutMs: number): Promise<BrowserContext>;
|
|
4
|
+
//# sourceMappingURL=apply.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/tools/auth/apply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAEjE,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CAsCzB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
export async function createAuthenticatedContext(browser, auth, timeoutMs) {
|
|
3
|
+
if (!auth) {
|
|
4
|
+
return browser.newContext();
|
|
5
|
+
}
|
|
6
|
+
if (auth.type === 'storage-state') {
|
|
7
|
+
const storagePath = resolve(process.cwd(), auth.path);
|
|
8
|
+
return browser.newContext({ storageState: storagePath });
|
|
9
|
+
}
|
|
10
|
+
const context = await browser.newContext();
|
|
11
|
+
const page = await context.newPage();
|
|
12
|
+
try {
|
|
13
|
+
await page.goto(auth.loginUrl, { timeout: timeoutMs, waitUntil: 'domcontentloaded' });
|
|
14
|
+
await page.fill(auth.selectors.username, auth.credentials.username);
|
|
15
|
+
await page.fill(auth.selectors.password, auth.credentials.password);
|
|
16
|
+
await page.click(auth.selectors.submit);
|
|
17
|
+
const urlFragment = auth.successIndicator.urlContains;
|
|
18
|
+
if (urlFragment) {
|
|
19
|
+
await page.waitForURL((url) => url.toString().includes(urlFragment), {
|
|
20
|
+
timeout: timeoutMs,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
const visibleSelector = auth.successIndicator.selectorVisible;
|
|
24
|
+
if (visibleSelector) {
|
|
25
|
+
await page.waitForSelector(visibleSelector, {
|
|
26
|
+
timeout: timeoutMs,
|
|
27
|
+
state: 'visible',
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
await page.close();
|
|
33
|
+
}
|
|
34
|
+
return context;
|
|
35
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Gap } from '../../schemas/gap-analysis.schema.js';
|
|
2
|
+
import type { StorageStateInvalidReason } from './detector.js';
|
|
3
|
+
export declare function buildAuthBlockGap(url: string): Gap;
|
|
4
|
+
export declare function buildStorageStateInvalidGap(input: {
|
|
5
|
+
url: string;
|
|
6
|
+
reasonCode: StorageStateInvalidReason;
|
|
7
|
+
reason: string;
|
|
8
|
+
}): Gap;
|
|
9
|
+
//# sourceMappingURL=block-gap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-gap.d.ts","sourceRoot":"","sources":["../../../src/tools/auth/block-gap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,sCAAsC,CAAC;AAChE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAmB/D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAYlD;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,yBAAyB,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,GAAG,CAqBN"}
|