@travisennis/acai 0.0.12 → 0.0.13

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 (237) hide show
  1. package/README.md +3 -2
  2. package/dist/agent/index.d.ts.map +1 -1
  3. package/dist/agent/index.js +2 -5
  4. package/dist/commands/history/types.d.ts +3 -2
  5. package/dist/commands/history/types.d.ts.map +1 -1
  6. package/dist/commands/init-project/utils.d.ts +0 -1
  7. package/dist/commands/init-project/utils.d.ts.map +1 -1
  8. package/dist/commands/init-project/utils.js +1 -1
  9. package/dist/commands/manager.d.ts.map +1 -1
  10. package/dist/commands/manager.js +0 -18
  11. package/dist/commands/share/html-renderer.d.ts.map +1 -1
  12. package/dist/commands/share/html-renderer.js +54 -48
  13. package/dist/commands/tools/index.js +39 -38
  14. package/dist/config/index.d.ts +0 -2
  15. package/dist/config/index.d.ts.map +1 -1
  16. package/dist/config/index.js +2 -6
  17. package/dist/index.d.ts +14 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +94 -76
  20. package/dist/models/manager.d.ts +1 -10
  21. package/dist/models/manager.d.ts.map +1 -1
  22. package/dist/models/manager.js +2 -2
  23. package/dist/models/opencode-go-provider.d.ts +4 -4
  24. package/dist/models/opencode-go-provider.d.ts.map +1 -1
  25. package/dist/models/opencode-go-provider.js +29 -35
  26. package/dist/models/providers.d.ts +1 -1
  27. package/dist/models/providers.d.ts.map +1 -1
  28. package/dist/prompts/system-prompt.d.ts +0 -2
  29. package/dist/prompts/system-prompt.d.ts.map +1 -1
  30. package/dist/prompts/system-prompt.js +6 -10
  31. package/dist/repl/index.d.ts +27 -11
  32. package/dist/repl/index.d.ts.map +1 -1
  33. package/dist/repl/index.js +238 -254
  34. package/dist/skills/index.d.ts +12 -2
  35. package/dist/skills/index.d.ts.map +1 -1
  36. package/dist/skills/index.js +123 -73
  37. package/dist/terminal/control.d.ts +1 -21
  38. package/dist/terminal/control.d.ts.map +1 -1
  39. package/dist/terminal/control.js +1 -32
  40. package/dist/terminal/formatting.d.ts +0 -33
  41. package/dist/terminal/formatting.d.ts.map +1 -1
  42. package/dist/terminal/formatting.js +0 -91
  43. package/dist/terminal/highlight/theme.d.ts +0 -37
  44. package/dist/terminal/highlight/theme.d.ts.map +1 -1
  45. package/dist/terminal/highlight/theme.js +1 -79
  46. package/dist/terminal/keys.d.ts +0 -97
  47. package/dist/terminal/keys.d.ts.map +1 -1
  48. package/dist/terminal/keys.js +0 -194
  49. package/dist/terminal/select-prompt.d.ts.map +1 -1
  50. package/dist/terminal/select-prompt.js +65 -51
  51. package/dist/terminal/style.d.ts +1 -1
  52. package/dist/terminal/style.d.ts.map +1 -1
  53. package/dist/terminal/supports-color.d.ts.map +1 -1
  54. package/dist/terminal/supports-color.js +38 -20
  55. package/dist/terminal/supports-hyperlinks.d.ts +3 -0
  56. package/dist/terminal/supports-hyperlinks.d.ts.map +1 -1
  57. package/dist/terminal/supports-hyperlinks.js +72 -31
  58. package/dist/terminal/table/layout-manager.d.ts +0 -20
  59. package/dist/terminal/table/layout-manager.d.ts.map +1 -1
  60. package/dist/terminal/table/layout-manager.js +68 -44
  61. package/dist/terminal/table/utils.d.ts +0 -1
  62. package/dist/terminal/table/utils.d.ts.map +1 -1
  63. package/dist/terminal/table/utils.js +2 -4
  64. package/dist/tools/apply-patch.d.ts +5 -3
  65. package/dist/tools/apply-patch.d.ts.map +1 -1
  66. package/dist/tools/apply-patch.js +154 -123
  67. package/dist/tools/bash.d.ts.map +1 -1
  68. package/dist/tools/bash.js +11 -8
  69. package/dist/tools/dynamic-tool-loader.d.ts +6 -1
  70. package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
  71. package/dist/tools/dynamic-tool-loader.js +154 -135
  72. package/dist/tools/index.d.ts +3 -133
  73. package/dist/tools/index.d.ts.map +1 -1
  74. package/dist/tools/index.js +0 -20
  75. package/dist/tools/read-file.d.ts.map +1 -1
  76. package/dist/tools/read-file.js +32 -13
  77. package/dist/tools/skill.d.ts.map +1 -1
  78. package/dist/tools/skill.js +20 -13
  79. package/dist/tools/web-fetch.d.ts +2 -6
  80. package/dist/tools/web-fetch.d.ts.map +1 -1
  81. package/dist/tools/web-fetch.js +59 -36
  82. package/dist/tools/web-search.d.ts +0 -4
  83. package/dist/tools/web-search.d.ts.map +1 -1
  84. package/dist/tools/web-search.js +40 -32
  85. package/dist/tui/autocomplete/utils.d.ts +0 -15
  86. package/dist/tui/autocomplete/utils.d.ts.map +1 -1
  87. package/dist/tui/autocomplete/utils.js +0 -85
  88. package/dist/tui/autocomplete.d.ts +1 -1
  89. package/dist/tui/autocomplete.d.ts.map +1 -1
  90. package/dist/tui/autocomplete.js +1 -1
  91. package/dist/tui/components/editor.d.ts +12 -0
  92. package/dist/tui/components/editor.d.ts.map +1 -1
  93. package/dist/tui/components/editor.js +181 -195
  94. package/dist/tui/components/input.d.ts +4 -0
  95. package/dist/tui/components/input.d.ts.map +1 -1
  96. package/dist/tui/components/input.js +33 -31
  97. package/dist/tui/components/markdown.d.ts +30 -0
  98. package/dist/tui/components/markdown.d.ts.map +1 -1
  99. package/dist/tui/components/markdown.js +274 -242
  100. package/dist/tui/components/modal.d.ts.map +1 -1
  101. package/dist/tui/components/modal.js +11 -11
  102. package/dist/tui/components/select-list.d.ts +5 -0
  103. package/dist/tui/components/select-list.d.ts.map +1 -1
  104. package/dist/tui/components/select-list.js +69 -98
  105. package/dist/tui/components/table.d.ts +6 -0
  106. package/dist/tui/components/table.d.ts.map +1 -1
  107. package/dist/tui/components/table.js +61 -52
  108. package/dist/tui/index.d.ts +1 -8
  109. package/dist/tui/index.d.ts.map +1 -1
  110. package/dist/tui/index.js +0 -8
  111. package/dist/tui/tui.d.ts +9 -0
  112. package/dist/tui/tui.d.ts.map +1 -1
  113. package/dist/tui/tui.js +78 -48
  114. package/dist/tui/utils.d.ts +7 -0
  115. package/dist/tui/utils.d.ts.map +1 -1
  116. package/dist/tui/utils.js +117 -53
  117. package/dist/utils/bash.d.ts.map +1 -1
  118. package/dist/utils/bash.js +121 -104
  119. package/dist/utils/command-protection.d.ts +3 -2
  120. package/dist/utils/command-protection.d.ts.map +1 -1
  121. package/dist/utils/command-protection.js +42 -33
  122. package/dist/utils/filesystem/operations.d.ts +0 -15
  123. package/dist/utils/filesystem/operations.d.ts.map +1 -1
  124. package/dist/utils/filesystem/operations.js +1 -38
  125. package/dist/utils/filesystem/security.d.ts.map +1 -1
  126. package/dist/utils/filesystem/security.js +22 -15
  127. package/dist/utils/filetype-detection.d.ts +0 -1
  128. package/dist/utils/filetype-detection.d.ts.map +1 -1
  129. package/dist/utils/filetype-detection.js +0 -12
  130. package/dist/utils/formatting.d.ts +0 -30
  131. package/dist/utils/formatting.d.ts.map +1 -1
  132. package/dist/utils/formatting.js +0 -44
  133. package/dist/utils/git.d.ts +4 -6
  134. package/dist/utils/git.d.ts.map +1 -1
  135. package/dist/utils/git.js +36 -46
  136. package/dist/utils/ignore.d.ts +1 -1
  137. package/dist/utils/ignore.d.ts.map +1 -1
  138. package/dist/utils/ignore.js +1 -1
  139. package/dist/utils/process.d.ts.map +1 -1
  140. package/dist/utils/process.js +77 -79
  141. package/dist/utils/yaml.d.ts +0 -1
  142. package/dist/utils/yaml.d.ts.map +1 -1
  143. package/dist/utils/yaml.js +80 -89
  144. package/dist/utils/zod.d.ts +0 -3
  145. package/dist/utils/zod.d.ts.map +1 -1
  146. package/dist/utils/zod.js +0 -7
  147. package/package.json +25 -24
  148. package/dist/agent/sub-agent.d.ts +0 -23
  149. package/dist/agent/sub-agent.d.ts.map +0 -1
  150. package/dist/agent/sub-agent.js +0 -109
  151. package/dist/commands/add-directory/index.d.ts +0 -3
  152. package/dist/commands/add-directory/index.d.ts.map +0 -1
  153. package/dist/commands/add-directory/index.js +0 -50
  154. package/dist/commands/add-directory/utils.d.ts +0 -3
  155. package/dist/commands/add-directory/utils.d.ts.map +0 -1
  156. package/dist/commands/add-directory/utils.js +0 -15
  157. package/dist/commands/clear/index.d.ts +0 -3
  158. package/dist/commands/clear/index.d.ts.map +0 -1
  159. package/dist/commands/clear/index.js +0 -13
  160. package/dist/commands/generate-rules/index.d.ts +0 -3
  161. package/dist/commands/generate-rules/index.d.ts.map +0 -1
  162. package/dist/commands/generate-rules/index.js +0 -206
  163. package/dist/commands/generate-rules/service.d.ts +0 -22
  164. package/dist/commands/generate-rules/service.d.ts.map +0 -1
  165. package/dist/commands/generate-rules/service.js +0 -103
  166. package/dist/commands/generate-rules/utils.d.ts +0 -5
  167. package/dist/commands/generate-rules/utils.d.ts.map +0 -1
  168. package/dist/commands/generate-rules/utils.js +0 -25
  169. package/dist/commands/handoff/index.d.ts +0 -3
  170. package/dist/commands/handoff/index.d.ts.map +0 -1
  171. package/dist/commands/handoff/index.js +0 -97
  172. package/dist/commands/handoff/utils.d.ts +0 -4
  173. package/dist/commands/handoff/utils.d.ts.map +0 -1
  174. package/dist/commands/handoff/utils.js +0 -123
  175. package/dist/commands/list-directories/index.d.ts +0 -3
  176. package/dist/commands/list-directories/index.d.ts.map +0 -1
  177. package/dist/commands/list-directories/index.js +0 -35
  178. package/dist/commands/pickup/index.d.ts +0 -3
  179. package/dist/commands/pickup/index.d.ts.map +0 -1
  180. package/dist/commands/pickup/index.js +0 -141
  181. package/dist/commands/pickup/types.d.ts +0 -6
  182. package/dist/commands/pickup/types.d.ts.map +0 -1
  183. package/dist/commands/pickup/types.js +0 -1
  184. package/dist/commands/pickup/utils.d.ts +0 -7
  185. package/dist/commands/pickup/utils.d.ts.map +0 -1
  186. package/dist/commands/pickup/utils.js +0 -56
  187. package/dist/commands/remove-directory/index.d.ts +0 -3
  188. package/dist/commands/remove-directory/index.d.ts.map +0 -1
  189. package/dist/commands/remove-directory/index.js +0 -55
  190. package/dist/commands/review/index.d.ts +0 -3
  191. package/dist/commands/review/index.d.ts.map +0 -1
  192. package/dist/commands/review/index.js +0 -12
  193. package/dist/commands/review/review-panel.d.ts +0 -3
  194. package/dist/commands/review/review-panel.d.ts.map +0 -1
  195. package/dist/commands/review/review-panel.js +0 -186
  196. package/dist/commands/review/utils.d.ts +0 -18
  197. package/dist/commands/review/utils.d.ts.map +0 -1
  198. package/dist/commands/review/utils.js +0 -146
  199. package/dist/commands/shell/index.d.ts +0 -3
  200. package/dist/commands/shell/index.d.ts.map +0 -1
  201. package/dist/commands/shell/index.js +0 -96
  202. package/dist/subagents/index.d.ts +0 -16
  203. package/dist/subagents/index.d.ts.map +0 -1
  204. package/dist/subagents/index.js +0 -231
  205. package/dist/terminal/index.d.ts +0 -9
  206. package/dist/terminal/index.d.ts.map +0 -1
  207. package/dist/terminal/index.js +0 -8
  208. package/dist/tools/agent.d.ts +0 -27
  209. package/dist/tools/agent.d.ts.map +0 -1
  210. package/dist/tools/agent.js +0 -81
  211. package/dist/tools/directory-tree.d.ts +0 -28
  212. package/dist/tools/directory-tree.d.ts.map +0 -1
  213. package/dist/tools/directory-tree.js +0 -154
  214. package/dist/tools/glob.d.ts +0 -35
  215. package/dist/tools/glob.d.ts.map +0 -1
  216. package/dist/tools/glob.js +0 -167
  217. package/dist/tools/grep.d.ts +0 -100
  218. package/dist/tools/grep.d.ts.map +0 -1
  219. package/dist/tools/grep.js +0 -608
  220. package/dist/tools/ls.d.ts +0 -26
  221. package/dist/tools/ls.d.ts.map +0 -1
  222. package/dist/tools/ls.js +0 -83
  223. package/dist/tui/components/header.d.ts +0 -21
  224. package/dist/tui/components/header.d.ts.map +0 -1
  225. package/dist/tui/components/header.js +0 -63
  226. package/dist/utils/bash/parse.d.ts +0 -19
  227. package/dist/utils/bash/parse.d.ts.map +0 -1
  228. package/dist/utils/bash/parse.js +0 -223
  229. package/dist/utils/bash/quote.d.ts +0 -6
  230. package/dist/utils/bash/quote.d.ts.map +0 -1
  231. package/dist/utils/bash/quote.js +0 -23
  232. package/dist/utils/generators.d.ts +0 -3
  233. package/dist/utils/generators.d.ts.map +0 -1
  234. package/dist/utils/generators.js +0 -25
  235. package/dist/utils/glob.d.ts +0 -52
  236. package/dist/utils/glob.d.ts.map +0 -1
  237. package/dist/utils/glob.js +0 -376
