@topolo/cli 0.12.32 → 0.13.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.
Files changed (119) hide show
  1. package/README.md +62 -0
  2. package/agent-packs/README.md +341 -0
  3. package/agent-packs/pyproject.toml +16 -0
  4. package/agent-packs/requirements-test.txt +1 -0
  5. package/agent-packs/src/topolo_agent_pack/__init__.py +1 -0
  6. package/agent-packs/src/topolo_agent_pack/blueprint.py +57 -0
  7. package/agent-packs/src/topolo_agent_pack/cli.py +416 -0
  8. package/agent-packs/src/topolo_agent_pack/fresh.py +158 -0
  9. package/agent-packs/src/topolo_agent_pack/live.py +362 -0
  10. package/agent-packs/src/topolo_agent_pack/native.py +645 -0
  11. package/agent-packs/src/topolo_agent_pack/storage.py +271 -0
  12. package/agent-packs/src/topolo_agent_pack/topolo.py +321 -0
  13. package/agent-packs/templates/career/AGENTS.md +17 -0
  14. package/agent-packs/templates/career/README.md +14 -0
  15. package/agent-packs/templates/career/agents/intakes/career-intake/AGENTS.md +21 -0
  16. package/agent-packs/templates/career/agents/specialists/application-preparation/AGENTS.md +21 -0
  17. package/agent-packs/templates/career/agents/specialists/application-tracker/AGENTS.md +21 -0
  18. package/agent-packs/templates/career/agents/specialists/interview-coach/AGENTS.md +21 -0
  19. package/agent-packs/templates/career/agents/specialists/opportunity-research/AGENTS.md +21 -0
  20. package/agent-packs/templates/career/agents/specialists/profile-cv/AGENTS.md +21 -0
  21. package/agent-packs/templates/career/pack.json +124 -0
  22. package/agent-packs/templates/career/shared/PACK.md +22 -0
  23. package/agent-packs/templates/career/shared/TOPOLO.md +13 -0
  24. package/agent-packs/templates/career/shared/WORKFLOW.md +13 -0
  25. package/agent-packs/templates/career/skills/topolo/SKILL.md +305 -0
  26. package/agent-packs/templates/clients/AGENTS.md +17 -0
  27. package/agent-packs/templates/clients/README.md +14 -0
  28. package/agent-packs/templates/clients/agents/intakes/client-intake/AGENTS.md +21 -0
  29. package/agent-packs/templates/clients/agents/specialists/acceptance-review/AGENTS.md +21 -0
  30. package/agent-packs/templates/clients/agents/specialists/delivery-planner/AGENTS.md +21 -0
  31. package/agent-packs/templates/clients/agents/specialists/discovery/AGENTS.md +21 -0
  32. package/agent-packs/templates/clients/agents/specialists/proposal-writer/AGENTS.md +21 -0
  33. package/agent-packs/templates/clients/agents/specialists/solution-design/AGENTS.md +21 -0
  34. package/agent-packs/templates/clients/pack.json +126 -0
  35. package/agent-packs/templates/clients/shared/PACK.md +22 -0
  36. package/agent-packs/templates/clients/shared/TOPOLO.md +13 -0
  37. package/agent-packs/templates/clients/shared/WORKFLOW.md +13 -0
  38. package/agent-packs/templates/clients/skills/topolo/SKILL.md +305 -0
  39. package/agent-packs/templates/creative/AGENTS.md +17 -0
  40. package/agent-packs/templates/creative/README.md +14 -0
  41. package/agent-packs/templates/creative/agents/intakes/creative-director/AGENTS.md +21 -0
  42. package/agent-packs/templates/creative/agents/specialists/brand-copy/AGENTS.md +21 -0
  43. package/agent-packs/templates/creative/agents/specialists/media-production/AGENTS.md +21 -0
  44. package/agent-packs/templates/creative/agents/specialists/quality-review/AGENTS.md +21 -0
  45. package/agent-packs/templates/creative/agents/specialists/storytelling/AGENTS.md +21 -0
  46. package/agent-packs/templates/creative/agents/specialists/visual-design/AGENTS.md +21 -0
  47. package/agent-packs/templates/creative/pack.json +128 -0
  48. package/agent-packs/templates/creative/shared/PACK.md +22 -0
  49. package/agent-packs/templates/creative/shared/TOPOLO.md +13 -0
  50. package/agent-packs/templates/creative/shared/WORKFLOW.md +13 -0
  51. package/agent-packs/templates/creative/skills/topolo/SKILL.md +305 -0
  52. package/agent-packs/templates/founder/AGENTS.md +17 -0
  53. package/agent-packs/templates/founder/README.md +14 -0
  54. package/agent-packs/templates/founder/agents/intakes/founder-intake/AGENTS.md +21 -0
  55. package/agent-packs/templates/founder/agents/specialists/commercial-modelling/AGENTS.md +21 -0
  56. package/agent-packs/templates/founder/agents/specialists/customer-research/AGENTS.md +21 -0
  57. package/agent-packs/templates/founder/agents/specialists/decision-review/AGENTS.md +21 -0
  58. package/agent-packs/templates/founder/agents/specialists/partnerships/AGENTS.md +21 -0
  59. package/agent-packs/templates/founder/agents/specialists/strategy/AGENTS.md +21 -0
  60. package/agent-packs/templates/founder/pack.json +126 -0
  61. package/agent-packs/templates/founder/shared/PACK.md +22 -0
  62. package/agent-packs/templates/founder/shared/TOPOLO.md +13 -0
  63. package/agent-packs/templates/founder/shared/WORKFLOW.md +13 -0
  64. package/agent-packs/templates/founder/skills/topolo/SKILL.md +305 -0
  65. package/agent-packs/templates/learning/AGENTS.md +17 -0
  66. package/agent-packs/templates/learning/README.md +14 -0
  67. package/agent-packs/templates/learning/agents/intakes/learning-intake/AGENTS.md +21 -0
  68. package/agent-packs/templates/learning/agents/specialists/critical-reviewer/AGENTS.md +21 -0
  69. package/agent-packs/templates/learning/agents/specialists/curriculum-designer/AGENTS.md +21 -0
  70. package/agent-packs/templates/learning/agents/specialists/knowledge-steward/AGENTS.md +21 -0
  71. package/agent-packs/templates/learning/agents/specialists/practice-coach/AGENTS.md +21 -0
  72. package/agent-packs/templates/learning/agents/specialists/tutor/AGENTS.md +21 -0
  73. package/agent-packs/templates/learning/pack.json +124 -0
  74. package/agent-packs/templates/learning/shared/PACK.md +22 -0
  75. package/agent-packs/templates/learning/shared/TOPOLO.md +13 -0
  76. package/agent-packs/templates/learning/shared/WORKFLOW.md +13 -0
  77. package/agent-packs/templates/learning/skills/topolo/SKILL.md +305 -0
  78. package/agent-packs/templates/personal/AGENTS.md +17 -0
  79. package/agent-packs/templates/personal/README.md +14 -0
  80. package/agent-packs/templates/personal/agents/intakes/personal-intake/AGENTS.md +21 -0
  81. package/agent-packs/templates/personal/agents/specialists/correspondence/AGENTS.md +21 -0
  82. package/agent-packs/templates/personal/agents/specialists/document-assistant/AGENTS.md +21 -0
  83. package/agent-packs/templates/personal/agents/specialists/planning/AGENTS.md +21 -0
  84. package/agent-packs/templates/personal/agents/specialists/research/AGENTS.md +21 -0
  85. package/agent-packs/templates/personal/agents/specialists/travel-logistics/AGENTS.md +21 -0
  86. package/agent-packs/templates/personal/pack.json +125 -0
  87. package/agent-packs/templates/personal/shared/PACK.md +22 -0
  88. package/agent-packs/templates/personal/shared/TOPOLO.md +13 -0
  89. package/agent-packs/templates/personal/shared/WORKFLOW.md +13 -0
  90. package/agent-packs/templates/personal/skills/topolo/SKILL.md +305 -0
  91. package/agent-packs/templates/research/AGENTS.md +17 -0
  92. package/agent-packs/templates/research/README.md +14 -0
  93. package/agent-packs/templates/research/agents/intakes/research-intake/AGENTS.md +21 -0
  94. package/agent-packs/templates/research/agents/specialists/adversarial-review/AGENTS.md +21 -0
  95. package/agent-packs/templates/research/agents/specialists/data-analysis/AGENTS.md +21 -0
  96. package/agent-packs/templates/research/agents/specialists/source-research/AGENTS.md +21 -0
  97. package/agent-packs/templates/research/agents/specialists/synthesis/AGENTS.md +21 -0
  98. package/agent-packs/templates/research/agents/specialists/technical-research/AGENTS.md +21 -0
  99. package/agent-packs/templates/research/pack.json +124 -0
  100. package/agent-packs/templates/research/shared/PACK.md +22 -0
  101. package/agent-packs/templates/research/shared/TOPOLO.md +13 -0
  102. package/agent-packs/templates/research/shared/WORKFLOW.md +13 -0
  103. package/agent-packs/templates/research/skills/topolo/SKILL.md +305 -0
  104. package/agent-packs/templates/ventures/AGENTS.md +17 -0
  105. package/agent-packs/templates/ventures/README.md +14 -0
  106. package/agent-packs/templates/ventures/agents/intakes/venture-intake/AGENTS.md +21 -0
  107. package/agent-packs/templates/ventures/agents/specialists/customer-discovery/AGENTS.md +21 -0
  108. package/agent-packs/templates/ventures/agents/specialists/economics/AGENTS.md +21 -0
  109. package/agent-packs/templates/ventures/agents/specialists/experiment-design/AGENTS.md +21 -0
  110. package/agent-packs/templates/ventures/agents/specialists/market-research/AGENTS.md +21 -0
  111. package/agent-packs/templates/ventures/agents/specialists/product-concept/AGENTS.md +21 -0
  112. package/agent-packs/templates/ventures/pack.json +126 -0
  113. package/agent-packs/templates/ventures/shared/PACK.md +22 -0
  114. package/agent-packs/templates/ventures/shared/TOPOLO.md +13 -0
  115. package/agent-packs/templates/ventures/shared/WORKFLOW.md +13 -0
  116. package/agent-packs/templates/ventures/skills/topolo/SKILL.md +305 -0
  117. package/agent-packs/topolo-agent-pack +8 -0
  118. package/dist/index.js +119 -51
  119. package/package.json +7 -4
