guanwei 1.3.2 → 1.3.4

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.
Files changed (52) hide show
  1. package/README.md +28 -8
  2. package/dist/assets/index-DVd66cjI.js +102 -0
  3. package/dist/index.html +1 -1
  4. package/package.json +13 -7
  5. package/packages/guanwei-api/package.json +26 -0
  6. package/packages/guanwei-api/src/mcp-http.ts +89 -0
  7. package/packages/guanwei-api/src/mcp.ts +108 -0
  8. package/packages/guanwei-api/src/routes/arts.ts +23 -0
  9. package/packages/guanwei-api/src/routes/chart.ts +24 -0
  10. package/packages/guanwei-api/src/server.ts +73 -0
  11. package/scripts/check-boundary.mjs +80 -0
  12. package/scripts/check-package.mjs +71 -0
  13. package/scripts/credentials.mjs +52 -0
  14. package/scripts/github-history-cleanup.mjs +140 -0
  15. package/scripts/npm-release.mjs +79 -0
  16. package/scripts/preflight-release.sh +29 -0
  17. package/scripts/release.sh +8 -3
  18. package/server/package.json +24 -0
  19. package/server/src/index.ts +58 -16
  20. package/server/src/routes/ai.ts +11 -17
  21. package/server/src/routes/divine.ts +36 -29
  22. package/server/src/routes/hour.ts +4 -0
  23. package/server/src/routes/tarot.ts +30 -7
  24. package/server/src/routes/users.ts +99 -48
  25. package/server/src/services/auth.ts +53 -0
  26. package/server/src/services/dataDir.ts +80 -0
  27. package/server/src/services/divineStore.ts +5 -2
  28. package/server/src/services/duanyu.ts +3 -3
  29. package/server/src/services/llmProvider.ts +4 -3
  30. package/server/src/services/usersDb.ts +45 -0
  31. package/shared/core/data/gua64.ts +5 -5
  32. package/shared/core/data/qimen.ts +11 -9
  33. package/shared/core/data/ziwei.ts +16 -15
  34. package/shared/core/engine/bazi.ts +64 -13
  35. package/shared/core/engine/calendar.ts +18 -5
  36. package/shared/core/engine/chart.ts +3 -1
  37. package/shared/core/engine/liuren.ts +32 -13
  38. package/shared/core/engine/liuyao.ts +6 -1
  39. package/shared/core/engine/qimen.ts +102 -60
  40. package/shared/core/engine/trueSolarTime.ts +9 -6
  41. package/shared/core/engine/xiaoliuren.ts +6 -2
  42. package/shared/core/engine/ziwei.ts +4 -3
  43. package/shared/core/types.ts +7 -7
  44. package/src/components/arts/XiaoliurenArt.tsx +1 -1
  45. package/src/pages/DemoPage.tsx +1 -1
  46. package/src/services/api.ts +18 -1
  47. package/src/utils/userStore.ts +6 -2
  48. package/vite.config.ts +7 -3
  49. package/dist/assets/index-BZTUsUN1.js +0 -102
  50. package/dist/assets/index-BZTUsUN1.js.map +0 -1
  51. package/server/src/data/db.json +0 -7226
  52. package/server/src/data/guanwei.db +0 -0
@@ -87,10 +87,10 @@ export interface ZiweiResult {
87
87
  fuStars: Record<string, number>; // 辅星位置(0=寅起)
88
88
  sihua: { lu: string; quan: string; ke: string; ji: string }; // 生年四化星名
89
89
  sihuaPos: { lu?: number; quan?: number; ke?: number; ji?: number }; // 四化落宫位
90
- brightness: Record<string, string>; // 十四主星亮度('庙'|'旺'|'得'|'利'|'平'|'陷')
90
+ brightness: Record<string, string>; // 十四主星亮度('庙'|'旺'|'得'|'利'|'平'|'陷'|'不'(不得地))
91
91
  geju: { key: string; name: string; ji: '吉' | '凶' | '平'; desc: string; why: string }[]; // 格局
92
92
  // ─── 修正层(2026-09-05 算法边界反馈)───
93
- dayNight?: 'day' | 'night'; // 昼生/夜生(按生时:卯~申为昼,酉~寅为夜)
93
+ dayNight?: 'day' | 'night'; // 昼生/夜生(按生时:卯~申为昼,酉~寅为夜;时辰序 0=子)
94
94
  effBrightness?: Record<string, string>; // 昼夜调整后有效亮度(太阳喜昼、太阴喜夜)
95
95
  borrowedStars?: Record<number, string[]>; // 空宫借对宫主星(十二宫位 → 所借主星)
96
96
  }
