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 +94 -0
- package/SKILL.md +142 -0
- package/bin/install.cjs +249 -0
- package/bin/ziwei.js +151 -0
- package/lib/commands/bazi.js +35 -0
- package/lib/commands/palace.js +156 -0
- package/lib/commands/synastry.js +124 -0
- package/lib/engine/astrolabe.js +216 -0
- package/lib/engine/bazi.js +207 -0
- package/lib/engine/config.js +167 -0
- package/lib/engine/geo.js +252 -0
- package/lib/engine/patterns.js +371 -0
- package/lib/engine/solar.js +211 -0
- package/lib/engine/synastry.js +437 -0
- package/package.json +49 -0
- package/system-prompt.md +539 -0
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 紫微斗数合盘分析模块
|
|
3
|
+
* 评估两人命盘的匹配度
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
PALACE_NAMES, MAJOR_14, SOFT, TOUGH, FLOWER, HELPER, POS_ADJ, NEG_ADJ,
|
|
8
|
+
BASE_WEIGHTS, MUTAGEN_WEIGHTS, FLOWER_WEIGHT, HELPER_WEIGHT,
|
|
9
|
+
POS_ADJ_WEIGHT, NEG_ADJ_WEIGHT, TRI_WEIGHTS, NORM_PARAMS,
|
|
10
|
+
BRIGHTNESS_ALIASES, BRIGHTNESS_POS_MULT, BRIGHTNESS_NEG_MULT,
|
|
11
|
+
SYNASTRY_BINS, BUCKET_TONE, PALACE_ADVICE, STAR_BRIEF
|
|
12
|
+
} from './config.js';
|
|
13
|
+
import { generateAstrolabe, getScopePalaces } from './astrolabe.js';
|
|
14
|
+
|
|
15
|
+
// 宫位导航函数
|
|
16
|
+
function opp(i) { return (i + 6) % 12; }
|
|
17
|
+
function triIndices(i) { return [i, opp(i), (i + 4) % 12, (i + 8) % 12]; }
|
|
18
|
+
|
|
19
|
+
// 构建星盘映射表
|
|
20
|
+
function buildMaps(chart) {
|
|
21
|
+
const palStars = {};
|
|
22
|
+
const palMutagen = {};
|
|
23
|
+
const nameToIdx = {};
|
|
24
|
+
const idxToBranch = {};
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < 12; i++) {
|
|
27
|
+
const palace = chart[i];
|
|
28
|
+
nameToIdx[palace.name] = palace.index;
|
|
29
|
+
idxToBranch[palace.index] = palace.earthlyBranch;
|
|
30
|
+
|
|
31
|
+
const stars = new Set();
|
|
32
|
+
const muts = new Set();
|
|
33
|
+
|
|
34
|
+
for (const s of palace.majorStars || []) {
|
|
35
|
+
stars.add(s.name);
|
|
36
|
+
if (s.mutagen) muts.add(s.mutagen);
|
|
37
|
+
}
|
|
38
|
+
for (const s of palace.minorStars || []) {
|
|
39
|
+
stars.add(s.name);
|
|
40
|
+
if (s.mutagen) muts.add(s.mutagen);
|
|
41
|
+
}
|
|
42
|
+
for (const s of palace.adjectiveStars || []) {
|
|
43
|
+
stars.add(s.name);
|
|
44
|
+
if (s.mutagen) muts.add(s.mutagen);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
palStars[palace.index] = stars;
|
|
48
|
+
palMutagen[palace.index] = muts;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return { palStars, palMutagen, nameToIdx, idxToBranch };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 构建亮度映射表
|
|
55
|
+
function buildBrightnessMap(chart) {
|
|
56
|
+
const palBright = {};
|
|
57
|
+
for (let i = 0; i < 12; i++) {
|
|
58
|
+
const palace = chart[i];
|
|
59
|
+
const mp = {};
|
|
60
|
+
const allStars = [...(palace.majorStars || []), ...(palace.minorStars || []), ...(palace.adjectiveStars || [])];
|
|
61
|
+
for (const s of allStars) {
|
|
62
|
+
if (s.name && s.brightness) {
|
|
63
|
+
mp[s.name] = s.brightness;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
palBright[palace.index] = mp;
|
|
67
|
+
}
|
|
68
|
+
return palBright;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 构建权重字典
|
|
72
|
+
function buildWeightMap() {
|
|
73
|
+
const weights = { ...BASE_WEIGHTS };
|
|
74
|
+
for (const s of FLOWER) weights[s] = FLOWER_WEIGHT;
|
|
75
|
+
for (const s of HELPER) weights[s] = HELPER_WEIGHT;
|
|
76
|
+
for (const s of POS_ADJ) weights[s] = POS_ADJ_WEIGHT;
|
|
77
|
+
for (const s of NEG_ADJ) weights[s] = NEG_ADJ_WEIGHT;
|
|
78
|
+
return weights;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 按地支叠加B的星曜到A的宫位
|
|
82
|
+
function overlaySameBranch(AIdxToBranch, BIdxToBranch, BPalStars, BPalMut) {
|
|
83
|
+
const overlayStars = {};
|
|
84
|
+
const overlayMut = {};
|
|
85
|
+
const bMap = {};
|
|
86
|
+
|
|
87
|
+
for (const [i, br] of Object.entries(BIdxToBranch)) {
|
|
88
|
+
bMap[br] = parseInt(i);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
for (const [ai, abr] of Object.entries(AIdxToBranch)) {
|
|
92
|
+
const bi = bMap[abr];
|
|
93
|
+
const aiNum = parseInt(ai);
|
|
94
|
+
|
|
95
|
+
if (bi === undefined) {
|
|
96
|
+
overlayStars[aiNum] = new Set();
|
|
97
|
+
overlayMut[aiNum] = new Set();
|
|
98
|
+
} else {
|
|
99
|
+
overlayStars[aiNum] = new Set(BPalStars[bi] || []);
|
|
100
|
+
overlayMut[aiNum] = new Set(BPalMut[bi] || []);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return { overlayStars, overlayMut };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 归一化亮度标签
|
|
108
|
+
function normalizeBrightnessLabel(br) {
|
|
109
|
+
if (!br) return null;
|
|
110
|
+
return BRIGHTNESS_ALIASES[br] || br;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// 应用亮度调整
|
|
114
|
+
function applyBrightnessAdjust(w, br) {
|
|
115
|
+
if (br === null || br === undefined) return w;
|
|
116
|
+
const normalizedBr = normalizeBrightnessLabel(br);
|
|
117
|
+
if (!normalizedBr) return w;
|
|
118
|
+
|
|
119
|
+
if (w >= 0) {
|
|
120
|
+
return w * (BRIGHTNESS_POS_MULT[normalizedBr] || 1.0);
|
|
121
|
+
} else {
|
|
122
|
+
return w * (BRIGHTNESS_NEG_MULT[normalizedBr] || 1.0);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 将B盘的亮度映射到与A盘同地支的宫位上
|
|
127
|
+
function mapBrightnessByBranch(AIdxToBranch, BIdxToBranch, BBright) {
|
|
128
|
+
const branchToBIdx = {};
|
|
129
|
+
for (const [i, br] of Object.entries(BIdxToBranch)) {
|
|
130
|
+
branchToBIdx[br] = parseInt(i);
|
|
131
|
+
}
|
|
132
|
+
const ABright = {};
|
|
133
|
+
for (const [ai, abr] of Object.entries(AIdxToBranch)) {
|
|
134
|
+
const bi = branchToBIdx[abr];
|
|
135
|
+
const aiNum = parseInt(ai);
|
|
136
|
+
ABright[aiNum] = (bi !== undefined && BBright[bi]) ? BBright[bi] : {};
|
|
137
|
+
}
|
|
138
|
+
return ABright;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 计算单个宫位得分
|
|
142
|
+
function scorePalace(i, BOnAStars, BOnAMut, weight = 1.0, nameByIdx = null, brightMap = null) {
|
|
143
|
+
const tri = triIndices(i);
|
|
144
|
+
const wMap = {
|
|
145
|
+
[i]: TRI_WEIGHTS.self,
|
|
146
|
+
[opp(i)]: TRI_WEIGHTS.opp,
|
|
147
|
+
[(i + 4) % 12]: TRI_WEIGHTS.tri1,
|
|
148
|
+
[(i + 8) % 12]: TRI_WEIGHTS.tri2
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
let pts = 0.0;
|
|
152
|
+
const reasons = [];
|
|
153
|
+
const baseW = buildWeightMap();
|
|
154
|
+
|
|
155
|
+
for (const j of tri) {
|
|
156
|
+
const jw = wMap[j] || 0.0;
|
|
157
|
+
|
|
158
|
+
for (const s of BOnAStars[j] || []) {
|
|
159
|
+
let br = null;
|
|
160
|
+
if (brightMap && brightMap[j]) {
|
|
161
|
+
br = brightMap[j][s];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const base = baseW[s] || 0.0;
|
|
165
|
+
const adj = applyBrightnessAdjust(base, br);
|
|
166
|
+
const inc = adj * jw * weight;
|
|
167
|
+
|
|
168
|
+
if (Math.abs(inc) > 1e-9) {
|
|
169
|
+
pts += inc;
|
|
170
|
+
const ti = nameByIdx ? nameByIdx[i] : PALACE_NAMES[i];
|
|
171
|
+
const tj = nameByIdx ? nameByIdx[j] : PALACE_NAMES[j];
|
|
172
|
+
const brn = normalizeBrightnessLabel(br);
|
|
173
|
+
|
|
174
|
+
if (br) {
|
|
175
|
+
reasons.push(`${ti}←${tj}: B星[${s}|${brn}] *${jw.toFixed(1)} => ${inc.toFixed(2)}`);
|
|
176
|
+
} else {
|
|
177
|
+
reasons.push(`${ti}←${tj}: B星[${s}] *${jw.toFixed(1)} => ${inc.toFixed(2)}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
for (const m of BOnAMut[j] || []) {
|
|
183
|
+
const inc = (MUTAGEN_WEIGHTS[m] || 0.0) * jw * weight;
|
|
184
|
+
if (Math.abs(inc) > 1e-9) {
|
|
185
|
+
pts += inc;
|
|
186
|
+
const ti = nameByIdx ? nameByIdx[i] : PALACE_NAMES[i];
|
|
187
|
+
const tj = nameByIdx ? nameByIdx[j] : PALACE_NAMES[j];
|
|
188
|
+
reasons.push(`${ti}←${tj}: B化[${m}] *${jw.toFixed(1)} => ${inc.toFixed(2)}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return { pts, reasons };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// 归一化分数到0-100
|
|
197
|
+
function normScore(x, center = null, spread = null) {
|
|
198
|
+
if (center === null) center = NORM_PARAMS.center;
|
|
199
|
+
if (spread === null) spread = NORM_PARAMS.spread;
|
|
200
|
+
const z = (x - center) / (spread > 0 ? spread : 1.0);
|
|
201
|
+
const sig = 1.0 / (1.0 + Math.exp(-z));
|
|
202
|
+
return sig * 100.0;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// 根据分数判断档位
|
|
206
|
+
function getBucket(x) {
|
|
207
|
+
for (const [name, lo, hi] of SYNASTRY_BINS) {
|
|
208
|
+
if (lo <= x && x < hi) return name;
|
|
209
|
+
}
|
|
210
|
+
return "中性";
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* 紫微斗数合盘评分
|
|
215
|
+
*/
|
|
216
|
+
export function synastryScore(chartA, chartB) {
|
|
217
|
+
const { palStars: AStars, palMutagen: AMut, nameToIdx: AN2I, idxToBranch: AI2B } = buildMaps(chartA);
|
|
218
|
+
const { palStars: BStars, palMutagen: BMut, idxToBranch: BI2B } = buildMaps(chartB);
|
|
219
|
+
|
|
220
|
+
const { overlayStars: BOnAStars, overlayMut: BOnAMut } = overlaySameBranch(AI2B, BI2B, BStars, BMut);
|
|
221
|
+
|
|
222
|
+
const AI2N = Object.fromEntries(Object.entries(AN2I).map(([k, v]) => [v, k]));
|
|
223
|
+
const ABright = mapBrightnessByBranch(AI2B, BI2B, buildBrightnessMap(chartB));
|
|
224
|
+
|
|
225
|
+
const palaceScores = {};
|
|
226
|
+
const palaceReasons = {};
|
|
227
|
+
for (const [pName, idx] of Object.entries(AN2I)) {
|
|
228
|
+
const { pts, reasons } = scorePalace(idx, BOnAStars, BOnAMut, 1.0, AI2N, ABright);
|
|
229
|
+
palaceScores[pName] = pts;
|
|
230
|
+
palaceReasons[pName] = reasons;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
palaces: palaceScores,
|
|
235
|
+
explanations: { palaces: palaceReasons }
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* 基于宫位的合盘解释
|
|
241
|
+
*/
|
|
242
|
+
export function interpretSynastryByPalace(result, minAbsEffect = 0.3, maxItemsPerPolarity = null) {
|
|
243
|
+
const palRaw = result.palaces || {};
|
|
244
|
+
const palExps = result.explanations?.palaces || {};
|
|
245
|
+
|
|
246
|
+
const out = { palaces: {} };
|
|
247
|
+
|
|
248
|
+
function parseInc(line) {
|
|
249
|
+
if (!line.includes('=>')) return null;
|
|
250
|
+
try {
|
|
251
|
+
const incTxt = line.split('=>').pop().trim();
|
|
252
|
+
return parseFloat(incTxt);
|
|
253
|
+
} catch (e) {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function adviceFor(pal, bucket) {
|
|
259
|
+
const posKeys = new Set(["相合", "强合", "共振"]);
|
|
260
|
+
const negKeys = new Set(["相克", "相冲"]);
|
|
261
|
+
|
|
262
|
+
let key = 'neu';
|
|
263
|
+
if (posKeys.has(bucket)) key = 'pos';
|
|
264
|
+
else if (negKeys.has(bucket)) key = 'neg';
|
|
265
|
+
|
|
266
|
+
return PALACE_ADVICE[pal]?.[key] || [];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
for (const [pal, raw] of Object.entries(palRaw)) {
|
|
270
|
+
const lines = palExps[pal] || [];
|
|
271
|
+
const posLinesWithV = [];
|
|
272
|
+
const negLinesWithV = [];
|
|
273
|
+
|
|
274
|
+
for (const ln of lines) {
|
|
275
|
+
const v = parseInc(ln);
|
|
276
|
+
if (v === null) continue;
|
|
277
|
+
if (Math.abs(v) < minAbsEffect) continue;
|
|
278
|
+
|
|
279
|
+
if (v > 0) posLinesWithV.push([Math.abs(v), ln]);
|
|
280
|
+
else if (v < 0) negLinesWithV.push([Math.abs(v), ln]);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
posLinesWithV.sort((a, b) => b[0] - a[0]);
|
|
284
|
+
negLinesWithV.sort((a, b) => b[0] - a[0]);
|
|
285
|
+
|
|
286
|
+
let posLines = posLinesWithV.map(x => x[1]);
|
|
287
|
+
let negLines = negLinesWithV.map(x => x[1]);
|
|
288
|
+
|
|
289
|
+
if (maxItemsPerPolarity !== null) {
|
|
290
|
+
posLines = posLines.slice(0, maxItemsPerPolarity);
|
|
291
|
+
negLines = negLines.slice(0, maxItemsPerPolarity);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const score = normScore(raw);
|
|
295
|
+
const bucket = getBucket(score);
|
|
296
|
+
|
|
297
|
+
out.palaces[pal] = {
|
|
298
|
+
raw: raw,
|
|
299
|
+
score: score,
|
|
300
|
+
bucket: bucket,
|
|
301
|
+
highlights: posLines,
|
|
302
|
+
risks: negLines,
|
|
303
|
+
advice: adviceFor(pal, bucket)
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return out;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* 生成自然语言合盘分析
|
|
312
|
+
*/
|
|
313
|
+
export function renderSynastryText(aName, bName, synResult, interpResult) {
|
|
314
|
+
const palOut = [];
|
|
315
|
+
const pals = interpResult.palaces || {};
|
|
316
|
+
|
|
317
|
+
for (const [pal, info] of Object.entries(pals)) {
|
|
318
|
+
const bucket = info.bucket || '中性';
|
|
319
|
+
const tone = BUCKET_TONE[bucket] || '';
|
|
320
|
+
const oneLiner = tone.endsWith('。') ? tone : `${tone}。`;
|
|
321
|
+
|
|
322
|
+
palOut.push({
|
|
323
|
+
palace: pal,
|
|
324
|
+
bucket: bucket,
|
|
325
|
+
score: Math.round(info.score),
|
|
326
|
+
one_liner: oneLiner,
|
|
327
|
+
advice: info.advice || []
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return { headline: `${aName} × ${bName}`, palaces: palOut };
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* 完整的合盘分析接口
|
|
336
|
+
*/
|
|
337
|
+
export function analyzeSynastry(chartA, chartB, nameA = "A", nameB = "B", options = {}) {
|
|
338
|
+
const { minAbsEffect = 0.3, maxItemsPerPolarity = null, includeRawData = false } = options;
|
|
339
|
+
|
|
340
|
+
try {
|
|
341
|
+
const synResult = synastryScore(chartA, chartB);
|
|
342
|
+
const interpResult = interpretSynastryByPalace(synResult, minAbsEffect, maxItemsPerPolarity);
|
|
343
|
+
const textResult = renderSynastryText(nameA, nameB, synResult, interpResult);
|
|
344
|
+
|
|
345
|
+
const result = {
|
|
346
|
+
summary: {
|
|
347
|
+
headline: textResult.headline,
|
|
348
|
+
total_palaces: Object.keys(interpResult.palaces).length
|
|
349
|
+
},
|
|
350
|
+
palaces: textResult.palaces,
|
|
351
|
+
metadata: {
|
|
352
|
+
analysis_time: new Date().toISOString(),
|
|
353
|
+
min_effect_threshold: minAbsEffect
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
if (includeRawData) {
|
|
358
|
+
result.raw_data = {
|
|
359
|
+
synastry_scores: synResult,
|
|
360
|
+
interpretation: interpResult
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return { success: true, data: result };
|
|
365
|
+
|
|
366
|
+
} catch (error) {
|
|
367
|
+
return { success: false, error: `合盘分析失败: ${error.message}` };
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* 通过用户信息进行合盘分析
|
|
373
|
+
*/
|
|
374
|
+
export async function analyzeSynastryByUserInfo({
|
|
375
|
+
birth_date_a, birth_time_a, gender_a, city_a, name_a = "A",
|
|
376
|
+
birth_date_b, birth_time_b, gender_b, city_b, name_b = "B",
|
|
377
|
+
is_lunar_a = false, is_leap_a = false,
|
|
378
|
+
is_lunar_b = false, is_leap_b = false,
|
|
379
|
+
scope = 'origin',
|
|
380
|
+
query_date = null,
|
|
381
|
+
min_abs_effect = 0.3,
|
|
382
|
+
max_items_per_polarity = null,
|
|
383
|
+
include_raw_data = false
|
|
384
|
+
}) {
|
|
385
|
+
try {
|
|
386
|
+
const astroA = await generateAstrolabe({
|
|
387
|
+
birth_date: birth_date_a,
|
|
388
|
+
time: birth_time_a,
|
|
389
|
+
gender: gender_a,
|
|
390
|
+
city: city_a,
|
|
391
|
+
is_lunar: is_lunar_a,
|
|
392
|
+
is_leap: is_leap_a
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
const astroB = await generateAstrolabe({
|
|
396
|
+
birth_date: birth_date_b,
|
|
397
|
+
time: birth_time_b,
|
|
398
|
+
gender: gender_b,
|
|
399
|
+
city: city_b,
|
|
400
|
+
is_lunar: is_lunar_b,
|
|
401
|
+
is_leap: is_leap_b
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
let chartA, chartB;
|
|
405
|
+
|
|
406
|
+
if (scope === 'origin') {
|
|
407
|
+
chartA = astroA.palaces;
|
|
408
|
+
chartB = astroB.palaces;
|
|
409
|
+
} else {
|
|
410
|
+
const horoscopeA = astroA.horoscope(query_date);
|
|
411
|
+
const horoscopeB = astroB.horoscope(query_date);
|
|
412
|
+
chartA = getScopePalaces(horoscopeA, scope);
|
|
413
|
+
chartB = getScopePalaces(horoscopeB, scope);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const result = analyzeSynastry(chartA, chartB, name_a, name_b, {
|
|
417
|
+
minAbsEffect: min_abs_effect,
|
|
418
|
+
maxItemsPerPolarity: max_items_per_polarity,
|
|
419
|
+
includeRawData: include_raw_data
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
return {
|
|
423
|
+
success: true,
|
|
424
|
+
data: result.data,
|
|
425
|
+
message: `${name_a}与${name_b}的合盘分析完成`,
|
|
426
|
+
time: new Date().toISOString()
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
} catch (error) {
|
|
430
|
+
return {
|
|
431
|
+
success: false,
|
|
432
|
+
error: error.message,
|
|
433
|
+
message: '合盘分析失败',
|
|
434
|
+
time: new Date().toISOString()
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ziwei-cli",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "紫微斗数 + 八字命理分析 CLI 工具 - Claude Code / OpenClaw Skill",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "bin/ziwei.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"ziwei-cli": "./bin/install.cjs",
|
|
9
|
+
"ziwei": "./bin/ziwei.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin/",
|
|
13
|
+
"lib/",
|
|
14
|
+
"SKILL.md",
|
|
15
|
+
"system-prompt.md",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"start": "node bin/ziwei.js",
|
|
20
|
+
"postinstall": "node bin/install.cjs || true"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"紫微斗数",
|
|
24
|
+
"八字",
|
|
25
|
+
"四柱",
|
|
26
|
+
"算命",
|
|
27
|
+
"命理",
|
|
28
|
+
"astrology",
|
|
29
|
+
"bazi",
|
|
30
|
+
"ziwei",
|
|
31
|
+
"fortune",
|
|
32
|
+
"claude-code",
|
|
33
|
+
"openclaw",
|
|
34
|
+
"skill"
|
|
35
|
+
],
|
|
36
|
+
"author": "shanrichard",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"cantian-tymext": "^0.0.21",
|
|
40
|
+
"commander": "^12.0.0",
|
|
41
|
+
"iztro": "^2.5.3",
|
|
42
|
+
"lunar-javascript": "^1.6.12",
|
|
43
|
+
"tyme4ts": "^1.4.2"
|
|
44
|
+
},
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/shanrichard/ziwei-skill"
|
|
48
|
+
}
|
|
49
|
+
}
|