opencode-agents 1.0.7 → 1.0.9

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/build.mjs CHANGED
@@ -23,6 +23,7 @@ async function build() {
23
23
  },
24
24
  sourcemap: true,
25
25
  minify: false,
26
+ external: ['inquirer', 'os', 'path', 'fs', 'module', 'url'],
26
27
  });
27
28
 
28
29
  // Copy bin file
package/dist/index.js CHANGED
@@ -25196,6 +25196,9 @@ var {
25196
25196
 
25197
25197
  // src/commands/add.ts
25198
25198
  var import_ora = __toESM(require_ora(), 1);
25199
+ import inquirer from "inquirer";
25200
+ import { tmpdir as tmpdir2 } from "os";
25201
+ import { existsSync as existsSync4, rmSync as rmSync3 } from "fs";
25199
25202
 
25200
25203
  // src/core/installer.ts
25201
25204
  import { join as join3, basename as basename3 } from "path";
@@ -25911,14 +25914,24 @@ var logger = {
25911
25914
 
25912
25915
  // src/core/installer.ts
25913
25916
  async function installAgent(options2) {
25914
- const { source, global: global2, platforms, agentName, copy } = options2;
25917
+ const { source, sourcePath, global: global2, platforms, agentName, copy, selectedAgents } = options2;
25915
25918
  logger.info(`Installing agent from: ${source}`);
25916
- const tempDir = await fetchSource(source);
25917
- try {
25918
- const agents = await discoverFromDirectory(tempDir);
25919
+ let tempDir;
25920
+ let agents;
25921
+ if (selectedAgents) {
25922
+ tempDir = sourcePath || source;
25923
+ agents = selectedAgents;
25924
+ } else {
25925
+ tempDir = await fetchSource(source);
25926
+ agents = await discoverFromDirectory(tempDir);
25919
25927
  if (agents.length === 0) {
25928
+ if (existsSync3(tempDir) && tempDir.startsWith(tmpdir())) {
25929
+ rmSync2(tempDir, { recursive: true, force: true });
25930
+ }
25920
25931
  throw new Error("No agents found in the source");
25921
25932
  }
25933
+ }
25934
+ try {
25922
25935
  for (const platform of platforms) {
25923
25936
  const targetPaths = getPlatformPaths(platform, global2);
25924
25937
  for (const targetPath of targetPaths) {
@@ -25931,21 +25944,22 @@ async function installAgent(options2) {
25931
25944
  continue;
25932
25945
  }
25933
25946
  if (copy) {
25934
- const sourcePath = agentFile.path;
25935
- if (isDirectory(sourcePath)) {
25936
- copyDirectory(sourcePath, join3(targetPath, name));
25947
+ const sourcePath2 = agentFile.path;
25948
+ if (isDirectory(sourcePath2)) {
25949
+ copyDirectory(sourcePath2, join3(targetPath, name));
25937
25950
  } else {
25938
- copyFileSync2(sourcePath, finalPath);
25951
+ copyFileSync2(sourcePath2, finalPath);
25939
25952
  }
25940
25953
  logger.success(`Copied agent "${name}" to ${finalPath}`);
25941
25954
  } else {
25942
- const sourceDir = tempDir;
25955
+ const sourcePath2 = agentFile.path;
25956
+ const linkType = isDirectory(sourcePath2) ? "dir" : "file";
25943
25957
  try {
25944
- symlinkSync2(sourceDir, finalPath, "dir");
25958
+ symlinkSync2(sourcePath2, finalPath, linkType);
25945
25959
  logger.success(`Symlinked agent "${name}" to ${finalPath}`);
25946
25960
  } catch (err) {
25947
25961
  logger.warn(`Failed to create symlink, copying instead: ${err}`);
25948
- copyDirectory(sourceDir, join3(targetPath, name));
25962
+ copyDirectory(sourcePath2, join3(targetPath, name));
25949
25963
  logger.success(`Copied agent "${name}" to ${targetPath}`);
25950
25964
  }
25951
25965
  }
@@ -25953,7 +25967,7 @@ async function installAgent(options2) {
25953
25967
  }
25954
25968
  }
25955
25969
  } finally {
25956
- if (existsSync3(tempDir) && tempDir.startsWith(tmpdir())) {
25970
+ if (!selectedAgents && existsSync3(tempDir) && tempDir.startsWith(tmpdir())) {
25957
25971
  rmSync2(tempDir, { recursive: true, force: true });
25958
25972
  }
25959
25973
  }
@@ -26047,8 +26061,99 @@ function readlinkCheck(path, name) {
26047
26061
  }
26048
26062
 
26049
26063
  // src/commands/add.ts
26064
+ import { basename as basename4 } from "path";
26065
+ async function promptInstallLocation() {
26066
+ const answers = await inquirer.prompt([
26067
+ {
26068
+ type: "list",
26069
+ name: "scope",
26070
+ message: "Where would you like to install this agent?",
26071
+ choices: [
26072
+ { name: "Current project (./.opencode/agents/)", value: false },
26073
+ { name: "Global (~/.config/opencode/agents/)", value: true }
26074
+ ],
26075
+ default: 0
26076
+ }
26077
+ ]);
26078
+ return answers.scope;
26079
+ }
26080
+ async function promptSelectAgents(agents) {
26081
+ const choices = agents.map((agent) => ({
26082
+ name: agent.agent.name || basename4(agent.path, ".md"),
26083
+ value: agent,
26084
+ checked: false
26085
+ }));
26086
+ const answers = await inquirer.prompt([
26087
+ {
26088
+ type: "checkbox",
26089
+ name: "selected",
26090
+ message: "Select agents to install (space to select, enter to confirm):",
26091
+ choices
26092
+ }
26093
+ ]);
26094
+ return answers.selected;
26095
+ }
26096
+ async function fetchSource2(source) {
26097
+ const { mkdtempSync: mkdtempSync2, join: join5 } = await import("path");
26098
+ const degit = await Promise.resolve().then(() => __toESM(require_dist(), 1));
26099
+ const tempDir = mkdtempSync2(join5(tmpdir2(), "agents-cli-"));
26100
+ const parts = source.split("/");
26101
+ let owner = parts[0];
26102
+ let repo = parts[1]?.replace(/#.+$/, "") || "";
26103
+ let ref = "";
26104
+ if (source.includes("#")) {
26105
+ const [repoPart, refPart] = source.split("#");
26106
+ repo = repoPart.split("/")[1];
26107
+ ref = refPart;
26108
+ }
26109
+ try {
26110
+ const target = ref ? `${owner}/${repo}#${ref}` : `${owner}/${repo}`;
26111
+ await degit.default(target).clone(tempDir);
26112
+ return tempDir;
26113
+ } catch (err) {
26114
+ rmSync3(tempDir, { recursive: true, force: true });
26115
+ throw new Error(`Failed to fetch from ${source}: ${err}`);
26116
+ }
26117
+ }
26050
26118
  async function addCommand(source, options2) {
26051
- const spinner = (0, import_ora.default)("Installing agent...").start();
26119
+ let isGlobal = options2.global;
26120
+ if (isGlobal === void 0) {
26121
+ isGlobal = await promptInstallLocation();
26122
+ }
26123
+ const fetchSpinner = (0, import_ora.default)("Fetching source...").start();
26124
+ let tempDir;
26125
+ try {
26126
+ tempDir = await fetchSource2(source);
26127
+ fetchSpinner.succeed("Source fetched");
26128
+ } catch (err) {
26129
+ fetchSpinner.fail(`Failed to fetch source: ${err instanceof Error ? err.message : String(err)}`);
26130
+ logger.error(String(err));
26131
+ process.exit(1);
26132
+ }
26133
+ const discoverSpinner = (0, import_ora.default)("Discovering agents...").start();
26134
+ let agents;
26135
+ try {
26136
+ agents = await discoverFromDirectory(tempDir);
26137
+ discoverSpinner.succeed(`Found ${agents.length} agent(s)`);
26138
+ } catch (err) {
26139
+ discoverSpinner.fail(`Failed to discover agents: ${err instanceof Error ? err.message : String(err)}`);
26140
+ process.exit(1);
26141
+ }
26142
+ if (agents.length === 0) {
26143
+ logger.error("No agents found in the source");
26144
+ process.exit(1);
26145
+ }
26146
+ let selectedAgents;
26147
+ if (options2.yes) {
26148
+ selectedAgents = agents;
26149
+ } else {
26150
+ selectedAgents = await promptSelectAgents(agents);
26151
+ }
26152
+ if (selectedAgents.length === 0) {
26153
+ logger.warn("No agents selected, aborting");
26154
+ process.exit(0);
26155
+ }
26156
+ const installSpinner = (0, import_ora.default)("Installing agent(s)...").start();
26052
26157
  try {
26053
26158
  let platforms;
26054
26159
  if (options2.agent && options2.agent.length > 0) {
@@ -26058,18 +26163,24 @@ async function addCommand(source, options2) {
26058
26163
  }
26059
26164
  const installOptions = {
26060
26165
  source,
26061
- global: options2.global,
26166
+ sourcePath: tempDir,
26167
+ global: isGlobal,
26062
26168
  platforms,
26063
26169
  agentName: options2.agentName,
26064
26170
  copy: options2.copy,
26065
- yes: options2.yes
26171
+ yes: options2.yes,
26172
+ selectedAgents
26066
26173
  };
26067
26174
  await installAgent(installOptions);
26068
- spinner.succeed(`Successfully installed agent from ${source}`);
26175
+ installSpinner.succeed(`Successfully installed ${selectedAgents.length} agent(s)`);
26069
26176
  } catch (err) {
26070
- spinner.fail(`Failed to install agent: ${err instanceof Error ? err.message : String(err)}`);
26177
+ installSpinner.fail(`Failed to install agent: ${err instanceof Error ? err.message : String(err)}`);
26071
26178
  logger.error(String(err));
26072
26179
  process.exit(1);
26180
+ } finally {
26181
+ if (existsSync4(tempDir) && tempDir.startsWith(tmpdir2())) {
26182
+ rmSync3(tempDir, { recursive: true, force: true });
26183
+ }
26073
26184
  }
26074
26185
  }
26075
26186
 
@@ -26133,7 +26244,7 @@ async function removeCommand(name, options2) {
26133
26244
 
26134
26245
  // src/commands/init.ts
26135
26246
  import { join as join4 } from "path";
26136
- import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
26247
+ import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
26137
26248
  import { fileURLToPath } from "url";
26138
26249
  import { dirname as dirname2 } from "path";
26139
26250
  var __dirname = dirname2(fileURLToPath(import.meta.url));
@@ -26142,14 +26253,14 @@ async function initCommand(name, _options) {
26142
26253
  const targetName = name || "my-agent";
26143
26254
  const targetDir = name ? join4(process.cwd(), name) : process.cwd();
26144
26255
  const targetPath = join4(targetDir, `${targetName}.md`);
26145
- if (existsSync4(targetPath)) {
26256
+ if (existsSync5(targetPath)) {
26146
26257
  logger.error(`Agent file already exists at ${targetPath}`);
26147
26258
  process.exit(1);
26148
26259
  }
26149
26260
  ensureDir(targetDir);
26150
26261
  let template;
26151
26262
  const templatePath = join4(__dirname, "..", "..", "templates", "default-agent.md");
26152
- if (existsSync4(templatePath)) {
26263
+ if (existsSync5(templatePath)) {
26153
26264
  template = readFileSync4(templatePath, "utf-8");
26154
26265
  } else {
26155
26266
  template = getDefaultTemplate(targetName);