@cerebriline/core 4.100.274 → 4.100.277

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 (76) hide show
  1. package/assets/prompt-templates/claude.md +7 -7
  2. package/assets/prompt-templates/deepseek.md +8 -8
  3. package/assets/prompt-templates/default.md +14 -14
  4. package/assets/prompt-templates/gemma.md +5 -5
  5. package/assets/prompt-templates/glm.md +9 -9
  6. package/assets/prompt-templates/kimi-k3.md +8 -8
  7. package/assets/prompt-templates/kimi.md +10 -10
  8. package/assets/prompt-templates/minimax-m3.1-flash.md +9 -8
  9. package/assets/prompt-templates/minimax.md +12 -10
  10. package/assets/prompt-templates/nemotron.md +9 -9
  11. package/assets/prompt-templates/qwen.md +9 -9
  12. package/dist/cloud/index.js +2 -2
  13. package/dist/document-reader-child.js +20 -20
  14. package/dist/extensions/browser/chrome-browser-driver.d.ts +50 -0
  15. package/dist/extensions/browser/chrome-render-driver.d.ts +36 -0
  16. package/dist/extensions/config/prompt-template-review.d.ts +1 -1
  17. package/dist/extensions/diagnostics/check-file-diagnostics.d.ts +99 -0
  18. package/dist/extensions/diagnostics/editor-diagnostics.d.ts +125 -0
  19. package/dist/extensions/diagnostics/render.d.ts +25 -0
  20. package/dist/extensions/diagnostics/types.d.ts +52 -0
  21. package/dist/extensions/lsp/lsp-connection.d.ts +138 -0
  22. package/dist/extensions/lsp/lsp-host.d.ts +134 -0
  23. package/dist/extensions/tools/ask-lsp.d.ts +1 -1
  24. package/dist/extensions/tools/browser.d.ts +1 -1
  25. package/dist/extensions/tools/check-file.d.ts +18 -3
  26. package/dist/extensions/tools/command-guard.d.ts +4 -3
  27. package/dist/extensions/tools/delimiter-balance.d.ts +50 -0
  28. package/dist/extensions/tools/edit-verification.d.ts +13 -4
  29. package/dist/extensions/tools/error-locations.d.ts +1 -1
  30. package/dist/extensions/tools/executors/awk-parser.d.ts +5 -0
  31. package/dist/extensions/tools/executors/awk.d.ts +14 -2
  32. package/dist/extensions/tools/executors/bash.d.ts +2 -0
  33. package/dist/extensions/tools/executors/document/formats.d.ts +4 -0
  34. package/dist/extensions/tools/executors/document/images.d.ts +6 -1
  35. package/dist/extensions/tools/executors/document/legacy.d.ts +9 -0
  36. package/dist/extensions/tools/executors/file-read.d.ts +15 -0
  37. package/dist/extensions/tools/executors/read-receipts.d.ts +10 -0
  38. package/dist/extensions/tools/executors/search.d.ts +2 -2
  39. package/dist/extensions/tools/executors/sed.d.ts +40 -0
  40. package/dist/extensions/tools/executors/unchanged-reads.d.ts +6 -0
  41. package/dist/extensions/tools/executors/web-fetch.d.ts +12 -0
  42. package/dist/extensions/tools/executors/whole-file.d.ts +7 -2
  43. package/dist/extensions/tools/helpers.d.ts +15 -1
  44. package/dist/extensions/tools/jev.d.ts +1 -1
  45. package/dist/extensions/tools/list-files.d.ts +17 -1
  46. package/dist/extensions/tools/media-endpoint.d.ts +16 -0
  47. package/dist/extensions/tools/model-tool-routing.d.ts +6 -0
  48. package/dist/extensions/tools/schemas.d.ts +12 -12
  49. package/dist/extensions/tools/task-progress.d.ts +2 -0
  50. package/dist/extensions/tools/team/agent-check.d.ts +15 -2
  51. package/dist/extensions/tools/team/agent-controls.d.ts +1 -1
  52. package/dist/extensions/tools/team/batch-report.d.ts +8 -0
  53. package/dist/extensions/tools/team/lead-agent-tools.d.ts +2 -2
  54. package/dist/extensions/tools/transform-image.d.ts +11 -0
  55. package/dist/hub/daemon/entry.js +718 -635
  56. package/dist/hub/index.js +703 -620
  57. package/dist/index.d.ts +9 -1
  58. package/dist/index.js +987 -874
  59. package/dist/remote/remote-helper-entry.js +2 -2
  60. package/dist/remote/remote-helper.js +2 -2
  61. package/dist/runtime/atomic/check-progress.d.ts +13 -0
  62. package/dist/runtime/atomic/file-revisions.d.ts +15 -1
  63. package/dist/runtime/atomic/oracle.d.ts +14 -0
  64. package/dist/runtime/atomic/page-check.d.ts +12 -2
  65. package/dist/runtime/atomic/plan-tool.d.ts +14 -2
  66. package/dist/runtime/atomic/protocol.d.ts +2 -0
  67. package/dist/runtime/atomic/restore-file-tool.d.ts +3 -3
  68. package/dist/runtime/atomic/snapshot.d.ts +15 -0
  69. package/dist/runtime/atomic/stalled-checks.d.ts +12 -4
  70. package/dist/runtime/atomic/transaction-controller.d.ts +10 -0
  71. package/dist/runtime/atomic/unparseable-change.d.ts +3 -1
  72. package/dist/runtime/safety/loop-detection.d.ts +15 -1
  73. package/dist/services/global-settings.d.ts +3 -3
  74. package/dist/services/retrieval/memory.d.ts +9 -0
  75. package/dist/services/sdd/sdd-engine.d.ts +14 -1
  76. package/package.json +11 -7
