libretto 0.5.0 → 0.5.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.
Files changed (122) hide show
  1. package/README.md +109 -35
  2. package/dist/cli/cli.js +22 -97
  3. package/dist/cli/commands/browser.js +86 -59
  4. package/dist/cli/commands/execution.js +199 -86
  5. package/dist/cli/commands/init.js +34 -29
  6. package/dist/cli/commands/logs.js +4 -5
  7. package/dist/cli/commands/shared.js +30 -29
  8. package/dist/cli/commands/snapshot.js +26 -39
  9. package/dist/cli/core/ai-config.js +21 -4
  10. package/dist/cli/core/api-snapshot-analyzer.js +15 -5
  11. package/dist/cli/core/browser.js +207 -37
  12. package/dist/cli/core/context.js +4 -1
  13. package/dist/cli/core/session-telemetry.js +434 -174
  14. package/dist/cli/core/session.js +21 -8
  15. package/dist/cli/core/snapshot-analyzer.js +14 -31
  16. package/dist/cli/core/snapshot-api-config.js +2 -6
  17. package/dist/cli/core/telemetry.js +20 -4
  18. package/dist/cli/framework/simple-cli.js +45 -25
  19. package/dist/cli/router.js +14 -21
  20. package/dist/cli/workers/run-integration-runtime.js +24 -5
  21. package/dist/cli/workers/run-integration-worker-protocol.js +3 -1
  22. package/dist/cli/workers/run-integration-worker.js +1 -4
  23. package/dist/index.d.ts +1 -2
  24. package/dist/index.js +7 -10
  25. package/dist/runtime/download/download.js +5 -1
  26. package/dist/runtime/extract/extract.js +11 -2
  27. package/dist/runtime/network/network.js +8 -1
  28. package/dist/runtime/recovery/agent.js +6 -2
  29. package/dist/runtime/recovery/errors.js +3 -1
  30. package/dist/runtime/recovery/recovery.js +3 -1
  31. package/dist/shared/condense-dom/condense-dom.js +17 -69
  32. package/dist/shared/config/config.d.ts +1 -9
  33. package/dist/shared/config/config.js +0 -18
  34. package/dist/shared/config/index.d.ts +2 -1
  35. package/dist/shared/config/index.js +0 -10
  36. package/dist/shared/debug/pause.js +9 -3
  37. package/dist/shared/dom-semantics.d.ts +8 -0
  38. package/dist/shared/dom-semantics.js +69 -0
  39. package/dist/shared/instrumentation/instrument.js +101 -5
  40. package/dist/shared/llm/ai-sdk-adapter.js +3 -1
  41. package/dist/shared/llm/client.js +3 -1
  42. package/dist/shared/logger/index.js +4 -1
  43. package/dist/shared/run/api.js +3 -1
  44. package/dist/shared/run/browser.js +47 -3
  45. package/dist/shared/state/session-state.d.ts +2 -1
  46. package/dist/shared/state/session-state.js +5 -2
  47. package/dist/shared/visualization/ghost-cursor.js +36 -14
  48. package/dist/shared/visualization/highlight.js +9 -6
  49. package/dist/shared/workflow/workflow.d.ts +4 -5
  50. package/dist/shared/workflow/workflow.js +3 -5
  51. package/package.json +6 -2
  52. package/scripts/check-skills-sync.mjs +25 -0
  53. package/scripts/compare-eval-summary.mjs +47 -0
  54. package/scripts/postinstall.mjs +15 -15
  55. package/scripts/prepare-release.sh +97 -0
  56. package/scripts/skills-libretto.mjs +103 -0
  57. package/scripts/summarize-evals.mjs +135 -0
  58. package/scripts/sync-skills.mjs +12 -0
  59. package/skills/libretto/SKILL.md +132 -54
  60. package/skills/libretto/references/action-logs.md +101 -0
  61. package/skills/libretto/references/auth-profiles.md +1 -2
  62. package/skills/libretto/references/code-generation-rules.md +210 -0
  63. package/skills/libretto/references/configuration-file-reference.md +53 -0
  64. package/skills/libretto/references/pages-and-page-targeting.md +1 -1
  65. package/skills/libretto/references/site-security-review.md +143 -0
  66. package/src/cli/cli.ts +23 -110
  67. package/src/cli/commands/browser.ts +94 -70
  68. package/src/cli/commands/execution.ts +233 -102
  69. package/src/cli/commands/init.ts +37 -33
  70. package/src/cli/commands/logs.ts +7 -7
  71. package/src/cli/commands/shared.ts +36 -37
  72. package/src/cli/commands/snapshot.ts +44 -59
  73. package/src/cli/core/ai-config.ts +24 -4
  74. package/src/cli/core/api-snapshot-analyzer.ts +17 -6
  75. package/src/cli/core/browser.ts +260 -49
  76. package/src/cli/core/context.ts +7 -2
  77. package/src/cli/core/session-telemetry.ts +449 -197
  78. package/src/cli/core/session.ts +21 -7
  79. package/src/cli/core/snapshot-analyzer.ts +26 -46
  80. package/src/cli/core/snapshot-api-config.ts +170 -175
  81. package/src/cli/core/telemetry.ts +39 -4
  82. package/src/cli/framework/simple-cli.ts +144 -77
  83. package/src/cli/router.ts +13 -21
  84. package/src/cli/workers/run-integration-runtime.ts +36 -9
  85. package/src/cli/workers/run-integration-worker-protocol.ts +2 -0
  86. package/src/cli/workers/run-integration-worker.ts +1 -4
  87. package/src/index.ts +73 -66
  88. package/src/runtime/download/download.ts +62 -58
  89. package/src/runtime/download/index.ts +5 -5
  90. package/src/runtime/extract/extract.ts +71 -61
  91. package/src/runtime/network/index.ts +3 -3
  92. package/src/runtime/network/network.ts +99 -93
  93. package/src/runtime/recovery/agent.ts +217 -212
  94. package/src/runtime/recovery/errors.ts +107 -104
  95. package/src/runtime/recovery/index.ts +3 -3
  96. package/src/runtime/recovery/recovery.ts +38 -35
  97. package/src/shared/condense-dom/condense-dom.ts +27 -82
  98. package/src/shared/config/config.ts +0 -19
  99. package/src/shared/config/index.ts +0 -5
  100. package/src/shared/debug/pause.ts +57 -51
  101. package/src/shared/dom-semantics.ts +68 -0
  102. package/src/shared/instrumentation/errors.ts +64 -62
  103. package/src/shared/instrumentation/index.ts +5 -5
  104. package/src/shared/instrumentation/instrument.ts +339 -209
  105. package/src/shared/llm/ai-sdk-adapter.ts +58 -55
  106. package/src/shared/llm/client.ts +181 -174
  107. package/src/shared/llm/types.ts +39 -39
  108. package/src/shared/logger/index.ts +11 -4
  109. package/src/shared/logger/logger.ts +312 -306
  110. package/src/shared/logger/sinks.ts +118 -114
  111. package/src/shared/paths/paths.ts +50 -49
  112. package/src/shared/paths/repo-root.ts +17 -17
  113. package/src/shared/run/api.ts +5 -1
  114. package/src/shared/run/browser.ts +65 -3
  115. package/src/shared/state/index.ts +9 -9
  116. package/src/shared/state/session-state.ts +46 -43
  117. package/src/shared/visualization/ghost-cursor.ts +180 -149
  118. package/src/shared/visualization/highlight.ts +89 -86
  119. package/src/shared/visualization/index.ts +13 -13
  120. package/src/shared/workflow/workflow.ts +19 -25
  121. package/skills/libretto/references/reverse-engineering-network-requests.md +0 -39
  122. package/skills/libretto/references/user-action-log.md +0 -31
