oneagent 0.2.3 → 0.2.5

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 (2) hide show
  1. package/dist/index.js +176 -150
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1290,6 +1290,57 @@ var init_dist3 = __esm(() => {
1290
1290
  zt = { light: C("─", "-"), heavy: C("━", "="), block: C("█", "#") };
1291
1291
  Qt = `${import_picocolors2.default.gray(d)} `;
1292
1292
  });
1293
+ // ../core/src/agents.ts
1294
+ var AGENT_DEFINITIONS;
1295
+ var init_agents = __esm(() => {
1296
+ AGENT_DEFINITIONS = [
1297
+ {
1298
+ target: "claude",
1299
+ displayName: "Claude Code",
1300
+ hint: "CLAUDE.md + .claude/rules/",
1301
+ detectIndicators: ["CLAUDE.md", ".claude"],
1302
+ mainFile: "CLAUDE.md",
1303
+ rulesDir: ".claude/rules",
1304
+ skillsDir: ".claude/skills"
1305
+ },
1306
+ {
1307
+ target: "cursor",
1308
+ displayName: "Cursor",
1309
+ hint: "AGENTS.md + .cursor/rules/",
1310
+ detectIndicators: [".cursor", ".cursorrules"],
1311
+ mainFile: "AGENTS.md",
1312
+ rulesDir: ".cursor/rules",
1313
+ skillsDir: ".cursor/skills",
1314
+ deprecatedFiles: [".cursorrules"]
1315
+ },
1316
+ {
1317
+ target: "windsurf",
1318
+ displayName: "Windsurf",
1319
+ hint: "AGENTS.md + .windsurf/rules/",
1320
+ detectIndicators: [".windsurf", ".windsurfrules"],
1321
+ mainFile: "AGENTS.md",
1322
+ rulesDir: ".windsurf/rules",
1323
+ skillsDir: ".windsurf/skills",
1324
+ deprecatedFiles: [".windsurfrules"]
1325
+ },
1326
+ {
1327
+ target: "opencode",
1328
+ displayName: "OpenCode",
1329
+ hint: "AGENTS.md + opencode.json",
1330
+ detectIndicators: ["opencode.json", ".opencode"],
1331
+ mainFile: "AGENTS.md"
1332
+ },
1333
+ {
1334
+ target: "copilot",
1335
+ displayName: "GitHub Copilot",
1336
+ hint: ".github/instructions/*.instructions.md",
1337
+ detectIndicators: [".github/copilot-instructions.md", ".github"],
1338
+ mainFile: ".github/copilot-instructions.md",
1339
+ skillsDir: ".github/skills"
1340
+ }
1341
+ ];
1342
+ });
1343
+
1293
1344
  // ../../node_modules/.bun/yaml@2.8.2/node_modules/yaml/dist/nodes/identity.js
