tarsk 0.5.74 → 0.5.76

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 (167) hide show
  1. package/dist/bundled-skills/skill-creator/scripts/__tests__/quick_validate.test.js +79 -0
  2. package/dist/bundled-skills/skill-creator/scripts/quick_validate.js +78 -65
  3. package/dist/index.js +21828 -13103
  4. package/dist/jelly.webp +0 -0
  5. package/dist/public/assets/account-view-CWtpznW2.js +1 -0
  6. package/dist/public/assets/alert-dialog-BxMfaLuO.js +7 -0
  7. package/dist/public/assets/api-DX1ny6q-.js +2 -0
  8. package/dist/public/assets/async-error-boundary-BX1G17o9.js +1 -0
  9. package/dist/public/assets/async-loading-fallback-V0EaQ_Kn.js +1 -0
  10. package/dist/public/assets/browser-tab-D_5MLhxE.js +12 -0
  11. package/dist/public/assets/button-kWtLAMpB.js +1 -0
  12. package/dist/public/assets/card-B_EASkic.js +1 -0
  13. package/dist/public/assets/chat-dock-context-8K8Ikjgy.js +1 -0
  14. package/dist/public/assets/commit-dialog-CSXPoomw.js +1 -0
  15. package/dist/public/assets/commit-error-dialog-CdcGI69P.js +1 -0
  16. package/dist/public/assets/commit-method-fields-BtEHb0_G.js +1 -0
  17. package/dist/public/assets/context-menu-BcM6I0Sx.js +1 -0
  18. package/dist/public/assets/conversation-history-view-CuzU9qF6.js +1 -0
  19. package/dist/public/assets/create-project-dialog-a6Wgq-Z8.js +2 -0
  20. package/dist/public/assets/create-project-workspace-Dv_lEfZx.js +2 -0
  21. package/dist/public/assets/create-repo-dialog-BTIQ5Nw4.js +1 -0
  22. package/dist/public/assets/{delete-confirm-dialog-3DX1u0Dg.js → delete-confirm-dialog-Dl76vaxb.js} +1 -1
  23. package/dist/public/assets/diff-view-DA1uT9tc.js +4 -0
  24. package/dist/public/assets/dist-C2G92uPn.js +1 -0
  25. package/dist/public/assets/dist-CHhgoHp6.js +1 -0
  26. package/dist/public/assets/dist-CTLFS4dn.js +2 -0
  27. package/dist/public/assets/dist-D-2G8xGB.js +5 -0
  28. package/dist/public/assets/dist-DD4GtbiM.js +1 -0
  29. package/dist/public/assets/{dist-rO95BjzU.js → dist-DoxvnNEY.js} +1 -1
  30. package/dist/public/assets/dist-DsmF-KJ-.js +1 -0
  31. package/dist/public/assets/dist-c_QADQ5u.js +1 -0
  32. package/dist/public/assets/dist-yM5kyz9Q.js +1 -0
  33. package/dist/public/assets/es2015-BlPKkFZZ.js +41 -0
  34. package/dist/public/assets/explorer-monaco-editor-BdZ_bBqh.js +1 -0
  35. package/dist/public/assets/explorer-tab-view-CewTYYOm.js +2 -0
  36. package/dist/public/assets/explorer-tree-C0VDhihz.js +1 -0
  37. package/dist/public/assets/explorer-view-RCfDm3p5.js +76 -0
  38. package/dist/public/assets/git-history-dialog-DL0Trxiz.js +1 -0
  39. package/dist/public/assets/index-B3-5kIOf.js +3658 -0
  40. package/dist/public/assets/index-BLNUy5nZ.css +1 -0
  41. package/dist/public/assets/merged-pr-dialog-BzND8nzx.js +1 -0
  42. package/dist/public/assets/model-list-controls-I67L2x3H.js +1 -0
  43. package/dist/public/assets/onboarding-dialog-DY8v11hv.js +1 -0
  44. package/dist/public/assets/project-coding-view-DxOwsjtt.js +1 -0
  45. package/dist/public/assets/project-danger-zone-view-CkvKOQrl.js +1 -0
  46. package/dist/public/assets/project-env-vars-view-DYLWA7s0.js +1 -0
  47. package/dist/public/assets/project-model-aliases-view-DWu9khLA.js +1 -0
  48. package/dist/public/assets/project-settings-view-DJfmaWn6.js +1 -0
  49. package/dist/public/assets/project-tools-view-BEjBkghz.js +1 -0
  50. package/dist/public/assets/providers-list-view-jMEPJCci.js +1 -0
  51. package/dist/public/assets/pull-request-dialog-B_JCqT53.js +1 -0
  52. package/dist/public/assets/pull-with-changes-dialog-V3_km2zQ.js +1 -0
  53. package/dist/public/assets/push-before-pr-dialog-CarrD3y2.js +1 -0
  54. package/dist/public/assets/radio-group-Dn_pN-pn.js +1 -0
  55. package/dist/public/assets/scroll-area-lkVMElz5.js +1 -0
  56. package/dist/public/assets/settings-general-view-BhrfHGfQ.js +1 -0
  57. package/dist/public/assets/settings-list-DiiYzOxn.js +1 -0
  58. package/dist/public/assets/settings-logs-view-DbKM1SNk.js +5 -0
  59. package/dist/public/assets/settings-mcp-servers-view-4FpPIeYV.js +5 -0
  60. package/dist/public/assets/settings-models-view-CJVeo9ad.js +1 -0
  61. package/dist/public/assets/settings-skills-view-DoRPGbHG.js +3 -0
  62. package/dist/public/assets/settings-slack-view-Cc1NgVkx.js +1 -0
  63. package/dist/public/assets/settings-slash-commands-view-CmlWqqmi.js +1 -0
  64. package/dist/public/assets/settings-statistics-view-DRuyEbcN.js +1 -0
  65. package/dist/public/assets/settings-storage-view-DihbtUYb.js +1 -0
  66. package/dist/public/assets/settings-subagents-view-B2RvxDZI.js +2 -0
  67. package/dist/public/assets/settings-system-prompt-view-CvVbgjNN.js +1 -0
  68. package/dist/public/assets/settings-view-CPUAjTMa.js +2 -0
  69. package/dist/public/assets/slug-utils-CQ8PMWUL.js +1 -0
  70. package/dist/public/assets/store-BSzKIu5G.js +9 -0
  71. package/dist/public/assets/suspense-resource-BFrb_XJX.js +1 -0
  72. package/dist/public/assets/table-A3cgauiZ.js +1 -0
  73. package/dist/public/assets/tasks-view-CvFFLPeD.js +1 -0
  74. package/dist/public/assets/{terminal-panel-DHDoOXAH.js → terminal-panel-DIh6it7K.js} +3 -3
  75. package/dist/public/assets/toggle-group-Q36wRGKA.js +1 -0
  76. package/dist/public/assets/tooltip-Db8UeYxm.js +1 -0
  77. package/dist/public/assets/{use-active-dock-panel-instance-cO_DR87G.js → use-active-dock-panel-instance-DRfRj6MV.js} +1 -1
  78. package/dist/public/assets/use-installed-ai-files-C8nNWGC7.js +1 -0
  79. package/dist/public/assets/{use-suspense-resource-Dkz6ddFN.js → use-suspense-resource-Dakt9lfT.js} +1 -1
  80. package/dist/public/assets/useBaseQuery-34f0-SVd.js +1 -0
  81. package/dist/public/assets/{web-C7jr0n2X.js → web-Bn9n5e7r.js} +1 -1
  82. package/dist/public/assets/{web-D0nlJHDu.js → web-C2KGFouM.js} +1 -1
  83. package/dist/public/assets/{web-jJ1krOD-.js → web-Dk3GAfTy.js} +1 -1
  84. package/dist/public/assets/{web-DPW3m0cL.js → web-DycfRH4j.js} +1 -1
  85. package/dist/public/browser-preview-rpc.js +107 -82
  86. package/dist/public/index.html +26 -33
  87. package/dist/recommended-models.txt +2 -2
  88. package/package.json +6 -6
  89. package/dist/public/assets/Combination-BdvBzSm4.js +0 -41
  90. package/dist/public/assets/account-view-c-UG0JKH.js +0 -1
  91. package/dist/public/assets/alert-dialog-DAHkynVZ.js +0 -7
  92. package/dist/public/assets/api-D1GxdEEp.js +0 -2
  93. package/dist/public/assets/async-error-boundary-DNJqC4BV.js +0 -1
  94. package/dist/public/assets/async-loading-fallback-D2X0o4Qa.js +0 -1
  95. package/dist/public/assets/browser-tab-BKQJKTg8.js +0 -12
  96. package/dist/public/assets/button-B6HDsfd5.js +0 -1
  97. package/dist/public/assets/card-DZGd45nw.js +0 -1
  98. package/dist/public/assets/chat-dock-context-8_5G30KG.js +0 -1
  99. package/dist/public/assets/commit-dialog-OQFa4W6i.js +0 -1
  100. package/dist/public/assets/commit-error-dialog-BFByxoUG.js +0 -1
  101. package/dist/public/assets/commit-method-fields-BihSf23f.js +0 -1
  102. package/dist/public/assets/context-menu-e5jeH0Jl.js +0 -1
  103. package/dist/public/assets/conversation-history-view-BUlO9oJ6.js +0 -1
  104. package/dist/public/assets/create-project-dialog-CY5wIGQV.js +0 -2
  105. package/dist/public/assets/create-project-workspace-ClILToZd.js +0 -1
  106. package/dist/public/assets/create-repo-dialog-CKUQoOaX.js +0 -1
  107. package/dist/public/assets/dialog--0foS3aw.js +0 -1
  108. package/dist/public/assets/diff-view-DLPu21IR.js +0 -4
  109. package/dist/public/assets/dist-Bxyh1Ml_.js +0 -1
  110. package/dist/public/assets/dist-CFXDhuA_.js +0 -5
  111. package/dist/public/assets/dist-CNOCRPxn.js +0 -1
  112. package/dist/public/assets/dist-Cda_ffeR.js +0 -1
  113. package/dist/public/assets/dist-CkQILg8A.js +0 -1
  114. package/dist/public/assets/dist-CqGsum35.js +0 -1
  115. package/dist/public/assets/dist-DjiNKpTV.js +0 -2
  116. package/dist/public/assets/dist-eMdiO0P3.js +0 -1
  117. package/dist/public/assets/explorer-tab-view-nzl0M0Vm.js +0 -2
  118. package/dist/public/assets/explorer-tree-Bkb6dzmf.js +0 -1
  119. package/dist/public/assets/explorer-view-NcArt0_H.js +0 -75
  120. package/dist/public/assets/git-history-dialog-rWkjoaR5.js +0 -1
  121. package/dist/public/assets/index-BOB3ZUQs.js +0 -3386
  122. package/dist/public/assets/index-BdGMz8sL.css +0 -1
  123. package/dist/public/assets/markdown-renderer-BkKibNMs.js +0 -8
  124. package/dist/public/assets/mcp-server-card-DFT7uyRh.js +0 -1
  125. package/dist/public/assets/merged-pr-dialog-BOrFaYk6.js +0 -1
  126. package/dist/public/assets/model-list-controls-CpQjn6i7.js +0 -1
  127. package/dist/public/assets/ndjson-stream-DeGpE5o5.js +0 -2
  128. package/dist/public/assets/onboarding-dialog-HJpyzVWa.js +0 -1
  129. package/dist/public/assets/project-env-vars-view-C9VTTfTo.js +0 -1
  130. package/dist/public/assets/project-model-aliases-view-DKRoV7Gc.js +0 -1
  131. package/dist/public/assets/project-settings-view-BDYqpibk.js +0 -1
  132. package/dist/public/assets/project-tools-view-9WUc4Yca.js +0 -1
  133. package/dist/public/assets/providers-list-view-BgvIWP_0.js +0 -1
  134. package/dist/public/assets/pull-request-dialog-BM1dkFpK.js +0 -1
  135. package/dist/public/assets/pull-with-changes-dialog-Bjl_esir.js +0 -1
  136. package/dist/public/assets/push-before-pr-dialog-Cbc_zaI8.js +0 -1
  137. package/dist/public/assets/query-keys-5QPW6Dv-.js +0 -1
  138. package/dist/public/assets/radio-group-CMW5ku-w.js +0 -1
  139. package/dist/public/assets/scenic-chrome-CbN3vum7.js +0 -1
  140. package/dist/public/assets/scroll-area-BMQFeWmq.js +0 -1
  141. package/dist/public/assets/settings-general-view-BaMVw6kD.js +0 -1
  142. package/dist/public/assets/settings-instructions-view-BRE87H2U.js +0 -1
  143. package/dist/public/assets/settings-list-BpPbGcpS.js +0 -1
  144. package/dist/public/assets/settings-logs-view-Bbue8ZOn.js +0 -5
  145. package/dist/public/assets/settings-mcp-servers-view-BiMCy8sH.js +0 -5
  146. package/dist/public/assets/settings-models-view-BkZtGcUP.js +0 -1
  147. package/dist/public/assets/settings-rules-view-TK7LEC-0.js +0 -8
  148. package/dist/public/assets/settings-skills-view-Bv9Kn55r.js +0 -3
  149. package/dist/public/assets/settings-slack-view-Dy2bFJqU.js +0 -1
  150. package/dist/public/assets/settings-slash-commands-view-DiR1IyMF.js +0 -1
  151. package/dist/public/assets/settings-statistics-view-DX1UVeCJ.js +0 -1
  152. package/dist/public/assets/settings-storage-view-D8tHP8XT.js +0 -1
  153. package/dist/public/assets/settings-subagents-view-Bz7jBhbB.js +0 -2
  154. package/dist/public/assets/settings-system-prompt-view-VHGAqfQk.js +0 -1
  155. package/dist/public/assets/settings-view-QBOhYAyv.js +0 -2
  156. package/dist/public/assets/skeleton-DvLd14RU.js +0 -1
  157. package/dist/public/assets/store-CHF6tOp2.js +0 -9
  158. package/dist/public/assets/suspense-resource-DnYnmTbs.js +0 -1
  159. package/dist/public/assets/switch-P5m18oUl.js +0 -1
  160. package/dist/public/assets/table-MUx4ZxvS.js +0 -1
  161. package/dist/public/assets/tasks-view-l00Nc2fV.js +0 -2
  162. package/dist/public/assets/toggle-group-DMR7z3pz.js +0 -1
  163. package/dist/public/assets/tooltip-BtJG5fZl.js +0 -1
  164. package/dist/public/assets/use-installed-ai-files-CJr_PVcY.js +0 -1
  165. package/dist/public/assets/use-open-chat-dock-panel-B31lwcQF.js +0 -1
  166. package/dist/public/assets/useInfiniteQuery-DUeUxDcu.js +0 -1
  167. package/dist/public/assets/utils-CT-Dw22R.js +0 -1
