@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
package/bin/commands/agent.js
CHANGED
|
@@ -1,37 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mindos agent — AI Agent: interactive REPL (default) or one-shot (-p)
|
|
3
|
+
*
|
|
4
|
+
* Inspired by Claude Code: bare `mindos agent` enters interactive mode;
|
|
5
|
+
* `mindos agent -p "task"` prints the result and exits.
|
|
6
|
+
*
|
|
7
|
+
* Management subcommands (list/info/stats) are available as sub-routes.
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
import { bold, dim, cyan, green, red, yellow } from '../lib/colors.js';
|
|
2
11
|
import { MCP_AGENTS, detectAgentPresence } from '../lib/mcp-agents.js';
|
|
3
12
|
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
-
import {
|
|
5
|
-
import { homedir } from 'node:os';
|
|
13
|
+
import { loadConfig } from '../lib/config.js';
|
|
6
14
|
import { output, isJsonMode, EXIT } from '../lib/command.js';
|
|
15
|
+
import { startRepl } from '../lib/repl.js';
|
|
16
|
+
import { executeOneShot } from '../lib/one-shot.js';
|
|
17
|
+
import { expandHome } from '../lib/path-expand.js';
|
|
7
18
|
|
|
8
|
-
|
|
9
|
-
return p.startsWith('~/') ? resolve(homedir(), p.slice(2)) : p;
|
|
10
|
-
}
|
|
19
|
+
const MANAGEMENT_SUBCOMMANDS = new Set(['list', 'ls', 'info', 'stats', 'help']);
|
|
11
20
|
|
|
12
21
|
export const meta = {
|
|
13
22
|
name: 'agent',
|
|
14
|
-
group: '
|
|
15
|
-
summary: 'AI Agent
|
|
16
|
-
usage: 'mindos agent <
|
|
23
|
+
group: 'AI',
|
|
24
|
+
summary: 'AI Agent: interactive REPL or one-shot (-p)',
|
|
25
|
+
usage: 'mindos agent [-p "<task>"]',
|
|
26
|
+
flags: {
|
|
27
|
+
'-p, --print': 'Non-interactive: run task and print result',
|
|
28
|
+
'--file <path>': 'Attach a file as context',
|
|
29
|
+
'--max-steps <n>': 'Max agent steps (default: 20)',
|
|
30
|
+
'--json': 'Output as JSON (implies -p)',
|
|
31
|
+
'--port <port>': 'MindOS web port (default: 3456)',
|
|
32
|
+
},
|
|
33
|
+
examples: [
|
|
34
|
+
'mindos agent # interactive REPL',
|
|
35
|
+
'mindos agent -p "Organize my inbox"',
|
|
36
|
+
'mindos agent "Summarize notes" # also one-shot',
|
|
37
|
+
'mindos agent list # list detected agents',
|
|
38
|
+
],
|
|
17
39
|
};
|
|
18
40
|
|
|
19
41
|
export async function run(args, flags) {
|
|
20
42
|
const sub = args[0];
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
43
|
+
|
|
44
|
+
// Management subcommands always take priority
|
|
45
|
+
if (sub && MANAGEMENT_SUBCOMMANDS.has(sub)) {
|
|
46
|
+
if (sub === 'help') { printHelp(); return; }
|
|
47
|
+
if (sub === 'list' || sub === 'ls') return agentList(flags);
|
|
48
|
+
if (sub === 'info') return agentInfo(args[1], flags);
|
|
49
|
+
if (sub === 'stats') return agentStats(flags);
|
|
27
50
|
return;
|
|
28
51
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
52
|
+
|
|
53
|
+
// Determine mode: -p / --print / --json / bare task → print; otherwise interactive
|
|
54
|
+
const isPrintMode = flags.p || flags.print || isJsonMode(flags) || (sub != null);
|
|
55
|
+
|
|
56
|
+
if (isPrintMode) {
|
|
57
|
+
const task = args.join(' ');
|
|
58
|
+
if (!task) {
|
|
59
|
+
console.error(red('No task provided.'));
|
|
60
|
+
console.error(dim('Usage: mindos agent -p "<task>"'));
|
|
61
|
+
console.error(dim(' mindos agent (interactive mode)'));
|
|
62
|
+
process.exit(EXIT.ARGS);
|
|
63
|
+
}
|
|
64
|
+
return agentExecute(task, flags);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Interactive REPL (default)
|
|
68
|
+
return agentInteractive(flags);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Interactive REPL
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
async function agentInteractive(flags) {
|
|
76
|
+
loadConfig();
|
|
77
|
+
const port = flags.port || process.env.MINDOS_WEB_PORT || '3456';
|
|
78
|
+
const token = process.env.MINDOS_AUTH_TOKEN || '';
|
|
79
|
+
const baseUrl = `http://localhost:${port}`;
|
|
80
|
+
|
|
81
|
+
const maxSteps = (() => {
|
|
82
|
+
if (!flags['max-steps']) return undefined;
|
|
83
|
+
const n = parseInt(flags['max-steps'], 10);
|
|
84
|
+
return (!Number.isNaN(n) && n > 0) ? n : undefined;
|
|
85
|
+
})();
|
|
86
|
+
|
|
87
|
+
await startRepl({
|
|
88
|
+
baseUrl,
|
|
89
|
+
token,
|
|
90
|
+
mode: 'agent',
|
|
91
|
+
prompt: 'agent> ',
|
|
92
|
+
welcome: bold('MindOS Agent') + dim(' (interactive) — full tool access'),
|
|
93
|
+
showTools: true,
|
|
94
|
+
attachedFiles: flags.file ? [flags.file] : undefined,
|
|
95
|
+
maxSteps,
|
|
96
|
+
});
|
|
33
97
|
}
|
|
34
98
|
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// Print Mode — One-shot Task Execution
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
|
|
103
|
+
async function agentExecute(task, flags) {
|
|
104
|
+
loadConfig();
|
|
105
|
+
const port = flags.port || process.env.MINDOS_WEB_PORT || '3456';
|
|
106
|
+
const token = process.env.MINDOS_AUTH_TOKEN || '';
|
|
107
|
+
|
|
108
|
+
const maxSteps = (() => {
|
|
109
|
+
if (!flags['max-steps']) return undefined;
|
|
110
|
+
const n = parseInt(flags['max-steps'], 10);
|
|
111
|
+
return (!Number.isNaN(n) && n > 0) ? n : undefined;
|
|
112
|
+
})();
|
|
113
|
+
|
|
114
|
+
await executeOneShot({
|
|
115
|
+
baseUrl: `http://localhost:${port}`,
|
|
116
|
+
token,
|
|
117
|
+
message: task,
|
|
118
|
+
mode: 'agent',
|
|
119
|
+
showTools: true,
|
|
120
|
+
maxSteps,
|
|
121
|
+
attachedFiles: flags.file ? [flags.file] : undefined,
|
|
122
|
+
json: isJsonMode(flags),
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
// Agent Management — List / Info / Stats
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
|
|
35
130
|
function hasMindosConfig(agent) {
|
|
36
131
|
const paths = [agent.global, agent.project].filter(Boolean).map(expandHome);
|
|
37
132
|
for (const p of paths) {
|
|
@@ -76,12 +171,13 @@ function agentList(flags) {
|
|
|
76
171
|
function agentInfo(key, flags) {
|
|
77
172
|
if (!key) {
|
|
78
173
|
console.error(red('Usage: mindos agent info <agent-key>'));
|
|
79
|
-
process.exit(EXIT.
|
|
174
|
+
process.exit(EXIT.ARGS);
|
|
80
175
|
}
|
|
81
176
|
const agent = MCP_AGENTS[key];
|
|
82
177
|
if (!agent) {
|
|
83
178
|
console.error(red('Unknown agent: ' + key));
|
|
84
|
-
|
|
179
|
+
console.error(dim('Available: ' + Object.keys(MCP_AGENTS).join(', ')));
|
|
180
|
+
process.exit(EXIT.NOT_FOUND);
|
|
85
181
|
}
|
|
86
182
|
|
|
87
183
|
const installed = detectAgentPresence(key);
|
|
@@ -108,3 +204,43 @@ function agentInfo(key, flags) {
|
|
|
108
204
|
if (!connected && installed) console.log('\n Connect: mindos mcp install ' + key);
|
|
109
205
|
console.log('');
|
|
110
206
|
}
|
|
207
|
+
|
|
208
|
+
function agentStats(flags) {
|
|
209
|
+
if (isJsonMode(flags)) {
|
|
210
|
+
output({ message: 'Agent usage statistics are not yet available.' }, flags);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
console.log(dim('\n Agent usage statistics are not yet available.'));
|
|
214
|
+
console.log(dim(' This feature will be added in a future release.\n'));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// ---------------------------------------------------------------------------
|
|
218
|
+
// Help
|
|
219
|
+
// ---------------------------------------------------------------------------
|
|
220
|
+
|
|
221
|
+
export function printHelp() {
|
|
222
|
+
console.log(`
|
|
223
|
+
${bold('mindos agent')} — AI Agent with full tool access
|
|
224
|
+
|
|
225
|
+
${bold('Interactive (default):')}
|
|
226
|
+
${cyan('mindos agent')} Enter multi-turn REPL
|
|
227
|
+
${dim('Commands inside REPL: /clear, /exit')}
|
|
228
|
+
|
|
229
|
+
${bold('Non-interactive (-p):')}
|
|
230
|
+
${cyan('mindos agent -p "<task>"')} Run task, print result, exit
|
|
231
|
+
${cyan('mindos agent "<task>"')} Same (shorthand)
|
|
232
|
+
|
|
233
|
+
${bold('Manage agents:')}
|
|
234
|
+
${cyan('mindos agent list')} List detected AI agents
|
|
235
|
+
${cyan('mindos agent info <agent-key>')} Show agent details
|
|
236
|
+
${cyan('mindos agent stats')} Usage statistics
|
|
237
|
+
|
|
238
|
+
${bold('Options:')}
|
|
239
|
+
${dim('-p, --print')} Non-interactive mode
|
|
240
|
+
${dim('--file <path>')} Attach file as context
|
|
241
|
+
${dim('--max-steps <n>')} Max agent steps (default: 20)
|
|
242
|
+
${dim('--json')} JSON output (implies -p)
|
|
243
|
+
|
|
244
|
+
${bold('Note:')} For lightweight Q&A (read-only), use ${cyan('mindos ask')}.
|
|
245
|
+
`);
|
|
246
|
+
}
|
package/bin/commands/api.js
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import { bold, dim, cyan, red } from '../lib/colors.js';
|
|
2
2
|
import { loadConfig } from '../lib/config.js';
|
|
3
|
-
import { EXIT } from '../lib/command.js';
|
|
3
|
+
import { EXIT, printCommandHelp } from '../lib/command.js';
|
|
4
4
|
|
|
5
5
|
export const meta = {
|
|
6
6
|
name: 'api',
|
|
7
|
-
group: '
|
|
8
|
-
summary: 'Raw API passthrough (GET/POST/PUT/DELETE
|
|
7
|
+
group: 'Config',
|
|
8
|
+
summary: 'Raw API passthrough (GET/POST/PUT/DELETE)',
|
|
9
9
|
usage: 'mindos api <METHOD> <path>',
|
|
10
|
+
flags: {
|
|
11
|
+
'--body <json>': 'Request body as JSON string',
|
|
12
|
+
'--port <port>': 'MindOS web port',
|
|
13
|
+
},
|
|
14
|
+
examples: [
|
|
15
|
+
'mindos api GET /api/health',
|
|
16
|
+
'mindos api GET /api/files',
|
|
17
|
+
'mindos api POST /api/ask --body \'{"messages":[...],"mode":"chat"}\'',
|
|
18
|
+
],
|
|
10
19
|
};
|
|
11
20
|
|
|
12
21
|
export async function run(args, flags) {
|
|
13
|
-
if (args.length < 2
|
|
14
|
-
|
|
15
|
-
console.log('Usage: mindos api <METHOD> <path> [--body <json>]');
|
|
16
|
-
console.log('Methods: GET, POST, PUT, PATCH, DELETE\n');
|
|
17
|
-
console.log('Examples:');
|
|
18
|
-
console.log(' mindos api GET /api/health');
|
|
19
|
-
console.log(' mindos api GET /api/files');
|
|
20
|
-
console.log(' mindos api POST /api/ask --body \'{"question":"..."}\'');
|
|
22
|
+
if (args.length < 2) {
|
|
23
|
+
printCommandHelp({ meta });
|
|
21
24
|
return;
|
|
22
25
|
}
|
|
23
26
|
|
package/bin/commands/ask.js
CHANGED
|
@@ -1,101 +1,112 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* mindos ask — AI
|
|
2
|
+
* mindos ask — AI Chat: interactive REPL (default) or one-shot (-p)
|
|
3
|
+
*
|
|
4
|
+
* Uses 'chat' mode: read-only tools, lower step cap, smaller prompt.
|
|
5
|
+
* For full agent mode with tool execution, use `mindos agent`.
|
|
3
6
|
*/
|
|
4
7
|
|
|
5
|
-
import { bold, dim, cyan,
|
|
8
|
+
import { bold, dim, cyan, red } from '../lib/colors.js';
|
|
6
9
|
import { loadConfig } from '../lib/config.js';
|
|
7
|
-
import {
|
|
10
|
+
import { isJsonMode, EXIT } from '../lib/command.js';
|
|
11
|
+
import { startRepl } from '../lib/repl.js';
|
|
12
|
+
import { executeOneShot } from '../lib/one-shot.js';
|
|
8
13
|
|
|
9
14
|
export const meta = {
|
|
10
15
|
name: 'ask',
|
|
11
|
-
group: '
|
|
12
|
-
summary: '
|
|
13
|
-
usage: 'mindos ask "<question>"',
|
|
16
|
+
group: 'AI',
|
|
17
|
+
summary: 'Chat with your knowledge base (read-only)',
|
|
18
|
+
usage: 'mindos ask [-p "<question>"]',
|
|
14
19
|
flags: {
|
|
15
|
-
'--
|
|
20
|
+
'-p, --print': 'Non-interactive: answer and exit',
|
|
21
|
+
'--file <path>': 'Attach a file as context',
|
|
22
|
+
'--json': 'Output as JSON (implies -p)',
|
|
16
23
|
'--port <port>': 'MindOS web port (default: 3456)',
|
|
17
24
|
},
|
|
18
25
|
examples: [
|
|
19
|
-
'mindos ask
|
|
20
|
-
'mindos ask "What
|
|
21
|
-
'mindos ask "
|
|
26
|
+
'mindos ask # interactive chat',
|
|
27
|
+
'mindos ask -p "What is RAG?"',
|
|
28
|
+
'mindos ask "Summarize my notes" # also one-shot',
|
|
22
29
|
],
|
|
23
30
|
};
|
|
24
31
|
|
|
25
32
|
export async function run(args, flags) {
|
|
26
|
-
const
|
|
33
|
+
const isPrintMode = flags.p || flags.print || isJsonMode(flags) || (args.length > 0);
|
|
27
34
|
|
|
28
|
-
if (
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
if (isPrintMode) {
|
|
36
|
+
const question = args.join(' ');
|
|
37
|
+
if (!question) {
|
|
38
|
+
console.error(red('No question provided. Usage: mindos ask -p "<question>"'));
|
|
39
|
+
process.exit(EXIT.ARGS);
|
|
40
|
+
}
|
|
41
|
+
return askExecute(question, flags);
|
|
42
|
+
}
|
|
34
43
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
44
|
+
// Interactive REPL (default)
|
|
45
|
+
return askInteractive(flags);
|
|
46
|
+
}
|
|
38
47
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Interactive REPL
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
43
51
|
|
|
52
|
+
async function askInteractive(flags) {
|
|
44
53
|
loadConfig();
|
|
45
54
|
const port = flags.port || process.env.MINDOS_WEB_PORT || '3456';
|
|
46
55
|
const token = process.env.MINDOS_AUTH_TOKEN || '';
|
|
47
56
|
const baseUrl = `http://localhost:${port}`;
|
|
48
57
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
await startRepl({
|
|
59
|
+
baseUrl,
|
|
60
|
+
token,
|
|
61
|
+
mode: 'chat',
|
|
62
|
+
prompt: 'chat> ',
|
|
63
|
+
welcome: bold('MindOS Chat') + dim(' (interactive) — read-only knowledge access'),
|
|
64
|
+
showTools: false,
|
|
65
|
+
attachedFiles: flags.file ? [flags.file] : undefined,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
57
68
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Print Mode — One-shot Q&A
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
|
|
73
|
+
async function askExecute(question, flags) {
|
|
74
|
+
loadConfig();
|
|
75
|
+
const port = flags.port || process.env.MINDOS_WEB_PORT || '3456';
|
|
76
|
+
const token = process.env.MINDOS_AUTH_TOKEN || '';
|
|
61
77
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
78
|
+
await executeOneShot({
|
|
79
|
+
baseUrl: `http://localhost:${port}`,
|
|
80
|
+
token,
|
|
81
|
+
message: question,
|
|
82
|
+
mode: 'chat',
|
|
83
|
+
attachedFiles: flags.file ? [flags.file] : undefined,
|
|
84
|
+
json: isJsonMode(flags),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
65
87
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
body: JSON.stringify({ question }),
|
|
70
|
-
});
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// Help
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
71
91
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
92
|
+
export function printHelp() {
|
|
93
|
+
console.log(`
|
|
94
|
+
${bold('mindos ask')} — Chat with your knowledge base (read-only)
|
|
76
95
|
|
|
77
|
-
|
|
96
|
+
${bold('Interactive (default):')}
|
|
97
|
+
${cyan('mindos ask')} Enter multi-turn chat
|
|
98
|
+
${dim('Commands inside REPL: /clear, /exit')}
|
|
78
99
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
100
|
+
${bold('Non-interactive (-p):')}
|
|
101
|
+
${cyan('mindos ask -p "<question>"')} Answer and exit
|
|
102
|
+
${cyan('mindos ask "<question>"')} Same (shorthand)
|
|
83
103
|
|
|
84
|
-
|
|
85
|
-
|
|
104
|
+
${bold('Options:')}
|
|
105
|
+
${dim('-p, --print')} Non-interactive mode
|
|
106
|
+
${dim('--file <path>')} Attach file as context
|
|
107
|
+
${dim('--json')} JSON output (implies -p)
|
|
86
108
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
console.log(data.text);
|
|
91
|
-
} else {
|
|
92
|
-
console.log(JSON.stringify(data, null, 2));
|
|
93
|
-
}
|
|
94
|
-
} catch (err) {
|
|
95
|
-
if (!isJsonMode(flags)) {
|
|
96
|
-
process.stdout.write('\r' + ' '.repeat(40) + '\r');
|
|
97
|
-
}
|
|
98
|
-
console.error(red(err.message));
|
|
99
|
-
process.exit(EXIT.ERROR);
|
|
100
|
-
}
|
|
109
|
+
${bold('Note:')} Chat mode uses read-only tools for knowledge access.
|
|
110
|
+
For full agent mode with write tools, use ${cyan('mindos agent')}.
|
|
111
|
+
`);
|
|
101
112
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mindos build — Build for production
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { resolve } from 'node:path';
|
|
6
|
+
import { ROOT } from '../lib/constants.js';
|
|
7
|
+
import { ensureAppDeps, cleanNextDir, writeBuildStamp } from '../lib/build.js';
|
|
8
|
+
import { execInherited } from '../lib/shell.js';
|
|
9
|
+
|
|
10
|
+
const NEXT_BIN = resolve(ROOT, 'app', 'node_modules', '.bin', 'next');
|
|
11
|
+
|
|
12
|
+
export const meta = {
|
|
13
|
+
name: 'build',
|
|
14
|
+
group: 'Service',
|
|
15
|
+
summary: 'Build for production',
|
|
16
|
+
usage: 'mindos build',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const run = (args) => {
|
|
20
|
+
const extra = args.join(' ');
|
|
21
|
+
ensureAppDeps({ force: true });
|
|
22
|
+
cleanNextDir();
|
|
23
|
+
execInherited('node scripts/gen-renderer-index.js', ROOT);
|
|
24
|
+
execInherited(`${NEXT_BIN} build --webpack ${extra}`, resolve(ROOT, 'app'));
|
|
25
|
+
writeBuildStamp();
|
|
26
|
+
};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mindos config — View and update MindOS configuration
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
6
|
+
import { resolve } from 'node:path';
|
|
7
|
+
import { CONFIG_PATH, ROOT } from '../lib/constants.js';
|
|
8
|
+
import { bold, dim, cyan, green, red } from '../lib/colors.js';
|
|
9
|
+
import { EXIT } from '../lib/command.js';
|
|
10
|
+
|
|
11
|
+
export const meta = {
|
|
12
|
+
name: 'config',
|
|
13
|
+
group: 'Config',
|
|
14
|
+
summary: 'View or update configuration',
|
|
15
|
+
usage: 'mindos config <subcommand>',
|
|
16
|
+
flags: {
|
|
17
|
+
'--json': 'Output as JSON',
|
|
18
|
+
},
|
|
19
|
+
examples: [
|
|
20
|
+
'mindos config show',
|
|
21
|
+
'mindos config set startMode dev',
|
|
22
|
+
'mindos config unset sync.remote',
|
|
23
|
+
'mindos config validate',
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const maskKey = (val) => {
|
|
28
|
+
if (!val) return val;
|
|
29
|
+
if (val.length <= 8) return '****';
|
|
30
|
+
return val.slice(0, 6) + '****';
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const readConfig = () => {
|
|
34
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
35
|
+
console.error(red('No config found. Run `mindos onboard` first.'));
|
|
36
|
+
process.exit(EXIT.ERROR);
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
return JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
|
|
40
|
+
} catch {
|
|
41
|
+
console.error(red('Failed to parse config file.'));
|
|
42
|
+
process.exit(EXIT.ERROR);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const coerceValue = (v) => {
|
|
47
|
+
if (v === 'true') return true;
|
|
48
|
+
if (v === 'false') return false;
|
|
49
|
+
if (v === 'null') return null;
|
|
50
|
+
if (v === '""' || v === "''") return '';
|
|
51
|
+
if (v.trim() !== '' && !isNaN(Number(v))) return Number(v);
|
|
52
|
+
return v;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const run = (args, flags) => {
|
|
56
|
+
const sub = args[0];
|
|
57
|
+
|
|
58
|
+
if (sub === 'show') {
|
|
59
|
+
const config = readConfig();
|
|
60
|
+
const display = JSON.parse(JSON.stringify(config));
|
|
61
|
+
if (display.ai?.providers?.anthropic?.apiKey)
|
|
62
|
+
display.ai.providers.anthropic.apiKey = maskKey(display.ai.providers.anthropic.apiKey);
|
|
63
|
+
if (display.ai?.providers?.openai?.apiKey)
|
|
64
|
+
display.ai.providers.openai.apiKey = maskKey(display.ai.providers.openai.apiKey);
|
|
65
|
+
if (display.ai?.anthropicApiKey)
|
|
66
|
+
display.ai.anthropicApiKey = maskKey(display.ai.anthropicApiKey);
|
|
67
|
+
if (display.ai?.openaiApiKey)
|
|
68
|
+
display.ai.openaiApiKey = maskKey(display.ai.openaiApiKey);
|
|
69
|
+
if (display.authToken)
|
|
70
|
+
display.authToken = maskKey(display.authToken);
|
|
71
|
+
if (display.webPassword)
|
|
72
|
+
display.webPassword = maskKey(display.webPassword);
|
|
73
|
+
|
|
74
|
+
if (flags.json) {
|
|
75
|
+
console.log(JSON.stringify(display, null, 2));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const pkgVersion = (() => { try { return JSON.parse(readFileSync(resolve(ROOT, 'package.json'), 'utf-8')).version; } catch { return '?'; } })();
|
|
79
|
+
console.log(`\n${bold('MindOS Config')} ${dim(`v${pkgVersion}`)} ${dim(CONFIG_PATH)}\n`);
|
|
80
|
+
console.log(JSON.stringify(display, null, 2));
|
|
81
|
+
console.log();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (sub === 'validate') {
|
|
86
|
+
const config = readConfig();
|
|
87
|
+
const issues = [];
|
|
88
|
+
if (!config.mindRoot) issues.push('missing required field: mindRoot');
|
|
89
|
+
if (!config.ai?.provider) issues.push('missing field: ai.provider');
|
|
90
|
+
if (config.ai?.provider === 'anthropic') {
|
|
91
|
+
const key = config.ai?.providers?.anthropic?.apiKey || config.ai?.anthropicApiKey;
|
|
92
|
+
if (!key) issues.push('ai.provider is "anthropic" but no API key found');
|
|
93
|
+
}
|
|
94
|
+
if (config.ai?.provider === 'openai') {
|
|
95
|
+
const key = config.ai?.providers?.openai?.apiKey || config.ai?.openaiApiKey;
|
|
96
|
+
if (!key) issues.push('ai.provider is "openai" but no API key found');
|
|
97
|
+
}
|
|
98
|
+
if (issues.length) {
|
|
99
|
+
console.error(`\n${red('✘ Config has issues:')}`);
|
|
100
|
+
issues.forEach(i => console.error(` ${red('•')} ${i}`));
|
|
101
|
+
console.error(`\n ${dim('Run `mindos onboard` to fix.\n')}`);
|
|
102
|
+
process.exit(EXIT.ERROR);
|
|
103
|
+
}
|
|
104
|
+
console.log(`\n${green('✔ Config is valid')}\n`);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (sub === 'set') {
|
|
109
|
+
const key = args[1];
|
|
110
|
+
const val = args[2];
|
|
111
|
+
if (!key || val === undefined) {
|
|
112
|
+
console.error(red('Usage: mindos config set <key> <value>'));
|
|
113
|
+
console.error(dim(' Examples:'));
|
|
114
|
+
console.error(dim(' mindos config set port 3002'));
|
|
115
|
+
console.error(dim(' mindos config set mcpPort 8788'));
|
|
116
|
+
console.error(dim(' mindos config set ai.provider openai'));
|
|
117
|
+
process.exit(EXIT.ARGS);
|
|
118
|
+
}
|
|
119
|
+
const config = readConfig();
|
|
120
|
+
const parts = key.split('.');
|
|
121
|
+
let obj = config;
|
|
122
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
123
|
+
if (typeof obj[parts[i]] !== 'object' || !obj[parts[i]]) obj[parts[i]] = {};
|
|
124
|
+
obj = obj[parts[i]];
|
|
125
|
+
}
|
|
126
|
+
const coerced = coerceValue(val);
|
|
127
|
+
obj[parts[parts.length - 1]] = coerced;
|
|
128
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), 'utf-8');
|
|
129
|
+
console.log(`${green('✔')} Set ${cyan(key)} = ${bold(String(coerced))}`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (sub === 'unset') {
|
|
134
|
+
const key = args[1];
|
|
135
|
+
if (!key) {
|
|
136
|
+
console.error(red('Usage: mindos config unset <key>'));
|
|
137
|
+
process.exit(EXIT.ARGS);
|
|
138
|
+
}
|
|
139
|
+
const config = readConfig();
|
|
140
|
+
const parts = key.split('.');
|
|
141
|
+
let obj = config;
|
|
142
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
143
|
+
if (!obj[parts[i]]) { console.log(dim(`Key "${key}" not found`)); return; }
|
|
144
|
+
obj = obj[parts[i]];
|
|
145
|
+
}
|
|
146
|
+
if (!(parts[parts.length - 1] in obj)) { console.log(dim(`Key "${key}" not found`)); return; }
|
|
147
|
+
delete obj[parts[parts.length - 1]];
|
|
148
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), 'utf-8');
|
|
149
|
+
console.log(`${green('✔')} Removed ${cyan(key)}`);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// No subcommand → show help
|
|
154
|
+
const row = (c, d) => ` ${cyan(c.padEnd(32))}${dim(d)}`;
|
|
155
|
+
console.log(`
|
|
156
|
+
${bold('mindos config')} — view and update MindOS configuration
|
|
157
|
+
|
|
158
|
+
${bold('Subcommands:')}
|
|
159
|
+
${row('mindos config show', 'Print current config (API keys masked)')}
|
|
160
|
+
${row('mindos config validate', 'Validate config file')}
|
|
161
|
+
${row('mindos config set <key> <v>', 'Update a single field (dot-notation supported)')}
|
|
162
|
+
${row('mindos config unset <key>', 'Remove a config field')}
|
|
163
|
+
|
|
164
|
+
${bold('Examples:')}
|
|
165
|
+
${dim('mindos config set port 3002')}
|
|
166
|
+
${dim('mindos config set ai.provider openai')}
|
|
167
|
+
${dim('mindos config set setupPending false')}
|
|
168
|
+
${dim('mindos config unset webPassword')}
|
|
169
|
+
`);
|
|
170
|
+
};
|