@winspan/claude-forge 8.51.1 → 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.
Files changed (409) hide show
  1. package/DEVELOPMENT.md +290 -221
  2. package/README.md +50 -8
  3. package/dist/cli/commands/skills.d.ts.map +1 -1
  4. package/dist/cli/commands/skills.js +121 -2
  5. package/dist/cli/commands/skills.js.map +1 -1
  6. package/dist/cli/init/hook-manager.d.ts +1 -1
  7. package/dist/cli/init/hook-manager.d.ts.map +1 -1
  8. package/dist/cli/init/hook-manager.js +1 -0
  9. package/dist/cli/init/hook-manager.js.map +1 -1
  10. package/dist/core/constants.d.ts +2 -0
  11. package/dist/core/constants.d.ts.map +1 -1
  12. package/dist/core/constants.js +4 -0
  13. package/dist/core/constants.js.map +1 -1
  14. package/dist/core/storage/events.d.ts.map +1 -1
  15. package/dist/core/storage/events.js +0 -1
  16. package/dist/core/storage/events.js.map +1 -1
  17. package/dist/core/storage/maintenance.d.ts +25 -3
  18. package/dist/core/storage/maintenance.d.ts.map +1 -1
  19. package/dist/core/storage/maintenance.js +33 -4
  20. package/dist/core/storage/maintenance.js.map +1 -1
  21. package/dist/core/storage/routing.d.ts +4 -0
  22. package/dist/core/storage/routing.d.ts.map +1 -1
  23. package/dist/core/storage/routing.js +10 -4
  24. package/dist/core/storage/routing.js.map +1 -1
  25. package/dist/core/storage/sessions.d.ts +17 -0
  26. package/dist/core/storage/sessions.d.ts.map +1 -1
  27. package/dist/core/storage/sessions.js +64 -0
  28. package/dist/core/storage/sessions.js.map +1 -1
  29. package/dist/core/storage/skills.d.ts +4 -0
  30. package/dist/core/storage/skills.d.ts.map +1 -1
  31. package/dist/core/storage/skills.js +10 -2
  32. package/dist/core/storage/skills.js.map +1 -1
  33. package/dist/core/storage/sqlite.d.ts +5 -0
  34. package/dist/core/storage/sqlite.d.ts.map +1 -1
  35. package/dist/core/storage/sqlite.js +6 -0
  36. package/dist/core/storage/sqlite.js.map +1 -1
  37. package/dist/core/storage/tasks.d.ts.map +1 -1
  38. package/dist/core/storage/tasks.js +2 -0
  39. package/dist/core/storage/tasks.js.map +1 -1
  40. package/dist/core/types.d.ts +7 -0
  41. package/dist/core/types.d.ts.map +1 -1
  42. package/dist/daemon/index.d.ts.map +1 -1
  43. package/dist/daemon/index.js +30 -5
  44. package/dist/daemon/index.js.map +1 -1
  45. package/dist/daemon/skill-sync.d.ts +21 -0
  46. package/dist/daemon/skill-sync.d.ts.map +1 -0
  47. package/dist/daemon/skill-sync.js +75 -0
  48. package/dist/daemon/skill-sync.js.map +1 -0
  49. package/dist/hooks/notification.sh +1 -1
  50. package/dist/hooks/post-tool-use.sh +1 -1
  51. package/dist/hooks/pre-tool-use.sh +1 -1
  52. package/dist/hooks/stop.sh +1 -1
  53. package/dist/hooks/user-prompt-submit.sh +1 -1
  54. package/dist/skills/official/code-simplifier.md +37 -1
  55. package/dist/skills/official/find-skills.md +120 -1
  56. package/dist/skills/official/official-api-design.md +14 -1
  57. package/dist/skills/official/official-architecture-decision.md +22 -1
  58. package/dist/skills/official/official-db-schema-design.md +19 -1
  59. package/dist/skills/official/official-debug.md +9 -1
  60. package/dist/skills/official/official-pr-review.md +1 -1
  61. package/dist/skills/official/official-security-hardening.md +7 -1
  62. package/dist/skills/official/planning-with-files.md +206 -2
  63. package/dist/skills/official/ui-ux-pro-max.md +88 -1
  64. package/dist/skills/official/webapp-testing.md +85 -1
  65. package/dist/skills/registry.d.ts +1 -1
  66. package/dist/skills/registry.d.ts.map +1 -1
  67. package/dist/skills/registry.js +15 -4
  68. package/dist/skills/registry.js.map +1 -1
  69. package/dist/skills/semantic-matcher.d.ts +4 -3
  70. package/dist/skills/semantic-matcher.d.ts.map +1 -1
  71. package/dist/skills/semantic-matcher.js +20 -22
  72. package/dist/skills/semantic-matcher.js.map +1 -1
  73. package/dist/skills/upgrade-engine.d.ts +93 -0
  74. package/dist/skills/upgrade-engine.d.ts.map +1 -0
  75. package/dist/skills/upgrade-engine.js +447 -0
  76. package/dist/skills/upgrade-engine.js.map +1 -0
  77. package/dist/skills/upgrade-prompt.d.ts +20 -0
  78. package/dist/skills/upgrade-prompt.d.ts.map +1 -0
  79. package/dist/skills/upgrade-prompt.js +75 -0
  80. package/dist/skills/upgrade-prompt.js.map +1 -0
  81. package/dist/web/analytics/weekly-report.d.ts.map +1 -1
  82. package/dist/web/analytics/weekly-report.js +21 -29
  83. package/dist/web/analytics/weekly-report.js.map +1 -1
  84. package/dist/web/routes/patch.d.ts.map +1 -1
  85. package/dist/web/routes/patch.js +32 -2
  86. package/dist/web/routes/patch.js.map +1 -1
  87. package/dist/web/routes/sessions.d.ts.map +1 -1
  88. package/dist/web/routes/sessions.js +9 -7
  89. package/dist/web/routes/sessions.js.map +1 -1
  90. package/dist/web/routes/trace.d.ts.map +1 -1
  91. package/dist/web/routes/trace.js +2 -3
  92. package/dist/web/routes/trace.js.map +1 -1
  93. package/dist/web/server.d.ts.map +1 -1
  94. package/dist/web/server.js +3 -2
  95. package/dist/web/server.js.map +1 -1
  96. package/package.json +12 -2
  97. package/scripts/postinstall.cjs +21 -0
  98. package/.claude/CLAUDE.md +0 -17
  99. package/.eslintrc.js +0 -23
  100. package/.prettierrc +0 -8
  101. package/ARCHITECTURE_ISSUES.md +0 -249
  102. package/CLAUDE.md +0 -265
  103. package/CLAUDE.md.backup +0 -488
  104. package/docs/concurrent-agents.md +0 -129
  105. package/docs/design/architecture-review-20260516.md +0 -232
  106. package/docs/design/fix-skills-data-and-set-leak-spec-20260516-1300.md +0 -219
  107. package/docs/design/h1-storage-aggregation-spec-20260518-1121.md +0 -299
  108. package/docs/design/h2-getdatabase-encapsulation-spec-20260518-1450.md +0 -191
  109. package/docs/design/h3-fallback-removal-spec-20260518-1245.md +0 -76
  110. package/docs/design/h4-index-dedup-spec-20260518-1230.md +0 -109
  111. package/docs/design/h6-services-migration-spec-20260518-1355.md +0 -82
  112. package/docs/design/hook-failure-queue-spec-20260516-1530.md +0 -204
  113. package/docs/design/l1-swarm-protocol-extract-spec-20260518-1605.md +0 -106
  114. package/docs/design/m10-forge-paths-spec-20260518-1320.md +0 -121
  115. package/docs/design/m2-m3-tool-input-spec-20260518-1425.md +0 -131
  116. package/docs/design/m7-routing-event-association-spec-20260518-1545.md +0 -103
  117. package/docs/design/project-path-gitroot-spec-20260518-1715.md +0 -134
  118. package/docs/design/refactor-phase1-spec-20260515-1600.md +0 -543
  119. package/docs/design/refactor-phase2-spec-20260515-1700.md +0 -424
  120. package/docs/design/task-active-gc-spec-20260518-1745.md +0 -146
  121. package/docs/design/tasks-list-filter-pagination-spec-20260518-0930.md +0 -208
  122. package/docs/implementation/fix-skills-data-and-set-leak-changelog-20260516-1300.md +0 -104
  123. package/docs/implementation/h1-storage-aggregation-changelog-20260518-1121.md +0 -82
  124. package/docs/implementation/h2-final-changelog-20260518-1530.md +0 -61
  125. package/docs/implementation/h2-phase1-safety-net-changelog-20260518-1450.md +0 -70
  126. package/docs/implementation/h2-phase2-operations-changelog-20260518-1450.md +0 -120
  127. package/docs/implementation/h2-phase3-callsites-changelog-20260518-1450.md +0 -71
  128. package/docs/implementation/h3-fallback-removal-changelog-20260518-1245.md +0 -71
  129. package/docs/implementation/h4-index-dedup-changelog-20260518-1230.md +0 -60
  130. package/docs/implementation/h6-services-migration-changelog-20260518-1355.md +0 -46
  131. package/docs/implementation/h7-m9-defaults-changelog-20260518-1300.md +0 -46
  132. package/docs/implementation/hook-failure-queue-changelog-20260516-1530.md +0 -196
  133. package/docs/implementation/hotfix-daemon-event-reject-20260516-1430.md +0 -56
  134. package/docs/implementation/l1-swarm-protocol-extract-changelog-20260518-1605.md +0 -45
  135. package/docs/implementation/l3-l4-daemon-perf-changelog-20260518-1410.md +0 -63
  136. package/docs/implementation/l6-l8-final-cleanup-changelog-20260518-1640.md +0 -38
  137. package/docs/implementation/m1-m4-m5-l7-cleanup-changelog-20260518-1310.md +0 -58
  138. package/docs/implementation/m10-forge-paths-changelog-20260518-1320.md +0 -60
  139. package/docs/implementation/m2-m3-tool-input-changelog-20260518-1425.md +0 -43
  140. package/docs/implementation/m6-m8-naming-shutdown-changelog-20260518-1340.md +0 -56
  141. package/docs/implementation/m7-routing-association-changelog-20260518-1545.md +0 -69
  142. package/docs/implementation/project-path-gitroot-changelog-20260518-1715.md +0 -63
  143. package/docs/implementation/refactor-phase1-changelog-20260515-1630.md +0 -354
  144. package/docs/implementation/refactor-phase2-changelog-20260515-1705.md +0 -421
  145. package/docs/implementation/task-active-gc-changelog-20260518-1745.md +0 -35
  146. package/docs/implementation/task-title-summary-changelog-20260518-1130.md +0 -39
  147. package/docs/implementation/tasks-detail-back-loses-filters-changelog-20260518-1100.md +0 -22
  148. package/docs/implementation/tasks-list-filter-pagination-changelog-20260518-0930.md +0 -72
  149. package/docs/implementation/tasks-page-white-screen-hotfix-changelog-20260518-1015.md +0 -56
  150. package/docs/reviews/claudemd-template-sync.md +0 -54
  151. package/docs/reviews/task-title-summary.md +0 -92
  152. package/docs/reviews/tasks-detail-back-loses-filters.md +0 -58
  153. package/docs/reviews/tasks-filter-pagination.md +0 -80
  154. package/docs/reviews/tasks-page-white-screen-hotfix.md +0 -126
  155. package/docs/ruflo-learning-strategy.md +0 -322
  156. package/docs/skills-deduplication-analysis.md +0 -83
  157. package/docs/skills-multiformat-support.md +0 -177
  158. package/docs/skills-third-party.md +0 -183
  159. package/docs/testing/tasks-filter-pagination-test-report.md +0 -86
  160. package/forge +0 -321
  161. package/playwright.config.ts +0 -40
  162. package/scripts/demo-v2.ts +0 -91
  163. package/scripts/dev-daemon.sh +0 -232
  164. package/scripts/dev-web.ts +0 -109
  165. package/scripts/e2e-mcp-link.ts +0 -423
  166. package/scripts/e2e-methodology-quality.ts +0 -253
  167. package/scripts/e2e-routing.ts +0 -456
  168. package/scripts/e2e-user-methodology.ts +0 -326
  169. package/scripts/e2e-web-workflows.ts +0 -299
  170. package/scripts/migrate-legacy-to-dynamic.sql +0 -108
  171. package/scripts/regenerate-execution-docs.ts +0 -116
  172. package/scripts/sync-agent-skills.ts +0 -193
  173. package/scripts/test-hook.sh +0 -71
  174. package/scripts/verify-skill-loading.ts +0 -62
  175. package/src/claudemd/claudemd-generator.ts +0 -568
  176. package/src/claudemd/convention-extractor.ts +0 -69
  177. package/src/claudemd/index.ts +0 -35
  178. package/src/claudemd/persona-manager.ts +0 -88
  179. package/src/claudemd/resume-manager.ts +0 -236
  180. package/src/claudemd/tech-detector.ts +0 -220
  181. package/src/claudemd/templates/swarm-protocol.md +0 -222
  182. package/src/cli/commands/claudemd.ts +0 -84
  183. package/src/cli/commands/config.ts +0 -46
  184. package/src/cli/commands/daemon.ts +0 -310
  185. package/src/cli/commands/executions.ts +0 -115
  186. package/src/cli/commands/init.ts +0 -204
  187. package/src/cli/commands/logs.ts +0 -181
  188. package/src/cli/commands/mcp.ts +0 -242
  189. package/src/cli/commands/menu.ts +0 -357
  190. package/src/cli/commands/skills.ts +0 -185
  191. package/src/cli/commands/stats.ts +0 -73
  192. package/src/cli/commands/status.ts +0 -69
  193. package/src/cli/commands/template.ts +0 -77
  194. package/src/cli/commands/trace.ts +0 -148
  195. package/src/cli/index.ts +0 -42
  196. package/src/cli/init/hook-manager.ts +0 -132
  197. package/src/core/ai/provider.ts +0 -308
  198. package/src/core/ai/types.ts +0 -51
  199. package/src/core/config.ts +0 -124
  200. package/src/core/constants.ts +0 -62
  201. package/src/core/event-fields.ts +0 -32
  202. package/src/core/queue/index.ts +0 -192
  203. package/src/core/storage/base.ts +0 -302
  204. package/src/core/storage/events.ts +0 -434
  205. package/src/core/storage/injections.ts +0 -78
  206. package/src/core/storage/maintenance.ts +0 -59
  207. package/src/core/storage/migrations/002_add_skill_tracking.sql +0 -6
  208. package/src/core/storage/migrations/003_add_skill_invocations.sql +0 -23
  209. package/src/core/storage/performance-indexes.sql +0 -23
  210. package/src/core/storage/routing.ts +0 -322
  211. package/src/core/storage/rows.ts +0 -112
  212. package/src/core/storage/schema.sql +0 -224
  213. package/src/core/storage/sessions.ts +0 -168
  214. package/src/core/storage/skills.ts +0 -233
  215. package/src/core/storage/sqlite.ts +0 -293
  216. package/src/core/storage/tasks.ts +0 -318
  217. package/src/core/storage/token-usage.ts +0 -93
  218. package/src/core/types.ts +0 -181
  219. package/src/core/utils/error-handler.ts +0 -257
  220. package/src/core/utils/forge-resume-block.ts +0 -74
  221. package/src/core/utils/format.ts +0 -69
  222. package/src/core/utils/git.ts +0 -23
  223. package/src/core/utils/logger.ts +0 -134
  224. package/src/core/utils/lru-cache.ts +0 -54
  225. package/src/core/utils/path.ts +0 -19
  226. package/src/core/utils/session.ts +0 -26
  227. package/src/core/utils/time.ts +0 -37
  228. package/src/core/utils/token-tracker.ts +0 -97
  229. package/src/daemon/event-parser.ts +0 -36
  230. package/src/daemon/handlers/history-exporter.ts +0 -117
  231. package/src/daemon/handlers/post-tool-use.ts +0 -54
  232. package/src/daemon/handlers/stop.ts +0 -208
  233. package/src/daemon/handlers/user-prompt.ts +0 -178
  234. package/src/daemon/hook-sync.ts +0 -91
  235. package/src/daemon/index.ts +0 -302
  236. package/src/daemon/launchd/com.claude-forge.daemon.plist.template +0 -47
  237. package/src/daemon/launchd-installer.ts +0 -260
  238. package/src/daemon/lifecycle.ts +0 -128
  239. package/src/daemon/router.ts +0 -40
  240. package/src/daemon/server.ts +0 -196
  241. package/src/daemon/services/task-segmenter.ts +0 -112
  242. package/src/hooks/hook-lib.sh +0 -118
  243. package/src/hooks/notification.sh +0 -35
  244. package/src/hooks/post-tool-use.sh +0 -61
  245. package/src/hooks/pre-tool-use.sh +0 -63
  246. package/src/hooks/stop.sh +0 -43
  247. package/src/hooks/user-prompt-submit.sh +0 -69
  248. package/src/mcp/server.ts +0 -322
  249. package/src/skills/index.ts +0 -2
  250. package/src/skills/invocation-guard.ts +0 -177
  251. package/src/skills/matcher.ts +0 -148
  252. package/src/skills/official/code-simplifier.md +0 -16
  253. package/src/skills/official/find-skills.md +0 -23
  254. package/src/skills/official/official-api-design.md +0 -17
  255. package/src/skills/official/official-architecture-decision.md +0 -20
  256. package/src/skills/official/official-bmad.md +0 -118
  257. package/src/skills/official/official-db-schema-design.md +0 -16
  258. package/src/skills/official/official-debug.md +0 -17
  259. package/src/skills/official/official-doc-driven.md +0 -31
  260. package/src/skills/official/official-harness-engineering.md +0 -108
  261. package/src/skills/official/official-performance-optimization.md +0 -30
  262. package/src/skills/official/official-pr-review.md +0 -35
  263. package/src/skills/official/official-release-checklist.md +0 -30
  264. package/src/skills/official/official-security-hardening.md +0 -26
  265. package/src/skills/official/official-spec-driven-design.md +0 -31
  266. package/src/skills/official/planning-with-files.md +0 -37
  267. package/src/skills/official/ui-ux-pro-max.md +0 -18
  268. package/src/skills/official/webapp-testing.md +0 -12
  269. package/src/skills/official-skills.ts +0 -89
  270. package/src/skills/registry.ts +0 -355
  271. package/src/skills/semantic-matcher.ts +0 -231
  272. package/src/skills/tools/pipeline-suggest.ts +0 -226
  273. package/src/skills/tools/skill-invoke.ts +0 -168
  274. package/src/skills/tools/skill-list.ts +0 -59
  275. package/src/templates/go.yaml +0 -53
  276. package/src/templates/python.yaml +0 -59
  277. package/src/templates/react.yaml +0 -55
  278. package/src/templates/template-manager.ts +0 -170
  279. package/src/web/analytics/anti-pattern-detector.ts +0 -367
  280. package/src/web/analytics/drift-detector.ts +0 -219
  281. package/src/web/analytics/weekly-report.ts +0 -431
  282. package/src/web/auth-middleware.ts +0 -54
  283. package/src/web/routes/_helpers.ts +0 -34
  284. package/src/web/routes/ai.ts +0 -204
  285. package/src/web/routes/auth.ts +0 -22
  286. package/src/web/routes/drift.ts +0 -25
  287. package/src/web/routes/error-handler.ts +0 -120
  288. package/src/web/routes/events.ts +0 -47
  289. package/src/web/routes/insights.ts +0 -43
  290. package/src/web/routes/patch.ts +0 -117
  291. package/src/web/routes/reports.ts +0 -34
  292. package/src/web/routes/rules.ts +0 -76
  293. package/src/web/routes/sessions.ts +0 -250
  294. package/src/web/routes/skill-stats.ts +0 -92
  295. package/src/web/routes/skills.ts +0 -350
  296. package/src/web/routes/static.ts +0 -67
  297. package/src/web/routes/stats.ts +0 -50
  298. package/src/web/routes/status.ts +0 -30
  299. package/src/web/routes/tasks.ts +0 -193
  300. package/src/web/routes/token-usage.ts +0 -20
  301. package/src/web/routes/trace.ts +0 -126
  302. package/src/web/routes/types.ts +0 -57
  303. package/src/web/server.ts +0 -134
  304. package/src/web/ssrf-guard.ts +0 -112
  305. package/src/web/static/index.html +0 -3251
  306. package/src/web/static/vendor/chart.umd.min.js +0 -20
  307. package/tests/e2e/dashboard.spec.ts +0 -205
  308. package/tests/e2e/routing-skill-e2e.test.ts +0 -39
  309. package/tests/helpers/mock-ai.ts +0 -92
  310. package/tests/helpers/mock-storage.ts +0 -159
  311. package/tests/integration/claudemd-generator.test.ts +0 -90
  312. package/tests/integration/queue-replay.integration.test.ts +0 -193
  313. package/tests/integration/tasks-filter.integration.test.ts +0 -154
  314. package/tests/integration/web-analytics.integration.test.ts +0 -133
  315. package/tests/integration/web-stats.integration.test.ts +0 -135
  316. package/tests/integration/web-trace.integration.test.ts +0 -175
  317. package/tests/performance/database.benchmark.ts +0 -161
  318. package/tests/semantic-matcher.test.ts +0 -99
  319. package/tests/skill-matcher.test.ts +0 -110
  320. package/tests/unit/ai-provider-retry.test.ts +0 -194
  321. package/tests/unit/ai-provider-vision.test.ts +0 -224
  322. package/tests/unit/claudemd-generator.test.ts +0 -68
  323. package/tests/unit/cli-mcp.test.ts +0 -141
  324. package/tests/unit/core/forge-paths.test.ts +0 -99
  325. package/tests/unit/daemon/hook-sync.test.ts +0 -71
  326. package/tests/unit/daemon/post-tool-use.test.ts +0 -121
  327. package/tests/unit/daemon/stop-handler-behavior-summary.test.ts +0 -202
  328. package/tests/unit/daemon/task-segmenter-recover.test.ts +0 -84
  329. package/tests/unit/event-fields.test.ts +0 -88
  330. package/tests/unit/event-parser.test.ts +0 -55
  331. package/tests/unit/handlers.test.ts +0 -171
  332. package/tests/unit/hooks/resolve-project-path.test.ts +0 -122
  333. package/tests/unit/invocation-guard.test.ts +0 -125
  334. package/tests/unit/queue.test.ts +0 -272
  335. package/tests/unit/router.test.ts +0 -138
  336. package/tests/unit/security.test.ts +0 -128
  337. package/tests/unit/skill-invocations-workflow.test.ts +0 -495
  338. package/tests/unit/skill-registry.test.ts +0 -94
  339. package/tests/unit/skills/invocation-guard-ttl.test.ts +0 -211
  340. package/tests/unit/skills/official-skills-loader.test.ts +0 -126
  341. package/tests/unit/skills/registry-multiformat.test.ts +0 -92
  342. package/tests/unit/socket-server.test.ts +0 -183
  343. package/tests/unit/storage/event-operations-aggregates.test.ts +0 -342
  344. package/tests/unit/storage/migration-idempotent.test.ts +0 -304
  345. package/tests/unit/storage/routing-aggregates.test.ts +0 -276
  346. package/tests/unit/storage/routing.test.ts +0 -117
  347. package/tests/unit/storage/schema-missing.test.ts +0 -81
  348. package/tests/unit/storage/session-operations-aggregates.test.ts +0 -120
  349. package/tests/unit/storage/sessions-aggregate.test.ts +0 -435
  350. package/tests/unit/storage/skill-operations-counts.test.ts +0 -106
  351. package/tests/unit/storage/skills-aggregates.test.ts +0 -104
  352. package/tests/unit/storage/sqlite-refactor-harness.test.ts +0 -314
  353. package/tests/unit/storage/task-operations-counts.test.ts +0 -46
  354. package/tests/unit/storage/tasks-getById.test.ts +0 -343
  355. package/tests/unit/storage/tasks-stale-gc.test.ts +0 -86
  356. package/tests/unit/storage.test.ts +0 -172
  357. package/tests/unit/token-usage.test.ts +0 -144
  358. package/tests/unit/type-guards.test.ts +0 -201
  359. package/tests/unit/utils/format.test.ts +0 -189
  360. package/tests/unit/utils/session.test.ts +0 -89
  361. package/tests/unit/utils/time.test.ts +0 -112
  362. package/tests/unit/web/navigation-back-contract.test.ts +0 -134
  363. package/tests/unit/web/routes-auth.test.ts +0 -93
  364. package/tests/unit/web/routes-events.test.ts +0 -101
  365. package/tests/unit/web/routes-rules.test.ts +0 -182
  366. package/tests/unit/web/routes-sessions.test.ts +0 -181
  367. package/tests/unit/web/routes-skill-stats.test.ts +0 -179
  368. package/tests/unit/web/routes-stats.test.ts +0 -92
  369. package/tests/unit/web/routes-tasks.test.ts +0 -385
  370. package/tests/unit/web/task-title-contract.test.ts +0 -210
  371. package/tests/unit/web/tasks-component-contract.test.ts +0 -179
  372. package/tsconfig.json +0 -22
  373. package/vitest.config.ts +0 -21
  374. package/vitest.integration.config.ts +0 -16
  375. package/web/CLAUDE.md +0 -20
  376. package/web/index.html +0 -13
  377. package/web/package-lock.json +0 -4854
  378. package/web/package.json +0 -35
  379. package/web/postcss.config.js +0 -6
  380. package/web/src/App.tsx +0 -110
  381. package/web/src/components/CodeBlock.tsx +0 -31
  382. package/web/src/components/Confirm.tsx +0 -96
  383. package/web/src/components/Drawer.tsx +0 -60
  384. package/web/src/components/Layout.tsx +0 -145
  385. package/web/src/components/MarkdownRenderer.tsx +0 -77
  386. package/web/src/components/SearchInput.tsx +0 -31
  387. package/web/src/components/SessionDetailContent.tsx +0 -157
  388. package/web/src/components/Toast.tsx +0 -92
  389. package/web/src/index.css +0 -19
  390. package/web/src/main.tsx +0 -31
  391. package/web/src/pages/AIConfig.tsx +0 -233
  392. package/web/src/pages/Dashboard.tsx +0 -572
  393. package/web/src/pages/Events.tsx +0 -271
  394. package/web/src/pages/Reports.tsx +0 -428
  395. package/web/src/pages/SessionDetail.tsx +0 -162
  396. package/web/src/pages/Sessions.tsx +0 -205
  397. package/web/src/pages/Skills.tsx +0 -180
  398. package/web/src/pages/TaskDetail.tsx +0 -515
  399. package/web/src/pages/Tasks.tsx +0 -415
  400. package/web/src/utils/auth.ts +0 -59
  401. package/web/src/utils/export.ts +0 -54
  402. package/web/src/utils/navigation.ts +0 -25
  403. package/web/src/utils/task-title.ts +0 -49
  404. package/web/src/utils/time.ts +0 -13
  405. package/web/tailwind.config.js +0 -11
  406. package/web/tsconfig.json +0 -21
  407. package/web/tsconfig.node.json +0 -10
  408. package/web/vite.config.ts +0 -76
  409. package/winspan-claude-forge-8.43.0.tgz +0 -0
@@ -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
- }
@@ -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
- }