@@ -0,0 +1,79 @@
1
+ const assert = require("node:assert/strict");
2
+ const fs = require("node:fs");
3
+ const os = require("node:os");
4
+ const path = require("node:path");
5
+ const test = require("node:test");
6
+
7
+ const { validateSkill } = require("../quick_validate.js");
8
+
9
+ function withSkill(content, callback) {
10
+ const skillPath = fs.mkdtempSync(path.join(os.tmpdir(), "tarsk-skill-"));
11
+ try {
12
+ if (content !== null) fs.writeFileSync(path.join(skillPath, "SKILL.md"), content);
13
+ return callback(skillPath);
14
+ } finally {
15
+ fs.rmSync(skillPath, { recursive: true, force: true });
16
+ }
17
+ }
18
+
19
+ test("validates a skill with supported frontmatter", () => {
20
+ const result = withSkill(
21
+ "---\nname: example-skill\ndescription: A useful skill\ncompatibility: Works everywhere\n---\n",
22
+ (skillPath) => validateSkill(skillPath),
23
+ );
24
+ assert.deepEqual(result, [true, "Skill is valid!"]);
25
+ });
26
+
27
+ test("rejects missing and malformed skill files", () => {
28
+ assert.deepEqual(withSkill(null, validateSkill), [false, "SKILL.md not found"]);
29
+ assert.deepEqual(withSkill("Skill content", validateSkill), [false, "No YAML frontmatter found"]);
30
+ assert.deepEqual(withSkill("---\nname: example\n", validateSkill), [
31
+ false,
32
+ "Invalid frontmatter format",
33
+ ]);
34
+ });
35
+
36
+ test("rejects invalid frontmatter properties and required fields", () => {
37
+ assert.match(
38
+ withSkill("---\nname: example\ndescription: test\nunknown: value\n---\n", validateSkill)[1],
39
+ /Unexpected key\(s\)/,
40
+ );
41
+ assert.deepEqual(withSkill("---\ndescription: test\n---\n", validateSkill), [
42
+ false,
43
+ "Missing 'name' in frontmatter",
44
+ ]);
45
+ assert.deepEqual(withSkill("---\nname: example\n---\n", validateSkill), [
46
+ false,
47
+ "Missing 'description' in frontmatter",
48
+ ]);
49
+ });
50
+
51
+ test("rejects invalid name, description, and compatibility values", () => {
52
+ assert.match(
53
+ withSkill("---\nname: Bad Name\ndescription: test\n---\n", validateSkill)[1],
54
+ /should be kebab-case/,
55
+ );
56
+ assert.match(
57
+ withSkill("---\nname: -bad\ndescription: test\n---\n", validateSkill)[1],
58
+ /cannot start\/end with hyphen/,
59
+ );
60
+ assert.match(
61
+ withSkill(`---\nname: ${"a".repeat(65)}\ndescription: test\n---\n`, validateSkill)[1],
62
+ /Name is too long/,
63
+ );
64
+ assert.deepEqual(withSkill("---\nname: example\ndescription: <unsafe>\n---\n", validateSkill), [
65
+ false,
66
+ "Description cannot contain angle brackets (< or >)",
67
+ ]);
68
+ assert.match(
69
+ withSkill(`---\nname: example\ndescription: ${"a".repeat(1025)}\n---\n`, validateSkill)[1],
70
+ /Description is too long/,
71
+ );
72
+ assert.match(
73
+ withSkill(
74
+ "---\nname: example\ndescription: test\ncompatibility: " + "a".repeat(501) + "\n---\n",
75
+ validateSkill,
76
+ )[1],
77
+ /Compatibility is too long/,
78
+ );
79
+ });
@@ -34,29 +34,7 @@ function parseSimpleFrontmatter(text) {
34
34
  return frontmatter;
35
35
  }
