unbrowse 2.12.7 → 3.0.1

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.
Files changed (93) hide show
  1. package/README.md +127 -10
  2. package/SKILL.md +791 -0
  3. package/bin/unbrowse-update-hint.mjs +22 -0
  4. package/bin/unbrowse-wrapper.mjs +107 -0
  5. package/bin/unbrowse.js +37 -0
  6. package/dist/cli.js +3387 -500
  7. package/dist/mcp.js +1983 -0
  8. package/package.json +15 -6
  9. package/runtime-src/agent-outcome.ts +166 -0
  10. package/runtime-src/analytics-session.ts +55 -0
  11. package/runtime-src/api/browse-index.ts +317 -0
  12. package/runtime-src/api/browse-session.ts +572 -0
  13. package/runtime-src/api/browse-submit-prereqs.ts +48 -0
  14. package/runtime-src/api/browse-submit.ts +1184 -0
  15. package/runtime-src/api/routes.ts +1357 -32
  16. package/runtime-src/auth/index.ts +296 -33
  17. package/runtime-src/auth/runtime.ts +116 -0
  18. package/runtime-src/browser/index.ts +659 -0
  19. package/runtime-src/browser/types.ts +41 -0
  20. package/runtime-src/build-info.generated.ts +6 -0
  21. package/runtime-src/capture/index.ts +692 -130
  22. package/runtime-src/capture/prefetch.ts +95 -0
  23. package/runtime-src/capture/rsc.ts +45 -0
  24. package/runtime-src/cli/shortcuts.ts +273 -0
  25. package/runtime-src/cli.ts +1181 -383
  26. package/runtime-src/client/graph-client.ts +100 -0
  27. package/runtime-src/client/index.ts +711 -32
  28. package/runtime-src/execution/index.ts +706 -147
  29. package/runtime-src/execution/robots.ts +167 -0
  30. package/runtime-src/execution/search-forms.ts +188 -0
  31. package/runtime-src/foundry/publish-bundle.ts +392 -0
  32. package/runtime-src/graph/index.ts +707 -19
  33. package/runtime-src/graph/planner.ts +411 -0
  34. package/runtime-src/graph/session.ts +294 -0
  35. package/runtime-src/graph/trace-store.ts +136 -0
  36. package/runtime-src/indexer/index.ts +465 -0
  37. package/runtime-src/intent-match.ts +27 -27
  38. package/runtime-src/kuri/client.ts +1227 -244
  39. package/runtime-src/mcp.ts +1698 -0
  40. package/runtime-src/orchestrator/browser-agent.ts +374 -0
  41. package/runtime-src/orchestrator/dag-advisor.ts +59 -0
  42. package/runtime-src/orchestrator/dag-feedback.ts +257 -0
  43. package/runtime-src/orchestrator/first-pass-action.ts +403 -0
  44. package/runtime-src/orchestrator/index.ts +2921 -532
  45. package/runtime-src/orchestrator/passive-publish.ts +187 -0
  46. package/runtime-src/orchestrator/timing-economics.ts +80 -0
  47. package/runtime-src/payments/cascade.ts +137 -0
  48. package/runtime-src/payments/index.ts +270 -0
  49. package/runtime-src/payments/wallet.ts +98 -0
  50. package/runtime-src/publish/review-context.ts +93 -0
  51. package/runtime-src/publish/sanitize.ts +197 -0
  52. package/runtime-src/publish/schema-review.ts +192 -0
  53. package/runtime-src/publish-admission.ts +388 -0
  54. package/runtime-src/reverse-engineer/description-prompt.ts +213 -0
  55. package/runtime-src/reverse-engineer/index.ts +361 -45
  56. package/runtime-src/router.ts +17 -0
  57. package/runtime-src/routing-telemetry.ts +395 -0
  58. package/runtime-src/runtime/browser-access.ts +11 -0
  59. package/runtime-src/runtime/browser-auth.ts +12 -0
  60. package/runtime-src/runtime/browser-host.ts +48 -0
  61. package/runtime-src/runtime/lifecycle.ts +17 -0
  62. package/runtime-src/runtime/local-server.ts +227 -22
  63. package/runtime-src/runtime/paths.ts +13 -5
  64. package/runtime-src/runtime/setup.ts +56 -1
  65. package/runtime-src/runtime/supervisor.ts +69 -0
  66. package/runtime-src/runtime/update-hints.ts +351 -0
  67. package/runtime-src/server.ts +11 -11
  68. package/runtime-src/settings.ts +221 -0
  69. package/runtime-src/single-binary.ts +143 -0
  70. package/runtime-src/site-policy.ts +54 -0
  71. package/runtime-src/stale-cleanup-runner.ts +144 -0
  72. package/runtime-src/stale-cleanup.ts +133 -0
  73. package/runtime-src/telemetry-attribution.ts +120 -0
  74. package/runtime-src/telemetry.ts +253 -0
  75. package/runtime-src/types/skill.ts +581 -2
  76. package/runtime-src/verification/auth-gate.ts +8 -0
  77. package/runtime-src/verification/candidates.ts +27 -0
  78. package/runtime-src/verification/index.ts +35 -14
  79. package/runtime-src/verification/matrix.ts +30 -0
  80. package/runtime-src/version.ts +106 -10
  81. package/runtime-src/workflow/artifact.ts +161 -0
  82. package/runtime-src/workflow/compile.ts +808 -0
  83. package/runtime-src/workflow/publish.ts +225 -0
  84. package/runtime-src/workflow/runtime.ts +213 -0
  85. package/scripts/postinstall.mjs +120 -0
  86. package/scripts/release-assets.mjs +28 -0
  87. package/scripts/verify-release-assets.mjs +43 -0
  88. package/vendor/kuri/darwin-arm64/kuri +0 -0
  89. package/vendor/kuri/darwin-x64/kuri +0 -0
  90. package/vendor/kuri/linux-arm64/kuri +0 -0
  91. package/vendor/kuri/linux-x64/kuri +0 -0
  92. package/vendor/kuri/manifest.json +24 -0
  93. package/runtime-src/transform/schema-hints.ts +0 -358