1294
1345
  var require_identity = __commonJS((exports) => {
1295
1346
  var ALIAS = Symbol.for("yaml.alias");
@@ -8243,6 +8294,7 @@ var init_dist4 = __esm(() => {
8243
8294
 
8244
8295
  // ../core/src/config.ts
8245
8296
  import path from "path";
8297
+ import fs from "fs/promises";
8246
8298
  function activeTargets(config) {
8247
8299
  return ALL_AGENT_TARGETS.filter((t) => config.targets[t]);
8248
8300
  }
@@ -8250,15 +8302,16 @@ function makeTargets(...enabled) {
8250
8302
  return Object.fromEntries(ALL_AGENT_TARGETS.map((t) => [t, enabled.includes(t)]));
8251
8303
  }
8252
8304
  async function configExists(root) {
8253
- return Bun.file(path.join(root, CONFIG_REL)).exists();
8305
+ return fs.access(path.join(root, CONFIG_REL)).then(() => true, () => false);
8254
8306
  }
8255
8307
  async function readConfig(root) {
8256
- const content = await Bun.file(path.join(root, CONFIG_REL)).text();
8308
+ const content = await fs.readFile(path.join(root, CONFIG_REL), "utf-8");
8257
8309
  return $parse(content);
8258
8310
  }
8259
8311
  async function writeConfig(root, config) {
8260
8312
  const filePath = path.join(root, CONFIG_REL);
8261
- await Bun.write(filePath, $stringify(config));
8313
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
8314
+ await fs.writeFile(filePath, $stringify(config));
8262
8315
  }
8263
8316
  var CONFIG_REL = ".oneagent/config.yml", ALL_AGENT_TARGETS;
8264
8317
  var init_config = __esm(() => {
@@ -8268,18 +8321,18 @@ var init_config = __esm(() => {
8268
8321
 
8269
8322
  // ../core/src/detect.ts
8270
8323
  import path2 from "path";
8271
- import fs from "fs/promises";
8324
+ import fs2 from "fs/promises";
8272
8325
  async function readDetectedFile(root, rel) {
8273
8326
  const absolutePath = path2.join(root, rel);
8274
8327
  try {
8275
- const stat = await fs.lstat(absolutePath);
8328
+ const stat = await fs2.lstat(absolutePath);
8276
8329
  if (stat.isSymbolicLink()) {
8277
- const linkTarget = await fs.readlink(absolutePath);
8330
+ const linkTarget = await fs2.readlink(absolutePath);
8278
8331
  const resolved = path2.resolve(path2.dirname(absolutePath), linkTarget);
8279
8332
  if (resolved.startsWith(path2.join(root, ".one")))
8280
8333
  return null;
8281
8334
  }
8282
- const content = await Bun.file(absolutePath).text();
8335
+ const content = await fs2.readFile(absolutePath, "utf-8");
8283
8336
  return {
8284
8337
  relativePath: rel,
8285
8338
  absolutePath,
@@ -8305,16 +8358,16 @@ async function removeDeprecatedFiles(root) {
8305
8358
  for (const rel of DEPRECATED_FILES) {
8306
8359
  const absPath = path2.join(root, rel);
8307
8360
  try {
8308
- const stat = await fs.lstat(absPath);
8361
+ const stat = await fs2.lstat(absPath);
8309
8362
  if (!stat.isSymbolicLink())
8310
- await fs.unlink(absPath);
8363
+ await fs2.unlink(absPath);
8311
8364
  } catch {}
8312
8365
  }
8313
8366
  }
8314
8367
  async function detectDeprecatedCommandFiles(root) {
8315
8368
  const commandsDir = path2.join(root, ".claude/commands");
8316
8369
  try {
8317
- const entries = await fs.readdir(commandsDir, { withFileTypes: true });
8370
+ const entries = await fs2.readdir(commandsDir, { withFileTypes: true });
8318
8371
  return entries.filter((e2) => e2.isFile()).map((e2) => path2.join(".claude/commands", e2.name));
8319
8372
  } catch {
8320
8373
  return [];
@@ -8322,6 +8375,7 @@ async function detectDeprecatedCommandFiles(root) {
8322
8375
  }
8323
8376
  var AGENT_FILES, DEPRECATED_FILES;
8324
8377
  var init_detect = __esm(() => {
8378
+ init_agents();
8325
8379
  AGENT_FILES = [
8326
8380
  "CLAUDE.md",
8327
8381
  "AGENTS.md",
@@ -8329,12 +8383,12 @@ var init_detect = __esm(() => {
8329
8383
  ".windsurfrules",
8330
8384
  ".github/copilot-instructions.md"
8331
8385
  ];
8332
- DEPRECATED_FILES = [".cursorrules"];
8386
+ DEPRECATED_FILES = AGENT_DEFINITIONS.flatMap((d2) => d2.deprecatedFiles ?? []);
8333
8387
  });
8334
8388
 
8335
8389
  // ../core/src/rules.ts
8336
8390
  import path3 from "path";
8337
- import fs2 from "fs/promises";
8391
+ import fs3 from "fs/promises";
8338
8392
  function parseFrontmatter(raw) {
8339
8393
  const match = raw.match(/^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/);
8340
8394
  if (!match)
@@ -8346,14 +8400,14 @@ function parseFrontmatter(raw) {
8346
8400
  return { applyTo, content };
8347
8401
  }
8348
8402
  async function readRuleFile(filePath) {
8349
- const raw = await Bun.file(filePath).text();
8403
+ const raw = await fs3.readFile(filePath, "utf-8");
8350
8404
  const { applyTo, content } = parseFrontmatter(raw);
8351
8405
  return { name: path3.basename(filePath, ".md"), path: filePath, applyTo, content };
8352
8406
  }
8353
8407
  async function readRules(root) {
8354
8408
  const rulesDir = path3.join(root, ".oneagent/rules");
8355
8409
  try {
8356
- const files = await fs2.readdir(rulesDir);
8410
+ const files = await fs3.readdir(rulesDir);
8357
8411
  const mdFiles = files.filter((f) => f.endsWith(".md"));
8358
8412
  const rules = await Promise.all(mdFiles.map((f) => readRuleFile(path3.join(rulesDir, f))));
8359
8413
  return rules.sort((a, b) => a.name.localeCompare(b.name));
@@ -8365,7 +8419,7 @@ var init_rules = () => {};
8365
8419
 
8366
8420
  // ../core/src/skills.ts
8367
8421
  import path4 from "path";
8368
- import fs3 from "fs/promises";
8422
+ import fs4 from "fs/promises";
8369
8423
  function parseSkillFrontmatter(raw) {
8370
8424
  const match = raw.match(/^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/);
8371
8425
  if (!match)
@@ -8380,14 +8434,14 @@ function parseSkillFrontmatter(raw) {
8380
8434
  return { description, mode, content };
8381
8435
  }
8382
8436
  async function readSkillFile(filePath) {
8383
- const raw = await Bun.file(filePath).text();
8437
+ const raw = await fs4.readFile(filePath, "utf-8");
8384
8438
  const { description, mode, content } = parseSkillFrontmatter(raw);
8385
8439
  return { name: path4.basename(filePath, ".md"), path: filePath, description, mode, content };
8386
8440
  }
8387
8441
  async function readSkills(root) {
8388
8442
  const skillsDir = path4.join(root, ".oneagent/skills");
8389
8443
  try {
8390
- const files = await fs3.readdir(skillsDir);
8444
+ const files = await fs4.readdir(skillsDir);
8391
8445
  const mdFiles = files.filter((f) => f.endsWith(".md"));
8392
8446
  const skills = await Promise.all(mdFiles.map((f) => readSkillFile(path4.join(skillsDir, f))));
8393
8447
  return skills.sort((a, b) => a.name.localeCompare(b.name));
@@ -8402,16 +8456,16 @@ var init_skills = __esm(() => {
8402
8456
 
8403
8457
  // ../core/src/symlinks.ts
8404
8458
  import path5 from "path";
8405
- import fs4 from "fs/promises";
8459
+ import fs5 from "fs/promises";
8406
8460
  async function ensureDir(dirPath) {
8407
- await fs4.mkdir(dirPath, { recursive: true });
8461
+ await fs5.mkdir(dirPath, { recursive: true });
8408
8462
  }
8409
8463
  async function createSymlink(symlinkPath, target) {
8410
8464
  await ensureDir(path5.dirname(symlinkPath));
8411
8465
  try {
8412
- await fs4.unlink(symlinkPath);
8466
+ await fs5.unlink(symlinkPath);
8413
8467
  } catch {}
8414
- await fs4.symlink(target, symlinkPath);
8468
+ await fs5.symlink(target, symlinkPath);
8415
8469
  }
8416
8470
  function relativeTarget(symlinkPath, targetAbsPath) {
8417
8471
  return path5.relative(path5.dirname(symlinkPath), targetAbsPath);
@@ -8420,24 +8474,8 @@ function buildMainSymlinks(root, targets) {
8420
8474
  const instructionsAbs = path5.join(root, ".oneagent/instructions.md");
8421
8475
  const seen = new Map;
8422
8476
  for (const target of targets) {
8423
- let symlinkPath;
8424
- switch (target) {
8425
- case "claude":
8426
- symlinkPath = path5.join(root, "CLAUDE.md");
8427
- break;
8428
- case "cursor":
8429
- symlinkPath = path5.join(root, "AGENTS.md");
8430
- break;
8431
- case "windsurf":
8432
- symlinkPath = path5.join(root, ".windsurfrules");
8433
- break;
8434
- case "opencode":
8435
- symlinkPath = path5.join(root, "AGENTS.md");
8436
- break;
8437
- case "copilot":
8438
- symlinkPath = path5.join(root, ".github/copilot-instructions.md");
8439
- break;
8440
- }
8477
+ const def = AGENT_DEFINITIONS.find((d2) => d2.target === target);
8478
+ const symlinkPath = path5.join(root, def.mainFile);
8441
8479
  if (!seen.has(symlinkPath)) {
8442
8480
  seen.set(symlinkPath, {
8443
8481
  symlinkPath,
@@ -8448,49 +8486,18 @@ function buildMainSymlinks(root, targets) {
8448
8486
  }
8449
8487
  return Array.from(seen.values());
8450
8488
  }
8451
- function buildRulesSymlinks(root, targets, rules) {
8452
- const entries = [];
8453
- for (const target of targets) {
8454
- let rulesDir = null;
8455
- switch (target) {
8456
- case "claude":
8457
- rulesDir = path5.join(root, ".claude/rules");
8458
- break;
8459
- case "cursor":
8460
- rulesDir = path5.join(root, ".cursor/rules");
8461
- break;
8462
- case "windsurf":
8463
- rulesDir = path5.join(root, ".windsurf/rules");
8464
- break;
8465
- case "opencode":
8466
- case "copilot":
8467
- rulesDir = null;
8468
- break;
8469
- }
8470
- if (!rulesDir)
8471
- continue;
8472
- for (const rule of rules) {
8473
- const symlinkPath = path5.join(rulesDir, `${rule.name}.md`);
8474
- entries.push({
8475
- symlinkPath,
8476
- target: relativeTarget(symlinkPath, rule.path),
8477
- label: path5.relative(root, symlinkPath)
8478
- });
8479
- }
8480
- }
8481
- return entries;
8489
+ function buildRulesSymlinks(root, targets) {
8490
+ const targetAbs = path5.join(root, ".oneagent/rules");
8491
+ return AGENT_DEFINITIONS.filter((d2) => targets.includes(d2.target) && d2.rulesDir).map((d2) => {
8492
+ const symlinkPath = path5.join(root, d2.rulesDir);
8493
+ return { symlinkPath, target: relativeTarget(symlinkPath, targetAbs), label: d2.rulesDir };
8494
+ });
8482
8495
  }
8483
- function buildSkillSymlinks(root, targets, skills) {
8484
- if (!targets.includes("claude"))
8485
- return [];
8486
- const commandsDir = path5.join(root, ".claude/commands");
8487
- return skills.map((skill) => {
8488
- const symlinkPath = path5.join(commandsDir, `${skill.name}.md`);
8489
- return {
8490
- symlinkPath,
8491
- target: relativeTarget(symlinkPath, skill.path),
8492
- label: path5.relative(root, symlinkPath)
8493
- };
8496
+ function buildSkillSymlinks(root, targets) {
8497
+ const targetAbs = path5.join(root, ".oneagent/skills");
8498
+ return AGENT_DEFINITIONS.filter((d2) => targets.includes(d2.target) && d2.skillsDir).map((d2) => {
8499
+ const symlinkPath = path5.join(root, d2.skillsDir);
8500
+ return { symlinkPath, target: relativeTarget(symlinkPath, targetAbs), label: d2.skillsDir };
8494
8501
  });
8495
8502
  }
8496
8503
  function buildAgentsDirSymlinks(root) {
@@ -8499,10 +8506,10 @@ function buildAgentsDirSymlinks(root) {
8499
8506
  return [{ symlinkPath, target: relativeTarget(symlinkPath, targetAbs), label: ".agents/skills" }];
8500
8507
  }
8501
8508
  async function migrateFilesFromDir(srcDir, destDir, root) {
8502
- await fs4.mkdir(destDir, { recursive: true });
8509
+ await fs5.mkdir(destDir, { recursive: true });
8503
8510
  let entries;
8504
8511
  try {
8505
- entries = await fs4.readdir(srcDir, { withFileTypes: true });
8512
+ entries = await fs5.readdir(srcDir, { withFileTypes: true });
8506
8513
  } catch {
8507
8514
  return;
8508
8515
  }
@@ -8513,37 +8520,37 @@ async function migrateFilesFromDir(srcDir, destDir, root) {
8513
8520
  const destFile = path5.join(destDir, entry.name);
8514
8521
  let destExists = false;
8515
8522
  try {
8516
- await fs4.access(destFile);
8523
+ await fs5.access(destFile);
8517
8524
  destExists = true;
8518
8525
  } catch {}
8519
8526
  if (destExists) {
8520
8527
  const [srcContent, destContent] = await Promise.all([
8521
- Bun.file(srcFile).text(),
8522
- Bun.file(destFile).text()
8528
+ fs5.readFile(srcFile, "utf-8"),
8529
+ fs5.readFile(destFile, "utf-8")
8523
8530
  ]);
8524
8531
  if (srcContent !== destContent) {
8525
8532
  const backupDir = path5.join(root, ".oneagent/backup");
8526
- await fs4.mkdir(backupDir, { recursive: true });
8533
+ await fs5.mkdir(backupDir, { recursive: true });
8527
8534
  const safeName = path5.relative(root, srcFile).replace(/\//g, "_");
8528
- await Bun.write(path5.join(backupDir, safeName), srcContent);
8535
+ await fs5.writeFile(path5.join(backupDir, safeName), srcContent);
8529
8536
  }
8530
- await fs4.unlink(srcFile);
8537
+ await fs5.unlink(srcFile);
8531
8538
  } else {
8532
- await fs4.rename(srcFile, destFile);
8539
+ await fs5.rename(srcFile, destFile);
8533
8540
  }
8534
8541
  }
8535
8542
  }
8536
8543
  async function migrateAndRemoveDir(src, dest, root) {
8537
8544
  let stat;
8538
8545
  try {
8539
- stat = await fs4.lstat(src);
8546
+ stat = await fs5.lstat(src);
8540
8547
  } catch {
8541
8548
  return;
8542
8549
  }
8543
8550
  if (stat.isSymbolicLink() || !stat.isDirectory())
8544
8551
  return;
8545
8552
  await migrateFilesFromDir(src, dest, root);
8546
- await fs4.rm(src, { recursive: true, force: true });
8553
+ await fs5.rm(src, { recursive: true, force: true });
8547
8554
  }
8548
8555
  async function migrateRuleAndSkillFiles(root) {
8549
8556
  const destRules = path5.join(root, ".oneagent/rules");
@@ -8558,21 +8565,23 @@ async function createAllSymlinks(entries) {
8558
8565
  }
8559
8566
  async function checkSymlink(entry) {
8560
8567
  try {
8561
- const stat = await fs4.lstat(entry.symlinkPath);
8568
+ const stat = await fs5.lstat(entry.symlinkPath);
8562
8569
  if (!stat.isSymbolicLink()) {
8563
8570
  return { ...entry, exists: true, valid: false };
8564
8571
  }
8565
- const linkTarget = await fs4.readlink(entry.symlinkPath);
8572
+ const linkTarget = await fs5.readlink(entry.symlinkPath);
8566
8573
  return { ...entry, exists: true, valid: linkTarget === entry.target };
8567
8574
  } catch {
8568
8575
  return { ...entry, exists: false, valid: false };
8569
8576
  }
8570
8577
  }
8571
- var init_symlinks = () => {};
8578
+ var init_symlinks = __esm(() => {
8579
+ init_agents();
8580
+ });
8572
8581
 
8573
8582
  // ../core/src/copilot.ts
8574
8583
  import path6 from "path";
8575
- import fs5 from "fs/promises";
8584
+ import fs6 from "fs/promises";
8576
8585
  function buildCopilotContent(rule) {
8577
8586
  return `---
8578
8587
  applyTo: "${rule.applyTo}"
@@ -8584,8 +8593,8 @@ function copilotFilePath(root, ruleName) {
8584
8593
  }
8585
8594
  async function generateCopilotRule(root, rule) {
8586
8595
  const filePath = copilotFilePath(root, rule.name);
8587
- await fs5.mkdir(path6.dirname(filePath), { recursive: true });
8588
- await Bun.write(filePath, buildCopilotContent(rule));
8596
+ await fs6.mkdir(path6.dirname(filePath), { recursive: true });
8597
+ await fs6.writeFile(filePath, buildCopilotContent(rule));
8589
8598
  }
8590
8599
  async function generateCopilotRules(root, rules) {
8591
8600
  await Promise.all(rules.map((rule) => generateCopilotRule(root, rule)));
@@ -8603,8 +8612,8 @@ function copilotPromptFilePath(root, skillName) {
8603
8612
  }
8604
8613
  async function generateCopilotSkill(root, skill) {
8605
8614
  const filePath = copilotPromptFilePath(root, skill.name);
8606
- await fs5.mkdir(path6.dirname(filePath), { recursive: true });
8607
- await Bun.write(filePath, buildCopilotPromptContent(skill));
8615
+ await fs6.mkdir(path6.dirname(filePath), { recursive: true });
8616
+ await fs6.writeFile(filePath, buildCopilotPromptContent(skill));
8608
8617
  }
8609
8618
  async function generateCopilotSkills(root, skills) {
8610
8619
  await Promise.all(skills.map((skill) => generateCopilotSkill(root, skill)));
@@ -8613,9 +8622,10 @@ var init_copilot = () => {};
8613
8622
 
8614
8623
  // ../core/src/opencode.ts
8615
8624
  import path7 from "path";
8625
+ import fs7 from "fs/promises";
8616
8626
  async function readOpencode(root) {
8617
8627
  try {
8618
- const content = await Bun.file(path7.join(root, "opencode.json")).text();
8628
+ const content = await fs7.readFile(path7.join(root, "opencode.json"), "utf-8");
8619
8629
  return JSON.parse(content);
8620
8630
  } catch {
8621
8631
  return null;
@@ -8630,21 +8640,21 @@ function buildOpencodeConfig(existing) {
8630
8640
  async function writeOpencode(root, _rules) {
8631
8641
  const existing = await readOpencode(root);
8632
8642
  const config = buildOpencodeConfig(existing);
8633
- await Bun.write(path7.join(root, "opencode.json"), JSON.stringify(config, null, 2) + `
8643
+ await fs7.writeFile(path7.join(root, "opencode.json"), JSON.stringify(config, null, 2) + `
8634
8644
  `);
8635
8645
  }
8636
8646
  var init_opencode = () => {};
8637
8647
 
8638
8648
  // ../core/src/generate.ts
8639
8649
  import path8 from "path";
8640
- import fs6 from "fs/promises";
8650
+ import fs8 from "fs/promises";
8641
8651
  async function detectGenerateCollisions(root, config) {
8642
8652
  const [rules, skills] = await Promise.all([readRules(root), readSkills(root)]);
8643
8653
  const targets = activeTargets(config);
8644
8654
  const mainEntries = buildMainSymlinks(root, targets);
8645
8655
  const ruleSkillEntries = [
8646
- ...buildRulesSymlinks(root, targets, rules),
8647
- ...buildSkillSymlinks(root, targets, skills)
8656
+ ...buildRulesSymlinks(root, targets),
8657
+ ...buildSkillSymlinks(root, targets)
8648
8658
  ];
8649
8659
  const [mainCollisions, ruleSkillSymlinkCollisions] = await Promise.all([
8650
8660
  Promise.all(mainEntries.map((entry) => readDetectedFile(root, path8.relative(root, entry.symlinkPath)))).then((files) => files.filter((f) => f !== null)),
@@ -8656,10 +8666,10 @@ async function detectGenerateCollisions(root, config) {
8656
8666
  ...rules.map(async (rule) => {
8657
8667
  const filePath = copilotFilePath(root, rule.name);
8658
8668
  try {
8659
- const content = await Bun.file(filePath).text();
8669
+ const content = await fs8.readFile(filePath, "utf-8");
8660
8670
  if (content === buildCopilotContent(rule))
8661
8671
  return null;
8662
- const stat = await fs6.lstat(filePath);
8672
+ const stat = await fs8.lstat(filePath);
8663
8673
  return { relativePath: path8.relative(root, filePath), absolutePath: filePath, sizeBytes: stat.size, modifiedAt: stat.mtime, content };
8664
8674
  } catch {
8665
8675
  return null;
@@ -8668,10 +8678,10 @@ async function detectGenerateCollisions(root, config) {
8668
8678
  ...skills.map(async (skill) => {
8669
8679
  const filePath = copilotPromptFilePath(root, skill.name);
8670
8680
  try {
8671
- const content = await Bun.file(filePath).text();
8681
+ const content = await fs8.readFile(filePath, "utf-8");
8672
8682
  if (content === buildCopilotPromptContent(skill))
8673
8683
  return null;
8674
- const stat = await fs6.lstat(filePath);
8684
+ const stat = await fs8.lstat(filePath);
8675
8685
  return { relativePath: path8.relative(root, filePath), absolutePath: filePath, sizeBytes: stat.size, modifiedAt: stat.mtime, content };
8676
8686
  } catch {
8677
8687
  return null;
@@ -8688,10 +8698,10 @@ async function detectGenerateCollisions(root, config) {
8688
8698
  async function generate(root, config) {
8689
8699
  const [rules, skills] = await Promise.all([readRules(root), readSkills(root)]);
8690
8700
  const targets = activeTargets(config);
8691
- const mainSymlinks = buildMainSymlinks(root, targets);
8692
- const rulesSymlinks = buildRulesSymlinks(root, targets, rules);
8693
- const skillSymlinks = buildSkillSymlinks(root, targets, skills);
8694
8701
  await migrateRuleAndSkillFiles(root);
8702
+ const mainSymlinks = buildMainSymlinks(root, targets);
8703
+ const rulesSymlinks = buildRulesSymlinks(root, targets);
8704
+ const skillSymlinks = await buildSkillSymlinks(root, targets);
8695
8705
  await createAllSymlinks([...mainSymlinks, ...rulesSymlinks, ...skillSymlinks, ...buildAgentsDirSymlinks(root)]);
8696
8706
  if (targets.includes("copilot")) {
8697
8707
  await Promise.all([generateCopilotRules(root, rules), generateCopilotSkills(root, skills)]);
@@ -8711,11 +8721,12 @@ var init_generate = __esm(() => {
8711
8721
  });
8712
8722
 
8713
8723
  // ../core/src/status.ts
8724
+ import fs9 from "fs/promises";
8714
8725
  async function checkGeneratedFile(root, rule) {
8715
8726
  const filePath = copilotFilePath(root, rule.name);
8716
8727
  const expected = buildCopilotContent(rule);
8717
8728
  try {
8718
- const content = await Bun.file(filePath).text();
8729
+ const content = await fs9.readFile(filePath, "utf-8");
8719
8730
  return { path: filePath, exists: true, upToDate: content === expected };
8720
8731
  } catch {
8721
8732
  return { path: filePath, exists: false, upToDate: false };
@@ -8731,7 +8742,7 @@ async function checkCopilotPrompt(root, skill) {
8731
8742
  const filePath = copilotPromptFilePath(root, skill.name);
8732
8743
  const expected = buildCopilotPromptContent(skill);
8733
8744
  try {
8734
- const content = await Bun.file(filePath).text();
8745
+ const content = await fs9.readFile(filePath, "utf-8");
8735
8746
  return { path: filePath, exists: true, upToDate: content === expected };
8736
8747
  } catch {
8737
8748
  return { path: filePath, exists: false, upToDate: false };
@@ -8742,8 +8753,8 @@ async function checkStatus(root, config) {
8742
8753
  const targets = activeTargets(config);
8743
8754
  const allEntries = [
8744
8755
  ...buildMainSymlinks(root, targets),
8745
- ...buildRulesSymlinks(root, targets, rules),
8746
- ...buildSkillSymlinks(root, targets, skills),
8756
+ ...buildRulesSymlinks(root, targets),
8757
+ ...buildSkillSymlinks(root, targets),
8747
8758
  ...buildAgentsDirSymlinks(root)
8748
8759
  ];
8749
8760
  const symlinks = await Promise.all(allEntries.map(checkSymlink));
@@ -8765,20 +8776,22 @@ var init_status = __esm(() => {
8765
8776
 
8766
8777
  // ../core/src/apply-template.ts
8767
8778
  import path9 from "path";
8768
- import fs7 from "fs/promises";
8779
+ import fs10 from "fs/promises";
8780
+ import { execFile } from "child_process";
8781
+ import { promisify } from "util";
8769
8782
  async function applyTemplateFiles(root, template) {
8770
8783
  const oneagentDir = path9.join(root, ".oneagent");
8771
- await fs7.mkdir(path9.join(oneagentDir, "rules"), { recursive: true });
8772
- await fs7.mkdir(path9.join(oneagentDir, "skills"), { recursive: true });
8773
- await Bun.write(path9.join(oneagentDir, "instructions.md"), template.instructions);
8784
+ await fs10.mkdir(path9.join(oneagentDir, "rules"), { recursive: true });
8785
+ await fs10.mkdir(path9.join(oneagentDir, "skills"), { recursive: true });
8786
+ await fs10.writeFile(path9.join(oneagentDir, "instructions.md"), template.instructions);
8774
8787
  for (const rule of template.rules) {
8775
- await Bun.write(path9.join(oneagentDir, "rules", `${rule.name}.md`), rule.content);
8788
+ await fs10.writeFile(path9.join(oneagentDir, "rules", `${rule.name}.md`), rule.content);
8776
8789
  }
8777
8790
  }
8778
8791
  async function installTemplateSkills(root, template, onSkillInstalled) {
8779
8792
  for (const identifier of template.skills) {
8780
8793
  try {
8781
- await Bun.$`bunx skills add ${identifier} --agent universal --yes`.cwd(root).quiet();
8794
+ await execFileAsync("npx", ["skills", "add", identifier, "--agent", "universal", "--yes"], { cwd: root });
8782
8795
  onSkillInstalled?.(identifier);
8783
8796
  } catch (err) {
8784
8797
  const message = err instanceof Error ? err.message : String(err);
@@ -8848,10 +8861,14 @@ async function fetchGitHubRules(repoUrl) {
8848
8861
  return [];
8849
8862
  }
8850
8863
  }
8851
- var init_apply_template = () => {};
8864
+ var execFileAsync;
8865
+ var init_apply_template = __esm(() => {
8866
+ execFileAsync = promisify(execFile);
8867
+ });
8852
8868
 
8853
8869
  // ../core/src/index.ts
8854
8870
  var init_src = __esm(() => {
8871
+ init_agents();
8855
8872
  init_config();
8856
8873
  init_detect();
8857
8874
  init_rules();
@@ -8899,12 +8916,13 @@ var init_utils = __esm(() => {
8899
8916
 
8900
8917
  // ../templates/src/index.ts
8901
8918
  import path10 from "path";
8902
- import fs8 from "fs/promises";
8919
+ import fs11 from "fs/promises";
8920
+ import { fileURLToPath } from "url";
8903
8921
  async function loadTemplate(name) {
8904
- const templateDir = path10.join(import.meta.dir, "templates", name);
8922
+ const templateDir = path10.join(__dirname2, "templates", name);
8905
8923
  const [yamlText, instructions] = await Promise.all([
8906
- Bun.file(path10.join(templateDir, "template.yml")).text(),
8907
- Bun.file(path10.join(templateDir, "instructions.md")).text()
8924
+ fs11.readFile(path10.join(templateDir, "template.yml"), "utf-8"),
8925
+ fs11.readFile(path10.join(templateDir, "instructions.md"), "utf-8")
8908
8926
  ]);
8909
8927
  const descMatch = yamlText.match(/^description:\s*(.+)$/m);
8910
8928
  const description = descMatch?.[1]?.trim() ?? "";
@@ -8922,10 +8940,10 @@ async function loadTemplate(name) {
8922
8940
  const rulesDir = path10.join(templateDir, "rules");
8923
8941
  let rules2 = [];
8924
8942
  try {
8925
- const ruleFiles = await fs8.readdir(rulesDir);
8943
+ const ruleFiles = await fs11.readdir(rulesDir);
8926
8944
  rules2 = await Promise.all(ruleFiles.filter((f) => f.endsWith(".md")).map(async (f) => ({
8927
8945
  name: path10.basename(f, ".md"),
8928
- content: await Bun.file(path10.join(rulesDir, f)).text()
8946
+ content: await fs11.readFile(path10.join(rulesDir, f), "utf-8")
8929
8947
  })));
8930
8948
  } catch {}
8931
8949
  return { name, description, skills: skills2, instructions, rules: rules2 };
@@ -8935,8 +8953,9 @@ async function resolveBuiltinTemplate(name) {
8935
8953
  return null;
8936
8954
  return loadTemplate(name);
8937
8955
  }
8938
- var TEMPLATE_NAMES, BUILTIN_TEMPLATE_NAMES;
8956
+ var __dirname2, TEMPLATE_NAMES, BUILTIN_TEMPLATE_NAMES;
8939
8957
  var init_src2 = __esm(() => {
8958
+ __dirname2 = path10.dirname(fileURLToPath(import.meta.url));
8940
8959
  TEMPLATE_NAMES = ["default", "react", "react-native"];
8941
8960
  BUILTIN_TEMPLATE_NAMES = TEMPLATE_NAMES;
8942
8961
  });
@@ -8947,7 +8966,7 @@ __export(exports_init, {
8947
8966
  default: () => init_default
8948
8967
  });
8949
8968
  import path11 from "path";
8950
- import fs9 from "fs/promises";
8969
+ import fs12 from "fs/promises";
8951
8970
  function cancelAndExit() {
8952
8971
  Le("Cancelled.");
8953
8972
  process.exit(0);
@@ -8999,18 +9018,24 @@ async function chooseContent(detected) {
8999
9018
  const index = parseInt(result.replace("file:", ""), 10);
9000
9019
  return detected[index].content;
9001
9020
  }
9002
- async function pickTargets() {
9021
+ async function detectPresentTargets(root) {
9022
+ const results = await Promise.all(AGENT_DEFINITIONS.map(async (def) => {
9023
+ for (const indicator of def.detectIndicators) {
9024
+ try {
9025
+ await fs12.access(path11.join(root, indicator));
9026
+ return def.target;
9027
+ } catch {}
9028
+ }
9029
+ return null;
9030
+ }));
9031
+ return results.filter((t) => t !== null);
9032
+ }
9033
+ async function pickTargets(initialValues) {
9003
9034
  const result = await je({
9004
9035
  message: `Which AI agents do you want to support?
9005
9036
  \x1B[90m · Space to toggle · Enter to confirm\x1B[39m`,
9006
- options: [
9007
- { value: "claude", label: "Claude Code", hint: "CLAUDE.md + .claude/rules/" },
9008
- { value: "cursor", label: "Cursor", hint: "AGENTS.md + .cursor/rules/" },
9009
- { value: "windsurf", label: "Windsurf", hint: ".windsurfrules + .windsurf/rules/" },
9010
- { value: "opencode", label: "OpenCode", hint: "AGENTS.md + opencode.json" },
9011
- { value: "copilot", label: "GitHub Copilot", hint: ".github/instructions/*.instructions.md" }
9012
- ],
9013
- initialValues: ["claude"],
9037
+ options: AGENT_DEFINITIONS.map((d2) => ({ value: d2.target, label: d2.displayName, hint: d2.hint })),
9038
+ initialValues,
9014
9039
  required: true
9015
9040
  });
9016
9041
  if (Ct(result))
@@ -9021,10 +9046,10 @@ async function backupFiles(root, files) {
9021
9046
  if (files.length === 0)
9022
9047
  return;
9023
9048
  const backupDir = path11.join(root, ".oneagent/backup");
9024
- await fs9.mkdir(backupDir, { recursive: true });
9049
+ await fs12.mkdir(backupDir, { recursive: true });
9025
9050
  for (const file of files) {
9026
9051
  const safeName = file.relativePath.replace(/\//g, "_");
9027
- await Bun.write(path11.join(backupDir, safeName), file.content);
9052
+ await fs12.writeFile(path11.join(backupDir, safeName), file.content);
9028
9053
  }
9029
9054
  }
9030
9055
  async function resolveTemplate(templateArg) {
@@ -9101,11 +9126,12 @@ var init_init = __esm(() => {
9101
9126
  } else {
9102
9127
  importedContent = await chooseContent(detected);
9103
9128
  }
9104
- const selectedTargets = await pickTargets();
9129
+ const presentTargets = await detectPresentTargets(root);
9130
+ const selectedTargets = await pickTargets(presentTargets);
9105
9131
  const s = bt2();
9106
9132
  s.start("Setting up .oneagent/ directory...");
9107
- await fs9.mkdir(path11.join(root, ".oneagent/rules"), { recursive: true });
9108
- await fs9.mkdir(path11.join(root, ".oneagent/skills"), { recursive: true });
9133
+ await fs12.mkdir(path11.join(root, ".oneagent/rules"), { recursive: true });
9134
+ await fs12.mkdir(path11.join(root, ".oneagent/skills"), { recursive: true });
9109
9135
  await backupFiles(root, detected);
9110
9136
  await removeDeprecatedFiles(root);
9111
9137
  await warnDeprecatedCommandFiles(root);
@@ -9119,9 +9145,9 @@ var init_init = __esm(() => {
9119
9145
 
9120
9146
  Add your AI instructions here.
9121
9147
  `;
9122
- await Bun.write(path11.join(root, ".oneagent/instructions.md"), instructionsContent);
9148
+ await fs12.writeFile(path11.join(root, ".oneagent/instructions.md"), instructionsContent);
9123
9149
  }
9124
- await Bun.write(path11.join(root, ".oneagent/rules/oneagent.md"), DOTAI_META_RULE);
9150
+ await fs12.writeFile(path11.join(root, ".oneagent/rules/oneagent.md"), DOTAI_META_RULE);
9125
9151
  s.stop("Directory structure created.");
9126
9152
  const s2 = bt2();
9127
9153
  s2.start("Generating symlinks and agent files...");
@@ -9157,7 +9183,7 @@ __export(exports_generate, {
9157
9183
  default: () => generate_default
9158
9184
  });
9159
9185
  import path12 from "path";
9160
- import fs10 from "fs/promises";
9186
+ import fs13 from "fs/promises";
9161
9187
  var generate_default;
9162
9188
  var init_generate2 = __esm(() => {
9163
9189
  init_dist();
@@ -9181,10 +9207,10 @@ var init_generate2 = __esm(() => {
9181
9207
  const { mainFiles, ruleSkillFiles } = await detectGenerateCollisions(root, config2);
9182
9208
  if (mainFiles.length > 0) {
9183
9209
  const backupDir = path12.join(root, ".oneagent/backup");
9184
- await fs10.mkdir(backupDir, { recursive: true });
9210
+ await fs13.mkdir(backupDir, { recursive: true });
9185
9211
  for (const file of mainFiles) {
9186
9212
  const safeName = file.relativePath.replace(/\//g, "_");
9187
- await Bun.write(path12.join(backupDir, safeName), file.content);
9213
+ await fs13.writeFile(path12.join(backupDir, safeName), file.content);
9188
9214
  }
9189
9215
  }
9190
9216
  await warnDeprecatedCommandFiles(root);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oneagent",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "type": "module",
5
5
  "description": "One source of truth for AI agent rules — distributed via symlinks to Claude, Cursor, Windsurf, Copilot, OpenCode",
6
6
  "license": "MIT",