oneagent 0.2.5 → 0.2.6

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 +91 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1326,9 +1326,11 @@ var init_agents = __esm(() => {
1326
1326
  {
1327
1327
  target: "opencode",
1328
1328
  displayName: "OpenCode",
1329
- hint: "AGENTS.md + opencode.json",
1329
+ hint: "AGENTS.md + .opencode/",
1330
1330
  detectIndicators: ["opencode.json", ".opencode"],
1331
- mainFile: "AGENTS.md"
1331
+ mainFile: "AGENTS.md",
1332
+ rulesDir: ".opencode/rules",
1333
+ skillsDir: ".opencode/skills"
1332
1334
  },
1333
1335
  {
1334
1336
  target: "copilot",
@@ -8463,7 +8465,7 @@ async function ensureDir(dirPath) {
8463
8465
  async function createSymlink(symlinkPath, target) {
8464
8466
  await ensureDir(path5.dirname(symlinkPath));
8465
8467
  try {
8466
- await fs5.unlink(symlinkPath);
8468
+ await fs5.rm(symlinkPath, { recursive: true });
8467
8469
  } catch {}
8468
8470
  await fs5.symlink(target, symlinkPath);
8469
8471
  }
@@ -8555,9 +8557,10 @@ async function migrateAndRemoveDir(src, dest, root) {
8555
8557
  async function migrateRuleAndSkillFiles(root) {
8556
8558
  const destRules = path5.join(root, ".oneagent/rules");
8557
8559
  const destSkills = path5.join(root, ".oneagent/skills");
8558
- await migrateFilesFromDir(path5.join(root, ".cursor/rules"), destRules, root);
8559
- await migrateFilesFromDir(path5.join(root, ".claude/rules"), destRules, root);
8560
- await migrateFilesFromDir(path5.join(root, ".windsurf/rules"), destRules, root);
8560
+ await migrateAndRemoveDir(path5.join(root, ".cursor/rules"), destRules, root);
8561
+ await migrateAndRemoveDir(path5.join(root, ".claude/rules"), destRules, root);
8562
+ await migrateAndRemoveDir(path5.join(root, ".windsurf/rules"), destRules, root);
8563
+ await migrateAndRemoveDir(path5.join(root, ".opencode/rules"), destRules, root);
8561
8564
  await migrateAndRemoveDir(path5.join(root, ".agents/skills"), destSkills, root);
8562
8565
  }
8563
8566
  async function createAllSymlinks(entries) {
@@ -8637,6 +8640,21 @@ function buildOpencodeConfig(existing) {
8637
8640
  instructions: ".oneagent/instructions.md"
8638
8641
  };
8639
8642
  }
8643
+ async function addOpenCodePlugin(root, id) {
8644
+ const filePath = path7.join(root, "opencode.json");
8645
+ let existing;
8646
+ try {
8647
+ existing = JSON.parse(await fs7.readFile(filePath, "utf-8"));
8648
+ } catch {
8649
+ return;
8650
+ }
8651
+ const current = Array.isArray(existing.plugin) ? existing.plugin : [];
8652
+ if (current.includes(id))
8653
+ return;
8654
+ existing.plugin = [...current, id];
8655
+ await fs7.writeFile(filePath, JSON.stringify(existing, null, 2) + `
8656
+ `);
8657
+ }
8640
8658
  async function writeOpencode(root, _rules) {
8641
8659
  const existing = await readOpencode(root);
8642
8660
  const config = buildOpencodeConfig(existing);
@@ -8779,6 +8797,25 @@ import path9 from "path";
8779
8797
  import fs10 from "fs/promises";
8780
8798
  import { execFile } from "child_process";
8781
8799
  import { promisify } from "util";
8800
+ function parsePluginsFromYaml(yamlText) {
8801
+ const plugins = [];
8802
+ const section = yamlText.match(/^plugins:\s*\n((?:(?: -.+|\s{4}.+)\n?)*)/m);
8803
+ if (!section)
8804
+ return plugins;
8805
+ const block = section[1];
8806
+ const entries = block.split(/\n(?= -)/);
8807
+ for (const entry of entries) {
8808
+ const targetMatch = entry.match(/target:\s*(\S+)/);
8809
+ const idMatch = entry.match(/id:\s*(.+)/);
8810
+ if (targetMatch && idMatch) {
8811
+ plugins.push({
8812
+ target: targetMatch[1].trim(),
8813
+ id: idMatch[1].trim()
8814
+ });
8815
+ }
8816
+ }
8817
+ return plugins;
8818
+ }
8782
8819
  async function applyTemplateFiles(root, template) {
8783
8820
  const oneagentDir = path9.join(root, ".oneagent");
8784
8821
  await fs10.mkdir(path9.join(oneagentDir, "rules"), { recursive: true });
@@ -8799,6 +8836,37 @@ async function installTemplateSkills(root, template, onSkillInstalled) {
8799
8836
  }
8800
8837
  }
8801
8838
  }
8839
+ async function installTemplatePlugins(root, template, activeTargets2, onPluginInstalled) {
8840
+ const installed = [];
8841
+ const manual = [];
8842
+ for (const plugin of template.plugins) {
8843
+ if (!activeTargets2.includes(plugin.target))
8844
+ continue;
8845
+ switch (plugin.target) {
8846
+ case "claude":
8847
+ await execFileAsync("claude", ["plugin", "install", plugin.id], { cwd: root });
8848
+ installed.push(plugin);
8849
+ onPluginInstalled?.(plugin);
8850
+ break;
8851
+ case "copilot":
8852
+ await execFileAsync("copilot", ["plugin", "install", plugin.id], { cwd: root });
8853
+ installed.push(plugin);
8854
+ onPluginInstalled?.(plugin);
8855
+ break;
8856
+ case "opencode":
8857
+ await addOpenCodePlugin(root, plugin.id);
8858
+ installed.push(plugin);
8859
+ onPluginInstalled?.(plugin);
8860
+ break;
8861
+ case "cursor":
8862
+ manual.push(plugin);
8863
+ break;
8864
+ case "windsurf":
8865
+ break;
8866
+ }
8867
+ }
8868
+ return { installed, manual };
8869
+ }
8802
8870
  async function fetchTemplateFromGitHub(url) {
8803
8871
  const rawBase = githubUrlToRawBase(url);
8804
8872
  const [yamlText, instructions] = await Promise.all([
@@ -8820,8 +8888,9 @@ async function fetchTemplateFromGitHub(url) {
8820
8888
  skills.push(skill);
8821
8889
  }
8822
8890
  }
8891
+ const plugins = parsePluginsFromYaml(yamlText);
8823
8892
  const rules = await fetchGitHubRules(url);
8824
- return { name, description, skills, instructions, rules };
8893
+ return { name, description, skills, plugins, instructions, rules };
8825
8894
  }
8826
8895
  async function fetchText(url) {
8827
8896
  const response = await fetch(url);
@@ -8863,6 +8932,7 @@ async function fetchGitHubRules(repoUrl) {
8863
8932
  }
8864
8933
  var execFileAsync;
8865
8934
  var init_apply_template = __esm(() => {
8935
+ init_opencode();
8866
8936
  execFileAsync = promisify(execFile);
8867
8937
  });
8868
8938
 
@@ -8937,6 +9007,7 @@ async function loadTemplate(name) {
8937
9007
  skills2.push(skill);
8938
9008
  }
8939
9009
  }
9010
+ const plugins = parsePluginsFromYaml(yamlText);
8940
9011
  const rulesDir = path10.join(templateDir, "rules");
8941
9012
  let rules2 = [];
8942
9013
  try {
@@ -8946,7 +9017,7 @@ async function loadTemplate(name) {
8946
9017
  content: await fs11.readFile(path10.join(rulesDir, f), "utf-8")
8947
9018
  })));
8948
9019
  } catch {}
8949
- return { name, description, skills: skills2, instructions, rules: rules2 };
9020
+ return { name, description, skills: skills2, plugins, instructions, rules: rules2 };
8950
9021
  }
8951
9022
  async function resolveBuiltinTemplate(name) {
8952
9023
  if (!TEMPLATE_NAMES.includes(name))
@@ -8955,6 +9026,7 @@ async function resolveBuiltinTemplate(name) {
8955
9026
  }
8956
9027
  var __dirname2, TEMPLATE_NAMES, BUILTIN_TEMPLATE_NAMES;
8957
9028
  var init_src2 = __esm(() => {
9029
+ init_src();
8958
9030
  __dirname2 = path10.dirname(fileURLToPath(import.meta.url));
8959
9031
  TEMPLATE_NAMES = ["default", "react", "react-native"];
8960
9032
  BUILTIN_TEMPLATE_NAMES = TEMPLATE_NAMES;
@@ -9134,7 +9206,6 @@ var init_init = __esm(() => {
9134
9206
  await fs12.mkdir(path11.join(root, ".oneagent/skills"), { recursive: true });
9135
9207
  await backupFiles(root, detected);
9136
9208
  await removeDeprecatedFiles(root);
9137
- await warnDeprecatedCommandFiles(root);
9138
9209
  await migrateRuleAndSkillFiles(root);
9139
9210
  const config2 = { version: 1, targets: makeTargets(...selectedTargets) };
9140
9211
  await writeConfig(root, config2);
@@ -9149,6 +9220,7 @@ Add your AI instructions here.
9149
9220
  }
9150
9221
  await fs12.writeFile(path11.join(root, ".oneagent/rules/oneagent.md"), DOTAI_META_RULE);
9151
9222
  s.stop("Directory structure created.");
9223
+ await warnDeprecatedCommandFiles(root);
9152
9224
  const s2 = bt2();
9153
9225
  s2.start("Generating symlinks and agent files...");
9154
9226
  await generate(root, config2);
@@ -9160,11 +9232,20 @@ Add your AI instructions here.
9160
9232
  await installTemplateSkills(root, template, (id) => fetchedSkills.push(id));
9161
9233
  s3.stop(`Installed ${fetchedSkills.length} skill(s).`);
9162
9234
  }
9235
+ let pluginResult = { installed: [], manual: [] };
9236
+ if (template && template.plugins.length > 0) {
9237
+ const s4 = bt2();
9238
+ s4.start("Installing plugins...");
9239
+ pluginResult = await installTemplatePlugins(root, template, selectedTargets);
9240
+ s4.stop(`Installed ${pluginResult.installed.length} plugin(s).`);
9241
+ }
9163
9242
  const lines = [
9164
9243
  ...template ? [
9165
9244
  `Template: ${template.name} — ${template.description}`,
9166
9245
  ...fetchedSkills.length > 0 ? [`Fetched ${fetchedSkills.length} skill(s): ${fetchedSkills.join(", ")}`] : [],
9167
- ...template.rules.length > 0 ? [`Added ${template.rules.length} rule(s) from template`] : []
9246
+ ...template.rules.length > 0 ? [`Added ${template.rules.length} rule(s) from template`] : [],
9247
+ ...pluginResult.installed.length > 0 ? [`Installed ${pluginResult.installed.length} plugin(s): ${pluginResult.installed.map((p) => p.id).join(", ")}`] : [],
9248
+ ...pluginResult.manual.map((p) => `Run in Cursor chat: /add-plugin ${p.id}`)
9168
9249
  ] : ["Created .oneagent/instructions.md"],
9169
9250
  "Created .oneagent/rules/oneagent.md",
9170
9251
  ...selectedTargets.map((t) => `Configured: ${t}`),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oneagent",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
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",