@zcy2nn/agent-forge 1.0.1 → 1.0.3

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/README.md CHANGED
@@ -38,25 +38,6 @@ bunx @zcy2nn/agent-forge@latest install
38
38
 
39
39
  安装器会同时在 OpenCode 的 `tui.json` 中注册 TUI 插件,在侧边栏显示 Agent 状态和任务会话。手动安装时,需在 `opencode.json` 和 `tui.json` 的 `plugin` 数组中添加 `@zcy2nn/agent-forge`。
40
40
 
41
- ### 从 oh-my-opencode-slim 升级
42
-
43
- 如果你已有 `~/.config/opencode/oh-my-opencode-slim.json`,安装器会自动检测并引导迁移:
44
-
45
- - Agent 名称自动重映射(explorer→researcher, oracle→reviewer, designer→implementer)
46
- - 文件重命名为 `agent-forge.json`
47
- - 原文件保留为 `.bak` 备份
48
-
49
- 也可以手动重命名文件并替换 Agent 名称:
50
-
51
- | 旧名称 | 新名称 | 说明 |
52
- |--------|--------|------|
53
- | explorer | researcher | 合并(原 explorer + librarian) |
54
- | librarian | researcher | 合并(原 explorer + librarian) |
55
- | oracle | reviewer | 重命名 |
56
- | designer | implementer | 合并(原 designer + fixer) |
57
- | fixer | implementer | 合并(原 designer + fixer) |
58
- | observer | — | 已移除 |
59
-
60
41
  ### 开始使用
61
42
 
62
43
  安装器默认生成 OpenAI 和 OpenCode Go 两套预设,OpenAI 为默认激活。OpenAI 使用 `openai/gpt-5.5` 作为高判断力 Agent 的模型,`openai/gpt-5.4-mini` 作为快速执行 Agent 的模型。要使用 OpenCode Go,运行 `bunx @zcy2nn/agent-forge@latest install --preset=opencode-go`,或安装后在 `~/.config/opencode/agent-forge.json` 中修改默认预设。
package/dist/cli/index.js CHANGED
@@ -1256,7 +1256,7 @@ Options:
1256
1256
  }
1257
1257
 
1258
1258
  // src/cli/install.ts
1259
- import { existsSync as existsSync6 } from "node:fs";
1259
+ import { existsSync as existsSync5 } from "node:fs";
1260
1260
  import { createInterface } from "node:readline/promises";
1261
1261
  // src/cli/system.ts
1262
1262
  import { spawnSync as spawnSync2 } from "node:child_process";
@@ -1433,124 +1433,6 @@ function getOpenCodePath() {
1433
1433
  const path2 = resolveOpenCodePath();
1434
1434
  return path2 === "opencode" ? null : path2;
1435
1435
  }