package/dist/index.js CHANGED
@@ -1,7 +1,54 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // src/commands/agent-packs.ts
4
+ import { spawnSync } from "child_process";
5
+ import { existsSync } from "fs";
6
+ import { dirname, resolve } from "path";
7
+ import { fileURLToPath } from "url";
8
+ function registerAgentPacksCommand(program2) {
9
+ const packs = program2.command("agent-packs").description("Install and operate Topolo Agent Packs in supported local hosts").option("--store <path>", "Portable pack library (default ~/AgentPacks)");
10
+ const commands = [
11
+ "add",
12
+ "replace",
13
+ "switch",
14
+ "capture",
15
+ "build",
16
+ "install",
17
+ "export",
18
+ "status",
19
+ "list",
20
+ "recover",
21
+ "doctor",
22
+ "remote-recover",
23
+ "connect",
24
+ "remote-context",
25
+ "remember",
26
+ "artifact",
27
+ "artifact-get"
28
+ ];
29
+ for (const name of commands) {
30
+ packs.command(name).description(name === "add" ? "Add an installed or bundled pack, group, or agent" : `Run the pack ${name} operation`).option("--harness <name>", "Local host adapter (currently codex)", "codex").option("--adapter-help", "Show every option supported by the selected adapter").argument("[arguments...]").allowUnknownOption().allowExcessArguments().addHelpText("after", name === "add" ? "\nExamples:\n topolo agent-packs add founder\n topolo agent-packs add founder --group specialists\n topolo agent-packs add founder --agent strategy\n" : "\nRun topolo agent-packs <command> --adapter-help for all adapter options. Cloud commands require explicit --environment and --context-key.\n").action((args, options) => {
31
+ if (options.harness !== "codex") throw new Error(`The ${options.harness} pack adapter is not available. Only Codex switching has been verified.`);
32
+ const here = dirname(fileURLToPath(import.meta.url));
33
+ const adapter = [resolve(here, "../agent-packs/topolo-agent-pack"), resolve(here, "../../agent-packs/topolo-agent-pack")].find(existsSync);
34
+ if (!adapter) throw new Error("This CLI installation is missing its bundled Topolo Agent Pack adapter. Reinstall @topolo/cli.");
35
+ const store = packs.opts().store;
36
+ const forwarded = (options.adapterHelp ? ["--help"] : args).map((value) => value === "--group" ? "--set" : value);
37
+ const result = spawnSync("python3", [
38
+ adapter,
39
+ ...store ? ["--store", store] : [],
40
+ name,
41
+ ...forwarded,
42
+ ...name === "add" && !options.adapterHelp ? ["--catalog"] : []
43
+ ], { stdio: "inherit", env: { ...process.env, PYTHONDONTWRITEBYTECODE: "1", TOPOLO_AGENT_PACK_PUBLIC_CLI: "1" } });
44
+ if (result.error) throw new Error(`Python 3.11 or later is required for local packs: ${result.error.message}`);
45
+ if (result.status !== 0) process.exitCode = result.status ?? 2;
46
+ });
47
+ }
48
+ }
49
+
3
50
  // src/index.ts