@@ -133,66 +133,99 @@ async function shouldSkipEntry(entryPath, entryName) {
133
133
  }
134
134
  return false;
135
135
  }
136
- async function loadSkillsFromDirInternal(dir, source, mode, _useColonPath, subdir = "", visited = new Set()) {
137
- const skills = [];
138
- const fullDir = join(dir, subdir);
139
- // Resolve the real path to detect symlink cycles
136
+ /**
137
+ * Resolves the real path of a directory and checks for symlink cycles.
138
+ * Returns true if the directory can be safely processed.
139
+ */
140
+ async function resolveSkillDir(fullDir, visited) {
140
141
  try {
141
142
  const real = await realpath(fullDir);
142
143
  if (visited.has(real)) {
143
144
  logger.warn(`Skipping ${fullDir}: symlink cycle detected`);
144
- return skills;
145
+ return false;
145
146
  }
146
147
  visited.add(real);
148
+ return true;
147
149
  }
148
150
  catch {
149
- return skills;
151
+ return false;
150
152
  }
151
- let entries;
153
+ }
154
+ /**
155
+ * Reads directory entries, returning null if the directory doesn't exist
156
+ * or can't be read.
157
+ */
158
+ async function readSkillDirEntries(fullDir) {
152
159
  try {
153
160
  // @ts-expect-error - Node.js types have a quirk with withFileTypes
154
- entries = await readdir(fullDir, { withFileTypes: true });
161
+ return await readdir(fullDir, { withFileTypes: true });
155
162
  }
156
163
  catch (error) {
157
- // Directory doesn't exist or can't be read
158
164
  if (error.code !== "ENOENT") {
159
165
  logger.error(error, `Error reading skills directory ${fullDir}:`);
160
166
  }
167
+ return null;
168
+ }
169
+ }
170
+ /**
171
+ * Processes a directory entry in recursive mode: recursively scans subdirectories.
172
+ */
173
+ async function handleRecursiveDir(entryName, dir, source, mode, subdir, visited) {
174
+ const newSubdir = subdir ? join(subdir, entryName) : entryName;
175
+ return await loadSkillsFromDirInternal(dir, source, mode, false, newSubdir, visited);
176
+ }
177
+ /**
178
+ * Processes a directory entry in claude mode: checks for SKILL.md in the subdirectory.
179
+ */
180
+ async function handleClaudeDir(entryName, entryPath, source) {
181
+ const skillPath = join(entryPath, "SKILL.md");
182
+ const skill = await tryLoadSkillFromFile(skillPath, entryName, entryPath, source);
183
+ return skill ? [skill] : [];
184
+ }
185
+ /**
186
+ * Processes a directory entry based on the scan mode.
187
+ */
188
+ async function handleDirEntry(entryName, entryPath, dir, source, mode, subdir, visited) {
189
+ if (mode === "recursive") {
190
+ return await handleRecursiveDir(entryName, dir, source, mode, subdir, visited);
191
+ }
192
+ return await handleClaudeDir(entryName, entryPath, source);
193
+ }
194
+ /**
195
+ * Processes a SKILL.md file entry, loading it as a skill.
196
+ */
197
+ async function handleSkillFile(entryPath, dir, subdir, source) {
198
+ const baseDir = subdir ? join(dir, subdir) : dir;
199
+ const skill = await tryLoadSkillFromFile(entryPath, basename(dirname(entryPath)), baseDir, source);
200
+ return skill ? [skill] : [];
201
+ }
202
+ async function loadSkillsFromDirInternal(dir, source, mode, _useColonPath, subdir = "", visited = new Set()) {
203
+ const skills = [];
204
+ const fullDir = join(dir, subdir);
205
+ // Check symlink cycles
206
+ if (!(await resolveSkillDir(fullDir, visited))) {
161
207
  return skills;
162
208
  }
209
+ // Read directory
210
+ const entries = await readSkillDirEntries(fullDir);
211
+ if (!entries)
212
+ return skills;
213
+ // Process each entry
163
214
  for (const entry of entries) {
164
215
  const entryName = entry.name.toString();
165
216
  const entryPath = join(fullDir, entryName);
166
- // Skip hidden files, symlinks, etc.
167
217
  if (await shouldSkipEntry(entryPath, entryName)) {
168
218
  continue;
169
219
  }
170
- // Handle directories
171
220
  if (entry.isDirectory()) {
172
- if (mode === "recursive") {
173
- // Recursively scan subdirectories
174
- const newSubdir = subdir ? join(subdir, entryName) : entryName;
175
- const subSkills = await loadSkillsFromDirInternal(dir, source, mode, false, newSubdir, visited);
176
- skills.push(...subSkills);
177
- }
178
- else if (mode === "claude") {
179
- // Claude mode: only check immediate subdirectories for SKILL.md
180
- const skillPath = join(entryPath, "SKILL.md");
181
- const skill = await tryLoadSkillFromFile(skillPath, entryName, entryPath, source);
182
- if (skill) {
183
- skills.push(skill);
184
- }
185
- }
186
- continue;
221
+ const subSkills = await handleDirEntry(entryName, entryPath, dir, source, mode, subdir, visited);
222
+ skills.push(...subSkills);
187
223
  }
188
- // Handle files
189
- if (entry.isFile() && entryName === "SKILL.md" && mode === "recursive") {
190
- // Base directory is the directory containing the SKILL.md file
191
- const baseDir = subdir ? join(dir, subdir) : dir;
192
- const skill = await tryLoadSkillFromFile(entryPath, basename(dirname(entryPath)), baseDir, source);
193
- if (skill) {
194
- skills.push(skill);
195
- }
224
+ else if (entry.isFile() &&
225
+ entryName === "SKILL.md" &&
226
+ mode === "recursive") {
227
+ const fileSkills = await handleSkillFile(entryPath, dir, subdir, source);
228
+ skills.push(...fileSkills);
196
229
  }
197
230
  }
198
231
  return skills;
@@ -201,7 +234,7 @@ export async function loadSkillsFromDir(options, subdir = "") {
201
234
  const { dir, source, useColonPath = false } = options;
202
235
  return await loadSkillsFromDirInternal(dir, source, "recursive", useColonPath, subdir);
203
236
  }
204
- export class Skills {
237
+ class Skills {
205
238
  skills;
206
239
  constructor(skills) {
207
240
  this.skills = skills;
@@ -216,58 +249,75 @@ export class Skills {
216
249
  return this.skills.filter((s) => !s.disableModelInvocation);
217
250
  }
218
251
  }
219
- export async function loadSkills(additionalSkillPaths = []) {
220
- const skillMap = new Map();
221
- // Codex: recursive, simple directory name
222
- const codexUserDir = join(homedir(), ".codex", "skills");
223
- for (const skill of await loadSkillsFromDirInternal(codexUserDir, "codex-user", "recursive", false)) {
224
- skillMap.set(skill.name, skill);
225
- }
226
- // Claude: single level only
227
- const claudeUserDir = join(homedir(), ".claude", "skills");
228
- for (const skill of await loadSkillsFromDirInternal(claudeUserDir, "claude-user", "claude", false)) {
229
- skillMap.set(skill.name, skill);
230
- }
231
- const claudeProjectDir = resolve(process.cwd(), ".claude", "skills");
232
- for (const skill of await loadSkillsFromDirInternal(claudeProjectDir, "claude-project", "claude", false)) {
233
- skillMap.set(skill.name, skill);
234
- }
235
- // Deprecated: warn if skills exist in old .acai directories
236
- const deprecatedGlobalDir = join(homedir(), CONFIG_DIR_NAME, "skills");
252
+ async function warnIfDeprecatedSkillsDir(dirPath, message) {
237
253
  try {
238
- const entries = await readdir(deprecatedGlobalDir);
254
+ const entries = await readdir(dirPath);
239
255
  if (entries.length > 0) {
240
- logger.warn("Skills found in ~/.acai/skills/ are deprecated and will not be loaded. Move them to ~/.agents/skills/ to continue using them.");
256
+ logger.warn(message);
241
257
  }
242
258
  }
243
259
  catch {
244
260
  // Directory doesn't exist, no warning needed
245
261
  }
246
- const deprecatedProjectDir = resolve(process.cwd(), CONFIG_DIR_NAME, "skills");
247
- try {
248
- const entries = await readdir(deprecatedProjectDir);
249
- if (entries.length > 0) {
250
- logger.warn("Skills found in .acai/skills/ are deprecated and will not be loaded. Move them to .agents/skills/ to continue using them.");
262
+ }
263
+ async function loadAllSkillDirs(configs, skillMap) {
264
+ for (const { dir, source, mode, colonSeparated } of configs) {
265
+ for (const skill of await loadSkillsFromDirInternal(dir, source, mode, colonSeparated)) {
266
+ skillMap.set(skill.name, skill);
251
267
  }
252
268
  }
253
- catch {
254
- // Directory doesn't exist, no warning needed
255
- }
256
- // .agents: recursive, colon-separated path names (primary)
257
- const agentsGlobalSkillsDir = join(homedir(), ".agents", "skills");
258
- for (const skill of await loadSkillsFromDirInternal(agentsGlobalSkillsDir, "user", "recursive", true)) {
259
- skillMap.set(skill.name, skill);
260
- }
261
- const agentsProjectSkillsDir = resolve(process.cwd(), ".agents", "skills");
262
- for (const skill of await loadSkillsFromDirInternal(agentsProjectSkillsDir, "project", "recursive", true)) {
263
- skillMap.set(skill.name, skill);
264
- }
265
- // Additional skill paths from config (skills.path)
269
+ }
270
+ export async function loadSkills(additionalSkillPathsOrOptions) {
271
+ const options = Array.isArray(additionalSkillPathsOrOptions)
272
+ ? { additionalSkillPaths: additionalSkillPathsOrOptions }
273
+ : (additionalSkillPathsOrOptions ?? {});
274
+ const additionalSkillPaths = options.additionalSkillPaths ?? [];
275
+ const dirs = options.dirs ?? {};
276
+ const skillMap = new Map();
277
+ await warnIfDeprecatedSkillsDir(join(homedir(), CONFIG_DIR_NAME, "skills"), "Skills found in ~/.acai/skills/ are deprecated and will not be loaded. Move them to ~/.agents/skills/ to continue using them.");
278
+ await warnIfDeprecatedSkillsDir(resolve(process.cwd(), CONFIG_DIR_NAME, "skills"), "Skills found in .acai/skills/ are deprecated and will not be loaded. Move them to ~/.agents/skills/ to continue using them.");
279
+ // --- User-level skills (lowest priority) ---
280
+ await loadAllSkillDirs([
281
+ {
282
+ dir: dirs.codexUser ?? join(homedir(), ".codex", "skills"),
283
+ source: "codex-user",
284
+ mode: "recursive",
285
+ colonSeparated: false,
286
+ },
287
+ {
288
+ dir: dirs.claudeUser ?? join(homedir(), ".claude", "skills"),
289
+ source: "claude-user",
290
+ mode: "claude",
291
+ colonSeparated: false,
292
+ },
293
+ {
294
+ dir: dirs.agentsGlobal ?? join(homedir(), ".agents", "skills"),
295
+ source: "user",
296
+ mode: "recursive",
297
+ colonSeparated: true,
298
+ },
299
+ ], skillMap);
300
+ // --- Config-level skills (overrides user-level) ---
266
301
  for (const skillPath of additionalSkillPaths) {
267
302
  for (const skill of await loadSkillsFromDirInternal(skillPath, "config", "recursive", true)) {
268
303
  skillMap.set(skill.name, skill);
269
304
  }
270
305
  }
306
+ // --- Project-level skills (highest priority, always wins) ---
307
+ await loadAllSkillDirs([
308
+ {
309
+ dir: dirs.claudeProject ?? resolve(process.cwd(), ".claude", "skills"),
310
+ source: "claude-project",
311
+ mode: "claude",
312
+ colonSeparated: false,
313
+ },
314
+ {
315
+ dir: dirs.agentsProject ?? resolve(process.cwd(), ".agents", "skills"),
316
+ source: "project",
317
+ mode: "recursive",
318
+ colonSeparated: true,
319
+ },
320
+ ], skillMap);
271
321
  return new Skills(Array.from(skillMap.values()));
272
322
  }
273
323
  export function formatSkillsForPrompt(skills) {
@@ -3,35 +3,15 @@
3
3
  *
4
4
  * Provides functions for controlling terminal behavior and state.
5
5
  */
6
- export { isAltBackspace, isAltEnter, isAltLeft, isAltRight, isArrowDown, isArrowLeft, isArrowRight, isArrowUp, isBackspace, isCtrlA, isCtrlC, isCtrlD, isCtrlE, isCtrlG, isCtrlK, isCtrlL, isCtrlM, isCtrlN, isCtrlO, isCtrlP, isCtrlR, isCtrlT, isCtrlU, isCtrlW, isCtrlZ, isDelete, isEnd, isEnter, isEscape, isHome, isKittyCtrl, isKittyKey, isNavigationKey, isPageDown, isPageUp, isShiftCtrlD, isShiftCtrlO, isShiftCtrlP, isShiftEnter, isShiftTab, isTab, } from "./keys.ts";
6
+ export { isArrowDown, isArrowUp, isCtrlC, isCtrlD, isCtrlM, isCtrlN, isCtrlO, isCtrlR, isCtrlZ, isEnter, isEscape, isShiftTab, isTab, } from "./keys.ts";
7
7
  /**
8
8
  * Get the current shell
9
9
  */
10
10
  export declare function getShell(): string;
11
- /**
12
- * Check if terminal is interactive
13
- */
14
- export declare function isInteractive(): boolean;
15
11
  /**
16
12
  * Send terminal alert/notification
17
13
  */
18
14
  export declare function alert(): Promise<void>;
19
- /**
20
- * Clear the terminal screen
21
- */
22
- export declare function clearScreen(): void;
23
- /**
24
- * Clear the terminal screen including scrollback buffer
25
- *
26
- * Unlike clearScreen, this function:
27
- * 1. Clears the entire screen (\x1b[2J)
28
- * 2. Clears the scrollback buffer (\x1b[3J)
29
- * 3. Moves cursor to home position (\x1b[H)
30
- * 4. Returns a Promise that resolves when the write operation completes
31
- *
32
- * @returns Promise that resolves when the terminal has been cleared
33
- */
34
- export declare function clearTerminal(): Promise<void>;
35
15
  /**
36
16
  * Sets the terminal title
37
17
  */
@@ -1 +1 @@
1
- {"version":3,"file":"control.d.ts","sourceRoot":"","sources":["../../source/terminal/control.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EACL,cAAc,EACd,UAAU,EACV,SAAS,EACT,UAAU,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,WAAW,EACX,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,QAAQ,EACR,KAAK,EACL,OAAO,EACP,QAAQ,EACR,MAAM,EACN,WAAW,EACX,UAAU,EACV,eAAe,EACf,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,KAAK,GACN,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,wBAAgB,QAAQ,WAEvB;AAED;;GAEG;AACH,wBAAgB,aAAa,YAE5B;AAED;;GAEG;AACH,wBAAsB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAkB3C;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAGlC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAM7C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAYpD;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAgBnE;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAQpC;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAQnC"}
1
+ {"version":3,"file":"control.d.ts","sourceRoot":"","sources":["../../source/terminal/control.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EACL,WAAW,EACX,SAAS,EACT,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,QAAQ,EACR,UAAU,EACV,KAAK,GACN,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,wBAAgB,QAAQ,WAEvB;AAED;;GAEG;AACH,wBAAsB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAkB3C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAYpD;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAgBnE;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAQpC;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAQnC"}
@@ -6,19 +6,13 @@
6
6
  import { config } from "../config/index.js";
7
7
  import { logger } from "../utils/logger.js";
8
8
  // Re-export key functions from keys.ts for convenient imports
9
- export { isAltBackspace, isAltEnter, isAltLeft, isAltRight, isArrowDown, isArrowLeft, isArrowRight, isArrowUp, isBackspace, isCtrlA, isCtrlC, isCtrlD, isCtrlE, isCtrlG, isCtrlK, isCtrlL, isCtrlM, isCtrlN, isCtrlO, isCtrlP, isCtrlR, isCtrlT, isCtrlU, isCtrlW, isCtrlZ, isDelete, isEnd, isEnter, isEscape, isHome, isKittyCtrl, isKittyKey, isNavigationKey, isPageDown, isPageUp, isShiftCtrlD, isShiftCtrlO, isShiftCtrlP, isShiftEnter, isShiftTab, isTab, } from "./keys.js";
9
+ export { isArrowDown, isArrowUp, isCtrlC, isCtrlD, isCtrlM, isCtrlN, isCtrlO, isCtrlR, isCtrlZ, isEnter, isEscape, isShiftTab, isTab, } from "./keys.js";
10
10
  /**
11
11
  * Get the current shell
12
12
  */
13
13
  export function getShell() {
14
14
  return process.env["ZSH_VERSION"] ? "zsh" : process.env["SHELL"] || "bash";
15
15
  }
16
- /**
17
- * Check if terminal is interactive
18
- */
19
- export function isInteractive() {
20
- return Boolean(process.stdout.isTTY && process.stdin.isTTY);
21
- }
22
16
  /**
23
17
  * Send terminal alert/notification
24
18
  */
@@ -40,31 +34,6 @@ export async function alert() {
40
34
  logger.warn({ err }, "Failed to emit alert");
41
35
  }
42
36
  }
43
- /**
44
- * Clear the terminal screen
45
- */
46
- export function clearScreen() {
47
- // Clear screen and move cursor to top-left
48
- process.stdout.write("\x1b[2J\x1b[0f");
49
- }
50
- /**
51
- * Clear the terminal screen including scrollback buffer
52
- *
53
- * Unlike clearScreen, this function:
54
- * 1. Clears the entire screen (\x1b[2J)
55
- * 2. Clears the scrollback buffer (\x1b[3J)
56
- * 3. Moves cursor to home position (\x1b[H)
57
- * 4. Returns a Promise that resolves when the write operation completes
58
- *
59
- * @returns Promise that resolves when the terminal has been cleared
60
- */
61
- export function clearTerminal() {
62
- return new Promise((resolve) => {
63
- process.stdout.write("\x1b[2J\x1b[3J\x1b[H", () => {
64
- resolve();
65
- });
66
- });
67
- }
68
37
  /**
69
38
  * Sets the terminal title
70
39
  */
@@ -1,35 +1,2 @@
1
- /**
2
- * Create a horizontal rule
3
- */
4
- export declare function hr(width: number): string;
5
- /**
6
- * Word wrap text to the specified width
7
- */
8
- export declare function wordWrap(text: string, width: number): string;
9
1
  export declare const link: (text: string, url: string) => string | null;
10
- export declare const image: (data: string | Buffer, options?: {
11
- width?: number | string;
12
- height?: number | string;
13
- preserveAspectRatio?: boolean;
14
- }) => string;
15
- /**
16
- * Display a message with emphasis
17
- */
18
- export declare function emphasize(message: string): string;
19
- /**
20
- * Display an informational message
21
- */
22
- export declare function info(message: string): string;
23
- /**
24
- * Display a success message
25
- */
26
- export declare function success(message: string): string;
27
- /**
28
- * Display a warning message
29
- */
30
- export declare function warn(message: string): string;
31
- /**
32
- * Display an error message
33
- */
34
- export declare function error(message: string): string;
35
2
  //# sourceMappingURL=formatting.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../source/terminal/formatting.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,wBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,UAE/B;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAI5D;AA2CD,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,EAAE,KAAK,MAAM,kBAO7C,CAAC;AAEF,eAAO,MAAM,KAAK,GAChB,MAAM,MAAM,GAAG,MAAM,EACrB,UAAS;IACP,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC1B,WAiBP,CAAC;AAEF;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE7C"}
1
+ {"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../source/terminal/formatting.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,EAAE,KAAK,MAAM,kBAO7C,CAAC"}
@@ -3,55 +3,7 @@
3
3
  *
4
4
  * Provides functions for formatting and displaying text in the terminal.
5
5
  */
6
- import style from "./style.js";
7
6
  import { supportsHyperlinks } from "./supports-hyperlinks.js";
8
- /**
9
- * Create a horizontal rule
10
- */
11
- export function hr(width) {
12
- return `${style.gray("─").repeat(width)}`;
13
- }
14
- /**
15
- * Word wrap text to the specified width
16
- */
17
- export function wordWrap(text, width) {
18
- const lines = text.split("\n");
19
- return lines.map((line) => wrapLine(line, width)).join("\n");
20
- }
21
- function wrapLine(line, width) {
22
- // If the line is a code block or already shorter than the width, leave it as is
23
- if (line.trim().startsWith("┃") || line.length <= width) {
24
- return line;
25
- }
26
- // Word wrap the line
27
- const words = line.split(" ");
28
- const wrappedLines = [];
29
- let currentLine = "";
30
- for (const word of words) {
31
- // If adding this word would exceed the width
32
- if (currentLine.length + word.length + 1 > width) {
33
- // Add the current line to wrapped lines if it's not empty
34
- if (currentLine) {
35
- wrappedLines.push(currentLine);
36
- currentLine = word;
37
- }
38
- else {
39
- // If the current line is empty, it means the word itself is longer than the width
40
- wrappedLines.push(word);
41
- }
42
- }
43
- else {
44
- // Add the word to the current line
45
- currentLine = currentLine ? `${currentLine} ${word}` : word;
46
- }
47
- }
48
- // Add the last line if it's not empty
49
- if (currentLine) {
50
- wrappedLines.push(currentLine);
51
- }
52
- return wrappedLines.join("\n");
53
- }
54
- // const ESC = "\u001B[";
55
7
  const OSC = "\u001B]";
56
8
  const BEL = "\u0007";
57
9
  const SEP = ";";
@@ -61,46 +13,3 @@ export const link = (text, url) => {
61
13
  }
62
14
  return null;
63
15
  };
64
- export const image = (data, options = {}) => {
65
- let returnValue = `${OSC}1337;File=inline=1`;
66
- if (options.width) {
67
- returnValue += `;width=${options.width}`;
68
- }
69
- if (options.height) {
70
- returnValue += `;height=${options.height}`;
71
- }
72
- if (options.preserveAspectRatio === false) {
73
- returnValue += ";preserveAspectRatio=0";
74
- }
75
- return `${returnValue}:${Buffer.from(data).toString("base64")}${BEL}`;
76
- };
77
- /**
78
- * Display a message with emphasis
79
- */
80
- export function emphasize(message) {
81
- return style.cyan.bold(message);
82
- }
83
- /**
84
- * Display an informational message
85
- */
86
- export function info(message) {
87
- return style.blue(`ℹ ${message}`);
88
- }
89
- /**
90
- * Display a success message
91
- */
92
- export function success(message) {
93
- return style.green(`✓ ${message}`);
94
- }
95
- /**
96
- * Display a warning message
97
- */
98
- export function warn(message) {
99
- return style.yellow(`⚠ ${message}`);
100
- }
101
- /**
102
- * Display an error message
103
- */
104
- export function error(message) {
105
- return style.red(`✗ ${message}`);
106
- }
@@ -192,42 +192,5 @@ export interface Theme extends Tokens<(codePart: string) => string> {
192
192
  */
193
193
  default?: (codePart: string) => string;
194
194
  }
195
- /**
196
- * Stringifies a [[Theme]] with formatter functions to a JSON string.
197
- *
198
- * ```ts
199
- * import style from '../terminal/style.ts';
200
- * import {stringify} from './highlight/theme.ts';
201
- * import * as fs from 'node:fs';
202
- *
203
- * const myTheme: Theme = {
204
- * keyword: style.red.bold,
205
- * addition: style.green,
206
- * deletion: style.red.strikethrough,
207
- * number: plain
208
- * }
209
- * const json = stringify(myTheme);
210
- * fs.writeFile('mytheme.json', json, (err: any) => {
211
- * if (err) throw err;
212
- * console.log('Theme saved');
213
- * });
214
- * ```
215
- */
216
- export declare function stringify(theme: Theme): string;
217
- /**
218
- * Parses a JSON string into a [[Theme]] with formatter functions.
219
- *
220
- * ```ts
221
- * import * as fs from 'node:fs';
222
- * import {parse, highlight} from './highlight/index.ts';
223
- *
224
- * fs.readFile('mytheme.json', 'utf-8', (err: any, json: string) => {
225
- * if (err) throw err;
226
- * const code = highlight('SELECT * FROM table', {theme: parse(json)});
227
- * console.log(code);
228
- * });
229
- * ```
230
- */
231
- export declare function parse(json: string): Theme;
232
195
  export {};
233
196
  //# sourceMappingURL=theme.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../../source/terminal/highlight/theme.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../../source/terminal/highlight/theme.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,UAAU,MAAM,CAAC,CAAC;IAChB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC;IAEZ;;OAEG;IAEH,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEb;;OAEG;IACH,IAAI,CAAC,EAAE,CAAC,CAAC;IAET;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC;IAEZ;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC;IAEX;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC;IAEX;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC;IAEX;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,CAAC;IAEV;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC;IAEX;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,CAAC;IAEV;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEb;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,CAAC;IAEV;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC;IAEX;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC;IAEZ;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC;IAEX;;OAEG;IACH,IAAI,CAAC,EAAE,CAAC,CAAC;IAET;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC;IAEnB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC;IAEZ;;OAEG;IACH,GAAG,CAAC,EAAE,CAAC,CAAC;IAER;;OAEG;IACH,IAAI,CAAC,EAAE,CAAC,CAAC;IAET;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC;IAEnB;;OAEG;IACH,IAAI,CAAC,EAAE,CAAC,CAAC;IAET;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC;IAEd;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEb;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC;IAEX;;OAEG;IACH,IAAI,CAAC,EAAE,CAAC,CAAC;IAET;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEb;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC;IAEX;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC;IAEZ;;OAEG;IACH,IAAI,CAAC,EAAE,CAAC,CAAC;IAET;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,CAAC;IAEV;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC;IAEnB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,CAAC;IAElB;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAErB;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC;IAEpB;;OAEG;IACH,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAEtB;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC;IAEnB;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAC,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEb;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,KAAM,SAAQ,MAAM,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IACjE;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC"}
@@ -1,79 +1 @@
1
- import { id } from "../../utils/funcs.js";
2
- import style from "../style.js";
3
- /**
4
- * Converts a [[JsonTheme]] with string values to a [[Theme]] with formatter functions. Used by [[parse]].
5
- */
6
- function fromJson(json) {
7
- const theme = {};
8
- for (const key of Object.keys(json)) {
9
- // biome-ignore lint/suspicious/noExplicitAny: Dynamic theme access needed for highlight compatibility
10
- const styleValue = json[key];
11
- if (Array.isArray(styleValue)) {
12
- // biome-ignore lint/suspicious/noExplicitAny: Dynamic theme access needed for highlight compatibility
13
- theme[key] = styleValue.reduce((previous, current) =>
14
- // biome-ignore lint/suspicious/noExplicitAny: Dynamic theme access needed for highlight compatibility
15
- current === "plain" ? id : previous[current], style);
16
- }
17
- else {
18
- // biome-ignore lint/suspicious/noExplicitAny: Dynamic theme access needed for highlight compatibility
19
- theme[key] = style[styleValue];
20
- }
21
- }
22
- return theme;
23
- }
24
- /**
25
- * Converts a [[Theme]] with formatter functions to a [[JsonTheme]] with string values. Used by [[stringify]].
26
- */
27
- function toJson(theme) {
28
- // biome-ignore lint/suspicious/noExplicitAny: Dynamic theme access needed for highlight compatibility
29
- const jsonTheme = {};
30
- for (const key of Object.keys(theme)) {
31
- // biome-ignore lint/suspicious/noExplicitAny: Dynamic theme access needed for highlight compatibility
32
- const style = theme[key];
33
- if (style?._styles) {
34
- jsonTheme[key] = style._styles;
35
- }
36
- }
37
- return jsonTheme;
38
- }
39
- /**
40
- * Stringifies a [[Theme]] with formatter functions to a JSON string.
41
- *
42
- * ```ts
43
- * import style from '../terminal/style.ts';
44
- * import {stringify} from './highlight/theme.ts';
45
- * import * as fs from 'node:fs';
46
- *
47
- * const myTheme: Theme = {
48
- * keyword: style.red.bold,
49
- * addition: style.green,
50
- * deletion: style.red.strikethrough,
51
- * number: plain
52
- * }
53
- * const json = stringify(myTheme);
54
- * fs.writeFile('mytheme.json', json, (err: any) => {
55
- * if (err) throw err;
56
- * console.log('Theme saved');
57
- * });
58
- * ```
59
- */
60
- export function stringify(theme) {
61
- return JSON.stringify(toJson(theme));
62
- }
63
- /**
64
- * Parses a JSON string into a [[Theme]] with formatter functions.
65
- *
66
- * ```ts
67
- * import * as fs from 'node:fs';
68
- * import {parse, highlight} from './highlight/index.ts';
69
- *
70
- * fs.readFile('mytheme.json', 'utf-8', (err: any, json: string) => {
71
- * if (err) throw err;
72
- * const code = highlight('SELECT * FROM table', {theme: parse(json)});
73
- * console.log(code);
74
- * });
75
- * ```
76
- */
77
- export function parse(json) {
78
- return fromJson(JSON.parse(json));
79
- }
1
+ export {};