@warlock.js/core 5.33.0 → 5.34.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.
Files changed (103) hide show
  1. package/CHANGELOG.md +26 -46
  2. package/esm/cli/commands/check/check-command.action.mjs +2 -1
  3. package/esm/cli/commands/check/check-command.action.mjs.map +1 -1
  4. package/esm/cli/commands/check.command.mjs +2 -2
  5. package/esm/cli/commands/check.command.mjs.map +1 -1
  6. package/esm/cli/commands/e2e.command.mjs +63 -0
  7. package/esm/cli/commands/e2e.command.mjs.map +1 -0
  8. package/esm/cli/commands/load-e2e-spec.mjs +47 -0
  9. package/esm/cli/commands/load-e2e-spec.mjs.map +1 -0
  10. package/esm/cli/framework-cli-commands.mjs +2 -0
  11. package/esm/cli/framework-cli-commands.mjs.map +1 -1
  12. package/esm/dev-server/health-checker/checkers/oxlint-health-checker.mjs +1 -1
  13. package/esm/dev-server/health-checker/default-health-checkers.mjs +1 -6
  14. package/esm/dev-server/health-checker/default-health-checkers.mjs.map +1 -1
  15. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts +0 -2
  16. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts.map +1 -1
  17. package/esm/dev-server/health-checker/file-health-result.d.mts +1 -1
  18. package/esm/dev-server/health-checker/file-health-result.mjs.map +1 -1
  19. package/esm/e2e/browser.d.mts +4 -0
  20. package/esm/e2e/browser.d.mts.map +1 -0
  21. package/esm/e2e/browser.mjs +88 -0
  22. package/esm/e2e/browser.mjs.map +1 -0
  23. package/esm/e2e/cdp.d.mts +152 -0
  24. package/esm/e2e/cdp.d.mts.map +1 -0
  25. package/esm/e2e/cdp.mjs +106 -0
  26. package/esm/e2e/cdp.mjs.map +1 -0
  27. package/esm/e2e/fixture.mjs +195 -0
  28. package/esm/e2e/fixture.mjs.map +1 -0
  29. package/esm/e2e/index.d.mts +5 -0
  30. package/esm/e2e/index.mjs +6 -0
  31. package/esm/e2e/owned-process.mjs +193 -0
  32. package/esm/e2e/owned-process.mjs.map +1 -0
  33. package/esm/e2e/page.d.mts +64 -0
  34. package/esm/e2e/page.d.mts.map +1 -0
  35. package/esm/e2e/page.mjs +376 -0
  36. package/esm/e2e/page.mjs.map +1 -0
  37. package/esm/e2e/run-e2e.d.mts +17 -0
  38. package/esm/e2e/run-e2e.d.mts.map +1 -0
  39. package/esm/e2e/run-e2e.mjs +143 -0
  40. package/esm/e2e/run-e2e.mjs.map +1 -0
  41. package/esm/e2e/types.d.mts +123 -0
  42. package/esm/e2e/types.d.mts.map +1 -0
  43. package/esm/e2e/types.mjs +24 -0
  44. package/esm/e2e/types.mjs.map +1 -0
  45. package/esm/secrets/errors.d.mts +1 -1
  46. package/esm/secrets/errors.d.mts.map +1 -1
  47. package/esm/secrets/errors.mjs +2 -0
  48. package/esm/secrets/errors.mjs.map +1 -1
  49. package/esm/secrets/resolve-driver.mjs +14 -0
  50. package/esm/secrets/resolve-driver.mjs.map +1 -0
  51. package/esm/secrets/secret-store.d.mts.map +1 -1
  52. package/esm/secrets/secret-store.mjs +4 -1
  53. package/esm/secrets/secret-store.mjs.map +1 -1
  54. package/esm/secrets/secrets.d.mts.map +1 -1
  55. package/esm/secrets/secrets.mjs +10 -1
  56. package/esm/secrets/secrets.mjs.map +1 -1
  57. package/esm/secrets/types.d.mts +4 -0
  58. package/esm/secrets/types.d.mts.map +1 -1
  59. package/esm/tooling/check/lint-step.d.mts +3 -3
  60. package/esm/tooling/check/lint-step.d.mts.map +1 -1
  61. package/esm/tooling/check/lint-step.mjs +3 -47
  62. package/esm/tooling/check/lint-step.mjs.map +1 -1
  63. package/esm/tooling/check/run-check.d.mts +2 -2
  64. package/esm/tooling/check/run-check.mjs +4 -2
  65. package/esm/tooling/check/run-check.mjs.map +1 -1
  66. package/esm/tooling/problem.d.mts +1 -1
  67. package/esm/tooling/problem.d.mts.map +1 -1
  68. package/esm/tooling/problem.mjs.map +1 -1
  69. package/esm/updater/package-manager.mjs +5 -1
  70. package/esm/updater/package-manager.mjs.map +1 -1
  71. package/esm/upgrade/codemods/index.mjs +2 -1
  72. package/esm/upgrade/codemods/index.mjs.map +1 -1
  73. package/esm/upgrade/codemods/oxc-toolchain.mjs +59 -10
  74. package/esm/upgrade/codemods/oxc-toolchain.mjs.map +1 -1
  75. package/esm/upgrade/codemods/oxlint-rule-schemas.mjs +6 -0
  76. package/esm/upgrade/codemods/oxlint-rule-schemas.mjs.map +1 -0
  77. package/esm/upgrade/codemods/port-eslint-rules.mjs +343 -0
  78. package/esm/upgrade/codemods/port-eslint-rules.mjs.map +1 -0
  79. package/esm/upgrade/codemods/toolchain-templates.mjs +1 -1
  80. package/esm/upgrade/codemods/toolchain-templates.mjs.map +1 -1
  81. package/esm/upgrade/codemods/validate-oxlint-rule.mjs +60 -0
  82. package/esm/upgrade/codemods/validate-oxlint-rule.mjs.map +1 -0
  83. package/esm/upgrade/notes.mjs +14 -7
  84. package/esm/upgrade/notes.mjs.map +1 -1
  85. package/esm/warlock-config/types.d.mts +0 -1
  86. package/esm/warlock-config/types.d.mts.map +1 -1
  87. package/llms-full.txt +243 -41
  88. package/llms.txt +2 -1
  89. package/package.json +19 -20
  90. package/skills/create-module/SKILL.md +2 -2
  91. package/skills/run-app/SKILL.md +3 -3
  92. package/skills/store-secrets/SKILL.md +40 -1
  93. package/skills/test-browser/SKILL.md +119 -0
  94. package/skills/upgrade-from-5-29/SKILL.md +70 -29
  95. package/skills/warlock-check/SKILL.md +3 -3
  96. package/skills/warlock-doctor/SKILL.md +2 -3
  97. package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs +0 -152
  98. package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs.map +0 -1
  99. package/esm/dev-server/health-checker/eslint-support.mjs +0 -27
  100. package/esm/dev-server/health-checker/eslint-support.mjs.map +0 -1
  101. package/esm/dev-server/health-checker/workers/eslint-health.worker.d.mts +0 -1
  102. package/esm/dev-server/health-checker/workers/eslint-health.worker.mjs +0 -183
  103. package/esm/dev-server/health-checker/workers/eslint-health.worker.mjs.map +0 -1
