@winspan/claude-forge 8.53.2 → 8.54.3
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/DEVELOPMENT.md +290 -221
- package/README.md +50 -8
- package/dist/cli/commands/skills.d.ts.map +1 -1
- package/dist/cli/commands/skills.js +7 -3
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/init/hook-manager.d.ts +1 -1
- package/dist/cli/init/hook-manager.d.ts.map +1 -1
- package/dist/cli/init/hook-manager.js +1 -0
- package/dist/cli/init/hook-manager.js.map +1 -1
- package/dist/core/storage/events.d.ts.map +1 -1
- package/dist/core/storage/events.js +0 -1
- package/dist/core/storage/events.js.map +1 -1
- package/dist/core/storage/maintenance.d.ts +25 -3
- package/dist/core/storage/maintenance.d.ts.map +1 -1
- package/dist/core/storage/maintenance.js +33 -4
- package/dist/core/storage/maintenance.js.map +1 -1
- package/dist/core/storage/routing.d.ts +4 -0
- package/dist/core/storage/routing.d.ts.map +1 -1
- package/dist/core/storage/routing.js +10 -4
- package/dist/core/storage/routing.js.map +1 -1
- package/dist/core/storage/sessions.d.ts +17 -0
- package/dist/core/storage/sessions.d.ts.map +1 -1
- package/dist/core/storage/sessions.js +64 -0
- package/dist/core/storage/sessions.js.map +1 -1
- package/dist/core/storage/skills.d.ts +4 -0
- package/dist/core/storage/skills.d.ts.map +1 -1
- package/dist/core/storage/skills.js +10 -2
- package/dist/core/storage/skills.js.map +1 -1
- package/dist/core/storage/sqlite.d.ts +5 -0
- package/dist/core/storage/sqlite.d.ts.map +1 -1
- package/dist/core/storage/sqlite.js +6 -0
- package/dist/core/storage/sqlite.js.map +1 -1
- package/dist/core/storage/tasks.d.ts.map +1 -1
- package/dist/core/storage/tasks.js +2 -0
- package/dist/core/storage/tasks.js.map +1 -1
- package/dist/core/types.d.ts +7 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +19 -4
- package/dist/daemon/index.js.map +1 -1
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +13 -2
- package/dist/skills/registry.js.map +1 -1
- package/dist/skills/semantic-matcher.d.ts +2 -2
- package/dist/skills/semantic-matcher.d.ts.map +1 -1
- package/dist/skills/semantic-matcher.js +14 -19
- package/dist/skills/semantic-matcher.js.map +1 -1
- package/dist/skills/upgrade-engine.d.ts +3 -1
- package/dist/skills/upgrade-engine.d.ts.map +1 -1
- package/dist/skills/upgrade-engine.js +25 -14
- package/dist/skills/upgrade-engine.js.map +1 -1
- package/dist/web/analytics/weekly-report.d.ts.map +1 -1
- package/dist/web/analytics/weekly-report.js +21 -29
- package/dist/web/analytics/weekly-report.js.map +1 -1
- package/dist/web/routes/patch.d.ts.map +1 -1
- package/dist/web/routes/patch.js +32 -2
- package/dist/web/routes/patch.js.map +1 -1
- package/dist/web/routes/sessions.d.ts.map +1 -1
- package/dist/web/routes/sessions.js +9 -7
- package/dist/web/routes/sessions.js.map +1 -1
- package/dist/web/routes/trace.d.ts.map +1 -1
- package/dist/web/routes/trace.js +2 -3
- package/dist/web/routes/trace.js.map +1 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +3 -2
- package/dist/web/server.js.map +1 -1
- package/package.json +12 -2
- package/scripts/postinstall.cjs +21 -0
- package/.claude/CLAUDE.md +0 -17
- package/.eslintrc.js +0 -23
- package/.prettierrc +0 -8
- package/ARCHITECTURE_ISSUES.md +0 -249
- package/CLAUDE.md +0 -265
- package/CLAUDE.md.backup +0 -488
- package/docs/concurrent-agents.md +0 -129
- package/docs/design/architecture-review-20260516.md +0 -232
- package/docs/design/fix-skills-data-and-set-leak-spec-20260516-1300.md +0 -219
- package/docs/design/h1-storage-aggregation-spec-20260518-1121.md +0 -299
- package/docs/design/h2-getdatabase-encapsulation-spec-20260518-1450.md +0 -191
- package/docs/design/h3-fallback-removal-spec-20260518-1245.md +0 -76
- package/docs/design/h4-index-dedup-spec-20260518-1230.md +0 -109
- package/docs/design/h6-services-migration-spec-20260518-1355.md +0 -82
- package/docs/design/hook-failure-queue-spec-20260516-1530.md +0 -204
- package/docs/design/l1-swarm-protocol-extract-spec-20260518-1605.md +0 -106
- package/docs/design/m10-forge-paths-spec-20260518-1320.md +0 -121
- package/docs/design/m2-m3-tool-input-spec-20260518-1425.md +0 -131
- package/docs/design/m7-routing-event-association-spec-20260518-1545.md +0 -103
- package/docs/design/project-path-gitroot-spec-20260518-1715.md +0 -134
- package/docs/design/refactor-phase1-spec-20260515-1600.md +0 -543
- package/docs/design/refactor-phase2-spec-20260515-1700.md +0 -424
- package/docs/design/skill-ai-upgrade-spec-20260518-1930.md +0 -297
- package/docs/design/task-active-gc-spec-20260518-1745.md +0 -146
- package/docs/design/tasks-list-filter-pagination-spec-20260518-0930.md +0 -208
- package/docs/implementation/daemon-skill-sync-changelog-20260518-2000.md +0 -22
- package/docs/implementation/fix-skills-data-and-set-leak-changelog-20260516-1300.md +0 -104
- package/docs/implementation/h1-storage-aggregation-changelog-20260518-1121.md +0 -82
- package/docs/implementation/h2-final-changelog-20260518-1530.md +0 -61
- package/docs/implementation/h2-phase1-safety-net-changelog-20260518-1450.md +0 -70
- package/docs/implementation/h2-phase2-operations-changelog-20260518-1450.md +0 -120
- package/docs/implementation/h2-phase3-callsites-changelog-20260518-1450.md +0 -71
- package/docs/implementation/h3-fallback-removal-changelog-20260518-1245.md +0 -71
- package/docs/implementation/h4-index-dedup-changelog-20260518-1230.md +0 -60
- package/docs/implementation/h6-services-migration-changelog-20260518-1355.md +0 -46
- package/docs/implementation/h7-m9-defaults-changelog-20260518-1300.md +0 -46
- package/docs/implementation/hook-failure-queue-changelog-20260516-1530.md +0 -196
- package/docs/implementation/hotfix-daemon-event-reject-20260516-1430.md +0 -56
- package/docs/implementation/l1-swarm-protocol-extract-changelog-20260518-1605.md +0 -45
- package/docs/implementation/l3-l4-daemon-perf-changelog-20260518-1410.md +0 -63
- package/docs/implementation/l6-l8-final-cleanup-changelog-20260518-1640.md +0 -38
- package/docs/implementation/m1-m4-m5-l7-cleanup-changelog-20260518-1310.md +0 -58
- package/docs/implementation/m10-forge-paths-changelog-20260518-1320.md +0 -60
- package/docs/implementation/m2-m3-tool-input-changelog-20260518-1425.md +0 -43
- package/docs/implementation/m6-m8-naming-shutdown-changelog-20260518-1340.md +0 -56
- package/docs/implementation/m7-routing-association-changelog-20260518-1545.md +0 -69
- package/docs/implementation/project-path-gitroot-changelog-20260518-1715.md +0 -63
- package/docs/implementation/refactor-phase1-changelog-20260515-1630.md +0 -354
- package/docs/implementation/refactor-phase2-changelog-20260515-1705.md +0 -421
- package/docs/implementation/skill-ai-upgrade-changelog-20260518-1930.md +0 -49
- package/docs/implementation/task-active-gc-changelog-20260518-1745.md +0 -35
- package/docs/implementation/task-title-summary-changelog-20260518-1130.md +0 -39
- package/docs/implementation/tasks-detail-back-loses-filters-changelog-20260518-1100.md +0 -22
- package/docs/implementation/tasks-list-filter-pagination-changelog-20260518-0930.md +0 -72
- package/docs/implementation/tasks-page-white-screen-hotfix-changelog-20260518-1015.md +0 -56
- package/docs/reviews/claudemd-template-sync.md +0 -54
- package/docs/reviews/task-title-summary.md +0 -92
- package/docs/reviews/tasks-detail-back-loses-filters.md +0 -58
- package/docs/reviews/tasks-filter-pagination.md +0 -80
- package/docs/reviews/tasks-page-white-screen-hotfix.md +0 -126
- package/docs/ruflo-learning-strategy.md +0 -322
- package/docs/skills-deduplication-analysis.md +0 -83
- package/docs/skills-multiformat-support.md +0 -177
- package/docs/skills-third-party.md +0 -183
- package/docs/testing/tasks-filter-pagination-test-report.md +0 -86
- package/forge +0 -321
- package/playwright.config.ts +0 -40
- package/scripts/demo-v2.ts +0 -91
- package/scripts/dev-daemon.sh +0 -232
- package/scripts/dev-web.ts +0 -109
- package/scripts/e2e-mcp-link.ts +0 -423
- package/scripts/e2e-methodology-quality.ts +0 -253
- package/scripts/e2e-routing.ts +0 -456
- package/scripts/e2e-user-methodology.ts +0 -326
- package/scripts/e2e-web-workflows.ts +0 -299
- package/scripts/migrate-legacy-to-dynamic.sql +0 -108
- package/scripts/regenerate-execution-docs.ts +0 -116
- package/scripts/sync-agent-skills.ts +0 -193
- package/scripts/test-hook.sh +0 -71
- package/scripts/verify-skill-loading.ts +0 -62
- package/src/claudemd/claudemd-generator.ts +0 -568
- package/src/claudemd/convention-extractor.ts +0 -69
- package/src/claudemd/index.ts +0 -35
- package/src/claudemd/persona-manager.ts +0 -88
- package/src/claudemd/resume-manager.ts +0 -236
- package/src/claudemd/tech-detector.ts +0 -220
- package/src/claudemd/templates/swarm-protocol.md +0 -222
- package/src/cli/commands/claudemd.ts +0 -84
- package/src/cli/commands/config.ts +0 -46
- package/src/cli/commands/daemon.ts +0 -310
- package/src/cli/commands/executions.ts +0 -115
- package/src/cli/commands/init.ts +0 -204
- package/src/cli/commands/logs.ts +0 -181
- package/src/cli/commands/mcp.ts +0 -242
- package/src/cli/commands/menu.ts +0 -357
- package/src/cli/commands/skills.ts +0 -328
- package/src/cli/commands/stats.ts +0 -73
- package/src/cli/commands/status.ts +0 -69
- package/src/cli/commands/template.ts +0 -77
- package/src/cli/commands/trace.ts +0 -148
- package/src/cli/index.ts +0 -42
- package/src/cli/init/hook-manager.ts +0 -132
- package/src/core/ai/provider.ts +0 -308
- package/src/core/ai/types.ts +0 -51
- package/src/core/config.ts +0 -124
- package/src/core/constants.ts +0 -67
- package/src/core/event-fields.ts +0 -32
- package/src/core/queue/index.ts +0 -192
- package/src/core/storage/base.ts +0 -302
- package/src/core/storage/events.ts +0 -434
- package/src/core/storage/injections.ts +0 -78
- package/src/core/storage/maintenance.ts +0 -59
- package/src/core/storage/migrations/002_add_skill_tracking.sql +0 -6
- package/src/core/storage/migrations/003_add_skill_invocations.sql +0 -23
- package/src/core/storage/performance-indexes.sql +0 -23
- package/src/core/storage/routing.ts +0 -322
- package/src/core/storage/rows.ts +0 -112
- package/src/core/storage/schema.sql +0 -224
- package/src/core/storage/sessions.ts +0 -168
- package/src/core/storage/skills.ts +0 -233
- package/src/core/storage/sqlite.ts +0 -293
- package/src/core/storage/tasks.ts +0 -318
- package/src/core/storage/token-usage.ts +0 -93
- package/src/core/types.ts +0 -181
- package/src/core/utils/error-handler.ts +0 -257
- package/src/core/utils/forge-resume-block.ts +0 -74
- package/src/core/utils/format.ts +0 -69
- package/src/core/utils/git.ts +0 -23
- package/src/core/utils/logger.ts +0 -134
- package/src/core/utils/lru-cache.ts +0 -54
- package/src/core/utils/path.ts +0 -19
- package/src/core/utils/session.ts +0 -26
- package/src/core/utils/time.ts +0 -37
- package/src/core/utils/token-tracker.ts +0 -97
- package/src/daemon/event-parser.ts +0 -36
- package/src/daemon/handlers/history-exporter.ts +0 -117
- package/src/daemon/handlers/post-tool-use.ts +0 -54
- package/src/daemon/handlers/stop.ts +0 -208
- package/src/daemon/handlers/user-prompt.ts +0 -178
- package/src/daemon/hook-sync.ts +0 -91
- package/src/daemon/index.ts +0 -312
- package/src/daemon/launchd/com.claude-forge.daemon.plist.template +0 -47
- package/src/daemon/launchd-installer.ts +0 -260
- package/src/daemon/lifecycle.ts +0 -128
- package/src/daemon/router.ts +0 -40
- package/src/daemon/server.ts +0 -196
- package/src/daemon/services/task-segmenter.ts +0 -112
- package/src/daemon/skill-sync.ts +0 -88
- package/src/hooks/hook-lib.sh +0 -118
- package/src/hooks/notification.sh +0 -35
- package/src/hooks/post-tool-use.sh +0 -61
- package/src/hooks/pre-tool-use.sh +0 -63
- package/src/hooks/stop.sh +0 -43
- package/src/hooks/user-prompt-submit.sh +0 -69
- package/src/mcp/server.ts +0 -322
- package/src/skills/index.ts +0 -2
- package/src/skills/invocation-guard.ts +0 -177
- package/src/skills/matcher.ts +0 -148
- package/src/skills/official/code-simplifier.md +0 -52
- package/src/skills/official/find-skills.md +0 -142
- package/src/skills/official/official-api-design.md +0 -30
- package/src/skills/official/official-architecture-decision.md +0 -41
- package/src/skills/official/official-bmad.md +0 -118
- package/src/skills/official/official-db-schema-design.md +0 -34
- package/src/skills/official/official-debug.md +0 -25
- package/src/skills/official/official-doc-driven.md +0 -31
- package/src/skills/official/official-harness-engineering.md +0 -108
- package/src/skills/official/official-performance-optimization.md +0 -30
- package/src/skills/official/official-pr-review.md +0 -35
- package/src/skills/official/official-release-checklist.md +0 -30
- package/src/skills/official/official-security-hardening.md +0 -32
- package/src/skills/official/official-spec-driven-design.md +0 -31
- package/src/skills/official/planning-with-files.md +0 -241
- package/src/skills/official/ui-ux-pro-max.md +0 -105
- package/src/skills/official/webapp-testing.md +0 -96
- package/src/skills/official-skills.ts +0 -89
- package/src/skills/registry.ts +0 -355
- package/src/skills/semantic-matcher.ts +0 -234
- package/src/skills/tools/pipeline-suggest.ts +0 -226
- package/src/skills/tools/skill-invoke.ts +0 -168
- package/src/skills/tools/skill-list.ts +0 -59
- package/src/skills/upgrade-engine.ts +0 -541
- package/src/skills/upgrade-prompt.ts +0 -84
- package/src/templates/go.yaml +0 -53
- package/src/templates/python.yaml +0 -59
- package/src/templates/react.yaml +0 -55
- package/src/templates/template-manager.ts +0 -170
- package/src/web/analytics/anti-pattern-detector.ts +0 -367
- package/src/web/analytics/drift-detector.ts +0 -219
- package/src/web/analytics/weekly-report.ts +0 -431
- package/src/web/auth-middleware.ts +0 -54
- package/src/web/routes/_helpers.ts +0 -34
- package/src/web/routes/ai.ts +0 -204
- package/src/web/routes/auth.ts +0 -22
- package/src/web/routes/drift.ts +0 -25
- package/src/web/routes/error-handler.ts +0 -120
- package/src/web/routes/events.ts +0 -47
- package/src/web/routes/insights.ts +0 -43
- package/src/web/routes/patch.ts +0 -117
- package/src/web/routes/reports.ts +0 -34
- package/src/web/routes/rules.ts +0 -76
- package/src/web/routes/sessions.ts +0 -250
- package/src/web/routes/skill-stats.ts +0 -92
- package/src/web/routes/skills.ts +0 -350
- package/src/web/routes/static.ts +0 -67
- package/src/web/routes/stats.ts +0 -50
- package/src/web/routes/status.ts +0 -30
- package/src/web/routes/tasks.ts +0 -193
- package/src/web/routes/token-usage.ts +0 -20
- package/src/web/routes/trace.ts +0 -126
- package/src/web/routes/types.ts +0 -57
- package/src/web/server.ts +0 -134
- package/src/web/ssrf-guard.ts +0 -112
- package/src/web/static/index.html +0 -3251
- package/src/web/static/vendor/chart.umd.min.js +0 -20
- package/tests/e2e/dashboard.spec.ts +0 -205
- package/tests/e2e/routing-skill-e2e.test.ts +0 -39
- package/tests/helpers/mock-ai.ts +0 -92
- package/tests/helpers/mock-storage.ts +0 -159
- package/tests/integration/claudemd-generator.test.ts +0 -90
- package/tests/integration/queue-replay.integration.test.ts +0 -193
- package/tests/integration/tasks-filter.integration.test.ts +0 -154
- package/tests/integration/web-analytics.integration.test.ts +0 -133
- package/tests/integration/web-stats.integration.test.ts +0 -135
- package/tests/integration/web-trace.integration.test.ts +0 -175
- package/tests/performance/database.benchmark.ts +0 -161
- package/tests/semantic-matcher.test.ts +0 -99
- package/tests/skill-matcher.test.ts +0 -110
- package/tests/unit/ai-provider-retry.test.ts +0 -194
- package/tests/unit/ai-provider-vision.test.ts +0 -224
- package/tests/unit/claudemd-generator.test.ts +0 -68
- package/tests/unit/cli-mcp.test.ts +0 -141
- package/tests/unit/core/forge-paths.test.ts +0 -99
- package/tests/unit/daemon/hook-sync.test.ts +0 -71
- package/tests/unit/daemon/post-tool-use.test.ts +0 -121
- package/tests/unit/daemon/skill-sync.test.ts +0 -75
- package/tests/unit/daemon/stop-handler-behavior-summary.test.ts +0 -202
- package/tests/unit/daemon/task-segmenter-recover.test.ts +0 -84
- package/tests/unit/event-fields.test.ts +0 -88
- package/tests/unit/event-parser.test.ts +0 -55
- package/tests/unit/handlers.test.ts +0 -171
- package/tests/unit/hooks/resolve-project-path.test.ts +0 -122
- package/tests/unit/invocation-guard.test.ts +0 -125
- package/tests/unit/queue.test.ts +0 -272
- package/tests/unit/router.test.ts +0 -138
- package/tests/unit/security.test.ts +0 -128
- package/tests/unit/skill-invocations-workflow.test.ts +0 -495
- package/tests/unit/skill-registry.test.ts +0 -94
- package/tests/unit/skills/invocation-guard-ttl.test.ts +0 -211
- package/tests/unit/skills/official-skills-loader.test.ts +0 -126
- package/tests/unit/skills/registry-multiformat.test.ts +0 -92
- package/tests/unit/skills/upgrade-engine-parse.test.ts +0 -138
- package/tests/unit/skills/upgrade-engine.test.ts +0 -401
- package/tests/unit/skills/upgrade-prompt.test.ts +0 -89
- package/tests/unit/socket-server.test.ts +0 -183
- package/tests/unit/storage/event-operations-aggregates.test.ts +0 -342
- package/tests/unit/storage/migration-idempotent.test.ts +0 -304
- package/tests/unit/storage/routing-aggregates.test.ts +0 -276
- package/tests/unit/storage/routing.test.ts +0 -117
- package/tests/unit/storage/schema-missing.test.ts +0 -81
- package/tests/unit/storage/session-operations-aggregates.test.ts +0 -120
- package/tests/unit/storage/sessions-aggregate.test.ts +0 -435
- package/tests/unit/storage/skill-operations-counts.test.ts +0 -106
- package/tests/unit/storage/skills-aggregates.test.ts +0 -104
- package/tests/unit/storage/sqlite-refactor-harness.test.ts +0 -314
- package/tests/unit/storage/task-operations-counts.test.ts +0 -46
- package/tests/unit/storage/tasks-getById.test.ts +0 -343
- package/tests/unit/storage/tasks-stale-gc.test.ts +0 -86
- package/tests/unit/storage.test.ts +0 -172
- package/tests/unit/token-usage.test.ts +0 -144
- package/tests/unit/type-guards.test.ts +0 -201
- package/tests/unit/utils/format.test.ts +0 -189
- package/tests/unit/utils/session.test.ts +0 -89
- package/tests/unit/utils/time.test.ts +0 -112
- package/tests/unit/web/navigation-back-contract.test.ts +0 -134
- package/tests/unit/web/routes-auth.test.ts +0 -93
- package/tests/unit/web/routes-events.test.ts +0 -101
- package/tests/unit/web/routes-rules.test.ts +0 -182
- package/tests/unit/web/routes-sessions.test.ts +0 -181
- package/tests/unit/web/routes-skill-stats.test.ts +0 -179
- package/tests/unit/web/routes-stats.test.ts +0 -92
- package/tests/unit/web/routes-tasks.test.ts +0 -385
- package/tests/unit/web/task-title-contract.test.ts +0 -210
- package/tests/unit/web/tasks-component-contract.test.ts +0 -179
- package/tsconfig.json +0 -22
- package/vitest.config.ts +0 -21
- package/vitest.integration.config.ts +0 -16
- package/web/CLAUDE.md +0 -20
- package/web/index.html +0 -13
- package/web/package-lock.json +0 -4854
- package/web/package.json +0 -35
- package/web/postcss.config.js +0 -6
- package/web/src/App.tsx +0 -110
- package/web/src/components/CodeBlock.tsx +0 -31
- package/web/src/components/Confirm.tsx +0 -96
- package/web/src/components/Drawer.tsx +0 -60
- package/web/src/components/Layout.tsx +0 -145
- package/web/src/components/MarkdownRenderer.tsx +0 -77
- package/web/src/components/SearchInput.tsx +0 -31
- package/web/src/components/SessionDetailContent.tsx +0 -157
- package/web/src/components/Toast.tsx +0 -92
- package/web/src/index.css +0 -19
- package/web/src/main.tsx +0 -31
- package/web/src/pages/AIConfig.tsx +0 -233
- package/web/src/pages/Dashboard.tsx +0 -572
- package/web/src/pages/Events.tsx +0 -271
- package/web/src/pages/Reports.tsx +0 -428
- package/web/src/pages/SessionDetail.tsx +0 -162
- package/web/src/pages/Sessions.tsx +0 -205
- package/web/src/pages/Skills.tsx +0 -180
- package/web/src/pages/TaskDetail.tsx +0 -515
- package/web/src/pages/Tasks.tsx +0 -415
- package/web/src/utils/auth.ts +0 -59
- package/web/src/utils/export.ts +0 -54
- package/web/src/utils/navigation.ts +0 -25
- package/web/src/utils/task-title.ts +0 -49
- package/web/src/utils/time.ts +0 -13
- package/web/tailwind.config.js +0 -11
- package/web/tsconfig.json +0 -21
- package/web/tsconfig.node.json +0 -10
- package/web/vite.config.ts +0 -76
- package/winspan-claude-forge-8.43.0.tgz +0 -0
package/src/cli/commands/mcp.ts
DELETED
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* cf mcp — MCP server 注册与管理命令
|
|
3
|
-
*
|
|
4
|
-
* 子命令:
|
|
5
|
-
* cf mcp status — 检查 MCP server 是否已注册到 Claude Code
|
|
6
|
-
* cf mcp register — 向 Claude Code 注册 claude-forge MCP server(user scope)
|
|
7
|
-
* cf mcp unregister — 从 Claude Code 移除注册
|
|
8
|
-
*
|
|
9
|
-
* 实现要点:
|
|
10
|
-
* - claude mcp 配置存储在 ~/.claude.json(而非 ~/.claude/settings.json)
|
|
11
|
-
* - HTTP transport 必须显式 `--transport http`,不能用 `--url`
|
|
12
|
-
* - 默认注册到 user scope (`-s user`),让所有项目都能用
|
|
13
|
-
* - 必须把 daemon token 作为 `Authorization: Bearer ...` header 传入,
|
|
14
|
-
* 否则 MCP 调用会被 401 拦截
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import { Command } from 'commander';
|
|
18
|
-
import { execSync } from 'node:child_process';
|
|
19
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
20
|
-
import chalk from 'chalk';
|
|
21
|
-
import { ConfigManager } from '../../core/config.js';
|
|
22
|
-
import { DEFAULTS, FORGE_PATHS } from '../../core/constants.js';
|
|
23
|
-
|
|
24
|
-
const SERVER_NAME = 'claude-forge';
|
|
25
|
-
const SCOPE = 'user'; // user scope: 全局可用
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* 检查 Claude Code 是否已安装(通过检查 claude CLI 是否存在)
|
|
29
|
-
*/
|
|
30
|
-
export function isClaudeCodeInstalled(): boolean {
|
|
31
|
-
try {
|
|
32
|
-
execSync('command -v claude', { stdio: 'ignore' });
|
|
33
|
-
return true;
|
|
34
|
-
} catch {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 读取 daemon token(如果存在)
|
|
41
|
-
*/
|
|
42
|
-
function readDaemonToken(): string | null {
|
|
43
|
-
const tokenPath = FORGE_PATHS.daemonToken();
|
|
44
|
-
if (!existsSync(tokenPath)) return null;
|
|
45
|
-
try {
|
|
46
|
-
return readFileSync(tokenPath, 'utf-8').trim() || null;
|
|
47
|
-
} catch {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* 检查 claude-forge MCP server 是否已注册
|
|
54
|
-
*
|
|
55
|
-
* 通过 `claude mcp get <name>` 退出码判断:成功 = 已注册
|
|
56
|
-
*/
|
|
57
|
-
export function isMcpRegistered(): { registered: boolean; url?: string } {
|
|
58
|
-
try {
|
|
59
|
-
const output = execSync(`claude mcp get ${SERVER_NAME}`, {
|
|
60
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
61
|
-
encoding: 'utf-8',
|
|
62
|
-
});
|
|
63
|
-
// 从输出中尝试提取 URL(容错,匹配失败也认为已注册)
|
|
64
|
-
const urlMatch = output.match(/URL:\s*(\S+)/i);
|
|
65
|
-
return { registered: true, url: urlMatch?.[1] };
|
|
66
|
-
} catch {
|
|
67
|
-
return { registered: false };
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* 获取 daemon 的 MCP server URL
|
|
73
|
-
*/
|
|
74
|
-
export function getMcpServerUrl(): string {
|
|
75
|
-
const config = new ConfigManager().get();
|
|
76
|
-
const port = config.web.port ?? DEFAULTS.WEB_PORT;
|
|
77
|
-
return `http://127.0.0.1:${port}/mcp`;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* 是否处于 daemon 运行中(通过 pid 文件存在性判断,松散探测)
|
|
82
|
-
*/
|
|
83
|
-
function isDaemonRunning(): boolean {
|
|
84
|
-
return existsSync(FORGE_PATHS.daemonPid());
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* cf mcp status
|
|
89
|
-
*/
|
|
90
|
-
export function statusCommand(): void {
|
|
91
|
-
console.log(chalk.bold('🔍 MCP Server Status\n'));
|
|
92
|
-
|
|
93
|
-
// 1. 检查 Claude Code 是否安装
|
|
94
|
-
const claudeInstalled = isClaudeCodeInstalled();
|
|
95
|
-
console.log(
|
|
96
|
-
claudeInstalled
|
|
97
|
-
? chalk.green('✓ Claude Code CLI installed')
|
|
98
|
-
: chalk.red('✗ Claude Code CLI not found (install from claude.ai/code)'),
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
if (!claudeInstalled) {
|
|
102
|
-
console.log(chalk.dim('\n Cannot check registration without Claude Code CLI.'));
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// 2. 检查 MCP server 是否注册
|
|
107
|
-
const { registered, url } = isMcpRegistered();
|
|
108
|
-
if (registered) {
|
|
109
|
-
console.log(chalk.green(`✓ MCP server registered${url ? `: ${url}` : ''}`));
|
|
110
|
-
} else {
|
|
111
|
-
console.log(chalk.yellow('⚠ MCP server not registered'));
|
|
112
|
-
console.log(chalk.dim(' Run `cf mcp register` to register'));
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// 3. 检查 daemon 是否运行
|
|
116
|
-
console.log(
|
|
117
|
-
isDaemonRunning()
|
|
118
|
-
? chalk.green('✓ Daemon running')
|
|
119
|
-
: chalk.yellow('⚠ Daemon not running (start with `cf daemon start`)'),
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
// 4. 检查 daemon token
|
|
123
|
-
const token = readDaemonToken();
|
|
124
|
-
console.log(
|
|
125
|
-
token
|
|
126
|
-
? chalk.green('✓ Daemon token present')
|
|
127
|
-
: chalk.yellow('⚠ Daemon token missing (start daemon at least once)'),
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
// 5. 显示预期的 MCP URL
|
|
131
|
-
console.log(chalk.dim(`\nExpected MCP URL: ${getMcpServerUrl()}`));
|
|
132
|
-
console.log(chalk.dim(`Scope: ${SCOPE} (available in all projects)`));
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* cf mcp register
|
|
137
|
-
*/
|
|
138
|
-
export function registerCommand(): void {
|
|
139
|
-
console.log(chalk.bold('📡 Registering MCP Server\n'));
|
|
140
|
-
|
|
141
|
-
// 1. 检查 Claude Code CLI
|
|
142
|
-
if (!isClaudeCodeInstalled()) {
|
|
143
|
-
console.error(chalk.red('✗ Claude Code CLI not found'));
|
|
144
|
-
console.error(chalk.dim(' Install from https://claude.ai/code'));
|
|
145
|
-
process.exit(1);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// 2. 检查是否已注册
|
|
149
|
-
const { registered, url: existingUrl } = isMcpRegistered();
|
|
150
|
-
if (registered) {
|
|
151
|
-
console.log(chalk.yellow(`⚠ MCP server already registered${existingUrl ? `: ${existingUrl}` : ''}`));
|
|
152
|
-
console.log(chalk.dim(' Run `cf mcp unregister` first if you want to re-register'));
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// 3. 读取 daemon token(必需,否则 MCP 调用会 401)
|
|
157
|
-
const token = readDaemonToken();
|
|
158
|
-
if (!token) {
|
|
159
|
-
console.error(chalk.red('✗ Daemon token not found'));
|
|
160
|
-
console.error(chalk.dim(' Start daemon at least once: cf daemon start'));
|
|
161
|
-
console.error(chalk.dim(' This generates ~/.claude-forge/daemon.token'));
|
|
162
|
-
process.exit(1);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// 4. 获取 MCP URL
|
|
166
|
-
const mcpUrl = getMcpServerUrl();
|
|
167
|
-
|
|
168
|
-
// 5. 执行注册命令
|
|
169
|
-
// claude mcp add --transport http -s user claude-forge <url> -H "Authorization: Bearer <token>"
|
|
170
|
-
console.log(chalk.dim(`Registering: ${mcpUrl}`));
|
|
171
|
-
console.log(chalk.dim(`Scope: ${SCOPE} (all projects)`));
|
|
172
|
-
console.log(chalk.dim(`Token: <hidden>\n`));
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
execSync(
|
|
176
|
-
`claude mcp add --transport http -s ${SCOPE} ${SERVER_NAME} "${mcpUrl}" -H "Authorization: Bearer ${token}"`,
|
|
177
|
-
{ stdio: 'inherit' },
|
|
178
|
-
);
|
|
179
|
-
console.log(chalk.green('\n✓ MCP server registered successfully'));
|
|
180
|
-
console.log(chalk.dim(' Restart Claude Code (or open a new session) to apply'));
|
|
181
|
-
} catch (err) {
|
|
182
|
-
console.error(chalk.red('\n✗ Registration failed'));
|
|
183
|
-
if (err instanceof Error) {
|
|
184
|
-
console.error(chalk.dim(err.message));
|
|
185
|
-
}
|
|
186
|
-
process.exit(1);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* cf mcp unregister
|
|
192
|
-
*/
|
|
193
|
-
export function unregisterCommand(): void {
|
|
194
|
-
console.log(chalk.bold('🗑️ Unregistering MCP Server\n'));
|
|
195
|
-
|
|
196
|
-
if (!isClaudeCodeInstalled()) {
|
|
197
|
-
console.error(chalk.red('✗ Claude Code CLI not found'));
|
|
198
|
-
process.exit(1);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const { registered } = isMcpRegistered();
|
|
202
|
-
if (!registered) {
|
|
203
|
-
console.log(chalk.yellow('⚠ MCP server not registered'));
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
try {
|
|
208
|
-
execSync(`claude mcp remove -s ${SCOPE} ${SERVER_NAME}`, { stdio: 'inherit' });
|
|
209
|
-
console.log(chalk.green('\n✓ MCP server unregistered'));
|
|
210
|
-
} catch (err) {
|
|
211
|
-
console.error(chalk.red('\n✗ Unregister failed'));
|
|
212
|
-
if (err instanceof Error) {
|
|
213
|
-
console.error(chalk.dim(err.message));
|
|
214
|
-
}
|
|
215
|
-
process.exit(1);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* 注册 cf mcp 命令组
|
|
221
|
-
*/
|
|
222
|
-
export function register(program: Command): void {
|
|
223
|
-
const mcp = program
|
|
224
|
-
.command('mcp')
|
|
225
|
-
.description('MCP server registration and management');
|
|
226
|
-
|
|
227
|
-
mcp
|
|
228
|
-
.command('status')
|
|
229
|
-
.description('Check MCP server registration status')
|
|
230
|
-
.action(statusCommand);
|
|
231
|
-
|
|
232
|
-
mcp
|
|
233
|
-
.command('register')
|
|
234
|
-
.description('Register claude-forge MCP server with Claude Code (user scope)')
|
|
235
|
-
.action(registerCommand);
|
|
236
|
-
|
|
237
|
-
mcp
|
|
238
|
-
.command('unregister')
|
|
239
|
-
.alias('remove')
|
|
240
|
-
.description('Unregister claude-forge MCP server from Claude Code')
|
|
241
|
-
.action(unregisterCommand);
|
|
242
|
-
}
|
package/src/cli/commands/menu.ts
DELETED
|
@@ -1,357 +0,0 @@
|
|
|
1
|
-
import readline from 'readline';
|
|
2
|
-
import { spawn } from 'child_process';
|
|
3
|
-
import { createRequire } from 'module';
|
|
4
|
-
import type { Command } from 'commander';
|
|
5
|
-
import { DEFAULTS } from '../../core/constants.js';
|
|
6
|
-
|
|
7
|
-
const require = createRequire(import.meta.url);
|
|
8
|
-
const { version } = require('../../../package.json') as { version: string };
|
|
9
|
-
|
|
10
|
-
export function registerMenuCommand(program: Command): void {
|
|
11
|
-
program
|
|
12
|
-
.command('menu')
|
|
13
|
-
.description('Interactive menu for common operations')
|
|
14
|
-
.action(async () => {
|
|
15
|
-
await showMainMenu();
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async function showMainMenu(): Promise<void> {
|
|
20
|
-
console.clear();
|
|
21
|
-
console.log('\x1b[36m╔════════════════════════════════════════╗\x1b[0m');
|
|
22
|
-
console.log(`\x1b[36m║ Claude Forge v${version.padEnd(24)}║\x1b[0m`);
|
|
23
|
-
console.log('\x1b[36m╚════════════════════════════════════════╝\x1b[0m\n');
|
|
24
|
-
|
|
25
|
-
console.log(' \x1b[33m[1]\x1b[0m 🚀 运行与状态');
|
|
26
|
-
console.log(' \x1b[33m[2]\x1b[0m 📊 会话与日志');
|
|
27
|
-
console.log(' \x1b[33m[3]\x1b[0m ⚙️ 项目治理');
|
|
28
|
-
console.log(' \x1b[33m[4]\x1b[0m 🤖 AI 配置');
|
|
29
|
-
console.log(' \x1b[33m[5]\x1b[0m 📡 MCP Server');
|
|
30
|
-
console.log('');
|
|
31
|
-
console.log(' \x1b[33m[0]\x1b[0m 退出\n');
|
|
32
|
-
|
|
33
|
-
const choice = await prompt('请选择');
|
|
34
|
-
|
|
35
|
-
switch (choice) {
|
|
36
|
-
case '1': await showRuntimeMenu(); break;
|
|
37
|
-
case '2': await showSessionMenu(); break;
|
|
38
|
-
case '3': await showGovernanceMenu(); break;
|
|
39
|
-
case '4': await showAIConfigMenu(); break;
|
|
40
|
-
case '5': await showMcpMenu(); break;
|
|
41
|
-
case '0': process.exit(0);
|
|
42
|
-
default:
|
|
43
|
-
console.log('\x1b[31m无效选择\x1b[0m');
|
|
44
|
-
await waitForKey();
|
|
45
|
-
}
|
|
46
|
-
await showMainMenu();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async function showRuntimeMenu(): Promise<void> {
|
|
50
|
-
console.clear();
|
|
51
|
-
console.log('\x1b[36m═══ 🚀 运行与状态 ═══\x1b[0m\n');
|
|
52
|
-
console.log(' \x1b[33m[1]\x1b[0m 启动 daemon');
|
|
53
|
-
console.log(' \x1b[33m[2]\x1b[0m 停止 daemon');
|
|
54
|
-
console.log(' \x1b[33m[3]\x1b[0m 查看状态');
|
|
55
|
-
console.log(' \x1b[33m[4]\x1b[0m 打开 Web Dashboard');
|
|
56
|
-
console.log('');
|
|
57
|
-
console.log(' \x1b[33m[0]\x1b[0m 返回\n');
|
|
58
|
-
|
|
59
|
-
const choice = await prompt('请选择');
|
|
60
|
-
switch (choice) {
|
|
61
|
-
case '1': await runCommand('daemon', ['start']); await waitForKey(); break;
|
|
62
|
-
case '2': await runCommand('daemon', ['stop']); await waitForKey(); break;
|
|
63
|
-
case '3': await runCommand('status', []); await waitForKey(); break;
|
|
64
|
-
case '4': openDashboard(); await waitForKey(); break;
|
|
65
|
-
case '0': return;
|
|
66
|
-
default: console.log('\x1b[31m无效选择\x1b[0m'); await waitForKey();
|
|
67
|
-
}
|
|
68
|
-
await showRuntimeMenu();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async function showSessionMenu(): Promise<void> {
|
|
72
|
-
console.clear();
|
|
73
|
-
console.log('\x1b[36m═══ 📊 会话与日志 ═══\x1b[0m\n');
|
|
74
|
-
console.log(' \x1b[33m[1]\x1b[0m 最近会话(按会话分组)');
|
|
75
|
-
console.log(' \x1b[33m[2]\x1b[0m 最近事件(平铺)');
|
|
76
|
-
console.log(' \x1b[33m[3]\x1b[0m 查看注入历史');
|
|
77
|
-
console.log(' \x1b[33m[4]\x1b[0m 实时跟踪(follow)');
|
|
78
|
-
console.log('');
|
|
79
|
-
console.log(' \x1b[33m[0]\x1b[0m 返回\n');
|
|
80
|
-
|
|
81
|
-
const choice = await prompt('请选择');
|
|
82
|
-
switch (choice) {
|
|
83
|
-
case '1': await runCommand('logs', ['-n', '20']); await waitForKey(); break;
|
|
84
|
-
case '2': await runCommand('logs', ['--flat', '-n', '50']); await waitForKey(); break;
|
|
85
|
-
case '3': await runCommand('logs', ['--injections', '-n', '10']); await waitForKey(); break;
|
|
86
|
-
case '4': await runCommand('logs', ['--follow']); break;
|
|
87
|
-
case '0': return;
|
|
88
|
-
default: console.log('\x1b[31m无效选择\x1b[0m'); await waitForKey();
|
|
89
|
-
}
|
|
90
|
-
await showSessionMenu();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async function showGovernanceMenu(): Promise<void> {
|
|
94
|
-
console.clear();
|
|
95
|
-
console.log('\x1b[36m═══ ⚙️ 项目治理 ═══\x1b[0m\n');
|
|
96
|
-
console.log(' \x1b[33m[1]\x1b[0m 管理 CLAUDE.md');
|
|
97
|
-
console.log(' \x1b[33m[2]\x1b[0m 查看技能列表');
|
|
98
|
-
console.log(' \x1b[33m[3]\x1b[0m 查看配置');
|
|
99
|
-
console.log(' \x1b[33m[4]\x1b[0m 初始化项目');
|
|
100
|
-
console.log('');
|
|
101
|
-
console.log(' \x1b[33m[0]\x1b[0m 返回\n');
|
|
102
|
-
|
|
103
|
-
const choice = await prompt('请选择');
|
|
104
|
-
switch (choice) {
|
|
105
|
-
case '1': await runCommand('claudemd', ['--help']); await waitForKey(); break;
|
|
106
|
-
case '2': await runCommand('skills', ['list']); await waitForKey(); break;
|
|
107
|
-
case '3': await runCommand('config', ['show']); await waitForKey(); break;
|
|
108
|
-
case '4': await runCommand('init', []); await waitForKey(); break;
|
|
109
|
-
case '0': return;
|
|
110
|
-
default: console.log('\x1b[31m无效选择\x1b[0m'); await waitForKey();
|
|
111
|
-
}
|
|
112
|
-
await showGovernanceMenu();
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function runCommand(cmd: string, args: string[]): Promise<void> {
|
|
116
|
-
return new Promise((resolve) => {
|
|
117
|
-
console.log(`\n\x1b[90m$ cf ${cmd} ${args.join(' ')}\x1b[0m\n`);
|
|
118
|
-
const child = spawn('node', [process.argv[1], cmd, ...args], {
|
|
119
|
-
stdio: 'inherit',
|
|
120
|
-
cwd: process.cwd(),
|
|
121
|
-
});
|
|
122
|
-
child.on('close', () => resolve());
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function openDashboard(): void {
|
|
127
|
-
console.log('\x1b[32m正在打开 Web Dashboard...\x1b[0m');
|
|
128
|
-
console.log(`访问: \x1b[36mhttp://localhost:${DEFAULTS.WEB_PORT}\x1b[0m\n`);
|
|
129
|
-
const open = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
|
|
130
|
-
spawn(open, [`http://localhost:${DEFAULTS.WEB_PORT}`], { detached: true, stdio: 'ignore' }).unref();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function prompt(question: string): Promise<string> {
|
|
134
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
135
|
-
return new Promise((resolve) => {
|
|
136
|
-
rl.question(`\x1b[32m${question}: \x1b[0m`, (answer) => {
|
|
137
|
-
rl.close();
|
|
138
|
-
resolve(answer.trim());
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function waitForKey(): Promise<void> {
|
|
144
|
-
return new Promise((resolve) => {
|
|
145
|
-
console.log('\n\x1b[90m按任意键继续...\x1b[0m');
|
|
146
|
-
process.stdin.setRawMode(true);
|
|
147
|
-
process.stdin.resume();
|
|
148
|
-
process.stdin.once('data', () => {
|
|
149
|
-
process.stdin.setRawMode(false);
|
|
150
|
-
process.stdin.pause();
|
|
151
|
-
resolve();
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
async function showAIConfigMenu(): Promise<void> {
|
|
157
|
-
console.clear();
|
|
158
|
-
console.log('\x1b[36m═══ 🤖 AI 配置 ═══\x1b[0m\n');
|
|
159
|
-
console.log(' \x1b[33m[1]\x1b[0m 查看当前配置');
|
|
160
|
-
console.log(' \x1b[33m[2]\x1b[0m 设置 API Key');
|
|
161
|
-
console.log(' \x1b[33m[3]\x1b[0m 设置 Base URL');
|
|
162
|
-
console.log(' \x1b[33m[4]\x1b[0m 选择模型');
|
|
163
|
-
console.log(' \x1b[33m[5]\x1b[0m 测试连接');
|
|
164
|
-
console.log('');
|
|
165
|
-
console.log(' \x1b[33m[0]\x1b[0m 返回\n');
|
|
166
|
-
|
|
167
|
-
const choice = await prompt('请选择');
|
|
168
|
-
switch (choice) {
|
|
169
|
-
case '1': await showCurrentAIConfig(); await waitForKey(); break;
|
|
170
|
-
case '2': await setAPIKey(); await waitForKey(); break;
|
|
171
|
-
case '3': await setBaseURL(); await waitForKey(); break;
|
|
172
|
-
case '4': await selectModel(); await waitForKey(); break;
|
|
173
|
-
case '5': await testConnection(); await waitForKey(); break;
|
|
174
|
-
case '0': return;
|
|
175
|
-
default: console.log('\x1b[31m无效选择\x1b[0m'); await waitForKey();
|
|
176
|
-
}
|
|
177
|
-
await showAIConfigMenu();
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
async function showCurrentAIConfig(): Promise<void> {
|
|
181
|
-
try {
|
|
182
|
-
const { ConfigManager } = await import('../../core/config.js');
|
|
183
|
-
const { FORGE_PATHS } = await import('../../core/constants.js');
|
|
184
|
-
const configManager = new ConfigManager();
|
|
185
|
-
const config = configManager.get();
|
|
186
|
-
|
|
187
|
-
const maskApiKey = (key: string): string => {
|
|
188
|
-
if (!key || key.length < 10) return '(未设置)';
|
|
189
|
-
return key.slice(0, 6) + '***' + key.slice(-4);
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
console.log('\n\x1b[36m当前 AI 配置:\x1b[0m');
|
|
193
|
-
console.log(` API Key: ${maskApiKey(config.ai.api_key)}`);
|
|
194
|
-
console.log(` Base URL: ${config.ai.base_url || '(未设置)'}`);
|
|
195
|
-
console.log(` Model: ${config.ai.model}`);
|
|
196
|
-
console.log(` Provider: ${config.ai.provider}`);
|
|
197
|
-
console.log(`\n配置文件: ${FORGE_PATHS.config()}`);
|
|
198
|
-
} catch (err) {
|
|
199
|
-
console.log(`\x1b[31m读取配置失败: ${err}\x1b[0m`);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
async function setAPIKey(): Promise<void> {
|
|
204
|
-
try {
|
|
205
|
-
const apiKey = await prompt('请输入 API Key');
|
|
206
|
-
if (!apiKey) {
|
|
207
|
-
console.log('\x1b[31mAPI Key 不能为空\x1b[0m');
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const { ConfigManager } = await import('../../core/config.js');
|
|
212
|
-
const configManager = new ConfigManager();
|
|
213
|
-
const config = configManager.get();
|
|
214
|
-
config.ai.api_key = apiKey;
|
|
215
|
-
configManager.save();
|
|
216
|
-
|
|
217
|
-
console.log('\x1b[32m✓ API Key 已保存\x1b[0m');
|
|
218
|
-
console.log('\x1b[90m提示: 重启 daemon 后生效\x1b[0m');
|
|
219
|
-
} catch (err) {
|
|
220
|
-
console.log(`\x1b[31m保存失败: ${err}\x1b[0m`);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
async function setBaseURL(): Promise<void> {
|
|
225
|
-
try {
|
|
226
|
-
const baseUrl = await prompt('请输入 Base URL (留空使用默认)');
|
|
227
|
-
|
|
228
|
-
const { ConfigManager } = await import('../../core/config.js');
|
|
229
|
-
const configManager = new ConfigManager();
|
|
230
|
-
const config = configManager.get();
|
|
231
|
-
config.ai.base_url = baseUrl || undefined;
|
|
232
|
-
configManager.save();
|
|
233
|
-
|
|
234
|
-
console.log('\x1b[32m✓ Base URL 已保存\x1b[0m');
|
|
235
|
-
console.log('\x1b[90m提示: 重启 daemon 后生效\x1b[0m');
|
|
236
|
-
} catch (err) {
|
|
237
|
-
console.log(`\x1b[31m保存失败: ${err}\x1b[0m`);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async function selectModel(): Promise<void> {
|
|
242
|
-
try {
|
|
243
|
-
console.log('\n\x1b[36m正在获取模型列表...\x1b[0m');
|
|
244
|
-
|
|
245
|
-
const response = await fetch(`http://localhost:${DEFAULTS.WEB_PORT}/api/ai/models`);
|
|
246
|
-
if (!response.ok) {
|
|
247
|
-
const text = await response.text();
|
|
248
|
-
console.log(`\x1b[31m获取模型列表失败: ${text}\x1b[0m`);
|
|
249
|
-
console.log('\x1b[90m提示: 请先配置 API Key 和 Base URL,并确保 daemon 正在运行\x1b[0m');
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const data = await response.json() as { data?: Array<{ id: string }> };
|
|
254
|
-
const models = data.data || [];
|
|
255
|
-
|
|
256
|
-
if (models.length === 0) {
|
|
257
|
-
console.log('\x1b[31m未找到可用模型\x1b[0m');
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
console.log('\n\x1b[36m可用模型:\x1b[0m');
|
|
262
|
-
models.forEach((m, i) => {
|
|
263
|
-
console.log(` \x1b[33m[${i + 1}]\x1b[0m ${m.id}`);
|
|
264
|
-
});
|
|
265
|
-
console.log(' \x1b[33m[0]\x1b[0m 取消\n');
|
|
266
|
-
|
|
267
|
-
const choice = await prompt('请选择模型');
|
|
268
|
-
const idx = parseInt(choice) - 1;
|
|
269
|
-
|
|
270
|
-
if (choice === '0') return;
|
|
271
|
-
if (idx < 0 || idx >= models.length) {
|
|
272
|
-
console.log('\x1b[31m无效选择\x1b[0m');
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
const selectedModel = models[idx].id;
|
|
277
|
-
const { ConfigManager } = await import('../../core/config.js');
|
|
278
|
-
const configManager = new ConfigManager();
|
|
279
|
-
const config = configManager.get();
|
|
280
|
-
config.ai.model = selectedModel;
|
|
281
|
-
configManager.save();
|
|
282
|
-
|
|
283
|
-
console.log(`\x1b[32m✓ 已选择模型: ${selectedModel}\x1b[0m`);
|
|
284
|
-
console.log('\x1b[90m提示: 重启 daemon 后生效\x1b[0m');
|
|
285
|
-
} catch (err) {
|
|
286
|
-
console.log(`\x1b[31m操作失败: ${err}\x1b[0m`);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
async function testConnection(): Promise<void> {
|
|
291
|
-
try {
|
|
292
|
-
console.log('\n\x1b[36m正在测试连接...\x1b[0m');
|
|
293
|
-
|
|
294
|
-
const { ConfigManager } = await import('../../core/config.js');
|
|
295
|
-
const configManager = new ConfigManager();
|
|
296
|
-
const config = configManager.get();
|
|
297
|
-
|
|
298
|
-
const apiKey = config.ai.api_key;
|
|
299
|
-
const baseUrl = config.ai.base_url || 'https://api.anthropic.com';
|
|
300
|
-
const model = config.ai.model;
|
|
301
|
-
|
|
302
|
-
if (!apiKey) {
|
|
303
|
-
console.log('\x1b[31m请先配置 API Key\x1b[0m');
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
const messagesUrl = baseUrl.endsWith('/v1')
|
|
308
|
-
? `${baseUrl}/messages`
|
|
309
|
-
: `${baseUrl}/v1/messages`;
|
|
310
|
-
|
|
311
|
-
const response = await fetch(messagesUrl, {
|
|
312
|
-
method: 'POST',
|
|
313
|
-
headers: {
|
|
314
|
-
'Content-Type': 'application/json',
|
|
315
|
-
'x-api-key': apiKey,
|
|
316
|
-
'anthropic-version': '2023-06-01',
|
|
317
|
-
},
|
|
318
|
-
body: JSON.stringify({
|
|
319
|
-
model,
|
|
320
|
-
max_tokens: 10,
|
|
321
|
-
messages: [{ role: 'user', content: 'ping' }],
|
|
322
|
-
}),
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
if (!response.ok) {
|
|
326
|
-
const text = await response.text();
|
|
327
|
-
console.log(`\x1b[31m连接失败: ${response.status} ${text}\x1b[0m`);
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
const data = await response.json() as { model?: string };
|
|
332
|
-
console.log(`\x1b[32m✓ 连接成功!\x1b[0m`);
|
|
333
|
-
console.log(` 模型: ${data.model || model}`);
|
|
334
|
-
} catch (err) {
|
|
335
|
-
console.log(`\x1b[31m测试失败: ${err}\x1b[0m`);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
async function showMcpMenu(): Promise<void> {
|
|
340
|
-
console.clear();
|
|
341
|
-
console.log('\x1b[36m═══ 📡 MCP Server ═══\x1b[0m\n');
|
|
342
|
-
console.log(' \x1b[33m[1]\x1b[0m 查看状态');
|
|
343
|
-
console.log(' \x1b[33m[2]\x1b[0m 注册到 Claude Code');
|
|
344
|
-
console.log(' \x1b[33m[3]\x1b[0m 取消注册');
|
|
345
|
-
console.log('');
|
|
346
|
-
console.log(' \x1b[33m[0]\x1b[0m 返回\n');
|
|
347
|
-
|
|
348
|
-
const choice = await prompt('请选择');
|
|
349
|
-
switch (choice) {
|
|
350
|
-
case '1': await runCommand('mcp', ['status']); await waitForKey(); break;
|
|
351
|
-
case '2': await runCommand('mcp', ['register']); await waitForKey(); break;
|
|
352
|
-
case '3': await runCommand('mcp', ['unregister']); await waitForKey(); break;
|
|
353
|
-
case '0': return;
|
|
354
|
-
default: console.log('\x1b[31m无效选择\x1b[0m'); await waitForKey();
|
|
355
|
-
}
|
|
356
|
-
await showMcpMenu();
|
|
357
|
-
}
|