agentpacks 0.9.0 → 1.0.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 (67) hide show
  1. package/README.md +41 -14
  2. package/dist/api.js +403 -179
  3. package/dist/cli/export-cmd.js +58 -5
  4. package/dist/cli/generate.js +268 -59
  5. package/dist/cli/import-cmd.js +203 -95
  6. package/dist/cli/install.js +1 -0
  7. package/dist/cli/models-explain.js +56 -0
  8. package/dist/cli/pack/list.js +56 -0
  9. package/dist/cli/pack/validate.js +143 -18
  10. package/dist/cli/publish.js +1 -0
  11. package/dist/core/config.d.ts +1 -1
  12. package/dist/core/config.js +1 -0
  13. package/dist/core/index.js +56 -0
  14. package/dist/core/metarepo.js +1 -0
  15. package/dist/core/pack-loader.js +56 -0
  16. package/dist/exporters/cursor-plugin.js +109 -22
  17. package/dist/exporters/index.js +109 -22
  18. package/dist/features/index.d.ts +1 -1
  19. package/dist/features/index.js +59 -0
  20. package/dist/features/skills.d.ts +22 -0
  21. package/dist/features/skills.js +60 -1
  22. package/dist/importers/cursor.js +122 -26
  23. package/dist/importers/opencode.js +138 -24
  24. package/dist/importers/rulesync.js +147 -33
  25. package/dist/index.js +484 -244
  26. package/dist/node/api.js +403 -179
  27. package/dist/node/cli/export-cmd.js +58 -5
  28. package/dist/node/cli/generate.js +268 -59
  29. package/dist/node/cli/import-cmd.js +203 -95
  30. package/dist/node/cli/install.js +1 -0
  31. package/dist/node/cli/models-explain.js +56 -0
  32. package/dist/node/cli/pack/list.js +56 -0
  33. package/dist/node/cli/pack/validate.js +143 -18
  34. package/dist/node/cli/publish.js +1 -0
  35. package/dist/node/core/config.js +1 -0
  36. package/dist/node/core/index.js +56 -0
  37. package/dist/node/core/metarepo.js +1 -0
  38. package/dist/node/core/pack-loader.js +56 -0
  39. package/dist/node/exporters/cursor-plugin.js +109 -22
  40. package/dist/node/exporters/index.js +109 -22
  41. package/dist/node/features/index.js +59 -0
  42. package/dist/node/features/skills.js +60 -1
  43. package/dist/node/importers/cursor.js +122 -26
  44. package/dist/node/importers/opencode.js +138 -24
  45. package/dist/node/importers/rulesync.js +147 -33
  46. package/dist/node/index.js +484 -244
  47. package/dist/node/targets/claude-code.js +56 -1
  48. package/dist/node/targets/codex-cli.js +56 -1
  49. package/dist/node/targets/copilot.js +56 -1
  50. package/dist/node/targets/cursor.js +56 -5
  51. package/dist/node/targets/index.js +268 -59
  52. package/dist/node/targets/mistral-vibe.js +661 -0
  53. package/dist/node/targets/opencode.js +56 -1
  54. package/dist/node/targets/registry.js +267 -59
  55. package/dist/node/utils/model-allowlist.js +6 -2
  56. package/dist/targets/claude-code.js +56 -1
  57. package/dist/targets/codex-cli.js +56 -1
  58. package/dist/targets/copilot.js +56 -1
  59. package/dist/targets/cursor.js +56 -5
  60. package/dist/targets/index.d.ts +1 -0
  61. package/dist/targets/index.js +268 -59
  62. package/dist/targets/mistral-vibe.d.ts +13 -0
  63. package/dist/targets/mistral-vibe.js +661 -0
  64. package/dist/targets/opencode.js +56 -1
  65. package/dist/targets/registry.js +267 -59
  66. package/dist/utils/model-allowlist.js +6 -2
  67. package/package.json +15 -3
@@ -129,14 +129,104 @@ function serializeFrontmatter(data, content) {
129
129
  return matter.stringify(content, filtered);
130
130
  }
131
131
 
