@geminilight/mindos 0.5.46 → 0.5.48

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 CHANGED
@@ -16,7 +16,6 @@
16
16
  <a href="https://tianfuwang.tech/MindOS"><img src="https://img.shields.io/badge/Website-MindOS-0ea5e9.svg?style=for-the-badge" alt="Website"></a>
17
17
  <a href="https://www.npmjs.com/package/@geminilight/mindos"><img src="https://img.shields.io/npm/v/@geminilight/mindos.svg?style=for-the-badge&color=f59e0b" alt="npm version"></a>
18
18
  <a href="https://www.npmjs.com/package/@geminilight/mindos"><img src="https://img.shields.io/npm/dw/@geminilight/mindos.svg?style=for-the-badge&color=10b981" alt="npm downloads"></a>
19
- <a href="https://github.com/GeminiLight/MindOS/stargazers"><img src="https://img.shields.io/github/stars/GeminiLight/MindOS.svg?style=for-the-badge&color=f59e0b" alt="GitHub Stars"></a>
20
19
  <a href="#wechat"><img src="https://img.shields.io/badge/WeChat-Group-07C160.svg?style=for-the-badge&logo=wechat&logoColor=white" alt="WeChat"></a>
21
20
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-6366f1.svg?style=for-the-badge" alt="MIT License"></a>
22
21
  </p>
@@ -274,6 +273,8 @@ Join our WeChat group for early access, feedback, and AI workflow discussions:
274
273
 
275
274
  <a href="https://github.com/GeminiLight"><img src="https://github.com/GeminiLight.png" width="60" style="border-radius:50%" alt="GeminiLight" /></a>
276
275
  <a href="https://github.com/yeahjack"><img src="https://github.com/yeahjack.png" width="60" style="border-radius:50%" alt="yeahjack" /></a>
276
+ <a href="https://github.com/USTChandsomeboy"><img src="https://github.com/USTChandsomeboy.png" width="60" style="border-radius:50%" alt="USTChandsomeboy" /></a>
277
+ <a href="https://github.com/ppsmk388"><img src="https://github.com/ppsmk388.png" width="60" style="border-radius:50%" alt="ppsmk388" /></a>
277
278
 
278
279
  ---
279
280
 
package/README_zh.md CHANGED
@@ -16,7 +16,6 @@
16
16
  <a href="https://tianfuwang.tech/MindOS"><img src="https://img.shields.io/badge/Website-MindOS-0ea5e9.svg?style=for-the-badge" alt="Website"></a>
17
17
  <a href="https://www.npmjs.com/package/@geminilight/mindos"><img src="https://img.shields.io/npm/v/@geminilight/mindos.svg?style=for-the-badge&color=f59e0b" alt="npm version"></a>
18
18
  <a href="https://www.npmjs.com/package/@geminilight/mindos"><img src="https://img.shields.io/npm/dw/@geminilight/mindos.svg?style=for-the-badge&color=10b981" alt="npm downloads"></a>
19
- <a href="https://github.com/GeminiLight/MindOS/stargazers"><img src="https://img.shields.io/github/stars/GeminiLight/MindOS.svg?style=for-the-badge&color=f59e0b" alt="GitHub Stars"></a>
20
19
  <a href="#wechat"><img src="https://img.shields.io/badge/WeChat-群聊-07C160.svg?style=for-the-badge&logo=wechat&logoColor=white" alt="WeChat"></a>
21
20
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-6366f1.svg?style=for-the-badge" alt="MIT License"></a>
22
21
  </p>
@@ -274,6 +273,8 @@ MindOS/
274
273
 
275
274
  <a href="https://github.com/GeminiLight"><img src="https://github.com/GeminiLight.png" width="60" style="border-radius:50%" alt="GeminiLight" /></a>
276
275
  <a href="https://github.com/yeahjack"><img src="https://github.com/yeahjack.png" width="60" style="border-radius:50%" alt="yeahjack" /></a>
276
+ <a href="https://github.com/USTChandsomeboy"><img src="https://github.com/USTChandsomeboy.png" width="60" style="border-radius:50%" alt="USTChandsomeboy" /></a>
277
+ <a href="https://github.com/ppsmk388"><img src="https://github.com/ppsmk388.png" width="60" style="border-radius:50%" alt="ppsmk388" /></a>
277
278
 
278
279
  ---
279
280
 
