klio 1.4.9 → 1.5.1
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/.dockerignore +9 -0
- package/.nvmrc +1 -0
- package/Dockerfile +18 -0
- package/README.md +22 -0
- package/compose.yaml +6 -0
- package/package.json +8 -3
- package/src/astrology/astrologyConstants.js +7 -0
- package/src/astrology/astrologyService.js +327 -302
- package/src/astrology/astrologyServiceWeb.js +369 -0
- package/src/astrology/swephWasmLoader.js +106 -0
- package/src/astrology/swissephAdapter.js +279 -0
- package/src/cli/cli.js +148 -152
- package/src/cli/cliService.js +1197 -0
- package/src/cli/cliServiceWeb.js +406 -0
- package/src/config/configService.js +59 -35
- package/src/gui/public/index.html +839 -298
- package/src/gui/public/sweph/astro.data +0 -0
- package/src/gui/public/sweph/astro.js +3934 -0
- package/src/gui/public/sweph/astro.wasm +0 -0
- package/src/gui/public/tailwind.css +3 -0
- package/src/gui/public/tailwind.generated.css +1 -0
- package/src/gui/public/webcontainerService.js +435 -0
- package/src/gui/routes/api.js +64 -101
- package/src/gui/server.js +80 -31
- package/src/gui/webcontainerSetup.js +244 -0
- package/src/health/fileAnalysis.js +2 -2
- package/commands.db +0 -0
- package/src/gui/commandLogger.js +0 -67
- package/src/gui/database.js +0 -135
package/src/cli/cli.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
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, getPersonDataFromConfig, detectAspectFigures, calculatePersonalTransits, showPersonalTransitAspects, showCombinedAnalysis, calculatePersonalTransitAspects, determineAspectPhase,
|
|
4
|
+
const { getCurrentTimeInTimezone, showAspectFigures, analyzeElementDistribution, getTimezoneOffset, calculateJulianDayUTC, calculateHouses, getAstrologicalData, getPlanetHouse, showPlanetAspects, calculatePlanetAspects, getAllActiveAspects, showAllActiveAspects, getBirthDataFromConfig, getPersonDataFromConfig, detectAspectFigures, calculatePersonalTransits, showPersonalTransitAspects, showCombinedAnalysis, calculatePersonalTransitAspects, determineAspectPhase, getAspectAngle, getFutureAspects, getPastAspects, analyzeCSVWithDatetime, analyzeHouseDistributionSignificance, analyzeAspectDistributionSignificance, analyzeSignDistributionSignificance, calculateAspectStatistics, calculatePlanetComboAspects, showPlanetComboAspects, getCriticalPlanets, getHouseSystemCode, calculateNextPlanetIngress, calculateAstrologicalAngles, longitudeToSignDegree, calculateTransitFrequency } = require('../astrology/astrologyService');
|
|
5
5
|
const { performSetup, showConfigStatus, loadConfig, setAIModel, askAIModel, setPerson1, setPerson2, setPerson, getPersonData, listPeople, deletePerson } = require('../config/configService');
|
|
6
6
|
const { parseAppleHealthXML } = require('../health/healthService');
|
|
7
7
|
const { analyzeStepsByPlanetSign, analyzeStressByPlanetAspects, analyzePlanetAspectsForSleep, analyzeLateNightAspects, analyzeAllNighterAspects } = require('../health/healthAnalysis');
|
|
8
|
-
const { analyzeHouseDistribution, filterFilesByHouse } = require('../health/fileAnalysis');
|
|
9
8
|
const { getFileCreationDate, parseDateToComponents } = require('../utils/fileUtils');
|
|
10
|
-
const swisseph = require('swisseph');
|
|
11
9
|
const path = require('path');
|
|
12
10
|
const fs = require('fs');
|
|
13
11
|
|
|
@@ -43,7 +41,7 @@ const program = new Command();
|
|
|
43
41
|
|
|
44
42
|
// Helper function to check if person data should be used (including new options)
|
|
45
43
|
const shouldUsePersonData = (options) => {
|
|
46
|
-
return options.
|
|
44
|
+
return options.i || options.p1 || options.p2 || options.withPerson || options.wp || options.up;
|
|
47
45
|
};
|
|
48
46
|
|
|
49
47
|
// Universal AI handler function that works with any command
|
|
@@ -150,7 +148,7 @@ const getPersonDataToUse = (options) => {
|
|
|
150
148
|
return { source: 'p5', data: getPersonDataFromConfig('p5') };
|
|
151
149
|
} else if (options.p6) {
|
|
152
150
|
return { source: 'p6', data: getPersonDataFromConfig('p6') };
|
|
153
|
-
} else if (options.
|
|
151
|
+
} else if (options.i) {
|
|
154
152
|
return { source: 'birth', data: getPersonDataFromConfig('birth') };
|
|
155
153
|
}
|
|
156
154
|
return { source: null, data: null };
|
|
@@ -158,7 +156,7 @@ const getPersonDataToUse = (options) => {
|
|
|
158
156
|
|
|
159
157
|
// Helper function to check if birth data should be used (for backward compatibility only)
|
|
160
158
|
const shouldUseBirthData = (options) => {
|
|
161
|
-
return options.
|
|
159
|
+
return options.i;
|
|
162
160
|
};
|
|
163
161
|
|
|
164
162
|
// Function to calculate the Julian Day in UTC
|
|
@@ -224,19 +222,6 @@ program
|
|
|
224
222
|
.option('--a', 'Shows all aspects of the planet')
|
|
225
223
|
.option('--k', 'Shows aspects between any planet combinations')
|
|
226
224
|
.option('--s', 'Shows all planet positions in a table with signs, degrees and houses')
|
|
227
|
-
.option('--folder <path>', 'Analyzes house distribution of all files in the folder')
|
|
228
|
-
.option('--h1', 'Filters files with planet in house 1')
|
|
229
|
-
.option('--h2', 'Filters files with planet in house 2')
|
|
230
|
-
.option('--h3', 'Filters files with planet in house 3')
|
|
231
|
-
.option('--h4', 'Filters files with planet in house 4')
|
|
232
|
-
.option('--h5', 'Filters files with planet in house 5')
|
|
233
|
-
.option('--h6', 'Filters files with planet in house 6')
|
|
234
|
-
.option('--h7', 'Filters files with planet in house 7')
|
|
235
|
-
.option('--h8', 'Filters files with planet in house 8')
|
|
236
|
-
.option('--h9', 'Filters files with planet in house 9')
|
|
237
|
-
.option('--h10', 'Filters files with planet in house 10')
|
|
238
|
-
.option('--h11', 'Filters files with planet in house 11')
|
|
239
|
-
.option('--h12', 'Filters files with planet in house 12')
|
|
240
225
|
.option('--apple <filepath>', 'Analyzes Apple Health Export XML file')
|
|
241
226
|
.option('--hypothesis <type>', 'Specifies the hypothesis to test (e.g. "sleep-moon", "steps-moon", "stress-moon")')
|
|
242
227
|
.option('--sleep', 'Analyzes sleep patterns with moon aspects')
|
|
@@ -250,7 +235,6 @@ program
|
|
|
250
235
|
.option('--rx', 'Shows all retrograde or stationary planets')
|
|
251
236
|
.option('--c', 'Shows all planets on critical degrees')
|
|
252
237
|
.option('--status', 'Shows the stored configuration data')
|
|
253
|
-
.option('--ich', 'Uses the birth data from setup for calculations')
|
|
254
238
|
.option('--i', 'Uses the birth data from setup for calculations (short form)')
|
|
255
239
|
.option('--p1', 'Uses the data from person 1 for calculations')
|
|
256
240
|
.option('--p2', 'Uses the data from person 2 for calculations')
|
|
@@ -270,7 +254,6 @@ program
|
|
|
270
254
|
.option('--el', 'Shows the element distribution of planets in a horizontal chart')
|
|
271
255
|
.option('--af', 'Shows active aspect figures like T-squares, Grand Trines, etc.')
|
|
272
256
|
.option('--tra', 'Shows personal transits based on birth data')
|
|
273
|
-
.option('--transit-aspekte', 'Shows personal transit aspects (Transit → Radix)')
|
|
274
257
|
.option('--tr', 'Shows personal transit aspects (Transit → Radix) (short form)')
|
|
275
258
|
.option('--v <count>', 'Shows past aspects between two planets (Format: --v <count> planet1 aspectType planet2)')
|
|
276
259
|
.option('--z <count>', 'Shows future aspects between two planets (Format: --z <count> planet1 aspectType planet2)')
|
|
@@ -281,6 +264,7 @@ program
|
|
|
281
264
|
.option('--wiki <occupation>', 'Fetches people from Wikidata by occupation and checks for specific aspects (Format: planet1 aspectType planet2 --wiki <occupation> [limit])')
|
|
282
265
|
.option('--gui', 'Launches the web interface for command history (port 37421)')
|
|
283
266
|
.option('--gui-port <port>', 'Specify custom port for GUI server')
|
|
267
|
+
.option('--gui-verbose', 'Enable verbose logging for GUI server')
|
|
284
268
|
.option('--o', 'Shows how often this transit occurs in the sky (frequency calculation)')
|
|
285
269
|
.description('Shows astrological data for a planet')
|
|
286
270
|
.action(async (planetArg, planet2Arg, options) => {
|
|
@@ -292,19 +276,18 @@ program
|
|
|
292
276
|
if (options.gui) {
|
|
293
277
|
if (!guiServer) {
|
|
294
278
|
console.error('❌ GUI server is not available. Please install required dependencies.');
|
|
295
|
-
console.error('💡 Run: npm install express sqlite3');
|
|
296
279
|
process.exit(1);
|
|
297
280
|
}
|
|
298
281
|
|
|
299
282
|
try {
|
|
283
|
+
// Set verbose logging based on --gui-verbose flag
|
|
284
|
+
guiServer.enableVerboseLogging(!!options.guiVerbose);
|
|
285
|
+
|
|
300
286
|
await guiServer.initialize();
|
|
301
287
|
const port = options.guiPort ? parseInt(options.guiPort) : 37421;
|
|
302
288
|
await guiServer.start(port);
|
|
303
289
|
|
|
304
|
-
|
|
305
|
-
console.log(`📊 Open your browser and navigate to: http://localhost:${guiServer.getPort()}`);
|
|
306
|
-
console.log(`💡 Press Ctrl+C to stop the server and return to CLI`);
|
|
307
|
-
|
|
290
|
+
// Server start messages are now handled by the server itself
|
|
308
291
|
// Keep the process running
|
|
309
292
|
await new Promise(() => {});
|
|
310
293
|
return;
|
|
@@ -316,7 +299,7 @@ program
|
|
|
316
299
|
|
|
317
300
|
// Show critical planets if --c option is specified (no planet required)
|
|
318
301
|
if (actualOptions.c) {
|
|
319
|
-
// Use person data if --p1, --p2 or --
|
|
302
|
+
// Use person data if --p1, --p2 or --i option is specified
|
|
320
303
|
let customDate = null;
|
|
321
304
|
let personSource = null;
|
|
322
305
|
const personDataToUse = getPersonDataToUse(options);
|
|
@@ -341,6 +324,54 @@ program
|
|
|
341
324
|
}
|
|
342
325
|
}
|
|
343
326
|
|
|
327
|
+
// Use custom date if specified (overrides person data)
|
|
328
|
+
if (options.d) {
|
|
329
|
+
// Try to parse the date as DD.MM.YYYY or DD.MM.YYYY HH:MM
|
|
330
|
+
const dateRegex = /^(\d{1,2})\.(\d{1,2})\.(\d{4})(?:\s+(\d{1,2}):(\d{2}))?$/;
|
|
331
|
+
const match = options.d.match(dateRegex);
|
|
332
|
+
|
|
333
|
+
if (match) {
|
|
334
|
+
const day = parseInt(match[1], 10);
|
|
335
|
+
const month = parseInt(match[2], 10);
|
|
336
|
+
const year = parseInt(match[3], 10);
|
|
337
|
+
const hour = match[4] ? parseInt(match[4], 10) : 12; // Default: 12 o'clock
|
|
338
|
+
const minute = match[5] ? parseInt(match[5], 10) : 0; // Default: 0 minutes
|
|
339
|
+
|
|
340
|
+
// Check if the date is valid
|
|
341
|
+
const date = new Date(year, month - 1, day, hour, minute);
|
|
342
|
+
if (date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day) {
|
|
343
|
+
customDate = {
|
|
344
|
+
day: day,
|
|
345
|
+
month: month,
|
|
346
|
+
year: year,
|
|
347
|
+
hour: hour,
|
|
348
|
+
minute: minute
|
|
349
|
+
};
|
|
350
|
+
console.log(`Using custom date: ${day}.${month}.${year} ${hour}:${minute.toString().padStart(2, '0')}`);
|
|
351
|
+
} else {
|
|
352
|
+
console.error('Invalid date:', options.d);
|
|
353
|
+
console.error('💡 Please use the format: DD.MM.YYYY or "DD.MM.YYYY HH:MM" (with quotes for date with time)');
|
|
354
|
+
process.exit(1);
|
|
355
|
+
}
|
|
356
|
+
} else {
|
|
357
|
+
console.error('Invalid date:', options.d);
|
|
358
|
+
console.error('💡 Please use the format: DD.MM.YYYY or "DD.MM.YYYY HH:MM" (with quotes for date with time)');
|
|
359
|
+
process.exit(1);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// If no custom date is specified, use current date
|
|
364
|
+
if (!customDate) {
|
|
365
|
+
const currentTime = getCurrentTimeInTimezone();
|
|
366
|
+
customDate = {
|
|
367
|
+
day: currentTime.day,
|
|
368
|
+
month: currentTime.month,
|
|
369
|
+
year: currentTime.year,
|
|
370
|
+
hour: currentTime.hour,
|
|
371
|
+
minute: currentTime.minute
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
344
375
|
const criticalPlanets = getCriticalPlanets(customDate);
|
|
345
376
|
|
|
346
377
|
if (criticalPlanets.length === 0) {
|
|
@@ -348,18 +379,20 @@ program
|
|
|
348
379
|
return;
|
|
349
380
|
}
|
|
350
381
|
|
|
351
|
-
console.log('
|
|
352
|
-
console.log('| Planet | Sign | Degree | Type |');
|
|
353
|
-
console.log('
|
|
382
|
+
console.log('================================================================================================================');
|
|
383
|
+
console.log('| Planet | Sign | Degree | Type | Interpretation |');
|
|
384
|
+
console.log('================================================================================================================');
|
|
354
385
|
|
|
355
386
|
criticalPlanets.forEach(planet => {
|
|
356
387
|
const planetName = planet.name.charAt(0).toUpperCase() + planet.name.slice(1);
|
|
357
388
|
const sign = planet.sign.padEnd(10, ' ');
|
|
358
389
|
const degree = planet.degree.padEnd(5, ' ');
|
|
359
|
-
|
|
390
|
+
const criticalType = planet.criticalType.padEnd(20, ' ');
|
|
391
|
+
const interpretation = planet.interpretation.padEnd(46, ' ');
|
|
392
|
+
console.log(`| ${planetName.padEnd(8)} | ${sign} | ${degree} | ${criticalType} | ${interpretation} |`);
|
|
360
393
|
});
|
|
361
394
|
|
|
362
|
-
console.log('
|
|
395
|
+
console.log('================================================================================================================');
|
|
363
396
|
if (shouldUseBirthData(options)) {
|
|
364
397
|
console.log('\nThis analysis is based on your birth chart.');
|
|
365
398
|
} else {
|
|
@@ -426,7 +459,7 @@ program
|
|
|
426
459
|
|
|
427
460
|
// Show element distribution if --el option is specified (no planet required)
|
|
428
461
|
if (options.el) {
|
|
429
|
-
// Use person data if --p1, --p2 or --
|
|
462
|
+
// Use person data if --p1, --p2 or --i option is specified
|
|
430
463
|
let customDate = null;
|
|
431
464
|
let useBirthData = false;
|
|
432
465
|
let personSource = null;
|
|
@@ -452,7 +485,7 @@ program
|
|
|
452
485
|
console.log(`Location: ${customDate.location.name}, ${customDate.location.country}`);
|
|
453
486
|
}
|
|
454
487
|
}
|
|
455
|
-
// Use custom date if specified (overrides --p1, --p2 and --
|
|
488
|
+
// Use custom date if specified (overrides --p1, --p2 and --i options)
|
|
456
489
|
if (options.d) {
|
|
457
490
|
// Try to parse the date as DD.MM.YYYY or DD.MM.YYYY HH:MM
|
|
458
491
|
const dateRegex = /^(\d{1,2})\.(\d{1,2})\.(\d{4})(?:\s+(\d{1,2}):(\d{2}))?$/;
|
|
@@ -500,7 +533,7 @@ program
|
|
|
500
533
|
};
|
|
501
534
|
}
|
|
502
535
|
|
|
503
|
-
// Check if we should use natal positions (when --i
|
|
536
|
+
// Check if we should use natal positions (when --i is used without custom date)
|
|
504
537
|
if (shouldUseBirthData(options) && !options.d) {
|
|
505
538
|
useNatalPositions = true;
|
|
506
539
|
// customDate is already set to birth data from personDataToUse
|
|
@@ -639,9 +672,9 @@ program
|
|
|
639
672
|
return;
|
|
640
673
|
}
|
|
641
674
|
|
|
642
|
-
// Show combined analysis ONLY when --tr
|
|
675
|
+
// Show combined analysis ONLY when --tr is used together with --hs
|
|
643
676
|
// This ensures that `--tr` without `--hs` shows only personal transit aspects
|
|
644
|
-
if (
|
|
677
|
+
if (options.tr && options.hs) {
|
|
645
678
|
|
|
646
679
|
// Person data is required
|
|
647
680
|
const personDataToUse = getPersonDataToUse(options);
|
|
@@ -699,7 +732,7 @@ program
|
|
|
699
732
|
// If no planet is specified, show ONLY the transit aspects table
|
|
700
733
|
console.log('Transit aspects (Transit → Radix):');
|
|
701
734
|
console.log('================================================================================');
|
|
702
|
-
console.log('| Transit | Aspect | With Planet | Orb | Transit Pos | Transit House | Birth House | Phase |
|
|
735
|
+
console.log('| Transit | Aspect | With Planet | Orb | Transit Pos | Transit House | Birth House | Phase |');
|
|
703
736
|
console.log('================================================================================');
|
|
704
737
|
|
|
705
738
|
// Calculate houses once for all planets
|
|
@@ -729,18 +762,8 @@ program
|
|
|
729
762
|
const targetAngle = aspectAngles[aspect.type];
|
|
730
763
|
const phase = determineAspectPhase(planetName, aspect.birthPlanet, transitDateDisplay, aspect.type, targetAngle);
|
|
731
764
|
|
|
732
|
-
//
|
|
733
|
-
const
|
|
734
|
-
let dateTimeStr = '-';
|
|
735
|
-
if (exactDateTime) {
|
|
736
|
-
dateTimeStr = `${String(exactDateTime.day).padStart(2, '0')}.${String(exactDateTime.month).padStart(2, '0')}.${exactDateTime.year} ${String(exactDateTime.hour).padStart(2, '0')}:${String(exactDateTime.minute).padStart(2, '0')}`;
|
|
737
|
-
} else if (phase === 'separativ') {
|
|
738
|
-
// For separative phases: find the last exact date in the past
|
|
739
|
-
const lastExactDateTime = findLastExactAspectTime(planetName, aspect.birthPlanet, aspect.type, transitDateDisplay);
|
|
740
|
-
if (lastExactDateTime) {
|
|
741
|
-
dateTimeStr = `${String(lastExactDateTime.day).padStart(2, '0')}.${String(lastExactDateTime.month).padStart(2, '0')}.${lastExactDateTime.year} ${String(lastExactDateTime.hour).padStart(2, '0')}:${String(lastExactDateTime.minute).padStart(2, '0')} (e)`;
|
|
742
|
-
}
|
|
743
|
-
}
|
|
765
|
+
// Exact time calculation removed
|
|
766
|
+
const dateTimeStr = '-';
|
|
744
767
|
|
|
745
768
|
const transitPlanetFormatted = planetName.charAt(0).toUpperCase() + planetName.slice(1);
|
|
746
769
|
const aspectTypeFormatted = aspect.type.padEnd(11);
|
|
@@ -752,7 +775,7 @@ program
|
|
|
752
775
|
const phaseFormatted = phase === 'separativ' ? 'separativ'.padEnd(11) : phase.padEnd(11);
|
|
753
776
|
const dateTimeFormatted = dateTimeStr.padEnd(22);
|
|
754
777
|
|
|
755
|
-
console.log(`| ${transitPlanetFormatted.padEnd(10)} | ${aspectTypeFormatted} | ${aspectPlanetFormatted.padEnd(10)} | ${orbFormatted}° | ${transitPosFormatted.padEnd(16)} | ${transitHouseFormatted} | ${birthHouseFormatted} | ${phaseFormatted}
|
|
778
|
+
console.log(`| ${transitPlanetFormatted.padEnd(10)} | ${aspectTypeFormatted} | ${aspectPlanetFormatted.padEnd(10)} | ${orbFormatted}° | ${transitPosFormatted.padEnd(16)} | ${transitHouseFormatted} | ${birthHouseFormatted} | ${phaseFormatted} |`);
|
|
756
779
|
});
|
|
757
780
|
}
|
|
758
781
|
}
|
|
@@ -766,8 +789,8 @@ program
|
|
|
766
789
|
return;
|
|
767
790
|
}
|
|
768
791
|
|
|
769
|
-
// Show personal transit aspects if --
|
|
770
|
-
if (options.
|
|
792
|
+
// Show personal transit aspects if --tr option is specified
|
|
793
|
+
if (options.tr) {
|
|
771
794
|
// Person data is required for transit aspects
|
|
772
795
|
const personDataToUse = getPersonDataToUse(options);
|
|
773
796
|
if (!personDataToUse.data) {
|
|
@@ -845,7 +868,7 @@ program
|
|
|
845
868
|
|
|
846
869
|
// Show aspect figures if --af option is specified (no planet required)
|
|
847
870
|
if (options.af) {
|
|
848
|
-
// Use person data if --p1, --p2 or --
|
|
871
|
+
// Use person data if --p1, --p2 or --i option is specified
|
|
849
872
|
let customDate = null;
|
|
850
873
|
let useBirthData = false;
|
|
851
874
|
let personSource = null;
|
|
@@ -871,7 +894,7 @@ program
|
|
|
871
894
|
console.log(`Location: ${customDate.location.name}, ${customDate.location.country}`);
|
|
872
895
|
}
|
|
873
896
|
}
|
|
874
|
-
// Use custom date if specified (overrides --p1, --p2 and --
|
|
897
|
+
// Use custom date if specified (overrides --p1, --p2 and --i options)
|
|
875
898
|
if (options.d) {
|
|
876
899
|
// Try to parse the date as DD.MM.YYYY or DD.MM.YYYY HH:MM
|
|
877
900
|
const dateRegex = /^(\d{1,2})\.(\d{1,2})\.(\d{4})(?:\s+(\d{1,2}):(\d{2}))?$/;
|
|
@@ -1248,7 +1271,7 @@ program
|
|
|
1248
1271
|
|
|
1249
1272
|
// Show table view of all planet positions if --s option is specified
|
|
1250
1273
|
if (options.s) {
|
|
1251
|
-
// Use person data for house calculation if --p1, --p2 or --
|
|
1274
|
+
// Use person data for house calculation if --p1, --p2 or --i option is specified
|
|
1252
1275
|
let customDate = null;
|
|
1253
1276
|
let birthData = null;
|
|
1254
1277
|
let houseSystem = options.hs ? options.hs.toLowerCase() : 'koch';
|
|
@@ -1327,7 +1350,7 @@ program
|
|
|
1327
1350
|
};
|
|
1328
1351
|
}
|
|
1329
1352
|
|
|
1330
|
-
// Check if we should use natal positions (when --i
|
|
1353
|
+
// Check if we should use natal positions (when --i is used without custom date)
|
|
1331
1354
|
if (shouldUseBirthData(options) && !options.d) {
|
|
1332
1355
|
useNatalPositions = true;
|
|
1333
1356
|
customDate = birthData; // Use birth data for planet positions
|
|
@@ -1694,7 +1717,7 @@ program
|
|
|
1694
1717
|
const planet = planetArg ? planetArg.toLowerCase() : null;
|
|
1695
1718
|
|
|
1696
1719
|
if (options.a) {
|
|
1697
|
-
// Use person data if --p1, --p2 or --
|
|
1720
|
+
// Use person data if --p1, --p2 or --i option is specified
|
|
1698
1721
|
let customDate = null;
|
|
1699
1722
|
let useBirthData = false;
|
|
1700
1723
|
let personSource = null;
|
|
@@ -1720,7 +1743,7 @@ program
|
|
|
1720
1743
|
console.log(`Location: ${customDate.location.name}, ${customDate.location.country}`);
|
|
1721
1744
|
}
|
|
1722
1745
|
}
|
|
1723
|
-
// Use custom date if specified (overrides --p1, --p2 and --
|
|
1746
|
+
// Use custom date if specified (overrides --p1, --p2 and --i options)
|
|
1724
1747
|
if (options.d) {
|
|
1725
1748
|
// Try to parse the date as DD.MM.YYYY or DD.MM.YYYY HH:MM
|
|
1726
1749
|
const dateRegex = /^(\d{1,2})\.(\d{1,2})\.(\d{4})(?:\s+(\d{1,2}):(\d{2}))?$/;
|
|
@@ -1828,7 +1851,7 @@ program
|
|
|
1828
1851
|
process.exit(1);
|
|
1829
1852
|
}
|
|
1830
1853
|
|
|
1831
|
-
// Use person data if --p1, --p2 or --
|
|
1854
|
+
// Use person data if --p1, --p2 or --i option is specified
|
|
1832
1855
|
let customDate = null;
|
|
1833
1856
|
let useBirthData = false;
|
|
1834
1857
|
let personSource = null;
|
|
@@ -1854,7 +1877,7 @@ program
|
|
|
1854
1877
|
console.log(`Location: ${customDate.location.name}, ${customDate.location.country}`);
|
|
1855
1878
|
}
|
|
1856
1879
|
}
|
|
1857
|
-
// Use custom date if specified (overrides --p1, --p2 and --
|
|
1880
|
+
// Use custom date if specified (overrides --p1, --p2 and --i options)
|
|
1858
1881
|
if (options.d) {
|
|
1859
1882
|
// Try to parse the date as DD.MM.YYYY or DD.MM.YYYY HH:MM
|
|
1860
1883
|
const dateRegex = /^(\d{1,2})\.(\d{1,2})\.(\d{4})(?:\s+(\d{1,2}):(\d{2}))?$/;
|
|
@@ -2119,57 +2142,7 @@ program
|
|
|
2119
2142
|
return;
|
|
2120
2143
|
}
|
|
2121
2144
|
|
|
2122
|
-
//
|
|
2123
|
-
const houseOptions = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8', 'h9', 'h10', 'h11', 'h12'];
|
|
2124
|
-
const selectedHouseOption = houseOptions.find(opt => options[opt]);
|
|
2125
|
-
|
|
2126
|
-
if (selectedHouseOption && options.folder) {
|
|
2127
|
-
const targetHouse = parseInt(selectedHouseOption.substring(1));
|
|
2128
|
-
const houseSystem = options.hs ? options.hs.toLowerCase() : 'koch';
|
|
2129
|
-
await filterFilesByHouse(planet, options.folder, targetHouse,
|
|
2130
|
-
getHouseSystemCode(houseSystem));
|
|
2131
|
-
|
|
2132
|
-
// Handle AI request for house filter
|
|
2133
|
-
if (options.p) {
|
|
2134
|
-
const folderData = {
|
|
2135
|
-
planet: planet,
|
|
2136
|
-
sign: 'Multiple',
|
|
2137
|
-
degreeInSign: 'Multiple',
|
|
2138
|
-
dignity: `Folder analysis: Files filtered by ${planet} in house ${targetHouse} (${houseSystem} system)`,
|
|
2139
|
-
element: 'Multiple',
|
|
2140
|
-
decan: 'Multiple',
|
|
2141
|
-
analysisType: 'house-filter',
|
|
2142
|
-
targetHouse: targetHouse,
|
|
2143
|
-
houseSystem: houseSystem
|
|
2144
|
-
};
|
|
2145
|
-
await handleAIRequest(options, folderData);
|
|
2146
|
-
}
|
|
2147
|
-
return;
|
|
2148
|
-
}
|
|
2149
|
-
|
|
2150
|
-
// Perform folder analysis if --folder option is provided
|
|
2151
|
-
if (options.folder) {
|
|
2152
|
-
const houseSystem = options.hs ? options.hs.toLowerCase() : 'koch';
|
|
2153
|
-
await analyzeHouseDistribution(planet, options.folder, getHouseSystemCode(houseSystem));
|
|
2154
|
-
|
|
2155
|
-
// Handle AI request for folder analysis
|
|
2156
|
-
if (options.p) {
|
|
2157
|
-
const folderData = {
|
|
2158
|
-
planet: planet,
|
|
2159
|
-
sign: 'Multiple',
|
|
2160
|
-
degreeInSign: 'Multiple',
|
|
2161
|
-
dignity: `Folder analysis: House distribution for ${planet} (${houseSystem} system)`,
|
|
2162
|
-
element: 'Multiple',
|
|
2163
|
-
decan: 'Multiple',
|
|
2164
|
-
analysisType: 'folder-analysis',
|
|
2165
|
-
houseSystem: houseSystem
|
|
2166
|
-
};
|
|
2167
|
-
await handleAIRequest(options, folderData);
|
|
2168
|
-
}
|
|
2169
|
-
return;
|
|
2170
|
-
}
|
|
2171
|
-
|
|
2172
|
-
// Use person data if --p1, --p2, or --ich option is provided
|
|
2145
|
+
// Use person data if --p1, --p2, or --i option is provided
|
|
2173
2146
|
let customDate = null;
|
|
2174
2147
|
const personDataToUse = getPersonDataToUse(options);
|
|
2175
2148
|
if (personDataToUse.data) {
|
|
@@ -2193,7 +2166,7 @@ program
|
|
|
2193
2166
|
console.log(`Location: ${customDate.location.name}, ${customDate.location.country}`);
|
|
2194
2167
|
}
|
|
2195
2168
|
}
|
|
2196
|
-
// Use custom date if provided (overrides --p1, --p2, and --
|
|
2169
|
+
// Use custom date if provided (overrides --p1, --p2, and --i options)
|
|
2197
2170
|
if (options.d) {
|
|
2198
2171
|
// Try to parse the date as DD.MM.YYYY or DD.MM.YYYY HH:MM
|
|
2199
2172
|
const dateRegex = /^(\d{1,2})\.(\d{1,2})\.(\d{4})(?:\s+(\d{1,2}):(\d{2}))?$/;
|
|
@@ -2269,7 +2242,7 @@ program
|
|
|
2269
2242
|
// Show only house table (without planet info)
|
|
2270
2243
|
if (options.hl) {
|
|
2271
2244
|
const julianDay = getJulianDay(null, shouldUsePersonData(options));
|
|
2272
|
-
const useBirthLocation = shouldUsePersonData(options); // Use birth location if --p1, --p2 or --
|
|
2245
|
+
const useBirthLocation = shouldUsePersonData(options); // Use birth location if --p1, --p2 or --i option is specified
|
|
2273
2246
|
|
|
2274
2247
|
try {
|
|
2275
2248
|
let houses;
|
|
@@ -2331,33 +2304,45 @@ program
|
|
|
2331
2304
|
// Example: "saturn k neptun" for Saturn conjunction Neptune
|
|
2332
2305
|
|
|
2333
2306
|
// Parse planet and aspect information
|
|
2334
|
-
|
|
2307
|
+
let planet1, aspectType, planet2, count;
|
|
2308
|
+
|
|
2309
|
+
// Check if arguments are already parsed (from CLI service executeCommand)
|
|
2310
|
+
if (options.vPlanet1 && options.vAspectType && options.vPlanet2) {
|
|
2311
|
+
// Arguments already parsed by CLI service
|
|
2312
|
+
planet1 = options.vPlanet1.toLowerCase();
|
|
2313
|
+
aspectType = options.vAspectType.toLowerCase();
|
|
2314
|
+
planet2 = options.vPlanet2.toLowerCase();
|
|
2315
|
+
count = parseInt(options.v);
|
|
2316
|
+
} else {
|
|
2317
|
+
// Parse from process.argv (direct CLI execution)
|
|
2318
|
+
const args = process.argv.slice(2); // Skip 'node' and 'script.js'
|
|
2335
2319
|
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2320
|
+
// Find position of --v option
|
|
2321
|
+
const vIndex = args.findIndex(arg => arg === '--v');
|
|
2322
|
+
if (vIndex === -1) {
|
|
2323
|
+
console.error('Error: --v option not found');
|
|
2324
|
+
process.exit(1);
|
|
2325
|
+
}
|
|
2342
2326
|
|
|
2343
|
-
|
|
2344
|
-
|
|
2327
|
+
// The next arguments after --v should be count, planet1, aspectType, planet2
|
|
2328
|
+
count = parseInt(options.v);
|
|
2329
|
+
|
|
2330
|
+
// We need three additional arguments: planet1, aspectType, planet2
|
|
2331
|
+
// The arguments are the next three arguments after --v
|
|
2332
|
+
// Check if we have enough arguments
|
|
2333
|
+
if (args.length < vIndex + 5) {
|
|
2334
|
+
console.error('Error: Past aspects require two planets and an aspect type.');
|
|
2335
|
+
console.error('Format: --v <count> planet1 aspectType planet2');
|
|
2336
|
+
console.error('Example: --v 3 saturn k neptun');
|
|
2337
|
+
console.error('Aspect types: k=conjunction, o=opposition, q=square, t=trine, s=sextile');
|
|
2338
|
+
process.exit(1);
|
|
2339
|
+
}
|
|
2345
2340
|
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
if (args.length < vIndex + 5) {
|
|
2350
|
-
console.error('Error: Past aspects require two planets and an aspect type.');
|
|
2351
|
-
console.error('Format: --v <count> planet1 aspectType planet2');
|
|
2352
|
-
console.error('Example: --v 3 saturn k neptun');
|
|
2353
|
-
console.error('Aspect types: k=conjunction, o=opposition, q=square, t=trine, s=sextile');
|
|
2354
|
-
process.exit(1);
|
|
2341
|
+
planet1 = args[vIndex + 2].toLowerCase();
|
|
2342
|
+
aspectType = args[vIndex + 3].toLowerCase();
|
|
2343
|
+
planet2 = args[vIndex + 4].toLowerCase();
|
|
2355
2344
|
}
|
|
2356
2345
|
|
|
2357
|
-
const planet1 = args[vIndex + 2].toLowerCase();
|
|
2358
|
-
const aspectType = args[vIndex + 3].toLowerCase();
|
|
2359
|
-
const planet2 = args[vIndex + 4].toLowerCase();
|
|
2360
|
-
|
|
2361
2346
|
// Check if planets are valid
|
|
2362
2347
|
if (!planets[planet1] || !planets[planet2]) {
|
|
2363
2348
|
console.error('Error: Invalid planets.');
|
|
@@ -2420,23 +2405,35 @@ program
|
|
|
2420
2405
|
// Example: "saturn k neptun" for Saturn conjunction Neptune
|
|
2421
2406
|
|
|
2422
2407
|
// Parse planet and aspect information
|
|
2423
|
-
|
|
2408
|
+
let planet1, aspectType, planet2, count;
|
|
2409
|
+
|
|
2410
|
+
// Check if arguments are already parsed (from CLI service executeCommand)
|
|
2411
|
+
if (options.zPlanet1 && options.zAspectType && options.zPlanet2) {
|
|
2412
|
+
// Arguments already parsed by CLI service
|
|
2413
|
+
planet1 = options.zPlanet1.toLowerCase();
|
|
2414
|
+
aspectType = options.zAspectType.toLowerCase();
|
|
2415
|
+
planet2 = options.zPlanet2.toLowerCase();
|
|
2416
|
+
count = parseInt(options.z);
|
|
2417
|
+
} else {
|
|
2418
|
+
// Parse from process.argv (direct CLI execution)
|
|
2419
|
+
const args = process.argv.slice(2); // Skip 'node' and 'script.js'
|
|
2424
2420
|
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2421
|
+
// Find position of --z option
|
|
2422
|
+
const zIndex = args.findIndex(arg => arg === '--z');
|
|
2423
|
+
if (zIndex === -1) {
|
|
2424
|
+
console.error('Error: --z option not found');
|
|
2425
|
+
process.exit(1);
|
|
2426
|
+
}
|
|
2431
2427
|
|
|
2432
|
-
|
|
2433
|
-
|
|
2428
|
+
// The next arguments after --z should be count, planet1, aspectType, planet2
|
|
2429
|
+
count = parseInt(options.z);
|
|
2434
2430
|
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2431
|
+
// We need three additional arguments: planet1, aspectType, planet2
|
|
2432
|
+
// The arguments are the next three arguments after --z
|
|
2433
|
+
planet1 = args[zIndex + 2].toLowerCase();
|
|
2434
|
+
aspectType = args[zIndex + 3].toLowerCase();
|
|
2435
|
+
planet2 = args[zIndex + 4].toLowerCase();
|
|
2436
|
+
}
|
|
2440
2437
|
|
|
2441
2438
|
if (!planet1 || !aspectType || !planet2) {
|
|
2442
2439
|
console.error('Error: Future aspects require two planets and an aspect type.');
|
|
@@ -2715,7 +2712,7 @@ program
|
|
|
2715
2712
|
|
|
2716
2713
|
// House calculation with planet position
|
|
2717
2714
|
if (options.hs) {
|
|
2718
|
-
// Use person data if --p1, --p2 or --
|
|
2715
|
+
// Use person data if --p1, --p2 or --i option is specified
|
|
2719
2716
|
let customDate = null;
|
|
2720
2717
|
let useBirthData = false;
|
|
2721
2718
|
let personSource = null;
|
|
@@ -2801,4 +2798,3 @@ function getAspectTypeFullName(aspectType) {
|
|
|
2801
2798
|
|
|
2802
2799
|
return aspectNames[aspectType.toLowerCase()] || aspectType;
|
|
2803
2800
|
}
|
|
2804
|
-
|