132
+ // src/features/skills.ts
133
+ import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
134
+ import { basename, join as join2 } from "path";
135
+ var SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
136
+ var SKILL_NAME_MAX_LENGTH = 64;
137
+ function parseSkills(skillsDir, packName) {
138
+ const dirs = listDirs(skillsDir);
139
+ const skills = [];
140
+ for (const dir of dirs) {
141
+ const skillMd = join2(dir, "SKILL.md");
142
+ if (existsSync2(skillMd)) {
143
+ skills.push(parseSkillFile(skillMd, dir, packName));
144
+ }
145
+ }
146
+ return skills;
147
+ }
148
+ function parseSkillFile(filepath, skillDir, packName) {
149
+ const raw = readFileSync2(filepath, "utf-8");
150
+ const { data, content } = parseFrontmatter(raw);
151
+ return {
152
+ name: data.name ?? basename(skillDir),
153
+ sourcePath: filepath,
154
+ sourceDir: skillDir,
155
+ packName,
156
+ meta: data,
157
+ content
158
+ };
159
+ }
160
+ function buildSkillFrontmatter(skill) {
161
+ return {
162
+ ...skill.meta,
163
+ name: skill.name
164
+ };
165
+ }
166
+ function serializeSkill(skill) {
167
+ return serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
168
+ }
169
+ function normalizeImportedSkillMarkdown(source, skillName) {
170
+ const { data, content } = parseFrontmatter(source);
171
+ const normalized = {
172
+ ...data,
173
+ name: skillName
174
+ };
175
+ let addedDescription = false;
176
+ const description = normalized.description;
177
+ if (typeof description !== "string" || description.trim().length === 0) {
178
+ normalized.description = `Imported skill: ${skillName}`;
179
+ addedDescription = true;
180
+ }
181
+ return {
182
+ content: serializeFrontmatter(normalized, content),
183
+ addedDescription
184
+ };
185
+ }
186
+ function validateAgentSkillsFrontmatter(skill) {
187
+ const errors = [];
188
+ const dirName = basename(skill.sourceDir);
189
+ const declaredName = skill.meta.name;
190
+ if (typeof declaredName !== "string" || declaredName.trim().length === 0) {
191
+ errors.push('Missing required frontmatter field "name".');
192
+ } else {
193
+ if (declaredName.length > SKILL_NAME_MAX_LENGTH) {
194
+ errors.push(`Invalid "name": must be at most ${SKILL_NAME_MAX_LENGTH} characters.`);
195
+ }
196
+ if (!SKILL_NAME_PATTERN.test(declaredName)) {
197
+ errors.push('Invalid "name": use lowercase letters, numbers, and single hyphens only.');
198
+ }
199
+ if (declaredName !== dirName) {
200
+ errors.push(`Invalid "name": must match containing directory "${dirName}".`);
201
+ }
202
+ }
203
+ const description = skill.meta.description;
204
+ if (typeof description !== "string" || description.trim().length === 0) {
205
+ errors.push('Missing required frontmatter field "description".');
206
+ }
207
+ const allowedTools = skill.meta["allowed-tools"];
208
+ if (allowedTools !== undefined && (!Array.isArray(allowedTools) || allowedTools.some((tool) => typeof tool !== "string" || tool.length === 0))) {
209
+ errors.push('Invalid "allowed-tools": expected an array of non-empty strings.');
210
+ }
211
+ return errors;
212
+ }
213
+ function skillMatchesTarget(skill, targetId) {
214
+ const { targets } = skill.meta;
215
+ if (!targets || targets === "*")
216
+ return true;
217
+ if (Array.isArray(targets) && targets.includes("*"))
218
+ return true;
219
+ return Array.isArray(targets) && targets.includes(targetId);
220
+ }
221
+
132
222
  // src/importers/cursor.ts
