@arvoretech/hub 0.13.3 → 0.13.4

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.
@@ -5,7 +5,7 @@ import {
5
5
  // src/commands/generate.ts
6
6
  import { Command } from "commander";
7
7
  import { existsSync as existsSync2 } from "fs";
8
- import { mkdir as mkdir3, writeFile as writeFile3, readdir as readdir2, copyFile, readFile as readFile3, cp } from "fs/promises";
8
+ import { mkdir as mkdir3, writeFile as writeFile3, readdir as readdir2, copyFile, readFile as readFile3, cp, rm } from "fs/promises";
9
9
  import { join as join3, resolve as resolve2 } from "path";
10
10
  import chalk3 from "chalk";
11
11
  import inquirer from "inquirer";
@@ -117,7 +117,7 @@ async function checkAndAutoRegenerate(hubDir) {
117
117
  return;
118
118
  }
119
119
  console.log(chalk.yellow("\n Detected outdated configs, auto-regenerating..."));
120
- const { generators: generators2 } = await import("./generate-YSMMXJNC.js");
120
+ const { generators: generators2 } = await import("./generate-OIIS6DBO.js");
121
121
  const generator = generators2[result.editor];
122
122
  if (!generator) {
123
123
  console.log(chalk.red(` Unknown editor '${result.editor}' in cache. Run 'hub generate' manually.`));
@@ -903,24 +903,32 @@ ${rawContent}`;
903
903
  return `${lines.join("\n")}
904
904
  ${body}`;
905
905
  }
906
+ function stripDollarPrefix(env) {
907
+ const result = {};
908
+ for (const [key, value] of Object.entries(env)) {
909
+ result[key] = value.replace(/\$\{env:(\w+)\}/g, "{env:$1}").replace(/\$\{(\w+)\}/g, "{env:$1}");
910
+ }
911
+ return result;
912
+ }
906
913
  function buildOpenCodeMcpEntry(mcp) {
914
+ const env = mcp.env ? stripDollarPrefix(mcp.env) : void 0;
907
915
  if (mcp.url) {
908
916
  return { type: "remote", url: mcp.url };
909
917
  }
910
918
  if (mcp.image) {
911
919
  const cmd = ["docker", "run", "-i", "--rm"];
912
- if (mcp.env) {
913
- for (const [key, value] of Object.entries(mcp.env)) {
920
+ if (env) {
921
+ for (const [key, value] of Object.entries(env)) {
914
922
  cmd.push("-e", `${key}=${value}`);
915
923
  }
916
924
  }
917
925
  cmd.push(mcp.image);
918
- return { type: "local", command: cmd, ...mcp.env && { environment: mcp.env } };
926
+ return { type: "local", command: cmd, ...env && { environment: env } };
919
927
  }
920
928
  return {
921
929
  type: "local",
922
930
  command: ["npx", "-y", mcp.package],
923
- ...mcp.env && { environment: mcp.env }
931
+ ...env && { environment: env }
924
932
  };
925
933
  }
926
934
  function buildOpenCodeHooksPlugin(hooks) {
@@ -965,6 +973,22 @@ tools:
965
973
  bash: true
966
974
  ---
967
975
 
976
+ ${body.trim()}
977
+ `;
978
+ }
979
+ function buildOpenCodePrimaryAgentMarkdown(description, body) {
980
+ return `---
981
+ description: "${description}"
982
+ mode: primary
983
+ tools:
984
+ write: true
985
+ edit: true
986
+ bash: true
987
+ permission:
988
+ task:
989
+ "*": allow
990
+ ---
991
+
968
992
  ${body.trim()}
969
993
  `;
970
994
  }
@@ -1303,9 +1327,20 @@ async function generateOpenCode(config, hubDir) {
1303
1327
  const gitignoreLines = buildGitignoreLines(config);
1304
1328
  await writeManagedFile(join3(hubDir, ".gitignore"), gitignoreLines);
1305
1329
  console.log(chalk3.green(" Generated .gitignore"));
1306
- const orchestratorRule = buildOpenCodeOrchestratorRule(config);
1307
- await writeFile3(join3(opencodeDir, "rules", "orchestrator.md"), orchestratorRule + "\n", "utf-8");
1308
- console.log(chalk3.green(" Generated .opencode/rules/orchestrator.md"));
1330
+ if (config.repos.length > 0) {
1331
+ const ignoreContent = config.repos.map((r) => `!${r.name}`).join("\n") + "\n";
1332
+ await writeFile3(join3(hubDir, ".ignore"), ignoreContent, "utf-8");
1333
+ console.log(chalk3.green(" Generated .ignore"));
1334
+ }
1335
+ const orchestratorContent = buildOpenCodeOrchestratorRule(config);
1336
+ const orchestratorAgent = buildOpenCodePrimaryAgentMarkdown(
1337
+ "Development orchestrator. Delegates specialized work to subagents following a structured pipeline: refinement, coding, review, QA, and delivery.",
1338
+ orchestratorContent
1339
+ );
1340
+ await writeFile3(join3(opencodeDir, "agents", "orchestrator.md"), orchestratorAgent, "utf-8");
1341
+ console.log(chalk3.green(" Generated .opencode/agents/orchestrator.md (primary agent)"));
1342
+ await rm(join3(opencodeDir, "rules", "orchestrator.md")).catch(() => {
1343
+ });
1309
1344
  const hubSteeringDirOC = resolve2(hubDir, "steering");
1310
1345
  try {
1311
1346
  const steeringFiles = await readdir2(hubSteeringDirOC);
@@ -1321,7 +1356,8 @@ async function generateOpenCode(config, hubDir) {
1321
1356
  } catch {
1322
1357
  }
1323
1358
  const opencodeConfig = {
1324
- $schema: "https://opencode.ai/config.json"
1359
+ $schema: "https://opencode.ai/config.json",
1360
+ default_agent: "orchestrator"
1325
1361
  };
1326
1362
  if (config.mcps?.length) {
1327
1363
  const mcpConfig = {};
@@ -1348,6 +1384,7 @@ async function generateOpenCode(config, hubDir) {
1348
1384
  const agentFiles = await readdir2(agentsDir);
1349
1385
  const mdFiles = agentFiles.filter((f) => f.endsWith(".md"));
1350
1386
  for (const file of mdFiles) {
1387
+ if (file === "orchestrator.md") continue;
1351
1388
  const content = await readFile3(join3(agentsDir, file), "utf-8");
1352
1389
  const agentName = file.replace(/\.md$/, "");
1353
1390
  const converted = buildOpenCodeAgentMarkdown(agentName, content);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  generateCommand,
3
3
  generators
4
- } from "./chunk-H6BAEWCZ.js";
4
+ } from "./chunk-VE7RLHHJ.js";
5
5
  import "./chunk-VMN4KGAK.js";
6
6
  export {
7
7
  generateCommand,
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  checkAndAutoRegenerate,
4
4
  generateCommand
5
- } from "./chunk-H6BAEWCZ.js";
5
+ } from "./chunk-VE7RLHHJ.js";
6
6
  import {
7
7
  loadHubConfig,
8
8
  resolveConfigPath
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arvoretech/hub",
3
- "version": "0.13.3",
3
+ "version": "0.13.4",
4
4
  "description": "CLI for managing AI-aware multi-repository workspaces",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",