@geminilight/mindos 0.6.58 → 0.6.59
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 +24 -24
- 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/react-loadable-manifest.json +1 -1
- 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_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error.html +2 -2
- package/_standalone/.next/server/app/_global-error.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- 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/agents/custom/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask/route.js +3 -3
- 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_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +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_client-reference-manifest.js +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_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_client-reference-manifest.js +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_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_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_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_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 +1 -1
- 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/inbox/history/page.js +1 -1
- package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/inbox/history/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 +2 -8
- 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/wiki/page.js +2 -2
- package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app-paths-manifest.json +24 -24
- package/_standalone/.next/server/chunks/3484.js +1 -1
- package/_standalone/.next/server/chunks/530.js +65 -66
- package/_standalone/.next/server/chunks/{6793.js → 8343.js} +2 -2
- package/_standalone/.next/server/chunks/9787.js +2 -0
- package/_standalone/.next/server/middleware-build-manifest.js +1 -1
- package/_standalone/.next/server/middleware-react-loadable-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/{1814.a7c127b2c73d1f70.js → 1814.a79b84d37df75c43.js} +1 -1
- package/_standalone/.next/static/chunks/3427-2e61a5df1f5e55fb.js +1 -0
- package/_standalone/.next/static/chunks/{1053-fe009233cff06e72.js → 5581-dac72e9f16e5ea29.js} +3 -3
- package/_standalone/.next/static/chunks/6297-085daa21037d5f81.js +1 -0
- package/_standalone/.next/static/chunks/{7249-fa98ca10e9a10f39.js → 7249-6cf8f2b78718c59e.js} +1 -1
- package/_standalone/.next/static/chunks/8520-56ec9ff087c15204.js +22 -0
- package/_standalone/.next/static/chunks/9905-a19d379cb225246e.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/{page-7bdeab5af8e4f5f2.js → page-35ea6de1af2be3b5.js} +1 -1
- package/_standalone/.next/static/chunks/app/agents/page-b172ea3743adb047.js +1 -0
- package/_standalone/.next/static/chunks/app/changes/{page-5a72144d1080a699.js → page-6d2f49651c0061f7.js} +1 -1
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-84b95256f6e38aae.js +11 -0
- package/_standalone/.next/static/chunks/app/explore/{page-d3d99308146c2240.js → page-d9f58000bc445360.js} +2 -2
- package/_standalone/.next/static/chunks/app/help/{page-222df603080b5fab.js → page-f8cb806371b3175f.js} +1 -1
- package/_standalone/.next/static/chunks/app/inbox/history/{page-07819cf95cb0805f.js → page-26e71fb6f716a4c4.js} +1 -1
- package/_standalone/.next/static/chunks/app/layout-b89b0d955f39a753.js +164 -0
- package/_standalone/.next/static/chunks/app/login/{page-0eeef685052869a6.js → page-18fb00d568cd1f0e.js} +1 -1
- package/_standalone/.next/static/chunks/app/page-a8e6f085f38388bf.js +1 -0
- package/_standalone/.next/static/chunks/app/setup/{page-99fcfc460fa29733.js → page-821714e7477be46c.js} +1 -1
- package/_standalone/.next/static/chunks/app/trash/{page-54cbd5c98d9de69b.js → page-f92b728b78ac0f7e.js} +1 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/{not-found-fc04c2bd4f35bc6f.js → not-found-6e0c75ad26ce8572.js} +1 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-f87f4901b5e1a88f.js +12 -0
- package/_standalone/.next/static/chunks/app/wiki/page-641edb1f3cff2f93.js +1 -0
- package/_standalone/.next/static/chunks/{webpack-2c19436659aa657b.js → webpack-72e8d9e9073fd1f9.js} +1 -1
- package/_standalone/.next/static/css/6c104b118d3bc9b7.css +1 -0
- package/_standalone/.next/trace +64 -64
- package/_standalone/app/globals.css +2 -1
- package/_standalone/components/AskFab.tsx +4 -4
- package/_standalone/components/AskModal.tsx +1 -1
- package/_standalone/components/GuideCard.tsx +101 -152
- package/_standalone/components/RightAskPanel.tsx +2 -2
- package/_standalone/components/ask/AskContent.tsx +90 -51
- package/_standalone/components/ask/AskHeader.tsx +218 -18
- package/_standalone/components/ask/MessageList.tsx +66 -47
- package/_standalone/components/ask/SessionHistory.tsx +86 -60
- package/_standalone/components/ask/SessionTabBar.tsx +29 -21
- package/_standalone/components/ask/ThinkingBlock.tsx +6 -5
- package/_standalone/components/ask/ToolCallBlock.tsx +10 -9
- package/_standalone/components/settings/SettingsContent.tsx +1 -1
- package/_standalone/data/skills/mindos/SKILL.md +67 -15
- package/_standalone/data/skills/mindos-zh/SKILL.md +67 -11
- package/_standalone/hooks/useAskSession.ts +23 -1
- package/_standalone/lib/stores/locale-store.ts +20 -6
- package/_standalone/tsconfig.tsbuildinfo +1 -1
- package/app/app/globals.css +2 -1
- package/app/app/layout.tsx +16 -4
- package/app/components/AskFab.tsx +4 -4
- package/app/components/AskModal.tsx +1 -1
- package/app/components/GuideCard.tsx +101 -152
- package/app/components/HomeContent.tsx +116 -575
- package/app/components/RightAskPanel.tsx +2 -2
- package/app/components/WikiHomeContent.tsx +151 -3
- package/app/components/ask/AskContent.tsx +90 -51
- package/app/components/ask/AskHeader.tsx +218 -18
- package/app/components/ask/MessageList.tsx +66 -47
- package/app/components/ask/SessionHistory.tsx +86 -60
- package/app/components/ask/SessionTabBar.tsx +29 -21
- package/app/components/ask/ThinkingBlock.tsx +6 -5
- package/app/components/ask/ToolCallBlock.tsx +10 -9
- package/app/components/settings/SettingsContent.tsx +1 -1
- package/app/data/skills/mindos/SKILL.md +67 -15
- package/app/data/skills/mindos-zh/SKILL.md +67 -11
- package/app/hooks/useAskSession.ts +23 -1
- package/app/lib/i18n/modules/ai-chat.ts +97 -10
- package/app/lib/i18n/modules/onboarding.ts +12 -12
- package/app/lib/stores/LocaleStoreInit.tsx +24 -1
- package/app/lib/stores/locale-store.ts +20 -6
- package/app/lib/types.ts +1 -0
- package/package.json +1 -1
- package/skills/mindos/SKILL.md +67 -15
- package/skills/mindos/references/knowledge-health.md +120 -0
- package/skills/mindos-max/SKILL.md +52 -5
- package/skills/mindos-max-zh/SKILL.md +55 -6
- package/skills/mindos-zh/SKILL.md +67 -11
- package/_standalone/.next/server/chunks/2364.js +0 -2
- package/_standalone/.next/server/chunks/357.js +0 -1
- package/_standalone/.next/static/chunks/178-105779afb62d36d9.js +0 -1
- package/_standalone/.next/static/chunks/2218-d54538000574ffef.js +0 -1
- package/_standalone/.next/static/chunks/2549-e63cf57fa927a41d.js +0 -1
- package/_standalone/.next/static/chunks/9274-296ab35f9f09e42e.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/page-5d1446665ddb3801.js +0 -1
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-b0103509ce34444b.js +0 -11
- package/_standalone/.next/static/chunks/app/layout-7e02ddf4144b01f1.js +0 -186
- package/_standalone/.next/static/chunks/app/page-6a6a12bd6d6812d0.js +0 -7
- package/_standalone/.next/static/chunks/app/view/[...path]/page-ca7bdcbf27f88a46.js +0 -12
- package/_standalone/.next/static/chunks/app/wiki/page-d492256a93f0b8bc.js +0 -1
- package/_standalone/.next/static/css/fd84c8316ead16eb.css +0 -1
- /package/_standalone/.next/static/{2ksXveDzEcnCMRIElDkLq → u8p6oIRTcr_ns-ElNZ9rl}/_buildManifest.js +0 -0
- /package/_standalone/.next/static/{2ksXveDzEcnCMRIElDkLq → u8p6oIRTcr_ns-ElNZ9rl}/_ssgManifest.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
4
|
-
import { Trash2, Pencil } from 'lucide-react';
|
|
4
|
+
import { Trash2, Pencil, Pin, PinOff } from 'lucide-react';
|
|
5
5
|
import type { ChatSession } from '@/lib/types';
|
|
6
6
|
import { sessionTitle } from '@/hooks/useAskSession';
|
|
7
7
|
|
|
@@ -11,11 +11,25 @@ interface SessionHistoryProps {
|
|
|
11
11
|
onLoad: (id: string) => void;
|
|
12
12
|
onDelete: (id: string) => void;
|
|
13
13
|
onRename: (id: string, title: string) => void;
|
|
14
|
+
onTogglePin: (id: string) => void;
|
|
14
15
|
onClearAll: () => void;
|
|
15
16
|
labels: { title: string; clearAll: string; confirmClear: string; noSessions: string; rename: string };
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
function formatRelativeTime(date: Date): string {
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
const diff = now - date.getTime();
|
|
22
|
+
const mins = Math.floor(diff / 60000);
|
|
23
|
+
if (mins < 1) return 'just now';
|
|
24
|
+
if (mins < 60) return `${mins}m ago`;
|
|
25
|
+
const hours = Math.floor(mins / 60);
|
|
26
|
+
if (hours < 24) return `${hours}h ago`;
|
|
27
|
+
const days = Math.floor(hours / 24);
|
|
28
|
+
if (days < 7) return `${days}d ago`;
|
|
29
|
+
return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default function SessionHistory({ sessions, activeSessionId, onLoad, onDelete, onRename, onTogglePin, onClearAll, labels }: SessionHistoryProps) {
|
|
19
33
|
const [confirmClearAll, setConfirmClearAll] = useState(false);
|
|
20
34
|
const clearTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);
|
|
21
35
|
const [editingId, setEditingId] = useState<string | null>(null);
|
|
@@ -60,78 +74,90 @@ export default function SessionHistory({ sessions, activeSessionId, onLoad, onDe
|
|
|
60
74
|
}, []);
|
|
61
75
|
|
|
62
76
|
return (
|
|
63
|
-
<div className="border-b border-border px-4 py-
|
|
64
|
-
<div className="flex items-center justify-between mb-2">
|
|
65
|
-
<span className="text-xs text-muted-foreground">{labels.title}</span>
|
|
77
|
+
<div className="border-b border-border/40 px-4 py-3 max-h-[220px] overflow-y-auto">
|
|
78
|
+
<div className="flex items-center justify-between mb-2.5">
|
|
79
|
+
<span className="text-xs font-medium text-muted-foreground">{labels.title}</span>
|
|
66
80
|
{sessions.length > 1 && (
|
|
67
81
|
<button
|
|
68
82
|
type="button"
|
|
69
83
|
onClick={handleClearAll}
|
|
70
|
-
className={`text-2xs px-
|
|
84
|
+
className={`text-2xs px-2 py-0.5 rounded-md transition-colors ${
|
|
71
85
|
confirmClearAll
|
|
72
86
|
? 'bg-error/10 text-error font-medium'
|
|
73
|
-
: 'text-muted-foreground hover:text-error hover:bg-muted'
|
|
87
|
+
: 'text-muted-foreground/60 hover:text-error hover:bg-muted'
|
|
74
88
|
}`}
|
|
75
89
|
>
|
|
76
90
|
{confirmClearAll ? labels.confirmClear : labels.clearAll}
|
|
77
91
|
</button>
|
|
78
92
|
)}
|
|
79
93
|
</div>
|
|
80
|
-
<div className="flex flex-col gap-1
|
|
94
|
+
<div className="flex flex-col gap-1">
|
|
81
95
|
{sessions.length === 0 && (
|
|
82
|
-
<div className="text-xs text-muted-foreground/
|
|
96
|
+
<div className="text-xs text-muted-foreground/50 py-2 text-center">{labels.noSessions}</div>
|
|
83
97
|
)}
|
|
84
|
-
{sessions.map((s) =>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
98
|
+
{sessions.map((s) => {
|
|
99
|
+
const isActive = activeSessionId === s.id;
|
|
100
|
+
return (
|
|
101
|
+
<div key={s.id} className="group flex items-center gap-0.5">
|
|
102
|
+
{s.pinned && <Pin size={10} className="shrink-0 text-[var(--amber)]/50 -rotate-45 ml-1" />}
|
|
103
|
+
<button
|
|
104
|
+
type="button"
|
|
105
|
+
onClick={() => onLoad(s.id)}
|
|
106
|
+
onDoubleClick={() => startRename(s)}
|
|
107
|
+
className={`flex-1 text-left px-2.5 py-2 rounded-lg text-xs transition-colors min-w-0 ${
|
|
108
|
+
isActive
|
|
109
|
+
? 'bg-[var(--amber)]/8 text-foreground border border-[var(--amber)]/15'
|
|
110
|
+
: 'text-muted-foreground hover:bg-muted hover:text-foreground border border-transparent'
|
|
111
|
+
}`}
|
|
112
|
+
>
|
|
113
|
+
{editingId === s.id ? (
|
|
114
|
+
<input
|
|
115
|
+
ref={inputRef}
|
|
116
|
+
type="text"
|
|
117
|
+
value={editValue}
|
|
118
|
+
onChange={(e) => setEditValue(e.target.value)}
|
|
119
|
+
onBlur={commitRename}
|
|
120
|
+
onKeyDown={(e) => {
|
|
121
|
+
if (e.key === 'Enter') { e.preventDefault(); commitRename(); }
|
|
122
|
+
if (e.key === 'Escape') { e.preventDefault(); cancelRename(); }
|
|
123
|
+
}}
|
|
124
|
+
onClick={(e) => e.stopPropagation()}
|
|
125
|
+
className="w-full bg-transparent border-b border-[var(--amber)] outline-none text-xs text-foreground"
|
|
126
|
+
/>
|
|
127
|
+
) : (
|
|
128
|
+
<div className="truncate font-medium">{sessionTitle(s)}</div>
|
|
129
|
+
)}
|
|
130
|
+
{editingId !== s.id && (
|
|
131
|
+
<div className="text-2xs text-muted-foreground/50 mt-0.5">{formatRelativeTime(new Date(s.updatedAt))}</div>
|
|
132
|
+
)}
|
|
133
|
+
</button>
|
|
134
|
+
<button
|
|
135
|
+
type="button"
|
|
136
|
+
onClick={() => onTogglePin(s.id)}
|
|
137
|
+
className={`p-1.5 rounded-lg transition-opacity opacity-0 group-hover:opacity-100 ${s.pinned ? 'text-[var(--amber)] hover:text-muted-foreground' : 'text-muted-foreground hover:text-[var(--amber)]'}`}
|
|
138
|
+
title={s.pinned ? 'Unpin' : 'Pin'}
|
|
139
|
+
>
|
|
140
|
+
{s.pinned ? <PinOff size={11} /> : <Pin size={11} />}
|
|
141
|
+
</button>
|
|
142
|
+
<button
|
|
143
|
+
type="button"
|
|
144
|
+
onClick={() => startRename(s)}
|
|
145
|
+
className="p-1.5 rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted opacity-0 group-hover:opacity-100 transition-opacity"
|
|
146
|
+
title={labels.rename}
|
|
147
|
+
>
|
|
148
|
+
<Pencil size={11} />
|
|
149
|
+
</button>
|
|
150
|
+
<button
|
|
151
|
+
type="button"
|
|
152
|
+
onClick={() => onDelete(s.id)}
|
|
153
|
+
className="p-1.5 rounded-lg text-muted-foreground hover:text-error hover:bg-error/5 opacity-0 group-hover:opacity-100 transition-opacity"
|
|
154
|
+
title="Delete session"
|
|
155
|
+
>
|
|
156
|
+
<Trash2 size={11} />
|
|
157
|
+
</button>
|
|
158
|
+
</div>
|
|
159
|
+
);
|
|
160
|
+
})}
|
|
135
161
|
</div>
|
|
136
162
|
</div>
|
|
137
163
|
);
|
|
@@ -19,48 +19,56 @@ export default function SessionTabBar({
|
|
|
19
19
|
}: SessionTabBarProps) {
|
|
20
20
|
const { t } = useLocale();
|
|
21
21
|
const visibleSessions = sessions.slice(0, maxTabs);
|
|
22
|
+
const hasMore = sessions.length > maxTabs;
|
|
22
23
|
|
|
23
24
|
if (visibleSessions.length === 0) return null;
|
|
24
25
|
|
|
25
26
|
return (
|
|
26
|
-
<div className="flex items-center border-b border-border shrink-0 bg-background/50">
|
|
27
|
+
<div className="flex items-center border-b border-border/60 shrink-0 bg-background/50" role="tablist">
|
|
27
28
|
<div className="flex flex-1 min-w-0">
|
|
28
29
|
{visibleSessions.map((s) => {
|
|
29
30
|
const isActive = s.id === activeSessionId;
|
|
30
31
|
const title = sessionTitle(s);
|
|
31
32
|
return (
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
<div key={s.id} className="group relative flex items-center min-w-0 max-w-[160px]">
|
|
34
|
+
<button
|
|
35
|
+
type="button"
|
|
36
|
+
role="tab"
|
|
37
|
+
aria-selected={isActive}
|
|
38
|
+
onClick={() => onLoad(s.id)}
|
|
39
|
+
className={`flex-1 min-w-0 px-3 py-2.5 text-xs transition-colors truncate
|
|
40
|
+
${isActive
|
|
41
|
+
? 'text-foreground border-b-2 border-[var(--amber)] bg-card font-medium'
|
|
42
|
+
: 'text-muted-foreground hover:text-foreground hover:bg-muted/50 border-b-2 border-transparent'
|
|
43
|
+
}`}
|
|
44
|
+
title={title}
|
|
45
|
+
>
|
|
46
|
+
{title === '(empty session)' ? t.hints.newChat : title}
|
|
47
|
+
</button>
|
|
44
48
|
{visibleSessions.length > 1 && (
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
tabIndex={0}
|
|
49
|
+
<button
|
|
50
|
+
type="button"
|
|
48
51
|
onClick={(e) => { e.stopPropagation(); onDelete(s.id); }}
|
|
49
|
-
|
|
50
|
-
className="shrink-0 p-0.5 rounded opacity-0 group-hover:opacity-100 hover:bg-muted hover:text-error transition-opacity"
|
|
52
|
+
className="absolute right-0.5 top-1/2 -translate-y-1/2 shrink-0 p-0.5 rounded opacity-100 md:opacity-0 md:group-hover:opacity-100 hover:bg-muted hover:text-error transition-opacity"
|
|
51
53
|
title={t.hints.closeSession}
|
|
54
|
+
aria-label={`${t.hints.closeSession}: ${title}`}
|
|
52
55
|
>
|
|
53
56
|
<X size={10} />
|
|
54
|
-
</
|
|
57
|
+
</button>
|
|
55
58
|
)}
|
|
56
|
-
</
|
|
59
|
+
</div>
|
|
57
60
|
);
|
|
58
61
|
})}
|
|
62
|
+
{hasMore && (
|
|
63
|
+
<span className="flex items-center px-2 text-2xs text-muted-foreground/60">
|
|
64
|
+
+{sessions.length - maxTabs}
|
|
65
|
+
</span>
|
|
66
|
+
)}
|
|
59
67
|
</div>
|
|
60
68
|
<button
|
|
61
69
|
type="button"
|
|
62
70
|
onClick={onNew}
|
|
63
|
-
className="shrink-0 p-2 text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors"
|
|
71
|
+
className="shrink-0 p-2 text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors rounded-lg"
|
|
64
72
|
title={t.hints.newChat}
|
|
65
73
|
>
|
|
66
74
|
<Plus size={13} />
|
|
@@ -16,11 +16,12 @@ export default function ThinkingBlock({ text, isStreaming }: ThinkingBlockProps)
|
|
|
16
16
|
if (!text && !isStreaming) return null;
|
|
17
17
|
|
|
18
18
|
return (
|
|
19
|
-
<div className="my-1 rounded-
|
|
19
|
+
<div className="my-1.5 rounded-lg border border-border/30 bg-muted/15 text-xs">
|
|
20
20
|
<button
|
|
21
21
|
type="button"
|
|
22
22
|
onClick={() => setExpanded(v => !v)}
|
|
23
|
-
|
|
23
|
+
aria-expanded={expanded}
|
|
24
|
+
className="w-full flex items-center gap-1.5 px-2.5 py-2 text-left hover:bg-muted/30 transition-colors rounded-lg"
|
|
24
25
|
>
|
|
25
26
|
{expanded ? (
|
|
26
27
|
<ChevronDown size={12} className="shrink-0 text-muted-foreground" />
|
|
@@ -35,17 +36,17 @@ export default function ThinkingBlock({ text, isStreaming }: ThinkingBlockProps)
|
|
|
35
36
|
)}
|
|
36
37
|
</span>
|
|
37
38
|
{!expanded && text && (
|
|
38
|
-
<span className="text-muted-foreground/
|
|
39
|
+
<span className="text-muted-foreground/50 truncate flex-1 ml-1">
|
|
39
40
|
{text.slice(0, 80)}{text.length > 80 ? '...' : ''}
|
|
40
41
|
</span>
|
|
41
42
|
)}
|
|
42
43
|
</button>
|
|
43
44
|
{expanded && (
|
|
44
|
-
<div className="px-2 pb-2 pt-
|
|
45
|
+
<div className="px-2.5 pb-2.5 pt-1 border-t border-border/20">
|
|
45
46
|
<div className="text-muted-foreground whitespace-pre-wrap leading-relaxed">
|
|
46
47
|
{text}
|
|
47
48
|
{isStreaming && (
|
|
48
|
-
<span className="inline-block w-1 h-3 bg-muted-foreground/40 ml-0.5 align-middle animate-pulse rounded-
|
|
49
|
+
<span className="inline-block w-1 h-3 bg-muted-foreground/40 ml-0.5 align-middle animate-pulse rounded-full" />
|
|
49
50
|
)}
|
|
50
51
|
</div>
|
|
51
52
|
</div>
|
|
@@ -101,15 +101,16 @@ export default function ToolCallBlock({ part }: { part: ToolCallPart }) {
|
|
|
101
101
|
: formatInput(part.input);
|
|
102
102
|
|
|
103
103
|
return (
|
|
104
|
-
<div className={`my-1 rounded-
|
|
104
|
+
<div className={`my-1.5 rounded-lg border text-xs font-mono ${
|
|
105
105
|
isDestructive
|
|
106
106
|
? 'border-[var(--amber)]/30 bg-background/60'
|
|
107
|
-
: 'border-border/
|
|
107
|
+
: 'border-border/40 bg-background/50'
|
|
108
108
|
}`}>
|
|
109
109
|
<button
|
|
110
110
|
type="button"
|
|
111
111
|
onClick={() => setManualToggle(v => v === null ? !expanded : !v)}
|
|
112
|
-
|
|
112
|
+
aria-expanded={expanded}
|
|
113
|
+
className="w-full flex items-center gap-1.5 px-2.5 py-2 text-left hover:bg-muted/30 transition-colors rounded-lg"
|
|
113
114
|
>
|
|
114
115
|
{expanded ? <ChevronDown size={12} className="shrink-0 text-muted-foreground" /> : <ChevronRight size={12} className="shrink-0 text-muted-foreground" />}
|
|
115
116
|
{isDestructive && <AlertTriangle size={11} className="shrink-0 text-[var(--amber)]" />}
|
|
@@ -161,19 +162,19 @@ export default function ToolCallBlock({ part }: { part: ToolCallPart }) {
|
|
|
161
162
|
</div>
|
|
162
163
|
) : (
|
|
163
164
|
/* Fallback: show input (always), output when available */
|
|
164
|
-
<div className="px-2 pb-2 pt-1 space-y-1">
|
|
165
|
+
<div className="px-2.5 pb-2.5 pt-1.5 space-y-1.5">
|
|
165
166
|
{part.state === 'running' && (
|
|
166
|
-
<div className="text-muted-foreground/60 text-2xs flex items-center gap-1">
|
|
167
|
+
<div className="text-muted-foreground/60 text-2xs flex items-center gap-1.5">
|
|
167
168
|
<Loader2 size={10} className="animate-spin" /> Running...
|
|
168
169
|
</div>
|
|
169
170
|
)}
|
|
170
|
-
<div className="text-muted-foreground">
|
|
171
|
-
<span className="font-semibold">Input: </span>
|
|
171
|
+
<div className="text-muted-foreground leading-relaxed">
|
|
172
|
+
<span className="font-semibold text-foreground/70">Input: </span>
|
|
172
173
|
<span className="break-all whitespace-pre-wrap">{JSON.stringify(part.input, null, 2)}</span>
|
|
173
174
|
</div>
|
|
174
175
|
{part.output !== undefined && part.output !== '' && (
|
|
175
|
-
<div className="text-muted-foreground">
|
|
176
|
-
<span className="font-semibold">Output: </span>
|
|
176
|
+
<div className="text-muted-foreground leading-relaxed">
|
|
177
|
+
<span className="font-semibold text-foreground/70">Output: </span>
|
|
177
178
|
<span className="break-all whitespace-pre-wrap">{part.output.length > 500 ? part.output.slice(0, 500) + '…' : part.output}</span>
|
|
178
179
|
</div>
|
|
179
180
|
)}
|
|
@@ -66,7 +66,7 @@ export default function SettingsContent({ visible, initialTab, variant, onClose
|
|
|
66
66
|
|
|
67
67
|
if (justOpened) {
|
|
68
68
|
apiFetch<SettingsData>('/api/settings').then(d => { setData(d); dataLoaded.current = true; }).catch(() => setStatus('load-error'));
|
|
69
|
-
setFont(localStorage.getItem('prose-font') === 'geist' ? 'inter' : localStorage.getItem('prose-font') ?? '
|
|
69
|
+
setFont(localStorage.getItem('prose-font') === 'geist' ? 'inter' : localStorage.getItem('prose-font') ?? 'ibm-plex-sans');
|
|
70
70
|
setFontSize(localStorage.getItem('prose-font-size') ?? '15px');
|
|
71
71
|
setContentWidth(localStorage.getItem('content-width') ?? '780px');
|
|
72
72
|
const stored = localStorage.getItem('theme');
|
|
@@ -1,26 +1,33 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mindos
|
|
3
3
|
description: >
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
distill experience, sync related docs.
|
|
4
|
+
The user's shared knowledge base — persistent across sessions and agents. MindOS stores decisions,
|
|
5
|
+
meeting notes, SOPs, debugging lessons, architecture choices, research findings, and preferences.
|
|
7
6
|
更新笔记, 搜索知识库, 整理文件, 执行SOP/工作流, 复盘, 追加CSV, 跨Agent交接,
|
|
8
7
|
路由非结构化输入到对应文件, 提炼经验, 同步关联文档.
|
|
9
8
|
NOT for editing app source, project docs, or paths outside the KB.
|
|
10
9
|
Core concepts: Space, Instruction (INSTRUCTION.md), Skill (SKILL.md); notes can embody both.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
|
|
11
|
+
Trigger on: save or record anything, search for prior notes or context, update or edit a file,
|
|
12
|
+
organize notes, run a workflow or SOP, capture decisions, append rows to a table or CSV,
|
|
13
|
+
hand off context to another agent, check if something was discussed before, look up a past
|
|
14
|
+
decision, distill lessons learned, prepare context for a meeting, quick-capture to staging area,
|
|
15
|
+
organize inbox, check knowledge health, detect conflicts or contradictions, find stale content.
|
|
16
|
+
Chinese triggers: 帮我记下来, 搜一下笔记, 更新知识库, 整理文件, 复盘, 提炼经验,
|
|
17
|
+
保存, 记录, 交接, 查一下之前的, 有没有相关笔记, 把这个存起来, 放到暂存台,
|
|
18
|
+
整理暂存台, 知识健康检查, 检测知识冲突.
|
|
19
|
+
|
|
20
|
+
Proactive behavior — do not wait for the user to mention MindOS:
|
|
21
|
+
(1) When user's question implies stored context may exist (past decisions, previous discussions,
|
|
22
|
+
meeting records) → search MindOS first, even if they don't explicitly mention it.
|
|
23
|
+
(2) After completing valuable work (bug fixed, decision made, lesson learned, architecture chosen,
|
|
24
|
+
meeting summarized) → offer to save it to MindOS for future reference.
|
|
25
|
+
(3) After a long or multi-topic conversation → suggest persisting key decisions and context.
|
|
19
26
|
---
|
|
20
27
|
|
|
21
28
|
# MindOS Skill
|
|
22
29
|
|
|
23
|
-
<!-- version: 3.
|
|
30
|
+
<!-- version: 3.2.0 — CLI-first, MCP optional -->
|
|
24
31
|
|
|
25
32
|
## CLI commands
|
|
26
33
|
|
|
@@ -85,6 +92,7 @@ npm install -g @geminilight/mindos
|
|
|
85
92
|
- **Space** — Knowledge partitions organized the way you think. Agents follow the same structure.
|
|
86
93
|
- **Instruction** — A rules file (`INSTRUCTION.md`) all connected agents obey.
|
|
87
94
|
- **Skill** — Teaches agents how to read, write, and organize the KB.
|
|
95
|
+
- **Inbox** — The `Inbox/` directory is a staging area for quick capture. Files land here when there's no obvious home yet. They get organized later — by the user manually or via AI-assisted batch organization.
|
|
88
96
|
|
|
89
97
|
Notes can embody both Instruction and Skill — they're just Markdown files in the tree.
|
|
90
98
|
|
|
@@ -99,9 +107,13 @@ User request
|
|
|
99
107
|
│ └─ [Read-only]: search → read → answer with citations. No writes.
|
|
100
108
|
│
|
|
101
109
|
├─ Save / record / update / organize specific content?
|
|
102
|
-
│ ├─
|
|
110
|
+
│ ├─ Know where it goes → [Single-file edit]
|
|
111
|
+
│ ├─ Don't know where it goes → [Inbox path] — save to Inbox/, classify later
|
|
103
112
|
│ └─ Multiple files or unclear → [Multi-file routing] — plan first
|
|
104
113
|
│
|
|
114
|
+
├─ Organize inbox / classify staged files?
|
|
115
|
+
│ └─ [Inbox organize] — read Inbox/ files, propose destinations, move after approval
|
|
116
|
+
│
|
|
105
117
|
├─ Structural change (rename / move / delete / reorganize)?
|
|
106
118
|
│ └─ [Structural path] — check backlinks before and after
|
|
107
119
|
│
|
|
@@ -111,6 +123,9 @@ User request
|
|
|
111
123
|
├─ Retrospective / distill / handoff?
|
|
112
124
|
│ └─ [Retrospective path]
|
|
113
125
|
│
|
|
126
|
+
├─ Knowledge health check / detect conflicts?
|
|
127
|
+
│ └─ [Health check path] — read references/knowledge-health.md
|
|
128
|
+
│
|
|
114
129
|
└─ Ambiguous?
|
|
115
130
|
└─ ASK. Propose 2-3 specific options based on KB state.
|
|
116
131
|
```
|
|
@@ -125,8 +140,9 @@ User request
|
|
|
125
140
|
- "organize" → ask: display only, or write back?
|
|
126
141
|
|
|
127
142
|
**File location uncertainty:**
|
|
128
|
-
- Can't decide in 5 seconds →
|
|
129
|
-
- "Just put it somewhere" →
|
|
143
|
+
- Can't decide in 5 seconds → save to `Inbox/`, inform user, propose classification later
|
|
144
|
+
- "Just put it somewhere" / "先放着" → save to `Inbox/`
|
|
145
|
+
- User drags files or pastes unstructured content without specifying location → `Inbox/`
|
|
130
146
|
|
|
131
147
|
**Scope creep:**
|
|
132
148
|
- Input routes to >5 files → pause, confirm scope
|
|
@@ -159,6 +175,42 @@ When user expresses a standing preference → read [references/preference-captur
|
|
|
159
175
|
|
|
160
176
|
When creating/rewriting an SOP → read [references/sop-template.md](./references/sop-template.md).
|
|
161
177
|
|
|
178
|
+
## Inbox (staging area)
|
|
179
|
+
|
|
180
|
+
The `Inbox/` directory is the KB's quick-capture zone. It has its own `INSTRUCTION.md` that governs behavior.
|
|
181
|
+
|
|
182
|
+
**When to use Inbox:**
|
|
183
|
+
- User says "just save it" / "先放着" / "放到暂存台" without specifying a location
|
|
184
|
+
- Content doesn't clearly fit any existing Space or directory
|
|
185
|
+
- Batch import of multiple files that need individual classification
|
|
186
|
+
|
|
187
|
+
**How to save to Inbox:**
|
|
188
|
+
```bash
|
|
189
|
+
mindos file create "Inbox/<filename>.md" --content "..."
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**How to organize Inbox:**
|
|
193
|
+
1. List Inbox files: `mindos file list Inbox/`
|
|
194
|
+
2. Read each file to understand its content
|
|
195
|
+
3. For each file, propose the best destination directory based on KB structure
|
|
196
|
+
4. Present the full routing plan to user for approval
|
|
197
|
+
5. Move files: `mindos file rename "Inbox/<file>" "<target-dir>/<file>"`
|
|
198
|
+
6. After moving, check if the target directory's README needs updating
|
|
199
|
+
|
|
200
|
+
**Aging reminder:** Files in Inbox older than 7 days are considered "aging". If you notice aging files during bootstrap, mention it: "You have N files in Inbox that have been sitting there for over a week. Want me to help organize them?"
|
|
201
|
+
|
|
202
|
+
## Knowledge health check
|
|
203
|
+
|
|
204
|
+
When user asks to check knowledge health, detect conflicts, audit quality, or says "知识健康检查" / "检测冲突" → read [references/knowledge-health.md](./references/knowledge-health.md) for the full procedure.
|
|
205
|
+
|
|
206
|
+
Quick summary of what gets checked:
|
|
207
|
+
- **Contradictions**: conflicting facts across files on the same topic
|
|
208
|
+
- **Broken links**: references to files that no longer exist
|
|
209
|
+
- **Stale content**: files with outdated date markers or untouched for >6 months
|
|
210
|
+
- **Duplicates**: two files covering the same ground without cross-referencing
|
|
211
|
+
- **Orphan files**: files with zero backlinks, hard to discover
|
|
212
|
+
- **Structural issues**: wrong directory, missing READMEs, aging Inbox files
|
|
213
|
+
|
|
162
214
|
---
|
|
163
215
|
|
|
164
216
|
## Error handling (CLI)
|
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mindos-zh
|
|
3
3
|
description: >
|
|
4
|
-
MindOS
|
|
5
|
-
|
|
4
|
+
用户的共享知识库——跨会话、跨 Agent 持久存在。MindOS 存储决策记录、会议纪要、SOP、
|
|
5
|
+
排错经验、架构选型、调研结论和偏好设置。
|
|
6
6
|
仅 mindRoot 知识库内任务。不用于:改代码仓库、项目源码、KB 外路径。
|
|
7
7
|
核心概念:空间、指令(INSTRUCTION.md)、技能(SKILL.md);笔记可承载指令与技能。
|
|
8
|
+
|
|
8
9
|
触发场景:保存或记录任何内容、搜索历史笔记或上下文、更新或编辑文件、整理或重组文件结构、
|
|
9
10
|
执行SOP或工作流、捕获对话中的决策、复盘或总结经验、追加表格或CSV数据、跨Agent交接上下文、
|
|
10
11
|
提炼经验教训、同步关联文档、查找之前是否讨论过某事、查询历史决策、查找模板或SOP、
|
|
11
|
-
|
|
12
|
+
为会议准备上下文、快速暂存到暂存台、整理暂存台、知识健康检查、检测知识冲突或矛盾、
|
|
13
|
+
查找过期内容。
|
|
12
14
|
触发词:帮我记下来、搜一下我的笔记、更新知识库、整理文件、执行工作流、保存到知识库、
|
|
13
15
|
记录一下、整理笔记、复盘、提炼经验、同步文档、查一下之前的记录、有没有相关的笔记、
|
|
14
|
-
我之前写过什么、把这个存起来、总结一下保存、交接给其他Agent
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
我之前写过什么、把这个存起来、总结一下保存、交接给其他Agent、追加到表格、
|
|
17
|
+
放到暂存台、整理暂存台、知识健康检查、检测知识冲突。
|
|
18
|
+
English triggers: save, record, search notes, organize, retrospective, handoff, lessons learned,
|
|
19
|
+
inbox, staging, knowledge health, detect conflicts.
|
|
20
|
+
|
|
21
|
+
主动行为——不要等用户提到 MindOS:
|
|
22
|
+
(1) 用户的问题暗示可能存在历史记录(过去的决策、之前的讨论、会议纪要)→ 先搜 MindOS,
|
|
23
|
+
即使没有明确提到知识库。
|
|
24
|
+
(2) 完成有价值的工作后(修了 bug、做了决策、总结了经验、选定了架构、开完了会)→
|
|
25
|
+
主动提议保存到 MindOS,方便以后查阅。
|
|
26
|
+
(3) 经历了较长或多主题的对话后 → 建议把关键决策和上下文持久化。
|
|
18
27
|
---
|
|
19
28
|
|
|
20
29
|
# MindOS 技能
|
|
21
30
|
|
|
22
|
-
<!-- version: 3.
|
|
31
|
+
<!-- version: 3.2.0 — CLI 优先,MCP 可选 -->
|
|
23
32
|
|
|
24
33
|
## CLI 命令
|
|
25
34
|
|
|
@@ -84,6 +93,7 @@ npm install -g @geminilight/mindos
|
|
|
84
93
|
- **空间 (Space)** — 按你的思维方式组织的知识分区。Agent 遵循相同结构。
|
|
85
94
|
- **指令 (Instruction)** — `INSTRUCTION.md`,所有连接的 Agent 都遵守的规则文件。
|
|
86
95
|
- **技能 (Skill)** — 教 Agent 如何读写和整理知识库。
|
|
96
|
+
- **暂存台 (Inbox)** — `Inbox/` 目录是快速捕获区。内容暂时找不到归属时先放这里,之后再统一整理——用户手动或 AI 辅助批量归类。
|
|
87
97
|
|
|
88
98
|
笔记可以同时承载指令和技能——它们只是目录树中的 Markdown 文件。
|
|
89
99
|
|
|
@@ -98,9 +108,13 @@ npm install -g @geminilight/mindos
|
|
|
98
108
|
│ └─ [只读路径]:搜索 → 读取 → 带引用回答。不写入。
|
|
99
109
|
│
|
|
100
110
|
├─ 保存 / 记录 / 更新 / 整理具体内容?
|
|
101
|
-
│ ├─
|
|
111
|
+
│ ├─ 知道放哪 → [单文件编辑]
|
|
112
|
+
│ ├─ 不知道放哪 → [暂存台路径] — 存到 Inbox/,之后再归类
|
|
102
113
|
│ └─ 多文件或不确定 → [多文件路由] — 先出方案
|
|
103
114
|
│
|
|
115
|
+
├─ 整理暂存台 / 归类暂存文件?
|
|
116
|
+
│ └─ [暂存台整理] — 读 Inbox/ 文件,提议目标位置,获批后移动
|
|
117
|
+
│
|
|
104
118
|
├─ 结构变更(重命名 / 移动 / 删除 / 重组)?
|
|
105
119
|
│ └─ [结构路径] — 变更前后检查反向链接
|
|
106
120
|
│
|
|
@@ -110,6 +124,9 @@ npm install -g @geminilight/mindos
|
|
|
110
124
|
├─ 复盘 / 提炼 / 交接?
|
|
111
125
|
│ └─ [复盘路径]
|
|
112
126
|
│
|
|
127
|
+
├─ 知识健康检查 / 检测冲突?
|
|
128
|
+
│ └─ [健康检查路径] — 读取 references/knowledge-health.md
|
|
129
|
+
│
|
|
113
130
|
└─ 模糊?
|
|
114
131
|
└─ 提问。基于知识库状态提出 2-3 个具体选项。
|
|
115
132
|
```
|
|
@@ -124,8 +141,9 @@ npm install -g @geminilight/mindos
|
|
|
124
141
|
- "整理一下" → 先问:仅展示,还是写回知识库?
|
|
125
142
|
|
|
126
143
|
**文件位置不确定:**
|
|
127
|
-
- 5 秒内定不了 →
|
|
128
|
-
- "随便放哪" →
|
|
144
|
+
- 5 秒内定不了 → 存到 `Inbox/`,告知用户,之后提议归类
|
|
145
|
+
- "随便放哪" / "先放着" → 存到 `Inbox/`
|
|
146
|
+
- 用户拖拽文件或粘贴非结构化内容但没指定位置 → `Inbox/`
|
|
129
147
|
|
|
130
148
|
**范围蔓延:**
|
|
131
149
|
- 输入路由到 >5 个文件 → 暂停确认
|
|
@@ -158,6 +176,44 @@ npm install -g @geminilight/mindos
|
|
|
158
176
|
|
|
159
177
|
创建/重写工作流 SOP 时 → 读取 [references/sop-template.md](./references/sop-template.md)。
|
|
160
178
|
|
|
179
|
+
## 暂存台 (Inbox)
|
|
180
|
+
|
|
181
|
+
`Inbox/` 目录是知识库的快速捕获区,有自己的 `INSTRUCTION.md` 约束行为。
|
|
182
|
+
|
|
183
|
+
**何时使用暂存台:**
|
|
184
|
+
- 用户说"先存着" / "放到暂存台" / "随便放哪",没指定具体位置
|
|
185
|
+
- 内容明显不属于任何现有空间或目录
|
|
186
|
+
- 批量导入多个文件,需要逐个归类
|
|
187
|
+
|
|
188
|
+
**如何存到暂存台:**
|
|
189
|
+
```bash
|
|
190
|
+
mindos file create "Inbox/<文件名>.md" --content "..."
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**如何整理暂存台:**
|
|
194
|
+
1. 列出暂存文件:`mindos file list Inbox/`
|
|
195
|
+
2. 读取每个文件,理解其内容
|
|
196
|
+
3. 根据知识库结构,为每个文件提议最佳目标目录
|
|
197
|
+
4. 向用户展示完整路由方案,获批后执行
|
|
198
|
+
5. 移动文件:`mindos file rename "Inbox/<文件>" "<目标目录>/<文件>"`
|
|
199
|
+
6. 移动后检查目标目录的 README 是否需要更新
|
|
200
|
+
|
|
201
|
+
**老化提醒:** Inbox 中超过 7 天的文件视为"老化"。如果在 bootstrap 时发现老化文件,主动提醒:
|
|
202
|
+
"暂存台有 N 个文件已经放了一周以上了,要我帮你整理一下吗?"
|
|
203
|
+
|
|
204
|
+
## 知识健康检查
|
|
205
|
+
|
|
206
|
+
用户要求检查知识库健康度、检测冲突、审计质量,或说"知识健康检查" / "检测冲突" / "check knowledge health" 时
|
|
207
|
+
→ 读取 [references/knowledge-health.md](./references/knowledge-health.md) 获取完整流程。
|
|
208
|
+
|
|
209
|
+
检查维度速览:
|
|
210
|
+
- **矛盾/冲突**:同一主题的不同文件说法互相矛盾
|
|
211
|
+
- **断裂链接**:引用了不存在的文件
|
|
212
|
+
- **过期内容**:带有过期日期标记的文件,或超过 6 个月未更新的活跃主题
|
|
213
|
+
- **重复内容**:两个文件覆盖同一主题且没有互相引用
|
|
214
|
+
- **孤立文件**:零反向链接,难以被发现
|
|
215
|
+
- **结构问题**:文件放错目录、缺少 README、暂存台老化文件
|
|
216
|
+
|
|
161
217
|
---
|
|
162
218
|
|
|
163
219
|
## 错误处理(CLI)
|