4
- import { Command } from "commander";
51
+ import { Command, Help } from "commander";
5
52
 
6
53
  // src/commands/auth.ts
7
54
  import { spawn } from "child_process";
@@ -1592,7 +1639,7 @@ var TopoloClient = class _TopoloClient {
1592
1639
  } catch (error) {
1593
1640
  const transportFailure = !(error instanceof TopoloSdkError) && !opts.signal?.aborted;
1594
1641
  if (!transportFailure || attempt === maxAttempts) throw error;
1595
- await new Promise((resolve3) => setTimeout(resolve3, 250));
1642
+ await new Promise((resolve4) => setTimeout(resolve4, 250));
1596
1643
  }
1597
1644
  }
1598
1645
  throw new TopoloSdkError("network_error", "Topolo read retry loop exhausted.");
@@ -3582,7 +3629,7 @@ function createTopolo(options) {
3582
3629
  async function pollUntilApproved(params) {
3583
3630
  let interval = Math.max(params.intervalSeconds ?? 5, 1);
3584
3631
  while (Date.now() < params.expiresAtMs) {
3585
- await new Promise((resolve3) => setTimeout(resolve3, Math.min(interval * 1e3, params.expiresAtMs - Date.now())));
3632
+ await new Promise((resolve4) => setTimeout(resolve4, Math.min(interval * 1e3, params.expiresAtMs - Date.now())));
3586
3633
  if (Date.now() >= params.expiresAtMs) break;
3587
3634
  try {
3588
3635
  return await params.oauth.pollDeviceToken({
@@ -3617,11 +3664,11 @@ import { homedir as homedir2, platform } from "os";
3617
3664
  import { dirname as dirname2, join as join3 } from "path";
3618
3665
  import { createHash, randomUUID } from "crypto";
3619
3666
  import { join as join2 } from "path";
3620
- import { spawnSync } from "child_process";
3667
+ import { spawnSync as spawnSync2 } from "child_process";
3621
3668
  import { mkdir, readFile, readdir, rename, rm, writeFile, chmod } from "fs/promises";
3622
- import { existsSync } from "fs";
3669
+ import { existsSync as existsSync3 } from "fs";
3623
3670
  import { homedir, platform as hostPlatform } from "os";
3624
- import { dirname, join } from "path";
3671
+ import { dirname as dirname3, join } from "path";
3625
3672
  var TopoloSdkError2 = class extends Error {
3626
3673
  code;
3627
3674
  constructor(code, message2) {
@@ -4068,7 +4115,7 @@ function runOrThrow(result, operation) {
4068
4115
  }
4069
4116
  function createPlatformInstallationSecretBackend(options = {}) {
4070
4117
  const platform22 = options.platform ?? hostPlatform();
4071
- const spawn3 = options.spawn ?? ((command, args, spawnOptions) => spawnSync(command, args, spawnOptions));
4118
+ const spawn3 = options.spawn ?? ((command, args, spawnOptions) => spawnSync2(command, args, spawnOptions));
4072
4119
  const root = options.root ?? installationStorePath();
4073
4120
  const service = options.service ?? KEYCHAIN_SERVICE;
4074
4121
  if (platform22 === "darwin") {
@@ -4187,13 +4234,13 @@ function createPlatformInstallationSecretBackend(options = {}) {
4187
4234
  return {
4188
4235
  async set(account, value) {
4189
4236
  const path = secretPath(account);
4190
- await mkdir(dirname(path), { recursive: true });
4237
+ await mkdir(dirname3(path), { recursive: true });
4191
4238
  const script = "$p=$env:TOPOLO_SECRET_PATH;$v=[Console]::In.ReadToEnd();$b=[Text.Encoding]::UTF8.GetBytes($v);$e=[Security.Cryptography.ProtectedData]::Protect($b,$null,[Security.Cryptography.DataProtectionScope]::CurrentUser);[IO.File]::WriteAllBytes($p,$e)";
4192
4239
  runOrThrow(powershell(script, path, value), "Windows DPAPI write");
4193
4240
  },
4194
4241
  async get(account) {
4195
4242
  const path = secretPath(account);
4196
- if (!existsSync(path)) return null;
4243
+ if (!existsSync3(path)) return null;
4197
4244
  const script = "$p=$env:TOPOLO_SECRET_PATH;$b=[IO.File]::ReadAllBytes($p);$d=[Security.Cryptography.ProtectedData]::Unprotect($b,$null,[Security.Cryptography.DataProtectionScope]::CurrentUser);[Console]::Out.Write([Text.Encoding]::UTF8.GetString($d))";
4198
4245
  return runOrThrow(powershell(script, path), "Windows DPAPI read");
4199
4246
  },
@@ -4209,7 +4256,7 @@ async function writeExternalAgentInstallation(installation, secret, backend = cr
4209
4256
  await backend.set(accountName(installation.environment, installation.id), JSON.stringify(secret));
4210
4257
  const temporary = `${path}.${process.pid}.tmp`;
4211
4258
  try {
4212
- await mkdir(dirname(path), { recursive: true, mode: 448 });
4259
+ await mkdir(dirname3(path), { recursive: true, mode: 448 });
4213
4260
  await writeFile(temporary, `${JSON.stringify(installation, null, 2)}
4214
4261
  `, { encoding: "utf8", mode: 384 });
4215
4262
  await rename(temporary, path);
@@ -4222,7 +4269,7 @@ async function writeExternalAgentInstallation(installation, secret, backend = cr
4222
4269
  }
4223
4270
  async function listExternalAgentInstallations(environment) {
4224
4271
  const directory = join(installationStorePath(), environment);
4225
- if (!existsSync(directory)) return [];
4272
+ if (!existsSync3(directory)) return [];
4226
4273
  const entries = await readdir(directory, { withFileTypes: true });
4227
4274
  const installations = await Promise.all(entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map(async (entry) => JSON.parse(await readFile(join(directory, entry.name), "utf8"))));
4228
4275
  return installations.sort((left, right) => left.createdAt.localeCompare(right.createdAt));
@@ -4493,7 +4540,7 @@ async function withConfigWriteLock(operation) {
4493
4540
  if (Date.now() - startedAt >= CONFIG_LOCK_TIMEOUT_MS) {
4494
4541
  throw new Error(`Timed out waiting for credential configuration lock at ${lockPath}.`);
4495
4542
  }
4496
- await new Promise((resolve3) => setTimeout(resolve3, CONFIG_LOCK_RETRY_MS));
4543
+ await new Promise((resolve4) => setTimeout(resolve4, CONFIG_LOCK_RETRY_MS));
4497
4544
  }
4498
4545
  }
4499
4546
  try {
@@ -4765,11 +4812,11 @@ function normalizeError(err) {
4765
4812
 
4766
4813
  // src/version.ts
4767
4814
  import { readFileSync } from "fs";
4768
- import { dirname as dirname3, join as join4 } from "path";
4769
- import { fileURLToPath } from "url";
4815
+ import { dirname as dirname4, join as join4 } from "path";
4816
+ import { fileURLToPath as fileURLToPath2 } from "url";
4770
4817
  function readCliVersion() {
4771
4818
  try {
4772
- const here = dirname3(fileURLToPath(import.meta.url));
4819
+ const here = dirname4(fileURLToPath2(import.meta.url));
4773
4820
  const candidates = [
4774
4821
  join4(here, "package.json"),
4775
4822
  join4(here, "..", "package.json")
@@ -6076,17 +6123,17 @@ function formatCheckResult(result) {
6076
6123
  }
6077
6124
 
6078
6125
  // src/commands/skills.ts
6079
- import { spawnSync as spawnSync3 } from "child_process";
6080
- import { existsSync as existsSync5 } from "fs";
6126
+ import { spawnSync as spawnSync4 } from "child_process";
6127
+ import { existsSync as existsSync6 } from "fs";
6081
6128
  import { readFile as readFile6, rm as rm3 } from "fs/promises";
6082
6129
  import { homedir as homedir4 } from "os";
6083
- import { dirname as dirname5, join as join7, resolve } from "path";
6084
- import { fileURLToPath as fileURLToPath2 } from "url";
6130
+ import { dirname as dirname6, join as join7, resolve as resolve2 } from "path";
6131
+ import { fileURLToPath as fileURLToPath3 } from "url";
6085
6132
  import { createRequire } from "module";
6086
6133
 
6087
6134
  // src/commands/agent-host.ts
6088
- import { spawnSync as spawnSync2 } from "child_process";
6089
- import { existsSync as existsSync3 } from "fs";
6135
+ import { spawnSync as spawnSync3 } from "child_process";
6136
+ import { existsSync as existsSync4 } from "fs";
6090
6137
  import { readFile as readFile4 } from "fs/promises";
6091
6138
  import { homedir as homedir3 } from "os";
6092
6139
  import { isAbsolute, join as join6 } from "path";
@@ -6138,7 +6185,7 @@ function selectStableNodeCommand(whichOutput, fallback = process.execPath) {
6138
6185
  return candidate && isAbsolute(candidate) ? candidate : fallback;
6139
6186
  }
6140
6187
  function stableNodeCommand() {
6141
- const probe = spawnSync2(process.platform === "win32" ? "where" : "which", ["node"], {
6188
+ const probe = spawnSync3(process.platform === "win32" ? "where" : "which", ["node"], {
6142
6189
  encoding: "utf8",
6143
6190
  stdio: ["ignore", "pipe", "ignore"]
6144
6191
  });
@@ -6229,7 +6276,7 @@ function agentConfigPaths(agent, homeDir = homedir3(), projectDir) {
6229
6276
  return [{ path: join6(projectDir, ".amazonq", "mcp.json"), format: "json", rootKey: "mcpServers" }];
6230
6277
  }
6231
6278
  return [{
6232
- path: existsSync3(join6(homeDir, ".aws", "amazonq", "mcp.json")) ? join6(homeDir, ".aws", "amazonq", "mcp.json") : join6(homeDir, ".aws", "amazonq", "default.json"),
6279
+ path: existsSync4(join6(homeDir, ".aws", "amazonq", "mcp.json")) ? join6(homeDir, ".aws", "amazonq", "mcp.json") : join6(homeDir, ".aws", "amazonq", "default.json"),
6233
6280
  format: "json",
6234
6281
  rootKey: "mcpServers"
6235
6282
  }];
@@ -6262,7 +6309,7 @@ function agentCliNames(agent) {
6262
6309
  }
6263
6310
  }
6264
6311
  function agentConfigExists(agent, homeDir = homedir3(), projectDir) {
6265
- return agentConfigPaths(agent, homeDir, projectDir).some((config) => existsSync3(config.path));
6312
+ return agentConfigPaths(agent, homeDir, projectDir).some((config) => existsSync4(config.path));
6266
6313
  }
6267
6314
  function claudeDesktopConfigPath(homeDir) {
6268
6315
  if (process.platform === "darwin") return join6(homeDir, "Library", "Application Support", "Claude", "claude_desktop_config.json");
@@ -6277,7 +6324,7 @@ function vscodeUserConfigPath(homeDir) {
6277
6324
  async function readAgentRegistrations(agent, homeDir = homedir3(), projectDir) {
6278
6325
  const registrations = [];
6279
6326
  for (const config of agentConfigPaths(agent, homeDir, projectDir)) {
6280
- if (!existsSync3(config.path)) continue;
6327
+ if (!existsSync4(config.path)) continue;
6281
6328
  if (config.format === "json") {
6282
6329
  registrations.push(...await readJsonRegistrations(config.path, config.rootKey ?? "mcpServers", agent));
6283
6330
  } else if (config.format === "toml") {
@@ -6538,9 +6585,9 @@ function message(error) {
6538
6585
  }
6539
6586
 
6540
6587
  // src/commands/agent-config.ts
6541
- import { existsSync as existsSync4 } from "fs";
6588
+ import { existsSync as existsSync5 } from "fs";
6542
6589
  import { mkdir as mkdir3, readFile as readFile5, rename as rename2, writeFile as writeFile3 } from "fs/promises";
6543
- import { dirname as dirname4 } from "path";
6590
+ import { dirname as dirname5 } from "path";
6544
6591
  async function installAgentSkill(agent, source, homeDir, projectDir) {
6545
6592
  const path = agentSkillPath(agent, homeDir, projectDir);
6546
6593
  if (!path) return { installed: false };
@@ -6561,7 +6608,7 @@ async function registerAgentConfig(agent, mcp, homeDir, registration, projectDir
6561
6608
  }
6562
6609
  async function unregisterAgentConfig(agent, homeDir, name, projectDir) {
6563
6610
  for (const config of agentConfigPaths(agent, homeDir, projectDir)) {
6564
- if (!existsSync4(config.path)) continue;
6611
+ if (!existsSync5(config.path)) continue;
6565
6612
  if (config.format === "json") {
6566
6613
  await unregisterJson(config, agent, name);
6567
6614
  } else if (config.format === "toml") {
@@ -6581,7 +6628,7 @@ function registrationEnvironment(agent, registration) {
6581
6628
  }
6582
6629
  async function registerJson(config, agent, mcp, registration) {
6583
6630
  let parsed = {};
6584
- if (existsSync4(config.path)) {
6631
+ if (existsSync5(config.path)) {
6585
6632
  try {
6586
6633
  parsed = JSON.parse(await readFile5(config.path, "utf8"));
6587
6634
  } catch (error) {
@@ -6626,7 +6673,7 @@ async function unregisterJson(config, agent, name) {
6626
6673
  await atomicWrite(config.path, JSON.stringify(parsed, null, 2) + "\n");
6627
6674
  }
6628
6675
  async function registerToml(path, agent, mcp, registration) {
6629
- const existing = existsSync4(path) ? await readFile5(path, "utf8") : "";
6676
+ const existing = existsSync5(path) ? await readFile5(path, "utf8") : "";
6630
6677
  const text2 = withoutMcpServerSections(existing, registration.name);
6631
6678
  const args = mcp.args.length ? "\nargs = [" + mcp.args.map((item) => JSON.stringify(item)).join(", ") + "]" : "";
6632
6679
  const environment = registrationEnvironment(agent, registration);
@@ -6635,7 +6682,7 @@ async function registerToml(path, agent, mcp, registration) {
6635
6682
  await atomicWrite(path, text2 + block);
6636
6683
  }
6637
6684
  async function registerGoose(path, mcp, registration) {
6638
- const existing = existsSync4(path) ? await readFile5(path, "utf8") : "";
6685
+ const existing = existsSync5(path) ? await readFile5(path, "utf8") : "";
6639
6686
  const withoutTopolo = removeGooseExtension(existing, registration.name);
6640
6687
  const environment = registrationEnvironment("goose", registration);
6641
6688
  const block = [
@@ -6703,7 +6750,7 @@ function formatSkillForAgent(agent, source) {
6703
6750
  return "---\ntrigger: model_decision\ndescription: Use Topolo MCP for Topolo platform operations.\n---\n\n" + body;
6704
6751
  }
6705
6752
  async function atomicWrite(path, contents) {
6706
- await mkdir3(dirname4(path), { recursive: true });
6753
+ await mkdir3(dirname5(path), { recursive: true });
6707
6754
  const temporaryPath = path + ".topolo-" + process.pid + ".tmp";
6708
6755
  await writeFile3(temporaryPath, contents, { encoding: "utf8", mode: 384 });
6709
6756
  await rename2(temporaryPath, path);
@@ -6726,11 +6773,11 @@ function withoutMcpServerSections(text2, name) {
6726
6773
  // src/commands/skills.ts
6727
6774
  var AGENT_LABELS2 = AGENT_LABELS;
6728
6775
  function skillsSourceDir() {
6729
- const here = dirname5(fileURLToPath2(import.meta.url));
6730
- const distCandidate = resolve(here, "../skills");
6731
- const srcCandidate = resolve(here, "../../skills");
6776
+ const here = dirname6(fileURLToPath3(import.meta.url));
6777
+ const distCandidate = resolve2(here, "../skills");
6778
+ const srcCandidate = resolve2(here, "../../skills");
6732
6779
  for (const candidate of [distCandidate, srcCandidate]) {
6733
- if (existsSync5(join7(candidate, "topolo", "SKILL.md"))) return candidate;
6780
+ if (existsSync6(join7(candidate, "topolo", "SKILL.md"))) return candidate;
6734
6781
  }
6735
6782
  return distCandidate;
6736
6783
  }
@@ -6740,7 +6787,7 @@ function resolveMcpCommand() {
6740
6787
  }
6741
6788
  function agentBinaryExists(agent) {
6742
6789
  return agentCliNames(agent).some((bin) => {
6743
- const probe = spawnSync3(process.platform === "win32" ? "where" : "which", [bin], {
6790
+ const probe = spawnSync4(process.platform === "win32" ? "where" : "which", [bin], {
6744
6791
  stdio: "ignore"
6745
6792
  });
6746
6793
  return probe.status === 0;
@@ -6839,7 +6886,7 @@ function registerSkillsCommand(program2) {
6839
6886
  const mode = resolveOutputMode(opts.json);
6840
6887
  try {
6841
6888
  const rows = await agentSurfaceStatus({
6842
- homeDir: opts.agentHome ? resolve(opts.agentHome) : void 0,
6889
+ homeDir: opts.agentHome ? resolve2(opts.agentHome) : void 0,
6843
6890
  name: opts.name,
6844
6891
  agent: opts.agent,
6845
6892
  all: opts.all,
@@ -6855,7 +6902,7 @@ function registerSkillsCommand(program2) {
6855
6902
  try {
6856
6903
  const removed = await uninstallAgentSurfaces({
6857
6904
  ...opts,
6858
- homeDir: opts.agentHome ? resolve(opts.agentHome) : void 0
6905
+ homeDir: opts.agentHome ? resolve2(opts.agentHome) : void 0
6859
6906
  });
6860
6907
  emit(
6861
6908
  { removed },
@@ -6869,7 +6916,7 @@ function registerSkillsCommand(program2) {
6869
6916
  }
6870
6917
  async function installAgentSurfaces(opts) {
6871
6918
  const sourceDir = skillsSourceDir();
6872
- if (!existsSync5(join7(sourceDir, "topolo", "SKILL.md"))) {
6919
+ if (!existsSync6(join7(sourceDir, "topolo", "SKILL.md"))) {
6873
6920
  throw new Error("Bundled skill file not found. Reinstall the CLI: npm install -g @topolo/cli");
6874
6921
  }
6875
6922
  const mcp = resolveMcpCommand();
@@ -6919,7 +6966,7 @@ async function agentSurfaceStatus(options = {}) {
6919
6966
  });
6920
6967
  return Promise.all(agents.map(async (agent) => {
6921
6968
  const skillPath = agentSkillPath(agent, homeDir, options.project);
6922
- const installedSkill = skillPath && existsSync5(skillPath) ? await readFile6(skillPath, "utf8") : void 0;
6969
+ const installedSkill = skillPath && existsSync6(skillPath) ? await readFile6(skillPath, "utf8") : void 0;
6923
6970
  const registrations = (await readAgentRegistrations(agent, homeDir, options.project)).filter((registration) => !options.name || registration.name === options.name);
6924
6971
  return {
6925
6972
  agent,
@@ -6943,8 +6990,8 @@ async function uninstallAgentSurfaces(options) {
6943
6990
  await unregisterAgentConfig(agent, homeDir, name, options.project);
6944
6991
  const remaining = await readAgentRegistrations(agent, homeDir, options.project);
6945
6992
  const skillPath = agentSkillPath(agent, homeDir, options.project);
6946
- const skillRemoved = remaining.length === 0 && Boolean(skillPath && existsSync5(skillPath));
6947
- if (skillRemoved && skillPath) await rm3(dirname5(skillPath), { recursive: true, force: true });
6993
+ const skillRemoved = remaining.length === 0 && Boolean(skillPath && existsSync6(skillPath));
6994
+ if (skillRemoved && skillPath) await rm3(dirname6(skillPath), { recursive: true, force: true });
6948
6995
  removed.push({ agent, name, registrationRemoved, skillRemoved });
6949
6996
  }
6950
6997
  return removed;
@@ -6975,7 +7022,7 @@ function formatStatus(rows) {
6975
7022
  // src/commands/doctor.ts
6976
7023
  import { access } from "fs/promises";
6977
7024
  import { homedir as homedir5 } from "os";
6978
- import { resolve as resolve2 } from "path";
7025
+ import { resolve as resolve3 } from "path";
6979
7026
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
6980
7027
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
6981
7028
  var defaultDependencies = {
@@ -7037,7 +7084,7 @@ async function verifyMcpProtocol(command, args, env = definedEnvironment(process
7037
7084
  }
7038
7085
  async function resolveInstalledDoctorTarget(options) {
7039
7086
  const name = options.name?.trim() || "topolo";
7040
- const homeDir = options.agentHome ? resolve2(options.agentHome) : homedir5();
7087
+ const homeDir = options.agentHome ? resolve3(options.agentHome) : homedir5();
7041
7088
  const expected = resolveMcpCommand();
7042
7089
  const requestedAgents = resolveTargets({
7043
7090
  ...options,
@@ -7694,12 +7741,15 @@ try {
7694
7741
  }
7695
7742
  var environmentWasStated = Boolean(inheritedEnvironment) || environmentArgSeen;
7696
7743
  program.name("topolo").description(
7697
- "Public Topolo CLI for customer identity, organization context, applications, resources, and actions."
7698
- ).version(CLI_VERSION).option("--env <environment>", "Topolo environment: production, staging, development, or local");
7744
+ "Use Topolo from your terminal: sign in, find your apps, and run actions.\n\nQuick start (copy a command, then press Enter):\n topolo auth login # Sign in with your browser\n topolo whoami # See who you are signed in as\n topolo apps --no-json # List your apps as a readable table\n topolo auth --help # See sign-in commands\n topolo help apps # See app commands and options"
7745
+ ).version(CLI_VERSION).option("--env <environment>", "Topolo environment: production, staging, development, or local").addHelpText("beforeAll", '\nEvery command starts with "topolo". Running "topolo" alone prints help; it does not open an interactive prompt.\n').addHelpText("afterAll", "\nHelp notation: [brackets] mean optional; <angle brackets> mark a value to replace. Do not type the brackets.");
7699
7746
  program.hook("preAction", async (thisCommand, actionCommand) => {
7700
7747
  const opts = thisCommand.opts();
7701
7748
  if (opts.env) process.env.TOPOLO_ENV = normalizeEnvironment(opts.env);
7702
7749
  if (opts.env || environmentWasStated) return;
7750
+ for (let node = actionCommand; node; node = node.parent) {
7751
+ if (node.name() === "agent-packs") return;
7752
+ }
7703
7753
  const authenticated = await authenticatedEnvironments();
7704
7754
  if (authenticated.length < 2) return;
7705
7755
  const path = [];
@@ -7733,11 +7783,29 @@ registerContextCommand(program);
7733
7783
  registerResourcesCommand(program);
7734
7784
  registerWorkspacesCommand(program);
7735
7785
  registerInstallationsCommand(program);
7736
- program.parseAsync(argv).catch((err) => {
7737
- process.stderr.write(`Unexpected error: ${err instanceof Error ? err.message : String(err)}
7786
+ registerAgentPacksCommand(program);
7787
+ var helpCommands = [program];
7788
+ for (const command of helpCommands) {
7789
+ command.configureHelp({
7790
+ subcommandTerm(subcommand) {
7791
+ const parents = [];
7792
+ for (let parent = subcommand.parent ?? command; parent; parent = parent.parent) {
7793
+ parents.unshift(parent.name());
7794
+ }
7795
+ return [...parents, new Help().subcommandTerm(subcommand)].join(" ");
7796
+ }
7797
+ });
7798
+ helpCommands.push(...command.commands);
7799
+ }
7800
+ if (argv.length === 2) {
7801
+ program.outputHelp();
7802
+ } else {
7803
+ program.parseAsync(argv).catch((err) => {
7804
+ process.stderr.write(`Unexpected error: ${err instanceof Error ? err.message : String(err)}
7738
7805
  `);
7739
- process.exit(1);
7740
- });
7806
+ process.exit(1);
7807
+ });
7808
+ }
7741
7809
  function consumeEnvironmentArg(argv2) {
7742
7810
  const next = argv2.slice(0, 2);
7743
7811
  for (let i = 2; i < argv2.length; i += 1) {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@topolo/cli",
3
3
  "packageManager": "pnpm@10.17.1",
4
- "version": "0.12.32",
5
- "topoloPublishedVersion": "0.12.32",
4
+ "version": "0.13.0",
5
+ "topoloPublishedVersion": "0.13.0",
6
6
  "description": "Public command-line interface for Topolo customer organizations, developers, and agents.",
7
7
  "license": "UNLICENSED",
8
8
  "author": "Topolo",
@@ -14,7 +14,8 @@
14
14
  "files": [
15
15
  "dist",
16
16
  "skills",
17
- "postinstall.mjs"
17
+ "postinstall.mjs",
18
+ "agent-packs"
18
19
  ],
19
20
  "scripts": {
20
21
  "postinstall": "node postinstall.mjs",
@@ -24,7 +25,9 @@
24
25
  "start": "node dist/index.js",
25
26
  "test": "vitest run",
26
27
  "test:watch": "vitest",
27
- "coverage": "vitest run --coverage"
28
+ "coverage": "pnpm run coverage:node && pnpm run coverage:adapter",
29
+ "coverage:node": "vitest run --coverage",
30
+ "coverage:adapter": "python3 -m venv node_modules/.cache/agent-pack-test && node_modules/.cache/agent-pack-test/bin/python -m pip install --disable-pip-version-check --quiet --timeout 15 --retries 0 -r agent-packs/requirements-test.txt && PYTHONPATH=agent-packs/src COVERAGE_FILE=node_modules/.cache/agent-pack-test/.coverage node_modules/.cache/agent-pack-test/bin/python -m coverage run --branch --source=topolo_agent_pack.topolo -m unittest discover -s agent-packs/tests && COVERAGE_FILE=node_modules/.cache/agent-pack-test/.coverage node_modules/.cache/agent-pack-test/bin/python -m coverage report --fail-under=100"
28
31
  },
29
32
  "dependencies": {
30
33
  "@modelcontextprotocol/sdk": "^1.0.0",