133
- import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, copyFileSync } from "fs";
134
- import { resolve, join as join2, basename } from "path";
223
+ import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2, copyFileSync } from "fs";
224
+ import { resolve, join as join3, basename as basename2 } from "path";
135
225
  function importFromCursor(projectRoot, outputPackDir) {
136
226
  const cursorDir = resolve(projectRoot, ".cursor");
137
227
  const warnings = [];
138
228
  const filesImported = [];
139
- if (!existsSync2(cursorDir)) {
229
+ if (!existsSync3(cursorDir)) {
140
230
  return {
141
231
  packDir: "",
142
232
  filesImported: [],
@@ -147,12 +237,12 @@ function importFromCursor(projectRoot, outputPackDir) {
147
237
  const packDir = outputPackDir ?? resolve(projectRoot, "packs", "cursor-import");
148
238
  ensureDir(packDir);
149
239
  const rulesDir = resolve(cursorDir, "rules");
150
- if (existsSync2(rulesDir)) {
240
+ if (existsSync3(rulesDir)) {
151
241
  const outRulesDir = resolve(packDir, "rules");
152
242
  ensureDir(outRulesDir);
153
243
  const files = listFiles(rulesDir, { extension: ".mdc" });
154
244
  for (const file of files) {
155
- const raw = readFileSync2(file, "utf-8");
245
+ const raw = readFileSync3(file, "utf-8");
156
246
  const { data, content } = parseFrontmatter(raw);
157
247
  const meta = {};
158
248
  if (data.description)
@@ -163,65 +253,71 @@ function importFromCursor(projectRoot, outputPackDir) {
163
253
  meta.globs = data.globs;
164
254
  meta.cursor = { ...data };
165
255
  const mdContent = buildAgentpacksRule(meta, content);
166
- const name = basename(file, ".mdc");
167
- const dest = join2(outRulesDir, `${name}.md`);
256
+ const name = basename2(file, ".mdc");
257
+ const dest = join3(outRulesDir, `${name}.md`);
168
258
  writeFileSync2(dest, mdContent);
169
259
  filesImported.push(dest);
170
260
  }
171
261
  const mdFiles = listFiles(rulesDir, { extension: ".md" });
172
262
  for (const file of mdFiles) {
173
- const dest = join2(outRulesDir, basename(file));
263
+ const dest = join3(outRulesDir, basename2(file));
174
264
  copyFileSync(file, dest);
175
265
  filesImported.push(dest);
176
266
  }
177
267
  }
178
268
  const agentsDir = resolve(cursorDir, "agents");
179
- if (existsSync2(agentsDir)) {
269
+ if (existsSync3(agentsDir)) {
180
270
  const outDir = resolve(packDir, "agents");
181
271
  ensureDir(outDir);
182
272
  const files = listFiles(agentsDir, { extension: ".md" });
183
273
  for (const file of files) {
184
- const dest = join2(outDir, basename(file));
274
+ const dest = join3(outDir, basename2(file));
185
275
  copyFileSync(file, dest);
186
276
  filesImported.push(dest);
187
277
  }
188
278
  }
189
279
  const skillsDir = resolve(cursorDir, "skills");
190
- if (existsSync2(skillsDir)) {
280
+ if (existsSync3(skillsDir)) {
191
281
  const outDir = resolve(packDir, "skills");
192
282
  ensureDir(outDir);
193
283
  const dirs = listDirs(skillsDir);
194
284
  for (const dir of dirs) {
195
- const name = basename(dir);
196
- const skillMd = join2(dir, "SKILL.md");
197
- if (existsSync2(skillMd)) {
198
- const outSkillDir = join2(outDir, name);
285
+ const name = basename2(dir);
286
+ const skillMd = join3(dir, "SKILL.md");
287
+ if (existsSync3(skillMd)) {
288
+ const outSkillDir = join3(outDir, name);
199
289
  ensureDir(outSkillDir);
200
- copyFileSync(skillMd, join2(outSkillDir, "SKILL.md"));
201
- filesImported.push(join2(outSkillDir, "SKILL.md"));
290
+ const rawSkill = readFileSync3(skillMd, "utf-8");
291
+ const normalized = normalizeImportedSkillMarkdown(rawSkill, name);
292
+ const dest = join3(outSkillDir, "SKILL.md");
293
+ writeFileSync2(dest, normalized.content);
294
+ filesImported.push(dest);
295
+ if (normalized.addedDescription) {
296
+ warnings.push(`skills/${name}/SKILL.md missing description; added import placeholder.`);
297
+ }
202
298
  }
203
299
  }
204
300
  }
205
301
  const commandsDir = resolve(cursorDir, "commands");
206
- if (existsSync2(commandsDir)) {
302
+ if (existsSync3(commandsDir)) {
207
303
  const outDir = resolve(packDir, "commands");
208
304
  ensureDir(outDir);
209
305
  const files = listFiles(commandsDir, { extension: ".md" });
210
306
  for (const file of files) {
211
- const dest = join2(outDir, basename(file));
307
+ const dest = join3(outDir, basename2(file));
212
308
  copyFileSync(file, dest);
213
309
  filesImported.push(dest);
214
310
  }
215
311
  }
216
312
  const mcpJson = resolve(cursorDir, "mcp.json");
217
- if (existsSync2(mcpJson)) {
218
- copyFileSync(mcpJson, join2(packDir, "mcp.json"));
219
- filesImported.push(join2(packDir, "mcp.json"));
313
+ if (existsSync3(mcpJson)) {
314
+ copyFileSync(mcpJson, join3(packDir, "mcp.json"));
315
+ filesImported.push(join3(packDir, "mcp.json"));
220
316
  }
221
317
  const cursorIgnore = resolve(projectRoot, ".cursorignore");
222
- if (existsSync2(cursorIgnore)) {
223
- copyFileSync(cursorIgnore, join2(packDir, "ignore"));
224
- filesImported.push(join2(packDir, "ignore"));
318
+ if (existsSync3(cursorIgnore)) {
319
+ copyFileSync(cursorIgnore, join3(packDir, "ignore"));
320
+ filesImported.push(join3(packDir, "ignore"));
225
321
  }
226
322
  writePackJson(packDir, "cursor-import", filesImported);
227
323
  return { packDir, filesImported, warnings, configGenerated: false };
@@ -250,7 +346,7 @@ function writePackJson(packDir, name, filesImported) {
250
346
  targets: "*",
251
347
  features: "*"
252
348
  };
253
- const dest = join2(packDir, "pack.json");
349
+ const dest = join3(packDir, "pack.json");
254
350
  writeFileSync2(dest, JSON.stringify(packJson, null, 2) + `
255
351
  `);
256
352
  filesImported.push(dest);
@@ -111,14 +111,122 @@ function getHeader(type) {
111
111
  }
112
112
  }
113
113
 
114
+ // src/utils/frontmatter.ts
115
+ import matter from "gray-matter";
116
+ function parseFrontmatter(source) {
117
+ const { data, content } = matter(source);
118
+ return {
119
+ data,
120
+ content: content.trim(),
121
+ raw: source
122
+ };
123
+ }
124
+ function serializeFrontmatter(data, content) {
125
+ const filtered = Object.fromEntries(Object.entries(data).filter(([, v]) => v !== undefined));
126
+ if (Object.keys(filtered).length === 0) {
127
+ return content;
128
+ }
129
+ return matter.stringify(content, filtered);
130
+ }
131
+
132
+ // src/features/skills.ts
133
+ import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
134
+ import { basename, join as join2 } from "path";
135
+ var SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
136
+ var SKILL_NAME_MAX_LENGTH = 64;
137
+ function parseSkills(skillsDir, packName) {
138
+ const dirs = listDirs(skillsDir);
139
+ const skills = [];
140
+ for (const dir of dirs) {
141
+ const skillMd = join2(dir, "SKILL.md");
142
+ if (existsSync2(skillMd)) {
143
+ skills.push(parseSkillFile(skillMd, dir, packName));
144
+ }
145
+ }
146
+ return skills;
147
+ }
148
+ function parseSkillFile(filepath, skillDir, packName) {
149
+ const raw = readFileSync2(filepath, "utf-8");
150
+ const { data, content } = parseFrontmatter(raw);
151
+ return {
152
+ name: data.name ?? basename(skillDir),
153
+ sourcePath: filepath,
154
+ sourceDir: skillDir,
155
+ packName,
156
+ meta: data,
157
+ content
158
+ };
159
+ }
160
+ function buildSkillFrontmatter(skill) {
161
+ return {
162
+ ...skill.meta,
163
+ name: skill.name
164
+ };
165
+ }
166
+ function serializeSkill(skill) {
167
+ return serializeFrontmatter(buildSkillFrontmatter(skill), skill.content);
168
+ }
169
+ function normalizeImportedSkillMarkdown(source, skillName) {
170
+ const { data, content } = parseFrontmatter(source);
171
+ const normalized = {
172
+ ...data,
173
+ name: skillName
174
+ };
175
+ let addedDescription = false;
176
+ const description = normalized.description;
177
+ if (typeof description !== "string" || description.trim().length === 0) {
178
+ normalized.description = `Imported skill: ${skillName}`;
179
+ addedDescription = true;
180
+ }
181
+ return {
182
+ content: serializeFrontmatter(normalized, content),
183
+ addedDescription
184
+ };
185
+ }
186
+ function validateAgentSkillsFrontmatter(skill) {
187
+ const errors = [];
188
+ const dirName = basename(skill.sourceDir);
189
+ const declaredName = skill.meta.name;
190
+ if (typeof declaredName !== "string" || declaredName.trim().length === 0) {
191
+ errors.push('Missing required frontmatter field "name".');
192
+ } else {
193
+ if (declaredName.length > SKILL_NAME_MAX_LENGTH) {
194
+ errors.push(`Invalid "name": must be at most ${SKILL_NAME_MAX_LENGTH} characters.`);
195
+ }
196
+ if (!SKILL_NAME_PATTERN.test(declaredName)) {
197
+ errors.push('Invalid "name": use lowercase letters, numbers, and single hyphens only.');
198
+ }
199
+ if (declaredName !== dirName) {
200
+ errors.push(`Invalid "name": must match containing directory "${dirName}".`);
201
+ }
202
+ }
203
+ const description = skill.meta.description;
204
+ if (typeof description !== "string" || description.trim().length === 0) {
205
+ errors.push('Missing required frontmatter field "description".');
206
+ }
207
+ const allowedTools = skill.meta["allowed-tools"];
208
+ if (allowedTools !== undefined && (!Array.isArray(allowedTools) || allowedTools.some((tool) => typeof tool !== "string" || tool.length === 0))) {
209
+ errors.push('Invalid "allowed-tools": expected an array of non-empty strings.');
210
+ }
211
+ return errors;
212
+ }
213
+ function skillMatchesTarget(skill, targetId) {
214
+ const { targets } = skill.meta;
215
+ if (!targets || targets === "*")
216
+ return true;
217
+ if (Array.isArray(targets) && targets.includes("*"))
218
+ return true;
219
+ return Array.isArray(targets) && targets.includes(targetId);
220
+ }
221
+
114
222
  // src/importers/opencode.ts
115
- import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, copyFileSync } from "fs";
116
- import { resolve, join as join2, basename } from "path";
223
+ import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2, copyFileSync } from "fs";
224
+ import { resolve, join as join3, basename as basename2 } from "path";
117
225
  function importFromOpenCode(projectRoot, outputPackDir) {
118
226
  const warnings = [];
119
227
  const filesImported = [];
120
228
  const ocDir = resolve(projectRoot, ".opencode");
121
- if (!existsSync2(ocDir)) {
229
+ if (!existsSync3(ocDir)) {
122
230
  return {
123
231
  packDir: "",
124
232
  filesImported: [],
@@ -132,41 +240,47 @@ function importFromOpenCode(projectRoot, outputPackDir) {
132
240
  importDirMd(resolve(ocDir, "commands"), resolve(packDir, "commands"), filesImported);
133
241
  importDirMd(resolve(ocDir, "agents"), resolve(packDir, "agents"), filesImported);
134
242
  const skillDir = resolve(ocDir, "skill");
135
- if (existsSync2(skillDir)) {
243
+ if (existsSync3(skillDir)) {
136
244
  const outSkillDir = resolve(packDir, "skills");
137
245
  ensureDir(outSkillDir);
138
246
  const dirs = listDirs(skillDir);
139
247
  for (const dir of dirs) {
140
- const name = basename(dir);
248
+ const name = basename2(dir);
141
249
  if (name.startsWith("."))
142
250
  continue;
143
- const skillMd = join2(dir, "SKILL.md");
144
- if (existsSync2(skillMd)) {
145
- const outDir = join2(outSkillDir, name);
251
+ const skillMd = join3(dir, "SKILL.md");
252
+ if (existsSync3(skillMd)) {
253
+ const outDir = join3(outSkillDir, name);
146
254
  ensureDir(outDir);
147
- copyFileSync(skillMd, join2(outDir, "SKILL.md"));
148
- filesImported.push(join2(outDir, "SKILL.md"));
255
+ const rawSkill = readFileSync3(skillMd, "utf-8");
256
+ const normalized = normalizeImportedSkillMarkdown(rawSkill, name);
257
+ const dest2 = join3(outDir, "SKILL.md");
258
+ writeFileSync2(dest2, normalized.content);
259
+ filesImported.push(dest2);
260
+ if (normalized.addedDescription) {
261
+ warnings.push(`skills/${name}/SKILL.md missing description; added import placeholder.`);
262
+ }
149
263
  }
150
264
  }
151
265
  }
152
266
  const pluginsDir = resolve(ocDir, "plugins");
153
- if (existsSync2(pluginsDir)) {
267
+ if (existsSync3(pluginsDir)) {
154
268
  const outPluginsDir = resolve(packDir, "plugins");
155
269
  ensureDir(outPluginsDir);
156
270
  const files = listFiles(pluginsDir);
157
271
  for (const file of files) {
158
272
  if (file.endsWith(".ts") || file.endsWith(".js")) {
159
- const dest2 = join2(outPluginsDir, basename(file));
273
+ const dest2 = join3(outPluginsDir, basename2(file));
160
274
  copyFileSync(file, dest2);
161
275
  filesImported.push(dest2);
162
276
  }
163
277
  }
164
278
  }
165
279
  const agentsMd = resolve(projectRoot, "AGENTS.md");
166
- if (existsSync2(agentsMd)) {
280
+ if (existsSync3(agentsMd)) {
167
281
  const outRulesDir = resolve(packDir, "rules");
168
282
  ensureDir(outRulesDir);
169
- const raw = readFileSync2(agentsMd, "utf-8");
283
+ const raw = readFileSync3(agentsMd, "utf-8");
170
284
  const ruleContent = [
171
285
  "---",
172
286
  "root: true",
@@ -176,18 +290,18 @@ function importFromOpenCode(projectRoot, outputPackDir) {
176
290
  raw
177
291
  ].join(`
178
292
  `);
179
- const dest2 = join2(outRulesDir, "agents-md-root.md");
293
+ const dest2 = join3(outRulesDir, "agents-md-root.md");
180
294
  writeFileSync2(dest2, ruleContent);
181
295
  filesImported.push(dest2);
182
296
  }
183
297
  const ocJson = resolve(projectRoot, "opencode.json");
184
- if (existsSync2(ocJson)) {
298
+ if (existsSync3(ocJson)) {
185
299
  try {
186
- const raw = readFileSync2(ocJson, "utf-8");
300
+ const raw = readFileSync3(ocJson, "utf-8");
187
301
  const config = JSON.parse(raw);
188
302
  const mcpObj = config.mcp;
189
303
  if (mcpObj) {
190
- const dest2 = join2(packDir, "mcp.json");
304
+ const dest2 = join3(packDir, "mcp.json");
191
305
  writeFileSync2(dest2, JSON.stringify({ servers: mcpObj }, null, 2) + `
192
306
  `);
193
307
  filesImported.push(dest2);
@@ -197,9 +311,9 @@ function importFromOpenCode(projectRoot, outputPackDir) {
197
311
  }
198
312
  }
199
313
  const ocIgnore = resolve(projectRoot, ".opencodeignore");
200
- if (existsSync2(ocIgnore)) {
201
- copyFileSync(ocIgnore, join2(packDir, "ignore"));
202
- filesImported.push(join2(packDir, "ignore"));
314
+ if (existsSync3(ocIgnore)) {
315
+ copyFileSync(ocIgnore, join3(packDir, "ignore"));
316
+ filesImported.push(join3(packDir, "ignore"));
203
317
  }
204
318
  const packJson = {
205
319
  name: "opencode-import",
@@ -211,19 +325,19 @@ function importFromOpenCode(projectRoot, outputPackDir) {
211
325
  targets: "*",
212
326
  features: "*"
213
327
  };
214
- const dest = join2(packDir, "pack.json");
328
+ const dest = join3(packDir, "pack.json");
215
329
  writeFileSync2(dest, JSON.stringify(packJson, null, 2) + `
216
330
  `);
217
331
  filesImported.push(dest);
218
332
  return { packDir, filesImported, warnings, configGenerated: false };
219
333
  }
220
334
  function importDirMd(srcDir, outDir, filesImported) {
221
- if (!existsSync2(srcDir))
335
+ if (!existsSync3(srcDir))
222
336
  return;
223
337
  ensureDir(outDir);
224
338
  const files = listFiles(srcDir, { extension: ".md" });
225
339
  for (const file of files) {
226
- const dest = join2(outDir, basename(file));
340
+ const dest = join3(outDir, basename2(file));
227
341
  copyFileSync(file, dest);
228
342
  filesImported.push(dest);
229
343
  }