@openephemeris/mcp-server 3.23.1 → 4.0.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 (56) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/LICENSE +21 -21
  3. package/README.md +52 -3
  4. package/dist/analytics.js +37 -5
  5. package/dist/backend/client.d.ts +7 -0
  6. package/dist/backend/client.js +39 -38
  7. package/dist/index.js +64 -2
  8. package/dist/oauth/session-utils.d.ts +42 -18
  9. package/dist/oauth/session-utils.js +79 -0
  10. package/dist/server-sse.js +114 -14
  11. package/dist/tools/apps/bazi-app.js +12 -26
  12. package/dist/tools/apps/bi-wheel-app.js +2 -2
  13. package/dist/tools/apps/bodygraph-app.d.ts +5 -5
  14. package/dist/tools/apps/bodygraph-app.js +187 -225
  15. package/dist/tools/apps/chart-wheel-app.js +5 -3
  16. package/dist/tools/apps/location-tools.js +167 -18
  17. package/dist/tools/apps/moon-phase-app.js +10 -3
  18. package/dist/tools/apps/transit-timeline-app.js +6 -4
  19. package/dist/tools/apps/vedic-chart-app.js +15 -49
  20. package/dist/tools/datetime.d.ts +65 -0
  21. package/dist/tools/datetime.js +153 -0
  22. package/dist/tools/index.d.ts +45 -2
  23. package/dist/tools/index.js +78 -2
  24. package/dist/tools/specialized/account.d.ts +1 -0
  25. package/dist/tools/specialized/account.js +100 -0
  26. package/dist/tools/specialized/acg.js +16 -14
  27. package/dist/tools/specialized/bazi.d.ts +7 -1
  28. package/dist/tools/specialized/bazi.js +86 -19
  29. package/dist/tools/specialized/bi_wheel.js +5 -4
  30. package/dist/tools/specialized/chart_wheel.js +5 -8
  31. package/dist/tools/specialized/comparative.js +13 -5
  32. package/dist/tools/specialized/electional.js +7 -7
  33. package/dist/tools/specialized/ephemeris_core.js +13 -8
  34. package/dist/tools/specialized/ephemeris_extended.js +27 -17
  35. package/dist/tools/specialized/hd_bodygraph.js +8 -10
  36. package/dist/tools/specialized/hd_cycles.js +7 -14
  37. package/dist/tools/specialized/hd_group.js +20 -13
  38. package/dist/tools/specialized/human_design.js +11 -17
  39. package/dist/tools/specialized/moon.js +8 -2
  40. package/dist/tools/specialized/natal.js +7 -9
  41. package/dist/tools/specialized/progressed.js +12 -8
  42. package/dist/tools/specialized/relocation.js +9 -3
  43. package/dist/tools/specialized/returns.js +23 -11
  44. package/dist/tools/specialized/synastry.js +17 -6
  45. package/dist/tools/specialized/transits.js +9 -5
  46. package/dist/tools/specialized/vedic.js +5 -3
  47. package/dist/tools/specialized/venus_star_points.js +14 -9
  48. package/dist/ui/bazi.html +1063 -1049
  49. package/dist/ui/bi-wheel.html +4197 -4120
  50. package/dist/ui/bodygraph.html +3855 -3720
  51. package/dist/ui/chart-wheel.html +3779 -3706
  52. package/dist/ui/moon-phase.html +3228 -3145
  53. package/dist/ui/transit-timeline.html +199 -170
  54. package/dist/ui/vedic-chart.html +1116 -1098
  55. package/package.json +6 -3
  56. package/smithery.yaml +1 -1
