@geminilight/mindos 0.6.40 → 0.6.41
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 +18 -18
- 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 +5 -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/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.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.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.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.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.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.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.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.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.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.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.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.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.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.js.nft.json +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.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.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.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.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.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.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.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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 -2
- 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 +18 -18
- package/_standalone/.next/server/chunks/1550.js +1 -1
- package/_standalone/.next/server/chunks/2190.js +11 -0
- package/_standalone/.next/server/chunks/{6365.js → 2536.js} +2 -2
- package/_standalone/.next/server/chunks/5648.js +2 -0
- package/_standalone/.next/server/chunks/8388.js +1 -1
- package/_standalone/.next/server/chunks/953.js +1 -1
- package/_standalone/.next/server/chunks/9539.js +219 -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/next-font-manifest.js +1 -1
- package/_standalone/.next/server/next-font-manifest.json +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-b70535785cc5aaee.js +29 -0
- package/_standalone/.next/static/chunks/{8663-de911d2d395622be.js → 1880-c2a9e76201841c86.js} +1 -1
- package/_standalone/.next/static/chunks/3637.0541ac2d0ea7de1f.js +1 -0
- package/_standalone/.next/static/chunks/4563-b2a2ce80aff845af.js +6 -0
- package/_standalone/.next/static/chunks/6981-3d7dcac2d12a5670.js +1 -0
- package/_standalone/.next/static/chunks/7144-5febf62f1a79fe64.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-773071a99c4daac2.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/page-6102a884b2cb3cfe.js +5 -0
- package/_standalone/.next/static/chunks/app/help/page-2325d25b6846ca07.js +1 -0
- package/_standalone/.next/static/chunks/app/{layout-9378c1c8d3e5761b.js → layout-42cdbce19f404567.js} +34 -34
- package/_standalone/.next/static/chunks/app/{page-9bae420fbbdc5fff.js → page-8c9643b649e01735.js} +1 -1
- package/_standalone/.next/static/chunks/app/setup/page-d158b8cb533feb1e.js +1 -0
- package/_standalone/.next/static/chunks/app/trash/{page-b61ef2d5cd4f8d73.js → page-e9ab74ffeb96af41.js} +1 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-764a69a1c8bd4eef.js +12 -0
- package/_standalone/.next/static/chunks/{webpack-c28c55d0a6021a6b.js → webpack-7b276daaa930d480.js} +1 -1
- package/_standalone/.next/static/css/bc9179074eaf65ae.css +1 -0
- package/_standalone/.next/trace +63 -63
- package/_standalone/__tests__/api/mcp-install.test.ts +23 -0
- package/_standalone/__tests__/cli/agent-routing.test.ts +232 -0
- package/_standalone/__tests__/cli/file-subcommands.test.ts +379 -0
- package/_standalone/__tests__/core/tools.test.ts +3 -6
- package/_standalone/components/FileTree.tsx +3 -2
- package/_standalone/components/MarkdownView.tsx +30 -15
- package/_standalone/components/RightAskPanel.tsx +36 -6
- package/_standalone/components/Sidebar.tsx +3 -3
- package/_standalone/components/agents/AgentsMcpSection.tsx +3 -0
- package/_standalone/components/settings/McpAgentInstall.tsx +94 -27
- package/_standalone/components/settings/McpSkillsSection.tsx +1 -1
- package/_standalone/components/settings/McpTab.tsx +484 -340
- package/_standalone/components/settings/SettingsContent.tsx +12 -6
- package/_standalone/components/settings/types.ts +3 -0
- package/_standalone/components/setup/StepAgents.tsx +113 -47
- package/_standalone/components/setup/StepReview.tsx +14 -27
- package/_standalone/components/setup/types.ts +6 -0
- package/_standalone/data/skills/mindos/SKILL.md +92 -92
- package/_standalone/data/skills/mindos/references/write-supplement.md +119 -0
- package/_standalone/data/skills/mindos-zh/SKILL.md +100 -104
- package/_standalone/data/skills/mindos-zh/references/write-supplement.md +119 -0
- package/_standalone/lib/i18n/modules/features.ts +4 -4
- package/_standalone/lib/i18n/modules/knowledge.ts +4 -0
- package/_standalone/lib/i18n/modules/onboarding.ts +40 -30
- package/_standalone/lib/i18n/modules/settings.ts +78 -6
- package/_standalone/lib/mcp-snippets.ts +5 -1
- package/_standalone/tsconfig.tsbuildinfo +1 -1
- package/app/app/api/ask/route.ts +3 -2
- package/app/app/api/mcp/install/route.ts +2 -1
- package/app/app/api/mcp/status/route.ts +14 -6
- package/app/app/view/[...path]/ViewPageClient.tsx +12 -27
- package/app/components/FileTree.tsx +3 -2
- package/app/components/MarkdownView.tsx +30 -15
- package/app/components/RightAskPanel.tsx +36 -6
- package/app/components/Sidebar.tsx +3 -3
- package/app/components/agents/AgentsMcpSection.tsx +3 -0
- package/app/components/help/HelpContent.tsx +1 -0
- package/app/components/settings/McpAgentInstall.tsx +94 -27
- package/app/components/settings/McpSkillsSection.tsx +1 -1
- package/app/components/settings/McpTab.tsx +484 -340
- package/app/components/settings/SettingsContent.tsx +12 -6
- package/app/components/settings/types.ts +3 -0
- package/app/components/setup/StepAgents.tsx +113 -47
- package/app/components/setup/StepReview.tsx +14 -27
- package/app/components/setup/index.tsx +12 -11
- package/app/components/setup/types.ts +6 -0
- package/app/data/skills/mindos/SKILL.md +92 -92
- package/app/data/skills/mindos/references/write-supplement.md +119 -0
- package/app/data/skills/mindos-zh/SKILL.md +100 -104
- package/app/data/skills/mindos-zh/references/write-supplement.md +119 -0
- package/app/lib/fs.ts +0 -6
- package/app/lib/i18n/modules/features.ts +4 -4
- package/app/lib/i18n/modules/knowledge.ts +4 -0
- package/app/lib/i18n/modules/onboarding.ts +40 -30
- package/app/lib/i18n/modules/settings.ts +78 -6
- package/app/lib/mcp-agents.ts +1 -2
- package/app/lib/mcp-snippets.ts +5 -1
- package/app/lib/renderers/index.ts +2 -1
- package/bin/cli.js +168 -1404
- package/bin/commands/agent.js +156 -20
- package/bin/commands/api.js +14 -11
- package/bin/commands/ask.js +79 -68
- package/bin/commands/build.js +26 -0
- package/bin/commands/config.js +170 -0
- package/bin/commands/dev.js +58 -0
- package/bin/commands/doctor.js +205 -0
- package/bin/commands/file.js +551 -36
- package/bin/commands/gateway.js +42 -0
- package/bin/commands/init-skills.js +56 -0
- package/bin/commands/logs.js +32 -0
- package/bin/commands/mcp-cmd.js +57 -0
- package/bin/commands/onboard.js +25 -0
- package/bin/commands/open.js +41 -0
- package/bin/commands/restart.js +48 -0
- package/bin/commands/search.js +16 -14
- package/bin/commands/space.js +96 -25
- package/bin/commands/start.js +262 -0
- package/bin/commands/status.js +2 -2
- package/bin/commands/stop.js +14 -0
- package/bin/commands/sync-cmd.js +134 -0
- package/bin/commands/token.js +98 -0
- package/bin/commands/uninstall.js +154 -0
- package/bin/commands/update.js +286 -0
- package/bin/lib/build.js +1 -1
- package/bin/lib/colors.js +8 -7
- package/bin/lib/command.js +37 -96
- package/bin/lib/config.js +5 -0
- package/bin/lib/csv.js +19 -0
- package/bin/lib/jsonc.js +12 -0
- package/bin/lib/markdown.js +69 -0
- package/bin/lib/mcp-agents.js +1 -6
- package/bin/lib/mcp-build.js +1 -1
- package/bin/lib/mcp-install.js +2 -1
- package/bin/lib/one-shot.js +88 -0
- package/bin/lib/path-expand.js +9 -0
- package/bin/lib/remote.js +65 -0
- package/bin/lib/repl.js +167 -0
- package/bin/lib/{utils.js → shell.js} +10 -26
- package/bin/lib/skill-check.js +1 -1
- package/bin/lib/sse-stream.js +167 -0
- package/package.json +2 -2
- package/scripts/setup.js +182 -120
- package/skills/mindos/SKILL.md +92 -92
- package/skills/mindos-zh/SKILL.md +100 -104
- package/_standalone/.next/server/chunks/1955.js +0 -11
- package/_standalone/.next/server/chunks/3680.js +0 -1
- package/_standalone/.next/server/chunks/4497.js +0 -219
- package/_standalone/.next/server/chunks/5560.js +0 -2
- package/_standalone/.next/static/chunks/1053-0adaccc98a752a58.js +0 -29
- package/_standalone/.next/static/chunks/3637.f9a42cca59fd5bb5.js +0 -1
- package/_standalone/.next/static/chunks/4563-c2afaeacb241d1d0.js +0 -6
- package/_standalone/.next/static/chunks/6090-c98268ca726a68d3.js +0 -1
- package/_standalone/.next/static/chunks/9371-575600301da5d6bb.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-3e08abb495ecd5fd.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/page-e7e0f87ad3d765ac.js +0 -5
- package/_standalone/.next/static/chunks/app/help/page-3d0e1ceaa4abc243.js +0 -1
- package/_standalone/.next/static/chunks/app/setup/page-99ed3d1bb6b8f4ef.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-44fa78cbea613a78.js +0 -12
- package/_standalone/.next/static/css/d300701f384db50d.css +0 -1
- package/_standalone/components/renderers/agent-inspector/manifest.ts +0 -16
- /package/_standalone/.next/static/{rZLs1krFuduixvcVNe6q3 → Ij3PFh-a0zi5K_ANoSAW0}/_buildManifest.js +0 -0
- /package/_standalone/.next/static/{rZLs1krFuduixvcVNe6q3 → Ij3PFh-a0zi5K_ANoSAW0}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mindos start — production app + MCP server
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { execSync, execFileSync } from 'node:child_process';
|
|
6
|
+
import {
|
|
7
|
+
existsSync,
|
|
8
|
+
readFileSync,
|
|
9
|
+
mkdirSync,
|
|
10
|
+
cpSync,
|
|
11
|
+
unlinkSync,
|
|
12
|
+
} from 'node:fs';
|
|
13
|
+
import { resolve } from 'node:path';
|
|
14
|
+
|
|
15
|
+
import { ROOT, CONFIG_PATH, LOG_PATH } from '../lib/constants.js';
|
|
16
|
+
import { dim, cyan, green, red, yellow } from '../lib/colors.js';
|
|
17
|
+
import { loadConfig, isDaemonMode } from '../lib/config.js';
|
|
18
|
+
import {
|
|
19
|
+
ensureAppDeps,
|
|
20
|
+
needsBuild,
|
|
21
|
+
cleanNextDir,
|
|
22
|
+
writeBuildStamp,
|
|
23
|
+
hasPrebuiltStandalone,
|
|
24
|
+
} from '../lib/build.js';
|
|
25
|
+
import { assertPortFree } from '../lib/port.js';
|
|
26
|
+
import { savePids, clearPids } from '../lib/pid.js';
|
|
27
|
+
import { killByPort } from '../lib/stop.js';
|
|
28
|
+
import { printStartupInfo } from '../lib/startup.js';
|
|
29
|
+
import { spawnMcp } from '../lib/mcp-spawn.js';
|
|
30
|
+
import { EXIT } from '../lib/command.js';
|
|
31
|
+
import { execInherited } from '../lib/shell.js';
|
|
32
|
+
|
|
33
|
+
/** Local Next.js binary (avoids a mismatched global `next`). */
|
|
34
|
+
const NEXT_BIN = resolve(ROOT, 'app', 'node_modules', '.bin', 'next');
|
|
35
|
+
|
|
36
|
+
/** Command metadata for registry / help. */
|
|
37
|
+
export const meta = {
|
|
38
|
+
name: 'start',
|
|
39
|
+
group: 'Service',
|
|
40
|
+
summary: 'Start MindOS services',
|
|
41
|
+
usage: 'mindos start',
|
|
42
|
+
flags: {
|
|
43
|
+
'--daemon': 'Run as background daemon',
|
|
44
|
+
'--verbose': 'Show detailed output',
|
|
45
|
+
'--port <port>': 'Override web port',
|
|
46
|
+
},
|
|
47
|
+
examples: [
|
|
48
|
+
'mindos start',
|
|
49
|
+
'mindos start --daemon',
|
|
50
|
+
'mindos start --verbose',
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Start MindOS in production (foreground or OS service when `--daemon` / config daemon mode).
|
|
56
|
+
*
|
|
57
|
+
* @param {string[]} args — forwarded to `next start` after `-p <port>`
|
|
58
|
+
* @param {Record<string, unknown>} flags — e.g. `daemon`, `verbose`
|
|
59
|
+
* @returns {Promise<void>}
|
|
60
|
+
*/
|
|
61
|
+
export const run = async (args, flags) => {
|
|
62
|
+
const isDaemon = Boolean(flags.daemon) || isDaemonMode();
|
|
63
|
+
const isVerbose = Boolean(flags.verbose);
|
|
64
|
+
const extra = args.join(' ');
|
|
65
|
+
|
|
66
|
+
// Check for incomplete setup
|
|
67
|
+
if (existsSync(CONFIG_PATH)) {
|
|
68
|
+
try {
|
|
69
|
+
const cfg = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
|
|
70
|
+
if (cfg.setupPending === true) {
|
|
71
|
+
console.log(
|
|
72
|
+
`\n ${yellow('⚠ Setup was not completed.')} Run ${cyan('mindos onboard')} to finish, or ${cyan('mindos config set setupPending false')} to dismiss.\n`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
} catch { /* ignore malformed config */ }
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (isDaemon) {
|
|
79
|
+
const { getPlatform, runGatewayCommand, waitForHttp } = await import('../lib/gateway.js');
|
|
80
|
+
const platform = getPlatform();
|
|
81
|
+
if (!platform) {
|
|
82
|
+
console.warn(
|
|
83
|
+
yellow('Warning: daemon mode not supported on this platform. Falling back to foreground.'),
|
|
84
|
+
);
|
|
85
|
+
} else {
|
|
86
|
+
loadConfig();
|
|
87
|
+
if (!process.env.MINDOS_WEB_PORT) process.env.MINDOS_WEB_PORT = '3456';
|
|
88
|
+
if (!process.env.MINDOS_MCP_PORT) process.env.MINDOS_MCP_PORT = '8781';
|
|
89
|
+
const webPort = process.env.MINDOS_WEB_PORT;
|
|
90
|
+
const mcpPort = process.env.MINDOS_MCP_PORT;
|
|
91
|
+
console.log(cyan(`Installing MindOS as a background service (${platform})...`));
|
|
92
|
+
await runGatewayCommand('install');
|
|
93
|
+
// install() already starts the service via launchctl bootstrap + RunAtLoad=true.
|
|
94
|
+
// Do NOT call start() here — kickstart -k would kill the just-started process,
|
|
95
|
+
// causing a port-conflict race condition with KeepAlive restart loops.
|
|
96
|
+
console.log(
|
|
97
|
+
dim(' (First run may take a few minutes to install dependencies and build the app.)'),
|
|
98
|
+
);
|
|
99
|
+
const ready = await waitForHttp(Number(webPort), {
|
|
100
|
+
retries: 180,
|
|
101
|
+
intervalMs: 2000,
|
|
102
|
+
label: 'Web UI',
|
|
103
|
+
logFile: LOG_PATH,
|
|
104
|
+
});
|
|
105
|
+
if (!ready) {
|
|
106
|
+
console.error(red('\n✘ Service started but Web UI did not become ready in time.'));
|
|
107
|
+
console.error(dim(' Check logs with: mindos logs\n'));
|
|
108
|
+
process.exit(EXIT.ERROR);
|
|
109
|
+
}
|
|
110
|
+
await printStartupInfo(webPort, mcpPort);
|
|
111
|
+
// System notification
|
|
112
|
+
try {
|
|
113
|
+
if (process.platform === 'darwin') {
|
|
114
|
+
execSync(
|
|
115
|
+
`osascript -e 'display notification "http://localhost:${webPort}" with title "MindOS Ready"'`,
|
|
116
|
+
{ stdio: 'ignore' },
|
|
117
|
+
);
|
|
118
|
+
} else if (process.platform === 'linux') {
|
|
119
|
+
execSync(`notify-send "MindOS Ready" "http://localhost:${webPort}"`, { stdio: 'ignore' });
|
|
120
|
+
}
|
|
121
|
+
} catch { /* notification is best-effort */ }
|
|
122
|
+
console.log(`${green('✔ MindOS is running as a background service')}`);
|
|
123
|
+
console.log(dim(' View logs: mindos logs'));
|
|
124
|
+
console.log(dim(' Stop: mindos gateway stop'));
|
|
125
|
+
console.log(dim(' Uninstall: mindos gateway uninstall\n'));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
loadConfig();
|
|
131
|
+
if (!process.env.MINDOS_WEB_PORT) process.env.MINDOS_WEB_PORT = '3456';
|
|
132
|
+
if (!process.env.MINDOS_MCP_PORT) process.env.MINDOS_MCP_PORT = '8781';
|
|
133
|
+
const webPort = process.env.MINDOS_WEB_PORT;
|
|
134
|
+
const mcpPort = process.env.MINDOS_MCP_PORT;
|
|
135
|
+
|
|
136
|
+
// Clean up zombie processes from an abandoned GUI setup session.
|
|
137
|
+
// setup.js records a temporary port (setupPort) in config; if the user
|
|
138
|
+
// closed the browser without completing setup, that process is still
|
|
139
|
+
// running. Kill it before we proceed.
|
|
140
|
+
// Also read config for auto-migration below (avoids double readFileSync).
|
|
141
|
+
let startupCfg = {};
|
|
142
|
+
try {
|
|
143
|
+
startupCfg = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
|
|
144
|
+
} catch { /* ignore */ }
|
|
145
|
+
if (startupCfg.setupPort && Number(startupCfg.setupPort) !== Number(webPort)) {
|
|
146
|
+
killByPort(Number(startupCfg.setupPort));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ── Auto-migrate user preferences → .mindos/user-preferences.md ────────
|
|
150
|
+
try {
|
|
151
|
+
const mr = startupCfg.mindRoot;
|
|
152
|
+
if (mr && existsSync(mr)) {
|
|
153
|
+
const mindosDir = resolve(mr, '.mindos');
|
|
154
|
+
const newPath = resolve(mindosDir, 'user-preferences.md');
|
|
155
|
+
|
|
156
|
+
if (!existsSync(newPath)) {
|
|
157
|
+
// Ensure .mindos/ directory exists
|
|
158
|
+
if (!existsSync(mindosDir)) mkdirSync(mindosDir, { recursive: true });
|
|
159
|
+
|
|
160
|
+
// Try migrate from previous locations (newest → oldest)
|
|
161
|
+
const prevPaths = [
|
|
162
|
+
resolve(mindosDir, 'user-rules.md'), // v0.6.x interim
|
|
163
|
+
resolve(mr, 'user-skill-rules.md'), // v0.5.x root
|
|
164
|
+
];
|
|
165
|
+
let migrated = false;
|
|
166
|
+
for (const prev of prevPaths) {
|
|
167
|
+
if (existsSync(prev)) {
|
|
168
|
+
cpSync(prev, newPath);
|
|
169
|
+
unlinkSync(prev);
|
|
170
|
+
console.log(
|
|
171
|
+
` ${green('✓')} ${dim(`Migrated ${prev.split('/').pop()} → .mindos/user-preferences.md`)}`,
|
|
172
|
+
);
|
|
173
|
+
migrated = true;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (!migrated) {
|
|
178
|
+
// Try legacy location (.agents/skills/{name}/user-rules.md)
|
|
179
|
+
const isZh = startupCfg.disabledSkills?.includes('mindos');
|
|
180
|
+
const sName = isZh ? 'mindos-zh' : 'mindos';
|
|
181
|
+
const oldPath = resolve(mr, '.agents', 'skills', sName, 'user-rules.md');
|
|
182
|
+
if (existsSync(oldPath)) {
|
|
183
|
+
cpSync(oldPath, newPath);
|
|
184
|
+
console.log(
|
|
185
|
+
` ${green('✓')} ${dim('Migrated .agents/skills/ user-rules.md → .mindos/user-preferences.md')}`,
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} catch { /* best-effort, don't block startup */ }
|
|
192
|
+
|
|
193
|
+
// When launched by a daemon manager (launchd/systemd), wait for ports to
|
|
194
|
+
// free instead of exiting immediately — the previous instance may still be
|
|
195
|
+
// shutting down after a restart/update.
|
|
196
|
+
const launchedByDaemon =
|
|
197
|
+
process.env.LAUNCHED_BY_LAUNCHD === '1' || !!process.env.INVOCATION_ID; /* systemd sets INVOCATION_ID */
|
|
198
|
+
|
|
199
|
+
if (launchedByDaemon) {
|
|
200
|
+
const { waitForPortFree } = await import('../lib/gateway.js');
|
|
201
|
+
const webOk = await waitForPortFree(Number(webPort), { retries: 60, intervalMs: 500 });
|
|
202
|
+
const mcpOk = await waitForPortFree(Number(mcpPort), { retries: 60, intervalMs: 500 });
|
|
203
|
+
if (!webOk || !mcpOk) {
|
|
204
|
+
console.error('Ports still in use after 30s, exiting.');
|
|
205
|
+
process.exit(EXIT.ERROR); // KeepAlive will retry after ThrottleInterval
|
|
206
|
+
}
|
|
207
|
+
} else {
|
|
208
|
+
await assertPortFree(Number(webPort), 'web');
|
|
209
|
+
await assertPortFree(Number(mcpPort), 'mcp');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
process.env.MINDOS_CLI_PATH = resolve(ROOT, 'bin', 'cli.js');
|
|
213
|
+
process.env.MINDOS_NODE_BIN = process.execPath;
|
|
214
|
+
ensureAppDeps();
|
|
215
|
+
if (needsBuild()) {
|
|
216
|
+
console.log(yellow('Building MindOS (first run or new version detected)...\n'));
|
|
217
|
+
cleanNextDir();
|
|
218
|
+
execInherited('node scripts/gen-renderer-index.js', ROOT);
|
|
219
|
+
execInherited(`${NEXT_BIN} build --webpack`, resolve(ROOT, 'app'));
|
|
220
|
+
writeBuildStamp();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const { stopSyncDaemon, startSyncDaemon } = await import('../lib/sync.js');
|
|
224
|
+
|
|
225
|
+
const mcp = spawnMcp(isVerbose);
|
|
226
|
+
savePids(process.pid, mcp.pid);
|
|
227
|
+
process.on('exit', () => {
|
|
228
|
+
try { stopSyncDaemon(); } catch {}
|
|
229
|
+
clearPids();
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const mindRoot = process.env.MIND_ROOT;
|
|
233
|
+
if (mindRoot) {
|
|
234
|
+
startSyncDaemon(mindRoot).catch(() => {});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
await printStartupInfo(webPort, mcpPort);
|
|
238
|
+
|
|
239
|
+
// Prefer prebuilt standalone server (shipped with npm package) over next start.
|
|
240
|
+
// Standalone includes its own traced node_modules — no app/node_modules needed.
|
|
241
|
+
if (hasPrebuiltStandalone()) {
|
|
242
|
+
const standaloneServer = resolve(ROOT, '_standalone', 'server.js');
|
|
243
|
+
try {
|
|
244
|
+
execFileSync(process.execPath, [standaloneServer], {
|
|
245
|
+
cwd: resolve(ROOT, '_standalone'),
|
|
246
|
+
stdio: 'inherit',
|
|
247
|
+
env: {
|
|
248
|
+
...process.env,
|
|
249
|
+
NODE_ENV: 'production',
|
|
250
|
+
HOSTNAME: process.env.MINDOS_WEB_HOST || '0.0.0.0',
|
|
251
|
+
PORT: webPort,
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
} catch (err) {
|
|
255
|
+
process.exit(err.status || 1);
|
|
256
|
+
}
|
|
257
|
+
} else {
|
|
258
|
+
execInherited(`${NEXT_BIN} start -p ${webPort} ${extra}`, resolve(ROOT, 'app'), {
|
|
259
|
+
HOSTNAME: process.env.MINDOS_WEB_HOST || '0.0.0.0',
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
};
|
package/bin/commands/status.js
CHANGED
|
@@ -12,8 +12,8 @@ import { resolve } from 'node:path';
|
|
|
12
12
|
|
|
13
13
|
export const meta = {
|
|
14
14
|
name: 'status',
|
|
15
|
-
group: '
|
|
16
|
-
summary: 'Show
|
|
15
|
+
group: 'Service',
|
|
16
|
+
summary: 'Show service status',
|
|
17
17
|
usage: 'mindos status',
|
|
18
18
|
examples: [
|
|
19
19
|
'mindos status',
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mindos stop — Stop running MindOS processes
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { stopMindos } from '../lib/stop.js';
|
|
6
|
+
|
|
7
|
+
export const meta = {
|
|
8
|
+
name: 'stop',
|
|
9
|
+
group: 'Service',
|
|
10
|
+
summary: 'Stop services',
|
|
11
|
+
usage: 'mindos stop',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const run = () => stopMindos();
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mindos sync — Cross-device knowledge base sync (git-based).
|
|
3
|
+
*
|
|
4
|
+
* Subcommands: init, now, conflicts, on, off. Default: print status.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { bold, dim, cyan, green, red, yellow } from '../lib/colors.js';
|
|
8
|
+
import { loadConfig } from '../lib/config.js';
|
|
9
|
+
import { EXIT } from '../lib/command.js';
|
|
10
|
+
|
|
11
|
+
export const meta = {
|
|
12
|
+
name: 'sync',
|
|
13
|
+
group: 'Sync',
|
|
14
|
+
summary: 'Git sync (init/now/conflicts/on/off)',
|
|
15
|
+
usage: 'mindos sync [subcommand]',
|
|
16
|
+
flags: {
|
|
17
|
+
'--remote <url>': 'Git remote URL for init',
|
|
18
|
+
'--token <token>': 'Auth token for private repo',
|
|
19
|
+
'--branch <name>': 'Git branch (default: main)',
|
|
20
|
+
'--json': 'Output as JSON',
|
|
21
|
+
},
|
|
22
|
+
examples: [
|
|
23
|
+
'mindos sync',
|
|
24
|
+
'mindos sync init --remote https://github.com/user/repo.git',
|
|
25
|
+
'mindos sync now',
|
|
26
|
+
'mindos sync conflicts',
|
|
27
|
+
'mindos sync on',
|
|
28
|
+
'mindos sync off',
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const run = async (args, flags) => {
|
|
33
|
+
const sub = args[0];
|
|
34
|
+
loadConfig();
|
|
35
|
+
const mindRoot = process.env.MIND_ROOT;
|
|
36
|
+
|
|
37
|
+
const {
|
|
38
|
+
initSync,
|
|
39
|
+
getSyncStatus,
|
|
40
|
+
manualSync,
|
|
41
|
+
listConflicts,
|
|
42
|
+
setSyncEnabled,
|
|
43
|
+
stopSyncDaemon,
|
|
44
|
+
} = await import('../lib/sync.js');
|
|
45
|
+
|
|
46
|
+
if (sub === 'init') {
|
|
47
|
+
// Flags are already parsed by parseArgs into flags
|
|
48
|
+
const nonInteractive = flags['non-interactive'] === true;
|
|
49
|
+
|
|
50
|
+
if (nonInteractive) {
|
|
51
|
+
await initSync(mindRoot, {
|
|
52
|
+
nonInteractive: true,
|
|
53
|
+
remote: typeof flags.remote === 'string' ? flags.remote : '',
|
|
54
|
+
token: typeof flags.token === 'string' ? flags.token : '',
|
|
55
|
+
branch: (typeof flags.branch === 'string' ? flags.branch : '') || 'main',
|
|
56
|
+
});
|
|
57
|
+
} else {
|
|
58
|
+
await initSync(mindRoot);
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (sub === 'now') {
|
|
64
|
+
try {
|
|
65
|
+
console.log(dim('Pulling...'));
|
|
66
|
+
await manualSync(mindRoot);
|
|
67
|
+
console.log(green('✔ Sync complete'));
|
|
68
|
+
} catch (err) {
|
|
69
|
+
console.error(red(err.message));
|
|
70
|
+
process.exit(EXIT.ERROR);
|
|
71
|
+
}
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (sub === 'conflicts') {
|
|
76
|
+
await listConflicts(mindRoot);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (sub === 'on') {
|
|
81
|
+
await setSyncEnabled(true);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (sub === 'off') {
|
|
86
|
+
await setSyncEnabled(false);
|
|
87
|
+
await stopSyncDaemon();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Unknown subcommand check
|
|
92
|
+
if (sub) {
|
|
93
|
+
const validSubs = ['init', 'now', 'conflicts', 'on', 'off'];
|
|
94
|
+
if (!validSubs.includes(sub)) {
|
|
95
|
+
console.error(red(`Unknown sync subcommand: ${sub}`));
|
|
96
|
+
console.error(dim(`Available: ${validSubs.join(' | ')}`));
|
|
97
|
+
process.exit(EXIT.ARGS);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// default: sync status
|
|
102
|
+
const status = await getSyncStatus(mindRoot);
|
|
103
|
+
|
|
104
|
+
if (flags.json) {
|
|
105
|
+
console.log(JSON.stringify(status, null, 2));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (!status.enabled) {
|
|
110
|
+
console.log(`\n${bold('Sync Status')}`);
|
|
111
|
+
console.log(dim(' Not configured. Run `mindos sync init` to set up.\n'));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const ago = status.lastSync
|
|
115
|
+
? (() => {
|
|
116
|
+
const diff = Date.now() - new Date(status.lastSync).getTime();
|
|
117
|
+
if (diff < 60000) return 'just now';
|
|
118
|
+
if (diff < 3600000) return `${Math.floor(diff / 60000)} minutes ago`;
|
|
119
|
+
return `${Math.floor(diff / 3600000)} hours ago`;
|
|
120
|
+
})()
|
|
121
|
+
: 'never';
|
|
122
|
+
|
|
123
|
+
console.log(`\n${bold('Sync Status')}`);
|
|
124
|
+
console.log(` ${dim('Provider:')} ${cyan(`${status.provider} (${status.remote})`)}`);
|
|
125
|
+
console.log(` ${dim('Branch:')} ${cyan(status.branch)}`);
|
|
126
|
+
console.log(` ${dim('Last sync:')} ${ago}`);
|
|
127
|
+
console.log(` ${dim('Unpushed:')} ${status.unpushed} commits`);
|
|
128
|
+
console.log(` ${dim('Conflicts:')} ${status.conflicts.length ? yellow(`${status.conflicts.length} file(s)`) : green('none')}`);
|
|
129
|
+
console.log(` ${dim('Auto-sync:')} ${green('● enabled')} ${dim(`(commit: ${status.autoCommitInterval}s, pull: ${status.autoPullInterval / 60}min)`)}`);
|
|
130
|
+
if (status.lastError) {
|
|
131
|
+
console.log(` ${dim('Last error:')} ${red(status.lastError)}`);
|
|
132
|
+
}
|
|
133
|
+
console.log();
|
|
134
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mindos token — Show auth token and MCP config snippet
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
6
|
+
import { CONFIG_PATH } from '../lib/constants.js';
|
|
7
|
+
import { bold, dim, cyan, red } from '../lib/colors.js';
|
|
8
|
+
import { getLocalIP } from '../lib/startup.js';
|
|
9
|
+
import { MCP_AGENTS, detectAgentPresence } from '../lib/mcp-agents.js';
|
|
10
|
+
import { EXIT } from '../lib/command.js';
|
|
11
|
+
|
|
12
|
+
export const meta = {
|
|
13
|
+
name: 'token',
|
|
14
|
+
group: 'Connections',
|
|
15
|
+
summary: 'Show auth token and MCP config',
|
|
16
|
+
usage: 'mindos token',
|
|
17
|
+
flags: {
|
|
18
|
+
'--json': 'Output as JSON',
|
|
19
|
+
},
|
|
20
|
+
examples: [
|
|
21
|
+
'mindos token',
|
|
22
|
+
'mindos token --json',
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const run = (args, flags) => {
|
|
27
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
28
|
+
console.error(red('No config found. Run `mindos onboard` first.'));
|
|
29
|
+
process.exit(EXIT.ERROR);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let config = {};
|
|
33
|
+
try { config = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8')); } catch {}
|
|
34
|
+
const token = config.authToken || '';
|
|
35
|
+
if (!token) {
|
|
36
|
+
console.log(dim('No auth token set. Run `mindos onboard` to configure one.'));
|
|
37
|
+
process.exit(0);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const mcpPort = config.mcpPort || 8781;
|
|
41
|
+
const localIP = getLocalIP();
|
|
42
|
+
const localUrl = `http://localhost:${mcpPort}/mcp`;
|
|
43
|
+
|
|
44
|
+
if (flags.json) {
|
|
45
|
+
console.log(JSON.stringify({
|
|
46
|
+
token, mcpPort, localUrl,
|
|
47
|
+
remoteUrl: localIP ? `http://${localIP}:${mcpPort}/mcp` : null,
|
|
48
|
+
}, null, 2));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const sep = dim('━'.repeat(40));
|
|
53
|
+
const snippet = (url) => JSON.stringify({
|
|
54
|
+
mcpServers: { mindos: { url, headers: { Authorization: `Bearer ${token}` } } },
|
|
55
|
+
}, null, 2);
|
|
56
|
+
|
|
57
|
+
console.log(`\n${bold('Auth token:')} ${cyan(token)}\n`);
|
|
58
|
+
|
|
59
|
+
const installed = [];
|
|
60
|
+
const others = [];
|
|
61
|
+
for (const [key, agent] of Object.entries(MCP_AGENTS)) {
|
|
62
|
+
(detectAgentPresence(key) ? installed : others).push([key, agent]);
|
|
63
|
+
}
|
|
64
|
+
const toShow = [...installed.slice(0, 8), ...others.slice(0, Math.max(0, 3 - installed.length))];
|
|
65
|
+
|
|
66
|
+
for (const [key, agent] of toShow) {
|
|
67
|
+
console.log(sep);
|
|
68
|
+
console.log(bold(agent.name));
|
|
69
|
+
console.log(dim('Install:') + ` mindos mcp install ${key} -g -y`);
|
|
70
|
+
if (agent.global) console.log(dim(`Config: ${agent.global}`));
|
|
71
|
+
console.log(snippet(localUrl));
|
|
72
|
+
console.log();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (localIP) {
|
|
76
|
+
console.log(sep);
|
|
77
|
+
console.log(bold('Remote MCP (other devices)'));
|
|
78
|
+
console.log(`URL: ${cyan(`http://${localIP}:${mcpPort}/mcp`)}`);
|
|
79
|
+
console.log(snippet(`http://${localIP}:${mcpPort}/mcp`));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// CLI Skill remote config
|
|
83
|
+
const webPort = config.port || 3456;
|
|
84
|
+
console.log(sep);
|
|
85
|
+
console.log(bold('CLI Skill (remote access)'));
|
|
86
|
+
console.log(dim('For agents with bash (Claude Code, Gemini CLI, Codex):'));
|
|
87
|
+
console.log('');
|
|
88
|
+
console.log(` ${cyan('npm install -g @geminilight/mindos')}`);
|
|
89
|
+
console.log(` ${cyan(`mindos config set url http://${localIP || 'localhost'}:${webPort}`)}`);
|
|
90
|
+
console.log(` ${cyan(`mindos config set authToken ${token}`)}`);
|
|
91
|
+
console.log(` ${cyan('mindos file list')} ${dim('# verify connection')}`);
|
|
92
|
+
console.log('');
|
|
93
|
+
|
|
94
|
+
if (toShow.length < installed.length) {
|
|
95
|
+
console.log(dim(`\n +${installed.length - toShow.length} more agents detected. Run \`mindos agent list\` to see all.`));
|
|
96
|
+
}
|
|
97
|
+
console.log(dim('\nRun `mindos onboard` to regenerate.\n'));
|
|
98
|
+
};
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mindos uninstall — interactive teardown: stop processes, remove daemon, optional config/KB, npm uninstall.
|
|
3
|
+
*
|
|
4
|
+
* Uses dynamic import for readline and gateway to limit upfront module cost.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { execSync } from 'node:child_process';
|
|
8
|
+
import { existsSync, readFileSync, rmSync } from 'node:fs';
|
|
9
|
+
import { homedir } from 'node:os';
|
|
10
|
+
|
|
11
|
+
import { CONFIG_PATH, MINDOS_DIR } from '../lib/constants.js';
|
|
12
|
+
import { bold, dim, cyan, green, red, yellow } from '../lib/colors.js';
|
|
13
|
+
import { stopMindos } from '../lib/stop.js';
|
|
14
|
+
|
|
15
|
+
export const meta = {
|
|
16
|
+
name: 'uninstall',
|
|
17
|
+
group: 'Config',
|
|
18
|
+
summary: 'Fully uninstall MindOS',
|
|
19
|
+
usage: 'mindos uninstall',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const run = async () => {
|
|
23
|
+
const readline = await import('node:readline');
|
|
24
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
25
|
+
|
|
26
|
+
// Buffer lines eagerly — readline.question() loses buffered lines when
|
|
27
|
+
// piped stdin delivers multiple lines at once (Node.js known behavior).
|
|
28
|
+
const lineBuffer = [];
|
|
29
|
+
let lineResolve = null;
|
|
30
|
+
rl.on('line', (line) => {
|
|
31
|
+
if (lineResolve) {
|
|
32
|
+
const r = lineResolve;
|
|
33
|
+
lineResolve = null;
|
|
34
|
+
r(line);
|
|
35
|
+
} else {
|
|
36
|
+
lineBuffer.push(line);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
// On EOF with no pending resolve, close gracefully
|
|
40
|
+
rl.on('close', () => {
|
|
41
|
+
if (lineResolve) { lineResolve(''); lineResolve = null; }
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
function prompt(question) {
|
|
45
|
+
process.stdout.write(question + ' ');
|
|
46
|
+
if (lineBuffer.length > 0) return Promise.resolve(lineBuffer.shift());
|
|
47
|
+
return new Promise((resolve) => { lineResolve = resolve; });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function confirm(question) {
|
|
51
|
+
const a = (await prompt(question + ' [y/N]')).trim().toLowerCase();
|
|
52
|
+
return a === 'y' || a === 'yes';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function askInput(question) {
|
|
56
|
+
return (await prompt(question)).trim();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function askPassword(question) {
|
|
60
|
+
// Mute echoed keystrokes
|
|
61
|
+
const stdout = process.stdout;
|
|
62
|
+
const origWrite = stdout.write.bind(stdout);
|
|
63
|
+
stdout.write = (chunk, ...args) => {
|
|
64
|
+
// Suppress everything except the prompt itself
|
|
65
|
+
if (typeof chunk === 'string' && chunk.includes(question)) return origWrite(chunk, ...args);
|
|
66
|
+
return true;
|
|
67
|
+
};
|
|
68
|
+
const answer = await prompt(question);
|
|
69
|
+
stdout.write = origWrite;
|
|
70
|
+
console.log(); // newline after hidden input
|
|
71
|
+
return answer.trim();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const done = () => rl.close();
|
|
75
|
+
|
|
76
|
+
console.log(`\n${bold('🗑 MindOS Uninstall')}\n`);
|
|
77
|
+
console.log(' This will:');
|
|
78
|
+
console.log(` ${green('✓')} Stop running MindOS processes`);
|
|
79
|
+
console.log(` ${green('✓')} Remove background service (if installed)`);
|
|
80
|
+
console.log(` ${green('✓')} Uninstall npm package\n`);
|
|
81
|
+
|
|
82
|
+
if (!await confirm('Proceed?')) {
|
|
83
|
+
console.log(dim('\n Aborted.\n'));
|
|
84
|
+
done();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 1. Stop processes
|
|
89
|
+
console.log(`\n${cyan('Stopping MindOS...')}`);
|
|
90
|
+
try { stopMindos(); } catch { /* may not be running */ }
|
|
91
|
+
|
|
92
|
+
// 2. Remove daemon (skip if platform unsupported)
|
|
93
|
+
const gateway = await import('../lib/gateway.js');
|
|
94
|
+
if (await gateway.getPlatform()) {
|
|
95
|
+
try {
|
|
96
|
+
await gateway.runGatewayCommand('uninstall');
|
|
97
|
+
} catch {
|
|
98
|
+
// Daemon may not be installed — that's fine
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Read config before potentially deleting ~/.mindos/
|
|
103
|
+
let config = {};
|
|
104
|
+
try { config = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8')); } catch {}
|
|
105
|
+
const mindRoot = config.mindRoot?.replace(/^~/, homedir());
|
|
106
|
+
|
|
107
|
+
// 3. Ask to remove ~/.mindos/
|
|
108
|
+
if (existsSync(MINDOS_DIR)) {
|
|
109
|
+
if (await confirm(`Remove config directory (${dim(MINDOS_DIR)})?`)) {
|
|
110
|
+
rmSync(MINDOS_DIR, { recursive: true, force: true });
|
|
111
|
+
console.log(`${green('✔')} Removed ${dim(MINDOS_DIR)}`);
|
|
112
|
+
} else {
|
|
113
|
+
console.log(dim(` Kept ${MINDOS_DIR}`));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 4. Ask to remove knowledge base (triple protection: confirm → type YES → password)
|
|
118
|
+
if (mindRoot && existsSync(mindRoot)) {
|
|
119
|
+
if (await confirm(`Remove knowledge base (${dim(mindRoot)})?`)) {
|
|
120
|
+
const typed = await askInput(`${yellow('⚠ This is irreversible.')} Type ${bold('YES')} to confirm:`);
|
|
121
|
+
if (typed === 'YES') {
|
|
122
|
+
const webPassword = config.webPassword;
|
|
123
|
+
let authorized = true;
|
|
124
|
+
if (webPassword) {
|
|
125
|
+
const pw = await askPassword('Enter web password:');
|
|
126
|
+
if (pw !== webPassword) {
|
|
127
|
+
console.log(red(' Wrong password. Knowledge base kept.'));
|
|
128
|
+
authorized = false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (authorized) {
|
|
132
|
+
rmSync(mindRoot, { recursive: true, force: true });
|
|
133
|
+
console.log(`${green('✔')} Removed ${dim(mindRoot)}`);
|
|
134
|
+
}
|
|
135
|
+
} else {
|
|
136
|
+
console.log(dim(' Knowledge base kept.'));
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
console.log(dim(` Kept ${mindRoot}`));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 5. npm uninstall -g
|
|
144
|
+
console.log(`\n${cyan('Uninstalling npm package...')}`);
|
|
145
|
+
try {
|
|
146
|
+
execSync('npm uninstall -g @geminilight/mindos', { stdio: ['ignore', 'inherit', 'inherit'] });
|
|
147
|
+
} catch {
|
|
148
|
+
console.log(yellow(' npm uninstall failed — you may need to run manually:'));
|
|
149
|
+
console.log(dim(' npm uninstall -g @geminilight/mindos'));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
console.log(`\n${green('✔ MindOS uninstalled.')}\n`);
|
|
153
|
+
done();
|
|
154
|
+
};
|