mingpan 0.1.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/LICENSE +201 -0
- package/README.md +118 -0
- package/dist/core/bazi/BaziCore.d.ts +112 -0
- package/dist/core/bazi/BaziCore.d.ts.map +1 -0
- package/dist/core/bazi/BaziCore.js +606 -0
- package/dist/core/bazi/BaziCore.js.map +1 -0
- package/dist/core/bazi/SolarTermCalculator.d.ts +46 -0
- package/dist/core/bazi/SolarTermCalculator.d.ts.map +1 -0
- package/dist/core/bazi/SolarTermCalculator.js +452 -0
- package/dist/core/bazi/SolarTermCalculator.js.map +1 -0
- package/dist/core/bazi/TrueSolarTime.d.ts +64 -0
- package/dist/core/bazi/TrueSolarTime.d.ts.map +1 -0
- package/dist/core/bazi/TrueSolarTime.js +210 -0
- package/dist/core/bazi/TrueSolarTime.js.map +1 -0
- package/dist/core/bazi/ephemerisData.d.ts +10 -0
- package/dist/core/bazi/ephemerisData.d.ts.map +1 -0
- package/dist/core/bazi/ephemerisData.js +88 -0
- package/dist/core/bazi/ephemerisData.js.map +1 -0
- package/dist/core/bazi/index.d.ts +8 -0
- package/dist/core/bazi/index.d.ts.map +1 -0
- package/dist/core/bazi/index.js +30 -0
- package/dist/core/bazi/index.js.map +1 -0
- package/dist/core/bazi/types.d.ts +116 -0
- package/dist/core/bazi/types.d.ts.map +1 -0
- package/dist/core/bazi/types.js +7 -0
- package/dist/core/bazi/types.js.map +1 -0
- package/dist/core/calendar/SolarTermsCalculator.d.ts +33 -0
- package/dist/core/calendar/SolarTermsCalculator.d.ts.map +1 -0
- package/dist/core/calendar/SolarTermsCalculator.js +111 -0
- package/dist/core/calendar/SolarTermsCalculator.js.map +1 -0
- package/dist/core/calendar/astronomicalCalendar.d.ts +74 -0
- package/dist/core/calendar/astronomicalCalendar.d.ts.map +1 -0
- package/dist/core/calendar/astronomicalCalendar.js +276 -0
- package/dist/core/calendar/astronomicalCalendar.js.map +1 -0
- package/dist/core/calendar/calendar.d.ts +81 -0
- package/dist/core/calendar/calendar.d.ts.map +1 -0
- package/dist/core/calendar/calendar.js +223 -0
- package/dist/core/calendar/calendar.js.map +1 -0
- package/dist/core/calendar/constants.d.ts +151 -0
- package/dist/core/calendar/constants.d.ts.map +1 -0
- package/dist/core/calendar/constants.js +97 -0
- package/dist/core/calendar/constants.js.map +1 -0
- package/dist/core/calendar/julian.d.ts +54 -0
- package/dist/core/calendar/julian.d.ts.map +1 -0
- package/dist/core/calendar/julian.js +142 -0
- package/dist/core/calendar/julian.js.map +1 -0
- package/dist/core/calendar/lunarCalendar.d.ts +79 -0
- package/dist/core/calendar/lunarCalendar.d.ts.map +1 -0
- package/dist/core/calendar/lunarCalendar.js +164 -0
- package/dist/core/calendar/lunarCalendar.js.map +1 -0
- package/dist/core/calendar/solarTerms.d.ts +105 -0
- package/dist/core/calendar/solarTerms.d.ts.map +1 -0
- package/dist/core/calendar/solarTerms.js +487 -0
- package/dist/core/calendar/solarTerms.js.map +1 -0
- package/dist/core/constants/bazi.d.ts +138 -0
- package/dist/core/constants/bazi.d.ts.map +1 -0
- package/dist/core/constants/bazi.js +332 -0
- package/dist/core/constants/bazi.js.map +1 -0
- package/dist/core/constants/index.d.ts +6 -0
- package/dist/core/constants/index.d.ts.map +1 -0
- package/dist/core/constants/index.js +37 -0
- package/dist/core/constants/index.js.map +1 -0
- package/dist/core/constants/positions.d.ts +27 -0
- package/dist/core/constants/positions.d.ts.map +1 -0
- package/dist/core/constants/positions.js +39 -0
- package/dist/core/constants/positions.js.map +1 -0
- package/dist/core/ziwei/BrightnessSystem.d.ts +53 -0
- package/dist/core/ziwei/BrightnessSystem.d.ts.map +1 -0
- package/dist/core/ziwei/BrightnessSystem.js +278 -0
- package/dist/core/ziwei/BrightnessSystem.js.map +1 -0
- package/dist/core/ziwei/IztroAdapter.d.ts +78 -0
- package/dist/core/ziwei/IztroAdapter.d.ts.map +1 -0
- package/dist/core/ziwei/IztroAdapter.js +314 -0
- package/dist/core/ziwei/IztroAdapter.js.map +1 -0
- package/dist/core/ziwei/MutagenCore.d.ts +81 -0
- package/dist/core/ziwei/MutagenCore.d.ts.map +1 -0
- package/dist/core/ziwei/MutagenCore.js +246 -0
- package/dist/core/ziwei/MutagenCore.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1101 -0
- package/dist/index.js.map +1 -0
- package/dist/output/fortuneTextRenderer.d.ts +63 -0
- package/dist/output/fortuneTextRenderer.d.ts.map +1 -0
- package/dist/output/fortuneTextRenderer.js +384 -0
- package/dist/output/fortuneTextRenderer.js.map +1 -0
- package/dist/output/listTextRenderer.d.ts +298 -0
- package/dist/output/listTextRenderer.d.ts.map +1 -0
- package/dist/output/listTextRenderer.js +942 -0
- package/dist/output/listTextRenderer.js.map +1 -0
- package/dist/services/bazi/BaziService.d.ts +83 -0
- package/dist/services/bazi/BaziService.d.ts.map +1 -0
- package/dist/services/bazi/BaziService.js +635 -0
- package/dist/services/bazi/BaziService.js.map +1 -0
- package/dist/services/bazi/analyzers/ClimateAnalyzer.d.ts +31 -0
- package/dist/services/bazi/analyzers/ClimateAnalyzer.d.ts.map +1 -0
- package/dist/services/bazi/analyzers/ClimateAnalyzer.js +194 -0
- package/dist/services/bazi/analyzers/ClimateAnalyzer.js.map +1 -0
- package/dist/services/bazi/analyzers/HiddenStemsAnalyzer.d.ts +16 -0
- package/dist/services/bazi/analyzers/HiddenStemsAnalyzer.d.ts.map +1 -0
- package/dist/services/bazi/analyzers/HiddenStemsAnalyzer.js +60 -0
- package/dist/services/bazi/analyzers/HiddenStemsAnalyzer.js.map +1 -0
- package/dist/services/bazi/analyzers/NaYinAnalyzer.d.ts +33 -0
- package/dist/services/bazi/analyzers/NaYinAnalyzer.d.ts.map +1 -0
- package/dist/services/bazi/analyzers/NaYinAnalyzer.js +209 -0
- package/dist/services/bazi/analyzers/NaYinAnalyzer.js.map +1 -0
- package/dist/services/bazi/analyzers/PatternAnalyzer.d.ts +159 -0
- package/dist/services/bazi/analyzers/PatternAnalyzer.d.ts.map +1 -0
- package/dist/services/bazi/analyzers/PatternAnalyzer.js +1150 -0
- package/dist/services/bazi/analyzers/PatternAnalyzer.js.map +1 -0
- package/dist/services/bazi/analyzers/RelationsAnalyzer.d.ts +114 -0
- package/dist/services/bazi/analyzers/RelationsAnalyzer.d.ts.map +1 -0
- package/dist/services/bazi/analyzers/RelationsAnalyzer.js +704 -0
- package/dist/services/bazi/analyzers/RelationsAnalyzer.js.map +1 -0
- package/dist/services/bazi/analyzers/ShenShaAnalyzer.d.ts +236 -0
- package/dist/services/bazi/analyzers/ShenShaAnalyzer.d.ts.map +1 -0
- package/dist/services/bazi/analyzers/ShenShaAnalyzer.js +2079 -0
- package/dist/services/bazi/analyzers/ShenShaAnalyzer.js.map +1 -0
- package/dist/services/bazi/analyzers/StrengthAnalyzer.d.ts +181 -0
- package/dist/services/bazi/analyzers/StrengthAnalyzer.d.ts.map +1 -0
- package/dist/services/bazi/analyzers/StrengthAnalyzer.js +1119 -0
- package/dist/services/bazi/analyzers/StrengthAnalyzer.js.map +1 -0
- package/dist/services/bazi/analyzers/TenGodsAnalyzer.d.ts +78 -0
- package/dist/services/bazi/analyzers/TenGodsAnalyzer.d.ts.map +1 -0
- package/dist/services/bazi/analyzers/TenGodsAnalyzer.js +383 -0
- package/dist/services/bazi/analyzers/TenGodsAnalyzer.js.map +1 -0
- package/dist/services/bazi/analyzers/TraditionalAnalyzer.d.ts +46 -0
- package/dist/services/bazi/analyzers/TraditionalAnalyzer.d.ts.map +1 -0
- package/dist/services/bazi/analyzers/TraditionalAnalyzer.js +260 -0
- package/dist/services/bazi/analyzers/TraditionalAnalyzer.js.map +1 -0
- package/dist/services/bazi/analyzers/YongShenAnalyzer.d.ts +70 -0
- package/dist/services/bazi/analyzers/YongShenAnalyzer.d.ts.map +1 -0
- package/dist/services/bazi/analyzers/YongShenAnalyzer.js +858 -0
- package/dist/services/bazi/analyzers/YongShenAnalyzer.js.map +1 -0
- package/dist/services/bazi/calculators/DaYunCalculator.d.ts +71 -0
- package/dist/services/bazi/calculators/DaYunCalculator.d.ts.map +1 -0
- package/dist/services/bazi/calculators/DaYunCalculator.js +496 -0
- package/dist/services/bazi/calculators/DaYunCalculator.js.map +1 -0
- package/dist/services/bazi/calculators/LiuNianCalculator.d.ts +88 -0
- package/dist/services/bazi/calculators/LiuNianCalculator.d.ts.map +1 -0
- package/dist/services/bazi/calculators/LiuNianCalculator.js +546 -0
- package/dist/services/bazi/calculators/LiuNianCalculator.js.map +1 -0
- package/dist/services/bazi/calculators/LiuRiCalculator.d.ts +66 -0
- package/dist/services/bazi/calculators/LiuRiCalculator.d.ts.map +1 -0
- package/dist/services/bazi/calculators/LiuRiCalculator.js +497 -0
- package/dist/services/bazi/calculators/LiuRiCalculator.js.map +1 -0
- package/dist/services/bazi/calculators/LiuYueCalculator.d.ts +50 -0
- package/dist/services/bazi/calculators/LiuYueCalculator.d.ts.map +1 -0
- package/dist/services/bazi/calculators/LiuYueCalculator.js +338 -0
- package/dist/services/bazi/calculators/LiuYueCalculator.js.map +1 -0
- package/dist/services/bazi/calculators/LuckCycleCalculator.d.ts +123 -0
- package/dist/services/bazi/calculators/LuckCycleCalculator.d.ts.map +1 -0
- package/dist/services/bazi/calculators/LuckCycleCalculator.js +414 -0
- package/dist/services/bazi/calculators/LuckCycleCalculator.js.map +1 -0
- package/dist/services/bazi/index.d.ts +21 -0
- package/dist/services/bazi/index.d.ts.map +1 -0
- package/dist/services/bazi/index.js +83 -0
- package/dist/services/bazi/index.js.map +1 -0
- package/dist/services/bazi/types.d.ts +597 -0
- package/dist/services/bazi/types.d.ts.map +1 -0
- package/dist/services/bazi/types.js +123 -0
- package/dist/services/bazi/types.js.map +1 -0
- package/dist/services/ziwei/ZiweiService.d.ts +86 -0
- package/dist/services/ziwei/ZiweiService.d.ts.map +1 -0
- package/dist/services/ziwei/ZiweiService.js +343 -0
- package/dist/services/ziwei/ZiweiService.js.map +1 -0
- package/dist/services/ziwei/calculators/BrightnessCalculator.d.ts +38 -0
- package/dist/services/ziwei/calculators/BrightnessCalculator.d.ts.map +1 -0
- package/dist/services/ziwei/calculators/BrightnessCalculator.js +142 -0
- package/dist/services/ziwei/calculators/BrightnessCalculator.js.map +1 -0
- package/dist/services/ziwei/calculators/DailyCalculator.d.ts +27 -0
- package/dist/services/ziwei/calculators/DailyCalculator.d.ts.map +1 -0
- package/dist/services/ziwei/calculators/DailyCalculator.js +55 -0
- package/dist/services/ziwei/calculators/DailyCalculator.js.map +1 -0
- package/dist/services/ziwei/calculators/DecadeCalculator.d.ts +46 -0
- package/dist/services/ziwei/calculators/DecadeCalculator.d.ts.map +1 -0
- package/dist/services/ziwei/calculators/DecadeCalculator.js +181 -0
- package/dist/services/ziwei/calculators/DecadeCalculator.js.map +1 -0
- package/dist/services/ziwei/calculators/HoroscopeStarsCalculator.d.ts +28 -0
- package/dist/services/ziwei/calculators/HoroscopeStarsCalculator.d.ts.map +1 -0
- package/dist/services/ziwei/calculators/HoroscopeStarsCalculator.js +84 -0
- package/dist/services/ziwei/calculators/HoroscopeStarsCalculator.js.map +1 -0
- package/dist/services/ziwei/calculators/HourlyCalculator.d.ts +41 -0
- package/dist/services/ziwei/calculators/HourlyCalculator.d.ts.map +1 -0
- package/dist/services/ziwei/calculators/HourlyCalculator.js +139 -0
- package/dist/services/ziwei/calculators/HourlyCalculator.js.map +1 -0
- package/dist/services/ziwei/calculators/MinorLimitCalculator.d.ts +30 -0
- package/dist/services/ziwei/calculators/MinorLimitCalculator.d.ts.map +1 -0
- package/dist/services/ziwei/calculators/MinorLimitCalculator.js +90 -0
- package/dist/services/ziwei/calculators/MinorLimitCalculator.js.map +1 -0
- package/dist/services/ziwei/calculators/MonthlyCalculator.d.ts +39 -0
- package/dist/services/ziwei/calculators/MonthlyCalculator.d.ts.map +1 -0
- package/dist/services/ziwei/calculators/MonthlyCalculator.js +128 -0
- package/dist/services/ziwei/calculators/MonthlyCalculator.js.map +1 -0
- package/dist/services/ziwei/calculators/MutagenCalculator.d.ts +20 -0
- package/dist/services/ziwei/calculators/MutagenCalculator.d.ts.map +1 -0
- package/dist/services/ziwei/calculators/MutagenCalculator.js +121 -0
- package/dist/services/ziwei/calculators/MutagenCalculator.js.map +1 -0
- package/dist/services/ziwei/calculators/PalaceDynamicCalculator.d.ts +35 -0
- package/dist/services/ziwei/calculators/PalaceDynamicCalculator.d.ts.map +1 -0
- package/dist/services/ziwei/calculators/PalaceDynamicCalculator.js +55 -0
- package/dist/services/ziwei/calculators/PalaceDynamicCalculator.js.map +1 -0
- package/dist/services/ziwei/calculators/YearlyCalculator.d.ts +35 -0
- package/dist/services/ziwei/calculators/YearlyCalculator.d.ts.map +1 -0
- package/dist/services/ziwei/calculators/YearlyCalculator.js +119 -0
- package/dist/services/ziwei/calculators/YearlyCalculator.js.map +1 -0
- package/dist/services/ziwei/index.d.ts +15 -0
- package/dist/services/ziwei/index.d.ts.map +1 -0
- package/dist/services/ziwei/index.js +48 -0
- package/dist/services/ziwei/index.js.map +1 -0
- package/dist/services/ziwei/transformers/PalaceTransformer.d.ts +62 -0
- package/dist/services/ziwei/transformers/PalaceTransformer.d.ts.map +1 -0
- package/dist/services/ziwei/transformers/PalaceTransformer.js +153 -0
- package/dist/services/ziwei/transformers/PalaceTransformer.js.map +1 -0
- package/dist/services/ziwei/types.d.ts +185 -0
- package/dist/services/ziwei/types.d.ts.map +1 -0
- package/dist/services/ziwei/types.js +54 -0
- package/dist/services/ziwei/types.js.map +1 -0
- package/dist/shared/logger.d.ts +51 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +136 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/types.d.ts +91 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +7 -0
- package/dist/shared/types.js.map +1 -0
- package/dist/utils/ageCalculator.d.ts +30 -0
- package/dist/utils/ageCalculator.d.ts.map +1 -0
- package/dist/utils/ageCalculator.js +51 -0
- package/dist/utils/ageCalculator.js.map +1 -0
- package/package.json +54 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1101 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Mingpan MCP Server
|
|
5
|
+
*
|
|
6
|
+
* MCP service for accurate BaZi (八字) and ZiWei (紫微) chart calculations.
|
|
7
|
+
* Takes birth date/time and outputs structured fortune-telling information.
|
|
8
|
+
*
|
|
9
|
+
* Version 1.1.0: Added fortune list tools for DaYun, LiuNian, LiuYue, LiuRi
|
|
10
|
+
* - 八字流月 uses 干支月 (solar term months)
|
|
11
|
+
* - 紫微流月 uses 农历月 (lunar months)
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
15
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
16
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
17
|
+
const zod_1 = require("zod");
|
|
18
|
+
const zod_to_json_schema_1 = require("zod-to-json-schema");
|
|
19
|
+
const lunar_javascript_1 = require("lunar-javascript");
|
|
20
|
+
const BaziService_1 = require("./services/bazi/BaziService");
|
|
21
|
+
const ZiweiService_1 = require("./services/ziwei/ZiweiService");
|
|
22
|
+
const LiuNianCalculator_1 = require("./services/bazi/calculators/LiuNianCalculator");
|
|
23
|
+
const DaYunCalculator_1 = require("./services/bazi/calculators/DaYunCalculator");
|
|
24
|
+
const LuckCycleCalculator_1 = require("./services/bazi/calculators/LuckCycleCalculator");
|
|
25
|
+
const LiuYueCalculator_1 = require("./services/bazi/calculators/LiuYueCalculator");
|
|
26
|
+
const LiuRiCalculator_1 = require("./services/bazi/calculators/LiuRiCalculator");
|
|
27
|
+
const YearlyCalculator_1 = require("./services/ziwei/calculators/YearlyCalculator");
|
|
28
|
+
const fortuneTextRenderer_1 = require("./output/fortuneTextRenderer");
|
|
29
|
+
const listTextRenderer_1 = require("./output/listTextRenderer");
|
|
30
|
+
const logger_1 = require("./shared/logger");
|
|
31
|
+
const MutagenCore_1 = require("./core/ziwei/MutagenCore");
|
|
32
|
+
const logger = new logger_1.Logger("mingpan");
|
|
33
|
+
// Helper to avoid TypeScript's excessively deep type instantiation error
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
|
+
function schemaToJson(schema) {
|
|
36
|
+
return (0, zod_to_json_schema_1.zodToJsonSchema)(schema);
|
|
37
|
+
}
|
|
38
|
+
// ============================================
|
|
39
|
+
// Zod Schemas for Tool Inputs
|
|
40
|
+
// ============================================
|
|
41
|
+
// Base birth info schema
|
|
42
|
+
const BaseBirthInfoSchema = zod_1.z.object({
|
|
43
|
+
year: zod_1.z.number().int().min(1900).max(2100).describe("Birth year (e.g., 1990)"),
|
|
44
|
+
month: zod_1.z.number().int().min(1).max(12).describe("Birth month (1-12)"),
|
|
45
|
+
day: zod_1.z.number().int().min(1).max(31).describe("Birth day (1-31)"),
|
|
46
|
+
hour: zod_1.z.number().int().min(0).max(23).describe("Birth hour in 24-hour format (0-23)"),
|
|
47
|
+
minute: zod_1.z.number().int().min(0).max(59).optional().default(0).describe("Birth minute (0-59)"),
|
|
48
|
+
gender: zod_1.z.enum(["male", "female"]).describe("Gender for fortune direction calculation"),
|
|
49
|
+
longitude: zod_1.z.number().min(-180).max(180).optional().describe("Birth location longitude for true solar time adjustment"),
|
|
50
|
+
name: zod_1.z.string().optional().describe("Subject name (optional)"),
|
|
51
|
+
});
|
|
52
|
+
const BaziCalculateSchema = zod_1.z.object({
|
|
53
|
+
year: zod_1.z.number().int().min(1900).max(2100).describe("Birth year (e.g., 1990)"),
|
|
54
|
+
month: zod_1.z.number().int().min(1).max(12).describe("Birth month (1-12)"),
|
|
55
|
+
day: zod_1.z.number().int().min(1).max(31).describe("Birth day (1-31)"),
|
|
56
|
+
hour: zod_1.z.number().int().min(0).max(23).describe("Birth hour in 24-hour format (0-23)"),
|
|
57
|
+
minute: zod_1.z.number().int().min(0).max(59).optional().default(0).describe("Birth minute (0-59)"),
|
|
58
|
+
gender: zod_1.z.enum(["male", "female"]).optional().default("male").describe("Gender for DaYun calculation direction"),
|
|
59
|
+
longitude: zod_1.z.number().min(-180).max(180).optional().describe("Birth location longitude for true solar time adjustment"),
|
|
60
|
+
isLunar: zod_1.z.boolean().optional().default(false).describe("Whether the birth date is in lunar calendar"),
|
|
61
|
+
detail: zod_1.z.enum(["simple", "standard", "detailed"]).optional().default("standard").describe("Output detail level"),
|
|
62
|
+
includeAnalysis: zod_1.z.boolean().optional().default(true).describe("Include strength and pattern analysis"),
|
|
63
|
+
includeDaYun: zod_1.z.boolean().optional().default(true).describe("Include decade fortune (大運)"),
|
|
64
|
+
targetYear: zod_1.z.number().int().optional().describe("Calculate LiuNian (流年) for this specific year"),
|
|
65
|
+
});
|
|
66
|
+
const ZiweiCalculateSchema = zod_1.z.object({
|
|
67
|
+
year: zod_1.z.number().int().min(1900).max(2100).describe("Birth year (e.g., 1990)"),
|
|
68
|
+
month: zod_1.z.number().int().min(1).max(12).describe("Birth month (1-12)"),
|
|
69
|
+
day: zod_1.z.number().int().min(1).max(31).describe("Birth day (1-31)"),
|
|
70
|
+
hour: zod_1.z.number().int().min(0).max(23).describe("Birth hour in 24-hour format (0-23)"),
|
|
71
|
+
minute: zod_1.z.number().int().min(0).max(59).optional().default(0).describe("Birth minute (0-59)"),
|
|
72
|
+
gender: zod_1.z.enum(["male", "female"]).describe("Gender (required for ZiWei calculation)"),
|
|
73
|
+
isLunar: zod_1.z.boolean().optional().default(false).describe("Whether the birth date is in lunar calendar"),
|
|
74
|
+
detail: zod_1.z.enum(["simple", "standard", "detailed"]).optional().default("standard").describe("Output detail level"),
|
|
75
|
+
targetYear: zod_1.z.number().int().optional().describe("Calculate yearly fortune for this specific year"),
|
|
76
|
+
includeDecades: zod_1.z.boolean().optional().default(true).describe("Include decade fortune (大限)"),
|
|
77
|
+
includeMutagen: zod_1.z.boolean().optional().default(true).describe("Include four mutagens (四化)"),
|
|
78
|
+
});
|
|
79
|
+
const CombinedCalculateSchema = zod_1.z.object({
|
|
80
|
+
year: zod_1.z.number().int().min(1900).max(2100).describe("Birth year (e.g., 1990)"),
|
|
81
|
+
month: zod_1.z.number().int().min(1).max(12).describe("Birth month (1-12)"),
|
|
82
|
+
day: zod_1.z.number().int().min(1).max(31).describe("Birth day (1-31)"),
|
|
83
|
+
hour: zod_1.z.number().int().min(0).max(23).describe("Birth hour in 24-hour format (0-23)"),
|
|
84
|
+
minute: zod_1.z.number().int().min(0).max(59).optional().default(0).describe("Birth minute (0-59)"),
|
|
85
|
+
gender: zod_1.z.enum(["male", "female"]).describe("Gender (required for both calculations)"),
|
|
86
|
+
longitude: zod_1.z.number().min(-180).max(180).optional().describe("Birth location longitude for true solar time adjustment"),
|
|
87
|
+
isLunar: zod_1.z.boolean().optional().default(false).describe("Whether the birth date is in lunar calendar"),
|
|
88
|
+
detail: zod_1.z.enum(["simple", "standard", "detailed"]).optional().default("standard").describe("Output detail level"),
|
|
89
|
+
targetYear: zod_1.z.number().int().optional().describe("Calculate yearly fortune for this specific year"),
|
|
90
|
+
systems: zod_1.z.array(zod_1.z.enum(["bazi", "ziwei"])).optional().default(["bazi", "ziwei"]).describe("Which systems to calculate"),
|
|
91
|
+
});
|
|
92
|
+
// ============================================
|
|
93
|
+
// List Tool Schemas
|
|
94
|
+
// ============================================
|
|
95
|
+
// 八字大运列表
|
|
96
|
+
const BaziDaYunListSchema = BaseBirthInfoSchema.extend({
|
|
97
|
+
count: zod_1.z.number().int().min(1).max(12).optional().default(10).describe("Number of DaYun periods to display (default 10)"),
|
|
98
|
+
});
|
|
99
|
+
// 八字流年列表
|
|
100
|
+
const BaziLiuNianListSchema = BaseBirthInfoSchema.extend({
|
|
101
|
+
startYear: zod_1.z.number().int().min(1900).max(2100).describe("Start year for the range"),
|
|
102
|
+
endYear: zod_1.z.number().int().min(1900).max(2100).describe("End year for the range"),
|
|
103
|
+
});
|
|
104
|
+
// 八字流月列表(干支月/节气月)
|
|
105
|
+
const BaziLiuYueListSchema = BaseBirthInfoSchema.extend({
|
|
106
|
+
ganzhiYear: zod_1.z.union([
|
|
107
|
+
zod_1.z.string().describe("GanZhi year like '乙巳'"),
|
|
108
|
+
zod_1.z.number().int().min(1900).max(2100).describe("Gregorian year like 2025")
|
|
109
|
+
]).describe("The year to query (either GanZhi string or Gregorian year)"),
|
|
110
|
+
});
|
|
111
|
+
// 八字流日列表
|
|
112
|
+
const BaziLiuRiListSchema = BaseBirthInfoSchema.extend({
|
|
113
|
+
ganzhiYear: zod_1.z.union([
|
|
114
|
+
zod_1.z.string().describe("GanZhi year like '乙巳'"),
|
|
115
|
+
zod_1.z.number().int().min(1900).max(2100).describe("Gregorian year like 2025")
|
|
116
|
+
]).describe("The year of the month"),
|
|
117
|
+
ganzhiMonth: zod_1.z.union([
|
|
118
|
+
zod_1.z.string().describe("GanZhi month like '丙寅' (month 1 = 寅月)"),
|
|
119
|
+
zod_1.z.number().int().min(1).max(12).describe("Month number (1=寅月, 2=卯月, ..., 12=丑月)")
|
|
120
|
+
]).describe("The month to query (either GanZhi string or month number 1-12)"),
|
|
121
|
+
});
|
|
122
|
+
// 紫微大限列表
|
|
123
|
+
const ZiweiDaXianListSchema = BaseBirthInfoSchema.extend({
|
|
124
|
+
count: zod_1.z.number().int().min(1).max(12).optional().default(10).describe("Number of decade periods to display (default 10)"),
|
|
125
|
+
});
|
|
126
|
+
// 紫微小限列表
|
|
127
|
+
const ZiweiXiaoXianListSchema = BaseBirthInfoSchema.extend({
|
|
128
|
+
startAge: zod_1.z.number().int().min(1).max(120).describe("Start age (nominal age) for the range"),
|
|
129
|
+
endAge: zod_1.z.number().int().min(1).max(120).describe("End age (nominal age) for the range"),
|
|
130
|
+
});
|
|
131
|
+
// 紫微流年列表
|
|
132
|
+
const ZiweiLiuNianListSchema = BaseBirthInfoSchema.extend({
|
|
133
|
+
startYear: zod_1.z.number().int().min(1900).max(2100).describe("Start year for the range"),
|
|
134
|
+
endYear: zod_1.z.number().int().min(1900).max(2100).describe("End year for the range"),
|
|
135
|
+
});
|
|
136
|
+
// 紫微流月列表(农历月)
|
|
137
|
+
const ZiweiLiuYueListSchema = BaseBirthInfoSchema.extend({
|
|
138
|
+
lunarYear: zod_1.z.number().int().min(1900).max(2100).describe("The lunar year (Gregorian year) to query"),
|
|
139
|
+
});
|
|
140
|
+
// 紫微流日列表(农历日)
|
|
141
|
+
const ZiweiLiuRiListSchema = BaseBirthInfoSchema.extend({
|
|
142
|
+
lunarYear: zod_1.z.number().int().min(1900).max(2100).describe("The lunar year (Gregorian year)"),
|
|
143
|
+
lunarMonth: zod_1.z.number().int().min(-12).max(12).describe("Lunar month (1-12, use negative for leap month, e.g. -6 for leap 6th month)"),
|
|
144
|
+
});
|
|
145
|
+
// ============================================
|
|
146
|
+
// Create Server
|
|
147
|
+
// ============================================
|
|
148
|
+
const server = new index_js_1.Server({
|
|
149
|
+
name: "mingpan",
|
|
150
|
+
version: "0.1.1",
|
|
151
|
+
}, {
|
|
152
|
+
capabilities: {
|
|
153
|
+
tools: {},
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
// ============================================
|
|
157
|
+
// Tool Definitions
|
|
158
|
+
// ============================================
|
|
159
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
160
|
+
return {
|
|
161
|
+
tools: [
|
|
162
|
+
{
|
|
163
|
+
name: "bazi_basic",
|
|
164
|
+
description: `计算八字命盘(基础排盘)。
|
|
165
|
+
|
|
166
|
+
输入出生时间,返回完整的八字命盘信息:
|
|
167
|
+
- 四柱(年柱、月柱、日柱、时柱)干支
|
|
168
|
+
- 各柱藏干
|
|
169
|
+
- 十神配置
|
|
170
|
+
- 五行力量分析(360分制)
|
|
171
|
+
- 日主强弱判定
|
|
172
|
+
- 格局识别
|
|
173
|
+
- 神煞标注
|
|
174
|
+
|
|
175
|
+
输出为结构化文本,便于 AI 分析解读。`,
|
|
176
|
+
inputSchema: schemaToJson(BaziCalculateSchema),
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
name: "ziwei_basic",
|
|
180
|
+
description: `计算紫微斗数命盘(基础排盘)。
|
|
181
|
+
|
|
182
|
+
输入出生时间,返回完整的紫微命盘信息:
|
|
183
|
+
- 十二宫位排布及干支
|
|
184
|
+
- 各宫主星及亮度(庙/旺/得/利/平/不/陷)
|
|
185
|
+
- 各宫辅星配置
|
|
186
|
+
- 命宫与身宫位置
|
|
187
|
+
- 本命四化(化禄/权/科/忌)
|
|
188
|
+
|
|
189
|
+
输出为结构化文本,便于 AI 分析解读。`,
|
|
190
|
+
inputSchema: schemaToJson(ZiweiCalculateSchema),
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: "bazi_dayun",
|
|
194
|
+
description: `八字大运列表。
|
|
195
|
+
|
|
196
|
+
返回命主一生的大运周期(十年一运):
|
|
197
|
+
- 大运干支
|
|
198
|
+
- 起止虚岁
|
|
199
|
+
- 对应公历年份
|
|
200
|
+
- 起运方向(顺行/逆行)
|
|
201
|
+
- 起运年龄
|
|
202
|
+
|
|
203
|
+
用于了解人生各阶段的运势大框架。`,
|
|
204
|
+
inputSchema: schemaToJson(BaziDaYunListSchema),
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
name: "bazi_liunian",
|
|
208
|
+
description: `八字流年列表。
|
|
209
|
+
|
|
210
|
+
返回指定年份范围内的流年信息:
|
|
211
|
+
- 公历年份
|
|
212
|
+
- 干支年
|
|
213
|
+
- 虚岁
|
|
214
|
+
- 所属大运
|
|
215
|
+
|
|
216
|
+
用于分析多年运势趋势。`,
|
|
217
|
+
inputSchema: schemaToJson(BaziLiuNianListSchema),
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: "bazi_liuyue",
|
|
221
|
+
description: `八字流月列表。
|
|
222
|
+
|
|
223
|
+
重要:八字流月使用【节气月】,非农历月!
|
|
224
|
+
- 以节气为边界(立春起算)
|
|
225
|
+
- 寅月(正月)从立春开始,约2月4日
|
|
226
|
+
- 丑月(腊月)跨越公历年界
|
|
227
|
+
|
|
228
|
+
返回指定年份的12个月运势:
|
|
229
|
+
- 干支月
|
|
230
|
+
- 节气起止
|
|
231
|
+
- 公历日期范围
|
|
232
|
+
|
|
233
|
+
用于规划年度活动时机。`,
|
|
234
|
+
inputSchema: schemaToJson(BaziLiuYueListSchema),
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
name: "bazi_liuri",
|
|
238
|
+
description: `八字流日列表。
|
|
239
|
+
|
|
240
|
+
返回指定月份内的每日运势(含上下文):
|
|
241
|
+
- 当前大运、流年、流月资讯
|
|
242
|
+
- 公历日期
|
|
243
|
+
- 干支日
|
|
244
|
+
|
|
245
|
+
用于精细的日期选择。`,
|
|
246
|
+
inputSchema: schemaToJson(BaziLiuRiListSchema),
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: "ziwei_daxian",
|
|
250
|
+
description: `紫微大限列表。
|
|
251
|
+
|
|
252
|
+
返回命主一生的大限周期(十年一限):
|
|
253
|
+
- 起止虚岁
|
|
254
|
+
- 对应公历年份
|
|
255
|
+
- 大限宫位名称
|
|
256
|
+
- 宫内主星配置
|
|
257
|
+
- 大限四化
|
|
258
|
+
|
|
259
|
+
用于了解人生各阶段的运势大框架。`,
|
|
260
|
+
inputSchema: schemaToJson(ZiweiDaXianListSchema),
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: "ziwei_xiaoxian",
|
|
264
|
+
description: `紫微小限列表。
|
|
265
|
+
|
|
266
|
+
小限是紫微斗数中的年度运限单位,每年一宫:
|
|
267
|
+
- 虚岁(1岁起)
|
|
268
|
+
- 对应公历年份
|
|
269
|
+
- 小限宫位(根据出生年支起宫,男顺女逆)
|
|
270
|
+
- 宫内主星
|
|
271
|
+
- 所属大限
|
|
272
|
+
- 小限四化
|
|
273
|
+
|
|
274
|
+
小限与流年并列但计算方式不同:
|
|
275
|
+
- 小限:以出生年支定起宫,逐年移宫
|
|
276
|
+
- 流年:以该年地支定宫位
|
|
277
|
+
|
|
278
|
+
层级顺序:大限 > 小限 > 流年 > 流月 > 流日`,
|
|
279
|
+
inputSchema: schemaToJson(ZiweiXiaoXianListSchema),
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
name: "ziwei_liunian",
|
|
283
|
+
description: `紫微流年列表。
|
|
284
|
+
|
|
285
|
+
返回指定年份范围内的流年信息:
|
|
286
|
+
- 公历年份
|
|
287
|
+
- 干支年
|
|
288
|
+
- 虚岁
|
|
289
|
+
- 流年宫位
|
|
290
|
+
- 宫内主星
|
|
291
|
+
- 所属大限
|
|
292
|
+
- 流年四化
|
|
293
|
+
|
|
294
|
+
用于分析多年运势趋势。`,
|
|
295
|
+
inputSchema: schemaToJson(ZiweiLiuNianListSchema),
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: "ziwei_liuyue",
|
|
299
|
+
description: `紫微流月列表。
|
|
300
|
+
|
|
301
|
+
重要:紫微流月使用【农历月】,非节气月!
|
|
302
|
+
- 以农历初一为边界
|
|
303
|
+
- 正月从春节开始
|
|
304
|
+
- 闰月单独显示(如"闰六月")
|
|
305
|
+
|
|
306
|
+
返回指定年份的流月运势(含上下文):
|
|
307
|
+
- 当前大限、小限、流年资讯
|
|
308
|
+
- 农历月份及公历日期范围
|
|
309
|
+
- 流月宫位及宫内主星
|
|
310
|
+
- 完整四化系统(本命/大限/小限/流年/流月)
|
|
311
|
+
|
|
312
|
+
用于规划年度活动时机。`,
|
|
313
|
+
inputSchema: schemaToJson(ZiweiLiuYueListSchema),
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
name: "ziwei_liuri",
|
|
317
|
+
description: `紫微流日列表。
|
|
318
|
+
|
|
319
|
+
返回指定农历月内的每日运势(含上下文):
|
|
320
|
+
- 当前大限、小限、流年、流月资讯
|
|
321
|
+
- 农历日期与公历日期对照
|
|
322
|
+
- 干支日及流日宫位
|
|
323
|
+
- 完整四化系统(本命/大限/小限/流年/流月/流日)
|
|
324
|
+
|
|
325
|
+
闰月使用负数表示(如 -6 表示闰六月)。
|
|
326
|
+
|
|
327
|
+
用于精细的日期选择。`,
|
|
328
|
+
inputSchema: schemaToJson(ZiweiLiuRiListSchema),
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
};
|
|
332
|
+
});
|
|
333
|
+
// ============================================
|
|
334
|
+
// Tool Handlers
|
|
335
|
+
// ============================================
|
|
336
|
+
const baziService = new BaziService_1.BaziService({ debug: false });
|
|
337
|
+
const ziweiService = new ZiweiService_1.ZiweiService();
|
|
338
|
+
// Helper: Calculate year stem and branch
|
|
339
|
+
function getYearStemBranch(year) {
|
|
340
|
+
const STEMS = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'];
|
|
341
|
+
const BRANCHES = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];
|
|
342
|
+
const baseYear = 1984; // 甲子年
|
|
343
|
+
const yearDiff = year - baseYear;
|
|
344
|
+
const stemIndex = ((yearDiff % 10) + 10) % 10;
|
|
345
|
+
const branchIndex = ((yearDiff % 12) + 12) % 12;
|
|
346
|
+
return { stem: STEMS[stemIndex], branch: BRANCHES[branchIndex] };
|
|
347
|
+
}
|
|
348
|
+
// Helper: Parse GanZhi year input
|
|
349
|
+
function parseGanzhiYear(input) {
|
|
350
|
+
if (typeof input === 'number') {
|
|
351
|
+
const { stem, branch } = getYearStemBranch(input);
|
|
352
|
+
return { year: input, ganzhi: stem + branch };
|
|
353
|
+
}
|
|
354
|
+
// Parse GanZhi string to find year - search nearby years
|
|
355
|
+
const currentYear = new Date().getFullYear();
|
|
356
|
+
for (let y = currentYear - 60; y <= currentYear + 60; y++) {
|
|
357
|
+
const { stem, branch } = getYearStemBranch(y);
|
|
358
|
+
if (stem + branch === input) {
|
|
359
|
+
return { year: y, ganzhi: input };
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// Default to current year if not found
|
|
363
|
+
const { stem, branch } = getYearStemBranch(currentYear);
|
|
364
|
+
return { year: currentYear, ganzhi: stem + branch };
|
|
365
|
+
}
|
|
366
|
+
// Helper: Parse GanZhi month input
|
|
367
|
+
function parseGanzhiMonth(input) {
|
|
368
|
+
if (typeof input === 'number') {
|
|
369
|
+
return input; // 1-12
|
|
370
|
+
}
|
|
371
|
+
// Parse GanZhi month string to get month index
|
|
372
|
+
const BRANCHES = ['寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥', '子', '丑'];
|
|
373
|
+
const branch = input.substring(1, 2);
|
|
374
|
+
const idx = BRANCHES.indexOf(branch);
|
|
375
|
+
return idx >= 0 ? idx + 1 : 1;
|
|
376
|
+
}
|
|
377
|
+
// Helper: Get month stem branch for a given year and month
|
|
378
|
+
function getMonthStemBranch(year, monthNum) {
|
|
379
|
+
const STEMS = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'];
|
|
380
|
+
const BRANCHES = ['寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥', '子', '丑'];
|
|
381
|
+
// Month branch: monthNum 1 = 寅, 2 = 卯, ..., 12 = 丑
|
|
382
|
+
const branch = BRANCHES[(monthNum - 1) % 12];
|
|
383
|
+
// Month stem depends on year stem
|
|
384
|
+
const { stem: yearStem } = getYearStemBranch(year);
|
|
385
|
+
const yearStemIndex = STEMS.indexOf(yearStem);
|
|
386
|
+
// 五虎遁年起月诀
|
|
387
|
+
const firstMonthStemMap = {
|
|
388
|
+
0: 2, // 甲年 -> 丙寅月
|
|
389
|
+
1: 4, // 乙年 -> 戊寅月
|
|
390
|
+
2: 6, // 丙年 -> 庚寅月
|
|
391
|
+
3: 8, // 丁年 -> 壬寅月
|
|
392
|
+
4: 0, // 戊年 -> 甲寅月
|
|
393
|
+
5: 2, // 己年 -> 丙寅月
|
|
394
|
+
6: 4, // 庚年 -> 戊寅月
|
|
395
|
+
7: 6, // 辛年 -> 庚寅月
|
|
396
|
+
8: 8, // 壬年 -> 壬寅月
|
|
397
|
+
9: 0 // 癸年 -> 甲寅月
|
|
398
|
+
};
|
|
399
|
+
const firstMonthStemIndex = firstMonthStemMap[yearStemIndex];
|
|
400
|
+
const monthStemIndex = (firstMonthStemIndex + monthNum - 1) % 10;
|
|
401
|
+
return { stem: STEMS[monthStemIndex], branch };
|
|
402
|
+
}
|
|
403
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
404
|
+
const { name, arguments: args } = request.params;
|
|
405
|
+
logger.info(`Tool called: ${name}`, args);
|
|
406
|
+
try {
|
|
407
|
+
// === Existing Chart Calculation Handlers ===
|
|
408
|
+
if (name === "bazi_basic") {
|
|
409
|
+
const validated = BaziCalculateSchema.parse(args);
|
|
410
|
+
const result = await baziService.calculate({
|
|
411
|
+
year: validated.year,
|
|
412
|
+
month: validated.month,
|
|
413
|
+
day: validated.day,
|
|
414
|
+
hour: validated.hour,
|
|
415
|
+
minute: validated.minute,
|
|
416
|
+
gender: validated.gender,
|
|
417
|
+
longitude: validated.longitude,
|
|
418
|
+
useLunar: validated.isLunar,
|
|
419
|
+
});
|
|
420
|
+
// If targetYear is specified, calculate LiuNian
|
|
421
|
+
let liuNianInfo = "";
|
|
422
|
+
if (validated.targetYear && result.chart) {
|
|
423
|
+
const liuNians = LiuNianCalculator_1.LiuNianCalculator.calculate(result.chart, validated.year, validated.targetYear, validated.targetYear);
|
|
424
|
+
if (liuNians.length > 0) {
|
|
425
|
+
const liunian = liuNians[0];
|
|
426
|
+
liuNianInfo = `\n\n=== 流年 ${validated.targetYear} ===\n干支:${liunian.stem}${liunian.branch}`;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const options = {
|
|
430
|
+
detail: validated.detail,
|
|
431
|
+
includePersonal: false,
|
|
432
|
+
includeLocation: !!validated.longitude,
|
|
433
|
+
};
|
|
434
|
+
const birthDate = new Date(validated.year, validated.month - 1, validated.day, validated.hour, validated.minute);
|
|
435
|
+
const text = (0, fortuneTextRenderer_1.renderBaziText)({ bazi: result, gender: validated.gender, birthDate }, options);
|
|
436
|
+
return {
|
|
437
|
+
content: [
|
|
438
|
+
{
|
|
439
|
+
type: "text",
|
|
440
|
+
text: text + liuNianInfo,
|
|
441
|
+
},
|
|
442
|
+
],
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
if (name === "ziwei_basic") {
|
|
446
|
+
const validated = ZiweiCalculateSchema.parse(args);
|
|
447
|
+
const result = await ziweiService.calculate({
|
|
448
|
+
year: validated.year,
|
|
449
|
+
month: validated.month,
|
|
450
|
+
day: validated.day,
|
|
451
|
+
hour: validated.hour,
|
|
452
|
+
gender: validated.gender,
|
|
453
|
+
});
|
|
454
|
+
const options = {
|
|
455
|
+
detail: validated.detail,
|
|
456
|
+
includePersonal: false,
|
|
457
|
+
};
|
|
458
|
+
const birthDate = new Date(validated.year, validated.month - 1, validated.day, validated.hour, validated.minute);
|
|
459
|
+
const text = (0, fortuneTextRenderer_1.renderZiweiText)({
|
|
460
|
+
ziwei: result,
|
|
461
|
+
gender: validated.gender,
|
|
462
|
+
birthDate,
|
|
463
|
+
mutagen: result.mutagenInfo // 傳入四化信息
|
|
464
|
+
}, options);
|
|
465
|
+
return {
|
|
466
|
+
content: [
|
|
467
|
+
{
|
|
468
|
+
type: "text",
|
|
469
|
+
text,
|
|
470
|
+
},
|
|
471
|
+
],
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
// === BaZi List Tool Handlers ===
|
|
475
|
+
if (name === "bazi_dayun") {
|
|
476
|
+
const validated = BaziDaYunListSchema.parse(args);
|
|
477
|
+
// Calculate BaZi chart first
|
|
478
|
+
const result = await baziService.calculate({
|
|
479
|
+
year: validated.year,
|
|
480
|
+
month: validated.month,
|
|
481
|
+
day: validated.day,
|
|
482
|
+
hour: validated.hour,
|
|
483
|
+
minute: validated.minute,
|
|
484
|
+
gender: validated.gender,
|
|
485
|
+
longitude: validated.longitude,
|
|
486
|
+
});
|
|
487
|
+
if (!result.chart || !result.birthInfo) {
|
|
488
|
+
throw new Error("Failed to calculate BaZi chart");
|
|
489
|
+
}
|
|
490
|
+
// Calculate DaYun
|
|
491
|
+
const daYunList = DaYunCalculator_1.DaYunCalculator.calculate(result.chart, result.birthInfo, validated.gender, { startYear: validated.year, endYear: validated.year + 100 });
|
|
492
|
+
// Get direction and start info
|
|
493
|
+
const direction = LuckCycleCalculator_1.LuckCycleCalculator.calLuckySequence(validated.gender, result.chart.year.stem) === 'forward' ? '顺行' : '逆行';
|
|
494
|
+
const startAge = daYunList.length > 0 ? daYunList[0].startAge : 1;
|
|
495
|
+
const startYear = validated.year + startAge - 1;
|
|
496
|
+
const options = {
|
|
497
|
+
name: validated.name,
|
|
498
|
+
birthYear: validated.year,
|
|
499
|
+
birthMonth: validated.month,
|
|
500
|
+
birthDay: validated.day,
|
|
501
|
+
birthHour: validated.hour,
|
|
502
|
+
birthMinute: validated.minute,
|
|
503
|
+
gender: validated.gender,
|
|
504
|
+
dayMaster: result.chart.day.stem,
|
|
505
|
+
yearPillar: { stem: result.chart.year.stem, branch: result.chart.year.branch },
|
|
506
|
+
monthPillar: { stem: result.chart.month.stem, branch: result.chart.month.branch },
|
|
507
|
+
dayPillar: { stem: result.chart.day.stem, branch: result.chart.day.branch },
|
|
508
|
+
hourPillar: { stem: result.chart.hour.stem, branch: result.chart.hour.branch },
|
|
509
|
+
direction,
|
|
510
|
+
startAge,
|
|
511
|
+
startYear,
|
|
512
|
+
};
|
|
513
|
+
const text = (0, listTextRenderer_1.renderBaziDaYunList)(daYunList.slice(0, validated.count), options);
|
|
514
|
+
return { content: [{ type: "text", text }] };
|
|
515
|
+
}
|
|
516
|
+
if (name === "bazi_liunian") {
|
|
517
|
+
const validated = BaziLiuNianListSchema.parse(args);
|
|
518
|
+
// Calculate BaZi chart first
|
|
519
|
+
const result = await baziService.calculate({
|
|
520
|
+
year: validated.year,
|
|
521
|
+
month: validated.month,
|
|
522
|
+
day: validated.day,
|
|
523
|
+
hour: validated.hour,
|
|
524
|
+
minute: validated.minute,
|
|
525
|
+
gender: validated.gender,
|
|
526
|
+
longitude: validated.longitude,
|
|
527
|
+
});
|
|
528
|
+
if (!result.chart || !result.birthInfo) {
|
|
529
|
+
throw new Error("Failed to calculate BaZi chart");
|
|
530
|
+
}
|
|
531
|
+
// Calculate DaYun list to match each LiuNian to its DaYun
|
|
532
|
+
const daYunList = DaYunCalculator_1.DaYunCalculator.calculate(result.chart, result.birthInfo, validated.gender, { startYear: validated.year, endYear: validated.year + 100 });
|
|
533
|
+
// Calculate LiuNian for the range
|
|
534
|
+
const liuNianList = LiuNianCalculator_1.LiuNianCalculator.calculate(result.chart, validated.year, validated.startYear, validated.endYear);
|
|
535
|
+
const options = {
|
|
536
|
+
name: validated.name,
|
|
537
|
+
birthYear: validated.year,
|
|
538
|
+
birthMonth: validated.month,
|
|
539
|
+
birthDay: validated.day,
|
|
540
|
+
birthHour: validated.hour,
|
|
541
|
+
birthMinute: validated.minute,
|
|
542
|
+
gender: validated.gender,
|
|
543
|
+
dayMaster: result.chart.day.stem,
|
|
544
|
+
yearPillar: { stem: result.chart.year.stem, branch: result.chart.year.branch },
|
|
545
|
+
monthPillar: { stem: result.chart.month.stem, branch: result.chart.month.branch },
|
|
546
|
+
dayPillar: { stem: result.chart.day.stem, branch: result.chart.day.branch },
|
|
547
|
+
hourPillar: { stem: result.chart.hour.stem, branch: result.chart.hour.branch },
|
|
548
|
+
startYear: validated.startYear,
|
|
549
|
+
endYear: validated.endYear,
|
|
550
|
+
daYunList,
|
|
551
|
+
};
|
|
552
|
+
const text = (0, listTextRenderer_1.renderBaziLiuNianList)(liuNianList, options);
|
|
553
|
+
return { content: [{ type: "text", text }] };
|
|
554
|
+
}
|
|
555
|
+
if (name === "bazi_liuyue") {
|
|
556
|
+
const validated = BaziLiuYueListSchema.parse(args);
|
|
557
|
+
const { year: gregorianYear, ganzhi: ganzhiYear } = parseGanzhiYear(validated.ganzhiYear);
|
|
558
|
+
// Calculate BaZi chart first
|
|
559
|
+
const result = await baziService.calculate({
|
|
560
|
+
year: validated.year,
|
|
561
|
+
month: validated.month,
|
|
562
|
+
day: validated.day,
|
|
563
|
+
hour: validated.hour,
|
|
564
|
+
minute: validated.minute,
|
|
565
|
+
gender: validated.gender,
|
|
566
|
+
longitude: validated.longitude,
|
|
567
|
+
});
|
|
568
|
+
if (!result.chart || !result.birthInfo) {
|
|
569
|
+
throw new Error("Failed to calculate BaZi chart");
|
|
570
|
+
}
|
|
571
|
+
// Get year stem and branch
|
|
572
|
+
const { stem: yearStem, branch: yearBranch } = getYearStemBranch(gregorianYear);
|
|
573
|
+
// Calculate DaYun list to find current DaYun
|
|
574
|
+
const daYunList = DaYunCalculator_1.DaYunCalculator.calculate(result.chart, result.birthInfo, validated.gender, { startYear: validated.year, endYear: validated.year + 100 });
|
|
575
|
+
// Calculate age for the target year (虛歲)
|
|
576
|
+
const targetAge = gregorianYear - validated.year + 1;
|
|
577
|
+
// Find current DaYun
|
|
578
|
+
let currentDaYun;
|
|
579
|
+
const matchedDaYun = daYunList.find(dy => targetAge >= dy.startAge && targetAge <= dy.endAge);
|
|
580
|
+
if (matchedDaYun) {
|
|
581
|
+
currentDaYun = {
|
|
582
|
+
stem: matchedDaYun.stem,
|
|
583
|
+
branch: matchedDaYun.branch,
|
|
584
|
+
startAge: matchedDaYun.startAge,
|
|
585
|
+
endAge: matchedDaYun.endAge,
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
// Calculate current LiuNian
|
|
589
|
+
const liuNianList = LiuNianCalculator_1.LiuNianCalculator.calculate(result.chart, validated.year, gregorianYear, gregorianYear);
|
|
590
|
+
let currentLiuNian;
|
|
591
|
+
if (liuNianList.length > 0) {
|
|
592
|
+
const ln = liuNianList[0];
|
|
593
|
+
currentLiuNian = {
|
|
594
|
+
stem: ln.stem,
|
|
595
|
+
branch: ln.branch,
|
|
596
|
+
age: ln.age,
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
// Calculate LiuYue
|
|
600
|
+
const calculator = new LiuYueCalculator_1.LiuYueCalculator();
|
|
601
|
+
const liuYueList = calculator.calculateLiuYue(yearStem, yearBranch, (result.basic?.dayMasterElement || '木'), (result.traditional?.yongShen?.yongShen || []), {
|
|
602
|
+
year: validated.year,
|
|
603
|
+
month: validated.month,
|
|
604
|
+
day: validated.day,
|
|
605
|
+
hour: validated.hour,
|
|
606
|
+
minute: validated.minute,
|
|
607
|
+
}, gregorianYear);
|
|
608
|
+
const options = {
|
|
609
|
+
name: validated.name,
|
|
610
|
+
birthYear: validated.year,
|
|
611
|
+
birthMonth: validated.month,
|
|
612
|
+
birthDay: validated.day,
|
|
613
|
+
birthHour: validated.hour,
|
|
614
|
+
birthMinute: validated.minute,
|
|
615
|
+
gender: validated.gender,
|
|
616
|
+
dayMaster: result.chart.day.stem,
|
|
617
|
+
yearPillar: { stem: result.chart.year.stem, branch: result.chart.year.branch },
|
|
618
|
+
monthPillar: { stem: result.chart.month.stem, branch: result.chart.month.branch },
|
|
619
|
+
dayPillar: { stem: result.chart.day.stem, branch: result.chart.day.branch },
|
|
620
|
+
hourPillar: { stem: result.chart.hour.stem, branch: result.chart.hour.branch },
|
|
621
|
+
ganzhiYear,
|
|
622
|
+
gregorianYear,
|
|
623
|
+
currentDaYun,
|
|
624
|
+
currentLiuNian,
|
|
625
|
+
};
|
|
626
|
+
const text = (0, listTextRenderer_1.renderBaziLiuYueList)(liuYueList, options);
|
|
627
|
+
return { content: [{ type: "text", text }] };
|
|
628
|
+
}
|
|
629
|
+
if (name === "bazi_liuri") {
|
|
630
|
+
const validated = BaziLiuRiListSchema.parse(args);
|
|
631
|
+
const { year: gregorianYear, ganzhi: ganzhiYear } = parseGanzhiYear(validated.ganzhiYear);
|
|
632
|
+
const monthNum = parseGanzhiMonth(validated.ganzhiMonth);
|
|
633
|
+
// Calculate BaZi chart first
|
|
634
|
+
const result = await baziService.calculate({
|
|
635
|
+
year: validated.year,
|
|
636
|
+
month: validated.month,
|
|
637
|
+
day: validated.day,
|
|
638
|
+
hour: validated.hour,
|
|
639
|
+
minute: validated.minute,
|
|
640
|
+
gender: validated.gender,
|
|
641
|
+
longitude: validated.longitude,
|
|
642
|
+
});
|
|
643
|
+
if (!result.chart || !result.birthInfo) {
|
|
644
|
+
throw new Error("Failed to calculate BaZi chart");
|
|
645
|
+
}
|
|
646
|
+
// Get year and month stem/branch
|
|
647
|
+
const { stem: yearStem, branch: yearBranch } = getYearStemBranch(gregorianYear);
|
|
648
|
+
const { stem: monthStem, branch: monthBranch } = getMonthStemBranch(gregorianYear, monthNum);
|
|
649
|
+
// Calculate DaYun list to find current DaYun
|
|
650
|
+
const daYunList = DaYunCalculator_1.DaYunCalculator.calculate(result.chart, result.birthInfo, validated.gender, { startYear: validated.year, endYear: validated.year + 100 });
|
|
651
|
+
// Calculate age for the target year (虛歲)
|
|
652
|
+
const targetAge = gregorianYear - validated.year + 1;
|
|
653
|
+
// Find current DaYun
|
|
654
|
+
let currentDaYun;
|
|
655
|
+
const matchedDaYun = daYunList.find(dy => targetAge >= dy.startAge && targetAge <= dy.endAge);
|
|
656
|
+
if (matchedDaYun) {
|
|
657
|
+
currentDaYun = {
|
|
658
|
+
stem: matchedDaYun.stem,
|
|
659
|
+
branch: matchedDaYun.branch,
|
|
660
|
+
startAge: matchedDaYun.startAge,
|
|
661
|
+
endAge: matchedDaYun.endAge,
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
// Calculate current LiuNian
|
|
665
|
+
const liuNianList = LiuNianCalculator_1.LiuNianCalculator.calculate(result.chart, validated.year, gregorianYear, gregorianYear);
|
|
666
|
+
let currentLiuNian;
|
|
667
|
+
if (liuNianList.length > 0) {
|
|
668
|
+
const ln = liuNianList[0];
|
|
669
|
+
currentLiuNian = {
|
|
670
|
+
stem: ln.stem,
|
|
671
|
+
branch: ln.branch,
|
|
672
|
+
age: ln.age,
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
// Current LiuYue info
|
|
676
|
+
const currentLiuYue = {
|
|
677
|
+
stem: monthStem,
|
|
678
|
+
branch: monthBranch,
|
|
679
|
+
month: monthNum,
|
|
680
|
+
};
|
|
681
|
+
// Calculate LiuRi
|
|
682
|
+
const calculator = new LiuRiCalculator_1.LiuRiCalculator();
|
|
683
|
+
const liuRiList = calculator.calculateLiuRi(monthStem, monthBranch, yearStem, yearBranch, (result.basic?.dayMasterElement || '木'), (result.traditional?.yongShen?.yongShen || []), gregorianYear, monthNum);
|
|
684
|
+
// Get the first and last date from the calculated list
|
|
685
|
+
const startDate = liuRiList.length > 0 ? liuRiList[0].date : new Date();
|
|
686
|
+
const endDate = liuRiList.length > 0 ? liuRiList[liuRiList.length - 1].date : new Date();
|
|
687
|
+
const options = {
|
|
688
|
+
name: validated.name,
|
|
689
|
+
birthYear: validated.year,
|
|
690
|
+
birthMonth: validated.month,
|
|
691
|
+
birthDay: validated.day,
|
|
692
|
+
birthHour: validated.hour,
|
|
693
|
+
birthMinute: validated.minute,
|
|
694
|
+
gender: validated.gender,
|
|
695
|
+
dayMaster: result.chart.day.stem,
|
|
696
|
+
yearPillar: { stem: result.chart.year.stem, branch: result.chart.year.branch },
|
|
697
|
+
monthPillar: { stem: result.chart.month.stem, branch: result.chart.month.branch },
|
|
698
|
+
dayPillar: { stem: result.chart.day.stem, branch: result.chart.day.branch },
|
|
699
|
+
hourPillar: { stem: result.chart.hour.stem, branch: result.chart.hour.branch },
|
|
700
|
+
ganzhiMonth: monthStem + monthBranch,
|
|
701
|
+
ganzhiYear,
|
|
702
|
+
gregorianYear,
|
|
703
|
+
startDate,
|
|
704
|
+
endDate,
|
|
705
|
+
currentDaYun,
|
|
706
|
+
currentLiuNian,
|
|
707
|
+
currentLiuYue,
|
|
708
|
+
};
|
|
709
|
+
const text = (0, listTextRenderer_1.renderBaziLiuRiList)(liuRiList, options);
|
|
710
|
+
return { content: [{ type: "text", text }] };
|
|
711
|
+
}
|
|
712
|
+
// === ZiWei List Tool Handlers ===
|
|
713
|
+
if (name === "ziwei_daxian") {
|
|
714
|
+
const validated = ZiweiDaXianListSchema.parse(args);
|
|
715
|
+
// Calculate ZiWei chart
|
|
716
|
+
const result = ziweiService.calculate({
|
|
717
|
+
year: validated.year,
|
|
718
|
+
month: validated.month,
|
|
719
|
+
day: validated.day,
|
|
720
|
+
hour: validated.hour,
|
|
721
|
+
gender: validated.gender,
|
|
722
|
+
});
|
|
723
|
+
if (!result.decades || result.decades.length === 0) {
|
|
724
|
+
throw new Error("Failed to calculate ZiWei decades");
|
|
725
|
+
}
|
|
726
|
+
// Determine direction
|
|
727
|
+
const yangStems = ['甲', '丙', '戊', '庚', '壬'];
|
|
728
|
+
const yearStem = result.basicInfo?.fourPillars?.year?.stem || '';
|
|
729
|
+
const isYang = yangStems.includes(yearStem);
|
|
730
|
+
const isMale = validated.gender === 'male';
|
|
731
|
+
const direction = ((isYang && isMale) || (!isYang && !isMale)) ? '顺行' : '逆行';
|
|
732
|
+
// Find Ming Gong stars
|
|
733
|
+
const mingGongPalace = result.palaces?.find(p => p.name === '命宮' || p.name === '命宫' || p.name === 'Life');
|
|
734
|
+
const mingGongStars = mingGongPalace?.majorStars?.map(s => typeof s === 'string' ? s : s.name) || [];
|
|
735
|
+
// Find Shen Gong
|
|
736
|
+
const shenGongPalace = result.palaces?.find(p => p.isBodyPalace);
|
|
737
|
+
const shenGongStars = shenGongPalace?.majorStars?.map(s => typeof s === 'string' ? s : s.name) || [];
|
|
738
|
+
const options = {
|
|
739
|
+
name: validated.name,
|
|
740
|
+
birthYear: validated.year,
|
|
741
|
+
birthMonth: validated.month,
|
|
742
|
+
birthDay: validated.day,
|
|
743
|
+
birthHour: validated.hour,
|
|
744
|
+
birthMinute: validated.minute,
|
|
745
|
+
gender: validated.gender,
|
|
746
|
+
mingGong: mingGongPalace?.name || '命宮',
|
|
747
|
+
mingGongStars,
|
|
748
|
+
shenGong: shenGongPalace?.name,
|
|
749
|
+
shenGongStars,
|
|
750
|
+
palaces: result.palaces, // 传入完整宫位数据
|
|
751
|
+
mutagenInfo: result.mutagenInfo, // 传入四化信息
|
|
752
|
+
direction,
|
|
753
|
+
};
|
|
754
|
+
const text = (0, listTextRenderer_1.renderZiweiDaXianList)(result.decades.slice(0, validated.count), options);
|
|
755
|
+
return { content: [{ type: "text", text }] };
|
|
756
|
+
}
|
|
757
|
+
if (name === "ziwei_xiaoxian") {
|
|
758
|
+
const validated = ZiweiXiaoXianListSchema.parse(args);
|
|
759
|
+
const result = ziweiService.calculate({
|
|
760
|
+
year: validated.year,
|
|
761
|
+
month: validated.month,
|
|
762
|
+
day: validated.day,
|
|
763
|
+
hour: validated.hour,
|
|
764
|
+
gender: validated.gender,
|
|
765
|
+
});
|
|
766
|
+
if (!result.palaces) {
|
|
767
|
+
throw new Error("Failed to calculate ZiWei chart");
|
|
768
|
+
}
|
|
769
|
+
const minorLimitList = ziweiService.getMinorLimitRange(validated.year, validated.startAge, validated.endAge);
|
|
770
|
+
const mingGongPalace = result.palaces?.find(p => p.name === '命宮' || p.name === '命宫' || p.name === 'Life');
|
|
771
|
+
const mingGongStars = mingGongPalace?.majorStars?.map(s => typeof s === 'string' ? s : s.name) || [];
|
|
772
|
+
const currentYear = new Date().getFullYear();
|
|
773
|
+
const currentAge = currentYear - validated.year + 1;
|
|
774
|
+
let currentDecade;
|
|
775
|
+
if (result.decades && result.decades.length > 0) {
|
|
776
|
+
const matchedDecade = result.decades.find(d => currentAge >= d.startAge && currentAge <= d.endAge);
|
|
777
|
+
if (matchedDecade) {
|
|
778
|
+
currentDecade = {
|
|
779
|
+
palaceName: matchedDecade.palaceName || result.palaces?.[matchedDecade.palaceIndex]?.name || '未知',
|
|
780
|
+
startAge: matchedDecade.startAge,
|
|
781
|
+
endAge: matchedDecade.endAge,
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
const options = {
|
|
786
|
+
name: validated.name,
|
|
787
|
+
birthYear: validated.year,
|
|
788
|
+
birthMonth: validated.month,
|
|
789
|
+
birthDay: validated.day,
|
|
790
|
+
birthHour: validated.hour,
|
|
791
|
+
birthMinute: validated.minute,
|
|
792
|
+
gender: validated.gender,
|
|
793
|
+
mingGong: mingGongPalace?.name || '命宮',
|
|
794
|
+
mingGongStars,
|
|
795
|
+
palaces: result.palaces,
|
|
796
|
+
mutagenInfo: result.mutagenInfo,
|
|
797
|
+
startAge: validated.startAge,
|
|
798
|
+
endAge: validated.endAge,
|
|
799
|
+
currentDecade,
|
|
800
|
+
decades: result.decades,
|
|
801
|
+
};
|
|
802
|
+
const text = (0, listTextRenderer_1.renderZiweiXiaoXianList)(minorLimitList, options);
|
|
803
|
+
return { content: [{ type: "text", text }] };
|
|
804
|
+
}
|
|
805
|
+
if (name === "ziwei_liunian") {
|
|
806
|
+
const validated = ZiweiLiuNianListSchema.parse(args);
|
|
807
|
+
// Calculate ZiWei chart
|
|
808
|
+
const result = ziweiService.calculate({
|
|
809
|
+
year: validated.year,
|
|
810
|
+
month: validated.month,
|
|
811
|
+
day: validated.day,
|
|
812
|
+
hour: validated.hour,
|
|
813
|
+
gender: validated.gender,
|
|
814
|
+
});
|
|
815
|
+
if (!result.palaces) {
|
|
816
|
+
throw new Error("Failed to calculate ZiWei chart");
|
|
817
|
+
}
|
|
818
|
+
// Calculate yearly info for each year in the range
|
|
819
|
+
const yearlyList = [];
|
|
820
|
+
for (let year = validated.startYear; year <= validated.endYear; year++) {
|
|
821
|
+
const yearly = YearlyCalculator_1.YearlyCalculator.calculate(year, validated.year, result.palaces);
|
|
822
|
+
if (yearly) {
|
|
823
|
+
yearlyList.push(yearly);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
// Find Ming Gong
|
|
827
|
+
const mingGongPalace = result.palaces?.find(p => p.name === '命宮' || p.name === '命宫' || p.name === 'Life');
|
|
828
|
+
const mingGongStars = mingGongPalace?.majorStars?.map(s => typeof s === 'string' ? s : s.name) || [];
|
|
829
|
+
const options = {
|
|
830
|
+
name: validated.name,
|
|
831
|
+
birthYear: validated.year,
|
|
832
|
+
birthMonth: validated.month,
|
|
833
|
+
birthDay: validated.day,
|
|
834
|
+
birthHour: validated.hour,
|
|
835
|
+
birthMinute: validated.minute,
|
|
836
|
+
gender: validated.gender,
|
|
837
|
+
mingGong: mingGongPalace?.name || '命宮',
|
|
838
|
+
mingGongStars,
|
|
839
|
+
palaces: result.palaces, // 传入完整宫位数据
|
|
840
|
+
mutagenInfo: result.mutagenInfo, // 传入四化信息
|
|
841
|
+
startYear: validated.startYear,
|
|
842
|
+
endYear: validated.endYear,
|
|
843
|
+
decades: result.decades, // 传入大限列表用于匹配所属大限
|
|
844
|
+
};
|
|
845
|
+
const text = (0, listTextRenderer_1.renderZiweiLiuNianList)(yearlyList, options);
|
|
846
|
+
return { content: [{ type: "text", text }] };
|
|
847
|
+
}
|
|
848
|
+
if (name === "ziwei_liuyue") {
|
|
849
|
+
const validated = ZiweiLiuYueListSchema.parse(args);
|
|
850
|
+
// Calculate ZiWei chart
|
|
851
|
+
const result = ziweiService.calculate({
|
|
852
|
+
year: validated.year,
|
|
853
|
+
month: validated.month,
|
|
854
|
+
day: validated.day,
|
|
855
|
+
hour: validated.hour,
|
|
856
|
+
gender: validated.gender,
|
|
857
|
+
});
|
|
858
|
+
// Get yearly months (农历月)
|
|
859
|
+
const monthlyList = ziweiService.getYearlyMonths(validated.lunarYear);
|
|
860
|
+
// Find Ming Gong
|
|
861
|
+
const mingGongPalace = result.palaces?.find(p => p.name === '命宮' || p.name === '命宫' || p.name === 'Life');
|
|
862
|
+
const mingGongStars = mingGongPalace?.majorStars?.map(s => typeof s === 'string' ? s : s.name) || [];
|
|
863
|
+
// Check for leap month in this lunar year
|
|
864
|
+
const lunar = lunar_javascript_1.Lunar.fromYmd(validated.lunarYear, 1, 1);
|
|
865
|
+
const leapMonth = lunar.getYear() === validated.lunarYear ?
|
|
866
|
+
lunar_javascript_1.Lunar.fromYmd(validated.lunarYear, 6, 1).getLeapMonth?.() : undefined;
|
|
867
|
+
// Calculate age for the target year (虛歲)
|
|
868
|
+
const targetAge = validated.lunarYear - validated.year + 1;
|
|
869
|
+
// Find current decade (大限)
|
|
870
|
+
let currentDecade;
|
|
871
|
+
if (result.decades && result.decades.length > 0) {
|
|
872
|
+
const matchedDecade = result.decades.find(d => targetAge >= d.startAge && targetAge <= d.endAge);
|
|
873
|
+
if (matchedDecade) {
|
|
874
|
+
currentDecade = {
|
|
875
|
+
palaceName: matchedDecade.palaceName || result.palaces?.[matchedDecade.palaceIndex]?.name || '未知',
|
|
876
|
+
startAge: matchedDecade.startAge,
|
|
877
|
+
endAge: matchedDecade.endAge,
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
// Calculate current yearly (流年)
|
|
882
|
+
const yearlyInfo = YearlyCalculator_1.YearlyCalculator.calculate(validated.lunarYear, validated.year, result.palaces);
|
|
883
|
+
let currentYearly;
|
|
884
|
+
if (yearlyInfo) {
|
|
885
|
+
const { stem: yearStem, branch: yearBranch } = getYearStemBranch(validated.lunarYear);
|
|
886
|
+
currentYearly = {
|
|
887
|
+
year: validated.lunarYear,
|
|
888
|
+
age: targetAge,
|
|
889
|
+
palaceName: result.palaces?.[yearlyInfo.palaceIndex]?.name || '未知',
|
|
890
|
+
heavenlyStem: yearStem,
|
|
891
|
+
earthlyBranch: yearBranch,
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
// Calculate current minor limit (小限)
|
|
895
|
+
const minorLimitInfo = ziweiService.getMinorLimitInfo(validated.year, validated.lunarYear);
|
|
896
|
+
let currentMinorLimit;
|
|
897
|
+
if (minorLimitInfo) {
|
|
898
|
+
currentMinorLimit = {
|
|
899
|
+
age: minorLimitInfo.age,
|
|
900
|
+
palaceName: result.palaces?.[minorLimitInfo.palaceIndex]?.name || '未知',
|
|
901
|
+
heavenlyStem: minorLimitInfo.heavenlyStem,
|
|
902
|
+
earthlyBranch: minorLimitInfo.earthlyBranch,
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
// 添加小限四化到 mutagenInfo
|
|
906
|
+
const enhancedMutagenInfo = { ...result.mutagenInfo };
|
|
907
|
+
if (minorLimitInfo?.heavenlyStem) {
|
|
908
|
+
enhancedMutagenInfo.minorLimit = MutagenCore_1.MutagenCore.getMutagen(minorLimitInfo.heavenlyStem) || undefined;
|
|
909
|
+
}
|
|
910
|
+
const options = {
|
|
911
|
+
name: validated.name,
|
|
912
|
+
birthYear: validated.year,
|
|
913
|
+
birthMonth: validated.month,
|
|
914
|
+
birthDay: validated.day,
|
|
915
|
+
birthHour: validated.hour,
|
|
916
|
+
birthMinute: validated.minute,
|
|
917
|
+
gender: validated.gender,
|
|
918
|
+
mingGong: mingGongPalace?.name || '命宮',
|
|
919
|
+
mingGongStars,
|
|
920
|
+
palaces: result.palaces,
|
|
921
|
+
mutagenInfo: enhancedMutagenInfo,
|
|
922
|
+
lunarYear: validated.lunarYear,
|
|
923
|
+
gregorianYear: validated.lunarYear,
|
|
924
|
+
leapMonth: typeof leapMonth === 'number' ? leapMonth : undefined,
|
|
925
|
+
currentDecade,
|
|
926
|
+
currentMinorLimit,
|
|
927
|
+
currentYearly,
|
|
928
|
+
};
|
|
929
|
+
const text = (0, listTextRenderer_1.renderZiweiLiuYueList)(monthlyList, options);
|
|
930
|
+
return { content: [{ type: "text", text }] };
|
|
931
|
+
}
|
|
932
|
+
if (name === "ziwei_liuri") {
|
|
933
|
+
const validated = ZiweiLiuRiListSchema.parse(args);
|
|
934
|
+
// Calculate ZiWei chart
|
|
935
|
+
const result = ziweiService.calculate({
|
|
936
|
+
year: validated.year,
|
|
937
|
+
month: validated.month,
|
|
938
|
+
day: validated.day,
|
|
939
|
+
hour: validated.hour,
|
|
940
|
+
gender: validated.gender,
|
|
941
|
+
});
|
|
942
|
+
// Handle leap month (negative number)
|
|
943
|
+
const isLeapMonth = validated.lunarMonth < 0;
|
|
944
|
+
const actualMonth = Math.abs(validated.lunarMonth);
|
|
945
|
+
// Get lunar month boundaries
|
|
946
|
+
const monthParam = isLeapMonth ? -actualMonth : actualMonth;
|
|
947
|
+
const lunarFirstDay = lunar_javascript_1.Lunar.fromYmd(validated.lunarYear, monthParam, 1);
|
|
948
|
+
// Find last day of the month
|
|
949
|
+
let lastDayNum = 29;
|
|
950
|
+
try {
|
|
951
|
+
lunar_javascript_1.Lunar.fromYmd(validated.lunarYear, monthParam, 30);
|
|
952
|
+
lastDayNum = 30;
|
|
953
|
+
}
|
|
954
|
+
catch {
|
|
955
|
+
// Month only has 29 days
|
|
956
|
+
}
|
|
957
|
+
const lunarLastDay = lunar_javascript_1.Lunar.fromYmd(validated.lunarYear, monthParam, lastDayNum);
|
|
958
|
+
// Convert to solar dates
|
|
959
|
+
const firstSolar = lunarFirstDay.getSolar();
|
|
960
|
+
const lastSolar = lunarLastDay.getSolar();
|
|
961
|
+
const startDate = new Date(firstSolar.getYear(), firstSolar.getMonth() - 1, firstSolar.getDay());
|
|
962
|
+
const endDate = new Date(lastSolar.getYear(), lastSolar.getMonth() - 1, lastSolar.getDay());
|
|
963
|
+
// Build daily list
|
|
964
|
+
const dailyList = [];
|
|
965
|
+
for (let day = 1; day <= lastDayNum; day++) {
|
|
966
|
+
try {
|
|
967
|
+
const lunarDay = lunar_javascript_1.Lunar.fromYmd(validated.lunarYear, monthParam, day);
|
|
968
|
+
const solarDay = lunarDay.getSolar();
|
|
969
|
+
const solarDate = new Date(solarDay.getYear(), solarDay.getMonth() - 1, solarDay.getDay());
|
|
970
|
+
// Get daily info from calculator
|
|
971
|
+
const dailyInfo = ziweiService.getDailyInfo(solarDay.getYear(), solarDay.getMonth(), solarDay.getDay());
|
|
972
|
+
dailyList.push({
|
|
973
|
+
lunarMonth: actualMonth,
|
|
974
|
+
lunarDay: day,
|
|
975
|
+
isLeapMonth,
|
|
976
|
+
gregorianDate: solarDate,
|
|
977
|
+
ganzhi: dailyInfo ? `${dailyInfo.heavenlyStem}${dailyInfo.earthlyBranch}` : '',
|
|
978
|
+
palaceIndex: dailyInfo?.palaceIndex || 0,
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
catch (e) {
|
|
982
|
+
// Skip invalid dates
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
// Find Ming Gong
|
|
986
|
+
const mingGongPalace = result.palaces?.find(p => p.name === '命宮' || p.name === '命宫' || p.name === 'Life');
|
|
987
|
+
const mingGongStars = mingGongPalace?.majorStars?.map(s => typeof s === 'string' ? s : s.name) || [];
|
|
988
|
+
// Get monthly palace
|
|
989
|
+
const monthlyInfo = ziweiService.getMonthlyInfo(validated.lunarYear, actualMonth - 1, actualMonth, isLeapMonth);
|
|
990
|
+
const monthlyPalace = monthlyInfo ? result.palaces?.[monthlyInfo.palaceIndex]?.name : undefined;
|
|
991
|
+
// Calculate age for the target year (虛歲)
|
|
992
|
+
const targetAge = validated.lunarYear - validated.year + 1;
|
|
993
|
+
// Find current decade (大限)
|
|
994
|
+
let currentDecade;
|
|
995
|
+
if (result.decades && result.decades.length > 0) {
|
|
996
|
+
const matchedDecade = result.decades.find(d => targetAge >= d.startAge && targetAge <= d.endAge);
|
|
997
|
+
if (matchedDecade) {
|
|
998
|
+
currentDecade = {
|
|
999
|
+
palaceName: matchedDecade.palaceName || result.palaces?.[matchedDecade.palaceIndex]?.name || '未知',
|
|
1000
|
+
startAge: matchedDecade.startAge,
|
|
1001
|
+
endAge: matchedDecade.endAge,
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
// Calculate current yearly (流年)
|
|
1006
|
+
const yearlyInfo = YearlyCalculator_1.YearlyCalculator.calculate(validated.lunarYear, validated.year, result.palaces);
|
|
1007
|
+
let currentYearly;
|
|
1008
|
+
if (yearlyInfo) {
|
|
1009
|
+
const { stem: yearStem, branch: yearBranch } = getYearStemBranch(validated.lunarYear);
|
|
1010
|
+
currentYearly = {
|
|
1011
|
+
year: validated.lunarYear,
|
|
1012
|
+
age: targetAge,
|
|
1013
|
+
palaceName: result.palaces?.[yearlyInfo.palaceIndex]?.name || '未知',
|
|
1014
|
+
heavenlyStem: yearStem,
|
|
1015
|
+
earthlyBranch: yearBranch,
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
// Current monthly info (流月)
|
|
1019
|
+
let currentMonthly;
|
|
1020
|
+
if (monthlyInfo) {
|
|
1021
|
+
currentMonthly = {
|
|
1022
|
+
month: actualMonth,
|
|
1023
|
+
palaceName: result.palaces?.[monthlyInfo.palaceIndex]?.name || '未知',
|
|
1024
|
+
heavenlyStem: monthlyInfo.heavenlyStem,
|
|
1025
|
+
earthlyBranch: monthlyInfo.earthlyBranch,
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
// Calculate current minor limit (小限)
|
|
1029
|
+
const minorLimitInfo = ziweiService.getMinorLimitInfo(validated.year, validated.lunarYear);
|
|
1030
|
+
let currentMinorLimit;
|
|
1031
|
+
if (minorLimitInfo) {
|
|
1032
|
+
currentMinorLimit = {
|
|
1033
|
+
age: minorLimitInfo.age,
|
|
1034
|
+
palaceName: result.palaces?.[minorLimitInfo.palaceIndex]?.name || '未知',
|
|
1035
|
+
heavenlyStem: minorLimitInfo.heavenlyStem,
|
|
1036
|
+
earthlyBranch: minorLimitInfo.earthlyBranch,
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
// 计算小限四化和流月四化
|
|
1040
|
+
const enhancedMutagenInfo = { ...result.mutagenInfo };
|
|
1041
|
+
if (minorLimitInfo?.heavenlyStem) {
|
|
1042
|
+
enhancedMutagenInfo.minorLimit = MutagenCore_1.MutagenCore.getMutagen(minorLimitInfo.heavenlyStem) || undefined;
|
|
1043
|
+
}
|
|
1044
|
+
if (monthlyInfo?.heavenlyStem) {
|
|
1045
|
+
enhancedMutagenInfo.monthly = MutagenCore_1.MutagenCore.getMutagen(monthlyInfo.heavenlyStem) || undefined;
|
|
1046
|
+
}
|
|
1047
|
+
const options = {
|
|
1048
|
+
name: validated.name,
|
|
1049
|
+
birthYear: validated.year,
|
|
1050
|
+
birthMonth: validated.month,
|
|
1051
|
+
birthDay: validated.day,
|
|
1052
|
+
birthHour: validated.hour,
|
|
1053
|
+
birthMinute: validated.minute,
|
|
1054
|
+
gender: validated.gender,
|
|
1055
|
+
mingGong: mingGongPalace?.name || '命宮',
|
|
1056
|
+
mingGongStars,
|
|
1057
|
+
palaces: result.palaces,
|
|
1058
|
+
mutagenInfo: enhancedMutagenInfo,
|
|
1059
|
+
lunarYear: validated.lunarYear,
|
|
1060
|
+
lunarMonth: actualMonth,
|
|
1061
|
+
isLeapMonth,
|
|
1062
|
+
gregorianStartDate: startDate,
|
|
1063
|
+
gregorianEndDate: endDate,
|
|
1064
|
+
monthlyPalace,
|
|
1065
|
+
currentDecade,
|
|
1066
|
+
currentMinorLimit,
|
|
1067
|
+
currentYearly,
|
|
1068
|
+
currentMonthly,
|
|
1069
|
+
};
|
|
1070
|
+
const text = (0, listTextRenderer_1.renderZiweiLiuRiList)(dailyList, options);
|
|
1071
|
+
return { content: [{ type: "text", text }] };
|
|
1072
|
+
}
|
|
1073
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
1074
|
+
}
|
|
1075
|
+
catch (error) {
|
|
1076
|
+
logger.error(`Tool ${name} failed`, error);
|
|
1077
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1078
|
+
return {
|
|
1079
|
+
content: [
|
|
1080
|
+
{
|
|
1081
|
+
type: "text",
|
|
1082
|
+
text: `Error: ${errorMessage}`,
|
|
1083
|
+
},
|
|
1084
|
+
],
|
|
1085
|
+
isError: true,
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
});
|
|
1089
|
+
// ============================================
|
|
1090
|
+
// Start Server
|
|
1091
|
+
// ============================================
|
|
1092
|
+
async function main() {
|
|
1093
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
1094
|
+
await server.connect(transport);
|
|
1095
|
+
logger.info("Mingpan MCP server started (v0.1.1)");
|
|
1096
|
+
}
|
|
1097
|
+
main().catch((error) => {
|
|
1098
|
+
logger.error("Server failed to start", error);
|
|
1099
|
+
process.exit(1);
|
|
1100
|
+
});
|
|
1101
|
+
//# sourceMappingURL=index.js.map
|