@geminilight/mindos 0.6.43 → 0.6.45
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/_standalone/.mindos-build-version +1 -1
- package/_standalone/.next/BUILD_ID +1 -1
- package/_standalone/.next/app-path-routes-manifest.json +16 -16
- package/_standalone/.next/build-manifest.json +3 -3
- package/_standalone/.next/cache/.previewinfo +1 -1
- package/_standalone/.next/cache/.rscinfo +1 -1
- package/_standalone/.next/cache/config.json +3 -3
- package/_standalone/.next/prerender-manifest.json +3 -3
- package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error/page.js +3 -3
- package/_standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error.html +2 -2
- package/_standalone/.next/server/app/_global-error.rsc +2 -2
- package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
- package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/_standalone/.next/server/app/_not-found/page.js +2 -2
- package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js +2 -2
- package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/page.js +2 -2
- package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask/route.js +1 -1
- package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/backlinks/route.js +1 -1
- package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/changes/route.js +1 -1
- package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/export/route.js +2 -2
- package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/import/route.js +1 -1
- package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/route.js +1 -1
- package/_standalone/.next/server/app/api/file/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/files/route.js +1 -1
- package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/git/route.js +1 -1
- package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/graph/route.js +1 -1
- package/_standalone/.next/server/app/api/graph/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/inbox/route.js +1 -1
- package/_standalone/.next/server/app/api/inbox/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/init/route.js +1 -1
- package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/monitoring/route.js +1 -1
- package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/recent-files/route.js +1 -1
- package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/search/route.js +1 -1
- package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/route.js +1 -1
- package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/tree-version/route.js +1 -1
- package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/workflows/route.js +1 -1
- package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/changes/page.js +2 -2
- package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page.js +3 -3
- package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/page.js +2 -2
- package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/explore/page.js +2 -2
- package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/help/page.js +2 -2
- package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/login/page.js +2 -2
- package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/page.js +3 -3
- package/_standalone/.next/server/app/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/setup/page.js +2 -2
- package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/trash/page.js +3 -3
- package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/view/[...path]/page.js +3 -3
- package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app-paths-manifest.json +16 -16
- package/_standalone/.next/server/chunks/{66.js → 1405.js} +3 -3
- package/_standalone/.next/server/chunks/4241.js +219 -1
- package/_standalone/.next/server/chunks/{7471.js → 6117.js} +2 -2
- package/_standalone/.next/server/chunks/6539.js +1 -1
- package/_standalone/.next/server/chunks/6622.js +1 -0
- package/_standalone/.next/server/chunks/8388.js +1 -1
- package/_standalone/.next/server/middleware-build-manifest.js +1 -1
- package/_standalone/.next/server/pages/500.html +2 -2
- package/_standalone/.next/server/server-reference-manifest.js +1 -1
- package/_standalone/.next/server/server-reference-manifest.json +1 -1
- package/_standalone/.next/static/chunks/{1053-67f0ce444d1227e2.js → 1053-98e7148893702bd2.js} +2 -2
- package/_standalone/.next/static/chunks/app/global-error-e1ad0e18236ba26c.js +1 -0
- package/_standalone/.next/static/chunks/app/{layout-67c50f39fffd6c36.js → layout-f82c47d2213ba451.js} +45 -45
- package/_standalone/.next/static/chunks/app/page-adc8d13a522f9f8d.js +7 -0
- package/_standalone/.next/static/chunks/app/setup/page-abad6be1750aba3e.js +1 -0
- package/_standalone/.next/static/chunks/app/trash/page-842a9e8ebd653a0b.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/page-d1bd9b6231bb91a6.js +12 -0
- package/_standalone/.next/static/chunks/main-app-85439cf6d0f88401.js +1 -0
- package/_standalone/.next/trace +63 -63
- package/_standalone/__tests__/lib/i18n-new-keys.test.ts +2 -2
- package/_standalone/__tests__/lib/walkthrough-steps.test.ts +3 -3
- package/_standalone/components/setup/StepAI.tsx +4 -2
- package/_standalone/components/walkthrough/WalkthroughOverlay.tsx +13 -0
- package/_standalone/components/walkthrough/steps.ts +2 -5
- package/_standalone/lib/i18n/modules/onboarding.ts +0 -8
- package/app/app/global-error.tsx +50 -0
- package/app/app/page.tsx +10 -6
- package/app/components/setup/StepAI.tsx +4 -2
- package/app/components/setup/index.tsx +32 -17
- package/app/components/walkthrough/WalkthroughOverlay.tsx +13 -0
- package/app/components/walkthrough/steps.ts +2 -5
- package/app/lib/i18n/modules/onboarding.ts +0 -8
- package/app/lib/settings.ts +6 -1
- package/package.json +1 -1
- package/_standalone/.next/server/chunks/9539.js +0 -219
- package/_standalone/.next/static/chunks/app/page-ea1bff5e0ba77c16.js +0 -7
- package/_standalone/.next/static/chunks/app/setup/page-6132ea7632e08a9b.js +0 -1
- package/_standalone/.next/static/chunks/app/trash/page-6ee0637660fb00e9.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-182494955ef70870.js +0 -12
- package/_standalone/.next/static/chunks/main-app-e98a77f459b9b759.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-64470bfc5c888758.js +0 -1
- /package/_standalone/.next/static/{lpSyd-exxbKPK2GO1oNDZ → VjO4Ig1MkVHtQkepV2ZoO}/_buildManifest.js +0 -0
- /package/_standalone/.next/static/{lpSyd-exxbKPK2GO1oNDZ → VjO4Ig1MkVHtQkepV2ZoO}/_ssgManifest.js +0 -0
|
@@ -60,8 +60,8 @@ describe('i18n walkthrough keys', () => {
|
|
|
60
60
|
expect(w.exploreCta).toBeTruthy();
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
-
it('defines exactly
|
|
64
|
-
expect(w.steps).toHaveLength(
|
|
63
|
+
it('defines exactly 3 steps', () => {
|
|
64
|
+
expect(w.steps).toHaveLength(3);
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
it('each step has title and body', () => {
|
|
@@ -2,8 +2,8 @@ import { describe, it, expect } from 'vitest';
|
|
|
2
2
|
import { walkthroughSteps } from '@/components/walkthrough/steps';
|
|
3
3
|
|
|
4
4
|
describe('walkthrough/steps', () => {
|
|
5
|
-
it('defines exactly
|
|
6
|
-
expect(walkthroughSteps).toHaveLength(
|
|
5
|
+
it('defines exactly 3 steps', () => {
|
|
6
|
+
expect(walkthroughSteps).toHaveLength(3);
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
it('each step has anchor and position', () => {
|
|
@@ -19,7 +19,7 @@ describe('walkthrough/steps', () => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
it('anchors match the value-driven walkthrough sequence', () => {
|
|
22
|
-
const expected = ['files-panel', 'ask-button', 'agents-panel'
|
|
22
|
+
const expected = ['files-panel', 'ask-button', 'agents-panel'];
|
|
23
23
|
expect(walkthroughSteps.map(s => s.anchor)).toEqual(expected);
|
|
24
24
|
});
|
|
25
25
|
});
|
|
@@ -27,11 +27,12 @@ export default function StepAI({ state, update, s, onCopyToken, webPortStatus, m
|
|
|
27
27
|
const { locale } = useLocale();
|
|
28
28
|
const [portsOpen, setPortsOpen] = useState(false);
|
|
29
29
|
|
|
30
|
+
// Only auto-open Advanced if there's an unresolved port issue the user needs to see
|
|
30
31
|
useEffect(() => {
|
|
31
|
-
if (!portsOpen &&
|
|
32
|
+
if (!portsOpen && portConflict) {
|
|
32
33
|
setPortsOpen(true);
|
|
33
34
|
}
|
|
34
|
-
}, [
|
|
35
|
+
}, [portConflict, portsOpen]);
|
|
35
36
|
|
|
36
37
|
const currentProvider = state.provider !== 'skip' && isProviderId(state.provider) ? state.provider : null;
|
|
37
38
|
const currentPreset = currentProvider ? PROVIDER_PRESETS[currentProvider] : null;
|
|
@@ -58,6 +59,7 @@ export default function StepAI({ state, update, s, onCopyToken, webPortStatus, m
|
|
|
58
59
|
value={state.provider}
|
|
59
60
|
onChange={id => update('provider', id)}
|
|
60
61
|
showSkip
|
|
62
|
+
compact
|
|
61
63
|
configuredProviders={configuredProviders}
|
|
62
64
|
/>
|
|
63
65
|
|
|
@@ -68,6 +68,17 @@ export default function WalkthroughOverlay() {
|
|
|
68
68
|
return () => window.removeEventListener('keydown', handler, true);
|
|
69
69
|
}, [skipFn]);
|
|
70
70
|
|
|
71
|
+
// If target element doesn't exist (e.g. Echo not enabled), auto-skip this step
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (!step) return;
|
|
74
|
+
const el = document.querySelector(`[data-walkthrough="${step.anchor}"]`);
|
|
75
|
+
if (!el) {
|
|
76
|
+
// Target not in DOM — skip to next step after a brief delay
|
|
77
|
+
const timer = setTimeout(() => wt?.next(), 100);
|
|
78
|
+
return () => clearTimeout(timer);
|
|
79
|
+
}
|
|
80
|
+
}, [step, wt]);
|
|
81
|
+
|
|
71
82
|
if (!wt || !step) return null;
|
|
72
83
|
|
|
73
84
|
// Mobile: bottom sheet instead of spotlight
|
|
@@ -98,6 +109,8 @@ export default function WalkthroughOverlay() {
|
|
|
98
109
|
if (!inSpotlight) {
|
|
99
110
|
wt.skip();
|
|
100
111
|
}
|
|
112
|
+
} else {
|
|
113
|
+
wt.skip();
|
|
101
114
|
}
|
|
102
115
|
}}
|
|
103
116
|
>
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
export type WalkthroughAnchor =
|
|
3
3
|
| 'files-panel'
|
|
4
4
|
| 'ask-button'
|
|
5
|
-
| 'agents-panel'
|
|
6
|
-
| 'echo-panel';
|
|
5
|
+
| 'agents-panel';
|
|
7
6
|
|
|
8
7
|
export interface WalkthroughStep {
|
|
9
8
|
anchor: WalkthroughAnchor;
|
|
@@ -12,15 +11,13 @@ export interface WalkthroughStep {
|
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
/**
|
|
15
|
-
*
|
|
14
|
+
* 3-step value-driven walkthrough:
|
|
16
15
|
* 0. Project Memory (foundation)
|
|
17
16
|
* 1. AI That Already Knows You (wedge)
|
|
18
17
|
* 2. Multi-Agent Sharing (differentiation)
|
|
19
|
-
* 3. Echo — Cognitive Compound Interest (retention seed)
|
|
20
18
|
*/
|
|
21
19
|
export const walkthroughSteps: WalkthroughStep[] = [
|
|
22
20
|
{ anchor: 'files-panel', position: 'right' },
|
|
23
21
|
{ anchor: 'ask-button', position: 'right' },
|
|
24
22
|
{ anchor: 'agents-panel', position: 'right' },
|
|
25
|
-
{ anchor: 'echo-panel', position: 'right' },
|
|
26
23
|
];
|
|
@@ -211,10 +211,6 @@ export const onboardingEn = {
|
|
|
211
211
|
title: 'Connect Any Agent',
|
|
212
212
|
body: 'Link Cursor, Claude Code, or Windsurf via MCP — they all share the same project memory.',
|
|
213
213
|
},
|
|
214
|
-
{
|
|
215
|
-
title: 'Echo — Growth Compounds',
|
|
216
|
-
body: 'About you, daily reflections, growth tracking — MindOS helps you accumulate cognitive compound interest over time.',
|
|
217
|
-
},
|
|
218
214
|
],
|
|
219
215
|
},
|
|
220
216
|
} as const;
|
|
@@ -430,10 +426,6 @@ export const onboardingZh = {
|
|
|
430
426
|
title: '多 Agent 共享记忆',
|
|
431
427
|
body: '通过 MCP 连接 Cursor、Claude Code、Windsurf,它们共享同一份项目记忆。',
|
|
432
428
|
},
|
|
433
|
-
{
|
|
434
|
-
title: '回响 — 认知在积累',
|
|
435
|
-
body: '关于你、每日回顾、成长轨迹——MindOS 帮你沉淀判断与偏好,让经验不断复利。',
|
|
436
|
-
},
|
|
437
429
|
],
|
|
438
430
|
},
|
|
439
431
|
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Root-level error boundary that catches errors in the entire app,
|
|
5
|
+
* including layout.tsx and server component failures.
|
|
6
|
+
* This prevents the generic "Application error" white screen.
|
|
7
|
+
*/
|
|
8
|
+
export default function GlobalError({
|
|
9
|
+
error,
|
|
10
|
+
reset,
|
|
11
|
+
}: {
|
|
12
|
+
error: Error & { digest?: string };
|
|
13
|
+
reset: () => void;
|
|
14
|
+
}) {
|
|
15
|
+
return (
|
|
16
|
+
<html lang="en">
|
|
17
|
+
<body style={{ margin: 0, fontFamily: 'system-ui, sans-serif', background: '#0f0f0f', color: '#e5e5e5' }}>
|
|
18
|
+
<div style={{
|
|
19
|
+
display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
|
|
20
|
+
minHeight: '100vh', gap: '16px', padding: '24px', textAlign: 'center',
|
|
21
|
+
}}>
|
|
22
|
+
<h2 style={{ fontSize: '18px', fontWeight: 600, margin: 0 }}>Something went wrong</h2>
|
|
23
|
+
<p style={{ fontSize: '14px', color: '#888', maxWidth: '400px', margin: 0 }}>
|
|
24
|
+
{error.message || 'An unexpected error occurred. Please try again.'}
|
|
25
|
+
</p>
|
|
26
|
+
<div style={{ display: 'flex', gap: '12px', marginTop: '8px' }}>
|
|
27
|
+
<button
|
|
28
|
+
onClick={reset}
|
|
29
|
+
style={{
|
|
30
|
+
padding: '8px 16px', borderRadius: '6px', fontSize: '14px', fontWeight: 500,
|
|
31
|
+
background: '#222', color: '#e5e5e5', border: '1px solid #333', cursor: 'pointer',
|
|
32
|
+
}}
|
|
33
|
+
>
|
|
34
|
+
Try again
|
|
35
|
+
</button>
|
|
36
|
+
<a
|
|
37
|
+
href="/setup"
|
|
38
|
+
style={{
|
|
39
|
+
padding: '8px 16px', borderRadius: '6px', fontSize: '14px', fontWeight: 500,
|
|
40
|
+
background: '#c8873a', color: '#fff', textDecoration: 'none', cursor: 'pointer',
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
Go to Setup
|
|
44
|
+
</a>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</body>
|
|
48
|
+
</html>
|
|
49
|
+
);
|
|
50
|
+
}
|
package/app/app/page.tsx
CHANGED
|
@@ -54,12 +54,16 @@ function getTopLevelDirs(): SpaceInfo[] {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function getExistingFiles(paths: string[]): string[] {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
try {
|
|
58
|
+
const root = getMindRoot();
|
|
59
|
+
return paths.filter(p => {
|
|
60
|
+
try {
|
|
61
|
+
return fs.existsSync(path.join(root, p));
|
|
62
|
+
} catch { return false; }
|
|
63
|
+
});
|
|
64
|
+
} catch {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
export default function HomePage() {
|
|
@@ -27,11 +27,12 @@ export default function StepAI({ state, update, s, onCopyToken, webPortStatus, m
|
|
|
27
27
|
const { locale } = useLocale();
|
|
28
28
|
const [portsOpen, setPortsOpen] = useState(false);
|
|
29
29
|
|
|
30
|
+
// Only auto-open Advanced if there's an unresolved port issue the user needs to see
|
|
30
31
|
useEffect(() => {
|
|
31
|
-
if (!portsOpen &&
|
|
32
|
+
if (!portsOpen && portConflict) {
|
|
32
33
|
setPortsOpen(true);
|
|
33
34
|
}
|
|
34
|
-
}, [
|
|
35
|
+
}, [portConflict, portsOpen]);
|
|
35
36
|
|
|
36
37
|
const currentProvider = state.provider !== 'skip' && isProviderId(state.provider) ? state.provider : null;
|
|
37
38
|
const currentPreset = currentProvider ? PROVIDER_PRESETS[currentProvider] : null;
|
|
@@ -58,6 +59,7 @@ export default function StepAI({ state, update, s, onCopyToken, webPortStatus, m
|
|
|
58
59
|
value={state.provider}
|
|
59
60
|
onChange={id => update('provider', id)}
|
|
60
61
|
showSkip
|
|
62
|
+
compact
|
|
61
63
|
configuredProviders={configuredProviders}
|
|
62
64
|
/>
|
|
63
65
|
|
|
@@ -207,11 +207,11 @@ export default function SetupWizard() {
|
|
|
207
207
|
});
|
|
208
208
|
}, []);
|
|
209
209
|
|
|
210
|
-
// Auto-check ports when entering AI step
|
|
210
|
+
// Auto-check ports when entering AI step — auto-resolve occupied ports
|
|
211
211
|
useEffect(() => {
|
|
212
212
|
if (step === STEP_AI) {
|
|
213
|
-
checkPort(state.webPort, 'web');
|
|
214
|
-
checkPort(state.mcpPort, 'mcp');
|
|
213
|
+
checkPort(state.webPort, 'web', true);
|
|
214
|
+
checkPort(state.mcpPort, 'mcp', true);
|
|
215
215
|
}
|
|
216
216
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
217
217
|
}, [step]);
|
|
@@ -259,7 +259,7 @@ export default function SetupWizard() {
|
|
|
259
259
|
});
|
|
260
260
|
}, [state.authToken]);
|
|
261
261
|
|
|
262
|
-
const checkPort = useCallback(async (port: number, which: 'web' | 'mcp') => {
|
|
262
|
+
const checkPort = useCallback(async (port: number, which: 'web' | 'mcp', autoResolve = false) => {
|
|
263
263
|
if (port < 1024 || port > 65535) return;
|
|
264
264
|
const setStatus = which === 'web' ? setWebPortStatus : setMcpPortStatus;
|
|
265
265
|
setStatus({ checking: true, available: null, isSelf: false, suggestion: null });
|
|
@@ -270,7 +270,17 @@ export default function SetupWizard() {
|
|
|
270
270
|
body: JSON.stringify({ port }),
|
|
271
271
|
});
|
|
272
272
|
const data = await res.json();
|
|
273
|
-
|
|
273
|
+
const available = data.available ?? null;
|
|
274
|
+
const suggestion = data.suggestion ?? null;
|
|
275
|
+
setStatus({ checking: false, available, isSelf: !!data.isSelf, suggestion });
|
|
276
|
+
|
|
277
|
+
// Auto-resolve: if port is occupied and a suggestion is available, use it silently
|
|
278
|
+
if (autoResolve && available === false && suggestion) {
|
|
279
|
+
const key = which === 'web' ? 'webPort' : 'mcpPort';
|
|
280
|
+
setState(prev => ({ ...prev, [key]: suggestion }));
|
|
281
|
+
// Re-check the suggested port
|
|
282
|
+
setTimeout(() => checkPort(suggestion, which, false), 0);
|
|
283
|
+
}
|
|
274
284
|
} catch (e) {
|
|
275
285
|
console.warn('[SetupWizard] checkPort failed:', e);
|
|
276
286
|
setStatus({ checking: false, available: null, isSelf: false, suggestion: null });
|
|
@@ -380,23 +390,28 @@ export default function SetupWizard() {
|
|
|
380
390
|
}, [agents, agentScope, agentTransport, state.mcpPort, state.authToken]);
|
|
381
391
|
|
|
382
392
|
return (
|
|
383
|
-
<div className="fixed inset-0 z-50 flex
|
|
393
|
+
<div className="fixed inset-0 z-50 flex flex-col overflow-y-auto"
|
|
384
394
|
role="dialog" aria-modal="true" aria-labelledby="setup-title"
|
|
385
395
|
style={{ background: 'var(--background)' }}>
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
<
|
|
391
|
-
|
|
392
|
-
|
|
396
|
+
{/* Sticky header: logo + step dots */}
|
|
397
|
+
<div className="sticky top-0 z-10 pt-6 pb-3 px-6" style={{ background: 'var(--background)' }}>
|
|
398
|
+
<div className="max-w-xl mx-auto">
|
|
399
|
+
<div className="text-center mb-3">
|
|
400
|
+
<div className="inline-flex items-center gap-2">
|
|
401
|
+
<Sparkles size={18} style={{ color: 'var(--amber)' }} />
|
|
402
|
+
<h1 id="setup-title" className="text-2xl font-semibold tracking-tight font-display" style={{ color: 'var(--foreground)' }}>
|
|
403
|
+
MindOS
|
|
404
|
+
</h1>
|
|
405
|
+
</div>
|
|
406
|
+
</div>
|
|
407
|
+
<div className="flex justify-center">
|
|
408
|
+
<StepDots step={step} setStep={setStep} stepTitles={s.stepTitles} disabled={submitting || completed} numberedSteps={STEP_REVIEW} />
|
|
393
409
|
</div>
|
|
394
410
|
</div>
|
|
411
|
+
</div>
|
|
395
412
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
</div>
|
|
399
|
-
|
|
413
|
+
{/* Scrollable content */}
|
|
414
|
+
<div className="flex-1 w-full max-w-xl mx-auto px-6 pb-8">
|
|
400
415
|
<h2 className="text-lg font-semibold mb-5" style={{ color: 'var(--foreground)' }}>
|
|
401
416
|
{step === STEP_REVIEW ? `✓ ${s.stepTitles[step]}` : s.stepTitles[step]}
|
|
402
417
|
</h2>
|
|
@@ -68,6 +68,17 @@ export default function WalkthroughOverlay() {
|
|
|
68
68
|
return () => window.removeEventListener('keydown', handler, true);
|
|
69
69
|
}, [skipFn]);
|
|
70
70
|
|
|
71
|
+
// If target element doesn't exist (e.g. Echo not enabled), auto-skip this step
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (!step) return;
|
|
74
|
+
const el = document.querySelector(`[data-walkthrough="${step.anchor}"]`);
|
|
75
|
+
if (!el) {
|
|
76
|
+
// Target not in DOM — skip to next step after a brief delay
|
|
77
|
+
const timer = setTimeout(() => wt?.next(), 100);
|
|
78
|
+
return () => clearTimeout(timer);
|
|
79
|
+
}
|
|
80
|
+
}, [step, wt]);
|
|
81
|
+
|
|
71
82
|
if (!wt || !step) return null;
|
|
72
83
|
|
|
73
84
|
// Mobile: bottom sheet instead of spotlight
|
|
@@ -98,6 +109,8 @@ export default function WalkthroughOverlay() {
|
|
|
98
109
|
if (!inSpotlight) {
|
|
99
110
|
wt.skip();
|
|
100
111
|
}
|
|
112
|
+
} else {
|
|
113
|
+
wt.skip();
|
|
101
114
|
}
|
|
102
115
|
}}
|
|
103
116
|
>
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
export type WalkthroughAnchor =
|
|
3
3
|
| 'files-panel'
|
|
4
4
|
| 'ask-button'
|
|
5
|
-
| 'agents-panel'
|
|
6
|
-
| 'echo-panel';
|
|
5
|
+
| 'agents-panel';
|
|
7
6
|
|
|
8
7
|
export interface WalkthroughStep {
|
|
9
8
|
anchor: WalkthroughAnchor;
|
|
@@ -12,15 +11,13 @@ export interface WalkthroughStep {
|
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
/**
|
|
15
|
-
*
|
|
14
|
+
* 3-step value-driven walkthrough:
|
|
16
15
|
* 0. Project Memory (foundation)
|
|
17
16
|
* 1. AI That Already Knows You (wedge)
|
|
18
17
|
* 2. Multi-Agent Sharing (differentiation)
|
|
19
|
-
* 3. Echo — Cognitive Compound Interest (retention seed)
|
|
20
18
|
*/
|
|
21
19
|
export const walkthroughSteps: WalkthroughStep[] = [
|
|
22
20
|
{ anchor: 'files-panel', position: 'right' },
|
|
23
21
|
{ anchor: 'ask-button', position: 'right' },
|
|
24
22
|
{ anchor: 'agents-panel', position: 'right' },
|
|
25
|
-
{ anchor: 'echo-panel', position: 'right' },
|
|
26
23
|
];
|
|
@@ -211,10 +211,6 @@ export const onboardingEn = {
|
|
|
211
211
|
title: 'Connect Any Agent',
|
|
212
212
|
body: 'Link Cursor, Claude Code, or Windsurf via MCP — they all share the same project memory.',
|
|
213
213
|
},
|
|
214
|
-
{
|
|
215
|
-
title: 'Echo — Growth Compounds',
|
|
216
|
-
body: 'About you, daily reflections, growth tracking — MindOS helps you accumulate cognitive compound interest over time.',
|
|
217
|
-
},
|
|
218
214
|
],
|
|
219
215
|
},
|
|
220
216
|
} as const;
|
|
@@ -430,10 +426,6 @@ export const onboardingZh = {
|
|
|
430
426
|
title: '多 Agent 共享记忆',
|
|
431
427
|
body: '通过 MCP 连接 Cursor、Claude Code、Windsurf,它们共享同一份项目记忆。',
|
|
432
428
|
},
|
|
433
|
-
{
|
|
434
|
-
title: '回响 — 认知在积累',
|
|
435
|
-
body: '关于你、每日回顾、成长轨迹——MindOS 帮你沉淀判断与偏好,让经验不断复利。',
|
|
436
|
-
},
|
|
437
429
|
],
|
|
438
430
|
},
|
|
439
431
|
};
|
package/app/lib/settings.ts
CHANGED
|
@@ -181,7 +181,12 @@ export function readSettings(): ServerSettings {
|
|
|
181
181
|
guideState: parseGuideState(parsed.guideState),
|
|
182
182
|
};
|
|
183
183
|
} catch {
|
|
184
|
-
|
|
184
|
+
// Config file missing or corrupt → force setup wizard
|
|
185
|
+
return {
|
|
186
|
+
...DEFAULTS,
|
|
187
|
+
ai: { ...DEFAULTS.ai, providers: { ...DEFAULTS.ai.providers } },
|
|
188
|
+
setupPending: true,
|
|
189
|
+
};
|
|
185
190
|
}
|
|
186
191
|
}
|
|
187
192
|
|
package/package.json
CHANGED