@@ -101,12 +101,12 @@ export interface QimenResult {
101
101
  yin: boolean; ju: number; jqName: string;
102
102
  dayGZ: string; hourGZ: string;
103
103
  xunShou: string; xunshouName: string;
104
- zfStar: string; zsMen: string; zfPalace: number;
104
+ zfStar: string; zsMen: string; zfPalace: number; // 值符星/值使门/值符转后落宫(入中寄坤=2)
105
105
  pan: Record<number, { yi: string; men: string; star: string }>;
106
- // ─── 补齐层(2026-08-20)───
107
- zsPalace: number; // 值使门落宫(时干加临)
108
- tianYi: Record<number, string>; // 天盘奇仪(暗干)
109
- shen: Record<number, string>; // 八神布宫
106
+ // ─── 补齐层(2026-08-20;2026-09 起转盘五层对齐拆补权威口径)───
107
+ zsPalace: number; // 值使门飞落宫(入中寄坤=2)
108
+ tianYi: Record<number, string>; // 天盘奇仪(地盘旋转,符首→时干宫;中宫原地盘干)
109
+ shen: Record<number, string>; // 八神布宫(阳顺阴逆,值符神落时干宫;阳用勾陈朱雀、阴用白虎玄武)
110
110
  }
111
111
 
112
112
  // 梅花输入输出
@@ -40,7 +40,7 @@ export function XiaoliurenPanel({ onDivine }: PanelProps) {
40
40
  </div>
41
41
  )}
42
42
  <div className="field"><label htmlFor="xlr-h">时(时辰序)</label>
43
- <SongSelect id="xlr-h" value={String(h)} options={['子(1)', '丑(2)', '寅(3)', '卯(4)', '辰(5)', '巳(6)', '午(7)', '未(8)', '申(9)', '酉(10)', '戌(11)', '亥(12)'].map((t, i) => ({ value: String(i + 1), label: t }))} onChange={v => setH(Number(v))} />
43
+ <SongSelect id="xlr-h" value={String(h)} options={['子(0)', '丑(1)', '寅(2)', '卯(3)', '辰(4)', '巳(5)', '午(6)', '未(7)', '申(8)', '酉(9)', '戌(10)', '亥(11)'].map((t, i) => ({ value: String(i), label: t }))} onChange={v => setH(Number(v))} />
44
44
  </div>