@@ -2,6 +2,40 @@ export type SkillLifecycle = "active" | "deprecated" | "disabled";
2
2
  export type OwnerType = "agent" | "marketplace" | "user";
3
3
  export type Idempotency = "safe" | "unsafe";
4
4
  export type VerificationStatus = "verified" | "unverified" | "failed" | "pending" | "disabled";
5
+ export type GraphVisibility = "shadow" | "public";
6
+
7
+ export interface SkillSubmissionProvenance {
8
+ submitted_at: string;
9
+ submitter_agent_id?: string;
10
+ client_trace_version?: string;
11
+ client_code_hash?: string;
12
+ client_git_sha?: string;
13
+ transport?: string;
14
+ release_manifest_version?: string;
15
+ release_manifest_verified?: boolean;
16
+ release_manifest_reason?: string;
17
+ }
18
+
19
+ export interface SkillTrustMetadata {
20
+ graph_visibility: GraphVisibility;
21
+ promotion_reason: string;
22
+ submission_count: number;
23
+ unique_submitters: number;
24
+ verified_release_submissions: number;
25
+ unique_verified_submitters: number;
26
+ verified_ratio: number;
27
+ last_submission_at: string;
28
+ }
29
+
30
+ export interface EndpointCorroboration {
31
+ submission_count: number;
32
+ unique_submitters: number;
33
+ verified_release_submissions: number;
34
+ unique_verified_submitters: number;
35
+ last_submission_at: string;
36
+ submitter_agent_ids?: string[];
37
+ verified_release_submitter_ids?: string[];
38
+ }
5
39
 