@@ -1,183 +0,0 @@
1
- import { hasEslint } from "../eslint-support.mjs";
2
- import { ESLint } from "eslint";
3
- import { parentPort, workerData } from "worker_threads";
4
-
5
- //#region ../../packages/core/src/dev-server/health-checker/workers/eslint-health.worker.ts
6
- /**
7
- * ESLint Health Check Worker
8
- *
9
- * This worker runs in a dedicated thread to perform ESLint linting
10
- * without blocking the main dev server thread. It maintains a persistent
11
- * ESLint instance for efficient linting.
12
- *
13
- * Communication:
14
- * - Receives: { type: 'init' | 'check' | 'shutdown', ... }
15
- * - Sends: { type: 'results' | 'initialized' | 'error', ... }
16
- */
17
- /**
18
- * ESLint Health Worker class
19
- * Maintains persistent ESLint instance for efficient linting
20
- */
21
- var ESLintHealthWorker = class {
22
- constructor() {
23
- this.eslint = null;
24
- this.initialized = false;
25
- this.hasConfig = false;
26
- this.cwd = process.cwd();
27
- }
28
- /**
29
- * Initialize the worker with ESLint configuration
30
- */
31
- initialize(config) {
32
- try {
33
- this.cwd = config.cwd || process.cwd();
34
- this.hasConfig = hasEslint(this.cwd);
35
- if (!this.hasConfig) {
36
- this.initialized = true;
37
- return {
38
- success: true,
39
- hasConfig: false
40
- };
41
- }
42
- this.eslint = new ESLint({ cwd: this.cwd });
43
- this.initialized = true;
44
- return {
45
- success: true,
46
- hasConfig: true
47
- };
48
- } catch (error) {
49
- console.error("ESLint Worker: Failed to initialize:", error);
50
- this.initialized = true;
51
- return {
52
- success: false,
53
- hasConfig: false
54
- };
55
- }
56
- }
57
- /**
58
- * Check files for ESLint errors
59
- */
60
- async checkFiles(files) {
61
- if (!this.eslint || !this.hasConfig) return files.map((file) => ({
62
- path: file.path,
63
- relativePath: file.relativePath,
64
- healthy: true,
65
- errors: [],
66
- warnings: []
67
- }));
68
- const results = [];
69
- for (const file of files) {
70
- if (!this.isLintableFile(file.path)) {
71
- results.push({
72
- path: file.path,
73
- relativePath: file.relativePath,
74
- healthy: true,
75
- errors: [],
76
- warnings: []
77
- });
78
- continue;
79
- }
80
- try {
81
- const result = await this.checkSingleFile(file);
82
- results.push(result);
83
- } catch (error) {
84
- results.push({
85
- path: file.path,
86
- relativePath: file.relativePath,
87
- healthy: true,
88
- errors: [],
89
- warnings: []
90
- });
91
- }
92
- }
93
- return results;
94
- }
95
- /**
96
- * Check a single file for lint issues
97
- */
98
- async checkSingleFile(file) {
99
- if (!this.eslint) return {
100
- path: file.path,
101
- relativePath: file.relativePath,
102
- healthy: true,
103
- errors: [],
104
- warnings: []
105
- };
106
- const lintResult = (await this.eslint.lintText(file.content, { filePath: file.path }))[0];
107
- if (!lintResult) return {
108
- path: file.path,
109
- relativePath: file.relativePath,
110
- healthy: true,
111
- errors: [],
112
- warnings: []
113
- };
114
- const errors = [];
115
- const warnings = [];
116
- for (const message of lintResult.messages) {
117
- const lintMessage = {
118
- type: message.severity === 2 ? "error" : "warning",
119
- message: message.message,
120
- lineNumber: message.line || 1,
121
- columnNumber: message.column || 1,
122
- length: message.endColumn && message.column ? message.endColumn - message.column : 1,
123
- filePath: file.path,
124
- relativePath: file.relativePath,
125
- ruleId: message.ruleId || void 0
126
- };
127
- if (message.severity === 2) errors.push(lintMessage);
128
- else if (message.severity === 1) warnings.push(lintMessage);
129
- }
130
- return {
131
- path: file.path,
132
- relativePath: file.relativePath,
133
- healthy: errors.length === 0 && warnings.length === 0,
134
- errors,
135
- warnings
136
- };
137
- }
138
- /**
139
- * Check if file is a lintable file
140
- */
141
- isLintableFile(filePath) {
142
- const ext = filePath.toLowerCase();
143
- return ext.endsWith(".ts") || ext.endsWith(".tsx") || ext.endsWith(".js") || ext.endsWith(".jsx");
144
- }
145
- };
146
- const worker = new ESLintHealthWorker();
147
- parentPort?.on("message", async (message) => {
148
- try {
149
- switch (message.type) {
150
- case "init": {
151
- const initResult = worker.initialize(message.config);
152
- const response = {
153
- type: "initialized",
154
- success: initResult.success,
155
- hasConfig: initResult.hasConfig
156
- };
157
- parentPort?.postMessage(response);
158
- break;
159
- }
160
- case "check": {
161
- const response = {
162
- type: "results",
163
- results: await worker.checkFiles(message.files)
164
- };
165
- parentPort?.postMessage(response);
166
- break;
167
- }
168
- case "filesDeleted": break;
169
- case "shutdown": process.exit(0);
170
- }
171
- } catch (error) {
172
- const response = {
173
- type: "error",
174
- message: error instanceof Error ? error.message : String(error)
175
- };
176
- parentPort?.postMessage(response);
177
- }
178
- });
179
- if (workerData?.autoInit) worker.initialize({ cwd: workerData.cwd || process.cwd() });
180
-
181
- //#endregion
182
- export { };
183
- //# sourceMappingURL=eslint-health.worker.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eslint-health.worker.mjs","names":[],"sources":["../../../../../../../../../../packages/core/src/dev-server/health-checker/workers/eslint-health.worker.ts"],"sourcesContent":["/**\n * ESLint Health Check Worker\n *\n * This worker runs in a dedicated thread to perform ESLint linting\n * without blocking the main dev server thread. It maintains a persistent\n * ESLint instance for efficient linting.\n *\n * Communication:\n * - Receives: { type: 'init' | 'check' | 'shutdown', ... }\n * - Sends: { type: 'results' | 'initialized' | 'error', ... }\n */\nimport { ESLint } from \"eslint\";\nimport { parentPort, workerData } from \"worker_threads\";\nimport { hasEslint } from \"../eslint-support\";\n\n/**\n * Serialized file data received from main thread\n */\ntype SerializedFile = {\n /** Absolute file path */\n path: string;\n /** File content (source code) */\n content: string;\n /** Relative path for display */\n relativePath: string;\n};\n\n/**\n * Lint message sent back to main thread\n */\ntype LintMessage = {\n type: \"error\" | \"warning\";\n message: string;\n lineNumber: number;\n columnNumber: number;\n length: number;\n filePath: string;\n relativePath: string;\n ruleId?: string;\n};\n\n/**\n * Health check result for a single file\n */\ntype FileCheckResult = {\n path: string;\n relativePath: string;\n healthy: boolean;\n errors: LintMessage[];\n warnings: LintMessage[];\n};\n\n/**\n * Messages received from main thread\n */\n/**\n * Deleted file info\n */\ntype DeletedFile = {\n path: string;\n relativePath: string;\n};\n\n/**\n * Messages received from main thread\n */\ntype WorkerMessage =\n | { type: \"init\"; config: { cwd: string } }\n | { type: \"check\"; files: SerializedFile[] }\n | { type: \"filesDeleted\"; files: DeletedFile[] }\n | { type: \"shutdown\" };\n\n/**\n * Messages sent to main thread\n */\ntype WorkerResponse =\n | { type: \"initialized\"; success: boolean; hasConfig: boolean; error?: string }\n | { type: \"results\"; results: FileCheckResult[] }\n | { type: \"error\"; message: string };\n\n/**\n * ESLint Health Worker class\n * Maintains persistent ESLint instance for efficient linting\n */\nclass ESLintHealthWorker {\n /**\n * ESLint instance\n */\n private eslint: ESLint | null = null;\n\n /**\n * Whether the worker is initialized\n */\n private initialized = false;\n\n /**\n * Whether ESLint config was found\n */\n private hasConfig = false;\n\n /**\n * Current working directory\n */\n private cwd: string = process.cwd();\n\n /**\n * Initialize the worker with ESLint configuration\n */\n public initialize(config: { cwd: string }): { success: boolean; hasConfig: boolean } {\n try {\n this.cwd = config.cwd || process.cwd();\n\n // The main-thread checker emits the one-time deprecation warning.\n this.hasConfig = hasEslint(this.cwd);\n\n if (!this.hasConfig) {\n this.initialized = true;\n return { success: true, hasConfig: false };\n }\n\n // Create ESLint instance with flat config\n this.eslint = new ESLint({\n cwd: this.cwd,\n });\n\n this.initialized = true;\n return { success: true, hasConfig: true };\n } catch (error) {\n console.error(\"ESLint Worker: Failed to initialize:\", error);\n this.initialized = true;\n return { success: false, hasConfig: false };\n }\n }\n\n /**\n * Check files for ESLint errors\n */\n public async checkFiles(files: SerializedFile[]): Promise<FileCheckResult[]> {\n if (!this.eslint || !this.hasConfig) {\n // No ESLint config, return all files as healthy\n return files.map((file) => ({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n\n const results: FileCheckResult[] = [];\n\n for (const file of files) {\n // Only lint lintable files\n if (!this.isLintableFile(file.path)) {\n results.push({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n });\n continue;\n }\n\n try {\n const result = await this.checkSingleFile(file);\n results.push(result);\n } catch (error) {\n // On error, mark as healthy to avoid blocking\n results.push({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n });\n }\n }\n\n return results;\n }\n\n /**\n * Check a single file for lint issues\n */\n private async checkSingleFile(file: SerializedFile): Promise<FileCheckResult> {\n if (!this.eslint) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n // Use lintText to lint from memory (not disk)\n const lintResults = await this.eslint.lintText(file.content, {\n filePath: file.path,\n });\n\n const lintResult = lintResults[0];\n\n if (!lintResult) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n const errors: LintMessage[] = [];\n const warnings: LintMessage[] = [];\n\n for (const message of lintResult.messages) {\n const lintMessage: LintMessage = {\n type: message.severity === 2 ? \"error\" : \"warning\",\n message: message.message,\n lineNumber: message.line || 1,\n columnNumber: message.column || 1,\n length: message.endColumn && message.column ? message.endColumn - message.column : 1,\n filePath: file.path,\n relativePath: file.relativePath,\n ruleId: message.ruleId || undefined,\n };\n\n if (message.severity === 2) {\n errors.push(lintMessage);\n } else if (message.severity === 1) {\n warnings.push(lintMessage);\n }\n }\n\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: errors.length === 0 && warnings.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * Check if file is a lintable file\n */\n private isLintableFile(filePath: string): boolean {\n const ext = filePath.toLowerCase();\n return (\n ext.endsWith(\".ts\") || ext.endsWith(\".tsx\") || ext.endsWith(\".js\") || ext.endsWith(\".jsx\")\n );\n }\n}\n\n// Create worker instance\nconst worker = new ESLintHealthWorker();\n\n// Handle messages from main thread\nparentPort?.on(\"message\", async (message: WorkerMessage) => {\n try {\n switch (message.type) {\n case \"init\": {\n const initResult = worker.initialize(message.config);\n const response: WorkerResponse = {\n type: \"initialized\",\n success: initResult.success,\n hasConfig: initResult.hasConfig,\n };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"check\": {\n const results = await worker.checkFiles(message.files);\n const response: WorkerResponse = { type: \"results\", results };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"filesDeleted\": {\n // ESLint doesn't maintain internal file cache (lints from memory)\n // No cleanup needed, just acknowledge\n break;\n }\n\n case \"shutdown\": {\n process.exit(0);\n }\n }\n } catch (error) {\n const response: WorkerResponse = {\n type: \"error\",\n message: error instanceof Error ? error.message : String(error),\n };\n parentPort?.postMessage(response);\n }\n});\n\n// Handle initialization from workerData if provided\nif (workerData?.autoInit) {\n worker.initialize({ cwd: workerData.cwd || process.cwd() });\n}\n"],"mappings":"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"}