SLOPSHOPPER

named-subagents-mod

Gives every subagent a themed name in the task tree (display only; the agent is not told its name).

newguardtoaststatusagents
v0.0.1MITupdated 2026-10-06Bobby-cell-commits/named-subagents/mod
A shopper browsing a rack in a slop shop
README

named-subagents mod (experimental, unreleased)

Moved (2026-10-06) to named-subagents-mod. This folder is the last copy kept here (0bbd5c3) and is not updated.

A Claude Code mod (function hooks, CC 2.1.287+) that gives every subagent a themed name in the task tree, drawn from the same 395-name registry as the Python package. Names only: the agent is not told its name (the engine does not put a mod-set name into the subagent's context), so there is no SubagentStart queue, ledger or file lock, and no burst-start pairing to get wrong.

What it does

  • tool.call{Agent}: if the call has no name, draws one and calls next({ ...e, name }). The description is left as is. A model-supplied name passes through untouched.
  • Pool: the theme option pins one; auto matches subagent_type first (generic roles like general-purpose go by description keywords first), then the default pool. Same order as the Python resolve_for_hook.
  • Uniqueness: skips every name in $.agent.list() and every in-flight draw. An exhausted pool spills to the default pool, then to any free name, then to Name-2, Name-3, …
  • agent.spawn: after the spawn, checks the name reached it and that $.agent.list() shows it on the new agent id. Anything else raises a toast and a status line (named-subagents: drew X but …). Neither hook can block a dispatch: both carry a .catch that continues the call.

Options (userConfig)

FieldDefaultMeaning
themeautoauto, or a category key (code, explore, debug, …) to always use that pool
enabledtruefalse turns naming off without uninstalling

Layout

  • hooks/names.ts: the hooks module. hooks/draw.ts: pure draw logic. hooks/pool.ts: generated.
  • scripts/gen_pool.mjs: regenerates hooks/pool.ts from named_subagents/registry.json; --check exits 1 when it is stale.

Checks

node mod/scripts/gen_pool.mjs --check   # pool matches the registry
node --test mod/spec/*.spec.ts          # draw logic, plain node (18 tests)
claude plugin test mod                  # hooks against the engine's test kit (7 tests)
claude plugin validate mod

Run it

claude --plugin-dir mod for one session, or install it for every session from this folder (.claude-plugin/marketplace.json makes mod/ a local marketplace; edits apply after /reload-plugins):

claude plugin marketplace add ~/Dev/named-subagents/mod
claude plugin install named-subagents-mod@named-subagents-dev --scope user

Known limits

  • The name shows in the task tree and in $.agent.list(); the transcript's launch list and finish notices quote the description only.
  • With the 0.7.2 Python plugin also enabled, the mod's name wins, but the Python hooks still run (see probes/mods-names-proof/README.md).
  • Mods API is early access; tested on CC 2.1.291 only.
Source 3 files
hooks/names.ts 76 lines
1// named-subagents mod: every Agent dispatch without a model-supplied `name` gets one from
2// the themed pool, so the task tree labels it. The name is display-only: the engine does
3// not put it in the subagent's context, so there is no ledger, queue or file lock.
4//
5// tool.call{Agent}  draws a name not held by a listed agent or an in-flight draw, and
6//                   sets it on the call; the description is left as is.
7// agent.spawn       checks the name reached the spawn and that $.agent.list() shows it
8//                   on the new id; anything else raises a toast.
9
10import type { Register, EngineInterface } from 'claude-code';
11import { pickName } from './draw.ts';
12import { POOL } from './pool.ts';
13
14const TAG = 'named-subagents';
15
16// Drawn but not yet settled. JS runs the draw and the reserve with no await between them,
17// so parallel dispatches in one message cannot draw the same name.
18const reserved = new Set<string>();
19// tool_use_id -> the name this module set, read back by agent.spawn to verify.
20const drawn = new Map<string, string>();
21
22function rand(): number {
23  const a = new Uint32Array(1);
24  crypto.getRandomValues(a);
25  return (a[0] ?? 0) / 2 ** 32;
26}
27
28function alarm($: EngineInterface, text: string): void {
29  // Toast plus status line: the toast fades, the status line stays until the next clean spawn.
30  void Promise.resolve($.ui.toast(`${TAG}: ${text}`, { timeoutMs: 10000 })).catch(() => undefined); // audit-allow: fail-loud — the alarm itself has nowhere louder to report
31  void Promise.resolve($.ui.status(`${TAG}: ${text}`)).catch(() => undefined); // audit-allow: fail-loud — same
32}
33
34export const register: Register = (on, options) => {
35  if (options.enabled === false) return;
36  const theme = typeof options.theme === 'string' ? options.theme : 'auto';
37
38  on('tool.call', { tool: 'Agent' }, async ($, e, next) => {
39    if (e.name !== undefined && e.name !== '') return next(e); // the model named it: leave it
40    const live = (await $.agent.list()).map(a => a.name).filter((n): n is string => !!n);
41    const { name } = pickName(POOL, {
42      subagentType: e.subagent_type, description: e.description, theme,
43      taken: [...live, ...reserved], rand,
44    });
45    reserved.add(name);
46    drawn.set(e.tool_use_id, name);
47    try {
48      return await next({ ...e, name });
49    } finally {
50      reserved.delete(name);
51      drawn.delete(e.tool_use_id);
52    }
53  }).catch(($, e, next) => {
54    alarm($, 'naming failed; this agent runs unnamed');
55    return next(e); // replays the settled call if next already ran; never blocks the dispatch
56  });
57
58  on('agent.spawn', async ($, e, next) => {
59    const r = await next(e);
60    const want = drawn.get(e.tool_use_id);
61    if (want === undefined || r.agentId === undefined) return r; // not ours, or not started
62    try {
63      if (e.name !== want) {
64        alarm($, `drew ${want} but the spawn got ${e.name ?? 'no name'}`);
65      } else {
66        const row = (await $.agent.list()).find(a => a.id === r.agentId);
67        if (row?.name !== want) alarm($, `drew ${want} but the agent list shows ${row?.name ?? (row ? 'no name' : 'no row')}`);
68        else void Promise.resolve($.ui.status(undefined)).catch(() => undefined); // audit-allow: fail-loud — clearing a stale alarm line
69      }
70    } catch {
71      alarm($, `could not verify ${want}`);
72    }
73    return r;
74  }).catch(($, e, next) => next(e)); // replays the spawn if it already ran; never refuses one
75};
76
hooks/draw.ts 77 lines
1// Pure name-drawing logic: no engine calls, so it is unit-tested with plain node.
2
3export type Category = {
4  key: string;
5  subagent_types: string[];
6  keywords: string[];
7  names: string[];
8};
9export type Pool = { categories: Category[] };
10
11/** Roles that say nothing about the task: their description's keywords decide first. */
12export const GENERIC_ROLES = ['general-purpose', 'worker'];
13/** What the Agent tool runs when `subagent_type` is omitted. */
14const DEFAULT_ROLE = 'general-purpose';
15const FALLBACK = 'default';
16
17function byType(pool: Pool, role: string): string | undefined {
18  const r = role.trim().toLowerCase();
19  return pool.categories.find(c => c.subagent_types.some(t => t.toLowerCase() === r))?.key;
20}
21
22function byKeyword(pool: Pool, text: string): string | undefined {
23  const t = text.toLowerCase();
24  let best: string | undefined;
25  let bestHits = 0;
26  for (const c of pool.categories) {
27    const hits = c.keywords.filter(k => t.includes(k)).length;
28    if (hits > bestHits) { best = c.key; bestHits = hits; } // strict >: ties keep the earlier category
29  }
30  return best;
31}
32
33/**
34 * Category for one dispatch: a valid `theme` pins it; otherwise a specific role wins,
35 * a generic role defers to description keywords, and the default pool catches the rest.
36 * Mirrors the Python package's resolve_for_hook.
37 */
38export function categoryFor(pool: Pool, subagentType?: string, description?: string, theme = 'auto'): string {
39  if (theme !== 'auto' && pool.categories.some(c => c.key === theme)) return theme;
40  const role = subagentType ?? DEFAULT_ROLE;
41  const fromType = byType(pool, role);
42  const fromTask = description ? byKeyword(pool, description) : undefined;
43  if (GENERIC_ROLES.includes(role.trim().toLowerCase())) return fromTask ?? fromType ?? FALLBACK;
44  return fromType ?? fromTask ?? FALLBACK;
45}
46
47/**
48 * A name from `category` not in `taken` (case-insensitive). An exhausted category spills
49 * to the default pool, then to any free name; with all taken, a numbered suffix.
50 */
51export function drawName(pool: Pool, category: string, taken: Iterable<string>, rand: () => number): string {
52  const used = new Set([...taken].map(n => n.toLowerCase()));
53  const free = (names: string[]) => names.filter(n => !used.has(n.toLowerCase()));
54  const home = pool.categories.find(c => c.key === category) ?? pool.categories.find(c => c.key === FALLBACK);
55  const tiers = [home?.names ?? [], pool.categories.find(c => c.key === FALLBACK)?.names ?? [], pool.categories.flatMap(c => c.names)];
56  for (const tier of tiers) {
57    const f = free(tier);
58    const pick = f[Math.min(f.length - 1, Math.floor(rand() * f.length))];
59    if (pick !== undefined) return pick;
60  }
61  const base = home?.names[0] ?? 'Agent';
62  for (let n = 2; ; n++) if (!used.has(`${base}-${n}`.toLowerCase())) return `${base}-${n}`;
63}
64
65export type PickInput = {
66  subagentType?: string;
67  description?: string;
68  theme?: string;
69  taken: Iterable<string>;
70  rand: () => number;
71};
72
73export function pickName(pool: Pool, i: PickInput): { name: string; category: string } {
74  const category = categoryFor(pool, i.subagentType, i.description, i.theme);
75  return { name: drawName(pool, category, i.taken, i.rand), category };
76}
77
hooks/pool.ts 740 lines
1// GENERATED by mod/scripts/gen_pool.mjs from named_subagents/registry.json. Do not edit.
2import type { Pool } from './draw.ts';
3
4export const POOL: Pool = {
5  "categories": [
6    {
7      "key": "explore",
8      "subagent_types": [
9        "Explore",
10        "explorer"
11      ],
12      "keywords": [
13        "explore",
14        "search",
15        "map",
16        "survey",
17        "scout",
18        "locate",
19        "find",
20        "inventory",
21        "codebase",
22        "where is",
23        "trace files",
24        "discover"
25      ],
26      "names": [
27        "Magellan",
28        "Shackleton",
29        "Amundsen",
30        "Cook",
31        "Polo",
32        "Columbus",
33        "Livingstone",
34        "Hillary",
35        "Earhart",
36        "IbnBattuta",
37        "ZhengHe",
38        "Lewis",
39        "Clark",
40        "Drake",
41        "Hudson",
42        "Cabot",
43        "DaGama",
44        "Nansen",
45        "Scott",
46        "Boone",
47        "Sacagawea",
48        "Tenzing",
49        "Cousteau",
50        "Gagarin",
51        "Heyerdahl",
52        "Bering",
53        "Tasman",
54        "Xuanzang",
55        "Pytheas",
56        "Frobisher"
57      ]
58    },
59    {
60      "key": "code",
61      "subagent_types": [
62        "worker",
63        "general-purpose",
64        "coder",
65        "code"
66      ],
67      "keywords": [
68        "implement",
69        "build",
70        "feature",
71        "write code",
72        "function",
73        "endpoint",
74        "add",
75        "create",
76        "develop",
77        "patch",
78        "class",
79        "method",
80        "module"
81      ],
82      "names": [
83        "Turing",
84        "Dijkstra",
85        "Knuth",
86        "Hopper",
87        "Ada",
88        "Torvalds",
89        "Ritchie",
90        "Thompson",
91        "Kernighan",
92        "BernersLee",
93        "Stallman",
94        "Carmack",
95        "Guido",
96        "Stroustrup",
97        "Backus",
98        "McCarthy",
99        "AlanKay",
100        "Engelbart",
101        "Wozniak",
102        "Liskov",
103        "Lamport",
104        "Cerf",
105        "AlKhwarizmi",
106        "Babbage",
107        "Matz",
108        "Gosling",
109        "Hejlsberg",
110        "Aho",
111        "Ullman",
112        "Hamilton",
113        "Perlis",
114        "Iverson",
115        "Hoare"
116      ]
117    },
118    {
119      "key": "research",
120      "subagent_types": [
121        "research-subagent",
122        "researcher"
123      ],
124      "keywords": [
125        "research",
126        "investigate",
127        "compare",
128        "landscape",
129        "gather",
130        "sources",
131        "literature",
132        "cite",
133        "benchmark",
134        "study",
135        "survey the",
136        "state of the art"
137      ],
138      "names": [
139        "Darwin",
140        "Newton",
141        "Einstein",
142        "Curie",
143        "Feynman",
144        "Faraday",
145        "Bohr",
146        "Heisenberg",
147        "Rosalind",
148        "Mendel",
149        "Pasteur",
150        "Galileo",
151        "Kepler",
152        "Hubble",
153        "Hawking",
154        "Maxwell",
155        "Planck",
156        "Rutherford",
157        "Fermi",
158        "Dirac",
159        "Schrodinger",
160        "Volta",
161        "Kelvin",
162        "Herschel",
163        "Meitner",
164        "Goodall",
165        "Sagan",
166        "Chandrasekhar",
167        "McClintock",
168        "Pauling",
169        "Avicenna",
170        "Copernicus"
171      ]
172    },
173    {
174      "key": "reflect",
175      "subagent_types": [
176        "architect",
177        "philosopher"
178      ],
179      "keywords": [
180        "architecture",
181        "rationale",
182        "why is",
183        "why was",
184        "why did",
185        "why does",
186        "why do",
187        "philosophy",
188        "meta",
189        "reflect",
190        "principles",
191        "tradeoff",
192        "conceptual",
193        "wonder",
194        "intent",
195        "design decision",
196        "design choice",
197        "abstraction",
198        "chosen",
199        "first principles",
200        "ponder"
201      ],
202      "names": [
203        "Socrates",
204        "Plato",
205        "Aristotle",
206        "Kant",
207        "Hegel",
208        "Nietzsche",
209        "Descartes",
210        "Hume",
211        "Spinoza",
212        "Leibniz",
213        "Wittgenstein",
214        "Heidegger",
215        "Sartre",
216        "Confucius",
217        "Laozi",
218        "Aquinas",
219        "Locke",
220        "Rousseau",
221        "Camus",
222        "Arendt",
223        "Beauvoir",
224        "Aurelius",
225        "Epictetus",
226        "Seneca",
227        "Kierkegaard",
228        "Schopenhauer",
229        "Hypatia",
230        "Averroes",
231        "Zhuangzi",
232        "Montaigne",
233        "Weil"
234      ]
235    },
236    {
237      "key": "debug",
238      "subagent_types": [
239        "debugger"
240      ],
241      "keywords": [
242        "debug",
243        "root cause",
244        "bug",
245        "failure",
246        "crash",
247        "stack trace",
248        "reproduce",
249        "diagnose",
250        "failing",
251        "regression cause",
252        "why does it break"
253      ],
254      "names": [
255        "Holmes",
256        "Poirot",
257        "Marple",
258        "Dupin",
259        "Columbo",
260        "Spade",
261        "Marlowe",
262        "Nancy",
263        "Magnum",
264        "Clouseau",
265        "Wimsey",
266        "Maigret",
267        "Wolfe",
268        "Vance",
269        "Fandorin",
270        "Morse",
271        "Rebus",
272        "Bosch",
273        "Scarpetta",
274        "Archer",
275        "Hammer",
276        "Millhone",
277        "Goren",
278        "Brenner"
279      ]
280    },
281    {
282      "key": "test",
283      "subagent_types": [
284        "qa",
285        "tester",
286        "qa-expert"
287      ],
288      "keywords": [
289        "test",
290        "qa",
291        "edge case",
292        "fuzz",
293        "coverage",
294        "assertion",
295        "adversarial",
296        "break it",
297        "eval",
298        "regression",
299        "property test",
300        "boundary"
301      ],
302      "names": [
303        "Loki",
304        "Anansi",
305        "Coyote",
306        "Hermes",
307        "Prometheus",
308        "Sisyphus",
309        "Eris",
310        "Puck",
311        "Reynard",
312        "Kokopelli",
313        "Maui",
314        "Susanoo",
315        "Wukong",
316        "Eulenspiegel",
317        "Brer",
318        "Legba",
319        "Nasreddin",
320        "Iktomi",
321        "Kitsune",
322        "Tanuki",
323        "Pan",
324        "Set",
325        "Veles",
326        "Baubo"
327      ]
328    },
329    {
330      "key": "review",
331      "subagent_types": [
332        "code-reviewer",
333        "reviewer"
334      ],
335      "keywords": [
336        "review",
337        "critique",
338        "correctness",
339        "feedback",
340        "approve",
341        "verdict",
342        "scrutinize",
343        "pull request",
344        "pr review",
345        "sign off",
346        "assess quality"
347      ],
348      "names": [
349        "Solomon",
350        "Solon",
351        "Hammurabi",
352        "Justinian",
353        "Marshall",
354        "Cardozo",
355        "Brandeis",
356        "Ginsburg",
357        "Thurgood",
358        "OConnor",
359        "Scalia",
360        "Story",
361        "Blackstone",
362        "Bracton",
363        "Mansfield",
364        "Denning",
365        "Warren",
366        "Portia",
367        "Bao",
368        "Draco",
369        "Lycurgus",
370        "Ulpian",
371        "Papinian",
372        "Sotomayor"
373      ]
374    },
375    {
376      "key": "security",
377      "subagent_types": [
378        "security-auditor",
379        "penetration-tester"
380      ],
381      "keywords": [
382        "security",
383        "audit",
384        "vulnerability",
385        "threat",
386        "pentest",
387        "exploit",
388        "cve",
389        "auth",
390        "injection",
391        "guardrail",
392        "harden",
393        "secrets",
394        "ssrf"
395      ],
396      "names": [
397        "Argus",
398        "Cerberus",
399        "Heimdall",
400        "Horus",
401        "Bastet",
402        "Aegis",
403        "Fafnir",
404        "Ladon",
405        "Talos",
406        "Anubis",
407        "Tyr",
408        "Athena",
409        "Garuda",
410        "Hachiman",
411        "Sekhmet",
412        "Fenrir",
413        "Vidar",
414        "Perseus",
415        "Durga",
416        "Nemesis",
417        "Golem",
418        "Shu"
419      ]
420    },
421    {
422      "key": "design",
423      "subagent_types": [
424        "ui-designer",
425        "frontend-developer",
426        "ux-researcher"
427      ],
428      "keywords": [
429        "ui",
430        "ux",
431        "frontend",
432        "design",
433        "css",
434        "layout",
435        "component",
436        "visual",
437        "style",
438        "accessibility",
439        "wireframe",
440        "mockup",
441        "typography",
442        "palette"
443      ],
444      "names": [
445        "DaVinci",
446        "Michelangelo",
447        "Rembrandt",
448        "Monet",
449        "Picasso",
450        "Kahlo",
451        "Hokusai",
452        "Klimt",
453        "Matisse",
454        "OKeeffe",
455        "Vermeer",
456        "Caravaggio",
457        "Rothko",
458        "Kandinsky",
459        "Rams",
460        "PaulRand",
461        "Eames",
462        "Vignelli",
463        "SaulBass",
464        "Mucha",
465        "Escher",
466        "Gaudi",
467        "Basquiat",
468        "Warhol"
469      ]
470    },
471    {
472      "key": "data",
473      "subagent_types": [
474        "data-scientist",
475        "data-engineer",
476        "machine-learning-engineer"
477      ],
478      "keywords": [
479        "data",
480        "sql",
481        "query",
482        "analytics",
483        "statistics",
484        "ml",
485        "training",
486        "dataframe",
487        "dataset",
488        "visualization",
489        "chart",
490        "model accuracy",
491        "distribution"
492      ],
493      "names": [
494        "Gauss",
495        "Euler",
496        "Riemann",
497        "Fermat",
498        "Fibonacci",
499        "Bayes",
500        "Fisher",
501        "Tukey",
502        "Pascal",
503        "Laplace",
504        "Kolmogorov",
505        "Erdos",
506        "Hilbert",
507        "Cantor",
508        "Noether",
509        "Ramanujan",
510        "Nightingale",
511        "Gosset",
512        "Galois",
513        "Poincare",
514        "Bernoulli",
515        "Lagrange",
516        "Markov",
517        "Nash",
518        "Aryabhata",
519        "Brahmagupta",
520        "Shannon",
521        "Boole",
522        "Fourier",
523        "Cauchy"
524      ]
525    },
526    {
527      "key": "orchestrate",
528      "subagent_types": [
529        "Plan",
530        "orchestrator",
531        "coordinator",
532        "multi-agent-coordinator"
533      ],
534      "keywords": [
535        "orchestrate",
536        "coordinate",
537        "plan",
538        "break down",
539        "distribute",
540        "delegate",
541        "strategy",
542        "roadmap",
543        "milestone",
544        "schedule",
545        "sequence the work"
546      ],
547      "names": [
548        "SunTzu",
549        "Napoleon",
550        "Hannibal",
551        "Caesar",
552        "Alexander",
553        "Zhukov",
554        "Patton",
555        "Rommel",
556        "Scipio",
557        "Nelson",
558        "Wellington",
559        "Khalid",
560        "Saladin",
561        "Genghis",
562        "Belisarius",
563        "Themistocles",
564        "Leonidas",
565        "Pericles",
566        "Clausewitz",
567        "Marlborough",
568        "Timur",
569        "Joan",
570        "Boudica",
571        "Kutuzov",
572        "Nimitz",
573        "Cyrus",
574        "Subutai"
575      ]
576    },
577    {
578      "key": "docs",
579      "subagent_types": [
580        "documentation-engineer",
581        "docs",
582        "technical-writer"
583      ],
584      "keywords": [
585        "docs",
586        "documentation",
587        "readme",
588        "write up",
589        "write the",
590        "explain",
591        "guide",
592        "tutorial",
593        "changelog",
594        "comment",
595        "narrative",
596        "prose",
597        "manual",
598        "api reference",
599        "reference for",
600        "document the"
601      ],
602      "names": [
603        "Shakespeare",
604        "Tolstoy",
605        "Austen",
606        "Orwell",
607        "Hemingway",
608        "Borges",
609        "Woolf",
610        "Twain",
611        "Kafka",
612        "Dickens",
613        "Homer",
614        "Dante",
615        "Cervantes",
616        "Chekhov",
617        "Dostoevsky",
618        "Proust",
619        "Joyce",
620        "Melville",
621        "Poe",
622        "Angelou",
623        "Morrison",
624        "Marquez",
625        "Neruda",
626        "Rumi",
627        "Basho",
628        "Murasaki",
629        "Ovid",
630        "Virgil",
631        "Sappho",
632        "Achebe",
633        "Tagore"
634      ]
635    },
636    {
637      "key": "build",
638      "subagent_types": [
639        "devops-engineer",
640        "refactoring-specialist",
641        "build-engineer",
642        "performance-engineer"
643      ],
644      "keywords": [
645        "infra",
646        "deploy",
647        "devops",
648        "docker",
649        "kubernetes",
650        "ci",
651        "optimize",
652        "performance",
653        "refactor",
654        "legacy",
655        "migrate",
656        "terraform",
657        "cloud",
658        "cache",
659        "throughput"
660      ],
661      "names": [
662        "Tesla",
663        "Edison",
664        "Brunel",
665        "Eiffel",
666        "Watt",
667        "Stephenson",
668        "Roebling",
669        "Telford",
670        "Ford",
671        "Diesel",
672        "Otto",
673        "Benz",
674        "Daimler",
675        "Whitney",
676        "Arkwright",
677        "Nasmyth",
678        "Bessemer",
679        "Sikorsky",
680        "Whittle",
681        "Carver",
682        "GrahamBell",
683        "Marconi",
684        "Wright",
685        "Fulton",
686        "Gutenberg",
687        "Archimedes",
688        "Heron",
689        "Lamarr"
690      ]
691    },
692    {
693      "key": "default",
694      "subagent_types": [
695        "default",
696        "claude",
697        "general"
698      ],
699      "keywords": [],
700      "names": [
701        "Orion",
702        "Vega",
703        "Rigel",
704        "Altair",
705        "Sirius",
706        "Polaris",
707        "Antares",
708        "Cygnus",
709        "Aquila",
710        "Andromeda",
711        "Cassiopeia",
712        "Pyxis",
713        "Carina",
714        "Vela",
715        "Corvus",
716        "Auriga",
717        "Bootes",
718        "Hydra",
719        "Phoenix",
720        "Cepheus",
721        "Lynx",
722        "Pavo",
723        "Tucana",
724        "Grus",
725        "Ara",
726        "Norma",
727        "Fornax",
728        "Mensa",
729        "Volans",
730        "Dorado",
731        "Sculptor",
732        "Caelum",
733        "Pictor",
734        "Antlia",
735        "Crux"
736      ]
737    }
738  ]
739};
740