@@ -1,10 +1,10 @@
1
1
  /**
2
- * bodygraph-app.ts — MCP App tool registration for the Human Design Bodygraph Explorer.
2
+ * bodygraph-app.ts — MCP App tool registration for the Human Design Bodygraph Explorer.
3
3
  *
4
4
  * Entry tools [model + app]:
5
- * • explore_human_design — natal bodygraph, data + UI resource
6
- * • explore_human_design_transit — natal + transit overlay (premium)
7
- * • explore_human_design_connection — two-person connection/synastry overlay (premium)
5
+ * • explore_human_design — natal bodygraph, data + UI resource
6
+ * • explore_human_design_transit — natal + transit overlay (premium)
7
+ * • explore_human_design_connection — two-person connection/synastry overlay (premium)
8
8
  * Click handlers [app-only]: hd_on_center_click, hd_on_gate_click,
9
9
  * hd_on_channel_click, hd_on_planet_click, hd_on_variable_click,
10
10
  * hd_on_connection_channel_click, hd_on_transit_channel_click (overlay, Phase 5).
@@ -12,7 +12,7 @@
12
12
  * overlay SVG is returned inline by /human-design/transit-chart and
13
13
  * /human-design/composite (include_visual) rather than a separate render call.
14
14
  *
15
- * The bodygraph is rendered client-side from structured JSON — no SVG endpoint
15
+ * The bodygraph is rendered client-side from structured JSON — no SVG endpoint
16
16
  * is called, keeping latency at zero and the architecture consistent with
17
17
  * the chart-wheel-app approach.
18
18
  *
@@ -25,7 +25,8 @@ import { fileURLToPath } from "node:url";
25
25
  import { registerTool, SERVER_VERSION } from "../index.js";
26
26
  import { getActiveClient } from "../../backend/client.js";
27
27
  import { OUTPUT_SCHEMA_JSON } from "../output-schemas.js";
28
- // ── Constants ─────────────────────────────────────────────────────────────
28
+ import { localToUtcIso } from "../datetime.js";
29
+ // ── Constants ─────────────────────────────────────────────────────────────
29
30
  export const BODYGRAPH_RESOURCE_URI = "ui://openephemeris/bodygraph";
30
31
  // Appended to every model-visible HD tool description — trademark hygiene.
31
32
  const HD_DISCLAIMER = " Human Design was originated by Ra Uru Hu; OpenEphemeris is an independent calculation service, not affiliated with Jovian Archive.";
@@ -61,31 +62,11 @@ export function getBodygraphBundle() {
61
62
  export function clearBodygraphBundleCache() {
62
63
  cachedBundle = null;
63
64
  }
64
- // ── Helpers ──────────────────────────────────────────────────────────────
65
+ // ── Helpers ──────────────────────────────────────────────────────────────
65
66
  function capitalize(s) {
66
67
  return s.charAt(0).toUpperCase() + s.slice(1);
67
68
  }
68
- /** Ensure datetime has a UTC offset for Go time.Time parsing. */
69
- function ensureTimezone(dt) {
70
- if (!dt)
71
- return dt;
72
- if (/[Zz]$/.test(dt) || /[+-]\d{2}:\d{2}$/.test(dt))
73
- return dt;
74
- return dt + "Z";
75
- }
76
- /**
77
- * Fetch the canonical bodygraph SVG from the Go renderer.
78
- *
79
- * The Go engine is the source of truth for bodygraph visuals (Phase 4 of the
80
- * renderer unification). This SVG is inlined directly into the iframe and
81
- * bound to interaction handlers via its data-* attributes (data-center,
82
- * data-gate, data-channel, data-hanging, data-highlighted, etc.).
83
- *
84
- * Returns null on failure so the caller can fall back to the legacy client-side
85
- * renderer in bodygraph-renderer.ts. Non-fatal: a missing SVG should never
86
- * block the tool result.
87
- */
88
- async function fetchGoBodygraphSVG(body, theme = "dark") {
69
+ async function fetchGoBodygraphSVG(body, theme = "dark", view) {
89
70
  try {
90
71
  const client = getActiveClient();
91
72
  // /visualization/bodygraph is registered as binary in BINARY_ENDPOINT_PREFIXES.
@@ -96,7 +77,18 @@ async function fetchGoBodygraphSVG(body, theme = "dark") {
96
77
  // to "light" when style is omitted, which mismatches dark MCP hosts — so we
97
78
  // always pass an explicit theme (default "dark" to match the app shell; the
98
79
  // iframe re-fetches with the host-detected theme on load / theme change).
99
- const resp = await client.post(`/visualization/bodygraph?format=svg&size=800&style=${theme}`, body);
80
+ //
81
+ // layout/rings/house_system are already validated + billed server-side
82
+ // (handler_bodygraph.go) — only appended when the caller (the in-iframe
83
+ // layout toggle) actually requests the mandala view.
84
+ let qs = `format=svg&size=800&style=${theme}`;
85
+ if (view?.layout)
86
+ qs += `&layout=${encodeURIComponent(view.layout)}`;
87
+ if (view?.rings !== undefined)
88
+ qs += `&rings=${encodeURIComponent(view.rings)}`;
89
+ if (view?.houseSystem)
90
+ qs += `&house_system=${encodeURIComponent(view.houseSystem)}`;
91
+ const resp = await client.post(`/visualization/bodygraph?${qs}`, body);
100
92
  if (typeof resp === "string")
101
93
  return resp;
102
94
  if (resp && typeof resp === "object") {
@@ -112,54 +104,6 @@ async function fetchGoBodygraphSVG(body, theme = "dark") {
112
104
  return null;
113
105
  }
114
106
  }
115
- /**
116
- * Convert a local datetime string (no offset) to a UTC ISO 8601 string.
117
- * Uses the IANA timezone to compute the correct UTC offset.
118
- * Falls back to appending 'Z' (treating input as UTC) when no timezone is given
119
- * or when the Intl API cannot resolve the zone.
120
- *
121
- * @param dt - "YYYY-MM-DDTHH:MM:SS" (no offset)
122
- * @param tz - IANA timezone name, e.g. "America/New_York"
123
- */
124
- function localToUtcIso(dt, tz) {
125
- // Already has an offset / Z — pass through as-is
126
- if (!dt || /[Zz]$/.test(dt) || /[+-]\d{2}:\d{2}$/.test(dt))
127
- return ensureTimezone(dt);
128
- if (!tz)
129
- return dt + "Z"; // treat as UTC
130
- try {
131
- // Parse the local date components
132
- const [datePart, timePart = "00:00:00"] = dt.split("T");
133
- const [year, month, day] = datePart.split("-").map(Number);
134
- const [hour, min, sec = 0] = timePart.split(":").map(Number);
135
- // Build a Date assuming the inputs are LOCAL in the given timezone.
136
- // Strategy: create a UTC candidate and shift by the Intl-reported offset.
137
- // We iterate twice because DST can cause the offset to change at boundary datetimes.
138
- const candidateUtcMs = Date.UTC(year, month - 1, day, hour, min, sec);
139
- const getOffsetMs = (utcMs) => {
140
- const fmtParts = new Intl.DateTimeFormat("en-US", {
141
- timeZone: tz,
142
- year: "numeric", month: "2-digit", day: "2-digit",
143
- hour: "2-digit", minute: "2-digit", second: "2-digit",
144
- hour12: false,
145
- }).formatToParts(new Date(utcMs));
146
- const get = (t) => Number(fmtParts.find(p => p.type === t)?.value ?? 0);
147
- const localizedUtcMs = Date.UTC(get("year"), get("month") - 1, get("day"), get("hour") % 24, get("minute"), get("second"));
148
- return utcMs - localizedUtcMs; // positive = timezone behind UTC
149
- };
150
- // First pass: rough offset
151
- const offsetMs1 = getOffsetMs(candidateUtcMs);
152
- const correctedUtcMs1 = candidateUtcMs + offsetMs1;
153
- // Second pass: refine around DST boundary
154
- const offsetMs2 = getOffsetMs(correctedUtcMs1);
155
- const finalUtcMs = candidateUtcMs + offsetMs2;
156
- return new Date(finalUtcMs).toISOString();
157
- }
158
- catch {
159
- // Intl failed (bad timezone string etc.) — fall back to naive UTC
160
- return dt + "Z";
161
- }
162
- }
163
107
  const CENTER_ORDER = [
164
108
  "Head", "Ajna", "Throat", "G", "Sacral",
165
109
  "Heart", "Spleen", "Solar Plexus", "Root",
@@ -357,7 +301,7 @@ function buildHdSummary(payload, location) {
357
301
  `Channels (${payload.active_channels.length}): ${channelList}\n\n` +
358
302
  "Click any center, gate, or channel on the bodygraph for interpretation.");
359
303
  }
360
- // ── Tool: explore_human_design ────────────────────────────────────────────
304
+ // ── Tool: explore_human_design ────────────────────────────────────────────
361
305
  registerTool({
362
306
  name: "explore_human_design",
363
307
  description: "Generate an interactive Human Design Bodygraph with clickable centers, gates, and channels.\n\n" +
@@ -377,12 +321,12 @@ registerTool({
377
321
  datetime: {
378
322
  type: "string",
379
323
  description: "ISO 8601 birth datetime in UTC, e.g. '1990-04-15T19:30:00Z'. " +
380
- "Human Design is time-sensitive — accuracy to the minute matters. " +
324
+ "Human Design is time-sensitive — accuracy to the minute matters. " +
381
325
  "Include 'Z' or a timezone offset.",
382
326
  },
383
327
  latitude: {
384
328
  type: "number",
385
- description: "Birth latitude in decimal degrees (positive = North). Optional for HD charts.",
329
+ description: "Birth latitude in decimal degrees (positive = North). Optional for HD charts. Resolve from a place name with location_search; never recall coordinates from memory.",
386
330
  },
387
331
  longitude: {
388
332
  type: "number",
@@ -390,7 +334,7 @@ registerTool({
390
334
  },
391
335
  location: {
392
336
  type: "string",
393
- description: "Location name for display only (e.g. 'New York, NY').",
337
+ description: "Location name for display only (e.g. 'New York, NY'). This is a caption, NOT a geocoder — it does not set the chart location. Supply latitude/longitude too (resolve them with location_search), or the chart is computed at 0N 0E.",
394
338
  },
395
339
  timezone: {
396
340
  type: "string",
@@ -418,7 +362,7 @@ registerTool({
418
362
  handler: async (args) => {
419
363
  const client = getActiveClient();
420
364
  const timezone = args.timezone;
421
- const datetime = localToUtcIso(String(args.datetime), timezone);
365
+ const datetime = localToUtcIso("datetime", String(args.datetime), timezone);
422
366
  const location = String(args.location ?? (args.latitude != null ? `${args.latitude}, ${args.longitude}` : "Unknown")).slice(0, 120);
423
367
  const lat = args.latitude;
424
368
  const lon = args.longitude;
@@ -495,6 +439,19 @@ registerTool({
495
439
  enum: ["light", "dark"],
496
440
  description: "Render palette for the bodygraph SVG. Mirrors the MCP host's light/dark color scheme.",
497
441
  },
442
+ layout: {
443
+ type: "string",
444
+ enum: ["graph", "mandala"],
445
+ description: "Bodygraph composition. 'graph' (default) is the classic layout; 'mandala' nests the same diagram inside concentric rings. Set by the in-iframe layout toggle, never by the model.",
446
+ },
447
+ rings: {
448
+ type: "string",
449
+ description: "Comma-separated optional mandala rings (e.g. 'quarter,zodiac,planets'). Only used when layout=mandala. Omit for the server default; pass an empty string for none.",
450
+ },
451
+ house_system: {
452
+ type: "string",
453
+ description: "House system for the mandala house ring. Only used when layout=mandala and rings includes 'houses' with a birth location. Adds 1 credit when the house ring renders.",
454
+ },
498
455
  },
499
456
  required: ["datetime"],
500
457
  },
@@ -505,10 +462,13 @@ registerTool({
505
462
  const client = getActiveClient();
506
463
  const timezone = args.timezone;
507
464
  // Convert local-time input → UTC using IANA timezone when provided
508
- const datetime = localToUtcIso(String(args.datetime), timezone);
465
+ const datetime = localToUtcIso("datetime", String(args.datetime), timezone);
509
466
  const lat = args.latitude;
510
467
  const lon = args.longitude;
511
468
  const theme = args.theme === "light" ? "light" : "dark";
469
+ const layout = args.layout === "mandala" ? "mandala" : undefined;
470
+ const rings = typeof args.rings === "string" ? args.rings : undefined;
471
+ const houseSystem = typeof args.house_system === "string" ? args.house_system : undefined;
512
472
  const body = {
513
473
  birth_datetime_utc: datetime,
514
474
  };
@@ -521,7 +481,7 @@ registerTool({
521
481
  client.request("POST", "/human-design/chart", {
522
482
  data: body,
523
483
  }),
524
- fetchGoBodygraphSVG(body, theme),
484
+ fetchGoBodygraphSVG(body, theme, { layout, rings, houseSystem }),
525
485
  ]);
526
486
  const chart = chartData.chart ?? chartData;
527
487
  const modelPayload = buildHdModelPayload(chart, {
@@ -538,7 +498,7 @@ registerTool({
538
498
  };
539
499
  },
540
500
  });
541
- // ── Tool: hd_on_center_click ──────────────────────────────────────────────
501
+ // ── Tool: hd_on_center_click ──────────────────────────────────────────────
542
502
  registerTool({
543
503
  name: "hd_on_center_click",
544
504
  description: "Event handler called when the user clicks a center in the Human Design Bodygraph. " +
@@ -572,12 +532,12 @@ registerTool({
572
532
  };
573
533
  }
574
534
  const defLine = defined
575
- ? `**Defined** — ${info.defined_theme}`
576
- : `**Undefined (Open)** — ${info.undefined_theme}`;
535
+ ? `**Defined** — ${info.defined_theme}`
536
+ : `**Undefined (Open)** — ${info.undefined_theme}`;
577
537
  return {
578
538
  content: [{
579
539
  type: "text",
580
- text: `**${center} Center** ${defined ? "🔴" : "⬜"}\n\n` +
540
+ text: `**${center} Center** ${defined ? "🔴" : "⬜"}\n\n` +
581
541
  `${defLine}\n\n` +
582
542
  `**Keynote:** ${info.keynote}\n\n` +
583
543
  `**Biological Correlate:** ${info.biology}\n\n` +
@@ -589,7 +549,7 @@ registerTool({
589
549
  };
590
550
  },
591
551
  });
592
- // ── Tool: hd_on_gate_click ────────────────────────────────────────────────
552
+ // ── Tool: hd_on_gate_click ────────────────────────────────────────────────
593
553
  registerTool({
594
554
  name: "hd_on_gate_click",
595
555
  description: "Event handler called when the user clicks an active gate in the Human Design Bodygraph. " +
@@ -600,11 +560,11 @@ registerTool({
600
560
  properties: {
601
561
  gate: {
602
562
  type: "number",
603
- description: "Gate number (1–64).",
563
+ description: "Gate number (1–64).",
604
564
  },
605
565
  line: {
606
566
  type: "number",
607
- description: "I Ching line number (1–6). Optional.",
567
+ description: "I Ching line number (1–6). Optional.",
608
568
  },
609
569
  planet: {
610
570
  type: "string",
@@ -628,7 +588,7 @@ registerTool({
628
588
  const info = HD_GATE_DATA[gate];
629
589
  const lineRef = line ? `.${line}` : "";
630
590
  const planetNote = planet ? ` (activated by ${capitalize(planet)})` : "";
631
- const consciousNote = conscious === true ? " — **Personality** (conscious)" : conscious === false ? " — **Design** (unconscious)" : "";
591
+ const consciousNote = conscious === true ? " — **Personality** (conscious)" : conscious === false ? " — **Design** (unconscious)" : "";
632
592
  if (!info) {
633
593
  return {
634
594
  content: [{ type: "text", text: `**Gate ${gate}${lineRef}**${planetNote}${consciousNote}\n\nGate data not available.` }],
@@ -637,7 +597,7 @@ registerTool({
637
597
  return {
638
598
  content: [{
639
599
  type: "text",
640
- text: `**Gate ${gate}${lineRef} — ${info.name}**${planetNote}${consciousNote}\n\n` +
600
+ text: `**Gate ${gate}${lineRef} — ${info.name}**${planetNote}${consciousNote}\n\n` +
641
601
  `**I Ching Hexagram:** ${info.hexagram}\n\n` +
642
602
  `**Keynote:** ${info.keynote}\n\n` +
643
603
  `**Gift:** ${info.gift}\n\n` +
@@ -648,7 +608,7 @@ registerTool({
648
608
  };
649
609
  },
650
610
  });
651
- // ── Tool: hd_on_channel_click ─────────────────────────────────────────────
611
+ // ── Tool: hd_on_channel_click ─────────────────────────────────────────────
652
612
  registerTool({
653
613
  name: "hd_on_channel_click",
654
614
  description: "Event handler called when the user clicks an active channel in the Human Design Bodygraph. " +
@@ -679,7 +639,7 @@ registerTool({
679
639
  const channelStr = String(args.channel);
680
640
  const g1 = args.gate1 != null ? Number(args.gate1) : null;
681
641
  const g2 = args.gate2 != null ? Number(args.gate2) : null;
682
- // Normalise lookup key — try both gate orderings
642
+ // Normalise lookup key — try both gate orderings
683
643
  const key = channelStr.includes("-") ? channelStr : g1 != null && g2 != null ? `${g1}-${g2}` : channelStr;
684
644
  const info = HD_CHANNEL_DATA[key] ?? HD_CHANNEL_DATA[key.split("-").reverse().join("-")];
685
645
  if (!info) {
@@ -694,17 +654,17 @@ registerTool({
694
654
  };
695
655
  }
696
656
  const ENERGY_TYPE_DESCRIPTIONS = {
697
- manifested: "This is a **Manifesting** channel — it can initiate and impact the world directly.",
698
- generated: "This is a **Generated** channel — powered by sacral life-force, it sustains and builds.",
699
- projected: "This is a **Projected** channel — it guides and directs rather than generates energy.",
700
- reflected: "This is a **Reflected** channel — it samples and mirrors the whole.",
657
+ manifested: "This is a **Manifesting** channel — it can initiate and impact the world directly.",
658
+ generated: "This is a **Generated** channel — powered by sacral life-force, it sustains and builds.",
659
+ projected: "This is a **Projected** channel — it guides and directs rather than generates energy.",
660
+ reflected: "This is a **Reflected** channel — it samples and mirrors the whole.",
701
661
  };
702
662
  const energyDesc = ENERGY_TYPE_DESCRIPTIONS[info.energy_type.toLowerCase()] ?? `Energy type: ${info.energy_type}`;
703
663
  return {
704
664
  content: [{
705
665
  type: "text",
706
- text: `**Channel ${channelStr} — ${info.name}**\n\n` +
707
- `**Gates:** ${g1 ?? channelStr.split("-")[0]} ↔ ${g2 ?? channelStr.split("-")[1]}\n\n` +
666
+ text: `**Channel ${channelStr} — ${info.name}**\n\n` +
667
+ `**Gates:** ${g1 ?? channelStr.split("-")[0]} ↔ ${g2 ?? channelStr.split("-")[1]}\n\n` +
708
668
  `**Circuit:** ${info.circuit}\n\n` +
709
669
  `${energyDesc}\n\n` +
710
670
  `${info.description}`,
@@ -752,7 +712,7 @@ const TRANSIT_CLASS_DATA = {
752
712
  body: "Both gates of this channel are defined in your own design. This is part of your fixed wiring, not transit weather — the passing sky does not change it. It reads here for context alongside the temporary activations.",
753
713
  },
754
714
  };
755
- // ── Tool: hd_on_connection_channel_click [app-only] ────────────────────────
715
+ // ── Tool: hd_on_connection_channel_click [app-only] ────────────────────────
756
716
  // Fired when the user clicks a connection (synastry) channel in the overlay
757
717
  // bodygraph. Serves the connection-type dynamic for that specific channel.
758
718
  registerTool({
@@ -786,12 +746,12 @@ registerTool({
786
746
  const chan = HD_CHANNEL_DATA[key] ?? HD_CHANNEL_DATA[key.split("-").reverse().join("-")];
787
747
  const conn = CONNECTION_TYPE_DATA[typeKey];
788
748
  const chanName = chan?.name ?? "this channel";
789
- const gatesLine = `**Gates:** ${g1 ?? channelStr.split("-")[0] ?? "?"} ↔ ${g2 ?? channelStr.split("-")[1] ?? "?"}`;
749
+ const gatesLine = `**Gates:** ${g1 ?? channelStr.split("-")[0] ?? "?"} ↔ ${g2 ?? channelStr.split("-")[1] ?? "?"}`;
790
750
  if (!conn) {
791
751
  return {
792
752
  content: [{
793
753
  type: "text",
794
- text: `**Channel ${channelStr} — ${chanName}**\n\n${gatesLine}\n\n` +
754
+ text: `**Channel ${channelStr} — ${chanName}**\n\n${gatesLine}\n\n` +
795
755
  `This channel is defined across both people. ${chan?.description ?? ""}`.trim(),
796
756
  }],
797
757
  };
@@ -799,7 +759,7 @@ registerTool({
799
759
  return {
800
760
  content: [{
801
761
  type: "text",
802
- text: `**${conn.label} Connection — Channel of ${chanName} (${channelStr})**\n\n` +
762
+ text: `**${conn.label} Connection — Channel of ${chanName} (${channelStr})**\n\n` +
803
763
  `${gatesLine}\n\n` +
804
764
  `*${conn.tagline}*\n\n` +
805
765
  `${conn.body}` +
@@ -808,7 +768,7 @@ registerTool({
808
768
  };
809
769
  },
810
770
  });
811
- // ── Tool: hd_on_transit_channel_click [app-only] ──────────────────────────
771
+ // ── Tool: hd_on_transit_channel_click [app-only] ──────────────────────────
812
772
  // Fired when the user clicks a channel in a transit overlay bodygraph. Serves
813
773
  // the meaning of the channel's transit class (esp. transit_completed).
814
774
  registerTool({
@@ -842,11 +802,11 @@ registerTool({
842
802
  const chan = HD_CHANNEL_DATA[key] ?? HD_CHANNEL_DATA[key.split("-").reverse().join("-")];
843
803
  const info = TRANSIT_CLASS_DATA[cls] ?? TRANSIT_CLASS_DATA.transit_completed;
844
804
  const chanName = chan?.name ?? "this channel";
845
- const gatesLine = `**Gates:** ${g1 ?? channelStr.split("-")[0] ?? "?"} ↔ ${g2 ?? channelStr.split("-")[1] ?? "?"}`;
805
+ const gatesLine = `**Gates:** ${g1 ?? channelStr.split("-")[0] ?? "?"} ↔ ${g2 ?? channelStr.split("-")[1] ?? "?"}`;
846
806
  return {
847
807
  content: [{
848
808
  type: "text",
849
- text: `**Channel of ${chanName} (${channelStr}) — ${info.label}**\n\n` +
809
+ text: `**Channel of ${chanName} (${channelStr}) — ${info.label}**\n\n` +
850
810
  `${gatesLine}\n\n` +
851
811
  `${info.body}` +
852
812
  (chan?.description ? `\n\n**This channel:** ${chan.description}` : ""),
@@ -860,14 +820,14 @@ const HD_CENTER_DATA = {
860
820
  biology: "Pineal gland, crown of skull",
861
821
  circuit: "Knowing and Logic circuits",
862
822
  defined_theme: "Consistent mental pressure to question, inspire, and seek answers. A fixed set of questions drives the mind.",
863
- undefined_theme: "Amplifies others' mental pressure and questions. Wisdom comes from knowing which questions are worth answering — not every pressure needs resolution.",
823
+ undefined_theme: "Amplifies others' mental pressure and questions. Wisdom comes from knowing which questions are worth answering — not every pressure needs resolution.",
864
824
  },
865
825
  Ajna: {
866
826
  keynote: "Conceptualization, certainty/doubt, mental processing",
867
827
  biology: "Pituitary/pineal gland complex, prefrontal cortex",
868
828
  circuit: "Individual, Collective, and Tribal circuits",
869
829
  defined_theme: "Consistent way of thinking and processing information. Opinionated and certain; thoughts have a reliable flavour.",
870
- undefined_theme: "Open to many perspectives and ways of processing. The wisdom is in mental flexibility — not needing to be certain.",
830
+ undefined_theme: "Open to many perspectives and ways of processing. The wisdom is in mental flexibility — not needing to be certain.",
871
831
  },
872
832
  Throat: {
873
833
  keynote: "Communication, manifestation, action",
@@ -881,28 +841,28 @@ const HD_CENTER_DATA = {
881
841
  biology: "Liver, blood, immune system",
882
842
  circuit: "Individual Knowing circuit",
883
843
  defined_theme: "Fixed sense of direction and identity. Love, magnetic attraction, and life direction are reliable and self-directed.",
884
- undefined_theme: "Identity and direction shift with environment and the people around. Sensitive to place — geography matters profoundly for finding the right people.",
844
+ undefined_theme: "Identity and direction shift with environment and the people around. Sensitive to place — geography matters profoundly for finding the right people.",
885
845
  },
886
846
  Heart: {
887
847
  keynote: "Willpower, ego, material world, value",
888
848
  biology: "Heart, stomach, thymus, gallbladder",
889
849
  circuit: "Tribal circuit",
890
850
  defined_theme: "Consistent willpower and ability to make and keep promises. Strong sense of personal value and what is worth fighting for.",
891
- undefined_theme: "Willpower is not consistent — rest after exertion is essential. May prove worth unnecessarily. Nothing to prove.",
851
+ undefined_theme: "Willpower is not consistent — rest after exertion is essential. May prove worth unnecessarily. Nothing to prove.",
892
852
  },
893
853
  Sacral: {
894
854
  keynote: "Life-force, sexuality, work, response",
895
855
  biology: "Reproductive system, ovaries, testes",
896
856
  circuit: "Individual, Collective, and Tribal circuits",
897
857
  defined_theme: "Consistent, powerful life-force energy that replenishes daily. Designed to work sustainably and respond gut-first. The motor of Generators and Manifesting Generators.",
898
- undefined_theme: "No consistent life-force motor. Amplifies sacral energy of defined-sacral beings when around them. Must honour when energy is done — sacral is not a reliable source.",
858
+ undefined_theme: "No consistent life-force motor. Amplifies sacral energy of defined-sacral beings when around them. Must honour when energy is done — sacral is not a reliable source.",
899
859
  },
900
860
  Spleen: {
901
861
  keynote: "Intuition, instinct, fear, immune system, survival",
902
862
  biology: "Spleen, lymphatic system, immune system, skin",
903
863
  circuit: "Individual and Tribal circuits",
904
864
  defined_theme: "Consistent intuition and immune awareness. Instincts are reliable; the body knows. Fear signals can be a guide rather than a trap.",
905
- undefined_theme: "Splenic intuition is inconsistent — amplifies others' instincts. May hold on to things out of fear (relationships, jobs) rather than intuitive knowing.",
865
+ undefined_theme: "Splenic intuition is inconsistent — amplifies others' instincts. May hold on to things out of fear (relationships, jobs) rather than intuitive knowing.",
906
866
  },
907
867
  "Solar Plexus": {
908
868
  keynote: "Emotions, feelings, desires, spirit, moods",
@@ -920,112 +880,112 @@ const HD_CENTER_DATA = {
920
880
  },
921
881
  };
922
882
  const HD_GATE_DATA = {
923
- 1: { name: "The Creative", hexagram: "Hex 1 — Creative Power", keynote: "Self-expression as a creative force", gift: "Freshness — original self-expression that inspires", shadow: "Entropy — creative block from fear of not being unique", circuit: "Individual (Centering)" },
924
- 2: { name: "The Receptive", hexagram: "Hex 2 — Receptive Power", keynote: "The direction of the self", gift: "Orientation — knowing where to go", shadow: "Dislocation — living without inner compass", circuit: "Individual (Centering)" },
925
- 3: { name: "Ordering", hexagram: "Hex 3 — Difficulty at the Beginning", keynote: "Innovation from chaos", gift: "Innovation — bringing order from initial confusion", shadow: "Chaos — stuck in mutation, unable to stabilise", circuit: "Individual (Centering)" },
926
- 4: { name: "Formulization", hexagram: "Hex 4 — Youthful Folly", keynote: "Mental solutions that benefit humanity", gift: "Understanding — solutions that help the collective", shadow: "Incompetence — mental answers that cause harm", circuit: "Collective (Logic)" },
927
- 5: { name: "Fixed Rhythms", hexagram: "Hex 5 — Waiting", keynote: "Universal patterns and timing", gift: "Patience — trusting the correct timing", shadow: "Impatience — forcing outcomes", circuit: "Collective (Logic)" },
928
- 6: { name: "Friction", hexagram: "Hex 6 — Conflict", keynote: "The role model through experience", gift: "Diplomacy — conflict resolved through right relationship", shadow: "Conflict — isolation and withdrawal", circuit: "Collective (Logic)" },
929
- 7: { name: "The Role of the Self", hexagram: "Hex 7 — The Army", keynote: "Leadership in the direction of the future", gift: "Guidance — leading through personal example", shadow: "Division — leadership without authority", circuit: "Collective (Logic)" },
930
- 8: { name: "Contribution", hexagram: "Hex 8 — Holding Together", keynote: "Contribution to the collective through individual creativity", gift: "Style — unique contribution that inspires others", shadow: "Mediocrity — hiding unique self to fit in", circuit: "Individual (Centering)" },
931
- 9: { name: "Focus", hexagram: "Hex 9 — The Taming Power of the Small", keynote: "Determination and focus on detail", gift: "Determination — laser focus on what matters", shadow: "Inertia — scattered, unable to concentrate", circuit: "Collective (Logic)" },
932
- 10: { name: "Behaviour of the Self", hexagram: "Hex 10 — Treading", keynote: "Love of self, self-empowerment", gift: "Naturalness — authentic behaviour without self-consciousness", shadow: "Self-obsession — behaviour driven by approval-seeking", circuit: "Individual (Centering)" },
933
- 11: { name: "Ideas", hexagram: "Hex 11 — Peace", keynote: "The harmony of ideas", gift: "Idealism — ideas that envision greater harmony", shadow: "Obscurity — inability to ground and communicate visions", circuit: "Collective (Abstract)" },
934
- 12: { name: "Caution", hexagram: "Hex 12 — Standstill", keynote: "Active caution in social interaction", gift: "Discrimination — grace in social engagement", shadow: "Vanity — withdrawing emotionally from genuine connection", circuit: "Individual (Centering)" },
935
- 13: { name: "Fellowship of Man", hexagram: "Hex 13 — The Fellowship", keynote: "Universal listening", gift: "Empathy — the ear that holds others' stories", shadow: "Discord — secrets and betrayal", circuit: "Individual (Centering)" },
936
- 14: { name: "Power Skills", hexagram: "Hex 14 — Possession in Great Measure", keynote: "Accumulation of resources for collective good", gift: "Competence — using resources masterfully", shadow: "Compromise — accumulating for the wrong reasons", circuit: "Individual (Centering)" },
937
- 15: { name: "Extremes", hexagram: "Hex 15 — Modesty", keynote: "Extremes flow into the universal", gift: "Magnetism — extreme rhythms that attract the right others", shadow: "Dullness — inability to embrace natural extremes", circuit: "Individual (Centering)" },
938
- 16: { name: "Skills", hexagram: "Hex 16 — Enthusiasm", keynote: "Expressing talent with zeal", gift: "Versatility — enthusiastic expression of many skills", shadow: "Indifference — talent wasted by lack of drive", circuit: "Collective (Logic)" },
939
- 17: { name: "Opinions", hexagram: "Hex 17 — Following", keynote: "Opinions that help the collective move forward", gift: "Far-sightedness — opinions that serve the future", shadow: "Opinion — opinionating without wisdom", circuit: "Collective (Logic)" },
940
- 18: { name: "Correction", hexagram: "Hex 18 — Work on What Has Been Spoilt", keynote: "Judgment to find perfection", gift: "Integrity — correction that restores wholeness", shadow: "Judgment — criticism that wounds rather than heals", circuit: "Collective (Logic)" },
941
- 19: { name: "Wanting", hexagram: "Hex 19 — Approach", keynote: "Sensitivity to spirit and material needs", gift: "Sensitivity — awareness of unspoken needs", shadow: "Co-dependence — needs driving all decisions", circuit: "Tribal (Defence)" },
942
- 20: { name: "Contemplation", hexagram: "Hex 20 — Contemplation", keynote: "Presence in the now", gift: "Self-assurance — expressing truth in the moment", shadow: "Superficiality — words without depth", circuit: "Individual (Centering)" },
943
- 21: { name: "The Treasurer", hexagram: "Hex 21 — Biting Through", keynote: "Self-regulation and control in the material world", gift: "Authority — control exercised with integrity", shadow: "Control — possessiveness and domination", circuit: "Tribal (Ego)" },
944
- 22: { name: "Openness", hexagram: "Hex 22 — Grace", keynote: "The quality of emotional grace", gift: "Graciousness — emotional openness that transforms", shadow: "Dishonour — emotional withdrawal and defence", circuit: "Individual (Centering)" },
945
- 23: { name: "Splitting Apart", hexagram: "Hex 23 — Splitting Apart", keynote: "Translating the unique into language others can receive", gift: "Simplicity — the gift of making the complex clear", shadow: "Complexity — information without context or timing", circuit: "Individual (Centering)" },
946
- 24: { name: "Rationalisation", hexagram: "Hex 24 — Return", keynote: "The blessings of mental return and review", gift: "Invention — turning contemplation into breakthrough", shadow: "Addiction — mental looping without resolution", circuit: "Individual (Knowing)" },
947
- 25: { name: "Innocence", hexagram: "Hex 25 — Innocence", keynote: "The wisdom of innocence and universalising love", gift: "Acceptance — love without conditions or agenda", shadow: "Cruelty — the pain of love withheld", circuit: "Individual (Centering)" },
948
- 26: { name: "The Taming Power of the Great", hexagram: "Hex 26 — Taming", keynote: "Skilful transmitting of information", gift: "Artfulness — the gift of efficient, compelling communication", shadow: "Covetousness — ego-driven manipulation", circuit: "Tribal (Ego)" },
949
- 27: { name: "Caring", hexagram: "Hex 27 — Nourishment", keynote: "Preservation and nurturing", gift: "Altruism — sustaining others from genuine care", shadow: "Selfishness — nurturing only what benefits the self", circuit: "Tribal (Defence)" },
950
- 28: { name: "The Game Player", hexagram: "Hex 28 — Preponderance of the Great", keynote: "Finding purpose in struggle", gift: "Totality — fully committing to what gives life meaning", shadow: "Purposelessness — gambling with life's purpose", circuit: "Individual (Knowing)" },
951
- 29: { name: "The Abysmal", hexagram: "Hex 29 — The Abysmal", keynote: "Commitment and perseverance", gift: "Commitment — deep yes to what the sacral confirms", shadow: "Half-heartedness — over-committed without response", circuit: "Collective (Abstract)" },
952
- 30: { name: "Feelings", hexagram: "Hex 30 — The Clinging", keynote: "Recognition and feeling of experience", gift: "Lightness — riding the wave without being swept away", shadow: "Desire — driven by emotional craving", circuit: "Collective (Abstract)" },
953
- 31: { name: "Influence", hexagram: "Hex 31 — Influence", keynote: "Leading through democratic means", gift: "Leadership — influence through example and invitation", shadow: "Arrogance — influence through position rather than merit", circuit: "Collective (Logic)" },
954
- 32: { name: "Continuity", hexagram: "Hex 32 — Duration", keynote: "Intuitive assessment of what endures", gift: "Preservation — knowing what is worth preserving", shadow: "Failure — fear of failure blocking right assessment", circuit: "Tribal (Defence)" },
955
- 33: { name: "Privacy", hexagram: "Hex 33 — Retreat", keynote: "Knowing when to retreat and share later wisdom", gift: "Revelation — wisdom shared at the right time", shadow: "Forgetting — retreat without integration", circuit: "Collective (Abstract)" },
956
- 34: { name: "Power", hexagram: "Hex 34 — The Power of the Great", keynote: "Manifestation of power through response", gift: "Strength — responsive power that transforms", shadow: "Force — power without direction or response", circuit: "Individual (Centering)" },
957
- 35: { name: "Change", hexagram: "Hex 35 — Progress", keynote: "The hunger for experience", gift: "Adventure — embracing change for collective growth", shadow: "Hunger — chasing experience to fill an inner void", circuit: "Collective (Abstract)" },
958
- 36: { name: "Crisis", hexagram: "Hex 36 — Darkening of the Light", keynote: "The need for emotional experience as teacher", gift: "Humanity — finding compassion through crisis survived", shadow: "Turbulence — emotionally driven chaos and drama", circuit: "Collective (Abstract)" },
959
- 37: { name: "Friendship", hexagram: "Hex 37 — The Family", keynote: "Harmony through clear agreements in relationship", gift: "Equality — friendship built on mutual respect", shadow: "Inequality — bargaining and conditional love", circuit: "Tribal (Ego)" },
960
- 38: { name: "The Fighter", hexagram: "Hex 38 — Opposition", keynote: "Struggle in the search for purpose", gift: "Perseverance — fighting for what is meaningful", shadow: "Struggle — fighting against everything without purpose", circuit: "Individual (Knowing)" },
961
- 39: { name: "Provocation", hexagram: "Hex 39 — Obstruction", keynote: "Freeing the spirit through provocation", gift: "Dynamism — provocateur that liberates", shadow: "Provocation — stirring trouble unconsciously", circuit: "Individual (Knowing)" },
962
- 40: { name: "Aloneness", hexagram: "Hex 40 — Deliverance", keynote: "The demand for aloneness as restoration", gift: "Resolve — willpower renewed in solitude", shadow: "Exhaustion — depleted by giving without replenishment", circuit: "Tribal (Ego)" },
963
- 41: { name: "Contraction", hexagram: "Hex 41 — Decrease", keynote: "The beginning of all experience — fantasy and desire", gift: "Fantasy — imagination that seeds new experience", shadow: "Escapism — escapism", circuit: "Collective (Abstract)" },
964
- 42: { name: "Growth", hexagram: "Hex 42 — Increase", keynote: "The ability to perpetuate and complete growth cycles", gift: "Detachment — completing cycles with grace", shadow: "Incompletion — abandoning cycles before they end", circuit: "Collective (Abstract)" },
965
- 43: { name: "Insight", hexagram: "Hex 43 — Breakthrough", keynote: "Breakthrough from within", gift: "Insight — inner knowing that arrives as genius", shadow: "Deafness — genius unrecognised or unheard", circuit: "Individual (Knowing)" },
966
- 44: { name: "Alertness", hexagram: "Hex 44 — Coming to Meet", keynote: "Instinctive memory and pattern recognition", gift: "Teamwork — bringing the right people together", shadow: "Interference — driven by karmic patterns from the past", circuit: "Tribal (Defence)" },
967
- 45: { name: "The Gatherer", hexagram: "Hex 45 — Gathering Together", keynote: "Ruling and gathering resources for the tribe", gift: "Synergy — the king/queen who gathers and empowers", shadow: "Dominance — ruling through control", circuit: "Tribal (Ego)" },
968
- 46: { name: "The Serendipitous", hexagram: "Hex 46 — Pushing Upward", keynote: "Love of the body and serendipity", gift: "Delight — inhabiting the body fully", shadow: "Seriousness — disconnected from physical joy", circuit: "Individual (Centering)" },
969
- 47: { name: "Realisation", hexagram: "Hex 47 — Oppression", keynote: "The realisation that transforms oppression", gift: "Realisation — finding the gem in difficult experience", shadow: "Oppression — trapped in mental suffering", circuit: "Collective (Abstract)" },
970
- 48: { name: "Well", hexagram: "Hex 48 — The Well", keynote: "The depth that provides solutions", gift: "Resourcefulness — drawing from a depth of wisdom", shadow: "Inadequacy — fear of not being deep enough", circuit: "Collective (Logic)" },
971
- 49: { name: "Revolution", hexagram: "Hex 49 — Revolution", keynote: "Sensitivity to right principles", gift: "Revolution — principled transformation", shadow: "Reaction — rejection driven by fear", circuit: "Tribal (Defence)" },
972
- 50: { name: "Values", hexagram: "Hex 50 — The Cauldron", keynote: "Values for humanity's nourishment", gift: "Responsibility — holding values that sustain the tribe", shadow: "Corruption — values compromised for survival", circuit: "Tribal (Defence)" },
973
- 51: { name: "The Arousing", hexagram: "Hex 51 — The Arousing", keynote: "The shock that awakens spirit", gift: "Initiative — shock as awakening force", shadow: "Agitation — disruption without purpose", circuit: "Individual (Centering)" },
974
- 52: { name: "Concentration", hexagram: "Hex 52 — Keeping Still", keynote: "Concentration and stillness as a power", gift: "Restraint — focused stillness that creates mastery", shadow: "Stress — adrenal pressure without direction", circuit: "Collective (Logic)" },
975
- 53: { name: "Beginnings", hexagram: "Hex 53 — Development", keynote: "Pressure to start new cycles", gift: "Expansion — initiating growth cycles", shadow: "Immaturity — starting without completing", circuit: "Collective (Abstract)" },
976
- 54: { name: "Ambition", hexagram: "Hex 54 — The Marrying Maiden", keynote: "The transformative fuel of ambition", gift: "Aspiration — ambition that elevates all", shadow: "Greed — reaching for position at others' expense", circuit: "Tribal (Defence)" },
977
- 55: { name: "Abundance", hexagram: "Hex 55 — Abundance", keynote: "Emotional abundance and spirit", gift: "Freedom — emotional richness surrendered to spirit", shadow: "Victimisation — emotional suffering without spirit", circuit: "Individual (Knowing)" },
978
- 56: { name: "Stimulation", hexagram: "Hex 56 — The Wanderer", keynote: "Stimulating stories and beliefs", gift: "Enrichment — stories that expand perspective", shadow: "Distraction — stories that mislead", circuit: "Collective (Abstract)" },
979
- 57: { name: "Intuitive Insight", hexagram: "Hex 57 — The Gentle", keynote: "Intuitive insight in the now", gift: "Clarity — penetrating intuition that clears confusion", shadow: "Unease — anxiety from ignoring the body's signals", circuit: "Individual (Knowing)" },
980
- 58: { name: "Vitality", hexagram: "Hex 58 — The Joyous", keynote: "Vitality and the joy of life", gift: "Vitality — life-force expressed as joy", shadow: "Dissatisfaction — criticism of what is imperfect", circuit: "Collective (Logic)" },
981
- 59: { name: "Sexuality", hexagram: "Hex 59 — Dispersion", keynote: "Intimacy and aura penetration", gift: "Intimacy — dissolving the aura safely into union", shadow: "Dishonesty — seduction without regard for truth", circuit: "Tribal (Defence)" },
982
- 60: { name: "Acceptance", hexagram: "Hex 60 — Limitation", keynote: "Acceptance of limitation as the basis for transcendence", gift: "Realism — working within constraints creatively", shadow: "Conservatism — clinging to limitation as identity", circuit: "Individual (Knowing)" },
983
- 61: { name: "Mystery", hexagram: "Hex 61 — Inner Truth", keynote: "The pressure to understand the unknowable", gift: "Inspiration — inner knowing beyond logic", shadow: "Psychosis — consumed by the search for unknowable truths", circuit: "Individual (Knowing)" },
984
- 62: { name: "Detail", hexagram: "Hex 62 — Preponderance of the Small", keynote: "The precision of detail and naming", gift: "Precision — detail that serves communication", shadow: "Intellectualism — detail without substance", circuit: "Collective (Logic)" },
985
- 63: { name: "Doubt", hexagram: "Hex 63 — After Completion", keynote: "Logical doubt as a mental pressure", gift: "Inquiry — questioning that leads to new solutions", shadow: "Doubt — anxiety about an unknowable future", circuit: "Collective (Logic)" },
986
- 64: { name: "Confusion", hexagram: "Hex 64 — Before Completion", keynote: "The inspiration pressure before clarity", gift: "Imagination — holding confusion long enough for illumination", shadow: "Confusion — overwhelmed by unresolved mental images", circuit: "Collective (Abstract)" },
883
+ 1: { name: "The Creative", hexagram: "Hex 1 — Creative Power", keynote: "Self-expression as a creative force", gift: "Freshness — original self-expression that inspires", shadow: "Entropy — creative block from fear of not being unique", circuit: "Individual (Centering)" },
884
+ 2: { name: "The Receptive", hexagram: "Hex 2 — Receptive Power", keynote: "The direction of the self", gift: "Orientation — knowing where to go", shadow: "Dislocation — living without inner compass", circuit: "Individual (Centering)" },
885
+ 3: { name: "Ordering", hexagram: "Hex 3 — Difficulty at the Beginning", keynote: "Innovation from chaos", gift: "Innovation — bringing order from initial confusion", shadow: "Chaos — stuck in mutation, unable to stabilise", circuit: "Individual (Centering)" },
886
+ 4: { name: "Formulization", hexagram: "Hex 4 — Youthful Folly", keynote: "Mental solutions that benefit humanity", gift: "Understanding — solutions that help the collective", shadow: "Incompetence — mental answers that cause harm", circuit: "Collective (Logic)" },
887
+ 5: { name: "Fixed Rhythms", hexagram: "Hex 5 — Waiting", keynote: "Universal patterns and timing", gift: "Patience — trusting the correct timing", shadow: "Impatience — forcing outcomes", circuit: "Collective (Logic)" },
888
+ 6: { name: "Friction", hexagram: "Hex 6 — Conflict", keynote: "The role model through experience", gift: "Diplomacy — conflict resolved through right relationship", shadow: "Conflict — isolation and withdrawal", circuit: "Collective (Logic)" },
889
+ 7: { name: "The Role of the Self", hexagram: "Hex 7 — The Army", keynote: "Leadership in the direction of the future", gift: "Guidance — leading through personal example", shadow: "Division — leadership without authority", circuit: "Collective (Logic)" },
890
+ 8: { name: "Contribution", hexagram: "Hex 8 — Holding Together", keynote: "Contribution to the collective through individual creativity", gift: "Style — unique contribution that inspires others", shadow: "Mediocrity — hiding unique self to fit in", circuit: "Individual (Centering)" },
891
+ 9: { name: "Focus", hexagram: "Hex 9 — The Taming Power of the Small", keynote: "Determination and focus on detail", gift: "Determination — laser focus on what matters", shadow: "Inertia — scattered, unable to concentrate", circuit: "Collective (Logic)" },
892
+ 10: { name: "Behaviour of the Self", hexagram: "Hex 10 — Treading", keynote: "Love of self, self-empowerment", gift: "Naturalness — authentic behaviour without self-consciousness", shadow: "Self-obsession — behaviour driven by approval-seeking", circuit: "Individual (Centering)" },
893
+ 11: { name: "Ideas", hexagram: "Hex 11 — Peace", keynote: "The harmony of ideas", gift: "Idealism — ideas that envision greater harmony", shadow: "Obscurity — inability to ground and communicate visions", circuit: "Collective (Abstract)" },
894
+ 12: { name: "Caution", hexagram: "Hex 12 — Standstill", keynote: "Active caution in social interaction", gift: "Discrimination — grace in social engagement", shadow: "Vanity — withdrawing emotionally from genuine connection", circuit: "Individual (Centering)" },
895
+ 13: { name: "Fellowship of Man", hexagram: "Hex 13 — The Fellowship", keynote: "Universal listening", gift: "Empathy — the ear that holds others' stories", shadow: "Discord — secrets and betrayal", circuit: "Individual (Centering)" },
896
+ 14: { name: "Power Skills", hexagram: "Hex 14 — Possession in Great Measure", keynote: "Accumulation of resources for collective good", gift: "Competence — using resources masterfully", shadow: "Compromise — accumulating for the wrong reasons", circuit: "Individual (Centering)" },
897
+ 15: { name: "Extremes", hexagram: "Hex 15 — Modesty", keynote: "Extremes flow into the universal", gift: "Magnetism — extreme rhythms that attract the right others", shadow: "Dullness — inability to embrace natural extremes", circuit: "Individual (Centering)" },
898
+ 16: { name: "Skills", hexagram: "Hex 16 — Enthusiasm", keynote: "Expressing talent with zeal", gift: "Versatility — enthusiastic expression of many skills", shadow: "Indifference — talent wasted by lack of drive", circuit: "Collective (Logic)" },
899
+ 17: { name: "Opinions", hexagram: "Hex 17 — Following", keynote: "Opinions that help the collective move forward", gift: "Far-sightedness — opinions that serve the future", shadow: "Opinion — opinionating without wisdom", circuit: "Collective (Logic)" },
900
+ 18: { name: "Correction", hexagram: "Hex 18 — Work on What Has Been Spoilt", keynote: "Judgment to find perfection", gift: "Integrity — correction that restores wholeness", shadow: "Judgment — criticism that wounds rather than heals", circuit: "Collective (Logic)" },
901
+ 19: { name: "Wanting", hexagram: "Hex 19 — Approach", keynote: "Sensitivity to spirit and material needs", gift: "Sensitivity — awareness of unspoken needs", shadow: "Co-dependence — needs driving all decisions", circuit: "Tribal (Defence)" },
902
+ 20: { name: "Contemplation", hexagram: "Hex 20 — Contemplation", keynote: "Presence in the now", gift: "Self-assurance — expressing truth in the moment", shadow: "Superficiality — words without depth", circuit: "Individual (Centering)" },
903
+ 21: { name: "The Treasurer", hexagram: "Hex 21 — Biting Through", keynote: "Self-regulation and control in the material world", gift: "Authority — control exercised with integrity", shadow: "Control — possessiveness and domination", circuit: "Tribal (Ego)" },
904
+ 22: { name: "Openness", hexagram: "Hex 22 — Grace", keynote: "The quality of emotional grace", gift: "Graciousness — emotional openness that transforms", shadow: "Dishonour — emotional withdrawal and defence", circuit: "Individual (Centering)" },
905
+ 23: { name: "Splitting Apart", hexagram: "Hex 23 — Splitting Apart", keynote: "Translating the unique into language others can receive", gift: "Simplicity — the gift of making the complex clear", shadow: "Complexity — information without context or timing", circuit: "Individual (Centering)" },
906
+ 24: { name: "Rationalisation", hexagram: "Hex 24 — Return", keynote: "The blessings of mental return and review", gift: "Invention — turning contemplation into breakthrough", shadow: "Addiction — mental looping without resolution", circuit: "Individual (Knowing)" },
907
+ 25: { name: "Innocence", hexagram: "Hex 25 — Innocence", keynote: "The wisdom of innocence and universalising love", gift: "Acceptance — love without conditions or agenda", shadow: "Cruelty — the pain of love withheld", circuit: "Individual (Centering)" },
908
+ 26: { name: "The Taming Power of the Great", hexagram: "Hex 26 — Taming", keynote: "Skilful transmitting of information", gift: "Artfulness — the gift of efficient, compelling communication", shadow: "Covetousness — ego-driven manipulation", circuit: "Tribal (Ego)" },
909
+ 27: { name: "Caring", hexagram: "Hex 27 — Nourishment", keynote: "Preservation and nurturing", gift: "Altruism — sustaining others from genuine care", shadow: "Selfishness — nurturing only what benefits the self", circuit: "Tribal (Defence)" },
910
+ 28: { name: "The Game Player", hexagram: "Hex 28 — Preponderance of the Great", keynote: "Finding purpose in struggle", gift: "Totality — fully committing to what gives life meaning", shadow: "Purposelessness — gambling with life's purpose", circuit: "Individual (Knowing)" },
911
+ 29: { name: "The Abysmal", hexagram: "Hex 29 — The Abysmal", keynote: "Commitment and perseverance", gift: "Commitment — deep yes to what the sacral confirms", shadow: "Half-heartedness — over-committed without response", circuit: "Collective (Abstract)" },
912
+ 30: { name: "Feelings", hexagram: "Hex 30 — The Clinging", keynote: "Recognition and feeling of experience", gift: "Lightness — riding the wave without being swept away", shadow: "Desire — driven by emotional craving", circuit: "Collective (Abstract)" },
913
+ 31: { name: "Influence", hexagram: "Hex 31 — Influence", keynote: "Leading through democratic means", gift: "Leadership — influence through example and invitation", shadow: "Arrogance — influence through position rather than merit", circuit: "Collective (Logic)" },
914
+ 32: { name: "Continuity", hexagram: "Hex 32 — Duration", keynote: "Intuitive assessment of what endures", gift: "Preservation — knowing what is worth preserving", shadow: "Failure — fear of failure blocking right assessment", circuit: "Tribal (Defence)" },
915
+ 33: { name: "Privacy", hexagram: "Hex 33 — Retreat", keynote: "Knowing when to retreat and share later wisdom", gift: "Revelation — wisdom shared at the right time", shadow: "Forgetting — retreat without integration", circuit: "Collective (Abstract)" },
916
+ 34: { name: "Power", hexagram: "Hex 34 — The Power of the Great", keynote: "Manifestation of power through response", gift: "Strength — responsive power that transforms", shadow: "Force — power without direction or response", circuit: "Individual (Centering)" },
917
+ 35: { name: "Change", hexagram: "Hex 35 — Progress", keynote: "The hunger for experience", gift: "Adventure — embracing change for collective growth", shadow: "Hunger — chasing experience to fill an inner void", circuit: "Collective (Abstract)" },
918
+ 36: { name: "Crisis", hexagram: "Hex 36 — Darkening of the Light", keynote: "The need for emotional experience as teacher", gift: "Humanity — finding compassion through crisis survived", shadow: "Turbulence — emotionally driven chaos and drama", circuit: "Collective (Abstract)" },
919
+ 37: { name: "Friendship", hexagram: "Hex 37 — The Family", keynote: "Harmony through clear agreements in relationship", gift: "Equality — friendship built on mutual respect", shadow: "Inequality — bargaining and conditional love", circuit: "Tribal (Ego)" },
920
+ 38: { name: "The Fighter", hexagram: "Hex 38 — Opposition", keynote: "Struggle in the search for purpose", gift: "Perseverance — fighting for what is meaningful", shadow: "Struggle — fighting against everything without purpose", circuit: "Individual (Knowing)" },
921
+ 39: { name: "Provocation", hexagram: "Hex 39 — Obstruction", keynote: "Freeing the spirit through provocation", gift: "Dynamism — provocateur that liberates", shadow: "Provocation — stirring trouble unconsciously", circuit: "Individual (Knowing)" },
922
+ 40: { name: "Aloneness", hexagram: "Hex 40 — Deliverance", keynote: "The demand for aloneness as restoration", gift: "Resolve — willpower renewed in solitude", shadow: "Exhaustion — depleted by giving without replenishment", circuit: "Tribal (Ego)" },
923
+ 41: { name: "Contraction", hexagram: "Hex 41 — Decrease", keynote: "The beginning of all experience — fantasy and desire", gift: "Fantasy — imagination that seeds new experience", shadow: "Escapism — escapism", circuit: "Collective (Abstract)" },
924
+ 42: { name: "Growth", hexagram: "Hex 42 — Increase", keynote: "The ability to perpetuate and complete growth cycles", gift: "Detachment — completing cycles with grace", shadow: "Incompletion — abandoning cycles before they end", circuit: "Collective (Abstract)" },
925
+ 43: { name: "Insight", hexagram: "Hex 43 — Breakthrough", keynote: "Breakthrough from within", gift: "Insight — inner knowing that arrives as genius", shadow: "Deafness — genius unrecognised or unheard", circuit: "Individual (Knowing)" },
926
+ 44: { name: "Alertness", hexagram: "Hex 44 — Coming to Meet", keynote: "Instinctive memory and pattern recognition", gift: "Teamwork — bringing the right people together", shadow: "Interference — driven by karmic patterns from the past", circuit: "Tribal (Defence)" },
927
+ 45: { name: "The Gatherer", hexagram: "Hex 45 — Gathering Together", keynote: "Ruling and gathering resources for the tribe", gift: "Synergy — the king/queen who gathers and empowers", shadow: "Dominance — ruling through control", circuit: "Tribal (Ego)" },
928
+ 46: { name: "The Serendipitous", hexagram: "Hex 46 — Pushing Upward", keynote: "Love of the body and serendipity", gift: "Delight — inhabiting the body fully", shadow: "Seriousness — disconnected from physical joy", circuit: "Individual (Centering)" },
929
+ 47: { name: "Realisation", hexagram: "Hex 47 — Oppression", keynote: "The realisation that transforms oppression", gift: "Realisation — finding the gem in difficult experience", shadow: "Oppression — trapped in mental suffering", circuit: "Collective (Abstract)" },
930
+ 48: { name: "Well", hexagram: "Hex 48 — The Well", keynote: "The depth that provides solutions", gift: "Resourcefulness — drawing from a depth of wisdom", shadow: "Inadequacy — fear of not being deep enough", circuit: "Collective (Logic)" },
931
+ 49: { name: "Revolution", hexagram: "Hex 49 — Revolution", keynote: "Sensitivity to right principles", gift: "Revolution — principled transformation", shadow: "Reaction — rejection driven by fear", circuit: "Tribal (Defence)" },
932
+ 50: { name: "Values", hexagram: "Hex 50 — The Cauldron", keynote: "Values for humanity's nourishment", gift: "Responsibility — holding values that sustain the tribe", shadow: "Corruption — values compromised for survival", circuit: "Tribal (Defence)" },
933
+ 51: { name: "The Arousing", hexagram: "Hex 51 — The Arousing", keynote: "The shock that awakens spirit", gift: "Initiative — shock as awakening force", shadow: "Agitation — disruption without purpose", circuit: "Individual (Centering)" },
934
+ 52: { name: "Concentration", hexagram: "Hex 52 — Keeping Still", keynote: "Concentration and stillness as a power", gift: "Restraint — focused stillness that creates mastery", shadow: "Stress — adrenal pressure without direction", circuit: "Collective (Logic)" },
935
+ 53: { name: "Beginnings", hexagram: "Hex 53 — Development", keynote: "Pressure to start new cycles", gift: "Expansion — initiating growth cycles", shadow: "Immaturity — starting without completing", circuit: "Collective (Abstract)" },
936
+ 54: { name: "Ambition", hexagram: "Hex 54 — The Marrying Maiden", keynote: "The transformative fuel of ambition", gift: "Aspiration — ambition that elevates all", shadow: "Greed — reaching for position at others' expense", circuit: "Tribal (Defence)" },
937
+ 55: { name: "Abundance", hexagram: "Hex 55 — Abundance", keynote: "Emotional abundance and spirit", gift: "Freedom — emotional richness surrendered to spirit", shadow: "Victimisation — emotional suffering without spirit", circuit: "Individual (Knowing)" },
938
+ 56: { name: "Stimulation", hexagram: "Hex 56 — The Wanderer", keynote: "Stimulating stories and beliefs", gift: "Enrichment — stories that expand perspective", shadow: "Distraction — stories that mislead", circuit: "Collective (Abstract)" },
939
+ 57: { name: "Intuitive Insight", hexagram: "Hex 57 — The Gentle", keynote: "Intuitive insight in the now", gift: "Clarity — penetrating intuition that clears confusion", shadow: "Unease — anxiety from ignoring the body's signals", circuit: "Individual (Knowing)" },
940
+ 58: { name: "Vitality", hexagram: "Hex 58 — The Joyous", keynote: "Vitality and the joy of life", gift: "Vitality — life-force expressed as joy", shadow: "Dissatisfaction — criticism of what is imperfect", circuit: "Collective (Logic)" },
941
+ 59: { name: "Sexuality", hexagram: "Hex 59 — Dispersion", keynote: "Intimacy and aura penetration", gift: "Intimacy — dissolving the aura safely into union", shadow: "Dishonesty — seduction without regard for truth", circuit: "Tribal (Defence)" },
942
+ 60: { name: "Acceptance", hexagram: "Hex 60 — Limitation", keynote: "Acceptance of limitation as the basis for transcendence", gift: "Realism — working within constraints creatively", shadow: "Conservatism — clinging to limitation as identity", circuit: "Individual (Knowing)" },
943
+ 61: { name: "Mystery", hexagram: "Hex 61 — Inner Truth", keynote: "The pressure to understand the unknowable", gift: "Inspiration — inner knowing beyond logic", shadow: "Psychosis — consumed by the search for unknowable truths", circuit: "Individual (Knowing)" },
944
+ 62: { name: "Detail", hexagram: "Hex 62 — Preponderance of the Small", keynote: "The precision of detail and naming", gift: "Precision — detail that serves communication", shadow: "Intellectualism — detail without substance", circuit: "Collective (Logic)" },
945
+ 63: { name: "Doubt", hexagram: "Hex 63 — After Completion", keynote: "Logical doubt as a mental pressure", gift: "Inquiry — questioning that leads to new solutions", shadow: "Doubt — anxiety about an unknowable future", circuit: "Collective (Logic)" },
946
+ 64: { name: "Confusion", hexagram: "Hex 64 — Before Completion", keynote: "The inspiration pressure before clarity", gift: "Imagination — holding confusion long enough for illumination", shadow: "Confusion — overwhelmed by unresolved mental images", circuit: "Collective (Abstract)" },
987
947
  };
988
948
  const HD_CHANNEL_DATA = {
989
- "1-8": { name: "Inspiration", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of creative inspiration — a unique individual frequency that inspires others through authentic self-expression. Not designed to broadcast; waits for recognition." },
990
- "2-14": { name: "The Beat", circuit: "Individual (Centering)", energy_type: "generated", description: "The channel of the keeper of keys — a powerful sacral motor connected to the G center's direction. Attracts others magnetically toward purposeful resource accumulation." },
991
- "3-60": { name: "Mutation", circuit: "Individual (Knowing)", energy_type: "generated", description: "The channel of mutation — energy that transforms through accepted limitation. Initiates new patterns in a discontinuous, pulse-like fashion that disrupts the old." },
992
- "4-63": { name: "Logic", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of mental logic — pressure and solutions meeting in a cycle of questioning and formulizing. Mental energy that must wait to be asked before offering answers." },
993
- "5-15": { name: "Rhythm", circuit: "Collective (Logic)", energy_type: "generated", description: "The channel of fixed rhythms — humanity's flow and fixed patterns. Sacral motor powering universal timing; key to humanity's biological health rhythms." },
994
- "6-59": { name: "Intimacy", circuit: "Tribal (Defence)", energy_type: "generated", description: "The channel of intimacy — penetrating auras for mating and reproduction. Emotional authority governing who is let past one's auric boundaries." },
995
- "7-31": { name: "The Alpha", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of the leader — democratic leadership providing direction to the collective. Recognition and invitation are essential; leadership must be elected, not seized." },
996
- "9-52": { name: "Concentration", circuit: "Collective (Logic)", energy_type: "generated", description: "The channel of the focused mind — detail and concentration driving sacral response. Sustains attention on a single thread of logic until it resolves." },
997
- "10-20": { name: "Awakening", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of awakening — the behaviour of the self expressed in the now. Presence and authenticity expressed without self-consciousness; a love of life in motion." },
998
- "10-34": { name: "Exploration", circuit: "Individual (Centering)", energy_type: "generated", description: "The channel of following one's convictions — sacral power directed toward authentic self-expression and exploration. Highly independent." },
999
- "10-57": { name: "Perfected Form", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of perfected form — survival instinct guided by intuition. Body awareness at its most refined; may produce physical beauty or extraordinary physical gifts." },
1000
- "11-56": { name: "Curiosity", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of the storyteller — abstract ideas turned into stimulating stories that expand others' perspectives. Conceptual awareness awaiting recognition." },
1001
- "12-22": { name: "Openness", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of openness — emotional grace in social engagement. When the wave is right, this channel opens conversations that can transform others profoundly." },
1002
- "13-33": { name: "The Prodigal", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of witness — listening to humanity's stories and retreating to share crystallised wisdom at the right time. The therapist channel." },
1003
- "16-48": { name: "The Wavelength", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of talent — depth of skill expressed as enthusiasm. Natural mastery that appears effortless; awakens when talents are recognised and invited." },
1004
- "17-62": { name: "Acceptance", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of organised activity — opinions formulated into detailed plans and frameworks. Facts and logic turned into workable systems." },
1005
- "18-58": { name: "Judgement", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of judgement — passionate criticism in service of joy and vitality. The desire to perfect what is alive; driven by love of life." },
1006
- "19-49": { name: "Synthesis", circuit: "Tribal (Defence)", energy_type: "projected", description: "The channel of synthesis — sensitivity to the tribe's emotional and material needs, combined with the power to revolutionise through principle. Resources and revolution." },
1007
- "20-34": { name: "Charisma", circuit: "Individual (Centering)", energy_type: "generated", description: "The channel of charisma — sacral response expressed in the now with extraordinary presence. Manifesting Generators often carry this channel; built for busy, impactful lives." },
1008
- "20-57": { name: "The Brain Wave", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of the brain wave — penetrating intuitive insight expressed without hesitation. A frequency that can inform the now with body-level knowing." },
1009
- "21-45": { name: "Money Line", circuit: "Tribal (Ego)", energy_type: "projected", description: "The channel of the money line — material world governance. Control over resources in the tribal hierarchy; the king/queen and the treasurer aligned." },
1010
- "23-43": { name: "Structuring", circuit: "Individual (Knowing)", energy_type: "projected", description: "The channel of structuring — translating individual genius into language that others can hear. The key is timing; genius shared before recognition falls on deaf ears." },
1011
- "24-61": { name: "Awareness", circuit: "Individual (Knowing)", energy_type: "projected", description: "The channel of awareness — mental pressure toward inner truth. Contemplative awareness cycling through questions until a genuine breakthrough arrives." },
1012
- "25-51": { name: "Initiation", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of initiation — innocence meeting the shock of the new. The shamanic channel; moves through crisis into universalising love." },
1013
- "26-44": { name: "Surrender", circuit: "Tribal (Defence)", energy_type: "projected", description: "The channel of surrender — ego memory and the transmission of the tribe's past patterns. Alert to what has and has not worked; a natural business channel." },
1014
- "27-50": { name: "Preservation", circuit: "Tribal (Defence)", energy_type: "generated", description: "The channel of preservation — nurturing and values sustaining the tribe across generations. The channel of the mother/father archetype; keeping what is valuable alive." },
1015
- "28-38": { name: "Struggle", circuit: "Individual (Knowing)", energy_type: "generated", description: "The channel of struggle — the game player meets the fighter in a search for purpose. Life is the game; the question is what is worth the fight." },
1016
- "29-46": { name: "Discovery", circuit: "Collective (Abstract)", energy_type: "generated", description: "The channel of discovery — sacral commitment to embodied experience. The body as the vehicle for serendipitous encounter; the great 'yes' to life." },
1017
- "30-41": { name: "Recognition", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of recognition — the beginning of all human experience. Emotional desire and fantasy that ignites new experiential cycles." },
1018
- "32-54": { name: "Transformation", circuit: "Tribal (Defence)", energy_type: "generated", description: "The channel of transformation — instinct to transform ambition into material continuity. What endures; which ambitions serve the tribe's long-term survival." },
1019
- "34-57": { name: "Power", circuit: "Individual (Centering)", energy_type: "generated", description: "The channel of power — sacral life-force guided by intuition. Raw responsive power with in-the-moment instinctive awareness; self-sufficient and magnetic." },
1020
- "35-36": { name: "Transitoriness", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of transitoriness — the hunger for experience and the emotional crisis of each encounter. Rich emotional lessons through fully-felt experience." },
1021
- "37-40": { name: "Community", circuit: "Tribal (Ego)", energy_type: "projected", description: "The channel of community — bargain and agreement sustaining the family/tribe. Willpower renewed through rest; clear deals that make community sustainable." },
1022
- "39-55": { name: "Emoting", circuit: "Individual (Knowing)", energy_type: "projected", description: "The channel of emoting — the provocateur meeting the spirit of abundance. Gate 39 stirs the emotional wave; gate 55 determines whether spirit or suffering answers." },
1023
- "42-53": { name: "Maturation", circuit: "Collective (Abstract)", energy_type: "generated", description: "The channel of maturation — beginning and completing cycles of growth. The channel of sustainability; sacral energy that completes what it starts." },
1024
- "47-64": { name: "Abstraction", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of abstraction — confusion ripening into realisation. Mental pressure from the past meeting images from the future; the alchemy of wisdom." },
1025
- "57-20": { name: "The Brain Wave", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of the brain wave — penetrating intuitive insight expressed without hesitation. A frequency that can inform the now with body-level knowing." },
1026
- "58-18": { name: "Judgement", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of judgement — vitality and correction. Joy arising from the pursuit of perfection in what is living and alive." },
1027
- "59-6": { name: "Intimacy", circuit: "Tribal (Defence)", energy_type: "generated", description: "The channel of intimacy — penetrating auras for mating and reproduction. Emotional authority governing who is let past one's auric boundaries." },
1028
- "60-3": { name: "Mutation", circuit: "Individual (Knowing)", energy_type: "generated", description: "The channel of mutation — energy that transforms through accepted limitation. Initiates new patterns in a discontinuous, pulse-like fashion." },
949
+ "1-8": { name: "Inspiration", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of creative inspiration — a unique individual frequency that inspires others through authentic self-expression. Not designed to broadcast; waits for recognition." },
950
+ "2-14": { name: "The Beat", circuit: "Individual (Centering)", energy_type: "generated", description: "The channel of the keeper of keys — a powerful sacral motor connected to the G center's direction. Attracts others magnetically toward purposeful resource accumulation." },
951
+ "3-60": { name: "Mutation", circuit: "Individual (Knowing)", energy_type: "generated", description: "The channel of mutation — energy that transforms through accepted limitation. Initiates new patterns in a discontinuous, pulse-like fashion that disrupts the old." },
952
+ "4-63": { name: "Logic", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of mental logic — pressure and solutions meeting in a cycle of questioning and formulizing. Mental energy that must wait to be asked before offering answers." },
953
+ "5-15": { name: "Rhythm", circuit: "Collective (Logic)", energy_type: "generated", description: "The channel of fixed rhythms — humanity's flow and fixed patterns. Sacral motor powering universal timing; key to humanity's biological health rhythms." },
954
+ "6-59": { name: "Intimacy", circuit: "Tribal (Defence)", energy_type: "generated", description: "The channel of intimacy — penetrating auras for mating and reproduction. Emotional authority governing who is let past one's auric boundaries." },
955
+ "7-31": { name: "The Alpha", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of the leader — democratic leadership providing direction to the collective. Recognition and invitation are essential; leadership must be elected, not seized." },
956
+ "9-52": { name: "Concentration", circuit: "Collective (Logic)", energy_type: "generated", description: "The channel of the focused mind — detail and concentration driving sacral response. Sustains attention on a single thread of logic until it resolves." },
957
+ "10-20": { name: "Awakening", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of awakening — the behaviour of the self expressed in the now. Presence and authenticity expressed without self-consciousness; a love of life in motion." },
958
+ "10-34": { name: "Exploration", circuit: "Individual (Centering)", energy_type: "generated", description: "The channel of following one's convictions — sacral power directed toward authentic self-expression and exploration. Highly independent." },
959
+ "10-57": { name: "Perfected Form", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of perfected form — survival instinct guided by intuition. Body awareness at its most refined; may produce physical beauty or extraordinary physical gifts." },
960
+ "11-56": { name: "Curiosity", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of the storyteller — abstract ideas turned into stimulating stories that expand others' perspectives. Conceptual awareness awaiting recognition." },
961
+ "12-22": { name: "Openness", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of openness — emotional grace in social engagement. When the wave is right, this channel opens conversations that can transform others profoundly." },
962
+ "13-33": { name: "The Prodigal", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of witness — listening to humanity's stories and retreating to share crystallised wisdom at the right time. The therapist channel." },
963
+ "16-48": { name: "The Wavelength", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of talent — depth of skill expressed as enthusiasm. Natural mastery that appears effortless; awakens when talents are recognised and invited." },
964
+ "17-62": { name: "Acceptance", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of organised activity — opinions formulated into detailed plans and frameworks. Facts and logic turned into workable systems." },
965
+ "18-58": { name: "Judgement", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of judgement — passionate criticism in service of joy and vitality. The desire to perfect what is alive; driven by love of life." },
966
+ "19-49": { name: "Synthesis", circuit: "Tribal (Defence)", energy_type: "projected", description: "The channel of synthesis — sensitivity to the tribe's emotional and material needs, combined with the power to revolutionise through principle. Resources and revolution." },
967
+ "20-34": { name: "Charisma", circuit: "Individual (Centering)", energy_type: "generated", description: "The channel of charisma — sacral response expressed in the now with extraordinary presence. Manifesting Generators often carry this channel; built for busy, impactful lives." },
968
+ "20-57": { name: "The Brain Wave", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of the brain wave — penetrating intuitive insight expressed without hesitation. A frequency that can inform the now with body-level knowing." },
969
+ "21-45": { name: "Money Line", circuit: "Tribal (Ego)", energy_type: "projected", description: "The channel of the money line — material world governance. Control over resources in the tribal hierarchy; the king/queen and the treasurer aligned." },
970
+ "23-43": { name: "Structuring", circuit: "Individual (Knowing)", energy_type: "projected", description: "The channel of structuring — translating individual genius into language that others can hear. The key is timing; genius shared before recognition falls on deaf ears." },
971
+ "24-61": { name: "Awareness", circuit: "Individual (Knowing)", energy_type: "projected", description: "The channel of awareness — mental pressure toward inner truth. Contemplative awareness cycling through questions until a genuine breakthrough arrives." },
972
+ "25-51": { name: "Initiation", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of initiation — innocence meeting the shock of the new. The shamanic channel; moves through crisis into universalising love." },
973
+ "26-44": { name: "Surrender", circuit: "Tribal (Defence)", energy_type: "projected", description: "The channel of surrender — ego memory and the transmission of the tribe's past patterns. Alert to what has and has not worked; a natural business channel." },
974
+ "27-50": { name: "Preservation", circuit: "Tribal (Defence)", energy_type: "generated", description: "The channel of preservation — nurturing and values sustaining the tribe across generations. The channel of the mother/father archetype; keeping what is valuable alive." },
975
+ "28-38": { name: "Struggle", circuit: "Individual (Knowing)", energy_type: "generated", description: "The channel of struggle — the game player meets the fighter in a search for purpose. Life is the game; the question is what is worth the fight." },
976
+ "29-46": { name: "Discovery", circuit: "Collective (Abstract)", energy_type: "generated", description: "The channel of discovery — sacral commitment to embodied experience. The body as the vehicle for serendipitous encounter; the great 'yes' to life." },
977
+ "30-41": { name: "Recognition", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of recognition — the beginning of all human experience. Emotional desire and fantasy that ignites new experiential cycles." },
978
+ "32-54": { name: "Transformation", circuit: "Tribal (Defence)", energy_type: "generated", description: "The channel of transformation — instinct to transform ambition into material continuity. What endures; which ambitions serve the tribe's long-term survival." },
979
+ "34-57": { name: "Power", circuit: "Individual (Centering)", energy_type: "generated", description: "The channel of power — sacral life-force guided by intuition. Raw responsive power with in-the-moment instinctive awareness; self-sufficient and magnetic." },
980
+ "35-36": { name: "Transitoriness", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of transitoriness — the hunger for experience and the emotional crisis of each encounter. Rich emotional lessons through fully-felt experience." },
981
+ "37-40": { name: "Community", circuit: "Tribal (Ego)", energy_type: "projected", description: "The channel of community — bargain and agreement sustaining the family/tribe. Willpower renewed through rest; clear deals that make community sustainable." },
982
+ "39-55": { name: "Emoting", circuit: "Individual (Knowing)", energy_type: "projected", description: "The channel of emoting — the provocateur meeting the spirit of abundance. Gate 39 stirs the emotional wave; gate 55 determines whether spirit or suffering answers." },
983
+ "42-53": { name: "Maturation", circuit: "Collective (Abstract)", energy_type: "generated", description: "The channel of maturation — beginning and completing cycles of growth. The channel of sustainability; sacral energy that completes what it starts." },
984
+ "47-64": { name: "Abstraction", circuit: "Collective (Abstract)", energy_type: "projected", description: "The channel of abstraction — confusion ripening into realisation. Mental pressure from the past meeting images from the future; the alchemy of wisdom." },
985
+ "57-20": { name: "The Brain Wave", circuit: "Individual (Centering)", energy_type: "projected", description: "The channel of the brain wave — penetrating intuitive insight expressed without hesitation. A frequency that can inform the now with body-level knowing." },
986
+ "58-18": { name: "Judgement", circuit: "Collective (Logic)", energy_type: "projected", description: "The channel of judgement — vitality and correction. Joy arising from the pursuit of perfection in what is living and alive." },
987
+ "59-6": { name: "Intimacy", circuit: "Tribal (Defence)", energy_type: "generated", description: "The channel of intimacy — penetrating auras for mating and reproduction. Emotional authority governing who is let past one's auric boundaries." },
988
+ "60-3": { name: "Mutation", circuit: "Individual (Knowing)", energy_type: "generated", description: "The channel of mutation — energy that transforms through accepted limitation. Initiates new patterns in a discontinuous, pulse-like fashion." },
1029
989
  };
1030
990
  // ── Planet biographical themes (shared across tools) ─────────────────────────────
1031
991
  const HD_PLANET_HD_THEMES = {
@@ -1349,7 +1309,7 @@ registerTool({
1349
1309
  },
1350
1310
  latitude: { type: "number", description: "Natal birth latitude (decimal degrees, +N). Optional." },
1351
1311
  longitude: { type: "number", description: "Natal birth longitude (decimal degrees, +E). Optional." },
1352
- location: { type: "string", description: "Natal location name, display only." },
1312
+ location: { type: "string", description: "Natal location name, display only. This is a caption, NOT a geocoder — it does not set the chart location. Supply latitude/longitude too (resolve them with location_search), or the chart is computed at 0N 0E." },
1353
1313
  timezone: { type: "string", description: "IANA timezone for the birth location (e.g. 'America/New_York')." },
1354
1314
  transit_datetime: {
1355
1315
  type: "string",
@@ -1376,7 +1336,7 @@ registerTool({
1376
1336
  handler: async (args) => {
1377
1337
  const client = getActiveClient();
1378
1338
  const timezone = args.timezone;
1379
- const natalIso = localToUtcIso(String(args.datetime), timezone);
1339
+ const natalIso = localToUtcIso("datetime", String(args.datetime), timezone);
1380
1340
  const lat = args.latitude ?? 0;
1381
1341
  const lon = args.longitude ?? 0;
1382
1342
  // SubjectRequest wire shape: name (required), birth_datetime.iso, and
@@ -1394,7 +1354,9 @@ registerTool({
1394
1354
  },
1395
1355
  };
1396
1356
  if (args.transit_datetime) {
1397
- body.transit_datetime = { iso: ensureTimezone(String(args.transit_datetime)) };
1357
+ body.transit_datetime = {
1358
+ iso: localToUtcIso("transit_datetime", String(args.transit_datetime), args.timezone),
1359
+ };
1398
1360
  }
1399
1361
  const bundleAvailable = Boolean(getBodygraphBundle());
1400
1362
  // The Go endpoint defaults visual_config.theme to "light", which mismatches
@@ -1495,17 +1457,17 @@ registerTool({
1495
1457
  _meta: { ui: { resourceUri: BODYGRAPH_RESOURCE_URI, visibility: ["model", "app"] } },
1496
1458
  handler: async (args) => {
1497
1459
  const client = getActiveClient();
1498
- const toSubject = (p) => {
1460
+ const toSubject = (p, label) => {
1499
1461
  const tz = p?.timezone;
1500
1462
  return {
1501
- birth_datetime_utc: localToUtcIso(String(p?.datetime), tz),
1463
+ birth_datetime_utc: localToUtcIso(`${label}.datetime`, String(p?.datetime), tz, `${label}.timezone`),
1502
1464
  latitude: p?.latitude ?? 0,
1503
1465
  longitude: p?.longitude ?? 0,
1504
1466
  };
1505
1467
  };
1506
1468
  const body = {
1507
- subject_1: toSubject(args.person_a),
1508
- subject_2: toSubject(args.person_b),
1469
+ subject_1: toSubject(args.person_a, "person_a"),
1470
+ subject_2: toSubject(args.person_b, "person_b"),
1509
1471
  };
1510
1472
  const bundleAvailable = Boolean(getBodygraphBundle());
1511
1473
  // Mirror the transit tool: explicit dark default, host-theme refetch.