oneagent 0.3.0 → 0.4.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.
- package/dist/index.js +470 -85
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1387,6 +1387,9 @@ function timeAgo(date) {
|
|
|
1387
1387
|
return `${months}mo ago`;
|
|
1388
1388
|
return `${Math.floor(months / 12)}y ago`;
|
|
1389
1389
|
}
|
|
1390
|
+
|
|
1391
|
+
// ../core/src/constants.ts
|
|
1392
|
+
var ONEAGENT_DIR = ".oneagent";
|
|
1390
1393
|
// ../core/src/agents.ts
|
|
1391
1394
|
var AGENT_DEFINITIONS;
|
|
1392
1395
|
var init_agents = __esm(() => {
|
|
@@ -1436,7 +1439,7 @@ var init_agents = __esm(() => {
|
|
|
1436
1439
|
target: "copilot",
|
|
1437
1440
|
displayName: "GitHub Copilot",
|
|
1438
1441
|
hint: ".github/instructions/*.instructions.md",
|
|
1439
|
-
detectIndicators: [".github/copilot-instructions.md", ".github"],
|
|
1442
|
+
detectIndicators: [".github/copilot-instructions.md", ".github/instructions"],
|
|
1440
1443
|
mainFile: ".github/copilot-instructions.md",
|
|
1441
1444
|
skillsDir: ".github/skills"
|
|
1442
1445
|
}
|
|
@@ -8415,9 +8418,10 @@ async function writeConfig(root, config) {
|
|
|
8415
8418
|
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
8416
8419
|
await fs.writeFile(filePath, $stringify(config));
|
|
8417
8420
|
}
|
|
8418
|
-
var CONFIG_REL
|
|
8421
|
+
var CONFIG_REL, ALL_AGENT_TARGETS;
|
|
8419
8422
|
var init_config = __esm(() => {
|
|
8420
8423
|
init_dist4();
|
|
8424
|
+
CONFIG_REL = `${ONEAGENT_DIR}/config.yml`;
|
|
8421
8425
|
ALL_AGENT_TARGETS = ["claude", "cursor", "windsurf", "opencode", "copilot"];
|
|
8422
8426
|
});
|
|
8423
8427
|
|
|
@@ -8431,7 +8435,7 @@ async function readDetectedFile(root, rel) {
|
|
|
8431
8435
|
if (stat.isSymbolicLink()) {
|
|
8432
8436
|
const linkTarget = await fs2.readlink(absolutePath);
|
|
8433
8437
|
const resolved = path2.resolve(path2.dirname(absolutePath), linkTarget);
|
|
8434
|
-
if (resolved.startsWith(path2.join(root,
|
|
8438
|
+
if (resolved.startsWith(path2.join(root, ONEAGENT_DIR)))
|
|
8435
8439
|
return null;
|
|
8436
8440
|
}
|
|
8437
8441
|
const content = await fs2.readFile(absolutePath, "utf-8");
|
|
@@ -8483,7 +8487,7 @@ var init_detect = __esm(() => {
|
|
|
8483
8487
|
import path3 from "path";
|
|
8484
8488
|
import fs3 from "fs/promises";
|
|
8485
8489
|
async function readRules(root) {
|
|
8486
|
-
const rulesDir = path3.join(root, "
|
|
8490
|
+
const rulesDir = path3.join(root, ONEAGENT_DIR, "rules");
|
|
8487
8491
|
try {
|
|
8488
8492
|
const files = await fs3.readdir(rulesDir);
|
|
8489
8493
|
return files.filter((f) => f.endsWith(".md")).map((f) => ({ name: path3.basename(f, ".md"), path: path3.join(rulesDir, f) })).sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -8518,7 +8522,7 @@ async function readSkillFile(filePath) {
|
|
|
8518
8522
|
return { name: path4.basename(filePath, ".md"), path: filePath, description, mode, content };
|
|
8519
8523
|
}
|
|
8520
8524
|
async function readSkills(root) {
|
|
8521
|
-
const skillsDir = path4.join(root, "
|
|
8525
|
+
const skillsDir = path4.join(root, ONEAGENT_DIR, "skills");
|
|
8522
8526
|
try {
|
|
8523
8527
|
const files = await fs4.readdir(skillsDir);
|
|
8524
8528
|
const mdFiles = files.filter((f) => f.endsWith(".md"));
|
|
@@ -8542,15 +8546,26 @@ async function ensureDir(dirPath) {
|
|
|
8542
8546
|
async function createSymlink(symlinkPath, target) {
|
|
8543
8547
|
await ensureDir(path5.dirname(symlinkPath));
|
|
8544
8548
|
try {
|
|
8545
|
-
await fs5.
|
|
8549
|
+
const stat = await fs5.lstat(symlinkPath);
|
|
8550
|
+
if (stat.isSymbolicLink() && await fs5.readlink(symlinkPath) === target)
|
|
8551
|
+
return;
|
|
8546
8552
|
} catch {}
|
|
8547
|
-
|
|
8553
|
+
for (let attempt = 0;attempt < 3; attempt++) {
|
|
8554
|
+
await fs5.rm(symlinkPath, { recursive: true, force: true });
|
|
8555
|
+
try {
|
|
8556
|
+
await fs5.symlink(target, symlinkPath);
|
|
8557
|
+
return;
|
|
8558
|
+
} catch (err) {
|
|
8559
|
+
if (err.code !== "EEXIST" || attempt === 2)
|
|
8560
|
+
throw err;
|
|
8561
|
+
}
|
|
8562
|
+
}
|
|
8548
8563
|
}
|
|
8549
8564
|
function relativeTarget(symlinkPath, targetAbsPath) {
|
|
8550
8565
|
return path5.relative(path5.dirname(symlinkPath), targetAbsPath);
|
|
8551
8566
|
}
|
|
8552
8567
|
function buildMainSymlinks(root, targets) {
|
|
8553
|
-
const instructionsAbs = path5.join(root, "
|
|
8568
|
+
const instructionsAbs = path5.join(root, ONEAGENT_DIR, "instructions.md");
|
|
8554
8569
|
const seen = new Map;
|
|
8555
8570
|
for (const target of targets) {
|
|
8556
8571
|
const def = AGENT_DEFINITIONS.find((d2) => d2.target === target);
|
|
@@ -8566,21 +8581,21 @@ function buildMainSymlinks(root, targets) {
|
|
|
8566
8581
|
return Array.from(seen.values());
|
|
8567
8582
|
}
|
|
8568
8583
|
function buildRulesSymlinks(root, targets) {
|
|
8569
|
-
const targetAbs = path5.join(root, "
|
|
8584
|
+
const targetAbs = path5.join(root, ONEAGENT_DIR, "rules");
|
|
8570
8585
|
return AGENT_DEFINITIONS.filter((d2) => targets.includes(d2.target) && d2.rulesDir).map((d2) => {
|
|
8571
8586
|
const symlinkPath = path5.join(root, d2.rulesDir);
|
|
8572
8587
|
return { symlinkPath, target: relativeTarget(symlinkPath, targetAbs), label: d2.rulesDir };
|
|
8573
8588
|
});
|
|
8574
8589
|
}
|
|
8575
8590
|
function buildSkillSymlinks(root, targets) {
|
|
8576
|
-
const targetAbs = path5.join(root, "
|
|
8591
|
+
const targetAbs = path5.join(root, ONEAGENT_DIR, "skills");
|
|
8577
8592
|
return AGENT_DEFINITIONS.filter((d2) => targets.includes(d2.target) && d2.skillsDir).map((d2) => {
|
|
8578
8593
|
const symlinkPath = path5.join(root, d2.skillsDir);
|
|
8579
8594
|
return { symlinkPath, target: relativeTarget(symlinkPath, targetAbs), label: d2.skillsDir };
|
|
8580
8595
|
});
|
|
8581
8596
|
}
|
|
8582
8597
|
function buildCommandSymlinks(root, targets) {
|
|
8583
|
-
const targetAbs = path5.join(root, "
|
|
8598
|
+
const targetAbs = path5.join(root, ONEAGENT_DIR, "commands");
|
|
8584
8599
|
return AGENT_DEFINITIONS.filter((d2) => targets.includes(d2.target) && d2.commandsDir).map((d2) => {
|
|
8585
8600
|
const symlinkPath = path5.join(root, d2.commandsDir);
|
|
8586
8601
|
return { symlinkPath, target: relativeTarget(symlinkPath, targetAbs), label: d2.commandsDir };
|
|
@@ -8588,7 +8603,7 @@ function buildCommandSymlinks(root, targets) {
|
|
|
8588
8603
|
}
|
|
8589
8604
|
function buildAgentsDirSymlinks(root) {
|
|
8590
8605
|
const symlinkPath = path5.join(root, ".agents/skills");
|
|
8591
|
-
const targetAbs = path5.join(root, "
|
|
8606
|
+
const targetAbs = path5.join(root, ONEAGENT_DIR, "skills");
|
|
8592
8607
|
return [{ symlinkPath, target: relativeTarget(symlinkPath, targetAbs), label: ".agents/skills" }];
|
|
8593
8608
|
}
|
|
8594
8609
|
async function migrateFilesFromDir(srcDir, destDir, root) {
|
|
@@ -8600,9 +8615,22 @@ async function migrateFilesFromDir(srcDir, destDir, root) {
|
|
|
8600
8615
|
return;
|
|
8601
8616
|
}
|
|
8602
8617
|
for (const entry of entries) {
|
|
8603
|
-
if (!entry.isFile())
|
|
8604
|
-
continue;
|
|
8605
8618
|
const srcFile = path5.join(srcDir, entry.name);
|
|
8619
|
+
const fileStat = await fs5.lstat(srcFile);
|
|
8620
|
+
if (fileStat.isSymbolicLink())
|
|
8621
|
+
continue;
|
|
8622
|
+
if (fileStat.isDirectory()) {
|
|
8623
|
+
const destSub = path5.join(destDir, entry.name);
|
|
8624
|
+
try {
|
|
8625
|
+
await fs5.access(destSub);
|
|
8626
|
+
} catch {
|
|
8627
|
+
await fs5.mkdir(destDir, { recursive: true });
|
|
8628
|
+
await fs5.rename(srcFile, destSub);
|
|
8629
|
+
}
|
|
8630
|
+
continue;
|
|
8631
|
+
}
|
|
8632
|
+
if (!fileStat.isFile())
|
|
8633
|
+
continue;
|
|
8606
8634
|
const destFile = path5.join(destDir, entry.name);
|
|
8607
8635
|
let destExists = false;
|
|
8608
8636
|
try {
|
|
@@ -8615,7 +8643,7 @@ async function migrateFilesFromDir(srcDir, destDir, root) {
|
|
|
8615
8643
|
fs5.readFile(destFile, "utf-8")
|
|
8616
8644
|
]);
|
|
8617
8645
|
if (srcContent !== destContent) {
|
|
8618
|
-
const backupDir = path5.join(root, "
|
|
8646
|
+
const backupDir = path5.join(root, ONEAGENT_DIR, "backup");
|
|
8619
8647
|
await fs5.mkdir(backupDir, { recursive: true });
|
|
8620
8648
|
const safeName = path5.relative(root, srcFile).replace(/\//g, "_");
|
|
8621
8649
|
await fs5.writeFile(path5.join(backupDir, safeName), srcContent);
|
|
@@ -8639,21 +8667,75 @@ async function migrateAndRemoveDir(src, dest, root) {
|
|
|
8639
8667
|
await fs5.rm(src, { recursive: true, force: true });
|
|
8640
8668
|
}
|
|
8641
8669
|
async function migrateRuleAndSkillFiles(root) {
|
|
8642
|
-
const destRules = path5.join(root, "
|
|
8643
|
-
const destSkills = path5.join(root, "
|
|
8644
|
-
const destCommands = path5.join(root, "
|
|
8670
|
+
const destRules = path5.join(root, ONEAGENT_DIR, "rules");
|
|
8671
|
+
const destSkills = path5.join(root, ONEAGENT_DIR, "skills");
|
|
8672
|
+
const destCommands = path5.join(root, ONEAGENT_DIR, "commands");
|
|
8645
8673
|
for (const def of AGENT_DEFINITIONS) {
|
|
8646
8674
|
if (def.rulesDir)
|
|
8647
8675
|
await migrateAndRemoveDir(path5.join(root, def.rulesDir), destRules, root);
|
|
8648
8676
|
}
|
|
8677
|
+
for (const def of AGENT_DEFINITIONS) {
|
|
8678
|
+
if (def.skillsDir)
|
|
8679
|
+
await migrateAndRemoveDir(path5.join(root, def.skillsDir), destSkills, root);
|
|
8680
|
+
}
|
|
8649
8681
|
await migrateAndRemoveDir(path5.join(root, ".agents/skills"), destSkills, root);
|
|
8650
8682
|
for (const def of AGENT_DEFINITIONS) {
|
|
8651
8683
|
if (def.commandsDir)
|
|
8652
8684
|
await migrateAndRemoveDir(path5.join(root, def.commandsDir), destCommands, root);
|
|
8653
8685
|
}
|
|
8654
8686
|
}
|
|
8687
|
+
async function backupDirRecursive(srcDir, backupDir, prefix) {
|
|
8688
|
+
let entries;
|
|
8689
|
+
try {
|
|
8690
|
+
entries = await fs5.readdir(srcDir, { withFileTypes: true });
|
|
8691
|
+
} catch {
|
|
8692
|
+
return;
|
|
8693
|
+
}
|
|
8694
|
+
for (const entry of entries) {
|
|
8695
|
+
const srcPath = path5.join(srcDir, entry.name);
|
|
8696
|
+
const lstat = await fs5.lstat(srcPath);
|
|
8697
|
+
if (lstat.isSymbolicLink())
|
|
8698
|
+
continue;
|
|
8699
|
+
if (lstat.isDirectory()) {
|
|
8700
|
+
await backupDirRecursive(srcPath, backupDir, `${prefix}_${entry.name}`);
|
|
8701
|
+
} else if (lstat.isFile()) {
|
|
8702
|
+
await fs5.mkdir(backupDir, { recursive: true });
|
|
8703
|
+
await fs5.copyFile(srcPath, path5.join(backupDir, `${prefix}_${entry.name}`));
|
|
8704
|
+
}
|
|
8705
|
+
}
|
|
8706
|
+
}
|
|
8707
|
+
async function cleanupAgentDir(root, target) {
|
|
8708
|
+
const def = AGENT_DEFINITIONS.find((d2) => d2.target === target);
|
|
8709
|
+
const backupDir = path5.join(root, ONEAGENT_DIR, "backup");
|
|
8710
|
+
const agentDir = [def.rulesDir, def.skillsDir, def.commandsDir].filter(Boolean).map((d2) => d2.split("/")[0]).find((d2) => d2 !== ".github");
|
|
8711
|
+
if (agentDir) {
|
|
8712
|
+
const agentDirAbs = path5.join(root, agentDir);
|
|
8713
|
+
let stat;
|
|
8714
|
+
try {
|
|
8715
|
+
stat = await fs5.lstat(agentDirAbs);
|
|
8716
|
+
} catch {}
|
|
8717
|
+
if (stat && stat.isDirectory() && !stat.isSymbolicLink()) {
|
|
8718
|
+
await backupDirRecursive(agentDirAbs, backupDir, agentDir);
|
|
8719
|
+
await fs5.rm(agentDirAbs, { recursive: true, force: true });
|
|
8720
|
+
}
|
|
8721
|
+
}
|
|
8722
|
+
if (target === "opencode") {
|
|
8723
|
+
const opPath = path5.join(root, "opencode.json");
|
|
8724
|
+
try {
|
|
8725
|
+
const content = await fs5.readFile(opPath, "utf-8");
|
|
8726
|
+
await fs5.mkdir(backupDir, { recursive: true });
|
|
8727
|
+
await fs5.writeFile(path5.join(backupDir, "opencode.json"), content);
|
|
8728
|
+
} catch {}
|
|
8729
|
+
try {
|
|
8730
|
+
await fs5.unlink(opPath);
|
|
8731
|
+
} catch {}
|
|
8732
|
+
}
|
|
8733
|
+
}
|
|
8655
8734
|
async function createAllSymlinks(entries) {
|
|
8656
|
-
|
|
8735
|
+
const deduped = new Map;
|
|
8736
|
+
for (const e2 of entries)
|
|
8737
|
+
deduped.set(e2.symlinkPath, e2);
|
|
8738
|
+
for (const e2 of deduped.values()) {
|
|
8657
8739
|
await createSymlink(e2.symlinkPath, e2.target);
|
|
8658
8740
|
}
|
|
8659
8741
|
}
|
|
@@ -8722,7 +8804,7 @@ async function readOpencode(root) {
|
|
|
8722
8804
|
function buildOpencodeConfig(existing) {
|
|
8723
8805
|
return {
|
|
8724
8806
|
...existing,
|
|
8725
|
-
instructions:
|
|
8807
|
+
instructions: `${ONEAGENT_DIR}/instructions.md`
|
|
8726
8808
|
};
|
|
8727
8809
|
}
|
|
8728
8810
|
async function addOpenCodePlugin(root, id) {
|
|
@@ -8846,7 +8928,7 @@ async function checkOpencodeStatus(root, _rules) {
|
|
|
8846
8928
|
const existing = await readOpencode(root);
|
|
8847
8929
|
if (!existing)
|
|
8848
8930
|
return { exists: false, valid: false };
|
|
8849
|
-
return { exists: true, valid: existing["instructions"] ===
|
|
8931
|
+
return { exists: true, valid: existing["instructions"] === `${ONEAGENT_DIR}/instructions.md` };
|
|
8850
8932
|
}
|
|
8851
8933
|
async function checkCopilotPrompt(root, skill) {
|
|
8852
8934
|
const filePath = copilotPromptFilePath(root, skill.name);
|
|
@@ -8895,9 +8977,11 @@ function parseTemplateYaml(yamlText, fallbackName = "custom") {
|
|
|
8895
8977
|
const name = nameMatch?.[1]?.trim() ?? fallbackName;
|
|
8896
8978
|
const descMatch = yamlText.match(/^description:\s*(.+)$/m);
|
|
8897
8979
|
const description = descMatch?.[1]?.trim() ?? "";
|
|
8980
|
+
const extendsMatch = yamlText.match(/^extends:\s*(.+)$/m);
|
|
8981
|
+
const extendsValue = extendsMatch?.[1]?.trim();
|
|
8898
8982
|
const skills = parseSkillsFromYaml(yamlText);
|
|
8899
8983
|
const plugins = parsePluginsFromYaml(yamlText);
|
|
8900
|
-
return { name, description, skills, plugins };
|
|
8984
|
+
return { name, description, skills, plugins, ...extendsValue ? { extends: extendsValue } : {} };
|
|
8901
8985
|
}
|
|
8902
8986
|
function parseSkillsFromYaml(yamlText) {
|
|
8903
8987
|
const skills = [];
|
|
@@ -8934,8 +9018,31 @@ function parsePluginsFromYaml(yamlText) {
|
|
|
8934
9018
|
}
|
|
8935
9019
|
return plugins;
|
|
8936
9020
|
}
|
|
9021
|
+
async function resolveExtends(child, resolveBuiltin) {
|
|
9022
|
+
if (!child.extends)
|
|
9023
|
+
return child;
|
|
9024
|
+
let parent;
|
|
9025
|
+
if (child.extends.startsWith("https://")) {
|
|
9026
|
+
parent = await fetchTemplateFromGitHub(child.extends);
|
|
9027
|
+
} else if (resolveBuiltin) {
|
|
9028
|
+
const resolved = await resolveBuiltin(child.extends);
|
|
9029
|
+
if (!resolved)
|
|
9030
|
+
throw new Error(`Unknown builtin template: "${child.extends}"`);
|
|
9031
|
+
parent = resolved;
|
|
9032
|
+
} else {
|
|
9033
|
+
throw new Error(`Cannot resolve extends: "${child.extends}"`);
|
|
9034
|
+
}
|
|
9035
|
+
return {
|
|
9036
|
+
name: child.name,
|
|
9037
|
+
description: child.description,
|
|
9038
|
+
instructions: child.instructions,
|
|
9039
|
+
skills: [...parent.skills, ...child.skills],
|
|
9040
|
+
plugins: [...parent.plugins, ...child.plugins],
|
|
9041
|
+
rules: [...parent.rules, ...child.rules]
|
|
9042
|
+
};
|
|
9043
|
+
}
|
|
8937
9044
|
async function applyTemplateFiles(root, template) {
|
|
8938
|
-
const oneagentDir = path9.join(root,
|
|
9045
|
+
const oneagentDir = path9.join(root, ONEAGENT_DIR);
|
|
8939
9046
|
await fs10.mkdir(path9.join(oneagentDir, "rules"), { recursive: true });
|
|
8940
9047
|
await fs10.mkdir(path9.join(oneagentDir, "skills"), { recursive: true });
|
|
8941
9048
|
await fs10.writeFile(path9.join(oneagentDir, "instructions.md"), template.instructions);
|
|
@@ -8944,19 +9051,26 @@ async function applyTemplateFiles(root, template) {
|
|
|
8944
9051
|
}
|
|
8945
9052
|
}
|
|
8946
9053
|
async function installTemplateSkills(root, template) {
|
|
8947
|
-
const
|
|
9054
|
+
const installed = [];
|
|
9055
|
+
const failed = [];
|
|
9056
|
+
for (const entry of template.skills) {
|
|
8948
9057
|
try {
|
|
8949
9058
|
await execFileAsync("npx", ["skills", "add", entry.repo, "--skill", entry.skill, "--agent", "universal", "--yes"], { cwd: root });
|
|
8950
|
-
|
|
9059
|
+
installed.push(entry);
|
|
8951
9060
|
} catch (err) {
|
|
8952
9061
|
const reason = err instanceof Error ? err.message : String(err);
|
|
8953
|
-
|
|
9062
|
+
failed.push({ entry, reason });
|
|
8954
9063
|
}
|
|
8955
|
-
}
|
|
8956
|
-
return {
|
|
8957
|
-
|
|
8958
|
-
|
|
8959
|
-
|
|
9064
|
+
}
|
|
9065
|
+
return { installed, failed };
|
|
9066
|
+
}
|
|
9067
|
+
async function installBuiltinSkill(root) {
|
|
9068
|
+
try {
|
|
9069
|
+
await execFileAsync("npx", ["skills", "add", BUILTIN_SKILL_REPO, "--skill", BUILTIN_SKILL_NAME, "--agent", "universal", "--yes"], { cwd: root });
|
|
9070
|
+
return true;
|
|
9071
|
+
} catch {
|
|
9072
|
+
return false;
|
|
9073
|
+
}
|
|
8960
9074
|
}
|
|
8961
9075
|
async function installTemplatePlugins(root, template, activeTargets2) {
|
|
8962
9076
|
const installed = [];
|
|
@@ -8993,14 +9107,31 @@ async function installTemplatePlugins(root, template, activeTargets2) {
|
|
|
8993
9107
|
return { installed, manual, failed };
|
|
8994
9108
|
}
|
|
8995
9109
|
async function fetchTemplateFromGitHub(url) {
|
|
8996
|
-
const
|
|
9110
|
+
const { owner, repo, branch, subdir } = parseGitHubUrl(url);
|
|
9111
|
+
const branchExplicit = url.includes("/tree/");
|
|
9112
|
+
const resolvedBranch = branchExplicit ? branch : await fetchDefaultBranch(owner, repo);
|
|
9113
|
+
const rawBase = `https://raw.githubusercontent.com/${owner}/${repo}/${resolvedBranch}${subdir ? `/${subdir}` : ""}`;
|
|
8997
9114
|
const [yamlText, instructions] = await Promise.all([
|
|
8998
9115
|
fetchText(`${rawBase}/template.yml`),
|
|
8999
9116
|
fetchText(`${rawBase}/instructions.md`)
|
|
9000
9117
|
]);
|
|
9001
|
-
const
|
|
9118
|
+
const parsed = parseTemplateYaml(yamlText);
|
|
9002
9119
|
const rules = await fetchGitHubRules(url);
|
|
9003
|
-
|
|
9120
|
+
const base = { ...parsed, instructions, rules };
|
|
9121
|
+
return resolveExtends(base);
|
|
9122
|
+
}
|
|
9123
|
+
async function fetchDefaultBranch(owner, repo) {
|
|
9124
|
+
try {
|
|
9125
|
+
const response = await fetch(`https://api.github.com/repos/${owner}/${repo}`, {
|
|
9126
|
+
headers: { Accept: "application/vnd.github.v3+json" }
|
|
9127
|
+
});
|
|
9128
|
+
if (!response.ok)
|
|
9129
|
+
return "main";
|
|
9130
|
+
const data = await response.json();
|
|
9131
|
+
return data.default_branch ?? "main";
|
|
9132
|
+
} catch {
|
|
9133
|
+
return "main";
|
|
9134
|
+
}
|
|
9004
9135
|
}
|
|
9005
9136
|
async function fetchText(url) {
|
|
9006
9137
|
const response = await fetch(url);
|
|
@@ -9017,11 +9148,6 @@ function parseGitHubUrl(url) {
|
|
|
9017
9148
|
const [, owner, repo, branch = "main", subdir = ""] = match;
|
|
9018
9149
|
return { owner, repo, branch, subdir };
|
|
9019
9150
|
}
|
|
9020
|
-
function githubUrlToRawBase(url) {
|
|
9021
|
-
const { owner, repo, branch, subdir } = parseGitHubUrl(url);
|
|
9022
|
-
const base = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}`;
|
|
9023
|
-
return subdir ? `${base}/${subdir}` : base;
|
|
9024
|
-
}
|
|
9025
9151
|
async function fetchGitHubRules(repoUrl) {
|
|
9026
9152
|
const { owner, repo, branch, subdir } = parseGitHubUrl(repoUrl);
|
|
9027
9153
|
const rulesPath = subdir ? `${subdir}/rules` : "rules";
|
|
@@ -9043,7 +9169,7 @@ async function fetchGitHubRules(repoUrl) {
|
|
|
9043
9169
|
return [];
|
|
9044
9170
|
}
|
|
9045
9171
|
}
|
|
9046
|
-
var execFileAsync;
|
|
9172
|
+
var execFileAsync, BUILTIN_SKILL_REPO = "https://github.com/moskalakamil/oneagent", BUILTIN_SKILL_NAME = "oneagent";
|
|
9047
9173
|
var init_apply_template = __esm(() => {
|
|
9048
9174
|
init_opencode();
|
|
9049
9175
|
execFileAsync = promisify(execFile);
|
|
@@ -9075,7 +9201,7 @@ async function loadTemplate(name) {
|
|
|
9075
9201
|
fs11.readFile(path10.join(templateDir, "template.yml"), "utf-8"),
|
|
9076
9202
|
fs11.readFile(path10.join(templateDir, "instructions.md"), "utf-8")
|
|
9077
9203
|
]);
|
|
9078
|
-
const
|
|
9204
|
+
const parsed = parseTemplateYaml(yamlText, name);
|
|
9079
9205
|
const rulesDir = path10.join(templateDir, "rules");
|
|
9080
9206
|
let rules2 = [];
|
|
9081
9207
|
try {
|
|
@@ -9085,7 +9211,8 @@ async function loadTemplate(name) {
|
|
|
9085
9211
|
content: await fs11.readFile(path10.join(rulesDir, f), "utf-8")
|
|
9086
9212
|
})));
|
|
9087
9213
|
} catch {}
|
|
9088
|
-
|
|
9214
|
+
const base = { ...parsed, instructions, rules: rules2 };
|
|
9215
|
+
return resolveExtends(base, (n) => resolveBuiltinTemplate(n));
|
|
9089
9216
|
}
|
|
9090
9217
|
async function resolveBuiltinTemplate(name) {
|
|
9091
9218
|
if (!TEMPLATE_NAMES.includes(name))
|
|
@@ -9121,20 +9248,12 @@ async function chooseContent(detected) {
|
|
|
9121
9248
|
return "";
|
|
9122
9249
|
if (detected.length === 1) {
|
|
9123
9250
|
const file = detected[0];
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
});
|
|
9127
|
-
if (Ct(result2))
|
|
9128
|
-
cancelAndExit();
|
|
9129
|
-
return result2 ? file.content : "";
|
|
9251
|
+
R2.info(`Found ${file.relativePath} (${timeAgo(file.modifiedAt)}) — importing into ${ONEAGENT_DIR}/instructions.md`);
|
|
9252
|
+
return file.content;
|
|
9130
9253
|
}
|
|
9131
9254
|
if (filesHaveSameContent(detected)) {
|
|
9132
|
-
|
|
9133
|
-
|
|
9134
|
-
});
|
|
9135
|
-
if (Ct(result2))
|
|
9136
|
-
cancelAndExit();
|
|
9137
|
-
return result2 ? detected[0].content : "";
|
|
9255
|
+
R2.info(`Found ${detected.length} files with identical content — importing into ${ONEAGENT_DIR}/instructions.md`);
|
|
9256
|
+
return detected[0].content;
|
|
9138
9257
|
}
|
|
9139
9258
|
Ve(detected.map((f) => ` • ${f.relativePath} ${timeAgo(f.modifiedAt)}`).join(`
|
|
9140
9259
|
`), "Multiple files with different content found");
|
|
@@ -9190,13 +9309,19 @@ async function pickTargets(initialValues) {
|
|
|
9190
9309
|
async function backupFiles(root, files) {
|
|
9191
9310
|
if (files.length === 0)
|
|
9192
9311
|
return;
|
|
9193
|
-
const backupDir = path11.join(root, "
|
|
9312
|
+
const backupDir = path11.join(root, ONEAGENT_DIR, "backup");
|
|
9194
9313
|
await fs12.mkdir(backupDir, { recursive: true });
|
|
9195
9314
|
for (const file of files) {
|
|
9196
9315
|
const safeName = file.relativePath.replace(/\//g, "_");
|
|
9197
9316
|
await fs12.writeFile(path11.join(backupDir, safeName), file.content);
|
|
9198
9317
|
}
|
|
9199
9318
|
}
|
|
9319
|
+
async function cleanupUnselectedAgentDirs(root, presentTargets, selectedTargets) {
|
|
9320
|
+
const unselected = presentTargets.filter((t) => !selectedTargets.includes(t));
|
|
9321
|
+
for (const target of unselected) {
|
|
9322
|
+
await cleanupAgentDir(root, target);
|
|
9323
|
+
}
|
|
9324
|
+
}
|
|
9200
9325
|
async function pickTemplateInteractively() {
|
|
9201
9326
|
const result = await Je({
|
|
9202
9327
|
message: "Which template would you like to use?",
|
|
@@ -9232,13 +9357,12 @@ async function resolveTemplate(templateArg) {
|
|
|
9232
9357
|
return builtin;
|
|
9233
9358
|
throw new Error(`Unknown template "${templateArg}". Use one of: ${BUILTIN_TEMPLATE_NAMES.join(", ")} — or a GitHub URL.`);
|
|
9234
9359
|
}
|
|
9235
|
-
var
|
|
9360
|
+
var init_default;
|
|
9236
9361
|
var init_init = __esm(() => {
|
|
9237
9362
|
init_dist();
|
|
9238
9363
|
init_dist3();
|
|
9239
9364
|
init_src();
|
|
9240
9365
|
init_src2();
|
|
9241
|
-
ABOUT_ONEAGENT_RULE_PATH = new URL("../assets/about-oneagent.md", import.meta.url);
|
|
9242
9366
|
init_default = defineCommand2({
|
|
9243
9367
|
meta: {
|
|
9244
9368
|
name: "init",
|
|
@@ -9248,6 +9372,12 @@ var init_init = __esm(() => {
|
|
|
9248
9372
|
template: {
|
|
9249
9373
|
type: "string",
|
|
9250
9374
|
description: `Template to use: builtin name (${BUILTIN_TEMPLATE_NAMES.join("/")}) or GitHub URL`
|
|
9375
|
+
},
|
|
9376
|
+
yes: {
|
|
9377
|
+
type: "boolean",
|
|
9378
|
+
alias: "y",
|
|
9379
|
+
description: "Skip prompts: auto-import detected files and select detected agents",
|
|
9380
|
+
default: false
|
|
9251
9381
|
}
|
|
9252
9382
|
},
|
|
9253
9383
|
async run({ args }) {
|
|
@@ -9276,19 +9406,26 @@ var init_init = __esm(() => {
|
|
|
9276
9406
|
Ve(message, "Error");
|
|
9277
9407
|
process.exit(1);
|
|
9278
9408
|
}
|
|
9409
|
+
} else if (args.yes) {
|
|
9410
|
+
if (detected.length > 0) {
|
|
9411
|
+
const newest = detected.toSorted((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime())[0];
|
|
9412
|
+
importedContent = newest.content;
|
|
9413
|
+
R2.info(`Auto-importing content from ${newest.relativePath}`);
|
|
9414
|
+
}
|
|
9279
9415
|
} else {
|
|
9280
9416
|
importedContent = await chooseContent(detected);
|
|
9281
9417
|
}
|
|
9282
9418
|
const presentTargets = await detectPresentTargets(root);
|
|
9283
|
-
const selectedTargets = await pickTargets(presentTargets);
|
|
9419
|
+
const selectedTargets = args.yes ? presentTargets.length > 0 ? presentTargets : ALL_AGENT_TARGETS.slice(0, 1) : await pickTargets(presentTargets);
|
|
9284
9420
|
const s = bt2();
|
|
9285
|
-
s.start(
|
|
9286
|
-
await fs12.mkdir(path11.join(root, "
|
|
9287
|
-
await fs12.mkdir(path11.join(root, "
|
|
9288
|
-
await fs12.mkdir(path11.join(root, "
|
|
9421
|
+
s.start(`Setting up ${ONEAGENT_DIR}/ directory...`);
|
|
9422
|
+
await fs12.mkdir(path11.join(root, ONEAGENT_DIR, "rules"), { recursive: true });
|
|
9423
|
+
await fs12.mkdir(path11.join(root, ONEAGENT_DIR, "skills"), { recursive: true });
|
|
9424
|
+
await fs12.mkdir(path11.join(root, ONEAGENT_DIR, "commands"), { recursive: true });
|
|
9289
9425
|
await backupFiles(root, detected);
|
|
9290
9426
|
await removeDeprecatedFiles(root);
|
|
9291
9427
|
await migrateRuleAndSkillFiles(root);
|
|
9428
|
+
await cleanupUnselectedAgentDirs(root, presentTargets, selectedTargets);
|
|
9292
9429
|
const config2 = { version: 1, targets: makeTargets(...selectedTargets) };
|
|
9293
9430
|
await writeConfig(root, config2);
|
|
9294
9431
|
if (template) {
|
|
@@ -9298,30 +9435,37 @@ var init_init = __esm(() => {
|
|
|
9298
9435
|
|
|
9299
9436
|
Add your AI instructions here.
|
|
9300
9437
|
`;
|
|
9301
|
-
await fs12.writeFile(path11.join(root, "
|
|
9438
|
+
await fs12.writeFile(path11.join(root, ONEAGENT_DIR, "instructions.md"), instructionsContent);
|
|
9302
9439
|
}
|
|
9303
|
-
await fs12.copyFile(ABOUT_ONEAGENT_RULE_PATH, path11.join(root, ".oneagent/rules/about-oneagent.md"));
|
|
9304
9440
|
s.stop("Directory structure created.");
|
|
9305
|
-
const commandFiles = await fs12.readdir(path11.join(root, "
|
|
9441
|
+
const commandFiles = await fs12.readdir(path11.join(root, ONEAGENT_DIR, "commands")).catch(() => []);
|
|
9306
9442
|
if (commandFiles.some((f) => f.endsWith(".md"))) {
|
|
9307
|
-
R2.warn(
|
|
9443
|
+
R2.warn(`Commands detected in ${ONEAGENT_DIR}/commands/. Consider migrating to ${ONEAGENT_DIR}/skills/ — skills are distributed to more agents and support richer features.`);
|
|
9308
9444
|
}
|
|
9309
9445
|
if (commandFiles.some((f) => f.endsWith(".md"))) {
|
|
9310
9446
|
const commandsSupported = new Set(AGENT_DEFINITIONS.filter((d2) => d2.commandsDir).map((d2) => d2.target));
|
|
9311
9447
|
const unsupported = selectedTargets.filter((t) => !commandsSupported.has(t));
|
|
9312
9448
|
if (unsupported.length > 0) {
|
|
9313
9449
|
const names = unsupported.map((t) => AGENT_DEFINITIONS.find((d2) => d2.target === t).displayName).join(", ");
|
|
9314
|
-
R2.warn(`Commands in
|
|
9450
|
+
R2.warn(`Commands in ${ONEAGENT_DIR}/commands/ will not be available in: ${names} — these agents do not support custom slash commands.`);
|
|
9315
9451
|
}
|
|
9316
9452
|
}
|
|
9317
9453
|
const s2 = bt2();
|
|
9318
9454
|
s2.start("Generating symlinks and agent files...");
|
|
9319
9455
|
await generate(root, config2);
|
|
9320
9456
|
s2.stop("Done.");
|
|
9457
|
+
const sSkill = bt2();
|
|
9458
|
+
sSkill.start("Installing oneagent skill...");
|
|
9459
|
+
const builtinInstalled = await installBuiltinSkill(root);
|
|
9460
|
+
if (builtinInstalled) {
|
|
9461
|
+
sSkill.stop("Installed oneagent skill.");
|
|
9462
|
+
} else {
|
|
9463
|
+
sSkill.stop("Could not install oneagent skill (skipped).");
|
|
9464
|
+
}
|
|
9321
9465
|
let skillResult = { installed: [], failed: [] };
|
|
9322
9466
|
if (template && template.skills.length > 0) {
|
|
9323
9467
|
const s3 = bt2();
|
|
9324
|
-
s3.start("Installing skills...");
|
|
9468
|
+
s3.start("Installing template skills...");
|
|
9325
9469
|
skillResult = await installTemplateSkills(root, template);
|
|
9326
9470
|
s3.stop(`Installed ${skillResult.installed.length} skill(s).`);
|
|
9327
9471
|
for (const f of skillResult.failed) {
|
|
@@ -9344,10 +9488,10 @@ Add your AI instructions here.
|
|
|
9344
9488
|
...skillResult.installed.length > 0 ? [`Installed ${skillResult.installed.length} skill(s): ${skillResult.installed.map((s3) => s3.skill).join(", ")}`] : [],
|
|
9345
9489
|
...template.rules.length > 0 ? [`Added ${template.rules.length} rule(s) from template`] : [],
|
|
9346
9490
|
...pluginResult.installed.length > 0 ? [`Installed ${pluginResult.installed.length} plugin(s): ${pluginResult.installed.map((p) => p.id).join(", ")}`] : []
|
|
9347
|
-
] : [
|
|
9348
|
-
|
|
9491
|
+
] : [`Created ${ONEAGENT_DIR}/instructions.md`],
|
|
9492
|
+
...builtinInstalled ? [`Installed oneagent skill`] : [],
|
|
9349
9493
|
...selectedTargets.map((t) => `Configured: ${t}`),
|
|
9350
|
-
...detected.length > 0 ? [`Backed up ${detected.length} file(s) to
|
|
9494
|
+
...detected.length > 0 ? [`Backed up ${detected.length} file(s) to ${ONEAGENT_DIR}/backup/`] : []
|
|
9351
9495
|
];
|
|
9352
9496
|
Ve(lines.map((l) => ` • ${l}`).join(`
|
|
9353
9497
|
`), "Setup complete");
|
|
@@ -9380,18 +9524,25 @@ var init_generate2 = __esm(() => {
|
|
|
9380
9524
|
name: "generate",
|
|
9381
9525
|
description: "Generate symlinks and agent-specific files"
|
|
9382
9526
|
},
|
|
9383
|
-
|
|
9527
|
+
args: {
|
|
9528
|
+
yes: {
|
|
9529
|
+
type: "boolean",
|
|
9530
|
+
alias: "y",
|
|
9531
|
+
description: "Skip confirmation prompts and auto-migrate colliding files"
|
|
9532
|
+
}
|
|
9533
|
+
},
|
|
9534
|
+
async run({ args }) {
|
|
9384
9535
|
const root = process.cwd();
|
|
9385
9536
|
let config2;
|
|
9386
9537
|
try {
|
|
9387
9538
|
config2 = await readConfig(root);
|
|
9388
9539
|
} catch {
|
|
9389
|
-
console.error(
|
|
9540
|
+
console.error(`Error: No ${ONEAGENT_DIR}/config.yml found. Run \`oneagent init\` first.`);
|
|
9390
9541
|
process.exit(1);
|
|
9391
9542
|
}
|
|
9392
9543
|
const { mainFiles, ruleSkillFiles } = await detectGenerateCollisions(root, config2);
|
|
9393
9544
|
if (mainFiles.length > 0) {
|
|
9394
|
-
const backupDir = path12.join(root, "
|
|
9545
|
+
const backupDir = path12.join(root, ONEAGENT_DIR, "backup");
|
|
9395
9546
|
await fs13.mkdir(backupDir, { recursive: true });
|
|
9396
9547
|
for (const file of mainFiles) {
|
|
9397
9548
|
const safeName = file.relativePath.replace(/\//g, "_");
|
|
@@ -9399,16 +9550,20 @@ var init_generate2 = __esm(() => {
|
|
|
9399
9550
|
}
|
|
9400
9551
|
}
|
|
9401
9552
|
if (ruleSkillFiles.length > 0) {
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
|
|
9409
|
-
|
|
9553
|
+
if (args.yes) {
|
|
9554
|
+
await migrateRuleAndSkillFiles(root);
|
|
9555
|
+
} else {
|
|
9556
|
+
Ve(ruleSkillFiles.map((f) => ` • ${f.relativePath}`).join(`
|
|
9557
|
+
`), "These rule/skill files are not oneagent symlinks");
|
|
9558
|
+
const proceed = await Re({
|
|
9559
|
+
message: `Move them to ${ONEAGENT_DIR}/ and replace with symlinks?`
|
|
9560
|
+
});
|
|
9561
|
+
if (Ct(proceed) || !proceed) {
|
|
9562
|
+
Le("Aborted.");
|
|
9563
|
+
process.exit(0);
|
|
9564
|
+
}
|
|
9565
|
+
await migrateRuleAndSkillFiles(root);
|
|
9410
9566
|
}
|
|
9411
|
-
await migrateRuleAndSkillFiles(root);
|
|
9412
9567
|
}
|
|
9413
9568
|
const s = bt2();
|
|
9414
9569
|
s.start("Generating...");
|
|
@@ -9444,7 +9599,7 @@ var init_status2 = __esm(() => {
|
|
|
9444
9599
|
try {
|
|
9445
9600
|
config2 = await readConfig(root);
|
|
9446
9601
|
} catch {
|
|
9447
|
-
console.error(
|
|
9602
|
+
console.error(`Error: No ${ONEAGENT_DIR}/config.yml found. Run \`oneagent init\` first.`);
|
|
9448
9603
|
process.exit(1);
|
|
9449
9604
|
}
|
|
9450
9605
|
const status2 = await checkStatus(root, config2);
|
|
@@ -9477,6 +9632,233 @@ OpenCode:
|
|
|
9477
9632
|
});
|
|
9478
9633
|
});
|
|
9479
9634
|
|
|
9635
|
+
// src/commands/targets.ts
|
|
9636
|
+
var exports_targets = {};
|
|
9637
|
+
__export(exports_targets, {
|
|
9638
|
+
default: () => targets_default
|
|
9639
|
+
});
|
|
9640
|
+
import path13 from "path";
|
|
9641
|
+
import fs14 from "fs/promises";
|
|
9642
|
+
function cancelAndExit2() {
|
|
9643
|
+
Le("Cancelled.");
|
|
9644
|
+
process.exit(0);
|
|
9645
|
+
}
|
|
9646
|
+
async function detectPresentTargets2(root) {
|
|
9647
|
+
const results = await Promise.all(AGENT_DEFINITIONS.map(async (def) => {
|
|
9648
|
+
for (const indicator of def.detectIndicators) {
|
|
9649
|
+
try {
|
|
9650
|
+
await fs14.access(path13.join(root, indicator));
|
|
9651
|
+
return def.target;
|
|
9652
|
+
} catch {}
|
|
9653
|
+
}
|
|
9654
|
+
return null;
|
|
9655
|
+
}));
|
|
9656
|
+
return results.filter((t) => t !== null);
|
|
9657
|
+
}
|
|
9658
|
+
var targets_default;
|
|
9659
|
+
var init_targets = __esm(() => {
|
|
9660
|
+
init_dist();
|
|
9661
|
+
init_dist3();
|
|
9662
|
+
init_src();
|
|
9663
|
+
targets_default = defineCommand2({
|
|
9664
|
+
meta: {
|
|
9665
|
+
name: "targets",
|
|
9666
|
+
description: "Add or remove AI agent targets"
|
|
9667
|
+
},
|
|
9668
|
+
async run() {
|
|
9669
|
+
const root = process.cwd();
|
|
9670
|
+
let config2;
|
|
9671
|
+
try {
|
|
9672
|
+
config2 = await readConfig(root);
|
|
9673
|
+
} catch {
|
|
9674
|
+
console.error(`Error: No ${ONEAGENT_DIR}/config.yml found. Run \`oneagent init\` first.`);
|
|
9675
|
+
process.exit(1);
|
|
9676
|
+
}
|
|
9677
|
+
const current = activeTargets(config2);
|
|
9678
|
+
const presentTargets = await detectPresentTargets2(root);
|
|
9679
|
+
const initialValues = [...new Set([...current, ...presentTargets])];
|
|
9680
|
+
Ve(current.map((t) => ` • ${AGENT_DEFINITIONS.find((d2) => d2.target === t).displayName}`).join(`
|
|
9681
|
+
`), "Currently configured targets");
|
|
9682
|
+
const result = await je({
|
|
9683
|
+
message: `Which AI agents do you want to support?
|
|
9684
|
+
\x1B[90m · Space to toggle · Enter to confirm\x1B[39m`,
|
|
9685
|
+
options: AGENT_DEFINITIONS.map((d2) => ({ value: d2.target, label: d2.displayName, hint: d2.hint })),
|
|
9686
|
+
initialValues,
|
|
9687
|
+
required: true
|
|
9688
|
+
});
|
|
9689
|
+
if (Ct(result))
|
|
9690
|
+
cancelAndExit2();
|
|
9691
|
+
const selected = result;
|
|
9692
|
+
const removed = current.filter((t) => !selected.includes(t));
|
|
9693
|
+
const added = selected.filter((t) => !current.includes(t));
|
|
9694
|
+
if (removed.length === 0 && added.length === 0) {
|
|
9695
|
+
Le("No changes.");
|
|
9696
|
+
return;
|
|
9697
|
+
}
|
|
9698
|
+
const s = bt2();
|
|
9699
|
+
s.start("Updating targets...");
|
|
9700
|
+
for (const target of removed) {
|
|
9701
|
+
await cleanupAgentDir(root, target);
|
|
9702
|
+
}
|
|
9703
|
+
config2.targets = makeTargets(...selected);
|
|
9704
|
+
await writeConfig(root, config2);
|
|
9705
|
+
await generate(root, config2);
|
|
9706
|
+
s.stop("Done.");
|
|
9707
|
+
const lines = [
|
|
9708
|
+
...added.length > 0 ? [`Added: ${added.map((t) => AGENT_DEFINITIONS.find((d2) => d2.target === t).displayName).join(", ")}`] : [],
|
|
9709
|
+
...removed.length > 0 ? [`Removed: ${removed.map((t) => AGENT_DEFINITIONS.find((d2) => d2.target === t).displayName).join(", ")}`] : []
|
|
9710
|
+
];
|
|
9711
|
+
Ve(lines.map((l) => ` • ${l}`).join(`
|
|
9712
|
+
`), "Targets updated");
|
|
9713
|
+
if (removed.length > 0) {
|
|
9714
|
+
R2.info(`Removed agent files backed up to ${ONEAGENT_DIR}/backup/`);
|
|
9715
|
+
}
|
|
9716
|
+
Le("Run `oneagent status` to verify your setup.");
|
|
9717
|
+
}
|
|
9718
|
+
});
|
|
9719
|
+
});
|
|
9720
|
+
|
|
9721
|
+
// src/commands/add.ts
|
|
9722
|
+
var exports_add = {};
|
|
9723
|
+
__export(exports_add, {
|
|
9724
|
+
default: () => add_default
|
|
9725
|
+
});
|
|
9726
|
+
var add_default;
|
|
9727
|
+
var init_add = __esm(() => {
|
|
9728
|
+
init_dist();
|
|
9729
|
+
init_dist3();
|
|
9730
|
+
init_src();
|
|
9731
|
+
add_default = defineCommand2({
|
|
9732
|
+
meta: {
|
|
9733
|
+
name: "add",
|
|
9734
|
+
description: "Add an AI agent target"
|
|
9735
|
+
},
|
|
9736
|
+
args: {
|
|
9737
|
+
target: {
|
|
9738
|
+
type: "positional",
|
|
9739
|
+
description: "Agent to add (claude, cursor, windsurf, opencode, copilot)",
|
|
9740
|
+
required: false
|
|
9741
|
+
}
|
|
9742
|
+
},
|
|
9743
|
+
async run({ args }) {
|
|
9744
|
+
const root = process.cwd();
|
|
9745
|
+
let config2;
|
|
9746
|
+
try {
|
|
9747
|
+
config2 = await readConfig(root);
|
|
9748
|
+
} catch {
|
|
9749
|
+
console.error(`Error: No ${ONEAGENT_DIR}/config.yml found. Run \`oneagent init\` first.`);
|
|
9750
|
+
process.exit(1);
|
|
9751
|
+
}
|
|
9752
|
+
const current = activeTargets(config2);
|
|
9753
|
+
const available = ALL_AGENT_TARGETS.filter((t) => !current.includes(t));
|
|
9754
|
+
if (available.length === 0) {
|
|
9755
|
+
R2.info("All agents are already configured.");
|
|
9756
|
+
return;
|
|
9757
|
+
}
|
|
9758
|
+
let target;
|
|
9759
|
+
if (args.target) {
|
|
9760
|
+
if (!ALL_AGENT_TARGETS.includes(args.target)) {
|
|
9761
|
+
console.error(`Unknown target "${args.target}". Available: ${ALL_AGENT_TARGETS.join(", ")}`);
|
|
9762
|
+
process.exit(1);
|
|
9763
|
+
}
|
|
9764
|
+
target = args.target;
|
|
9765
|
+
if (current.includes(target)) {
|
|
9766
|
+
R2.info(`${AGENT_DEFINITIONS.find((d2) => d2.target === target).displayName} is already configured.`);
|
|
9767
|
+
return;
|
|
9768
|
+
}
|
|
9769
|
+
} else {
|
|
9770
|
+
const result = await Je({
|
|
9771
|
+
message: "Which agent do you want to add?",
|
|
9772
|
+
options: available.map((t) => {
|
|
9773
|
+
const def = AGENT_DEFINITIONS.find((d2) => d2.target === t);
|
|
9774
|
+
return { value: t, label: def.displayName, hint: def.hint };
|
|
9775
|
+
})
|
|
9776
|
+
});
|
|
9777
|
+
if (Ct(result)) {
|
|
9778
|
+
Le("Cancelled.");
|
|
9779
|
+
process.exit(0);
|
|
9780
|
+
}
|
|
9781
|
+
target = result;
|
|
9782
|
+
}
|
|
9783
|
+
config2.targets[target] = true;
|
|
9784
|
+
await writeConfig(root, config2);
|
|
9785
|
+
await generate(root, config2);
|
|
9786
|
+
R2.success(`Added ${AGENT_DEFINITIONS.find((d2) => d2.target === target).displayName}`);
|
|
9787
|
+
}
|
|
9788
|
+
});
|
|
9789
|
+
});
|
|
9790
|
+
|
|
9791
|
+
// src/commands/remove.ts
|
|
9792
|
+
var exports_remove = {};
|
|
9793
|
+
__export(exports_remove, {
|
|
9794
|
+
default: () => remove_default
|
|
9795
|
+
});
|
|
9796
|
+
var remove_default;
|
|
9797
|
+
var init_remove = __esm(() => {
|
|
9798
|
+
init_dist();
|
|
9799
|
+
init_dist3();
|
|
9800
|
+
init_src();
|
|
9801
|
+
remove_default = defineCommand2({
|
|
9802
|
+
meta: {
|
|
9803
|
+
name: "remove",
|
|
9804
|
+
description: "Remove an AI agent target"
|
|
9805
|
+
},
|
|
9806
|
+
args: {
|
|
9807
|
+
target: {
|
|
9808
|
+
type: "positional",
|
|
9809
|
+
description: "Agent to remove (claude, cursor, windsurf, opencode, copilot)",
|
|
9810
|
+
required: false
|
|
9811
|
+
}
|
|
9812
|
+
},
|
|
9813
|
+
async run({ args }) {
|
|
9814
|
+
const root = process.cwd();
|
|
9815
|
+
let config2;
|
|
9816
|
+
try {
|
|
9817
|
+
config2 = await readConfig(root);
|
|
9818
|
+
} catch {
|
|
9819
|
+
console.error(`Error: No ${ONEAGENT_DIR}/config.yml found. Run \`oneagent init\` first.`);
|
|
9820
|
+
process.exit(1);
|
|
9821
|
+
}
|
|
9822
|
+
const current = activeTargets(config2);
|
|
9823
|
+
if (current.length === 1) {
|
|
9824
|
+
console.error("Cannot remove the last target. At least one agent must be configured.");
|
|
9825
|
+
process.exit(1);
|
|
9826
|
+
}
|
|
9827
|
+
let target;
|
|
9828
|
+
if (args.target) {
|
|
9829
|
+
if (!ALL_AGENT_TARGETS.includes(args.target)) {
|
|
9830
|
+
console.error(`Unknown target "${args.target}". Available: ${ALL_AGENT_TARGETS.join(", ")}`);
|
|
9831
|
+
process.exit(1);
|
|
9832
|
+
}
|
|
9833
|
+
target = args.target;
|
|
9834
|
+
if (!current.includes(target)) {
|
|
9835
|
+
R2.info(`${AGENT_DEFINITIONS.find((d2) => d2.target === target).displayName} is not configured.`);
|
|
9836
|
+
return;
|
|
9837
|
+
}
|
|
9838
|
+
} else {
|
|
9839
|
+
const result = await Je({
|
|
9840
|
+
message: "Which agent do you want to remove?",
|
|
9841
|
+
options: current.map((t) => {
|
|
9842
|
+
const def = AGENT_DEFINITIONS.find((d2) => d2.target === t);
|
|
9843
|
+
return { value: t, label: def.displayName, hint: def.hint };
|
|
9844
|
+
})
|
|
9845
|
+
});
|
|
9846
|
+
if (Ct(result)) {
|
|
9847
|
+
Le("Cancelled.");
|
|
9848
|
+
process.exit(0);
|
|
9849
|
+
}
|
|
9850
|
+
target = result;
|
|
9851
|
+
}
|
|
9852
|
+
await cleanupAgentDir(root, target);
|
|
9853
|
+
config2.targets[target] = false;
|
|
9854
|
+
await writeConfig(root, config2);
|
|
9855
|
+
await generate(root, config2);
|
|
9856
|
+
R2.success(`Removed ${AGENT_DEFINITIONS.find((d2) => d2.target === target).displayName}`);
|
|
9857
|
+
R2.info(`Files backed up to ${ONEAGENT_DIR}/backup/`);
|
|
9858
|
+
}
|
|
9859
|
+
});
|
|
9860
|
+
});
|
|
9861
|
+
|
|
9480
9862
|
// ../../node_modules/.bun/citty@0.2.1/node_modules/citty/dist/index.mjs
|
|
9481
9863
|
init_scule();
|
|
9482
9864
|
import { parseArgs as parseArgs$1 } from "node:util";
|
|
@@ -9831,7 +10213,10 @@ var main = defineCommand({
|
|
|
9831
10213
|
subCommands: {
|
|
9832
10214
|
init: () => Promise.resolve().then(() => (init_init(), exports_init)).then((r) => r.default),
|
|
9833
10215
|
generate: () => Promise.resolve().then(() => (init_generate2(), exports_generate)).then((r) => r.default),
|
|
9834
|
-
status: () => Promise.resolve().then(() => (init_status2(), exports_status)).then((r) => r.default)
|
|
10216
|
+
status: () => Promise.resolve().then(() => (init_status2(), exports_status)).then((r) => r.default),
|
|
10217
|
+
targets: () => Promise.resolve().then(() => (init_targets(), exports_targets)).then((r) => r.default),
|
|
10218
|
+
add: () => Promise.resolve().then(() => (init_add(), exports_add)).then((r) => r.default),
|
|
10219
|
+
remove: () => Promise.resolve().then(() => (init_remove(), exports_remove)).then((r) => r.default)
|
|
9835
10220
|
}
|
|
9836
10221
|
});
|
|
9837
10222
|
runMain(main);
|
package/package.json
CHANGED