@qulib/core 0.4.2 → 0.5.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/README.md +135 -8
- package/dist/__tests__/cli-smoke-fixture.d.ts +2 -0
- package/dist/__tests__/cli-smoke-fixture.d.ts.map +1 -0
- package/dist/__tests__/cli-smoke-fixture.js +58 -0
- package/dist/__tests__/fixture-server.d.ts +6 -0
- package/dist/__tests__/fixture-server.d.ts.map +1 -0
- package/dist/__tests__/fixture-server.js +141 -0
- package/dist/analyze.d.ts.map +1 -1
- package/dist/analyze.js +84 -5
- package/dist/cli/auth-login-run.d.ts.map +1 -1
- package/dist/cli/auth-login-run.js +26 -2
- package/dist/cli/index.js +12 -6
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/llm/providers/anthropic.js +1 -1
- package/dist/phases/observe.js +2 -2
- package/dist/phases/think-finalize.d.ts.map +1 -1
- package/dist/phases/think-finalize.js +7 -1
- package/dist/phases/think.js +1 -1
- package/dist/schemas/automation-maturity.schema.d.ts +8 -0
- package/dist/schemas/automation-maturity.schema.d.ts.map +1 -1
- package/dist/schemas/automation-maturity.schema.js +1 -0
- package/dist/schemas/repo-analysis.schema.d.ts +7 -0
- package/dist/schemas/repo-analysis.schema.d.ts.map +1 -1
- 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 +9 -8
- package/dist/tools/auth-detector.d.ts.map +1 -1
- package/dist/tools/auth-detector.js +106 -8
- 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/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 +231 -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.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
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
9
|
export { resolveScanStateBaseDir, resolveReportDir } from './harness/state-manager.js';
|
package/dist/phases/observe.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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
7
|
import { emitTelemetry, redactUrlForTelemetry } from '../telemetry/emit.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"think-finalize.d.ts","sourceRoot":"","sources":["../../src/phases/think-finalize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACnG,OAAO,EAA4C,KAAK,WAAW,EAAwB,MAAM,mCAAmC,CAAC;AAQrI,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,gBAAgB,GAAG,kBAAkB,CAAC,CAAC;AAEtG,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,aAAa,EACrB,SAAS,GAAE,mBAA8C,EACzD,WAAW,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,sBAAsB,GAAG,mBAAmB,GAAG,MAAM,CAAC,GAC9F,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"think-finalize.d.ts","sourceRoot":"","sources":["../../src/phases/think-finalize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACnG,OAAO,EAA4C,KAAK,WAAW,EAAwB,MAAM,mCAAmC,CAAC;AAQrI,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,gBAAgB,GAAG,kBAAkB,CAAC,CAAC;AAEtG,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,aAAa,EACrB,SAAS,GAAE,mBAA8C,EACzD,WAAW,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,sBAAsB,GAAG,mBAAmB,GAAG,MAAM,CAAC,GAC9F,OAAO,CAAC,WAAW,CAAC,CAuLtB"}
|
|
@@ -87,7 +87,13 @@ export async function finalizeGapAnalysisFromDraft(draft, config, artifacts = {
|
|
|
87
87
|
: undefined,
|
|
88
88
|
});
|
|
89
89
|
try {
|
|
90
|
-
|
|
90
|
+
// Claude 4 models wrap JSON in markdown fences despite instructions.
|
|
91
|
+
// Strip ```json ... ``` or ``` ... ``` before parsing.
|
|
92
|
+
const rawText = llmResult.text.trim();
|
|
93
|
+
const stripped = rawText.replace(/^```(?:json)?\s*\n?/i, '').replace(/\n?```\s*$/i, '').trim();
|
|
94
|
+
// Also handle models that embed the array mid-prose — grab first [...] block
|
|
95
|
+
const jsonText = stripped.startsWith('[') ? stripped : (stripped.match(/\[[\s\S]*\]/)?.[0] ?? stripped);
|
|
96
|
+
const parsed = JSON.parse(jsonText);
|
|
91
97
|
const candidates = Array.isArray(parsed) ? parsed : [];
|
|
92
98
|
for (const item of candidates) {
|
|
93
99
|
const validated = NeutralScenarioSchema.safeParse(item);
|
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';
|
|
@@ -27,6 +27,7 @@ export declare const AutomationMaturityDimensionSchema: z.ZodObject<{
|
|
|
27
27
|
recommendations: z.ZodArray<z.ZodString, "many">;
|
|
28
28
|
applicability: z.ZodOptional<z.ZodEnum<["applicable", "not_applicable", "unknown"]>>;
|
|
29
29
|
reason: z.ZodOptional<z.ZodString>;
|
|
30
|
+
guidance: z.ZodOptional<z.ZodString>;
|
|
30
31
|
}, "strip", z.ZodTypeAny, {
|
|
31
32
|
recommendations: string[];
|
|
32
33
|
dimension: "test-coverage-breadth" | "framework-adoption" | "test-id-hygiene" | "ci-integration" | "auth-test-coverage" | "component-test-ratio";
|
|
@@ -35,6 +36,7 @@ export declare const AutomationMaturityDimensionSchema: z.ZodObject<{
|
|
|
35
36
|
evidence: string[];
|
|
36
37
|
reason?: string | undefined;
|
|
37
38
|
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
39
|
+
guidance?: string | undefined;
|
|
38
40
|
}, {
|
|
39
41
|
recommendations: string[];
|
|
40
42
|
dimension: "test-coverage-breadth" | "framework-adoption" | "test-id-hygiene" | "ci-integration" | "auth-test-coverage" | "component-test-ratio";
|
|
@@ -43,6 +45,7 @@ export declare const AutomationMaturityDimensionSchema: z.ZodObject<{
|
|
|
43
45
|
evidence: string[];
|
|
44
46
|
reason?: string | undefined;
|
|
45
47
|
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
48
|
+
guidance?: string | undefined;
|
|
46
49
|
}>;
|
|
47
50
|
export declare const AutomationMaturitySchema: z.ZodObject<{
|
|
48
51
|
computedAt: z.ZodString;
|
|
@@ -58,6 +61,7 @@ export declare const AutomationMaturitySchema: z.ZodObject<{
|
|
|
58
61
|
recommendations: z.ZodArray<z.ZodString, "many">;
|
|
59
62
|
applicability: z.ZodOptional<z.ZodEnum<["applicable", "not_applicable", "unknown"]>>;
|
|
60
63
|
reason: z.ZodOptional<z.ZodString>;
|
|
64
|
+
guidance: z.ZodOptional<z.ZodString>;
|
|
61
65
|
}, "strip", z.ZodTypeAny, {
|
|
62
66
|
recommendations: string[];
|
|
63
67
|
dimension: "test-coverage-breadth" | "framework-adoption" | "test-id-hygiene" | "ci-integration" | "auth-test-coverage" | "component-test-ratio";
|
|
@@ -66,6 +70,7 @@ export declare const AutomationMaturitySchema: z.ZodObject<{
|
|
|
66
70
|
evidence: string[];
|
|
67
71
|
reason?: string | undefined;
|
|
68
72
|
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
73
|
+
guidance?: string | undefined;
|
|
69
74
|
}, {
|
|
70
75
|
recommendations: string[];
|
|
71
76
|
dimension: "test-coverage-breadth" | "framework-adoption" | "test-id-hygiene" | "ci-integration" | "auth-test-coverage" | "component-test-ratio";
|
|
@@ -74,6 +79,7 @@ export declare const AutomationMaturitySchema: z.ZodObject<{
|
|
|
74
79
|
evidence: string[];
|
|
75
80
|
reason?: string | undefined;
|
|
76
81
|
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
82
|
+
guidance?: string | undefined;
|
|
77
83
|
}>, "many">;
|
|
78
84
|
topRecommendations: z.ZodArray<z.ZodString, "many">;
|
|
79
85
|
scoreFormula: z.ZodOptional<z.ZodString>;
|
|
@@ -91,6 +97,7 @@ export declare const AutomationMaturitySchema: z.ZodObject<{
|
|
|
91
97
|
evidence: string[];
|
|
92
98
|
reason?: string | undefined;
|
|
93
99
|
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
100
|
+
guidance?: string | undefined;
|
|
94
101
|
}[];
|
|
95
102
|
topRecommendations: string[];
|
|
96
103
|
scoreFormula?: string | undefined;
|
|
@@ -108,6 +115,7 @@ export declare const AutomationMaturitySchema: z.ZodObject<{
|
|
|
108
115
|
evidence: string[];
|
|
109
116
|
reason?: string | undefined;
|
|
110
117
|
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
118
|
+
guidance?: string | undefined;
|
|
111
119
|
}[];
|
|
112
120
|
topRecommendations: string[];
|
|
113
121
|
scoreFormula?: string | undefined;
|
|
@@ -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,qCAAqC,wDAIhD,CAAC;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iCAAiC
|
|
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;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgB5C,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"}
|
|
@@ -38,6 +38,7 @@ export const AutomationMaturityDimensionSchema = z.object({
|
|
|
38
38
|
recommendations: z.array(z.string()),
|
|
39
39
|
applicability: AutomationMaturityApplicabilitySchema.optional(),
|
|
40
40
|
reason: z.string().optional(),
|
|
41
|
+
guidance: z.string().optional(),
|
|
41
42
|
});
|
|
42
43
|
export const AutomationMaturitySchema = z.object({
|
|
43
44
|
computedAt: z.string().datetime(),
|
|
@@ -163,6 +163,7 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
163
163
|
recommendations: z.ZodArray<z.ZodString, "many">;
|
|
164
164
|
applicability: z.ZodOptional<z.ZodEnum<["applicable", "not_applicable", "unknown"]>>;
|
|
165
165
|
reason: z.ZodOptional<z.ZodString>;
|
|
166
|
+
guidance: z.ZodOptional<z.ZodString>;
|
|
166
167
|
}, "strip", z.ZodTypeAny, {
|
|
167
168
|
recommendations: string[];
|
|
168
169
|
dimension: "test-coverage-breadth" | "framework-adoption" | "test-id-hygiene" | "ci-integration" | "auth-test-coverage" | "component-test-ratio";
|
|
@@ -171,6 +172,7 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
171
172
|
evidence: string[];
|
|
172
173
|
reason?: string | undefined;
|
|
173
174
|
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
175
|
+
guidance?: string | undefined;
|
|
174
176
|
}, {
|
|
175
177
|
recommendations: string[];
|
|
176
178
|
dimension: "test-coverage-breadth" | "framework-adoption" | "test-id-hygiene" | "ci-integration" | "auth-test-coverage" | "component-test-ratio";
|
|
@@ -179,6 +181,7 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
179
181
|
evidence: string[];
|
|
180
182
|
reason?: string | undefined;
|
|
181
183
|
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
184
|
+
guidance?: string | undefined;
|
|
182
185
|
}>, "many">;
|
|
183
186
|
topRecommendations: z.ZodArray<z.ZodString, "many">;
|
|
184
187
|
scoreFormula: z.ZodOptional<z.ZodString>;
|
|
@@ -196,6 +199,7 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
196
199
|
evidence: string[];
|
|
197
200
|
reason?: string | undefined;
|
|
198
201
|
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
202
|
+
guidance?: string | undefined;
|
|
199
203
|
}[];
|
|
200
204
|
topRecommendations: string[];
|
|
201
205
|
scoreFormula?: string | undefined;
|
|
@@ -213,6 +217,7 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
213
217
|
evidence: string[];
|
|
214
218
|
reason?: string | undefined;
|
|
215
219
|
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
220
|
+
guidance?: string | undefined;
|
|
216
221
|
}[];
|
|
217
222
|
topRecommendations: string[];
|
|
218
223
|
scoreFormula?: string | undefined;
|
|
@@ -262,6 +267,7 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
262
267
|
evidence: string[];
|
|
263
268
|
reason?: string | undefined;
|
|
264
269
|
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
270
|
+
guidance?: string | undefined;
|
|
265
271
|
}[];
|
|
266
272
|
topRecommendations: string[];
|
|
267
273
|
scoreFormula?: string | undefined;
|
|
@@ -311,6 +317,7 @@ export declare const RepoAnalysisSchema: z.ZodObject<{
|
|
|
311
317
|
evidence: string[];
|
|
312
318
|
reason?: string | undefined;
|
|
313
319
|
applicability?: "unknown" | "applicable" | "not_applicable" | undefined;
|
|
320
|
+
guidance?: string | undefined;
|
|
314
321
|
}[];
|
|
315
322
|
topRecommendations: string[];
|
|
316
323
|
scoreFormula?: string | undefined;
|
|
@@ -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"}
|
|
@@ -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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
function safeOriginAndPath(url) {
|
|
2
|
+
try {
|
|
3
|
+
const u = new URL(url);
|
|
4
|
+
return `${u.origin}${u.pathname}`;
|
|
5
|
+
}
|
|
6
|
+
catch {
|
|
7
|
+
return url;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function safeHost(url) {
|
|
11
|
+
try {
|
|
12
|
+
return new URL(url).hostname;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return url;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function buildAuthBlockGap(url) {
|
|
19
|
+
const host = safeHost(url);
|
|
20
|
+
const safeUrl = safeOriginAndPath(url);
|
|
21
|
+
return {
|
|
22
|
+
id: 'auth-block',
|
|
23
|
+
path: '/',
|
|
24
|
+
severity: 'critical',
|
|
25
|
+
category: 'coverage',
|
|
26
|
+
reason: `Scan blocked by authentication. No authenticated pages were evaluated for ${host}.`,
|
|
27
|
+
description: 'Scan blocked by authentication. 0 authenticated pages were evaluated.',
|
|
28
|
+
recommendation: `Run \`qulib auth init --base-url ${safeUrl}\` to capture a storage state, then re-run with --auth storage-state.`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function buildStorageStateInvalidGap(input) {
|
|
32
|
+
const host = safeHost(input.url);
|
|
33
|
+
const safeUrl = safeOriginAndPath(input.url);
|
|
34
|
+
const recoveryByCode = {
|
|
35
|
+
'missing-file': `Storage state file was not found. Run \`qulib auth login --base-url ${safeUrl} --out <path>\` (or \`qulib auth init\`) to capture a fresh state, then re-run \`qulib analyze --url ${safeUrl} --auth-storage-state <path>\`.`,
|
|
36
|
+
'unreadable-file': `Storage state file exists but could not be read. Check file permissions, then re-run \`qulib auth login\` if needed.`,
|
|
37
|
+
'invalid-json': `Storage state file is not valid JSON. Run \`qulib auth login --base-url ${safeUrl} --out <path>\` again to regenerate it.`,
|
|
38
|
+
'wrong-origin': `Storage state belongs to a different origin than ${host}. Re-run \`qulib auth login --base-url ${safeUrl}\` against this target and pass the new file to \`qulib analyze\`.`,
|
|
39
|
+
'expired-or-unauthorized': `The session in the storage state has expired or is unauthorized. Run \`qulib auth login --base-url ${safeUrl}\` to capture a fresh state, then re-run \`qulib analyze --url ${safeUrl} --auth-storage-state <path>\`.`,
|
|
40
|
+
'no-auth-cookies': `Storage state file contains no cookies or localStorage entries — it is effectively empty. Run \`qulib auth login --base-url ${safeUrl}\` to capture a real session.`,
|
|
41
|
+
unknown: `Storage state could not be validated. Try \`qulib auth login --base-url ${safeUrl}\` again, and verify the file was saved on the same origin.`,
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
id: 'storage-state-invalid',
|
|
45
|
+
path: '/',
|
|
46
|
+
severity: 'critical',
|
|
47
|
+
category: 'coverage',
|
|
48
|
+
reason: `Authenticated scan could not continue because the provided storage state is invalid for ${host}. Reason: ${input.reasonCode} — ${input.reason}.`,
|
|
49
|
+
description: `Storage state validation failed before crawling. The session was checked against ${host} and rejected with reason code "${input.reasonCode}".`,
|
|
50
|
+
recommendation: recoveryByCode[input.reasonCode],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { OAuthProvider } from './providers.js';
|
|
2
|
+
export interface SerializedProvider {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
patterns: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function loadUserProviders(): OAuthProvider[];
|
|
8
|
+
export declare function addUserProvider(input: {
|
|
9
|
+
id: string;
|
|
10
|
+
label: string;
|
|
11
|
+
pattern: string;
|
|
12
|
+
}): void;
|
|
13
|
+
export declare function removeUserProvider(id: string): boolean;
|
|
14
|
+
export declare function listUserProviders(): SerializedProvider[];
|
|
15
|
+
//# sourceMappingURL=custom-providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-providers.d.ts","sourceRoot":"","sources":["../../../src/tools/auth/custom-providers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,iBAAiB,IAAI,aAAa,EAAE,CAOnD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAc3F;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAStD;AAED,wBAAgB,iBAAiB,IAAI,kBAAkB,EAAE,CAExD"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
const USER_PROVIDERS_PATH = join(homedir(), '.qulib', 'providers.json');
|
|
5
|
+
export function loadUserProviders() {
|
|
6
|
+
const raw = loadSerialized();
|
|
7
|
+
return raw.map((p) => ({
|
|
8
|
+
id: p.id,
|
|
9
|
+
label: p.label,
|
|
10
|
+
patterns: p.patterns.map((src) => new RegExp(src, 'i')),
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
export function addUserProvider(input) {
|
|
14
|
+
const existing = loadSerialized();
|
|
15
|
+
const idx = existing.findIndex((p) => p.id === input.id);
|
|
16
|
+
if (idx >= 0) {
|
|
17
|
+
const p = existing[idx];
|
|
18
|
+
if (!p.patterns.includes(input.pattern)) {
|
|
19
|
+
p.patterns.push(input.pattern);
|
|
20
|
+
}
|
|
21
|
+
p.label = input.label;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
existing.push({ id: input.id, label: input.label, patterns: [input.pattern] });
|
|
25
|
+
}
|
|
26
|
+
ensureDir();
|
|
27
|
+
writeFileSync(USER_PROVIDERS_PATH, JSON.stringify(existing, null, 2), 'utf-8');
|
|
28
|
+
}
|
|
29
|
+
export function removeUserProvider(id) {
|
|
30
|
+
const existing = loadSerialized();
|
|
31
|
+
const filtered = existing.filter((p) => p.id !== id);
|
|
32
|
+
if (filtered.length === existing.length) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
ensureDir();
|
|
36
|
+
writeFileSync(USER_PROVIDERS_PATH, JSON.stringify(filtered, null, 2), 'utf-8');
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
export function listUserProviders() {
|
|
40
|
+
return loadSerialized();
|
|
41
|
+
}
|
|
42
|
+
function loadSerialized() {
|
|
43
|
+
if (!existsSync(USER_PROVIDERS_PATH)) {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const parsed = JSON.parse(readFileSync(USER_PROVIDERS_PATH, 'utf-8'));
|
|
48
|
+
if (!Array.isArray(parsed)) {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
return parsed;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function ensureDir() {
|
|
58
|
+
const dir = dirname(USER_PROVIDERS_PATH);
|
|
59
|
+
if (!existsSync(dir)) {
|
|
60
|
+
mkdirSync(dir, { recursive: true });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Page } from '@playwright/test';
|
|
2
|
+
import type { DetectedAuth } from '../../schemas/config.schema.js';
|
|
3
|
+
import type { AnalyzeProgressSink } from '../../harness/progress-log.js';
|
|
4
|
+
export type StorageStateInvalidReason = 'missing-file' | 'unreadable-file' | 'invalid-json' | 'wrong-origin' | 'expired-or-unauthorized' | 'no-auth-cookies' | 'unknown';
|
|
5
|
+
export interface StorageStateValidationResult {
|
|
6
|
+
valid: boolean;
|
|
7
|
+
reasonCode: StorageStateInvalidReason | 'ok';
|
|
8
|
+
reason: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function evaluateStorageStateValidity(signals: {
|
|
11
|
+
expectedOrigin: string;
|
|
12
|
+
finalUrl: string;
|
|
13
|
+
visiblePasswordCount: number;
|
|
14
|
+
hadUnauthorizedHttp: boolean;
|
|
15
|
+
}): StorageStateValidationResult;
|
|
16
|
+
export declare function preflightStorageStateFile(storagePath: string): Promise<StorageStateValidationResult | null>;
|
|
17
|
+
export declare function waitForReturnToOrigin(page: Page, baseUrl: string, timeoutMs?: number): Promise<{
|
|
18
|
+
returned: boolean;
|
|
19
|
+
finalUrl: string;
|
|
20
|
+
}>;
|
|
21
|
+
export declare function validateStorageState(url: string, storagePath: string, timeoutMs?: number): Promise<StorageStateValidationResult>;
|
|
22
|
+
export declare function detectAuth(url: string, timeoutMs?: number, progress?: AnalyzeProgressSink): Promise<DetectedAuth>;
|
|
23
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../src/tools/auth/detect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAY,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAIzE,MAAM,MAAM,yBAAyB,GACjC,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,cAAc,GACd,yBAAyB,GACzB,iBAAiB,GACjB,SAAS,CAAC;AAEd,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,yBAAyB,GAAG,IAAI,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC;CAChB;AAsQD,wBAAgB,4BAA4B,CAAC,OAAO,EAAE;IACpD,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,OAAO,CAAC;CAC9B,GAAG,4BAA4B,CA6B/B;AAOD,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAgD9C;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,EACf,SAAS,SAAQ,GAChB,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAelD;AAED,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,SAAS,SAAQ,GAChB,OAAO,CAAC,4BAA4B,CAAC,CAyDvC;AAED,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,SAAS,SAAQ,EACjB,QAAQ,CAAC,EAAE,mBAAmB,GAC7B,OAAO,CAAC,YAAY,CAAC,CAqJvB"}
|