ziwei-cli 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # 紫微斗数 Ziwei Skill
2
+
3
+ 基于传统紫微斗数命理学的命盘分析与运势预测,支持 Claude Code 和 OpenClaw。
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npx ziwei-cli
9
+ ```
10
+
11
+ 这会:
12
+ 1. 检测你的 Claude Code / OpenClaw 安装
13
+ 2. 安装 skill 到正确位置
14
+ 3. 全局安装 `ziwei` CLI
15
+
16
+ ## 手动安装
17
+
18
+ ```bash
19
+ # Clone
20
+ git clone https://github.com/shanrichard/ziwei-skill ~/.claude/skills/ziwei
21
+ cd ~/.claude/skills/ziwei
22
+
23
+ # 安装依赖
24
+ npm install
25
+
26
+ # 全局安装 CLI
27
+ npm link
28
+ ```
29
+
30
+ ## CLI 使用
31
+
32
+ ```bash
33
+ # 本命层 - 查看命宫三方四正
34
+ ziwei palace --date 1990-05-15 --time 10:30 --gender 男 --city 北京 --palace 命宫
35
+
36
+ # 流年层 - 查看官禄宫流年运势
37
+ ziwei palace --palace 官禄宫 --scope yearly --year 2025 --date 1990-05-15 --time 10:30 --gender 男 --city 北京
38
+
39
+ # 流月层
40
+ ziwei palace --palace 财帛宫 --scope monthly --year 2025 --month 6 ...
41
+
42
+ # 本命合盘
43
+ ziwei synastry origin \
44
+ --a-date 1990-05-15 --a-time 10:30 --a-gender 男 --a-city 北京 \
45
+ --b-date 1992-03-20 --b-time 14:00 --b-gender 女 --b-city 上海
46
+ ```
47
+
48
+ ## Skill 使用
49
+
50
+ 安装后重启 Claude Code / OpenClaw,然后直接说:
51
+
52
+ - "帮我算命"
53
+ - "看看我今年的运势"
54
+ - "我和对方合适吗"
55
+
56
+ ## 支持的功能
57
+
58
+ ### 宫位查询 (`palace`)
59
+ - 本命层 (`origin`) - 默认
60
+ - 大限层 (`decadal`) - 需指定 `--year`
61
+ - 流年层 (`yearly`) - 需指定 `--year`
62
+ - 流月层 (`monthly`) - 需指定 `--year --month`
63
+ - 流日层 (`daily`) - 需指定 `--year --month --day`
64
+
65
+ ### 合盘分析 (`synastry`)
66
+ - 本命合盘 (`origin`)
67
+ - 流年合盘 (`yearly`)
68
+
69
+ ## 宫位与议题对应
70
+
71
+ | 议题 | 目标宫 |
72
+ |------|--------|
73
+ | 性格/整体运势 | 命宫 |
74
+ | 事业/升职 | 官禄宫 |
75
+ | 婚恋/感情 | 夫妻宫 |
76
+ | 财运/理财 | 财帛宫 |
77
+ | 健康 | 疾厄宫 |
78
+ | 房产/家庭 | 田宅宫 |
79
+ | 出行/移民 | 迁移宫 |
80
+ | 子女/创作 | 子女宫 |
81
+ | 朋友/同事 | 仆役宫 |
82
+ | 兄弟/合伙 | 兄弟宫 |
83
+ | 学业/考试 | 父母宫 |
84
+ | 心态/福报 | 福德宫 |
85
+
86
+ ## 技术栈
87
+
88
+ - [iztro](https://github.com/SylarLong/iztro) - 紫微斗数排盘库
89
+ - [lunar-javascript](https://github.com/6tail/lunar-javascript) - 农历转换
90
+ - [commander](https://github.com/tj/commander.js) - CLI 框架
91
+
92
+ ## License
93
+
94
+ MIT
package/SKILL.md ADDED
@@ -0,0 +1,142 @@
1
+ ---
2
+ name: ziwei
3
+ description: 紫微斗数 + 八字命理智能算命 - 基于传统命理学的命盘分析与运势预测
4
+ triggers:
5
+ - 算命
6
+ - 看命
7
+ - 命盘
8
+ - 运势
9
+ - 合盘
10
+ - 紫微
11
+ - 斗数
12
+ - 八字
13
+ - 四柱
14
+ - 流年
15
+ - 大限
16
+ - 黄历
17
+ - 十神
18
+ - 大运
19
+ ---
20
+
21
+ # 紫微斗数 + 八字命理智能算命
22
+
23
+ 基于传统命理学双体系(紫微斗数 + 八字命理),提供命盘分析、运势预测、合盘匹配等服务。两套体系可独立使用,也可交叉验证。
24
+
25
+ ## 使用方法
26
+
27
+ ### 1. 收集生辰信息
28
+
29
+ 需要以下信息:
30
+ - 出生日期(阳历或农历)
31
+ - 出生时间(尽量精确到分钟)
32
+ - 性别
33
+ - 出生地城市
34
+
35
+ ### 2. 调用 ziwei CLI
36
+
37
+ 根据用户问题映射到对应宫位,查询三方四正:
38
+
39
+ ```bash
40
+ # 本命层(默认)
41
+ ziwei palace --date 1990-05-15 --time 14:30 --gender 男 --city 北京 --palace 命宫
42
+
43
+ # 大限层
44
+ ziwei palace --palace 官禄宫 --scope decadal --year 2025 ...
45
+
46
+ # 流年层
47
+ ziwei palace --palace 财帛宫 --scope yearly --year 2025 ...
48
+
49
+ # 流月层
50
+ ziwei palace --palace 夫妻宫 --scope monthly --year 2025 --month 6 ...
51
+
52
+ # 流日层
53
+ ziwei palace --palace 疾厄宫 --scope daily --year 2025 --month 6 --day 15 ...
54
+
55
+ # 本命合盘
56
+ ziwei synastry origin \
57
+ --a-date 1990-05-15 --a-time 10:30 --a-gender 男 --a-city 北京 \
58
+ --b-date 1992-03-20 --b-time 14:00 --b-gender 女 --b-city 上海
59
+
60
+ # 流年合盘
61
+ ziwei synastry yearly --year 2025 ...
62
+
63
+ # 八字排盘
64
+ ziwei bazi --date 1990-05-15 --time 14:30 --gender 男
65
+
66
+ # 八字排盘(农历)
67
+ ziwei bazi --date 1990-04-21 --time 14:30 --gender 男 --lunar
68
+
69
+ # 黄历查询(指定日期)
70
+ ziwei calendar --date 2026-02-12
71
+
72
+ # 黄历查询(今天)
73
+ ziwei calendar
74
+ ```
75
+
76
+ ### 3. 解读结果
77
+
78
+ 根据 CLI 返回的 JSON 数据,按照紫微斗数口径进行解读:
79
+
80
+ 1. **命宫定底**:先查命宫三方四正,确定总体格局基调
81
+ 2. **目标宫分析**:根据用户问题映射到相应宫位查询
82
+ 3. **动态叠加**:需要时查询运限层级,结合四化进行修正
83
+ 4. **好坏并论**:既指出优势潜力,也点出风险隐患
84
+ 5. **八字辅助**:需要时调用 `ziwei bazi` 进行交叉验证(十神、大运、五行平衡)
85
+
86
+ ## 参数说明
87
+
88
+ ### 通用参数
89
+ - `--date`:出生日期,格式 YYYY-MM-DD
90
+ - `--time`:出生时间,格式 HH:MM
91
+ - `--gender`:性别,男 或 女
92
+ - `--city`:出生城市名称
93
+ - `--palace`:宫位名称(命宫、财帛宫、官禄宫等)
94
+ - `--lunar`:使用农历日期(可选)
95
+ - `--leap`:农历闰月(可选)
96
+
97
+ ### 层级参数(紫微斗数)
98
+ - `--scope`:查询层级,可选值:
99
+ - `origin`(默认):本命层
100
+ - `decadal`:大限层
101
+ - `yearly`:流年层
102
+ - `monthly`:流月层
103
+ - `daily`:流日层
104
+ - `--year`:查询年份(运限层级必需)
105
+ - `--month`:查询月份(流月/流日必需)
106
+ - `--day`:查询日期(流日必需)
107
+
108
+ ### 八字参数
109
+ - `--sect`:早晚子时配置(1=23:00后算次日,2=算当日,默认2)
110
+
111
+ ## 宫位与议题对应
112
+
113
+ | 议题 | 目标宫 |
114
+ |------|--------|
115
+ | 性格/整体运势 | 命宫 |
116
+ | 事业/升职 | 官禄宫 |
117
+ | 婚恋/感情 | 夫妻宫 |
118
+ | 财运/理财 | 财帛宫 |
119
+ | 健康 | 疾厄宫 |
120
+ | 房产/家庭 | 田宅宫 |
121
+ | 出行/移民 | 迁移宫 |
122
+ | 子女/创作 | 子女宫 |
123
+ | 朋友/同事 | 仆役宫 |
124
+ | 兄弟/合伙 | 兄弟宫 |
125
+ | 学业/考试 | 父母宫 |
126
+ | 心态/福报 | 福德宫 |
127
+
128
+ ## 八字与紫微的使用场景
129
+
130
+ | 场景 | 推荐工具 | 说明 |
131
+ |------|----------|------|
132
+ | 整体看命/性格分析 | 紫微 + 八字 | 两套交叉验证最准 |
133
+ | 某领域运势(事业/财运等) | 紫微为主 | 宫位体系擅长分领域分析 |
134
+ | 五行平衡/先天禀赋 | 八字为主 | 干支五行体系更直观 |
135
+ | 大运走势/人生阶段 | 八字为主 | 八字大运体系更清晰 |
136
+ | 流年/流月细节 | 紫微为主 | 紫微流盘数据更丰富 |
137
+ | 合盘/配对 | 紫微为主 | 有量化评分系统 |
138
+ | 今日黄历/择日 | calendar | 快速查询 |
139
+
140
+ ## 详细口径
141
+
142
+ 见 [system-prompt.md](./system-prompt.md)
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Ziwei Skill Installer for Claude Code / OpenClaw
5
+ *
6
+ * npx ziwei-cli
7
+ */
8
+
9
+ const fs = require("fs");
10
+ const path = require("path");
11
+ const readline = require("readline");
12
+ const { execSync } = require("child_process");
13
+ const os = require("os");
14
+
15
+ // Colors
16
+ const c = {
17
+ reset: "\x1b[0m",
18
+ bright: "\x1b[1m",
19
+ dim: "\x1b[2m",
20
+ red: "\x1b[31m",
21
+ green: "\x1b[32m",
22
+ yellow: "\x1b[33m",
23
+ blue: "\x1b[34m",
24
+ magenta: "\x1b[35m",
25
+ cyan: "\x1b[36m",
26
+ };
27
+
28
+ const color = (col, text) => `${c[col]}${text}${c.reset}`;
29
+
30
+ // Paths
31
+ const HOME = os.homedir();
32
+ const CLAUDE_SKILLS_DIR = path.join(HOME, ".claude", "skills");
33
+ const OPENCLAW_SKILLS_DIR = path.join(HOME, ".openclaw", "skills");
34
+ const SKILL_NAME = "ziwei";
35
+ const PACKAGE_ROOT = path.resolve(__dirname, "..");
36
+
37
+ function log(msg) { console.log(msg); }
38
+ function logStep(step, msg) { console.log(`\n${color("cyan", `[${step}]`)} ${msg}`); }
39
+ function logSuccess(msg) { console.log(`${color("green", "✓")} ${msg}`); }
40
+ function logError(msg) { console.log(`${color("red", "✗")} ${msg}`); }
41
+ function logInfo(msg) { console.log(`${color("blue", "→")} ${msg}`); }
42
+ function logWarn(msg) { console.log(`${color("yellow", "!")} ${msg}`); }
43
+
44
+ function createPrompt() {
45
+ return readline.createInterface({
46
+ input: process.stdin,
47
+ output: process.stdout,
48
+ });
49
+ }
50
+
51
+ function ask(rl, question) {
52
+ return new Promise((resolve) => {
53
+ rl.question(question, (answer) => resolve(answer.trim()));
54
+ });
55
+ }
56
+
57
+ function copyDir(src, dest) {
58
+ fs.mkdirSync(dest, { recursive: true });
59
+ const entries = fs.readdirSync(src, { withFileTypes: true });
60
+
61
+ for (const entry of entries) {
62
+ const srcPath = path.join(src, entry.name);
63
+ const destPath = path.join(dest, entry.name);
64
+
65
+ // Skip node_modules, .git, bin
66
+ if (["node_modules", ".git", "bin"].includes(entry.name)) continue;
67
+
68
+ if (entry.isDirectory()) {
69
+ copyDir(srcPath, destPath);
70
+ } else {
71
+ fs.copyFileSync(srcPath, destPath);
72
+ }
73
+ }
74
+ }
75
+
76
+ function printBanner() {
77
+ console.log(`
78
+ ${color("magenta", "┌──────────────────────────────────────────────┐")}
79
+ ${color("magenta", "│")} ${color("bright", "紫微斗数 Ziwei Skill")} - Installer ${color("magenta", "│")}
80
+ ${color("magenta", "└──────────────────────────────────────────────┘")}
81
+
82
+ 基于传统紫微斗数命理学的命盘分析与运势预测
83
+ 支持 ${color("cyan", "Claude Code")} 和 ${color("cyan", "OpenClaw")}
84
+ `);
85
+ }
86
+
87
+ async function detectPlatform() {
88
+ const hasClaude = fs.existsSync(path.join(HOME, ".claude"));
89
+ const hasOpenClaw = fs.existsSync(path.join(HOME, ".openclaw"));
90
+
91
+ return { hasClaude, hasOpenClaw };
92
+ }
93
+
94
+ async function selectPlatform(rl, platforms) {
95
+ logStep("1/4", "检测安装平台...");
96
+
97
+ const options = [];
98
+ if (platforms.hasClaude) {
99
+ options.push({ key: "1", name: "Claude Code", dir: CLAUDE_SKILLS_DIR });
100
+ logSuccess("检测到 Claude Code");
101
+ }
102
+ if (platforms.hasOpenClaw) {
103
+ options.push({ key: "2", name: "OpenClaw", dir: OPENCLAW_SKILLS_DIR });
104
+ logSuccess("检测到 OpenClaw");
105
+ }
106
+
107
+ if (options.length === 0) {
108
+ logWarn("未检测到 Claude Code 或 OpenClaw");
109
+ logInfo("将创建 Claude Code skills 目录");
110
+ fs.mkdirSync(CLAUDE_SKILLS_DIR, { recursive: true });
111
+ return { name: "Claude Code", dir: CLAUDE_SKILLS_DIR };
112
+ }
113
+
114
+ if (options.length === 1) {
115
+ return options[0];
116
+ }
117
+
118
+ // Both platforms available
119
+ log("\n请选择安装平台:");
120
+ options.forEach((opt, i) => {
121
+ log(` ${i + 1}. ${opt.name}`);
122
+ });
123
+ log(` 3. 两者都安装`);
124
+
125
+ const choice = await ask(rl, "\n选择 (1/2/3): ");
126
+
127
+ if (choice === "3") {
128
+ return "both";
129
+ }
130
+
131
+ return options[parseInt(choice) - 1] || options[0];
132
+ }
133
+
134
+ async function installSkill(targetDir, platformName) {
135
+ const skillDest = path.join(targetDir, SKILL_NAME);
136
+
137
+ // Check if already installed
138
+ if (fs.existsSync(skillDest)) {
139
+ logWarn(`${platformName} 已安装 ziwei skill`);
140
+ logInfo(`位置: ${skillDest}`);
141
+ return "exists";
142
+ }
143
+
144
+ // Create skill directory
145
+ fs.mkdirSync(skillDest, { recursive: true });
146
+
147
+ // Copy files
148
+ const filesToCopy = ["SKILL.md", "system-prompt.md"];
149
+ for (const file of filesToCopy) {
150
+ const src = path.join(PACKAGE_ROOT, file);
151
+ if (fs.existsSync(src)) {
152
+ fs.copyFileSync(src, path.join(skillDest, file));
153
+ }
154
+ }
155
+
156
+ logSuccess(`Skill 已安装到: ${skillDest}`);
157
+ return "installed";
158
+ }
159
+
160
+ async function installCli() {
161
+ logStep("3/4", "安装 ziwei CLI...");
162
+
163
+ try {
164
+ // Check if already installed
165
+ try {
166
+ execSync("which ziwei", { stdio: "ignore" });
167
+ logSuccess("ziwei CLI 已安装");
168
+ return true;
169
+ } catch {
170
+ // Not installed, proceed
171
+ }
172
+
173
+ // Try npm link from package root
174
+ logInfo("正在全局安装 ziwei CLI...");
175
+ execSync("npm link", { cwd: PACKAGE_ROOT, stdio: "inherit" });
176
+ logSuccess("ziwei CLI 安装成功");
177
+
178
+ // Verify
179
+ const version = execSync("ziwei --version", { encoding: "utf8" }).trim();
180
+ logInfo(`版本: ${version}`);
181
+
182
+ return true;
183
+ } catch (error) {
184
+ logError(`CLI 安装失败: ${error.message}`);
185
+ logInfo("你可以手动运行: cd " + PACKAGE_ROOT + " && npm link");
186
+ return false;
187
+ }
188
+ }
189
+
190
+ function printSummary(platforms) {
191
+ logStep("4/4", "安装完成!");
192
+
193
+ console.log(`
194
+ ${color("green", "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")}
195
+ ${color("bright", " 紫微斗数 Skill 已就绪!")}
196
+ ${color("green", "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")}
197
+
198
+ ${color("cyan", "CLI 命令:")}
199
+ ziwei palace --palace 命宫 --date 1990-05-15 --time 10:30 --gender 男 --city 北京
200
+ ziwei palace --palace 官禄宫 --scope yearly --year 2025 ...
201
+
202
+ ${color("cyan", "Skill 触发词:")}
203
+ 算命、看命、命盘、运势、合盘、紫微、流年、大限
204
+
205
+ ${color("yellow", "在 Claude Code / OpenClaw 中试试:")}
206
+ "帮我算命"
207
+ "看看我今年的运势"
208
+ "我和对方合适吗"
209
+
210
+ ${color("dim", "重启 Claude Code 会话后 skill 将自动加载")}
211
+ `);
212
+ }
213
+
214
+ async function main() {
215
+ const rl = createPrompt();
216
+
217
+ try {
218
+ printBanner();
219
+
220
+ // Step 1: Detect platforms
221
+ const platforms = await detectPlatform();
222
+ const selected = await selectPlatform(rl, platforms);
223
+
224
+ // Step 2: Install skill files
225
+ logStep("2/4", "安装 Skill 文件...");
226
+
227
+ if (selected === "both") {
228
+ await installSkill(CLAUDE_SKILLS_DIR, "Claude Code");
229
+ await installSkill(OPENCLAW_SKILLS_DIR, "OpenClaw");
230
+ } else {
231
+ await installSkill(selected.dir, selected.name);
232
+ }
233
+
234
+ // Step 3: Install CLI
235
+ await installCli();
236
+
237
+ // Step 4: Summary
238
+ printSummary(platforms);
239
+
240
+ rl.close();
241
+ } catch (error) {
242
+ logError(`安装失败: ${error.message}`);
243
+ console.error(error);
244
+ rl.close();
245
+ process.exit(1);
246
+ }
247
+ }
248
+
249
+ main();
package/bin/ziwei.js ADDED
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * 紫微斗数 CLI 入口
5
+ */
6
+
7
+ import { Command } from 'commander';
8
+ import { executePalace } from '../lib/commands/palace.js';
9
+ import { executeSynastry, executeSynastryYearly } from '../lib/commands/synastry.js';
10
+ import { executeBazi, executeCalendar } from '../lib/commands/bazi.js';
11
+
12
+ const program = new Command();
13
+
14
+ program
15
+ .name('ziwei')
16
+ .description('紫微斗数命理分析工具')
17
+ .version('1.0.0');
18
+
19
+ // 宫位查询命令
20
+ program
21
+ .command('palace')
22
+ .description('查询指定宫位的三方四正(支持本命/大限/流年/流月/流日)')
23
+ .requiredOption('--date <date>', '出生日期 (YYYY-MM-DD)')
24
+ .requiredOption('--time <time>', '出生时间 (HH:MM)')
25
+ .requiredOption('--gender <gender>', '性别 (男/女)')
26
+ .requiredOption('--city <city>', '出生城市')
27
+ .requiredOption('--palace <palace>', '宫位名称')
28
+ .option('--scope <scope>', '查询层级 (origin/decadal/yearly/monthly/daily)', 'origin')
29
+ .option('--year <year>', '查询年份(运限层级必需)')
30
+ .option('--month <month>', '查询月份(流月/流日必需)')
31
+ .option('--day <day>', '查询日期(流日必需)')
32
+ .option('--lunar', '农历日期', false)
33
+ .option('--leap', '闰月', false)
34
+ .action(async (options) => {
35
+ const result = await executePalace({
36
+ ...options,
37
+ year: options.year ? parseInt(options.year) : undefined,
38
+ month: options.month ? parseInt(options.month) : undefined,
39
+ day: options.day ? parseInt(options.day) : undefined
40
+ });
41
+ console.log(JSON.stringify(result, null, 2));
42
+ });
43
+
44
+ // 合盘分析命令
45
+ const synastry = program
46
+ .command('synastry')
47
+ .description('合盘分析');
48
+
49
+ // 本命合盘
50
+ synastry
51
+ .command('origin')
52
+ .description('本命合盘分析')
53
+ .requiredOption('--a-date <date>', 'A方出生日期 (YYYY-MM-DD)')
54
+ .requiredOption('--a-time <time>', 'A方出生时间 (HH:MM)')
55
+ .requiredOption('--a-gender <gender>', 'A方性别 (男/女)')
56
+ .requiredOption('--a-city <city>', 'A方出生城市')
57
+ .option('--a-name <name>', 'A方姓名', 'A')
58
+ .option('--a-lunar', 'A方农历日期', false)
59
+ .option('--a-leap', 'A方闰月', false)
60
+ .requiredOption('--b-date <date>', 'B方出生日期 (YYYY-MM-DD)')
61
+ .requiredOption('--b-time <time>', 'B方出生时间 (HH:MM)')
62
+ .requiredOption('--b-gender <gender>', 'B方性别 (男/女)')
63
+ .requiredOption('--b-city <city>', 'B方出生城市')
64
+ .option('--b-name <name>', 'B方姓名', 'B')
65
+ .option('--b-lunar', 'B方农历日期', false)
66
+ .option('--b-leap', 'B方闰月', false)
67
+ .action(async (options) => {
68
+ const result = await executeSynastry({
69
+ aDate: options.aDate,
70
+ aTime: options.aTime,
71
+ aGender: options.aGender,
72
+ aCity: options.aCity,
73
+ aName: options.aName,
74
+ aLunar: options.aLunar,
75
+ aLeap: options.aLeap,
76
+ bDate: options.bDate,
77
+ bTime: options.bTime,
78
+ bGender: options.bGender,
79
+ bCity: options.bCity,
80
+ bName: options.bName,
81
+ bLunar: options.bLunar,
82
+ bLeap: options.bLeap
83
+ });
84
+ console.log(JSON.stringify(result, null, 2));
85
+ });
86
+
87
+ // 流年合盘
88
+ synastry
89
+ .command('yearly')
90
+ .description('流年合盘分析')
91
+ .requiredOption('--a-date <date>', 'A方出生日期 (YYYY-MM-DD)')
92
+ .requiredOption('--a-time <time>', 'A方出生时间 (HH:MM)')
93
+ .requiredOption('--a-gender <gender>', 'A方性别 (男/女)')
94
+ .requiredOption('--a-city <city>', 'A方出生城市')
95
+ .option('--a-name <name>', 'A方姓名', 'A')
96
+ .option('--a-lunar', 'A方农历日期', false)
97
+ .option('--a-leap', 'A方闰月', false)
98
+ .requiredOption('--b-date <date>', 'B方出生日期 (YYYY-MM-DD)')
99
+ .requiredOption('--b-time <time>', 'B方出生时间 (HH:MM)')
100
+ .requiredOption('--b-gender <gender>', 'B方性别 (男/女)')
101
+ .requiredOption('--b-city <city>', 'B方出生城市')
102
+ .option('--b-name <name>', 'B方姓名', 'B')
103
+ .option('--b-lunar', 'B方农历日期', false)
104
+ .option('--b-leap', 'B方闰月', false)
105
+ .requiredOption('--year <year>', '查询年份')
106
+ .action(async (options) => {
107
+ const result = await executeSynastryYearly({
108
+ aDate: options.aDate,
109
+ aTime: options.aTime,
110
+ aGender: options.aGender,
111
+ aCity: options.aCity,
112
+ aName: options.aName,
113
+ aLunar: options.aLunar,
114
+ aLeap: options.aLeap,
115
+ bDate: options.bDate,
116
+ bTime: options.bTime,
117
+ bGender: options.bGender,
118
+ bCity: options.bCity,
119
+ bName: options.bName,
120
+ bLunar: options.bLunar,
121
+ bLeap: options.bLeap,
122
+ year: parseInt(options.year)
123
+ });
124
+ console.log(JSON.stringify(result, null, 2));
125
+ });
126
+
127
+ // 八字排盘命令
128
+ program
129
+ .command('bazi')
130
+ .description('八字排盘(四柱、十神、大运、神煞、刑冲合会)')
131
+ .requiredOption('--date <date>', '出生日期 (YYYY-MM-DD)')
132
+ .requiredOption('--time <time>', '出生时间 (HH:MM)')
133
+ .requiredOption('--gender <gender>', '性别 (男/女)')
134
+ .option('--lunar', '农历日期', false)
135
+ .option('--sect <sect>', '早晚子时 (1=次日/2=当日)', '2')
136
+ .action(async (options) => {
137
+ const result = await executeBazi(options);
138
+ console.log(JSON.stringify(result, null, 2));
139
+ });
140
+
141
+ // 黄历查询命令
142
+ program
143
+ .command('calendar')
144
+ .description('黄历查询(农历、干支、节气、生肖)')
145
+ .option('--date <date>', '阳历日期 (YYYY-MM-DD),不传则为当天')
146
+ .action(async (options) => {
147
+ const result = await executeCalendar(options);
148
+ console.log(JSON.stringify(result, null, 2));
149
+ });
150
+
151
+ program.parse();
@@ -0,0 +1,35 @@
1
+ /**
2
+ * 八字排盘命令处理
3
+ */
4
+
5
+ import { generateBazi, getCalendar } from '../engine/bazi.js';
6
+
7
+ /**
8
+ * 执行八字排盘
9
+ */
10
+ export async function executeBazi(options) {
11
+ try {
12
+ const result = generateBazi({
13
+ date: options.date,
14
+ time: options.time,
15
+ gender: options.gender,
16
+ lunar: options.lunar || false,
17
+ sect: options.sect ? parseInt(options.sect) : 2,
18
+ });
19
+ return { success: true, data: result };
20
+ } catch (error) {
21
+ return { success: false, error: error.message };
22
+ }
23
+ }
24
+
25
+ /**
26
+ * 执行黄历查询
27
+ */
28
+ export async function executeCalendar(options) {
29
+ try {
30
+ const result = getCalendar(options.date);
31
+ return { success: true, data: result };
32
+ } catch (error) {
33
+ return { success: false, error: error.message };
34
+ }
35
+ }