6
40
  export interface AuthProfile {
7
41
  oauth_type?: string;
@@ -50,6 +84,7 @@ export interface WsMessage {
50
84
 
51
85
  export interface OperationBinding {
52
86
  key: string;
87
+ description?: string;
53
88
  type?: string;
54
89
  semantic_type?: string;
55
90
  required?: boolean;
@@ -62,6 +97,9 @@ export interface EndpointSemanticDescriptor {
62
97
  resource_kind: string;
63
98
  description_in?: string;
64
99
  description_out?: string;
100
+ description_source?: "agent" | "auto" | "missing";
101
+ description_needs_review?: boolean;
102
+ description_warning?: string;
65
103
  response_summary?: string;
66
104
  example_request?: unknown;
67
105
  example_response_compact?: unknown;
@@ -75,6 +113,23 @@ export interface EndpointSemanticDescriptor {
75
113
  auth_required?: boolean;
76
114
  }
77
115
 
116
+ export interface EndpointPolicyDescriptor {
117
+ requires_third_party_terms_confirmation: boolean;
118
+ policy_domain: string;
119
+ reason: string;
120
+ }
121
+
122
+ export interface EndpointPathBindingCandidate {
123
+ placeholder: string;
124
+ observed_value: string;
125
+ segment_index: number;
126
+ source: "normalized_placeholder" | "file_basename" | "page_hint" | "context_diff" | "segment_pattern";
127
+ placeholder_hint?: string;
128
+ preceding_segment?: string;
129
+ filename_suffix?: string;
130
+ matched_page_hint?: boolean;
131
+ }
132
+
78
133
  export interface EndpointDescriptor {
79
134
  endpoint_id: string;
80
135
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | "WS";
@@ -111,8 +166,23 @@ export interface EndpointDescriptor {
111
166
  /** Learned execution strategy — set after first successful execution.
112
167
  * Skips doomed server-fetch on sites that need browser execution (e.g. LinkedIn). */
113
168
  exec_strategy?: "server" | "trigger-intercept" | "browser";
169
+ /** Server-owned graph visibility. Shadow endpoints are persisted but not indexed. */
170
+ graph_visibility?: GraphVisibility;
171
+ /** Server-owned corroboration counters used for staged promotion. */
172
+ corroboration?: EndpointCorroboration;
114
173
  /** Semantic v2 metadata for endpoint-level retrieval and DAG planning */
115
174
  semantic?: EndpointSemanticDescriptor;
175
+ /** Path template inferred by batch mining (passive captures without a context page URL).
176
+ * Internal annotation — not persisted to the skill manifest. */
177
+ _minedTemplate?: string;
178
+ /** Raw path binding evidence captured before semantic naming rewrites placeholders. */
179
+ _path_binding_candidates?: EndpointPathBindingCandidate[];
180
+ /** Structured search form spec — when present, indicates this endpoint can be driven
181
+ * by filling a DOM form rather than a direct API call. Used by isStructuredSearchForm
182
+ * to gate search-form execution paths. */
183
+ search_form?: import("../execution/search-forms.js").SearchFormSpec;
184
+ /** Optional third-party policy metadata surfaced to callers and enforced at execute time. */
185
+ policy?: EndpointPolicyDescriptor;
116
186
  }
117
187
 
118
188
  export type ExecutionType = "http" | "browser-capture";
@@ -152,7 +222,7 @@ export interface SkillOperationEdge {
152
222
  from_operation_id: string;
153
223
  to_operation_id: string;
154
224
  binding_key: string;
155
- kind: "dependency" | "hint";
225
+ kind: "dependency" | "hint" | "parent_child" | "pagination" | "auth";
156
226
  confidence: number;
157
227
  }
158
228
 
@@ -186,6 +256,49 @@ export interface AgentAvailableOperation {
186
256
  example_response_compact?: unknown;
187
257
  }
188
258
 
259
+ export interface AgentPrefetchOperation {
260
+ operation_id: string;
261
+ endpoint_id: string;
262
+ method: EndpointDescriptor["method"];
263
+ action_kind: string;
264
+ resource_kind: string;
265
+ reason: string;
266
+ binding_key: string;
267
+ edge_kind: SkillOperationEdge["kind"];
268
+ confidence: number;
269
+ }
270
+
271
+ export interface AgentWorkflowDagOperation {
272
+ operation_id: string;
273
+ endpoint_id: string;
274
+ method: EndpointDescriptor["method"];
275
+ action_kind: string;
276
+ resource_kind: string;
277
+ title: string;
278
+ url_template: string;
279
+ description_out?: string;
280
+ requires: string[];
281
+ yields: string[];
282
+ runnable: boolean;
283
+ prefetch_get_operations: AgentPrefetchOperation[];
284
+ }
285
+
286
+ export interface AgentWorkflowDagView {
287
+ skill_id: string;
288
+ intent?: string;
289
+ missing_bindings: string[];
290
+ suggested_next_operation_id?: string;
291
+ operations: AgentWorkflowDagOperation[];
292
+ edges: Array<{
293
+ edge_id: string;
294
+ from_operation_id: string;
295
+ to_operation_id: string;
296
+ binding_key: string;
297
+ kind: SkillOperationEdge["kind"];
298
+ confidence: number;
299
+ }>;
300
+ }
301
+
189
302
  export interface AgentSkillChunkView {
190
303
  skill_id: string;
191
304
  intent?: string;
@@ -216,8 +329,30 @@ export interface SkillManifest {
216
329
  discovery_cost?: DiscoveryCost;
217
330
  /** Intent strings that contributed endpoints to this domain-level skill */
218
331
  intents?: string[];
332
+ /** Agent ID of the indexer who published this skill - used for Tier 1 attribution */
333
+ indexer_id?: string;
334
+ /** All agents who contributed endpoints to this skill */
335
+ contributors?: Array<{
336
+ agent_id: string;
337
+ wallet_address?: string;
338
+ endpoints_contributed: number;
339
+ cumulative_delta: number;
340
+ share: number;
341
+ first_contributed_at: string;
342
+ last_contributed_at: string;
343
+ }>;
344
+ /** Cascade Split address — x402 payments route here for multi-contributor skills */
345
+ split_config?: string;
219
346
  /** Graph v2: endpoint dependencies, semantic summaries, and dynamic availability */
220
347
  operation_graph?: SkillOperationGraph;
348
+ /** Price in USD per execution; undefined or 0 = free */
349
+ base_price_usd?: number;
350
+ /** Whether the skill owner has opted into compensation */
351
+ owner_compensation_opt_in?: boolean;
352
+ /** Server-owned submission provenance for staged promotion and abuse analysis. */
353
+ provenance_events?: SkillSubmissionProvenance[];
354
+ /** Server-owned graph trust state. */
355
+ trust?: SkillTrustMetadata;
221
356
  }
222
357
 
223
358
  export interface ExecutionTrace {
@@ -227,6 +362,13 @@ export interface ExecutionTrace {
227
362
  started_at: string;
228
363
  completed_at: string;
229
364
  success: boolean;
365
+ session_id?: string;
366
+ step_index?: number;
367
+ state_hash?: string;
368
+ candidate_count?: number;
369
+ selected_operation_id?: string;
370
+ reachable_operation_count?: number;
371
+ api_call_count?: number;
230
372
  status_code?: number;
231
373
  error?: string;
232
374
  result?: unknown;
@@ -256,6 +398,8 @@ export interface DiscoveryCandidate {
256
398
 
257
399
  export interface ResponseSchema {
258
400
  type: string;
401
+ description?: string;
402
+ enum_values?: Array<string | number | boolean>;
259
403
  properties?: Record<string, ResponseSchema>;
260
404
  items?: ResponseSchema;
261
405
  required?: string[];
@@ -292,6 +436,8 @@ export interface EndpointStats {
292
436
 
293
437
  export interface ExecutionOptions {
294
438
  confirm_unsafe?: boolean;
439
+ /** Explicit user confirmation for domains/actions that may violate third-party site terms. */
440
+ confirm_third_party_terms?: boolean;
295
441
  dry_run?: boolean;
296
442
  /** User's request intent — used for endpoint ranking instead of skill.intent_signature */
297
443
  intent?: string;
@@ -301,6 +447,10 @@ export interface ExecutionOptions {
301
447
  force_capture?: boolean;
302
448
  /** Request/client namespace for isolating local server state across concurrent CLI users */
303
449
  client_scope?: string;
450
+ /** Set only when the caller has already completed payment verification for a paid run */
451
+ payment_verified?: boolean;
452
+ /** Skip robots.txt compliance check (e.g. for testing or trusted internal domains) */
453
+ skip_robots_check?: boolean;
304
454
  }
305
455
 
306
456
  export interface ValidationResult {
@@ -315,7 +465,7 @@ export interface OrchestrationTiming {
315
465
  get_skill_ms: number;
316
466
  execute_ms: number;
317
467
  total_ms: number;
318
- source: "marketplace" | "live-capture" | "dom-fallback" | "route-cache";
468
+ source: "marketplace" | "live-capture" | "dom-fallback" | "route-cache" | "browser-action";
319
469
  cache_hit: boolean;
320
470
  candidates_found: number;
321
471
  candidates_tried: number;
@@ -328,6 +478,435 @@ export interface OrchestrationTiming {
328
478
  time_saved_pct: number;
329
479
  /** Percentage token saved vs estimated full-page browsing cost */
330
480
  tokens_saved_pct: number;
481
+ /** Real capture baseline in ms when known */
482
+ baseline_total_ms?: number;
483
+ /** Actual runtime latency in ms for this resolve */
484
+ actual_total_ms?: number;
485
+ /** Real time saved in ms when baseline is known */
486
+ time_saved_ms?: number;
487
+ /** Real baseline cost in micro-cents when known */
488
+ baseline_cost_uc?: number;
489
+ /** Real amount charged for this run in micro-cents */
490
+ actual_cost_uc?: number;
491
+ /** Real cost saved in micro-cents when baseline is known */
492
+ cost_saved_uc?: number;
493
+ /** Tier 3 search fee charged during this resolve */
494
+ paid_search_uc?: number;
495
+ /** Paid execution fee charged during this resolve */
496
+ paid_execution_uc?: number;
331
497
  /** Code version hash + git SHA — tracks which code produced this timing */
332
498
  trace_version?: string;
333
499
  }
500
+
501
+ export type RoutingRunType = "single_shot" | "long_running";
502
+ export type RoutingTelemetrySource =
503
+ | "route-cache"
504
+ | "marketplace"
505
+ | "graph"
506
+ | "live-capture"
507
+ | "browser-action"
508
+ | "defer";
509
+ export type RoutingSessionOutcome = "success" | "failure" | "defer" | "abandon";
510
+
511
+ export interface RoutingContextBuckets {
512
+ role: "general" | "developer" | "researcher" | "analyst" | "operator" | "unknown";
513
+ cost_sensitivity: "low" | "medium" | "high" | "unknown";
514
+ latency_sensitivity: "low" | "medium" | "high" | "unknown";
515
+ output_preference: "structured" | "raw" | "mixed" | "unknown";
516
+ task_horizon: "short" | "long" | "unknown";
517
+ has_prior_history: boolean;
518
+ }
519
+
520
+ export interface RoutingCandidateSnapshot {
521
+ candidate_id: string;
522
+ rank: number;
523
+ skill_id?: string;
524
+ endpoint_id: string;
525
+ operation_id?: string;
526
+ route_fingerprint: string;
527
+ score: number;
528
+ chosen: boolean;
529
+ reachable: boolean;
530
+ rejection_reason?: string;
531
+ feature_snapshot: {
532
+ method?: string;
533
+ has_response_schema: boolean;
534
+ dom_extraction: boolean;
535
+ verification_status?: string;
536
+ reliability_score?: number;
537
+ unsafe_action_score?: number;
538
+ };
539
+ }
540
+
541
+ export interface RoutingTelemetryBaseEvent {
542
+ event_id: string;
543
+ event_type:
544
+ | "routing_session_started"
545
+ | "routing_candidates_ranked"
546
+ | "routing_step_executed"
547
+ | "routing_session_completed";
548
+ session_id: string;
549
+ created_at: string;
550
+ trace_version?: string;
551
+ anonymized_agent_id?: string;
552
+ top_level_intent: string;
553
+ normalized_domains: string[];
554
+ run_type: RoutingRunType;
555
+ }
556
+
557
+ export interface RoutingSessionEvent extends RoutingTelemetryBaseEvent {
558
+ event_type: "routing_session_started";
559
+ context_buckets: RoutingContextBuckets;
560
+ }
561
+
562
+ export interface RoutingCandidateEvent extends RoutingTelemetryBaseEvent {
563
+ event_type: "routing_candidates_ranked";
564
+ step_id: string;
565
+ step_index: number;
566
+ source: RoutingTelemetrySource;
567
+ state_hash_before: string;
568
+ candidate_count: number;
569
+ reachable_operation_count?: number;
570
+ available_binding_count?: number;
571
+ missing_binding_count?: number;
572
+ selected_endpoint_id?: string;
573
+ selected_operation_id?: string;
574
+ candidates: RoutingCandidateSnapshot[];
575
+ }
576
+
577
+ export interface RoutingStepEvent extends RoutingTelemetryBaseEvent {
578
+ event_type: "routing_step_executed";
579
+ step_id: string;
580
+ step_index: number;
581
+ source: RoutingTelemetrySource;
582
+ state_hash_before: string;
583
+ state_hash_after: string;
584
+ selected_skill_id?: string;
585
+ selected_endpoint_id?: string;
586
+ selected_operation_id?: string;
587
+ reachable_operation_count?: number;
588
+ available_binding_count?: number;
589
+ missing_binding_count?: number;
590
+ candidate_count: number;
591
+ execution_latency_ms?: number;
592
+ status_code?: number;
593
+ success?: boolean;
594
+ failure_reason?: string;
595
+ schema_fingerprint?: string;
596
+ response_hash?: string;
597
+ cross_domain_transition: boolean;
598
+ retry_count: number;
599
+ user_override: boolean;
600
+ did_step_unlock_next_step: boolean;
601
+ required_recovery: boolean;
602
+ }
603
+
604
+ export interface RoutingSessionCompletedEvent extends RoutingTelemetryBaseEvent {
605
+ event_type: "routing_session_completed";
606
+ completed_at: string;
607
+ final_outcome: RoutingSessionOutcome;
608
+ final_success: boolean;
609
+ total_steps: number;
610
+ total_candidates_ranked: number;
611
+ total_api_calls: number;
612
+ retry_count: number;
613
+ user_override: boolean;
614
+ required_recovery: boolean;
615
+ }
616
+
617
+ export type RoutingTelemetryEvent =
618
+ | RoutingSessionEvent
619
+ | RoutingCandidateEvent
620
+ | RoutingStepEvent
621
+ | RoutingSessionCompletedEvent;
622
+
623
+ export type WorkflowStepStrategy = "server" | "trigger-intercept" | "browser-action" | "browser-fetch";
624
+
625
+ export interface WorkflowActionStep {
626
+ action: string;
627
+ selector?: string;
628
+ value?: string;
629
+ ref?: string;
630
+ step_index?: number;
631
+ }
632
+
633
+ export interface WorkflowTokenCandidate {
634
+ source_kind: "cookie" | "request_header" | "response_header" | "request_body" | "hidden_input" | "meta" | "bootstrap_json";
635
+ source_name: string;
636
+ source_path?: string;
637
+ observed_value?: string;
638
+ confidence: number;
639
+ }
640
+
641
+ export interface TokenBinding {
642
+ binding_id: string;
643
+ target_location: "header" | "body";
644
+ target_name: string;
645
+ refresh_on_statuses: number[];
646
+ candidates: WorkflowTokenCandidate[];
647
+ selected_source_kind?: WorkflowTokenCandidate["source_kind"];
648
+ selected_source_name?: string;
649
+ }
650
+
651
+ export interface MutationGuard {
652
+ confirm_unsafe_required: boolean;
653
+ provenance_backed: boolean;
654
+ auth_required: boolean;
655
+ parameter_mapping_confident: boolean;
656
+ block_reason?: string;
657
+ }
658
+
659
+ export interface WorkflowStep {
660
+ step_id: string;
661
+ strategy: WorkflowStepStrategy;
662
+ provenance: "observed-request" | "bundle-inferred" | "dom-form" | "trigger-url" | "learned-runtime";
663
+ trigger_url?: string;
664
+ action_sequence?: WorkflowActionStep[];
665
+ success_count?: number;
666
+ failure_count?: number;
667
+ last_status?: number;
668
+ last_error?: string;
669
+ last_used_at?: string;
670
+ }
671
+
672
+ export interface WorkflowRecipe {
673
+ recipe_id: string;
674
+ endpoint_id: string;
675
+ operation_id?: string;
676
+ preferred: boolean;
677
+ provenance_backed: boolean;
678
+ steps: WorkflowStep[];
679
+ token_bindings: TokenBinding[];
680
+ mutation_guard: MutationGuard;
681
+ replay_contract: WorkflowReplayContract;
682
+ last_successful_strategy?: WorkflowStepStrategy;
683
+ last_used_at?: string;
684
+ }
685
+
686
+ export interface WorkflowDomFieldHint {
687
+ form_selector?: string;
688
+ field_name: string;
689
+ value?: string;
690
+ field_type?: string;
691
+ selector?: string;
692
+ required?: boolean;
693
+ pattern?: string;
694
+ min?: string;
695
+ max?: string;
696
+ }
697
+
698
+ export interface WorkflowMetaHint {
699
+ key: string;
700
+ value: string;
701
+ }
702
+
703
+ export interface WorkflowBootstrapHint {
704
+ path: string;
705
+ value: string;
706
+ }
707
+
708
+ export interface WorkflowDomOptionHint {
709
+ form_selector?: string;
710
+ field_name: string;
711
+ values: string[];
712
+ labels?: string[];
713
+ field_type?: string;
714
+ }
715
+
716
+ export interface WorkflowParameterSourceHint {
717
+ source_kind:
718
+ | WorkflowTokenCandidate["source_kind"]
719
+ | "path_template"
720
+ | "query_default"
721
+ | "body_default"
722
+ | "observed_query"
723
+ | "observed_body"
724
+ | "semantic_requires";
725
+ source_name: string;
726
+ source_path?: string;
727
+ confidence?: number;
728
+ }
729
+
730
+ export interface WorkflowParameterConstraint {
731
+ kind: "enum" | "format" | "pattern" | "min" | "max";
732
+ value?: string | number | boolean;
733
+ description?: string;
734
+ }
735
+
736
+ export interface WorkflowParameterSpec {
737
+ name: string;
738
+ location: "path" | "query" | "body" | "header";
739
+ description?: string;
740
+ type: "string" | "number" | "integer" | "boolean" | "object" | "array";
741
+ required: boolean;
742
+ user_supplied: boolean;
743
+ default_value?: unknown;
744
+ example_value?: unknown;
745
+ format?: string;
746
+ enum_values?: Array<string | number | boolean>;
747
+ derived_from?: string[];
748
+ constraints?: WorkflowParameterConstraint[];
749
+ source_hints: WorkflowParameterSourceHint[];
750
+ }
751
+
752
+ export interface EndpointParameterReview {
753
+ name: string;
754
+ location: "path" | "query" | "body" | "header";
755
+ description?: string;
756
+ type?: "string" | "number" | "integer" | "boolean" | "object" | "array";
757
+ required?: boolean;
758
+ user_supplied?: boolean;
759
+ format?: string;
760
+ enum_values?: Array<string | number | boolean>;
761
+ derived_from?: string[];
762
+ }
763
+
764
+ export interface EndpointResponseFieldReview {
765
+ path: string;
766
+ description?: string;
767
+ type?: string;
768
+ enum_values?: Array<string | number | boolean>;
769
+ }
770
+
771
+ export interface EndpointReviewPayload {
772
+ endpoint_id: string;
773
+ description?: string;
774
+ action_kind?: string;
775
+ resource_kind?: string;
776
+ example_request?: unknown;
777
+ example_response?: unknown;
778
+ parameter_reviews?: EndpointParameterReview[];
779
+ response_reviews?: EndpointResponseFieldReview[];
780
+ }
781
+
782
+ export interface WorkflowPrerequisiteSpec {
783
+ prerequisite_id: string;
784
+ kind: "authenticated-session" | "token-binding" | "hidden-field" | "page-context" | "browser-action" | "submit-blocker";
785
+ name: string;
786
+ description?: string;
787
+ required: boolean;
788
+ selector?: string;
789
+ source_kind?: string;
790
+ source_name?: string;
791
+ derived_from?: string;
792
+ }
793
+
794
+ export interface WorkflowNextStateSpec {
795
+ kind: "page_url" | "response_schema" | "dom_selector";
796
+ value: string;
797
+ description?: string;
798
+ }
799
+
800
+ export interface WorkflowPaymentRequirementSpec {
801
+ status: "free" | "x402_optional" | "x402_required";
802
+ price_usd?: string;
803
+ currency?: string;
804
+ wallet_required: boolean;
805
+ provider_hint?: string;
806
+ confirmation_field?: "payment_verified";
807
+ reason?: string;
808
+ }
809
+
810
+ export interface WorkflowReplayContract {
811
+ explicit_replay_only: boolean;
812
+ exposure_stage: "publish";
813
+ dependency_bindings: string[];
814
+ search_terms: string[];
815
+ parameter_specs: WorkflowParameterSpec[];
816
+ prerequisite_specs: WorkflowPrerequisiteSpec[];
817
+ next_state: WorkflowNextStateSpec[];
818
+ payment_requirement: WorkflowPaymentRequirementSpec;
819
+ }
820
+
821
+ export interface WorkflowEvidence {
822
+ observed_request_count: number;
823
+ observed_request_urls: string[];
824
+ har_lineage_ids: Array<string | undefined>;
825
+ trigger_urls: string[];
826
+ js_bundle_urls: string[];
827
+ dom_form_hints: WorkflowDomFieldHint[];
828
+ dom_option_hints: WorkflowDomOptionHint[];
829
+ meta_hints: WorkflowMetaHint[];
830
+ bootstrap_hints: WorkflowBootstrapHint[];
831
+ }
832
+
833
+ export interface WorkflowArtifact {
834
+ artifact_version: string;
835
+ skill_id: string;
836
+ domain: string;
837
+ intent_signature: string;
838
+ captured_at: string;
839
+ final_url: string;
840
+ auth_state: {
841
+ auth_profile_ref?: string;
842
+ cookie_names: string[];
843
+ header_names: string[];
844
+ authenticated: boolean;
845
+ };
846
+ evidence: WorkflowEvidence;
847
+ recipes: WorkflowRecipe[];
848
+ }
849
+
850
+ export type WorkflowPublishStatus = "captured" | "indexed" | "blocked-validation" | "published";
851
+
852
+ export interface WorkflowPublishBindingSource {
853
+ source_kind: WorkflowTokenCandidate["source_kind"];
854
+ source_name: string;
855
+ source_path?: string;
856
+ confidence: number;
857
+ }
858
+
859
+ export interface WorkflowPublishBinding {
860
+ target_location: TokenBinding["target_location"];
861
+ target_name: string;
862
+ refresh_on_statuses: number[];
863
+ selected_source_kind?: TokenBinding["selected_source_kind"];
864
+ selected_source_name?: string;
865
+ candidates: WorkflowPublishBindingSource[];
866
+ }
867
+
868
+ export interface WorkflowPublishRecipe {
869
+ endpoint_id: string;
870
+ operation_id?: string;
871
+ preferred: boolean;
872
+ provenance_backed: boolean;
873
+ last_successful_strategy?: WorkflowStepStrategy;
874
+ steps: Array<{
875
+ strategy: WorkflowStepStrategy;
876
+ provenance: WorkflowStep["provenance"];
877
+ trigger_url?: string;
878
+ action_count: number;
879
+ }>;
880
+ mutation_guard: MutationGuard;
881
+ token_bindings: WorkflowPublishBinding[];
882
+ replay_contract: WorkflowReplayContract;
883
+ usage_notes: string[];
884
+ }
885
+
886
+ export interface WorkflowPublishArtifact {
887
+ export_version: string;
888
+ generated_at: string;
889
+ publish_status: WorkflowPublishStatus;
890
+ published_at?: string;
891
+ validation_errors?: string[];
892
+ skill_id: string;
893
+ domain: string;
894
+ intent_signature: string;
895
+ sanitized_endpoints: EndpointDescriptor[];
896
+ workflow_summary: {
897
+ recipe_count: number;
898
+ preferred_endpoint_ids: string[];
899
+ authenticated_capture: boolean;
900
+ token_binding_count: number;
901
+ trigger_url_count: number;
902
+ included_endpoint_count: number;
903
+ root_endpoint_ids: string[];
904
+ closure_added_count: number;
905
+ };
906
+ auth_summary: WorkflowArtifact["auth_state"];
907
+ recipes: WorkflowPublishRecipe[];
908
+ docs: {
909
+ headline: string;
910
+ bullets: string[];
911
+ };
912
+ }
@@ -0,0 +1,8 @@
1
+ import type { EndpointDescriptor, SkillManifest } from "../types/index.js";
2
+
3
+ export function isAuthGatedEndpoint(
4
+ skill: SkillManifest,
5
+ endpoint: EndpointDescriptor,
6
+ ): boolean {
7
+ return Boolean(skill.auth_profile_ref || endpoint.semantic?.auth_required === true);
8
+ }
@@ -0,0 +1,27 @@
1
+ import type { EndpointDescriptor, SkillManifest } from "../types/index.js";
2
+
3
+ const STALE_THRESHOLD_MS = 24 * 60 * 60 * 1000; // 24 hours
4
+
5
+ export function selectVerificationCandidates(
6
+ skill: SkillManifest,
7
+ options?: {
8
+ staleOnly?: boolean;
9
+ limit?: number;
10
+ now?: number;
11
+ },
12
+ ): EndpointDescriptor[] {
13
+ const now = options?.now ?? Date.now();
14
+ const candidates = skill.endpoints.filter((endpoint) => {
15
+ if (endpoint.method !== "GET") return false;
16
+ if (!options?.staleOnly) return true;
17
+ const isDisabled = endpoint.verification_status === "disabled";
18
+ const isFailed = endpoint.verification_status === "failed";
19
+ const lowReliability = typeof endpoint.reliability_score === "number" && endpoint.reliability_score < 0.2;
20
+ const lastVerified = endpoint.last_verified_at
21
+ ? new Date(endpoint.last_verified_at).getTime()
22
+ : 0;
23
+ return isDisabled || isFailed || lowReliability || now - lastVerified > STALE_THRESHOLD_MS;
24
+ });
25
+ const limit = options?.limit && options.limit > 0 ? options.limit : candidates.length;
26
+ return candidates.slice(0, limit);
27
+ }