@qulib/core 0.2.0 → 0.2.2

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 CHANGED
@@ -8,6 +8,16 @@
8
8
  npm install @qulib/core
9
9
  ```
10
10
 
11
+ ## One-time browser setup
12
+
13
+ Qulib uses Playwright. Install Chromium once on the machine that runs scans:
14
+
15
+ ```bash
16
+ npx playwright install chromium
17
+ ```
18
+
19
+ If browsers are missing, commands fail with a short message pointing you here.
20
+
11
21
  ## Scanning authenticated apps
12
22
 
13
23
  Qulib supports three auth modes: anonymous (default), form-login, and storage-state.
@@ -45,6 +55,20 @@ qulib analyze --url https://app.example.com --auth-storage-state ./qulib-storage
45
55
 
46
56
  The storage state is just a JSON file of cookies and localStorage — keep it private, treat it like a credential.
47
57
 
58
+ ### Multi-path auth exploration (`explore-auth`)
59
+
60
+ For unfamiliar apps (especially enterprise SSO with several buttons), run **`qulib explore-auth --url <url>`** before `analyze`. The JSON lists every detected path (built-in OAuth names like Google/Clever, **heuristic** unknown buttons such as tenant-specific SSO labels, password forms, and magic-link copy) plus **`suggestedAgentBehavior`** for the agent.
61
+
62
+ Unknown SSO buttons include **`unrecognizedButtons`** with a hint. Teach this machine to recognize a label next time:
63
+
64
+ ```bash
65
+ qulib auth providers add --id scholastic-sync --label "Scholastic Sync" --pattern "scholastic sync"
66
+ qulib auth providers list
67
+ qulib auth providers remove --id scholastic-sync
68
+ ```
69
+
70
+ Patterns live in **`~/.qulib/providers.json`** (per user, not in the repo). Built-in public platforms stay in qulib’s curated list; tenant-specific names are never shipped as built-ins.
71
+
48
72
  ### Auth detection
49
73
 
50
74
  To check what auth pattern a site uses before configuring anything:
package/dist/cli/index.js CHANGED
@@ -6,6 +6,7 @@ import { z } from 'zod';
6
6
  import { HarnessConfigSchema } from '../schemas/config.schema.js';
7
7
  import { analyzeApp } from '../analyze.js';
8
8
  import { detectAuth } from '../tools/auth-detector.js';
9
+ import { exploreAuth } from '../tools/auth-explorer.js';
9
10
  const program = new Command();
10
11
  const AnalyzeUrlSchema = z.string().url();
11
12
  const FormLoginCliSchema = z.object({
@@ -166,6 +167,15 @@ program
166
167
  submitSelector: options.submitSelector,
167
168
  });
168
169
  });
170
+ program
171
+ .command('explore-auth')
172
+ .description('Explore all sign-in paths (OAuth, forms, magic link) for agent-driven setup before analyze')
173
+ .requiredOption('--url <url>', 'URL of the app or login page')
174
+ .option('--timeout <ms>', 'Navigation timeout in ms', '20000')
175
+ .action(async (options) => {
176
+ const result = await exploreAuth(options.url, parseInt(options.timeout, 10));
177
+ console.log(JSON.stringify(result, null, 2));
178
+ });
169
179
  program
170
180
  .command('detect-auth')
171
181
  .description('Detect the authentication pattern used by a deployed web app')
@@ -176,6 +186,43 @@ program
176
186
  console.log(JSON.stringify(result, null, 2));
177
187
  });
178
188
  const authCmd = program.command('auth').description('Authentication helpers for scans');
189
+ const providersCmd = authCmd
190
+ .command('providers')
191
+ .description('User-local OAuth/SSO button patterns (~/.qulib/providers.json)');
192
+ providersCmd
193
+ .command('list')
194
+ .description('List user-local providers registered on this machine')
195
+ .action(async () => {
196
+ const { listUserProviders } = await import('../tools/user-providers.js');
197
+ const providers = listUserProviders();
198
+ console.log(JSON.stringify(providers, null, 2));
199
+ });
200
+ providersCmd
201
+ .command('add')
202
+ .description('Register a custom provider pattern (case-insensitive regex source)')
203
+ .requiredOption('--id <id>', 'Stable id (kebab-case), e.g. scholastic-sync')
204
+ .requiredOption('--label <label>', 'Human-readable label')
205
+ .requiredOption('--pattern <regex>', 'Regex source, e.g. scholastic sync')
206
+ .action(async (opts) => {
207
+ try {
208
+ new RegExp(opts.pattern, 'i');
209
+ }
210
+ catch {
211
+ throw new Error(`Invalid regex pattern: ${opts.pattern}`);
212
+ }
213
+ const { addUserProvider } = await import('../tools/user-providers.js');
214
+ addUserProvider({ id: opts.id, label: opts.label, pattern: opts.pattern });
215
+ console.log(`[qulib] Added provider "${opts.label}" (id: ${opts.id}) to ~/.qulib/providers.json`);
216
+ });
217
+ providersCmd
218
+ .command('remove')
219
+ .description('Remove a user-local provider by id')
220
+ .requiredOption('--id <id>', 'Provider id to remove')
221
+ .action(async (opts) => {
222
+ const { removeUserProvider } = await import('../tools/user-providers.js');
223
+ const removed = removeUserProvider(opts.id);
224
+ console.log(removed ? `[qulib] Removed "${opts.id}"` : `[qulib] No provider with id "${opts.id}" found`);
225
+ });
179
226
  authCmd
180
227
  .command('init')
181
228
  .description('Open a browser, let the user log in manually, save the storage state to a file for reuse')
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export { analyzeApp } from './analyze.js';
2
2
  export { detectAuth } from './tools/auth-detector.js';
3
+ export { exploreAuth } from './tools/auth-explorer.js';
4
+ export { addUserProvider, removeUserProvider, listUserProviders } from './tools/user-providers.js';
3
5
  export type { AnalyzeOptions, AnalyzeResult } from './analyze.js';
4
- export type { HarnessConfig, AuthConfig, RouteInventory, GapAnalysis, RepoAnalysis, DetectedAuth, } from './schemas/index.js';
6
+ export type { HarnessConfig, AuthConfig, RouteInventory, GapAnalysis, RepoAnalysis, DetectedAuth, AuthExploration, AuthPath, AuthPathRequirements, } from './schemas/index.js';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -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,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClE,YAAY,EACV,aAAa,EACb,UAAU,EACV,cAAc,EACd,WAAW,EACX,YAAY,EACZ,YAAY,GACb,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,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnG,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClE,YAAY,EACV,aAAa,EACb,UAAU,EACV,cAAc,EACd,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,oBAAoB,GACrB,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,4 @@
1
1
  export { analyzeApp } from './analyze.js';
2
2
  export { detectAuth } from './tools/auth-detector.js';
3
+ export { exploreAuth } from './tools/auth-explorer.js';
4
+ export { addUserProvider, removeUserProvider, listUserProviders } from './tools/user-providers.js';
@@ -384,5 +384,362 @@ export declare const DetectedAuthSchema: z.ZodObject<{
384
384
  recommendation: string;
385
385
  }>;
386
386
  export type DetectedAuth = z.infer<typeof DetectedAuthSchema>;
387
+ export declare const AuthPathRequirementsSchema: z.ZodDiscriminatedUnion<"method", [z.ZodObject<{
388
+ method: z.ZodLiteral<"storage-state">;
389
+ instruction: z.ZodString;
390
+ }, "strip", z.ZodTypeAny, {
391
+ method: "storage-state";
392
+ instruction: string;
393
+ }, {
394
+ method: "storage-state";
395
+ instruction: string;
396
+ }>, z.ZodObject<{
397
+ method: z.ZodLiteral<"credentials">;
398
+ fields: z.ZodArray<z.ZodObject<{
399
+ name: z.ZodString;
400
+ label: z.ZodString;
401
+ type: z.ZodEnum<["text", "password", "email", "select", "checkbox"]>;
402
+ observedOptions: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
403
+ }, "strip", z.ZodTypeAny, {
404
+ type: "password" | "text" | "email" | "select" | "checkbox";
405
+ name: string;
406
+ label: string;
407
+ observedOptions: string[];
408
+ }, {
409
+ type: "password" | "text" | "email" | "select" | "checkbox";
410
+ name: string;
411
+ label: string;
412
+ observedOptions?: string[] | undefined;
413
+ }>, "many">;
414
+ }, "strip", z.ZodTypeAny, {
415
+ method: "credentials";
416
+ fields: {
417
+ type: "password" | "text" | "email" | "select" | "checkbox";
418
+ name: string;
419
+ label: string;
420
+ observedOptions: string[];
421
+ }[];
422
+ }, {
423
+ method: "credentials";
424
+ fields: {
425
+ type: "password" | "text" | "email" | "select" | "checkbox";
426
+ name: string;
427
+ label: string;
428
+ observedOptions?: string[] | undefined;
429
+ }[];
430
+ }>, z.ZodObject<{
431
+ method: z.ZodLiteral<"unknown">;
432
+ instruction: z.ZodString;
433
+ }, "strip", z.ZodTypeAny, {
434
+ method: "unknown";
435
+ instruction: string;
436
+ }, {
437
+ method: "unknown";
438
+ instruction: string;
439
+ }>]>;
440
+ export declare const AuthPathSchema: z.ZodObject<{
441
+ id: z.ZodString;
442
+ label: z.ZodString;
443
+ type: z.ZodEnum<["oauth", "oauth-unknown", "form-login", "form-multi", "magic-link", "unknown"]>;
444
+ provider: z.ZodNullable<z.ZodString>;
445
+ source: z.ZodEnum<["built-in", "user-local", "heuristic"]>;
446
+ automatable: z.ZodBoolean;
447
+ confidence: z.ZodEnum<["high", "medium", "low"]>;
448
+ requirements: z.ZodDiscriminatedUnion<"method", [z.ZodObject<{
449
+ method: z.ZodLiteral<"storage-state">;
450
+ instruction: z.ZodString;
451
+ }, "strip", z.ZodTypeAny, {
452
+ method: "storage-state";
453
+ instruction: string;
454
+ }, {
455
+ method: "storage-state";
456
+ instruction: string;
457
+ }>, z.ZodObject<{
458
+ method: z.ZodLiteral<"credentials">;
459
+ fields: z.ZodArray<z.ZodObject<{
460
+ name: z.ZodString;
461
+ label: z.ZodString;
462
+ type: z.ZodEnum<["text", "password", "email", "select", "checkbox"]>;
463
+ observedOptions: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
464
+ }, "strip", z.ZodTypeAny, {
465
+ type: "password" | "text" | "email" | "select" | "checkbox";
466
+ name: string;
467
+ label: string;
468
+ observedOptions: string[];
469
+ }, {
470
+ type: "password" | "text" | "email" | "select" | "checkbox";
471
+ name: string;
472
+ label: string;
473
+ observedOptions?: string[] | undefined;
474
+ }>, "many">;
475
+ }, "strip", z.ZodTypeAny, {
476
+ method: "credentials";
477
+ fields: {
478
+ type: "password" | "text" | "email" | "select" | "checkbox";
479
+ name: string;
480
+ label: string;
481
+ observedOptions: string[];
482
+ }[];
483
+ }, {
484
+ method: "credentials";
485
+ fields: {
486
+ type: "password" | "text" | "email" | "select" | "checkbox";
487
+ name: string;
488
+ label: string;
489
+ observedOptions?: string[] | undefined;
490
+ }[];
491
+ }>, z.ZodObject<{
492
+ method: z.ZodLiteral<"unknown">;
493
+ instruction: z.ZodString;
494
+ }, "strip", z.ZodTypeAny, {
495
+ method: "unknown";
496
+ instruction: string;
497
+ }, {
498
+ method: "unknown";
499
+ instruction: string;
500
+ }>]>;
501
+ }, "strip", z.ZodTypeAny, {
502
+ type: "unknown" | "form-login" | "oauth" | "magic-link" | "oauth-unknown" | "form-multi";
503
+ provider: string | null;
504
+ label: string;
505
+ id: string;
506
+ source: "built-in" | "user-local" | "heuristic";
507
+ automatable: boolean;
508
+ confidence: "high" | "medium" | "low";
509
+ requirements: {
510
+ method: "storage-state";
511
+ instruction: string;
512
+ } | {
513
+ method: "credentials";
514
+ fields: {
515
+ type: "password" | "text" | "email" | "select" | "checkbox";
516
+ name: string;
517
+ label: string;
518
+ observedOptions: string[];
519
+ }[];
520
+ } | {
521
+ method: "unknown";
522
+ instruction: string;
523
+ };
524
+ }, {
525
+ type: "unknown" | "form-login" | "oauth" | "magic-link" | "oauth-unknown" | "form-multi";
526
+ provider: string | null;
527
+ label: string;
528
+ id: string;
529
+ source: "built-in" | "user-local" | "heuristic";
530
+ automatable: boolean;
531
+ confidence: "high" | "medium" | "low";
532
+ requirements: {
533
+ method: "storage-state";
534
+ instruction: string;
535
+ } | {
536
+ method: "credentials";
537
+ fields: {
538
+ type: "password" | "text" | "email" | "select" | "checkbox";
539
+ name: string;
540
+ label: string;
541
+ observedOptions?: string[] | undefined;
542
+ }[];
543
+ } | {
544
+ method: "unknown";
545
+ instruction: string;
546
+ };
547
+ }>;
548
+ export declare const AuthExplorationSchema: z.ZodObject<{
549
+ url: z.ZodString;
550
+ authRequired: z.ZodBoolean;
551
+ authScope: z.ZodEnum<["site-wide", "section-only", "optional", "none"]>;
552
+ authPaths: z.ZodArray<z.ZodObject<{
553
+ id: z.ZodString;
554
+ label: z.ZodString;
555
+ type: z.ZodEnum<["oauth", "oauth-unknown", "form-login", "form-multi", "magic-link", "unknown"]>;
556
+ provider: z.ZodNullable<z.ZodString>;
557
+ source: z.ZodEnum<["built-in", "user-local", "heuristic"]>;
558
+ automatable: z.ZodBoolean;
559
+ confidence: z.ZodEnum<["high", "medium", "low"]>;
560
+ requirements: z.ZodDiscriminatedUnion<"method", [z.ZodObject<{
561
+ method: z.ZodLiteral<"storage-state">;
562
+ instruction: z.ZodString;
563
+ }, "strip", z.ZodTypeAny, {
564
+ method: "storage-state";
565
+ instruction: string;
566
+ }, {
567
+ method: "storage-state";
568
+ instruction: string;
569
+ }>, z.ZodObject<{
570
+ method: z.ZodLiteral<"credentials">;
571
+ fields: z.ZodArray<z.ZodObject<{
572
+ name: z.ZodString;
573
+ label: z.ZodString;
574
+ type: z.ZodEnum<["text", "password", "email", "select", "checkbox"]>;
575
+ observedOptions: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
576
+ }, "strip", z.ZodTypeAny, {
577
+ type: "password" | "text" | "email" | "select" | "checkbox";
578
+ name: string;
579
+ label: string;
580
+ observedOptions: string[];
581
+ }, {
582
+ type: "password" | "text" | "email" | "select" | "checkbox";
583
+ name: string;
584
+ label: string;
585
+ observedOptions?: string[] | undefined;
586
+ }>, "many">;
587
+ }, "strip", z.ZodTypeAny, {
588
+ method: "credentials";
589
+ fields: {
590
+ type: "password" | "text" | "email" | "select" | "checkbox";
591
+ name: string;
592
+ label: string;
593
+ observedOptions: string[];
594
+ }[];
595
+ }, {
596
+ method: "credentials";
597
+ fields: {
598
+ type: "password" | "text" | "email" | "select" | "checkbox";
599
+ name: string;
600
+ label: string;
601
+ observedOptions?: string[] | undefined;
602
+ }[];
603
+ }>, z.ZodObject<{
604
+ method: z.ZodLiteral<"unknown">;
605
+ instruction: z.ZodString;
606
+ }, "strip", z.ZodTypeAny, {
607
+ method: "unknown";
608
+ instruction: string;
609
+ }, {
610
+ method: "unknown";
611
+ instruction: string;
612
+ }>]>;
613
+ }, "strip", z.ZodTypeAny, {
614
+ type: "unknown" | "form-login" | "oauth" | "magic-link" | "oauth-unknown" | "form-multi";
615
+ provider: string | null;
616
+ label: string;
617
+ id: string;
618
+ source: "built-in" | "user-local" | "heuristic";
619
+ automatable: boolean;
620
+ confidence: "high" | "medium" | "low";
621
+ requirements: {
622
+ method: "storage-state";
623
+ instruction: string;
624
+ } | {
625
+ method: "credentials";
626
+ fields: {
627
+ type: "password" | "text" | "email" | "select" | "checkbox";
628
+ name: string;
629
+ label: string;
630
+ observedOptions: string[];
631
+ }[];
632
+ } | {
633
+ method: "unknown";
634
+ instruction: string;
635
+ };
636
+ }, {
637
+ type: "unknown" | "form-login" | "oauth" | "magic-link" | "oauth-unknown" | "form-multi";
638
+ provider: string | null;
639
+ label: string;
640
+ id: string;
641
+ source: "built-in" | "user-local" | "heuristic";
642
+ automatable: boolean;
643
+ confidence: "high" | "medium" | "low";
644
+ requirements: {
645
+ method: "storage-state";
646
+ instruction: string;
647
+ } | {
648
+ method: "credentials";
649
+ fields: {
650
+ type: "password" | "text" | "email" | "select" | "checkbox";
651
+ name: string;
652
+ label: string;
653
+ observedOptions?: string[] | undefined;
654
+ }[];
655
+ } | {
656
+ method: "unknown";
657
+ instruction: string;
658
+ };
659
+ }>, "many">;
660
+ observedAt: z.ZodString;
661
+ suggestedAgentBehavior: z.ZodString;
662
+ unrecognizedButtons: z.ZodDefault<z.ZodArray<z.ZodObject<{
663
+ label: z.ZodString;
664
+ hint: z.ZodString;
665
+ }, "strip", z.ZodTypeAny, {
666
+ label: string;
667
+ hint: string;
668
+ }, {
669
+ label: string;
670
+ hint: string;
671
+ }>, "many">>;
672
+ }, "strip", z.ZodTypeAny, {
673
+ url: string;
674
+ authRequired: boolean;
675
+ authScope: "none" | "site-wide" | "section-only" | "optional";
676
+ authPaths: {
677
+ type: "unknown" | "form-login" | "oauth" | "magic-link" | "oauth-unknown" | "form-multi";
678
+ provider: string | null;
679
+ label: string;
680
+ id: string;
681
+ source: "built-in" | "user-local" | "heuristic";
682
+ automatable: boolean;
683
+ confidence: "high" | "medium" | "low";
684
+ requirements: {
685
+ method: "storage-state";
686
+ instruction: string;
687
+ } | {
688
+ method: "credentials";
689
+ fields: {
690
+ type: "password" | "text" | "email" | "select" | "checkbox";
691
+ name: string;
692
+ label: string;
693
+ observedOptions: string[];
694
+ }[];
695
+ } | {
696
+ method: "unknown";
697
+ instruction: string;
698
+ };
699
+ }[];
700
+ observedAt: string;
701
+ suggestedAgentBehavior: string;
702
+ unrecognizedButtons: {
703
+ label: string;
704
+ hint: string;
705
+ }[];
706
+ }, {
707
+ url: string;
708
+ authRequired: boolean;
709
+ authScope: "none" | "site-wide" | "section-only" | "optional";
710
+ authPaths: {
711
+ type: "unknown" | "form-login" | "oauth" | "magic-link" | "oauth-unknown" | "form-multi";
712
+ provider: string | null;
713
+ label: string;
714
+ id: string;
715
+ source: "built-in" | "user-local" | "heuristic";
716
+ automatable: boolean;
717
+ confidence: "high" | "medium" | "low";
718
+ requirements: {
719
+ method: "storage-state";
720
+ instruction: string;
721
+ } | {
722
+ method: "credentials";
723
+ fields: {
724
+ type: "password" | "text" | "email" | "select" | "checkbox";
725
+ name: string;
726
+ label: string;
727
+ observedOptions?: string[] | undefined;
728
+ }[];
729
+ } | {
730
+ method: "unknown";
731
+ instruction: string;
732
+ };
733
+ }[];
734
+ observedAt: string;
735
+ suggestedAgentBehavior: string;
736
+ unrecognizedButtons?: {
737
+ label: string;
738
+ hint: string;
739
+ }[] | undefined;
740
+ }>;
741
+ export type AuthPathRequirements = z.infer<typeof AuthPathRequirementsSchema>;
742
+ export type AuthPath = z.infer<typeof AuthPathSchema>;
743
+ export type AuthExploration = z.infer<typeof AuthExplorationSchema>;
387
744
  export {};
388
745
  //# sourceMappingURL=config.schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/config.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,SAAS,CAAC;AACpD,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,aAAa,GAAG,mBAAmB,GAAG,KAAK,GAAG,eAAe,CAAC;AAEvG,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBvB,CAAC;AAEH,QAAA,MAAM,sBAAsB;;;;;;;;;EAG1B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAA8E,CAAC;AAE5G,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACtE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC5E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAe9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
1
+ {"version":3,"file":"config.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/config.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,SAAS,CAAC;AACpD,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,aAAa,GAAG,mBAAmB,GAAG,KAAK,GAAG,eAAe,CAAC;AAEvG,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBvB,CAAC;AAEH,QAAA,MAAM,sBAAsB;;;;;;;;;EAG1B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAA8E,CAAC;AAE5G,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACtE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC5E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAe9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAcrC,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASzB,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAehC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC9E,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
@@ -55,3 +55,40 @@ export const DetectedAuthSchema = z.object({
55
55
  })),
56
56
  recommendation: z.string(),
57
57
  });
58
+ export const AuthPathRequirementsSchema = z.discriminatedUnion('method', [
59
+ z.object({ method: z.literal('storage-state'), instruction: z.string() }),
60
+ z.object({
61
+ method: z.literal('credentials'),
62
+ fields: z.array(z.object({
63
+ name: z.string(),
64
+ label: z.string(),
65
+ type: z.enum(['text', 'password', 'email', 'select', 'checkbox']),
66
+ observedOptions: z.array(z.string()).default([]),
67
+ })),
68
+ }),
69
+ z.object({ method: z.literal('unknown'), instruction: z.string() }),
70
+ ]);
71
+ export const AuthPathSchema = z.object({
72
+ id: z.string(),
73
+ label: z.string(),
74
+ type: z.enum(['oauth', 'oauth-unknown', 'form-login', 'form-multi', 'magic-link', 'unknown']),
75
+ provider: z.string().nullable(),
76
+ source: z.enum(['built-in', 'user-local', 'heuristic']),
77
+ automatable: z.boolean(),
78
+ confidence: z.enum(['high', 'medium', 'low']),
79
+ requirements: AuthPathRequirementsSchema,
80
+ });
81
+ export const AuthExplorationSchema = z.object({
82
+ url: z.string(),
83
+ authRequired: z.boolean(),
84
+ authScope: z.enum(['site-wide', 'section-only', 'optional', 'none']),
85
+ authPaths: z.array(AuthPathSchema),
86
+ observedAt: z.string(),
87
+ suggestedAgentBehavior: z.string(),
88
+ unrecognizedButtons: z
89
+ .array(z.object({
90
+ label: z.string(),
91
+ hint: z.string(),
92
+ }))
93
+ .default([]),
94
+ });