@@ -23,7 +23,15 @@ export default function UpdateBanner() {
23
23
  const timer = setTimeout(async () => {
24
24
  try {
25
25
  const data = await apiFetch<{ hasUpdate: boolean; latest: string; current: string }>('/api/update-check');
26
- if (!data.hasUpdate) return;
26
+ if (!data.hasUpdate) {
27
+ // Clean up stale badge state from a previous update cycle
28
+ if (localStorage.getItem('mindos_update_latest')) {
29
+ localStorage.removeItem('mindos_update_latest');
30
+ localStorage.removeItem('mindos_update_dismissed');
31
+ window.dispatchEvent(new Event('mindos:update-dismissed'));
32
+ }
33
+ return;
34
+ }
27
35
 
28
36
  const dismissed = localStorage.getItem('mindos_update_dismissed');
29
37
  if (data.latest === dismissed) return;
@@ -58,6 +58,7 @@ export function UpdateTab() {
58
58
  const [errorMsg, setErrorMsg] = useState('');
59
59
  const [stages, setStages] = useState<StageInfo[]>([]);
60
60
  const [updateError, setUpdateError] = useState<string | null>(null);
61
+ const [serverDown, setServerDown] = useState(false);
61
62
  const pollRef = useRef<ReturnType<typeof setInterval>>(undefined);
62
63
  const timeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);
63
64
  const originalVersion = useRef<string>('');
@@ -83,12 +84,24 @@ export function UpdateTab() {
83
84
  clearTimeout(timeoutRef.current);
84
85
  }, []);
85
86
 
87
+ /** Mark update complete: clear badge, set state, schedule reload. */
88
+ const completeUpdate = useCallback((data: UpdateInfo) => {
89
+ cleanup();
90
+ setInfo(data);
91
+ setState('updated');
92
+ localStorage.removeItem('mindos_update_latest');
93
+ localStorage.removeItem('mindos_update_dismissed');
94
+ window.dispatchEvent(new Event('mindos:update-dismissed'));
95
+ setTimeout(() => window.location.reload(), 2000);
96
+ }, [cleanup]);
97
+
86
98
  useEffect(() => cleanup, [cleanup]);
87
99
 
88
100
  const handleUpdate = useCallback(async () => {
89
101
  setState('updating');
90
102
  setErrorMsg('');
91
103
  setUpdateError(null);
104
+ setServerDown(false);
92
105
  setStages([
93
106
  { id: 'downloading', status: 'pending' },
94
107
  { id: 'skills', status: 'pending' },
@@ -107,6 +120,7 @@ export function UpdateTab() {
107
120
  // Try status endpoint first (may fail when server is restarting)
108
121
  try {
109
122
  const status = await apiFetch<UpdateStatus>('/api/update-status', { timeout: 5000 });
123
+ setServerDown(false);
110
124
 
111
125
  if (status.stages?.length > 0) {
112
126
  setStages(status.stages);
@@ -124,24 +138,19 @@ export function UpdateTab() {
124
138
  try {
125
139
  const data = await apiFetch<UpdateInfo>('/api/update-check');
126
140
  if (data.current !== originalVersion.current) {
127
- cleanup();
128
- setInfo(data);
129
- setState('updated');
130
- setTimeout(() => window.location.reload(), 2000);
141
+ completeUpdate(data);
131
142
  return;
132
143
  }
133
144
  } catch { /* new server may not be fully ready */ }
134
145
  }
135
146
  } catch {
136
147
  // Server restarting — also try update-check as fallback
148
+ setServerDown(true);
137
149
  try {
138
150
  const data = await apiFetch<UpdateInfo>('/api/update-check', { timeout: 5000 });
139
151
  if (data.current !== originalVersion.current) {
140
- cleanup();
141
152
  setStages(prev => prev.map(s => ({ ...s, status: 'done' as const })));
142
- setInfo(data);
143
- setState('updated');
144
- setTimeout(() => window.location.reload(), 2000);
153
+ completeUpdate(data);
145
154
  }
146
155
  } catch {
147
156
  // Both endpoints down — server still restarting
@@ -153,7 +162,7 @@ export function UpdateTab() {
153
162
  cleanup();
154
163
  setState('timeout');
155
164
  }, POLL_TIMEOUT);
156
- }, [cleanup]);
165
+ }, [cleanup, completeUpdate]);
157
166
 
158
167
  const handleRetry = useCallback(() => {
159
168
  setUpdateError(null);
@@ -219,7 +228,9 @@ export function UpdateTab() {
219
228
  </div>
220
229
 
221
230
  <p className="text-2xs text-muted-foreground">
222
- {u?.updatingHint ?? 'This may take 1–3 minutes. Do not close this page.'}
231
+ {serverDown
232
+ ? (u?.serverRestarting ?? 'Server is restarting, please wait...')
233
+ : (u?.updatingHint ?? 'This may take 1–3 minutes. Do not close this page.')}
223
234
  </p>
224
235
  </div>
225
236
  )}
@@ -446,6 +446,7 @@ export const en = {
446
446
  available: (current: string, latest: string) => `Update available: v${current} → v${latest}`,
447
447
  updating: 'Updating MindOS... The server will restart shortly.',
448
448
  updatingHint: 'This may take 1–3 minutes. Do not close this page.',
449
+ serverRestarting: 'Server is restarting, please wait...',
449
450
  updated: 'Updated successfully! Reloading...',
450
451
  timeout: 'Update may still be in progress.',
451
452
  timeoutHint: 'The server may need more time to rebuild. Try refreshing.',
@@ -471,6 +471,7 @@ export const zh = {
471
471
  available: (current: string, latest: string) => `有新版本可用:v${current} → v${latest}`,
472
472
  updating: '正在更新 MindOS,服务器即将重启...',
473
473
  updatingHint: '预计 1–3 分钟,请勿关闭此页面。',
474
+ serverRestarting: '服务正在重启,请稍候...',
474
475
  updated: '更新成功!正在刷新...',
475
476
  timeout: '更新可能仍在进行中。',
476
477
  timeoutHint: '服务器可能需要更多时间重新构建,请尝试刷新页面。',
package/app/next-env.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types="next" />
2
2
  /// <reference types="next/image-types/global" />
3
- import "./.next/dev/types/routes.d.ts";
3
+ import "./.next/types/routes.d.ts";
4
4
 
5
5
  // NOTE: This file should not be edited
6
6
  // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
@@ -9,36 +9,19 @@ const STAGE_ORDER = ['downloading', 'skills', 'rebuilding', 'restarting'];
9
9
  /**
10
10
  * Write update progress to ~/.mindos/update-status.json.
11
11
  *
12
- * @param {'downloading'|'skills'|'rebuilding'|'restarting'|'done'|'failed'} stage
12
+ * @param {'downloading'|'skills'|'rebuilding'|'restarting'|'done'} stage
13
13
  * @param {{ error?: string, fromVersion?: string, toVersion?: string }} [opts]
14
14
  */
15
15
  export function writeUpdateStatus(stage, opts = {}) {
16
16
  const stages = STAGE_ORDER.map((id) => {
17
17
  const idx = STAGE_ORDER.indexOf(id);
18
18
  const currentIdx = STAGE_ORDER.indexOf(stage);
19
- let status = 'pending';
20
- if (stage === 'done' || stage === 'failed') {
21
- // done: all stages done; failed: stages up to current are done, current is failed
22
- if (stage === 'done') {
23
- status = 'done';
24
- } else {
25
- // For 'failed', we don't know which stage failed from just 'failed'
26
- // So we keep whatever was last written — this function is called per-stage
27
- status = 'pending';
28
- }
29
- } else if (idx < currentIdx) {
30
- status = 'done';
31
- } else if (idx === currentIdx) {
32
- status = 'running';
33
- }
34
- return { id, status };
19
+ if (stage === 'done') return { id, status: 'done' };
20
+ if (idx < currentIdx) return { id, status: 'done' };
21
+ if (idx === currentIdx) return { id, status: 'running' };
22
+ return { id, status: 'pending' };
35
23
  });
36
24
 
37
- // For 'done', mark all as done
38
- if (stage === 'done') {
39
- stages.forEach((s) => { s.status = 'done'; });
40
- }
41
-
42
25
  const data = {
43
26
  stage,
44
27
  stages,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geminilight/mindos",
3
- "version": "0.5.46",
3
+ "version": "0.5.48",
4
4
  "description": "MindOS — Human-Agent Collaborative Mind System. Local-first knowledge base that syncs your mind to all AI Agents via MCP.",
5
5
  "keywords": [
6
6
  "mindos",