45
45
  {mode === 'num' && (
46
46
  <div className="field"><label htmlFor="xlr-n3">三数</label><input className="input-line" type="number" id="xlr-n3" min={1} max={12} value={n3} onChange={e => setN3(Number(e.target.value))} /></div>
@@ -84,7 +84,7 @@ export default function DemoPage() {
84
84
  case 'meihua': return () => meihuaCalc({ mode: 'number', n1, n2, n3, now: new Date() } as any);
85
85
  case 'liuyao': return () => liuyaoCalc(undefined, { y, m, d });
86
86
  case 'liuren': return () => liurenCalc(new Date(y, m - 1, d, hour, 0));
87
- case 'xiaoliuren': return () => xiaoliurenCalc('time', m, d, Math.floor((hour % 24) / 2), n1, n2, n3);
87
+ case 'xiaoliuren': return () => xiaoliurenCalc('time', m, d, Math.floor(((hour % 24) + 1) % 24 / 2), n1, n2, n3);
88
88
  case 'tarot': return () => {
89
89
  const spread = allTarotSpreads().find((x: any) => x.id === 'three') || allTarotSpreads()[0];
90
90
  return { spread, cards: tarotDraw(3) };
@@ -264,7 +264,24 @@ export async function apiDivine(username: string, artId: string, inputs: unknown
264
264
  try { const e = await res.json(); msg = e.message || e.error || msg; } catch { /* ignore */ }
265
265
  throw new Error(msg);
266
266
  }
267
- return res.json();
267
+ const data = await res.json();
268
+ // L-NEW1 闭环:后端在「本次新建占位账号」时下发 claimToken(仅此一次),
269
+ // 保存到本地,供之后在 app 内注册时升级该占位账号(否则注册接口拒绝、拿不到云同步 token)
270
+ if (data?.claimToken) saveClaimToken(username, String(data.claimToken));
271
+ return data;
272
+ }
273
+
274
+ const CLAIM_KEY = (name: string) => 'guanwei_claim_' + name;
275
+
276
+ /** 保存/读取占位账号认领凭据(仅本地持有,随注册一次性使用) */
277
+ export function saveClaimToken(username: string, token: string): void {
278
+ try { localStorage.setItem(CLAIM_KEY(username), token); } catch { /* ignore */ }
279
+ }
280
+ export function claimTokenOf(username: string): string {
281
+ try { return localStorage.getItem(CLAIM_KEY(username)) || ''; } catch { return ''; }
282
+ }
283
+ export function clearClaimToken(username: string): void {
284
+ try { localStorage.removeItem(CLAIM_KEY(username)); } catch { /* ignore */ }
268
285
  }
269
286
 
270
287
  export interface DivineHistoryItem {
@@ -1,6 +1,7 @@
1
1
  // 本地用户体系(演示级):注册/登录/会话/出生档案
2
2
  // 注意:仅本地存储(localStorage),密码为演示级哈希,不适用于生产环境
3
3
  import type { GeoLocation } from '@core/types';
4
+ import { claimTokenOf, clearClaimToken } from '../services/api';
4
5
 
5
6
  export interface UserProfile {
6
7
  birthDate: string; // YYYY-MM-DD(公历)
@@ -142,13 +143,16 @@ async function fetchServerToken(username: string, password: string): Promise<voi
142
143
  body: JSON.stringify({ username, password }),
143
144
  });
144
145
  if (!res.ok) {
145
- // 后端无此用户 → 注册(自动建档即可;注册接口对已有用户返回 400)
146
+ // 后端无此用户 → 注册;若该名号已被「起占自动建档」占位,须携带建档时下发的 claimToken 方可升级
147
+ // (claimToken 由起占响应下发并由 services/api 落地本地,见 L-NEW1 闭环)
148
+ const claimToken = claimTokenOf(username);
146
149
  res = await fetch(API + '/register', {
147
150
  method: 'POST',
148
151
  headers: { 'Content-Type': 'application/json' },
149
- body: JSON.stringify({ username, password }),
152
+ body: JSON.stringify({ username, password, ...(claimToken ? { claimToken } : {}) }),
150
153
  });
151
154
  if (!res.ok) return;
155
+ clearClaimToken(username); // 一次性凭据,成功升级后即弃
152
156
  }
153
157
  const data = await res.json();
154
158
  if (data.token) {
package/vite.config.ts CHANGED
@@ -3,17 +3,21 @@ import react from '@vitejs/plugin-react'
3
3
  import tsconfigPaths from "vite-tsconfig-paths";
4
4
 
5
5
  // https://vite.dev/config/
6
+ // 后端地址:跟随 CLI 的 PORT/API_PORT(`guanwei start --api 4000` 时前端代理需同步)
7
+ const API_TARGET = `http://localhost:${process.env.API_PORT || process.env.PORT || 3018}`;
8
+
6
9
  export default defineConfig({
7
10
  test: {
8
11
  environment: 'jsdom',
9
12
  },
10
13
  build: {
11
- sourcemap: 'hidden',
14
+ // 生产不产出 sourcemap(原 'hidden' 仍生成 .map 文件,随 npm 包分发且可被公开访问 → 源码泄漏)
15
+ sourcemap: false,
12
16
  },
13
17
  server: {
14
18
  proxy: {
15
19
  '/api': {
16
- target: 'http://localhost:3018',
20
+ target: API_TARGET,
17
21
  changeOrigin: true,
18
22
  },
19
23
  },
@@ -22,7 +26,7 @@ export default defineConfig({
22
26
  preview: {
23
27
  proxy: {
24
28
  '/api': {
25
- target: 'http://localhost:3018',
29
+ target: API_TARGET,
26
30
  changeOrigin: true,
27
31
  },
28
32
  },