@@ -3,25 +3,25 @@ import type z from "zod";
3
3
  import type { MinimalLogger } from "../../shared/logger/logger.js";
4
4
 
5
5
  export type RequestConfig = {
6
- url: string;
7
- method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
8
- headers?: Record<string, string>;
9
- body?: Record<string, any> | string;
10
- /** How to serialize the body. Defaults to "json". */
11
- bodyType?: "json" | "form";
12
- /** How to parse the response. Defaults to "json". */
13
- responseType?: "json" | "text" | "xml";
6
+ url: string;
7
+ method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
8
+ headers?: Record<string, string>;
9
+ body?: Record<string, any> | string;
10
+ /** How to serialize the body. Defaults to "json". */
11
+ bodyType?: "json" | "form";
12
+ /** How to parse the response. Defaults to "json". */
13
+ responseType?: "json" | "text" | "xml";
14
14
  };
15
15
 
16
16
  export type PageRequestOptions<T extends z.ZodType | undefined = undefined> = {
17
- logger?: MinimalLogger;
18
- /** Optional Zod schema to validate the response body. */
19
- schema?: T;
17
+ logger?: MinimalLogger;
18
+ /** Optional Zod schema to validate the response body. */
19
+ schema?: T;
20
20
  };
21
21
 
22
22
  type PageRequestResult<T extends z.ZodType | undefined> = T extends z.ZodType
23
- ? z.infer<T>
24
- : any;
23
+ ? z.infer<T>
24
+ : any;
25
25
 
26
26
  /**
27
27
  * Executes a fetch() call inside the browser context via page.evaluate().
@@ -29,85 +29,91 @@ type PageRequestResult<T extends z.ZodType | undefined> = T extends z.ZodType
29
29
  * validation, and logging.
30
30
  */