1436
- // src/cli/migration.ts
1437
- import { existsSync as existsSync5, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
1438
- import { join as join5 } from "node:path";
1439
- var LEGACY_BASE_NAME = "oh-my-opencode-slim";
1440
- var PRIMARY_AGENT_MAP = {
1441
- explorer: "researcher",
1442
- oracle: "reviewer",
1443
- designer: "implementer"
1444
- };
1445
- var SECONDARY_AGENT_MAP = {
1446
- librarian: "researcher",
1447
- fixer: "implementer"
1448
- };
1449
- var REMOVED_AGENTS = new Set(["observer"]);
1450
- var ALL_LEGACY_NAMES = new Set([
1451
- ...Object.keys(PRIMARY_AGENT_MAP),
1452
- ...Object.keys(SECONDARY_AGENT_MAP),
1453
- ...REMOVED_AGENTS
1454
- ]);
1455
- function getLegacyConfigPaths() {
1456
- const configDir = getConfigDir();
1457
- return [
1458
- join5(configDir, `${LEGACY_BASE_NAME}.json`),
1459
- join5(configDir, `${LEGACY_BASE_NAME}.jsonc`)
1460
- ];
1461
- }
1462
- function detectLegacyConfig() {
1463
- const paths2 = getLegacyConfigPaths();
1464
- for (const p of paths2) {
1465
- if (existsSync5(p))
1466
- return p;
1467
- }
1468
- return;
1469
- }
1470
- function migrateAgentNames(config) {
1471
- const result = { ...config };
1472
- const presets = result.presets;
1473
- if (presets) {
1474
- const migratedPresets = {};
1475
- for (const [presetName, preset] of Object.entries(presets)) {
1476
- migratedPresets[presetName] = migrateRecord(preset);
1477
- }
1478
- result.presets = migratedPresets;
1479
- }
1480
- const agents = result.agents;
1481
- if (agents) {
1482
- result.agents = migrateRecord(agents);
1483
- }
1484
- const disabled = result.disabled_agents;
1485
- if (Array.isArray(disabled)) {
1486
- result.disabled_agents = disabled.filter((name) => !REMOVED_AGENTS.has(name));
1487
- }
1488
- return result;
1489
- }
1490
- function migrateRecord(record) {
1491
- const result = {};
1492
- const usedTargets = new Set;
1493
- for (const [key, value] of Object.entries(record)) {
1494
- if (REMOVED_AGENTS.has(key)) {
1495
- continue;
1496
- }
1497
- const primaryTarget = PRIMARY_AGENT_MAP[key];
1498
- if (primaryTarget) {
1499
- result[primaryTarget] = value;
1500
- usedTargets.add(primaryTarget);
1501
- continue;
1502
- }
1503
- if (!ALL_LEGACY_NAMES.has(key)) {
1504
- result[key] = value;
1505
- }
1506
- }
1507
- for (const [key, value] of Object.entries(record)) {
1508
- const secondaryTarget = SECONDARY_AGENT_MAP[key];
1509
- if (secondaryTarget && !usedTargets.has(secondaryTarget)) {
1510
- result[secondaryTarget] = value;
1511
- usedTargets.add(secondaryTarget);
1512
- }
1513
- }
1514
- return result;
1515
- }
1516
- function performMigration(legacyPath) {
1517
- try {
1518
- const content = readFileSync4(legacyPath, "utf-8");
1519
- if (content.trim().length === 0) {
1520
- return {
1521
- detected: true,
1522
- migrated: false,
1523
- legacyPath,
1524
- error: "Legacy config file is empty"
1525
- };
1526
- }
1527
- const config = JSON.parse(stripJsonComments(content));
1528
- const migrated = migrateAgentNames(config);
1529
- const configDir = getConfigDir();
1530
- const newPath = join5(configDir, "agent-forge.json");
1531
- const newContent = `${JSON.stringify(migrated, null, 2)}
1532
- `;
1533
- const tmpPath = `${newPath}.tmp`;
1534
- writeFileSync2(tmpPath, newContent);
1535
- renameSync2(tmpPath, newPath);
1536
- const bakPath = `${legacyPath}.bak`;
1537
- renameSync2(legacyPath, bakPath);
1538
- return {
1539
- detected: true,
1540
- migrated: true,
1541
- newPath,
1542
- legacyPath
1543
- };
1544
- } catch (err) {
1545
- return {
1546
- detected: true,
1547
- migrated: false,
1548
- legacyPath,
1549
- error: `Migration failed: ${err}`
1550
- };
1551
- }
1552
- }
1553
-
1554
1436
  // src/cli/install.ts
1555
1437
  var GREEN = "\x1B[32m";
1556
1438
  var BLUE = "\x1B[34m";
@@ -1652,10 +1534,6 @@ async function runInstall(config) {
1652
1534
  totalSteps += 1;
1653
1535
  if (config.installCustomSkills)
1654
1536
  totalSteps += 1;
1655
- const legacyPath = detectLegacyConfig();
1656
- const hasLegacy = legacyPath !== undefined;
1657
- if (hasLegacy)
1658
- totalSteps += 1;
1659
1537
  let step = 1;
1660
1538
  printStep(step++, totalSteps, "Checking OpenCode installation...");
1661
1539
  if (config.dryRun) {
@@ -1700,36 +1578,6 @@ async function runInstall(config) {
1700
1578
  if (!handleStepResult(lspResult, "LSP enabled"))
1701
1579
  return 1;
1702
1580
  }
1703
- if (hasLegacy && legacyPath) {
1704
- printStep(step++, totalSteps, "Migrating legacy configuration...");
1705
- if (config.dryRun) {
1706
- printInfo(`Dry run mode - detected legacy config: ${legacyPath}`);
1707
- printInfo("Would migrate agent names and rename to agent-forge.json");
1708
- } else if (config.reset) {
1709
- const migrationResult = performMigration(legacyPath);
1710
- if (migrationResult.migrated) {
1711
- printSuccess(`Legacy config migrated ${SYMBOLS.arrow} ${migrationResult.newPath}`);
1712
- } else if (migrationResult.error) {
1713
- printInfo(`Legacy config migration skipped: ${migrationResult.error}`);
1714
- }
1715
- } else {
1716
- printInfo(`Legacy config detected: ${DIM}${legacyPath}${RESET}`);
1717
- printInfo("This is an oh-my-opencode-slim config with old agent names (explorer, librarian, oracle, designer, fixer, observer).");
1718
- printInfo("New agent names: researcher (explorer+librarian), reviewer (oracle), implementer (designer+fixer).");
1719
- const shouldMigrate = await confirm("Migrate to agent-forge.json?", true);
1720
- if (shouldMigrate) {
1721
- const migrationResult = performMigration(legacyPath);
1722
- if (migrationResult.migrated) {
1723
- printSuccess(`Migrated ${SYMBOLS.arrow} ${DIM}${migrationResult.newPath}${RESET}`);
1724
- printInfo(`Legacy config backed up to ${DIM}${legacyPath}.bak${RESET}`);
1725
- } else {
1726
- printError(migrationResult.error ?? "Unknown migration error");
1727
- }
1728
- } else {
1729
- printInfo("Skipped migration. You can manually rename oh-my-opencode-slim.json to agent-forge.json and " + "update agent names: explorer→researcher, " + "oracle→reviewer, designer→implementer.");
1730
- }
1731
- }
1732
- }
1733
1581
  printStep(step++, totalSteps, "Writing agent-forge configuration...");
1734
1582
  if (config.dryRun) {
1735
1583
  const liteConfig = generateLiteConfig(config);
@@ -1739,7 +1587,7 @@ ${JSON.stringify(liteConfig, null, 2)}
1739
1587
  `);
1740
1588
  } else {
1741
1589
  const configPath2 = getExistingLiteConfigPath();
1742
- const configExists = existsSync6(configPath2);
1590
+ const configExists = existsSync5(configPath2);
1743
1591
  if (configExists && !config.reset) {
1744
1592
  printInfo(`Configuration already exists at ${configPath2}. Use --reset to overwrite.`);
1745
1593
  } else {
package/dist/index.js CHANGED
@@ -22194,29 +22194,29 @@ async function runBackgroundUpdateCheck(ctx, autoUpdate) {
22194
22194
  }
22195
22195
  log(`[auto-update-checker] Update available (${channel}): ${currentVersion} → ${latestVersion}`);
22196
22196
  if (pluginInfo.isPinned) {
22197
- showToast(ctx, `OMO-Slim ${latestVersion}`, `v${latestVersion} available.
22197
+ showToast(ctx, `AGF ${latestVersion}`, `v${latestVersion} available.
22198
22198
  Version is pinned. Update your plugin config to apply.`, "info", 8000);
22199
22199
  log(`[auto-update-checker] Version is pinned; skipping auto-update.`);
22200
22200
  return;
22201
22201
  }
22202
22202
  if (!autoUpdate) {
22203
- showToast(ctx, `OMO-Slim ${latestVersion}`, `v${latestVersion} available. Auto-update is disabled.`, "info", 8000);
22203
+ showToast(ctx, `AGF ${latestVersion}`, `v${latestVersion} available. Auto-update is disabled.`, "info", 8000);
22204
22204
  log("[auto-update-checker] Auto-update disabled, notification only");
22205
22205
  return;
22206
22206
  }
22207
22207
  const installDir = preparePackageUpdate(latestVersion, PACKAGE_NAME);
22208
22208
  if (!installDir) {
22209
- showToast(ctx, `OMO-Slim ${latestVersion}`, `v${latestVersion} available. Auto-update could not prepare the active install.`, "info", 8000);
22209
+ showToast(ctx, `AGF ${latestVersion}`, `v${latestVersion} available. Auto-update could not prepare the active install.`, "info", 8000);
22210
22210
  log("[auto-update-checker] Failed to prepare install root for auto-update");
22211
22211
  return;
22212
22212
  }
22213
22213
  const installSuccess = await runBunInstallSafe(installDir);
22214
22214
  if (installSuccess) {
22215
- showToast(ctx, "OMO-Slim Updated!", `v${currentVersion} → v${latestVersion}
22215
+ showToast(ctx, "AGF Updated!", `v${currentVersion} → v${latestVersion}
22216
22216
  Restart OpenCode to apply.`, "success", 8000);
22217
22217
  log(`[auto-update-checker] Update installed: ${currentVersion} → ${latestVersion}`);
22218
22218
  } else {
22219
- showToast(ctx, `OMO-Slim ${latestVersion}`, `v${latestVersion} available, but auto-update failed to install it. Check logs or retry manually.`, "error", 8000);
22219
+ showToast(ctx, `AGF ${latestVersion}`, `v${latestVersion} available, but auto-update failed to install it. Check logs or retry manually.`, "error", 8000);
22220
22220
  log("[auto-update-checker] bun install failed; update not installed");
22221
22221
  }
22222
22222
  }
package/dist/tui.js CHANGED
@@ -33,6 +33,8 @@ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports,
33
33
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
34
34
 
35
35
  // src/tui.ts
36
+ import { readFileSync as readFileSync2 } from "node:fs";
37
+ import { fileURLToPath } from "node:url";
36
38
  import { createElement, insert, setProp } from "@opentui/solid";
37
39
 
38
40
  // src/config/constants.ts
@@ -143,9 +145,10 @@ function recordTuiAgentModel(input) {
143
145
  var PLUGIN_NAME = "agent-forge";
144
146
  var FALLBACK_SIDEBAR_AGENTS = SUBAGENT_NAMES.filter((agent) => agent !== "councillor" && agent !== "council" && !DEFAULT_DISABLED_AGENTS.includes(agent));
145
147
  var BORDER = { type: "single" };
146
- async function readPackageVersion() {
148
+ function readPackageVersion() {
147
149
  try {
148
- const packageJson = await Bun.file(new URL("../package.json", import.meta.url)).json();
150
+ const pkgPath = fileURLToPath(new URL("../package.json", import.meta.url));
151
+ const packageJson = JSON.parse(readFileSync2(pkgPath, "utf8"));
149
152
  return typeof packageJson.version === "string" ? packageJson.version : undefined;
150
153
  } catch {
151
154
  return;
@@ -204,7 +207,7 @@ function renderSidebar(snapshot, version, theme) {
204
207
  justifyContent: "space-between",
205
208
  alignItems: "center"
206
209
  }, [
207
- box({ paddingLeft: 1, paddingRight: 1, backgroundColor: theme.accent }, [text({ fg: theme.background }, ["OMO-Slim"])]),
210
+ box({ paddingLeft: 1, paddingRight: 1, backgroundColor: theme.accent }, [text({ fg: theme.background }, ["AGF"])]),
208
211
  text({ fg: theme.textMuted }, [`v${version}`])
209
212
  ]),
210
213
  box({ width: "100%", marginTop: 1 }, [
@@ -219,7 +222,7 @@ function renderSidebar(snapshot, version, theme) {
219
222
  var plugin = {
220
223
  id: `${PLUGIN_NAME}:tui`,
221
224
  tui: async (api, _options, meta) => {
222
- const version = meta.version ?? await readPackageVersion() ?? "dev";
225
+ const version = meta.version ?? readPackageVersion() ?? "dev";
223
226
  let snapshot = readTuiSnapshot();
224
227
  const renderTimer = setInterval(async () => {
225
228
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zcy2nn/agent-forge",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Lightweight agent orchestration plugin for OpenCode - a slimmed-down fork of oh-my-opencode",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",