@@ -92,7 +92,7 @@ export declare const MAX_RESTORES_PER_TRANSACTION = 27;
92
92
  * without leaving the door open on a hundred.
93
93
  */
94
94
  export declare const MAX_NOOP_RESTORES_PER_TRANSACTION = 3;
95
- export declare const RESTORE_FILE_TOOL_DESCRIPTION = "Put one file back exactly as it was when this transaction opened, discarding every change you have made to it since.\n\nUse it the moment an edit goes wrong in a way you would otherwise have to undo by hand \u2014 you deleted more than you meant to, you merged two lines together, you have rewritten the same line four times and it is further from working than when you started. Restoring is exact. Retyping the original from memory is not, and on a long or minified line it is where runs go to die.\n\nIt affects one file. Anything you changed in other files this transaction stays. If the file did not exist when the transaction opened, restoring it deletes it.\n\n**You do not have to go all the way back.** Every time a tool writes a file, that version is kept and numbered, and `revision` says which one to return to:\n\n- `revision: \"last\"` undoes only your most recent change to the file, keeping everything before it. This is almost always the one you want after a single edit goes wrong.\n- `revision: \"#3\"` (or `3`) returns to that numbered version. Every edit's result tells you the number it just made, and every read of the file lists the ones you can go back to.\n- `revision: \"original\"` is the file as this transaction opened, which is what you get if you say nothing.\n\nGoing back one step is not the same as starting again. If you have fixed three things and broken the fourth, `last` keeps the three.\n\nThis is not the end of the transaction and it does not spend one \u2014 you carry on, from the file as it was. Read the file again afterwards: its line numbers are back to what they were at that revision, and any range you read earlier no longer addresses the same code.\n\nIf you only want to *see* what the file said before your changes, do not restore it \u2014 call `read_files` with `revision: \"base\"` and it is shown to you with the file left alone.";
95
+ export declare const RESTORE_FILE_TOOL_DESCRIPTION = "Put one file back exactly as it was when this transaction opened, discarding every change you have made to it since.\n\nUse it the moment an edit goes wrong in a way you would otherwise have to undo by hand \u2014 you deleted more than you meant to, you merged two lines together, you have rewritten the same line four times and it is further from working than when you started. Restoring is exact. Retyping the original from memory is not, and on a long or minified line it is where runs go to die.\n\nIt affects one file. Anything you changed in other files this transaction stays. If the file did not exist when the transaction opened, restoring it deletes it.\n\n**You do not have to go all the way back.** Every time a tool writes a file, that version is kept and numbered, and `revision` says which one to return to:\n\n- `revision: \"last\"` undoes only your most recent change to the file, keeping everything before it. This is almost always the one you want after a single edit goes wrong. Asking for it again goes one more step back; it does not undo the restore you just made.\n- `revision: \"#3\"` (or `3`) returns to that numbered version. Every edit's result tells you the number it just made, and every read of the file lists the ones you can go back to.\n- `revision: \"original\"` is the file as this transaction opened, which is what you get if you say nothing.\n\nGoing back one step is not the same as starting again. If you have fixed three things and broken the fourth, `last` keeps the three.\n\nThis is not the end of the transaction and it does not spend one \u2014 you carry on, from the file as it was. Read the file again afterwards: its line numbers are back to what they were at that revision, and any range you read earlier no longer addresses the same code.\n\nIf you only want to *see* what the file said before your changes, do not restore it \u2014 call `read_files` with `revision: \"base\"` and it is shown to you with the file left alone.";
96
96
  /**
97
97
  * The same tool, described for a session that has no transactions.
98
98
  *
@@ -103,7 +103,7 @@ export declare const RESTORE_FILE_TOOL_DESCRIPTION = "Put one file back exactly
103
103
  * carries over unchanged is the part that matters — going back is exact and
104
104
  * retyping from memory is not.
105
105
  */