36
36
 
37
- function validateSkill(skillPath) {
38
- skillPath = path.resolve(skillPath);
39
- const skillMd = path.join(skillPath, "SKILL.md");
40
-
41
- if (!fs.existsSync(skillMd)) {
42
- return [false, "SKILL.md not found"];
43
- }
44
-
45
- const content = fs.readFileSync(skillMd, "utf-8");
46
- if (!content.startsWith("---")) {
47
- return [false, "No YAML frontmatter found"];
48
- }
49
-
50
- const match = content.match(/^---\n([\s\S]*?)\n---/);
51
- if (!match) {
52
- return [false, "Invalid frontmatter format"];
53
- }
54
-
55
- const frontmatter = parseSimpleFrontmatter(match[1]);
56
- if (!frontmatter || typeof frontmatter !== "object") {
57
- return [false, "Frontmatter must be a YAML dictionary"];
58
- }
59
-
37
+ function validateFrontmatter(frontmatter) {
60
38
  const unexpectedKeys = Object.keys(frontmatter).filter((key) => !ALLOWED_PROPERTIES.has(key));
61
39
  if (unexpectedKeys.length > 0) {
62
40
  return [
@@ -66,56 +44,91 @@ function validateSkill(skillPath) {
66
44
  ];
67
45
  }
68
46
 
69
- if (!("name" in frontmatter)) {
70
- return [false, "Missing 'name' in frontmatter"];
47
+ if (!("name" in frontmatter)) return [false, "Missing 'name' in frontmatter"];
48
+ if (!("description" in frontmatter)) return [false, "Missing 'description' in frontmatter"];
49
+ return [true, ""];
50
+ }
51
+
52
+ function validateName(name) {
53
+ if (!name) return [true, ""];
54
+ const failure = [
55
+ [
56
+ !/^[a-z0-9-]+$/.test(name),
57
+ `Name '${name}' should be kebab-case (lowercase letters, digits, and hyphens only)`,
58
+ ],
59
+ [
60
+ /^-|-$|--/.test(name),
61
+ `Name '${name}' cannot start/end with hyphen or contain consecutive hyphens`,
62
+ ],
63
+ [name.length > 64, `Name is too long (${name.length} characters). Maximum is 64 characters.`],
64
+ ].find(function (result) {
65
+ return result[0];
66
+ });
67
+ return failure ? [false, failure[1]] : [true, ""];
68
+ }
69
+
70
+ function validateDescription(description) {
71
+ if (!description) return [true, ""];
72
+ if (description.includes("<") || description.includes(">")) {
73
+ return [false, "Description cannot contain angle brackets (< or >)"];
71
74
  }
72
- if (!("description" in frontmatter)) {
73
- return [false, "Missing 'description' in frontmatter"];
75
+ if (description.length > 1024) {
76
+ return [
77
+ false,
78
+ `Description is too long (${description.length} characters). Maximum is 1024 characters.`,
79
+ ];
74
80
  }
81
+ return [true, ""];
82
+ }
75
83
 
76
- const name = String(frontmatter.name ?? "").trim();
77
- if (name) {
78
- if (!/^[a-z0-9-]+$/.test(name)) {
79
- return [
80
- false,
81
- `Name '${name}' should be kebab-case (lowercase letters, digits, and hyphens only)`,
82
- ];
83
- }
84
- if (name.startsWith("-") || name.endsWith("-") || name.includes("--")) {
85
- return [false, `Name '${name}' cannot start/end with hyphen or contain consecutive hyphens`];
86
- }
87
- if (name.length > 64) {
88
- return [false, `Name is too long (${name.length} characters). Maximum is 64 characters.`];
89
- }
84
+ function validateCompatibility(compatibility) {
85
+ if (!compatibility) return [true, ""];
86
+ if (typeof compatibility !== "string") {
87
+ return [false, `Compatibility must be a string, got ${typeof compatibility}`];
90
88
  }
91
-
92
- const description = String(frontmatter.description ?? "").trim();
93
- if (description) {
94
- if (description.includes("<") || description.includes(">")) {
95
- return [false, "Description cannot contain angle brackets (< or >)"];
96
- }
97
- if (description.length > 1024) {
98
- return [
99
- false,
100
- `Description is too long (${description.length} characters). Maximum is 1024 characters.`,
101
- ];
102
- }
89
+ if (compatibility.length > 500) {
90
+ return [
91
+ false,
92
+ `Compatibility is too long (${compatibility.length} characters). Maximum is 500 characters.`,
93
+ ];
103
94
  }
95
+ return [true, ""];
96
+ }
104
97
 
105
- const compatibility = frontmatter.compatibility;
106
- if (compatibility) {
107
- if (typeof compatibility !== "string") {
108
- return [false, `Compatibility must be a string, got ${typeof compatibility}`];
109
- }
110
- if (compatibility.length > 500) {
111
- return [
112
- false,
113
- `Compatibility is too long (${compatibility.length} characters). Maximum is 500 characters.`,
114
- ];
115
- }
98
+ function readSkillFrontmatter(skillMd) {
99
+ if (!fs.existsSync(skillMd)) return [false, "SKILL.md not found"];
100
+
101
+ const content = fs.readFileSync(skillMd, "utf-8");
102
+ if (!content.startsWith("---")) return [false, "No YAML frontmatter found"];
103
+
104
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
105
+ if (!match) return [false, "Invalid frontmatter format"];
106
+
107
+ const frontmatter = parseSimpleFrontmatter(match[1]);
108
+ if (!frontmatter || typeof frontmatter !== "object") {
109
+ return [false, "Frontmatter must be a YAML dictionary"];
116
110
  }
111
+ return [true, frontmatter];
112
+ }
117
113
 
118
- return [true, "Skill is valid!"];
114
+ function isFailedValidation(result) {
115
+ return !result[0];
116
+ }
117
+
118
+ function validateSkill(skillPath) {
119
+ const skillMd = path.join(path.resolve(skillPath), "SKILL.md");
120
+ const frontmatterReadResult = readSkillFrontmatter(skillMd);
121
+ if (!frontmatterReadResult[0]) return frontmatterReadResult;
122
+
123
+ const frontmatter = frontmatterReadResult[1];
124
+ const failedValidation = [
125
+ validateFrontmatter(frontmatter),
126
+ validateName(String(frontmatter.name ?? "").trim()),
127
+ validateDescription(String(frontmatter.description ?? "").trim()),
128
+ validateCompatibility(frontmatter.compatibility),
129
+ ].find(isFailedValidation);
130
+
131
+ return failedValidation ?? [true, "Skill is valid!"];
119
132
  }
120
133
 
121
134
  if (require.main === module) {