31
31
  export async function pageRequest<T extends z.ZodType | undefined = undefined>(
32
- page: Page,
33
- config: RequestConfig,
34
- options?: PageRequestOptions<T>,
32
+ page: Page,
33
+ config: RequestConfig,
34
+ options?: PageRequestOptions<T>,
35
35
  ): Promise<PageRequestResult<T>> {
36
- const { url, method = "GET", headers = {}, body, bodyType = "json", responseType = "json" } = config;
37
- const { logger, schema } = options ?? {};
38
-
39
- const startTime = Date.now();
40
-
41
- // Build fetch options to pass into page.evaluate
42
- const fetchHeaders: Record<string, string> = { ...headers };
43
- let fetchBody: string | undefined;
44
-
45
- if (body !== undefined) {
46
- if (bodyType === "form") {
47
- fetchHeaders["Content-Type"] = "application/x-www-form-urlencoded";
48
- if (typeof body === "string") {
49
- fetchBody = body;
50
- } else {
51
- fetchBody = new URLSearchParams(
52
- Object.entries(body).map(([k, v]) => [k, String(v)]),
53
- ).toString();
54
- }
55
- } else {
56
- fetchHeaders["Content-Type"] = "application/json";
57
- fetchBody = typeof body === "string" ? body : JSON.stringify(body);
58
- }
59
- }
60
-
61
- const result = await page.evaluate(
62
- async ({ url, method, headers, body, responseType }) => {
63
- const res = await fetch(url, {
64
- method,
65
- headers,
66
- body: body ?? undefined,
67
- });
68
-
69
- const status = res.status;
70
- const ok = res.ok;
71
- let data: any;
72
-
73
- if (responseType === "json") {
74
- data = await res.json();
75
- } else {
76
- data = await res.text();
77
- }
78
-
79
- return { status, ok, data };
80
- },
81
- { url, method, headers: fetchHeaders, body: fetchBody, responseType },
82
- );
83
-
84
- const duration = Date.now() - startTime;
85
-
86
- if (!result.ok) {
87
- logger?.warn("network:request:error", {
88
- method,
89
- url,
90
- status: result.status,
91
- duration,
92
- body: typeof result.data === "string"
93
- ? result.data.slice(0, 500)
94
- : undefined,
95
- });
96
- throw new Error(
97
- `pageRequest failed: ${method} ${url} returned ${result.status}`,
98
- );
99
- }
100
-
101
- logger?.info("network:request", {
102
- method,
103
- url,
104
- status: result.status,
105
- duration,
106
- });
107
-
108
- if (schema) {
109
- return schema.parse(result.data) as PageRequestResult<T>;
110
- }
111
-
112
- return result.data as PageRequestResult<T>;
36
+ const {
37
+ url,
38
+ method = "GET",
39
+ headers = {},
40
+ body,
41
+ bodyType = "json",
42
+ responseType = "json",
43
+ } = config;
44
+ const { logger, schema } = options ?? {};
45
+
46
+ const startTime = Date.now();
47
+
48
+ // Build fetch options to pass into page.evaluate
49
+ const fetchHeaders: Record<string, string> = { ...headers };
50
+ let fetchBody: string | undefined;
51
+
52
+ if (body !== undefined) {
53
+ if (bodyType === "form") {
54
+ fetchHeaders["Content-Type"] = "application/x-www-form-urlencoded";
55
+ if (typeof body === "string") {
56
+ fetchBody = body;
57
+ } else {
58
+ fetchBody = new URLSearchParams(
59
+ Object.entries(body).map(([k, v]) => [k, String(v)]),
60
+ ).toString();
61
+ }
62
+ } else {
63
+ fetchHeaders["Content-Type"] = "application/json";
64
+ fetchBody = typeof body === "string" ? body : JSON.stringify(body);
65
+ }
66
+ }
67
+
68
+ const result = await page.evaluate(
69
+ async ({ url, method, headers, body, responseType }) => {
70
+ const res = await fetch(url, {
71
+ method,
72
+ headers,
73
+ body: body ?? undefined,
74
+ });
75
+
76
+ const status = res.status;
77
+ const ok = res.ok;
78
+ let data: any;
79
+
80
+ if (responseType === "json") {
81
+ data = await res.json();
82
+ } else {
83
+ data = await res.text();
84
+ }
85
+
86
+ return { status, ok, data };
87
+ },
88
+ { url, method, headers: fetchHeaders, body: fetchBody, responseType },
89
+ );
90
+
91
+ const duration = Date.now() - startTime;
92
+
93
+ if (!result.ok) {
94
+ logger?.warn("network:request:error", {
95
+ method,
96
+ url,
97
+ status: result.status,
98
+ duration,
99
+ body:
100
+ typeof result.data === "string" ? result.data.slice(0, 500) : undefined,
101
+ });
102
+ throw new Error(
103
+ `pageRequest failed: ${method} ${url} returned ${result.status}`,
104
+ );
105
+ }
106
+
107
+ logger?.info("network:request", {
108
+ method,
109
+ url,
110
+ status: result.status,
111
+ duration,
112
+ });
113
+
114
+ if (schema) {
115
+ return schema.parse(result.data) as PageRequestResult<T>;
116
+ }
117
+
118
+ return result.data as PageRequestResult<T>;
113
119
  }