@geminilight/mindos 0.5.51 → 0.5.54
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 +7 -7
- package/README_zh.md +5 -5
- package/app/app/layout.tsx +2 -0
- package/app/components/ActivityBar.tsx +3 -2
- package/app/components/Panel.tsx +1 -0
- package/app/components/RightAgentDetailPanel.tsx +121 -0
- package/app/components/SidebarLayout.tsx +62 -5
- package/app/components/UpdateOverlay.tsx +124 -0
- package/app/components/help/HelpContent.tsx +10 -7
- package/app/components/panels/AgentsPanel.tsx +156 -178
- package/app/components/panels/AgentsPanelAgentDetail.tsx +193 -0
- package/app/components/panels/AgentsPanelAgentGroups.tsx +116 -0
- package/app/components/panels/AgentsPanelAgentListRow.tsx +101 -0
- package/app/components/panels/AgentsPanelHubNav.tsx +48 -0
- package/app/components/panels/DiscoverPanel.tsx +6 -46
- package/app/components/panels/EchoPanel.tsx +82 -0
- package/app/components/panels/PanelNavRow.tsx +51 -0
- package/app/components/panels/agents-panel-resolve-status.ts +13 -0
- package/app/components/settings/McpSkillsSection.tsx +88 -2
- package/app/components/settings/McpTab.tsx +26 -0
- package/app/components/settings/UpdateTab.tsx +65 -27
- package/app/lib/i18n-en.ts +31 -2
- package/app/lib/i18n-zh.ts +30 -2
- package/app/next-env.d.ts +1 -1
- package/package.json +1 -1
|
@@ -29,6 +29,7 @@ type UpdateState = 'idle' | 'checking' | 'updating' | 'updated' | 'error' | 'tim
|
|
|
29
29
|
const CHANGELOG_URL = 'https://github.com/GeminiLight/MindOS/releases';
|
|
30
30
|
const POLL_INTERVAL = 3_000;
|
|
31
31
|
const POLL_TIMEOUT = 5 * 60 * 1000; // 5 minutes
|
|
32
|
+
const UPDATE_STATE_KEY = 'mindos_update_in_progress';
|
|
32
33
|
|
|
33
34
|
const STAGE_LABELS: Record<string, { en: string; zh: string }> = {
|
|
34
35
|
downloading: { en: 'Downloading update', zh: '下载更新' },
|
|
@@ -77,8 +78,6 @@ export function UpdateTab() {
|
|
|
77
78
|
}
|
|
78
79
|
}, [u]);
|
|
79
80
|
|
|
80
|
-
useEffect(() => { checkUpdate(); }, [checkUpdate]);
|
|
81
|
-
|
|
82
81
|
const cleanup = useCallback(() => {
|
|
83
82
|
clearInterval(pollRef.current);
|
|
84
83
|
clearTimeout(timeoutRef.current);
|
|
@@ -91,33 +90,14 @@ export function UpdateTab() {
|
|
|
91
90
|
setState('updated');
|
|
92
91
|
localStorage.removeItem('mindos_update_latest');
|
|
93
92
|
localStorage.removeItem('mindos_update_dismissed');
|
|
93
|
+
localStorage.removeItem(UPDATE_STATE_KEY);
|
|
94
94
|
window.dispatchEvent(new Event('mindos:update-dismissed'));
|
|
95
95
|
setTimeout(() => window.location.reload(), 2000);
|
|
96
96
|
}, [cleanup]);
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const handleUpdate = useCallback(async () => {
|
|
101
|
-
setState('updating');
|
|
102
|
-
setErrorMsg('');
|
|
103
|
-
setUpdateError(null);
|
|
104
|
-
setServerDown(false);
|
|
105
|
-
setStages([
|
|
106
|
-
{ id: 'downloading', status: 'pending' },
|
|
107
|
-
{ id: 'skills', status: 'pending' },
|
|
108
|
-
{ id: 'rebuilding', status: 'pending' },
|
|
109
|
-
{ id: 'restarting', status: 'pending' },
|
|
110
|
-
]);
|
|
111
|
-
|
|
112
|
-
try {
|
|
113
|
-
await apiFetch('/api/update', { method: 'POST' });
|
|
114
|
-
} catch {
|
|
115
|
-
// Expected — server may die during update
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Poll update-status for stage progress
|
|
98
|
+
/** Start polling for update progress */
|
|
99
|
+
const startPolling = useCallback(() => {
|
|
119
100
|
pollRef.current = setInterval(async () => {
|
|
120
|
-
// Try status endpoint first (may fail when server is restarting)
|
|
121
101
|
try {
|
|
122
102
|
const status = await apiFetch<UpdateStatus>('/api/update-status', { timeout: 5000 });
|
|
123
103
|
setServerDown(false);
|
|
@@ -128,13 +108,13 @@ export function UpdateTab() {
|
|
|
128
108
|
|
|
129
109
|
if (status.stage === 'failed') {
|
|
130
110
|
cleanup();
|
|
111
|
+
localStorage.removeItem(UPDATE_STATE_KEY);
|
|
131
112
|
setUpdateError(status.error || 'Update failed');
|
|
132
113
|
setState('error');
|
|
133
114
|
return;
|
|
134
115
|
}
|
|
135
116
|
|
|
136
117
|
if (status.stage === 'done') {
|
|
137
|
-
// Verify version actually changed
|
|
138
118
|
try {
|
|
139
119
|
const data = await apiFetch<UpdateInfo>('/api/update-check');
|
|
140
120
|
if (data.current !== originalVersion.current) {
|
|
@@ -144,11 +124,11 @@ export function UpdateTab() {
|
|
|
144
124
|
} catch { /* new server may not be fully ready */ }
|
|
145
125
|
}
|
|
146
126
|
} catch {
|
|
147
|
-
// Server restarting —
|
|
127
|
+
// Server restarting — try update-check as fallback
|
|
148
128
|
setServerDown(true);
|
|
149
129
|
try {
|
|
150
130
|
const data = await apiFetch<UpdateInfo>('/api/update-check', { timeout: 5000 });
|
|
151
|
-
if (data.current !== originalVersion.current) {
|
|
131
|
+
if (data.current && data.current !== originalVersion.current) {
|
|
152
132
|
setStages(prev => prev.map(s => ({ ...s, status: 'done' as const })));
|
|
153
133
|
completeUpdate(data);
|
|
154
134
|
}
|
|
@@ -160,10 +140,68 @@ export function UpdateTab() {
|
|
|
160
140
|
|
|
161
141
|
timeoutRef.current = setTimeout(() => {
|
|
162
142
|
cleanup();
|
|
143
|
+
localStorage.removeItem(UPDATE_STATE_KEY);
|
|
163
144
|
setState('timeout');
|
|
164
145
|
}, POLL_TIMEOUT);
|
|
165
146
|
}, [cleanup, completeUpdate]);
|
|
166
147
|
|
|
148
|
+
// On mount: check if an update was in progress (survives page reload / white screen)
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
const savedState = localStorage.getItem(UPDATE_STATE_KEY);
|
|
151
|
+
if (savedState) {
|
|
152
|
+
try {
|
|
153
|
+
const { originalVer } = JSON.parse(savedState);
|
|
154
|
+
originalVersion.current = originalVer;
|
|
155
|
+
setState('updating');
|
|
156
|
+
setServerDown(true);
|
|
157
|
+
setStages([
|
|
158
|
+
{ id: 'downloading', status: 'done' },
|
|
159
|
+
{ id: 'skills', status: 'done' },
|
|
160
|
+
{ id: 'rebuilding', status: 'done' },
|
|
161
|
+
{ id: 'restarting', status: 'running' },
|
|
162
|
+
]);
|
|
163
|
+
startPolling();
|
|
164
|
+
} catch {
|
|
165
|
+
localStorage.removeItem(UPDATE_STATE_KEY);
|
|
166
|
+
checkUpdate();
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
checkUpdate();
|
|
170
|
+
}
|
|
171
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
172
|
+
}, []);
|
|
173
|
+
|
|
174
|
+
useEffect(() => cleanup, [cleanup]);
|
|
175
|
+
|
|
176
|
+
const handleUpdate = useCallback(async () => {
|
|
177
|
+
setState('updating');
|
|
178
|
+
setErrorMsg('');
|
|
179
|
+
setUpdateError(null);
|
|
180
|
+
setServerDown(false);
|
|
181
|
+
setStages([
|
|
182
|
+
{ id: 'downloading', status: 'pending' },
|
|
183
|
+
{ id: 'skills', status: 'pending' },
|
|
184
|
+
{ id: 'rebuilding', status: 'pending' },
|
|
185
|
+
{ id: 'restarting', status: 'pending' },
|
|
186
|
+
]);
|
|
187
|
+
|
|
188
|
+
// Persist update state to localStorage — survives process restart / page reload
|
|
189
|
+
localStorage.setItem(UPDATE_STATE_KEY, JSON.stringify({
|
|
190
|
+
originalVer: originalVersion.current || info?.current,
|
|
191
|
+
startedAt: Date.now(),
|
|
192
|
+
}));
|
|
193
|
+
// Notify UpdateOverlay (same-tab, storage event doesn't fire for same-tab writes)
|
|
194
|
+
window.dispatchEvent(new Event('mindos:update-started'));
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
await apiFetch('/api/update', { method: 'POST' });
|
|
198
|
+
} catch {
|
|
199
|
+
// Expected — server may die during update
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
startPolling();
|
|
203
|
+
}, [startPolling, info]);
|
|
204
|
+
|
|
167
205
|
const handleRetry = useCallback(() => {
|
|
168
206
|
setUpdateError(null);
|
|
169
207
|
handleUpdate();
|
package/app/lib/i18n-en.ts
CHANGED
|
@@ -59,6 +59,7 @@ export const en = {
|
|
|
59
59
|
settingsTitle: 'Settings',
|
|
60
60
|
plugins: 'Plugins',
|
|
61
61
|
agents: 'Agents',
|
|
62
|
+
echo: 'Echo',
|
|
62
63
|
discover: 'Discover',
|
|
63
64
|
help: 'Help',
|
|
64
65
|
syncLabel: 'Sync',
|
|
@@ -148,6 +149,18 @@ export const en = {
|
|
|
148
149
|
newSkill: '+ New',
|
|
149
150
|
// Footer
|
|
150
151
|
advancedConfig: 'Advanced Config →',
|
|
152
|
+
// Hub nav (aligned with Discover panel rows)
|
|
153
|
+
navOverview: 'Overview',
|
|
154
|
+
navMcp: 'MCP',
|
|
155
|
+
navSkills: 'Skills',
|
|
156
|
+
rosterLabel: 'Your setup',
|
|
157
|
+
notFoundDetail: 'This agent app was not detected on this machine. Install it, then refresh the list.',
|
|
158
|
+
skillsEmptyHint: 'Enable and edit skills in MCP & Skills settings.',
|
|
159
|
+
backToList: 'Back',
|
|
160
|
+
closeAgentDetail: 'Close',
|
|
161
|
+
agentDetailPanelAria: 'Agent connection configuration',
|
|
162
|
+
agentDetailTransport: 'Transport',
|
|
163
|
+
agentDetailSnippet: 'Config snippet',
|
|
151
164
|
},
|
|
152
165
|
plugins: {
|
|
153
166
|
title: 'Plugins',
|
|
@@ -161,6 +174,20 @@ export const en = {
|
|
|
161
174
|
noFile: 'Entry file not found',
|
|
162
175
|
createFile: 'Create {file} to activate',
|
|
163
176
|
},
|
|
177
|
+
echo: {
|
|
178
|
+
title: 'Echo',
|
|
179
|
+
aboutYouTitle: 'Tied to you',
|
|
180
|
+
aboutYouHint: 'Paths and links in your library that curve back to your name.',
|
|
181
|
+
continuedTitle: 'Still open',
|
|
182
|
+
continuedHint: 'Drafts, half-written lines, todos you never closed.',
|
|
183
|
+
dailyEchoTitle: 'Daily echo',
|
|
184
|
+
dailyEchoHint: 'One quiet line for today—no need to open a full chat.',
|
|
185
|
+
pastYouTitle: 'Who you were',
|
|
186
|
+
pastYouHint: 'Choices and moods you set down at another point on the timeline.',
|
|
187
|
+
intentGrowthTitle: 'Heart & growth',
|
|
188
|
+
intentGrowthHint: 'What you are steering toward, and how it slowly shifts. Stays on device; you can wipe it anytime.',
|
|
189
|
+
comingSoon: 'On its way',
|
|
190
|
+
},
|
|
164
191
|
discover: {
|
|
165
192
|
title: 'Discover',
|
|
166
193
|
useCases: 'Use Cases',
|
|
@@ -352,6 +379,8 @@ export const en = {
|
|
|
352
379
|
skillBuiltin: 'Built-in',
|
|
353
380
|
skillUser: 'Custom',
|
|
354
381
|
addSkill: '+ Add Skill',
|
|
382
|
+
cliInstallHint: 'Install via CLI:',
|
|
383
|
+
skillPathHint: 'Skill files installed at:',
|
|
355
384
|
deleteSkill: 'Delete',
|
|
356
385
|
editSkill: 'Edit',
|
|
357
386
|
saveSkill: 'Save',
|
|
@@ -700,7 +729,7 @@ export const en = {
|
|
|
700
729
|
c1: {
|
|
701
730
|
title: 'Inject Your Identity',
|
|
702
731
|
desc: 'Tell all AI agents who you are — preferences, tech stack, communication style — in one shot.',
|
|
703
|
-
|
|
732
|
+
prompt: "Here's my resume, read it and organize my info into MindOS.",
|
|
704
733
|
},
|
|
705
734
|
c2: {
|
|
706
735
|
title: 'Save Information',
|
|
@@ -803,7 +832,7 @@ export const en = {
|
|
|
803
832
|
title: 'Using MindOS with AI Agents',
|
|
804
833
|
intro: 'Once you connect an agent (Claude Code, Cursor, Windsurf, etc.) via MCP, just talk to it naturally. The agent can read and write your knowledge base directly — no special commands needed. Here are the most common scenarios:',
|
|
805
834
|
scenarios: [
|
|
806
|
-
{ emoji: '🪪', title: 'Inject Your Identity', desc: 'Tell all AI agents who you are — preferences, tech stack, communication style — in one shot.', prompt:
|
|
835
|
+
{ emoji: '🪪', title: 'Inject Your Identity', desc: 'Tell all AI agents who you are — preferences, tech stack, communication style — in one shot.', prompt: "\"Here's my resume, read it and organize my info into MindOS.\"" },
|
|
807
836
|
{ emoji: '🔄', title: 'Cross-Agent Handoff', desc: 'Brainstorm ideas in GPT, then execute in Claude Code — zero context loss.', prompt: '"Save this conversation to MindOS."\n"Read the plan in MindOS and help me start coding."' },
|
|
808
837
|
{ emoji: '📋', title: 'Experience → SOP', desc: 'Turn hard-won debugging sessions into reusable workflows that prevent future mistakes.', prompt: '"Help me distill this conversation into a reusable workflow in MindOS."' },
|
|
809
838
|
{ emoji: '🚀', title: 'Project Cold Start', desc: 'Spin up a new project in minutes — your profile and SOPs guide the scaffolding automatically.', prompt: '"Help me start a new project following the Startup SOP in MindOS."' },
|
package/app/lib/i18n-zh.ts
CHANGED
|
@@ -84,6 +84,7 @@ export const zh = {
|
|
|
84
84
|
settingsTitle: '设置',
|
|
85
85
|
plugins: '插件',
|
|
86
86
|
agents: '智能体',
|
|
87
|
+
echo: '回响',
|
|
87
88
|
discover: '探索',
|
|
88
89
|
help: '帮助',
|
|
89
90
|
syncLabel: '同步',
|
|
@@ -173,6 +174,17 @@ export const zh = {
|
|
|
173
174
|
newSkill: '+ 新建',
|
|
174
175
|
// Footer
|
|
175
176
|
advancedConfig: '高级配置 →',
|
|
177
|
+
navOverview: '总览',
|
|
178
|
+
navMcp: 'MCP',
|
|
179
|
+
navSkills: '技能',
|
|
180
|
+
rosterLabel: '当前环境',
|
|
181
|
+
notFoundDetail: '本机未检测到该智能体客户端。请安装后刷新列表。',
|
|
182
|
+
skillsEmptyHint: '请在「MCP 与技能」设置中启用或编辑 Skills。',
|
|
183
|
+
backToList: '返回',
|
|
184
|
+
closeAgentDetail: '关闭',
|
|
185
|
+
agentDetailPanelAria: '智能体连接配置',
|
|
186
|
+
agentDetailTransport: '传输方式',
|
|
187
|
+
agentDetailSnippet: '配置片段',
|
|
176
188
|
},
|
|
177
189
|
plugins: {
|
|
178
190
|
title: '插件',
|
|
@@ -186,6 +198,20 @@ export const zh = {
|
|
|
186
198
|
noFile: '入口文件不存在',
|
|
187
199
|
createFile: '创建 {file} 以激活',
|
|
188
200
|
},
|
|
201
|
+
echo: {
|
|
202
|
+
title: '回响',
|
|
203
|
+
aboutYouTitle: '与你有关',
|
|
204
|
+
aboutYouHint: '路径与链接里,绕回你名下的那几笔。',
|
|
205
|
+
continuedTitle: '未完待续',
|
|
206
|
+
continuedHint: '草稿、写到一半的句子、没收口的待办。',
|
|
207
|
+
dailyEchoTitle: '每日回响',
|
|
208
|
+
dailyEchoHint: '给今天留一行空白;轻到不必为此开一场对话。',
|
|
209
|
+
pastYouTitle: '历史的你',
|
|
210
|
+
pastYouHint: '在另一个时间刻度上,你写下的选择与心情。',
|
|
211
|
+
intentGrowthTitle: '心向生长',
|
|
212
|
+
intentGrowthHint: '你在推的方向,以及它怎样慢慢偏转。只存本机,可随时清空。',
|
|
213
|
+
comingSoon: '随后到来',
|
|
214
|
+
},
|
|
189
215
|
discover: {
|
|
190
216
|
title: '探索',
|
|
191
217
|
useCases: '使用案例',
|
|
@@ -377,6 +403,8 @@ export const zh = {
|
|
|
377
403
|
skillBuiltin: '内置',
|
|
378
404
|
skillUser: '自定义',
|
|
379
405
|
addSkill: '+ 添加 Skill',
|
|
406
|
+
cliInstallHint: '通过命令行安装:',
|
|
407
|
+
skillPathHint: 'Skill 文件安装路径:',
|
|
380
408
|
deleteSkill: '删除',
|
|
381
409
|
editSkill: '编辑',
|
|
382
410
|
saveSkill: '保存',
|
|
@@ -725,7 +753,7 @@ export const zh = {
|
|
|
725
753
|
c1: {
|
|
726
754
|
title: '注入身份',
|
|
727
755
|
desc: '让所有 AI Agent 一次认识你 — 偏好、技术栈、沟通风格。',
|
|
728
|
-
|
|
756
|
+
prompt: '这是我的简历,读一下,把我的信息整理到 MindOS 里。',
|
|
729
757
|
},
|
|
730
758
|
c2: {
|
|
731
759
|
title: '注入信息',
|
|
@@ -828,7 +856,7 @@ export const zh = {
|
|
|
828
856
|
title: '在 AI Agent 中使用 MindOS',
|
|
829
857
|
intro: '通过 MCP 连接 Agent(Claude Code、Cursor、Windsurf 等)后,直接用自然语言对话即可。Agent 能自动读写你的知识库,不需要特殊指令。以下是最常见的使用场景:',
|
|
830
858
|
scenarios: [
|
|
831
|
-
{ emoji: '🪪', title: '注入身份', desc: '让所有 AI Agent 一次认识你——偏好、技术栈、沟通风格。', prompt: '"
|
|
859
|
+
{ emoji: '🪪', title: '注入身份', desc: '让所有 AI Agent 一次认识你——偏好、技术栈、沟通风格。', prompt: '"这是我的简历,读一下,把我的信息整理到 MindOS 里。"' },
|
|
832
860
|
{ emoji: '🔄', title: '跨 Agent 切换', desc: '在 GPT 里聊想法,到 Claude Code 去执行——上下文零丢失。', prompt: '"帮我把刚才的对话整理到 MindOS。"\n"读一下 MindOS 里的方案,帮我开始写代码。"' },
|
|
833
861
|
{ emoji: '📋', title: '经验→SOP', desc: '把踩坑经验沉淀为可复用的工作流,下次 3 分钟搞定。', prompt: '"帮我把这次对话的经验沉淀到 MindOS,形成可复用的工作流。"' },
|
|
834
862
|
{ emoji: '🚀', title: '项目冷启动', desc: '几分钟搭建新项目——Profile 和 SOP 自动引导脚手架。', prompt: '"帮我按 MindOS 里的 Startup SOP 启动一个新项目。"' },
|
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/types/routes.d.ts";
|
|
3
|
+
import "./.next/dev/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.
|
package/package.json
CHANGED