106
- export declare const RESTORE_FILE_TOOL_SESSION_DESCRIPTION = "Put one file back to a version of it you had earlier, discarding what you have written to it since.\n\nUse it the moment an edit goes wrong in a way you would otherwise have to undo by hand \u2014 you deleted more than you meant to, you merged two lines together, you replaced the file with something that was never meant to be its contents. Restoring is exact. Retyping the original from memory is not, and on a long or minified line it is where runs go to die.\n\nEvery time a tool writes a file, that version is kept and numbered, and `revision` says which one to return to:\n\n- `revision: \"last\"` undoes only your most recent change to the file, keeping everything before it. This is almost always the one you want after a single edit goes wrong.\n- `revision: \"#3\"` (or `3`) returns to that numbered version. Every edit's result tells you the number it just made, and every read of the file lists the ones you can go back to.\n- `revision: \"original\"` is the file as it stood before this session first wrote to it, which is what you get if you say nothing.\n\nIt affects one file, and only files this session has written: a file nothing has touched has no earlier version held, and this will say so rather than guess.\n\nRead the file again afterwards: its line numbers are back to what they were at that revision, and any range you read earlier no longer addresses the same code.\n\nIf you only want to *see* what the file said before your changes, do not restore it \u2014 call `read_files` with `revision: \"original\"` (or a number) and it is shown to you with the file left alone.";
106
+ export declare const RESTORE_FILE_TOOL_SESSION_DESCRIPTION = "Put one file back to a version of it you had earlier, discarding what you have written to it since.\n\nUse it the moment an edit goes wrong in a way you would otherwise have to undo by hand \u2014 you deleted more than you meant to, you merged two lines together, you replaced the file with something that was never meant to be its contents. Restoring is exact. Retyping the original from memory is not, and on a long or minified line it is where runs go to die.\n\nEvery time a tool writes a file, that version is kept and numbered, and `revision` says which one to return to:\n\n- `revision: \"last\"` undoes only your most recent change to the file, keeping everything before it. This is almost always the one you want after a single edit goes wrong. Asking for it again goes one more step back; it does not undo the restore you just made.\n- `revision: \"#3\"` (or `3`) returns to that numbered version. Every edit's result tells you the number it just made, and every read of the file lists the ones you can go back to.\n- `revision: \"original\"` is the file as it stood before this session first wrote to it, which is what you get if you say nothing.\n\nIt affects one file, and only files this session has written: a file nothing has touched has no earlier version held, and this will say so rather than guess.\n\nRead the file again afterwards: its line numbers are back to what they were at that revision, and any range you read earlier no longer addresses the same code.\n\nIf you only want to *see* what the file said before your changes, do not restore it \u2014 call `read_files` with `revision: \"original\"` (or a number) and it is shown to you with the file left alone.";
107
107
  export declare const RESTORE_FILE_TOOL_INPUT_SCHEMA: {
108
108
  readonly type: "object";
109
109
  readonly properties: {
@@ -113,7 +113,7 @@ export declare const RESTORE_FILE_TOOL_INPUT_SCHEMA: {
113
113
  };
114
114
  readonly revision: {
115
115
  readonly type: "string";
116
- readonly description: "Which version to return to: \"last\" to undo only your most recent change to this file, a number such as \"#3\" for that version, or \"original\" for the file as this transaction opened. Defaults to \"original\".";
116
+ readonly description: "Which version to return to: \"last\" to undo only your most recent change to this file (again, to go one more step back), a number such as \"#3\" for that version, or \"original\" for the earliest version held. Defaults to \"original\".";
117
117
  };
118
118
  readonly find: {
119
119
  readonly type: "string";
@@ -23,6 +23,16 @@ export interface Snapshot {
23
23
  readonly root: string;
24
24
  /** Files that existed but were too large to hold; never rolled back. */
25
25
  readonly skipped: readonly string[];
26
+ /**
27
+ * Size and modification time of each skipped file that could be statted,
28
+ * so a restore can say which of them the transaction changed.
29
+ */
30
+ readonly skippedStats: ReadonlyMap<string, SkippedStamp>;
31
+ }
32
+ /** Enough of a file's stat to tell that it changed. */
33
+ export interface SkippedStamp {
34
+ readonly size: number;
35
+ readonly mtimeMs: number;
26
36
  }
27
37
  export interface SnapshotLimits {
28
38
  /** Most files a snapshot will hold before it gives up on covering the tree. */
@@ -49,6 +59,11 @@ export interface RestoreReport {
49
59
  recreated: string[];
50
60
  /** Paths the snapshot never held, listed so nobody assumes they reverted. */
51
61
  uncovered: string[];
62
+ /**
63
+ * Of `uncovered`, the files the transaction changed or deleted: left as the
64
+ * transaction left them, because there was nothing to put back.
65
+ */
66
+ unrestored: string[];
52
67
  }
53
68
  /**
54
69
  * Put the tree back exactly as the snapshot found it.
@@ -70,8 +70,16 @@ export interface StalledCheckSource {
70
70
  */
71
71
  export type StalledCheckVerdict = "ok" | "nudge" | "settle";
72
72
  export interface StalledChecks {
73
- /** Record a check that has just run, and say what it has earned. */
74
- checked(passed: boolean): StalledCheckVerdict;
73
+ /**
74
+ * Record a check that has just run, and say what it has earned.
75
+ *
76
+ * `fingerprint` is what the files held when it ran, when the host can say.
77
+ * A fingerprint that moved since the last check is a change, whatever made
78
+ * it: counting only the editing tools let a file rewritten by a shell
79
+ * command run up the count, and the guard rolled back work that was moving
80
+ * (automaticum audit 2026-11-08, B10).
81
+ */
82
+ checked(passed: boolean, fingerprint?: string): StalledCheckVerdict;
75
83
  /** Record a change: whatever the next check says, it is judging new bytes. */
76
84
  changed(): void;
77
85
  /** The current run of checks over untouched files. */
@@ -98,8 +106,8 @@ export declare function withChangeSignal<T extends AgentToolDefinition>(tools: r
98
106
  *
99
107
  * It judges nothing and puts nothing back -- saying otherwise would have the
100
108
  * model report a transaction that is still open. What it adds is the thing the
101
- * re-run cannot give it: the check names where the parser gave up, and
102
- * `check_file` names the line that is actually wrong.
109
+ * re-run cannot give it: a reading of the whole file rather than the check's
110
+ * first complaint.
103
111
  */
104
112
  export declare function describeStalledCheckNudge(runs: number, label: string): string;
105
113
  /** What the model is told when the check is closed out from under it. */
@@ -236,6 +236,9 @@ export declare class TransactionController {
236
236
  * files rather than about the clock.
237
237
  */
238
238
  private readonly checkOutputs;
239
+ /** The check's most recent output, and the one before it. */
240
+ private lastCheckOutput?;
241
+ private previousCheckOutput?;
239
242
  private checkHasRepeated;
240
243
  /** Set by a carried settlement, so the next `open` keeps the older base. */
241
244
  private carrying;
@@ -331,6 +334,13 @@ export declare class TransactionController {
331
334
  get pending(): Snapshot | undefined;
332
335
  /** The open transaction's per-file history. Empty before the first write. */
333
336
  get revisions(): RevisionLog;
337
+ /**
338
+ * What the files under the open transaction's root hold right now, as one
339
+ * string, or nothing when no transaction is open. Two equal fingerprints
340
+ * mean nothing changed in between, by whatever means -- an edit, a shell
341
+ * command, another agent.
342
+ */
343
+ fingerprint(): Promise<string | undefined>;
334
344
  /** Whether the open transaction has changed anything on disk. */
335
345
  isUntouched(): Promise<boolean>;
336
346
  /**
@@ -32,4 +32,6 @@ export interface ChangedFile {
32
32
  * reasons far more often than for a bracket, and a verdict that guessed would
33
33
  * be worse than one that stayed quiet.
34
34
  */
35
- export declare function describeUnparseableChange(changed: readonly ChangedFile[], root: string): string | null;
35
+ export declare function describeUnparseableChange(changed: readonly ChangedFile[], root: string,
36
+ /** The work is carried into the next transaction rather than put back. */
37
+ carried?: boolean): string | null;
@@ -180,7 +180,21 @@ export interface LoopDetectionCall {
180
180
  export declare class LoopDetectionTracker {
181
181
  private readonly config;
182
182
  private readonly state;
183
- constructor(config?: Partial<LoopDetectionConfig>);
183
+ /** Where relative paths in a call resolve, to see whether they changed. */
184
+ private readonly root;
185
+ /**
186
+ * The files a failed or no-op call named, as they were when it was judged.
187
+ * The verdicts said "nothing has changed, so neither will the result"; a
188
+ * write the tracker never sees -- a shell `sed -i`, a rollback, the user --
189
+ * made that false, and the call that would now work was stopped.
190
+ */
191
+ private readonly stamps;
192
+ private pendingSpelled;
193
+ constructor(config?: Partial<LoopDetectionConfig>, options?: {
194
+ root?: string;
195
+ });
196
+ /** Drop what was concluded about one call, so it is judged afresh. */
197
+ private forgetVerdicts;
184
198
  inspect(call: LoopDetectionCall): LoopDetectionVerdict;
185
199
  /**
186
200
  * Attribute an outcome to the call `inspect()` last saw.
@@ -26,14 +26,14 @@ export declare const GlobalSettingsSchema: z.ZodPipe<z.ZodObject<{
26
26
  }>>>;
27
27
  toolAutoApprove: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
28
28
  tuiTheme: z.ZodCatch<z.ZodOptional<z.ZodString>>;
29
- disabledTools: z.ZodOptional<z.ZodPipe<z.ZodPreprocess<z.ZodOptional<z.ZodArray<z.ZodString>>>, z.ZodTransform<string[] | undefined, string[] | undefined>>>;
29
+ disabledTools: z.ZodOptional<z.ZodPipe<z.ZodPreprocess<z.ZodOptional<z.ZodArray<z.ZodString>>, unknown>, z.ZodTransform<string[] | undefined, string[] | undefined>>>;
30
30
  tools: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
31
31
  web_search: "web_search";
32
32
  }> & z.core.$partial, z.ZodObject<{
33
33
  enabled: z.ZodBoolean;
34
34
  }, z.core.$strip>>>;
35
- disabledPlugins: z.ZodOptional<z.ZodPipe<z.ZodPreprocess<z.ZodOptional<z.ZodArray<z.ZodString>>>, z.ZodTransform<string[] | undefined, string[] | undefined>>>;
36
- disabledAgentPlugins: z.ZodOptional<z.ZodPipe<z.ZodPreprocess<z.ZodOptional<z.ZodArray<z.ZodString>>>, z.ZodTransform<string[] | undefined, string[] | undefined>>>;
35
+ disabledPlugins: z.ZodOptional<z.ZodPipe<z.ZodPreprocess<z.ZodOptional<z.ZodArray<z.ZodString>>, unknown>, z.ZodTransform<string[] | undefined, string[] | undefined>>>;
36
+ disabledAgentPlugins: z.ZodOptional<z.ZodPipe<z.ZodPreprocess<z.ZodOptional<z.ZodArray<z.ZodString>>, unknown>, z.ZodTransform<string[] | undefined, string[] | undefined>>>;
37
37
  bundledSkills: z.ZodCatch<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
38
38
  enabled: z.ZodBoolean;
39
39
  }, z.core.$strip>>>>;
@@ -47,6 +47,15 @@ export type RememberOutcome =
47
47
  export declare const NEAR_DUPLICATE_SIMILARITY = 0.85;
48
48
  /** How alike two notes read, 0 to 1: the share of letter pairs they have in common. */
49
49
  export declare function noteSimilarity(a: string, b: string): number;
50
+ /**
51
+ * Whether one note negates what the other says: their negations differ.
52
+ *
53
+ * {@link noteSimilarity} counts letter pairs, so "the cache is enabled" and
54
+ * "the cache is not enabled" score far above the duplicate bar, and the
55
+ * correction was refused as saying "nearly the same" (automaticum audit
56
+ * 2026-11-08, rest N6). A pair that differs here is never a duplicate.
57
+ */
58
+ export declare function negationDiffers(a: string, b: string): boolean;
50
59
  export interface RecalledMemory extends MemoryItem {
51
60
  /** The reranker's score, 0 to 1, when there was one. */
52
61
  relevance?: number;
@@ -26,6 +26,17 @@ export type SliceStatus = "pending" | "done";
26
26
  export type TaskStatus = "pending" | "in_progress" | "done" | "blocked";
27
27
  export type Verdict = "pass" | "needs_remediation";
28
28
  export type UatResult = "pass" | "fail" | "needs_human";
29
+ /**
30
+ * A UAT result as a model writes it, or undefined when it is none of the
31
+ * three. "failed", "FAIL" and "needs human" were not "fail", so a failed
32
+ * check closed the slice (automaticum audit 2026-11-08, rest C1).
33
+ */
34
+ export declare function parseUatResult(value: string | undefined): UatResult | undefined;
35
+ /**
36
+ * Whether verify output reports failures: "1 failing", "3 failed", "FAIL".
37
+ * A count of zero does not, and neither does a word inside another.
38
+ */
39
+ export declare function reportsFailure(evidence: string): boolean;
29
40
  export interface SddRequirement {
30
41
  id: string;
31
42
  title: string;
@@ -231,7 +242,9 @@ export declare class SddEngine {
231
242
  result: UatResult;
232
243
  note?: string;
233
244
  }[];
234
- }): void;
245
+ }): {
246
+ awaitingPerson: string[];
247
+ };
235
248
  validateMilestone(input: {
236
249
  verdict: Verdict;
237
250
  findings: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cerebriline/core",
3
3
  "description": "Cerebriline Core SDK for Node Runtime",
4
- "version": "4.100.274",
4
+ "version": "4.100.277",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/mann1x/cline.git",
@@ -72,24 +72,28 @@
72
72
  "node-machine-id": "^1.1.12",
73
73
  "officeparser": "8.0.0",
74
74
  "pdfjs-dist": "6.2.108",
75
- "simple-git": "3.36.0",
75
+ "simple-git": "4.0.2",
76
76
  "tesseract.js": "7.0.0",
77
77
  "tree-sitter-wasms": "^0.1.12",
78
78
  "turndown": "7.2.0",
79
79
  "web-tree-sitter": "^0.25.0",
80
80
  "ws": "^8.20.0",
81
81
  "yaml": "^2.8.2",
82
- "zod": "4.4.3",
83
- "@cerebriline/agents": "4.100.274",
84
- "@cerebriline/llms": "4.100.274",
85
- "@cerebriline/shared": "4.100.274"
82
+ "zod": "4.6.7",
83
+ "@cerebriline/agents": "4.100.277",
84
+ "@cerebriline/llms": "4.100.277",
85
+ "@cerebriline/shared": "4.100.277"
86
86
  },
87
87
  "peerDependencies": {
88
- "posthog-node": "^5.8.0"
88
+ "posthog-node": "^5.8.0",
89
+ "puppeteer-core": "^23.4.0"
89
90
  },
90
91
  "peerDependenciesMeta": {
91
92
  "posthog-node": {
92
93
  "optional": true
94
+ },
95
+ "puppeteer-core": {
96
+ "optional": true
93
97
  }
94
98
  },
95
99
  "engines": {