klio 1.2.4 → 1.2.6

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.
package/README.md CHANGED
@@ -73,6 +73,12 @@ klio sonne --hs koch --i
73
73
  ```bash
74
74
  klio --s --hs koch
75
75
  ```
76
+ ### Persönliche Transit-Häuser
77
+ ```bash
78
+ klio --s --hs koch --i
79
+ ````
80
+
81
+
76
82
  #### Persönlich
77
83
  ```bash
78
84
  klio --s --hs koch --i
@@ -102,12 +108,16 @@ klio mond --a
102
108
  ```
103
109
  ```bash
104
110
  Aspekte für Mond:
105
- =================================================================
106
- | Aspekt | Planet | Winkel | Orb |
107
- =================================================================
108
- | Sextil | Jupiter | 65.79 ° | 5.79° |
109
- | Opposition | Saturn | 173.71° | 6.29° |
110
- ...
111
+ ================================================================================
112
+ | Aspekt | Planet | Orb | Exaktes Datum/Uhrzeit |
113
+ ================================================================================
114
+ | Opposition | Saturn | 1.82° | 15.11.2025 00:30 |
115
+ | Trigon | Uranus | 3.45° | 01.10.2025 22:05 |
116
+ | Opposition | Neptun | 0.65° | 15.11.2025 08:50 |
117
+ | Trigon | Pluto | 2.92° | 11.07.2026 06:15 |
118
+ ================================================================================
119
+
120
+ Diese Analyse basiert auf der aktuellen Planetenposition.
111
121
  ```
112
122
 
113
123
  ### Aspekte für einen Planeten (Geburtshoroskop)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "klio",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "Eine CLI für astrologische Berechnungen",
5
5
  "main": "src/main.js",
6
6
  "bin": {
@@ -1079,6 +1079,59 @@ function showAspectFigures(dateComponents, useBirthData = false, houseSystem = n
1079
1079
  }
1080
1080
  }
1081
1081
 
1082
+ async function calculatePersonalTransits(transitDate = null, birthData = null) {
1083
+ if (!birthData) {
1084
+ birthData = getBirthDataFromConfig();
1085
+ if (!birthData) {
1086
+ console.error('Keine Geburtsdaten verfügbar für persönliche Transite.');
1087
+ return null;
1088
+ }
1089
+ }
1090
+
1091
+ // Verwende aktuelles Datum, wenn kein Transitdatum angegeben
1092
+ if (!transitDate) {
1093
+ transitDate = getCurrentTimeInTimezone();
1094
+ }
1095
+
1096
+ // Berechne Häuser basierend auf Geburtsdaten (ASC-basiert)
1097
+ const birthJulianDay = calculateJulianDayUTC(birthData, getTimezoneOffset(birthData, birthData.location?.timezone || 'Europe/Zurich'));
1098
+ const houses = await calculateHouses(birthJulianDay, 'K', true); // Immer Koch-Haus-System für Transite
1099
+
1100
+ // Berechne aktuelle Planetenpositionen (Transit)
1101
+ const transitPlanets = {};
1102
+ for (const [name, planetId] of Object.entries(planets)) {
1103
+ const data = getAstrologicalData(name, transitDate);
1104
+ transitPlanets[name] = data;
1105
+ }
1106
+
1107
+ // Berechne Geburtsplanetenpositionen (Radix)
1108
+ const birthPlanets = {};
1109
+ for (const [name, planetId] of Object.entries(planets)) {
1110
+ const data = getAstrologicalData(name, birthData);
1111
+ birthPlanets[name] = data;
1112
+ }
1113
+
1114
+ // Bestimme die Häuser für alle Transitplaneten
1115
+ const transitResults = {};
1116
+ for (const [name, data] of Object.entries(transitPlanets)) {
1117
+ const planetLongitude = parseFloat(data.degreeInSign) + (signs.indexOf(data.sign) * 30);
1118
+ const house = getPlanetHouse(planetLongitude, houses.house);
1119
+
1120
+ transitResults[name] = {
1121
+ ...data,
1122
+ transitHouse: house,
1123
+ birthPosition: birthPlanets[name]
1124
+ };
1125
+ }
1126
+
1127
+ return {
1128
+ transitDate: transitDate,
1129
+ birthData: birthData,
1130
+ houses: houses,
1131
+ planets: transitResults
1132
+ };
1133
+ }
1134
+
1082
1135
  // Funktion zur Analyse der Elementverteilung
1083
1136
  function analyzeElementDistribution(dateComponents, useBirthData = false) {
1084
1137
  const elementCounts = {
@@ -1269,7 +1322,8 @@ module.exports = {
1269
1322
  getFutureAspects,
1270
1323
  findExactAspectTime,
1271
1324
  detectAspectFigures,
1272
- showAspectFigures
1325
+ showAspectFigures,
1326
+ calculatePersonalTransits
1273
1327
  };
1274
1328
 
1275
1329
  // Funktion zur Berechnung vergangener Aspekte zwischen zwei Planeten
package/src/cli/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const { Command } = require('commander');
2
2
  const { planets, signs } = require('../astrology/astrologyConstants');
3
3
  const { showRetrogradePlanets } = require('../astrology/retrogradeService');
4
- const { getCurrentTimeInTimezone, showAspectFigures, analyzeElementDistribution, getTimezoneOffset, calculateJulianDayUTC, calculateHouses, getAstrologicalData, getPlanetHouse, showPlanetAspects, calculatePlanetAspects, getAllActiveAspects, showAllActiveAspects, getBirthDataFromConfig, detectAspectFigures } = require('../astrology/astrologyService');
4
+ const { getCurrentTimeInTimezone, showAspectFigures, analyzeElementDistribution, getTimezoneOffset, calculateJulianDayUTC, calculateHouses, getAstrologicalData, getPlanetHouse, showPlanetAspects, calculatePlanetAspects, getAllActiveAspects, showAllActiveAspects, getBirthDataFromConfig, detectAspectFigures, calculatePersonalTransits } = require('../astrology/astrologyService');
5
5
  const { performSetup, showConfigStatus, loadConfig, setAIModel, askAIModel } = require('../config/configService');
6
6
  const { parseAppleHealthXML } = require('../health/healthService');
7
7
  const { analyzeStepsByPlanetSign, analyzeStressByPlanetAspects, analyzePlanetAspectsForSleep } = require('../health/healthAnalysis');
@@ -109,6 +109,7 @@ program
109
109
  .option('--p <prompt>', 'Stellt eine Frage an das KI-Modell (z.B. "Welche Berufe passen zu dieser Position?")')
110
110
  .option('--el', 'Zeigt die Elementverteilung der Planeten in einem horizontalen Chart an')
111
111
  .option('--af', 'Zeigt aktive Aspektfiguren wie T-Quadrate, Große Trigone, etc. an')
112
+ .option('--transite', 'Zeigt persönliche Transite basierend auf Geburtsdaten an')
112
113
  .option('--v <count>', 'Zeigt vergangene Aspekte zwischen zwei Planeten an (Format: --v <count> planet1 aspectType planet2)')
113
114
  .option('--z <count>', 'Zeigt zukünftige Aspekte zwischen zwei Planeten an (Format: --z <count> planet1 aspectType planet2)')
114
115
  .description('Zeigt astrologische Daten für einen Planeten an')
@@ -304,6 +305,109 @@ program
304
305
  return;
305
306
  }
306
307
 
308
+ // Persönliche Transite anzeigen, falls --transite Option angegeben (ohne Planet erforderlich)
309
+ if (options.transite) {
310
+ // Geburtsdaten sind für Transite erforderlich
311
+ const birthData = getBirthDataFromConfig();
312
+ if (!birthData) {
313
+ console.error('Fehler: Persönliche Transite erfordern Geburtsdaten. Bitte führe --setup aus, um deine Geburtsdaten zu konfigurieren.');
314
+ process.exit(1);
315
+ }
316
+
317
+ // Benutzerdefiniertes Datum verwenden, falls angegeben
318
+ let transitDate = null;
319
+ if (options.d) {
320
+ // Versuche, das Datum als DD.MM.YYYY oder DD.MM.YYYY HH:MM zu parsen
321
+ const dateRegex = /^(\d{1,2})\.(\d{1,2})\.(\d{4})(?:\s+(\d{1,2}):(\d{2}))?$/;
322
+ const match = options.d.match(dateRegex);
323
+
324
+ if (match) {
325
+ const day = parseInt(match[1], 10);
326
+ const month = parseInt(match[2], 10);
327
+ const year = parseInt(match[3], 10);
328
+ const hour = match[4] ? parseInt(match[4], 10) : 12; // Standard: 12 Uhr
329
+ const minute = match[5] ? parseInt(match[5], 10) : 0; // Standard: 0 Minuten
330
+
331
+ // Überprüfe, ob das Datum gültig ist
332
+ const date = new Date(year, month - 1, day, hour, minute);
333
+ if (date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day) {
334
+ transitDate = {
335
+ day: day,
336
+ month: month,
337
+ year: year,
338
+ hour: hour,
339
+ minute: minute
340
+ };
341
+ console.log(`Verwende Transitdatum: ${day}.${month}.${year} ${hour}:${minute.toString().padStart(2, '0')}`);
342
+ } else {
343
+ console.error('Ungültiges Datum:', options.d);
344
+ console.error('💡 Bitte verwende das Format: DD.MM.YYYY oder "DD.MM.YYYY HH:MM" (mit Anführungszeichen für Datum mit Uhrzeit)');
345
+ process.exit(1);
346
+ }
347
+ } else {
348
+ console.error('Ungültiges Datum:', options.d);
349
+ console.error('💡 Bitte verwende das Format: DD.MM.YYYY oder "DD.MM.YYYY HH:MM" (mit Anführungszeichen für Datum mit Uhrzeit)');
350
+ process.exit(1);
351
+ }
352
+ }
353
+
354
+ // Berechne persönliche Transite
355
+ const transitData = await calculatePersonalTransits(transitDate, birthData);
356
+
357
+ if (!transitData) {
358
+ console.error('Fehler bei der Berechnung der persönlichen Transite.');
359
+ process.exit(1);
360
+ }
361
+
362
+ // Zeige Geburtsdaten an
363
+ console.log(`Geburtsdaten: ${birthData.day}.${birthData.month}.${birthData.year} ${birthData.hour}:${birthData.minute.toString().padStart(2, '0')}`);
364
+ if (birthData.location) {
365
+ console.log(`Geburtsort: ${birthData.location.name}, ${birthData.location.country}`);
366
+ }
367
+
368
+ // Zeige Transitdatum an
369
+ const transitDateDisplay = transitDate || getCurrentTimeInTimezone();
370
+ console.log(`Transitdatum: ${transitDateDisplay.day}.${transitDateDisplay.month}.${transitDateDisplay.year} ${transitDateDisplay.hour}:${transitDateDisplay.minute.toString().padStart(2, '0')}`);
371
+
372
+ console.log('\nPersönliche Transite (Haus-System: Koch, basierend auf Geburts-ASC):');
373
+ console.log('================================================================================');
374
+ console.log('| Planet | Transit Position | Geburts Position | Transit Haus |');
375
+ console.log('================================================================================');
376
+
377
+ // Zeige alle Planeten mit ihren Transit- und Geburtspositionen
378
+ for (const [name, data] of Object.entries(transitData.planets)) {
379
+ const planetNameFormatted = name.charAt(0).toUpperCase() + name.slice(1);
380
+ const transitPos = `${data.sign} ${data.degreeInSign}°`;
381
+ const birthPos = `${data.birthPosition.sign} ${data.birthPosition.degreeInSign}°`;
382
+ const transitHouse = data.transitHouse;
383
+
384
+ console.log(`| ${planetNameFormatted.padEnd(11)} | ${transitPos.padEnd(22)} | ${birthPos.padEnd(22)} | ${transitHouse.toString().padEnd(11)} |`);
385
+ }
386
+
387
+ console.log('================================================================================');
388
+ console.log('\nHinweis: Die Häuser basieren auf deinem Geburts-ASC (Haus-System: Koch).');
389
+ console.log('Beispiel: Wenn Jupiter im Krebs ist und du Skorpion ASC hast, zeigt dies, in welchem');
390
+ console.log('deiner Geburtshäuser sich der Transit-Jupiter befindet.');
391
+
392
+ // Frage an das KI-Modell senden, falls --p Option angegeben
393
+ if (options.p) {
394
+ // Erstelle ein Datenobjekt für die KI mit den Transitinformationen
395
+ const aiData = {
396
+ planet: 'alle',
397
+ sign: 'Multiple',
398
+ degreeInSign: 'Multiple',
399
+ dignity: `Persönliche Transite: ${Object.entries(transitData.planets).map(([name, data]) => `${name} in ${data.sign} (${data.degreeInSign}° Haus ${data.transitHouse})`).join(', ')}`,
400
+ element: 'Multiple',
401
+ decan: 'Multiple',
402
+ transitData: transitData
403
+ };
404
+
405
+ await askAIModel(options.p, aiData);
406
+ }
407
+
408
+ return;
409
+ }
410
+
307
411
  // Aspektfiguren anzeigen, falls --af Option angegeben (ohne Planet erforderlich)
308
412
  if (options.af) {
309
413
  // Geburtsdaten verwenden, falls --ich Option angegeben
@@ -450,26 +554,26 @@ program
450
554
 
451
555
  // Tabellarische Übersicht aller Planetenpositionen anzeigen, falls --s Option angegeben
452
556
  if (options.s) {
453
- // Geburtsdaten verwenden, falls --ich Option angegeben
557
+ // Geburtsdaten für Hausberechnung verwenden, falls --ich Option angegeben
454
558
  let customDate = null;
455
- let useBirthData = false;
559
+ let birthData = null;
456
560
  let houseSystem = options.hs ? options.hs.toLowerCase() : 'koch';
457
561
 
562
+ // Prüfe, ob Geburtsdaten für Hausberechnung verwendet werden sollen
458
563
  if (shouldUseBirthData(options)) {
459
- const birthData = getBirthDataFromConfig();
564
+ birthData = getBirthDataFromConfig();
460
565
  if (birthData) {
461
- customDate = birthData;
462
- useBirthData = true;
463
- console.log(`Verwende Geburtsdaten: ${birthData.day}.${birthData.month}.${birthData.year} ${birthData.hour}:${birthData.minute.toString().padStart(2, '0')}`);
566
+ console.log(`Verwende Geburtsdaten für Hausberechnung: ${birthData.day}.${birthData.month}.${birthData.year} ${birthData.hour}:${birthData.minute.toString().padStart(2, '0')}`);
464
567
  if (birthData.location) {
465
568
  console.log(`Geburtsort: ${birthData.location.name}, ${birthData.location.country}`);
466
569
  }
467
570
  } else {
468
- console.log('Keine Geburtsdaten in der Konfiguration gefunden. Verwende aktuelle Daten.');
571
+ console.log('Keine Geburtsdaten in der Konfiguration gefunden. Verwende aktuellen Standort für Hausberechnung.');
469
572
  }
470
573
  }
471
- // Benutzerdefiniertes Datum verwenden, falls angegeben (überschreibt --ich Option)
472
- else if (options.d) {
574
+
575
+ // Benutzerdefiniertes Datum verwenden, falls angegeben (für Planetenpositionen)
576
+ if (options.d) {
473
577
  // Versuche, das Datum als DD.MM.YYYY oder DD.MM.YYYY HH:MM zu parsen
474
578
  const dateRegex = /^(\d{1,2})\.(\d{1,2})\.(\d{4})(?:\s+(\d{1,2}):(\d{2}))?$/;
475
579
  const match = options.d.match(dateRegex);
@@ -518,13 +622,11 @@ program
518
622
 
519
623
  const config = loadConfig();
520
624
 
521
- // Funktion zur Berechnung des Julianischen Tages in UTC
522
- const getJulianDayUTC = () => {
625
+ // Funktion zur Berechnung des Julianischen Tages in UTC für Planetenpositionen
626
+ const getJulianDayUTCForPlanets = () => {
523
627
  let timezoneOffsetMinutes = 0;
524
628
 
525
- if (shouldUseBirthData(options) && config && config.birthData && config.birthData.location) {
526
- timezoneOffsetMinutes = getTimezoneOffset(customDate, config.birthData.location.timezone || 'Europe/Zurich');
527
- } else if (config && config.currentLocation && config.currentLocation.timezone) {
629
+ if (config && config.currentLocation && config.currentLocation.timezone) {
528
630
  timezoneOffsetMinutes = getTimezoneOffset(customDate, config.currentLocation.timezone);
529
631
  } else {
530
632
  timezoneOffsetMinutes = -new Date().getTimezoneOffset();
@@ -533,21 +635,36 @@ program
533
635
  return calculateJulianDayUTC(customDate, timezoneOffsetMinutes);
534
636
  };
535
637
 
638
+ // Funktion zur Berechnung des Julianischen Tages in UTC für Hausberechnung
639
+ const getJulianDayUTCForHouses = () => {
640
+ let timezoneOffsetMinutes = 0;
641
+
642
+ if (birthData && birthData.location) {
643
+ timezoneOffsetMinutes = getTimezoneOffset(birthData, birthData.location.timezone || 'Europe/Zurich');
644
+ } else if (config && config.currentLocation && config.currentLocation.timezone) {
645
+ timezoneOffsetMinutes = getTimezoneOffset(customDate, config.currentLocation.timezone);
646
+ } else {
647
+ timezoneOffsetMinutes = -new Date().getTimezoneOffset();
648
+ }
649
+
650
+ return calculateJulianDayUTC(birthData ? birthData : customDate, timezoneOffsetMinutes);
651
+ };
652
+
536
653
  // Berechne Häuser, falls Haus-System angegeben
537
654
  let houses = null;
538
655
  if (houseSystem) {
539
656
  try {
540
- const julianDay = getJulianDayUTC();
541
- const useBirthLocation = shouldUseBirthData(options);
657
+ const julianDayForHouses = getJulianDayUTCForHouses();
658
+ const useBirthLocation = birthData !== null;
542
659
 
543
660
  if (houseSystem === 'koch') {
544
- houses = await calculateHouses(julianDay, 'K', useBirthLocation);
661
+ houses = await calculateHouses(julianDayForHouses, 'K', useBirthLocation);
545
662
  } else if (houseSystem === 'wholesign') {
546
- houses = await calculateHouses(julianDay, 'W', useBirthLocation);
663
+ houses = await calculateHouses(julianDayForHouses, 'W', useBirthLocation);
547
664
  } else if (houseSystem === 'gauquelin') {
548
- houses = await calculateHouses(julianDay, 'G', useBirthLocation);
665
+ houses = await calculateHouses(julianDayForHouses, 'G', useBirthLocation);
549
666
  } else {
550
- houses = await calculateHouses(julianDay, 'K', useBirthLocation);
667
+ houses = await calculateHouses(julianDayForHouses, 'K', useBirthLocation);
551
668
  }
552
669
  } catch (error) {
553
670
  console.error('Fehler bei der Hausberechnung:', error);
@@ -583,8 +700,9 @@ program
583
700
 
584
701
  console.log('================================================================================');
585
702
 
586
- if (useBirthData) {
587
- console.log('\nDiese Analyse basiert auf deinem Geburtshoroskop.');
703
+ if (birthData) {
704
+ console.log('\nDiese Analyse zeigt aktuelle Planetenpositionen in deinen Geburtshäusern.');
705
+ console.log('Die Häuser basieren auf deinem Geburts-ASC (persönliche Transite).');
588
706
  } else {
589
707
  console.log('\nDiese Analyse basiert auf der aktuellen Planetenposition.');
590
708
  }