registry.ts 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * Registry of all known agent targets.
  3. *
  4. * Adding a new target = create `targets/<id>.ts` exporting an
  5. * `AgentTarget`, then add it to the array below. Order here is the
  6. * order they appear in the multiselect prompt, in `--target=all`,
  7. * and in `--print-config`'s help listing — keep it stable.
  8. */
  9. import { AgentTarget, Location, TargetId } from './types';
  10. import { claudeTarget } from './claude';
  11. import { cursorTarget } from './cursor';
  12. import { codexTarget } from './codex';
  13. import { opencodeTarget } from './opencode';
  14. import { hermesTarget } from './hermes';
  15. import { geminiTarget } from './gemini';
  16. import { antigravityTarget } from './antigravity';
  17. import { kiroTarget } from './kiro';
  18. import { copilotVscodeTarget } from './copilot-vscode';
  19. import { copilotCliTarget } from './copilot-cli';
  20. import { copilotJetbrainsTarget } from './copilot-jetbrains';
  21. export const ALL_TARGETS: readonly AgentTarget[] = Object.freeze([
  22. claudeTarget,
  23. cursorTarget,
  24. codexTarget,
  25. opencodeTarget,
  26. hermesTarget,
  27. geminiTarget,
  28. antigravityTarget,
  29. kiroTarget,
  30. copilotVscodeTarget,
  31. copilotCliTarget,
  32. copilotJetbrainsTarget,
  33. ]);
  34. export function getTarget(id: string): AgentTarget | undefined {
  35. return ALL_TARGETS.find((t) => t.id === id);
  36. }
  37. export function listTargetIds(): TargetId[] {
  38. return ALL_TARGETS.map((t) => t.id);
  39. }
  40. /**
  41. * Run `detect()` for every target at the given location. Returns the
  42. * full registry zipped with detection results — orchestrator uses
  43. * this to seed the multiselect prompt with installed agents
  44. * pre-checked.
  45. */
  46. export function detectAll(loc: Location): Array<{
  47. target: AgentTarget;
  48. detection: ReturnType<AgentTarget['detect']>;
  49. }> {
  50. return ALL_TARGETS.map((target) => ({
  51. target,
  52. detection: target.detect(loc),
  53. }));
  54. }
  55. /**
  56. * Resolve a `--target=` flag value to a list of `AgentTarget`
  57. * instances. Accepts:
  58. *
  59. * - `auto` — return all targets whose `detect().installed` is true,
  60. * or `['claude']` as a fallback if none detected (least-surprise
  61. * for existing users).
  62. * - `all` — every target in the registry.
  63. * - `none` — empty list (caller skips agent writes entirely).
  64. * - csv list — `'claude,cursor'` etc. Unknown ids throw.
  65. */
  66. export function resolveTargetFlag(value: string, loc: Location): AgentTarget[] {
  67. if (value === 'none') return [];
  68. if (value === 'all') return [...ALL_TARGETS];
  69. if (value === 'auto') {
  70. const detected = detectAll(loc).filter(({ detection }) => detection.installed);
  71. if (detected.length > 0) return detected.map(({ target }) => target);
  72. const fallback = getTarget('claude');
  73. return fallback ? [fallback] : [];
  74. }
  75. const ids = value.split(',').map((s) => s.trim()).filter(Boolean);
  76. const resolved: AgentTarget[] = [];
  77. const unknown: string[] = [];
  78. for (const id of ids) {
  79. const t = getTarget(id);
  80. if (t) resolved.push(t);
  81. else unknown.push(id);
  82. }
  83. if (unknown.length > 0) {
  84. const known = listTargetIds().join(', ');
  85. throw new Error(
  86. `Unknown --target id(s): ${unknown.join(', ')}. Known: ${known}, plus 'auto' / 'all' / 'none'.`,
  87. );
  88. }
  89. return resolved;
  90. }