@winspan/claude-forge 8.53.2 → 8.54.4

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 (394) 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 +7 -3
  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/storage/events.d.ts.map +1 -1
  11. package/dist/core/storage/events.js +0 -1
  12. package/dist/core/storage/events.js.map +1 -1
  13. package/dist/core/storage/maintenance.d.ts +25 -3
  14. package/dist/core/storage/maintenance.d.ts.map +1 -1
  15. package/dist/core/storage/maintenance.js +33 -4
  16. package/dist/core/storage/maintenance.js.map +1 -1
  17. package/dist/core/storage/routing.d.ts +4 -0
  18. package/dist/core/storage/routing.d.ts.map +1 -1
  19. package/dist/core/storage/routing.js +10 -4
  20. package/dist/core/storage/routing.js.map +1 -1
  21. package/dist/core/storage/sessions.d.ts +17 -0
  22. package/dist/core/storage/sessions.d.ts.map +1 -1
  23. package/dist/core/storage/sessions.js +64 -0
  24. package/dist/core/storage/sessions.js.map +1 -1
  25. package/dist/core/storage/skills.d.ts +4 -0
  26. package/dist/core/storage/skills.d.ts.map +1 -1
  27. package/dist/core/storage/skills.js +10 -2
  28. package/dist/core/storage/skills.js.map +1 -1
  29. package/dist/core/storage/sqlite.d.ts +5 -0
  30. package/dist/core/storage/sqlite.d.ts.map +1 -1
  31. package/dist/core/storage/sqlite.js +6 -0
  32. package/dist/core/storage/sqlite.js.map +1 -1
  33. package/dist/core/storage/tasks.d.ts.map +1 -1
  34. package/dist/core/storage/tasks.js +2 -0
  35. package/dist/core/storage/tasks.js.map +1 -1
  36. package/dist/core/types.d.ts +7 -0
  37. package/dist/core/types.d.ts.map +1 -1
  38. package/dist/daemon/index.d.ts.map +1 -1
  39. package/dist/daemon/index.js +19 -4
  40. package/dist/daemon/index.js.map +1 -1
  41. package/dist/skills/official/official-openspec.md +89 -0
  42. package/dist/skills/official-skills.d.ts.map +1 -1
  43. package/dist/skills/official-skills.js +1 -0
  44. package/dist/skills/official-skills.js.map +1 -1
  45. package/dist/skills/registry.d.ts.map +1 -1
  46. package/dist/skills/registry.js +13 -2
  47. package/dist/skills/registry.js.map +1 -1
  48. package/dist/skills/semantic-matcher.d.ts +2 -2
  49. package/dist/skills/semantic-matcher.d.ts.map +1 -1
  50. package/dist/skills/semantic-matcher.js +14 -19
  51. package/dist/skills/semantic-matcher.js.map +1 -1
  52. package/dist/skills/upgrade-engine.d.ts +3 -1
  53. package/dist/skills/upgrade-engine.d.ts.map +1 -1
  54. package/dist/skills/upgrade-engine.js +25 -14
  55. package/dist/skills/upgrade-engine.js.map +1 -1
  56. package/dist/web/analytics/weekly-report.d.ts.map +1 -1
  57. package/dist/web/analytics/weekly-report.js +21 -29
  58. package/dist/web/analytics/weekly-report.js.map +1 -1
  59. package/dist/web/routes/patch.d.ts.map +1 -1
  60. package/dist/web/routes/patch.js +32 -2
  61. package/dist/web/routes/patch.js.map +1 -1
  62. package/dist/web/routes/sessions.d.ts.map +1 -1
  63. package/dist/web/routes/sessions.js +9 -7
  64. package/dist/web/routes/sessions.js.map +1 -1
  65. package/dist/web/routes/trace.d.ts.map +1 -1
  66. package/dist/web/routes/trace.js +2 -3
  67. package/dist/web/routes/trace.js.map +1 -1
  68. package/dist/web/server.d.ts.map +1 -1
  69. package/dist/web/server.js +3 -2
  70. package/dist/web/server.js.map +1 -1
  71. package/package.json +12 -2
  72. package/scripts/postinstall.cjs +21 -0
  73. package/.claude/CLAUDE.md +0 -17
  74. package/.eslintrc.js +0 -23
  75. package/.prettierrc +0 -8
  76. package/ARCHITECTURE_ISSUES.md +0 -249
  77. package/CLAUDE.md +0 -265
  78. package/CLAUDE.md.backup +0 -488
  79. package/docs/concurrent-agents.md +0 -129
  80. package/docs/design/architecture-review-20260516.md +0 -232
  81. package/docs/design/fix-skills-data-and-set-leak-spec-20260516-1300.md +0 -219
  82. package/docs/design/h1-storage-aggregation-spec-20260518-1121.md +0 -299
  83. package/docs/design/h2-getdatabase-encapsulation-spec-20260518-1450.md +0 -191
  84. package/docs/design/h3-fallback-removal-spec-20260518-1245.md +0 -76
  85. package/docs/design/h4-index-dedup-spec-20260518-1230.md +0 -109
  86. package/docs/design/h6-services-migration-spec-20260518-1355.md +0 -82
  87. package/docs/design/hook-failure-queue-spec-20260516-1530.md +0 -204
  88. package/docs/design/l1-swarm-protocol-extract-spec-20260518-1605.md +0 -106
  89. package/docs/design/m10-forge-paths-spec-20260518-1320.md +0 -121
  90. package/docs/design/m2-m3-tool-input-spec-20260518-1425.md +0 -131
  91. package/docs/design/m7-routing-event-association-spec-20260518-1545.md +0 -103
  92. package/docs/design/project-path-gitroot-spec-20260518-1715.md +0 -134
  93. package/docs/design/refactor-phase1-spec-20260515-1600.md +0 -543
  94. package/docs/design/refactor-phase2-spec-20260515-1700.md +0 -424
  95. package/docs/design/skill-ai-upgrade-spec-20260518-1930.md +0 -297
  96. package/docs/design/task-active-gc-spec-20260518-1745.md +0 -146
  97. package/docs/design/tasks-list-filter-pagination-spec-20260518-0930.md +0 -208
  98. package/docs/implementation/daemon-skill-sync-changelog-20260518-2000.md +0 -22
  99. package/docs/implementation/fix-skills-data-and-set-leak-changelog-20260516-1300.md +0 -104
  100. package/docs/implementation/h1-storage-aggregation-changelog-20260518-1121.md +0 -82
  101. package/docs/implementation/h2-final-changelog-20260518-1530.md +0 -61
  102. package/docs/implementation/h2-phase1-safety-net-changelog-20260518-1450.md +0 -70
  103. package/docs/implementation/h2-phase2-operations-changelog-20260518-1450.md +0 -120
  104. package/docs/implementation/h2-phase3-callsites-changelog-20260518-1450.md +0 -71
  105. package/docs/implementation/h3-fallback-removal-changelog-20260518-1245.md +0 -71
  106. package/docs/implementation/h4-index-dedup-changelog-20260518-1230.md +0 -60
  107. package/docs/implementation/h6-services-migration-changelog-20260518-1355.md +0 -46
  108. package/docs/implementation/h7-m9-defaults-changelog-20260518-1300.md +0 -46
  109. package/docs/implementation/hook-failure-queue-changelog-20260516-1530.md +0 -196
  110. package/docs/implementation/hotfix-daemon-event-reject-20260516-1430.md +0 -56
  111. package/docs/implementation/l1-swarm-protocol-extract-changelog-20260518-1605.md +0 -45
  112. package/docs/implementation/l3-l4-daemon-perf-changelog-20260518-1410.md +0 -63
  113. package/docs/implementation/l6-l8-final-cleanup-changelog-20260518-1640.md +0 -38
  114. package/docs/implementation/m1-m4-m5-l7-cleanup-changelog-20260518-1310.md +0 -58
  115. package/docs/implementation/m10-forge-paths-changelog-20260518-1320.md +0 -60
  116. package/docs/implementation/m2-m3-tool-input-changelog-20260518-1425.md +0 -43
  117. package/docs/implementation/m6-m8-naming-shutdown-changelog-20260518-1340.md +0 -56
  118. package/docs/implementation/m7-routing-association-changelog-20260518-1545.md +0 -69
  119. package/docs/implementation/project-path-gitroot-changelog-20260518-1715.md +0 -63
  120. package/docs/implementation/refactor-phase1-changelog-20260515-1630.md +0 -354
  121. package/docs/implementation/refactor-phase2-changelog-20260515-1705.md +0 -421
  122. package/docs/implementation/skill-ai-upgrade-changelog-20260518-1930.md +0 -49
  123. package/docs/implementation/task-active-gc-changelog-20260518-1745.md +0 -35
  124. package/docs/implementation/task-title-summary-changelog-20260518-1130.md +0 -39
  125. package/docs/implementation/tasks-detail-back-loses-filters-changelog-20260518-1100.md +0 -22
  126. package/docs/implementation/tasks-list-filter-pagination-changelog-20260518-0930.md +0 -72
  127. package/docs/implementation/tasks-page-white-screen-hotfix-changelog-20260518-1015.md +0 -56
  128. package/docs/reviews/claudemd-template-sync.md +0 -54
  129. package/docs/reviews/task-title-summary.md +0 -92
  130. package/docs/reviews/tasks-detail-back-loses-filters.md +0 -58
  131. package/docs/reviews/tasks-filter-pagination.md +0 -80
  132. package/docs/reviews/tasks-page-white-screen-hotfix.md +0 -126
  133. package/docs/ruflo-learning-strategy.md +0 -322
  134. package/docs/skills-deduplication-analysis.md +0 -83
  135. package/docs/skills-multiformat-support.md +0 -177
  136. package/docs/skills-third-party.md +0 -183
  137. package/docs/testing/tasks-filter-pagination-test-report.md +0 -86
  138. package/forge +0 -321
  139. package/playwright.config.ts +0 -40
  140. package/scripts/demo-v2.ts +0 -91
  141. package/scripts/dev-daemon.sh +0 -232
  142. package/scripts/dev-web.ts +0 -109
  143. package/scripts/e2e-mcp-link.ts +0 -423
  144. package/scripts/e2e-methodology-quality.ts +0 -253
  145. package/scripts/e2e-routing.ts +0 -456
  146. package/scripts/e2e-user-methodology.ts +0 -326
  147. package/scripts/e2e-web-workflows.ts +0 -299
  148. package/scripts/migrate-legacy-to-dynamic.sql +0 -108
  149. package/scripts/regenerate-execution-docs.ts +0 -116
  150. package/scripts/sync-agent-skills.ts +0 -193
  151. package/scripts/test-hook.sh +0 -71
  152. package/scripts/verify-skill-loading.ts +0 -62
  153. package/src/claudemd/claudemd-generator.ts +0 -568
  154. package/src/claudemd/convention-extractor.ts +0 -69
  155. package/src/claudemd/index.ts +0 -35
  156. package/src/claudemd/persona-manager.ts +0 -88
  157. package/src/claudemd/resume-manager.ts +0 -236
  158. package/src/claudemd/tech-detector.ts +0 -220
  159. package/src/claudemd/templates/swarm-protocol.md +0 -222
  160. package/src/cli/commands/claudemd.ts +0 -84
  161. package/src/cli/commands/config.ts +0 -46
  162. package/src/cli/commands/daemon.ts +0 -310
  163. package/src/cli/commands/executions.ts +0 -115
  164. package/src/cli/commands/init.ts +0 -204
  165. package/src/cli/commands/logs.ts +0 -181
  166. package/src/cli/commands/mcp.ts +0 -242
  167. package/src/cli/commands/menu.ts +0 -357
  168. package/src/cli/commands/skills.ts +0 -328
  169. package/src/cli/commands/stats.ts +0 -73
  170. package/src/cli/commands/status.ts +0 -69
  171. package/src/cli/commands/template.ts +0 -77
  172. package/src/cli/commands/trace.ts +0 -148
  173. package/src/cli/index.ts +0 -42
  174. package/src/cli/init/hook-manager.ts +0 -132
  175. package/src/core/ai/provider.ts +0 -308
  176. package/src/core/ai/types.ts +0 -51
  177. package/src/core/config.ts +0 -124
  178. package/src/core/constants.ts +0 -67
  179. package/src/core/event-fields.ts +0 -32
  180. package/src/core/queue/index.ts +0 -192
  181. package/src/core/storage/base.ts +0 -302
  182. package/src/core/storage/events.ts +0 -434
  183. package/src/core/storage/injections.ts +0 -78
  184. package/src/core/storage/maintenance.ts +0 -59
  185. package/src/core/storage/migrations/002_add_skill_tracking.sql +0 -6
  186. package/src/core/storage/migrations/003_add_skill_invocations.sql +0 -23
  187. package/src/core/storage/performance-indexes.sql +0 -23
  188. package/src/core/storage/routing.ts +0 -322
  189. package/src/core/storage/rows.ts +0 -112
  190. package/src/core/storage/schema.sql +0 -224
  191. package/src/core/storage/sessions.ts +0 -168
  192. package/src/core/storage/skills.ts +0 -233
  193. package/src/core/storage/sqlite.ts +0 -293
  194. package/src/core/storage/tasks.ts +0 -318
  195. package/src/core/storage/token-usage.ts +0 -93
  196. package/src/core/types.ts +0 -181
  197. package/src/core/utils/error-handler.ts +0 -257
  198. package/src/core/utils/forge-resume-block.ts +0 -74
  199. package/src/core/utils/format.ts +0 -69
  200. package/src/core/utils/git.ts +0 -23
  201. package/src/core/utils/logger.ts +0 -134
  202. package/src/core/utils/lru-cache.ts +0 -54
  203. package/src/core/utils/path.ts +0 -19
  204. package/src/core/utils/session.ts +0 -26
  205. package/src/core/utils/time.ts +0 -37
  206. package/src/core/utils/token-tracker.ts +0 -97
  207. package/src/daemon/event-parser.ts +0 -36
  208. package/src/daemon/handlers/history-exporter.ts +0 -117
  209. package/src/daemon/handlers/post-tool-use.ts +0 -54
  210. package/src/daemon/handlers/stop.ts +0 -208
  211. package/src/daemon/handlers/user-prompt.ts +0 -178
  212. package/src/daemon/hook-sync.ts +0 -91
  213. package/src/daemon/index.ts +0 -312
  214. package/src/daemon/launchd/com.claude-forge.daemon.plist.template +0 -47
  215. package/src/daemon/launchd-installer.ts +0 -260
  216. package/src/daemon/lifecycle.ts +0 -128
  217. package/src/daemon/router.ts +0 -40
  218. package/src/daemon/server.ts +0 -196
  219. package/src/daemon/services/task-segmenter.ts +0 -112
  220. package/src/daemon/skill-sync.ts +0 -88
  221. package/src/hooks/hook-lib.sh +0 -118
  222. package/src/hooks/notification.sh +0 -35
  223. package/src/hooks/post-tool-use.sh +0 -61
  224. package/src/hooks/pre-tool-use.sh +0 -63
  225. package/src/hooks/stop.sh +0 -43
  226. package/src/hooks/user-prompt-submit.sh +0 -69
  227. package/src/mcp/server.ts +0 -322
  228. package/src/skills/index.ts +0 -2
  229. package/src/skills/invocation-guard.ts +0 -177
  230. package/src/skills/matcher.ts +0 -148
  231. package/src/skills/official/code-simplifier.md +0 -52
  232. package/src/skills/official/find-skills.md +0 -142
  233. package/src/skills/official/official-api-design.md +0 -30
  234. package/src/skills/official/official-architecture-decision.md +0 -41
  235. package/src/skills/official/official-bmad.md +0 -118
  236. package/src/skills/official/official-db-schema-design.md +0 -34
  237. package/src/skills/official/official-debug.md +0 -25
  238. package/src/skills/official/official-doc-driven.md +0 -31
  239. package/src/skills/official/official-harness-engineering.md +0 -108
  240. package/src/skills/official/official-performance-optimization.md +0 -30
  241. package/src/skills/official/official-pr-review.md +0 -35
  242. package/src/skills/official/official-release-checklist.md +0 -30
  243. package/src/skills/official/official-security-hardening.md +0 -32
  244. package/src/skills/official/official-spec-driven-design.md +0 -31
  245. package/src/skills/official/planning-with-files.md +0 -241
  246. package/src/skills/official/ui-ux-pro-max.md +0 -105
  247. package/src/skills/official/webapp-testing.md +0 -96
  248. package/src/skills/official-skills.ts +0 -89
  249. package/src/skills/registry.ts +0 -355
  250. package/src/skills/semantic-matcher.ts +0 -234
  251. package/src/skills/tools/pipeline-suggest.ts +0 -226
  252. package/src/skills/tools/skill-invoke.ts +0 -168
  253. package/src/skills/tools/skill-list.ts +0 -59
  254. package/src/skills/upgrade-engine.ts +0 -541
  255. package/src/skills/upgrade-prompt.ts +0 -84
  256. package/src/templates/go.yaml +0 -53
  257. package/src/templates/python.yaml +0 -59
  258. package/src/templates/react.yaml +0 -55
  259. package/src/templates/template-manager.ts +0 -170
  260. package/src/web/analytics/anti-pattern-detector.ts +0 -367
  261. package/src/web/analytics/drift-detector.ts +0 -219
  262. package/src/web/analytics/weekly-report.ts +0 -431
  263. package/src/web/auth-middleware.ts +0 -54
  264. package/src/web/routes/_helpers.ts +0 -34
  265. package/src/web/routes/ai.ts +0 -204
  266. package/src/web/routes/auth.ts +0 -22
  267. package/src/web/routes/drift.ts +0 -25
  268. package/src/web/routes/error-handler.ts +0 -120
  269. package/src/web/routes/events.ts +0 -47
  270. package/src/web/routes/insights.ts +0 -43
  271. package/src/web/routes/patch.ts +0 -117
  272. package/src/web/routes/reports.ts +0 -34
  273. package/src/web/routes/rules.ts +0 -76
  274. package/src/web/routes/sessions.ts +0 -250
  275. package/src/web/routes/skill-stats.ts +0 -92
  276. package/src/web/routes/skills.ts +0 -350
  277. package/src/web/routes/static.ts +0 -67
  278. package/src/web/routes/stats.ts +0 -50
  279. package/src/web/routes/status.ts +0 -30
  280. package/src/web/routes/tasks.ts +0 -193
  281. package/src/web/routes/token-usage.ts +0 -20
  282. package/src/web/routes/trace.ts +0 -126
  283. package/src/web/routes/types.ts +0 -57
  284. package/src/web/server.ts +0 -134
  285. package/src/web/ssrf-guard.ts +0 -112
  286. package/src/web/static/index.html +0 -3251
  287. package/src/web/static/vendor/chart.umd.min.js +0 -20
  288. package/tests/e2e/dashboard.spec.ts +0 -205
  289. package/tests/e2e/routing-skill-e2e.test.ts +0 -39
  290. package/tests/helpers/mock-ai.ts +0 -92
  291. package/tests/helpers/mock-storage.ts +0 -159
  292. package/tests/integration/claudemd-generator.test.ts +0 -90
  293. package/tests/integration/queue-replay.integration.test.ts +0 -193
  294. package/tests/integration/tasks-filter.integration.test.ts +0 -154
  295. package/tests/integration/web-analytics.integration.test.ts +0 -133
  296. package/tests/integration/web-stats.integration.test.ts +0 -135
  297. package/tests/integration/web-trace.integration.test.ts +0 -175
  298. package/tests/performance/database.benchmark.ts +0 -161
  299. package/tests/semantic-matcher.test.ts +0 -99
  300. package/tests/skill-matcher.test.ts +0 -110
  301. package/tests/unit/ai-provider-retry.test.ts +0 -194
  302. package/tests/unit/ai-provider-vision.test.ts +0 -224
  303. package/tests/unit/claudemd-generator.test.ts +0 -68
  304. package/tests/unit/cli-mcp.test.ts +0 -141
  305. package/tests/unit/core/forge-paths.test.ts +0 -99
  306. package/tests/unit/daemon/hook-sync.test.ts +0 -71
  307. package/tests/unit/daemon/post-tool-use.test.ts +0 -121
  308. package/tests/unit/daemon/skill-sync.test.ts +0 -75
  309. package/tests/unit/daemon/stop-handler-behavior-summary.test.ts +0 -202
  310. package/tests/unit/daemon/task-segmenter-recover.test.ts +0 -84
  311. package/tests/unit/event-fields.test.ts +0 -88
  312. package/tests/unit/event-parser.test.ts +0 -55
  313. package/tests/unit/handlers.test.ts +0 -171
  314. package/tests/unit/hooks/resolve-project-path.test.ts +0 -122
  315. package/tests/unit/invocation-guard.test.ts +0 -125
  316. package/tests/unit/queue.test.ts +0 -272
  317. package/tests/unit/router.test.ts +0 -138
  318. package/tests/unit/security.test.ts +0 -128
  319. package/tests/unit/skill-invocations-workflow.test.ts +0 -495
  320. package/tests/unit/skill-registry.test.ts +0 -94
  321. package/tests/unit/skills/invocation-guard-ttl.test.ts +0 -211
  322. package/tests/unit/skills/official-skills-loader.test.ts +0 -126
  323. package/tests/unit/skills/registry-multiformat.test.ts +0 -92
  324. package/tests/unit/skills/upgrade-engine-parse.test.ts +0 -138
  325. package/tests/unit/skills/upgrade-engine.test.ts +0 -401
  326. package/tests/unit/skills/upgrade-prompt.test.ts +0 -89
  327. package/tests/unit/socket-server.test.ts +0 -183
  328. package/tests/unit/storage/event-operations-aggregates.test.ts +0 -342
  329. package/tests/unit/storage/migration-idempotent.test.ts +0 -304
  330. package/tests/unit/storage/routing-aggregates.test.ts +0 -276
  331. package/tests/unit/storage/routing.test.ts +0 -117
  332. package/tests/unit/storage/schema-missing.test.ts +0 -81
  333. package/tests/unit/storage/session-operations-aggregates.test.ts +0 -120
  334. package/tests/unit/storage/sessions-aggregate.test.ts +0 -435
  335. package/tests/unit/storage/skill-operations-counts.test.ts +0 -106
  336. package/tests/unit/storage/skills-aggregates.test.ts +0 -104
  337. package/tests/unit/storage/sqlite-refactor-harness.test.ts +0 -314
  338. package/tests/unit/storage/task-operations-counts.test.ts +0 -46
  339. package/tests/unit/storage/tasks-getById.test.ts +0 -343
  340. package/tests/unit/storage/tasks-stale-gc.test.ts +0 -86
  341. package/tests/unit/storage.test.ts +0 -172
  342. package/tests/unit/token-usage.test.ts +0 -144
  343. package/tests/unit/type-guards.test.ts +0 -201
  344. package/tests/unit/utils/format.test.ts +0 -189
  345. package/tests/unit/utils/session.test.ts +0 -89
  346. package/tests/unit/utils/time.test.ts +0 -112
  347. package/tests/unit/web/navigation-back-contract.test.ts +0 -134
  348. package/tests/unit/web/routes-auth.test.ts +0 -93
  349. package/tests/unit/web/routes-events.test.ts +0 -101
  350. package/tests/unit/web/routes-rules.test.ts +0 -182
  351. package/tests/unit/web/routes-sessions.test.ts +0 -181
  352. package/tests/unit/web/routes-skill-stats.test.ts +0 -179
  353. package/tests/unit/web/routes-stats.test.ts +0 -92
  354. package/tests/unit/web/routes-tasks.test.ts +0 -385
  355. package/tests/unit/web/task-title-contract.test.ts +0 -210
  356. package/tests/unit/web/tasks-component-contract.test.ts +0 -179
  357. package/tsconfig.json +0 -22
  358. package/vitest.config.ts +0 -21
  359. package/vitest.integration.config.ts +0 -16
  360. package/web/CLAUDE.md +0 -20
  361. package/web/index.html +0 -13
  362. package/web/package-lock.json +0 -4854
  363. package/web/package.json +0 -35
  364. package/web/postcss.config.js +0 -6
  365. package/web/src/App.tsx +0 -110
  366. package/web/src/components/CodeBlock.tsx +0 -31
  367. package/web/src/components/Confirm.tsx +0 -96
  368. package/web/src/components/Drawer.tsx +0 -60
  369. package/web/src/components/Layout.tsx +0 -145
  370. package/web/src/components/MarkdownRenderer.tsx +0 -77
  371. package/web/src/components/SearchInput.tsx +0 -31
  372. package/web/src/components/SessionDetailContent.tsx +0 -157
  373. package/web/src/components/Toast.tsx +0 -92
  374. package/web/src/index.css +0 -19
  375. package/web/src/main.tsx +0 -31
  376. package/web/src/pages/AIConfig.tsx +0 -233
  377. package/web/src/pages/Dashboard.tsx +0 -572
  378. package/web/src/pages/Events.tsx +0 -271
  379. package/web/src/pages/Reports.tsx +0 -428
  380. package/web/src/pages/SessionDetail.tsx +0 -162
  381. package/web/src/pages/Sessions.tsx +0 -205
  382. package/web/src/pages/Skills.tsx +0 -180
  383. package/web/src/pages/TaskDetail.tsx +0 -515
  384. package/web/src/pages/Tasks.tsx +0 -415
  385. package/web/src/utils/auth.ts +0 -59
  386. package/web/src/utils/export.ts +0 -54
  387. package/web/src/utils/navigation.ts +0 -25
  388. package/web/src/utils/task-title.ts +0 -49
  389. package/web/src/utils/time.ts +0 -13
  390. package/web/tailwind.config.js +0 -11
  391. package/web/tsconfig.json +0 -21
  392. package/web/tsconfig.node.json +0 -10
  393. package/web/vite.config.ts +0 -76
  394. package/winspan-claude-forge-8.43.0.tgz +0 -0
@@ -1,541 +0,0 @@
1
- /**
2
- * upgrade-engine.ts
3
- *
4
- * Orchestrates the AI-assisted official skill upgrade pipeline.
5
- * Does NOT contain AI prompt strings — those live in upgrade-prompt.ts.
6
- */
7
-
8
- import { execSync, exec } from 'node:child_process';
9
- import { promises as fs, readFileSync } from 'node:fs';
10
- import path from 'node:path';
11
- import { promisify } from 'node:util';
12
- import matter from 'gray-matter';
13
- import type { OfficialSkill } from './official-skills.js';
14
- import { buildEvaluationPrompt } from './upgrade-prompt.js';
15
- import type { ClaudeProvider } from '../core/ai/provider.js';
16
- import { logger } from '../core/utils/logger.js';
17
-
18
- const execAsync = promisify(exec);
19
-
20
- // ── Public types ────────────────────────────────────────────────────────────
21
-
22
- export interface CandidateSkill {
23
- id: string;
24
- source: string; // 'agent-skills' | 'superpowers'
25
- filePath: string;
26
- name: string;
27
- description: string;
28
- keywords: string[];
29
- content: string;
30
- }
31
-
32
- export interface MatchResult {
33
- officialId: string;
34
- score: number; // 0-100
35
- }
36
-
37
- export type UpgradeAction = 'upgrade' | 'merge' | 'skip';
38
-
39
- export interface UpgradeDecision {
40
- action: UpgradeAction;
41
- confidence: number; // 0-100
42
- reasoning: string;
43
- merged_content: string | null;
44
- }
45
-
46
- export interface ReportEntry {
47
- officialId: string;
48
- candidateId: string;
49
- candidateSource: string;
50
- action: UpgradeAction | 'error' | 'needs_review';
51
- confidence: number;
52
- reasoning: string;
53
- candidateFilePath: string;
54
- merged_content: string | null;
55
- }
56
-
57
- // ── Default candidate sources ───────────────────────────────────────────────
58
-
59
- export const DEFAULT_SOURCES: Array<{ name: string; url: string }> = [
60
- { name: 'agent-skills', url: 'https://github.com/addyosmani/agent-skills.git' },
61
- { name: 'superpowers', url: 'https://github.com/obra/superpowers.git' },
62
- ];
63
-
64
- // ── Helpers ─────────────────────────────────────────────────────────────────
65
-
66
- /**
67
- * Parse a .md file into a CandidateSkill.
68
- * If frontmatter is missing, falls back to filename-based id.
69
- */
70
- function parseCandidateFile(filePath: string, sourceName: string): CandidateSkill | null {
71
- try {
72
- const raw = readFileSync(filePath, 'utf-8');
73
- const parsed = matter(raw);
74
- const { data } = parsed;
75
-
76
- const fileName = path.basename(filePath, '.md');
77
- const id = typeof data.name === 'string' ? data.name : fileName;
78
- const name = typeof data.name === 'string' ? data.name : fileName;
79
- const description = typeof data.description === 'string' ? data.description : '';
80
-
81
- const rawKeywords: unknown = data.keywords ?? data.tags;
82
- const keywords: string[] = Array.isArray(rawKeywords)
83
- ? rawKeywords.filter((k): k is string => typeof k === 'string')
84
- : [];
85
-
86
- return {
87
- id,
88
- source: sourceName,
89
- filePath,
90
- name,
91
- description,
92
- keywords,
93
- content: raw,
94
- };
95
- } catch {
96
- return null;
97
- }
98
- }
99
-
100
- /**
101
- * Recursively scan a directory for .md files.
102
- * Supports both directory/SKILL.md format (agent-skills) and flat *.md format.
103
- */
104
- async function scanMdFiles(dir: string): Promise<string[]> {
105
- const results: string[] = [];
106
-
107
- async function walk(current: string): Promise<void> {
108
- let entries: import('node:fs').Dirent[];
109
- try {
110
- entries = await fs.readdir(current, { withFileTypes: true });
111
- } catch {
112
- return;
113
- }
114
-
115
- for (const entry of entries) {
116
- const fullPath = path.join(current, entry.name);
117
- if (entry.isDirectory()) {
118
- // Check for SKILL.md inside this directory (agent-skills format)
119
- const skillMd = path.join(fullPath, 'SKILL.md');
120
- try {
121
- await fs.access(skillMd);
122
- results.push(skillMd);
123
- } catch {
124
- // Recurse into sub-directories that don't have SKILL.md directly
125
- await walk(fullPath);
126
- }
127
- } else if (entry.isFile() && entry.name.endsWith('.md') && entry.name !== 'README.md') {
128
- results.push(fullPath);
129
- }
130
- }
131
- }
132
-
133
- await walk(dir);
134
- return results;
135
- }
136
-
137
- // ── Exported pipeline functions ─────────────────────────────────────────────
138
-
139
- /**
140
- * Clone or pull each source into `candidatesDir/<source.name>/`, then scan
141
- * all .md files and parse them into CandidateSkill objects.
142
- * Individual source failures are caught and logged; they do not abort the run.
143
- */
144
- export async function pullCandidates(
145
- sources: Array<{ name: string; url: string }>,
146
- candidatesDir: string,
147
- ): Promise<CandidateSkill[]> {
148
- await fs.mkdir(candidatesDir, { recursive: true });
149
-
150
- const candidates: CandidateSkill[] = [];
151
-
152
- for (const source of sources) {
153
- const targetDir = path.join(candidatesDir, source.name);
154
-
155
- let exists = false;
156
- try {
157
- await fs.access(targetDir);
158
- exists = true;
159
- } catch { /* not exists */ }
160
-
161
- // Try pull/clone, but don't abort scan if pull fails on existing dir
162
- try {
163
- if (exists) {
164
- logger.info(`[upgrade] Pulling ${source.name}...`);
165
- await execAsync(`git -C "${targetDir}" pull --ff-only`, { timeout: 60_000 });
166
- } else {
167
- logger.info(`[upgrade] Cloning ${source.name}...`);
168
- await execAsync(`git clone --depth=1 "${source.url}" "${targetDir}"`, { timeout: 120_000 });
169
- }
170
- } catch (err) {
171
- const msg = err instanceof Error ? err.message : String(err);
172
- if (exists) {
173
- logger.warn(`[upgrade] ${source.name} pull failed (using existing checkout): ${msg}`);
174
- } else {
175
- logger.warn(`[upgrade] ${source.name} clone failed, skipping: ${msg}`);
176
- continue;
177
- }
178
- }
179
-
180
- // Always scan if dir exists (even when pull fails — old checkout is better than nothing)
181
- try {
182
- const mdFiles = await scanMdFiles(targetDir);
183
- for (const filePath of mdFiles) {
184
- const candidate = parseCandidateFile(filePath, source.name);
185
- if (candidate) {
186
- candidates.push(candidate);
187
- }
188
- }
189
- logger.info(`[upgrade] ${source.name}: ${mdFiles.length} .md files found`);
190
- } catch (err) {
191
- const msg = err instanceof Error ? err.message : String(err);
192
- logger.warn(`[upgrade] Skipping source ${source.name}: ${msg}`);
193
- }
194
- }
195
-
196
- return candidates;
197
- }
198
-
199
- /**
200
- * Match a candidate skill to the best official skill using keyword + name token
201
- * overlap. Returns null if the best score is below the 30-point threshold.
202
- */
203
- export function matchToOfficial(
204
- candidate: CandidateSkill,
205
- officialSkills: OfficialSkill[],
206
- ): MatchResult | null {
207
- /** Tokenise a string into lowercase words / tokens. */
208
- function tokenise(text: string): Set<string> {
209
- return new Set(
210
- text
211
- .toLowerCase()
212
- .replace(/[^a-z0-9一-鿿\s-]/g, ' ')
213
- .split(/[\s-]+/)
214
- .filter((t) => t.length > 1),
215
- );
216
- }
217
-
218
- /** Jaccard-like overlap score (0–100). */
219
- function overlapScore(aSet: Set<string>, bSet: Set<string>): number {
220
- if (aSet.size === 0 && bSet.size === 0) return 0;
221
- let intersection = 0;
222
- for (const t of aSet) {
223
- if (bSet.has(t)) intersection++;
224
- }
225
- const union = new Set([...aSet, ...bSet]).size;
226
- return union === 0 ? 0 : Math.round((intersection / union) * 100);
227
- }
228
-
229
- const candidateKeywordTokens = tokenise(candidate.keywords.join(' '));
230
- const candidateNameTokens = tokenise(candidate.name + ' ' + candidate.description);
231
-
232
- let best: MatchResult | null = null;
233
-
234
- for (const official of officialSkills) {
235
- const officialKeywordTokens = tokenise(official.keywords.join(' '));
236
- const officialNameTokens = tokenise(official.name + ' ' + official.description);
237
-
238
- // keyword overlap (weight 60) + name/description token overlap (weight 40)
239
- const keywordScore = overlapScore(candidateKeywordTokens, officialKeywordTokens);
240
- const nameScore = overlapScore(candidateNameTokens, officialNameTokens);
241
- let combined = Math.round(keywordScore * 0.6 + nameScore * 0.4);
242
-
243
- // Substring boost: candidate id/name contains official keyword (or vice versa)
244
- // helps with English↔中文 token mismatch (e.g. "debugging" ↔ "debug"/"调试")
245
- const candidateText = (candidate.id + ' ' + candidate.name + ' ' + candidate.description).toLowerCase();
246
- const officialText = (official.name + ' ' + official.description).toLowerCase();
247
- for (const kw of official.keywords) {
248
- const kwLower = kw.toLowerCase();
249
- if (kwLower.length >= 3 && candidateText.includes(kwLower)) {
250
- combined = Math.max(combined, 50);
251
- break;
252
- }
253
- }
254
- for (const kw of candidate.keywords) {
255
- const kwLower = kw.toLowerCase();
256
- if (kwLower.length >= 3 && officialText.includes(kwLower)) {
257
- combined = Math.max(combined, 50);
258
- break;
259
- }
260
- }
261
-
262
- if (combined >= 15) {
263
- if (!best || combined > best.score) {
264
- best = { officialId: official.name, score: combined };
265
- }
266
- }
267
- }
268
-
269
- return best;
270
- }
271
-
272
- /**
273
- * Ask the AI provider to evaluate whether a candidate should upgrade / merge /
274
- * skip the matched official skill. Returns a parsed UpgradeDecision.
275
- *
276
- * On JSON parse failure → returns { action: 'skip', confidence: 0, reasoning:
277
- * 'AI response could not be parsed', merged_content: null } with needs_review=true
278
- * embedded in the reasoning (caller promotes to needs_review).
279
- */
280
- export async function evaluateWithAI(
281
- candidate: CandidateSkill,
282
- official: OfficialSkill,
283
- aiProvider: ClaudeProvider,
284
- ): Promise<UpgradeDecision & { needs_review?: boolean }> {
285
- const { system, user } = buildEvaluationPrompt(candidate, official);
286
-
287
- let raw: string;
288
- try {
289
- raw = await aiProvider.complete(user, {
290
- system,
291
- maxTokens: 1200,
292
- timeoutMs: 45_000,
293
- maxRetries: 2,
294
- });
295
- } catch (err) {
296
- const msg = err instanceof Error ? err.message : String(err);
297
- return {
298
- action: 'skip',
299
- confidence: 0,
300
- reasoning: `AI 调用失败: ${msg}`,
301
- merged_content: null,
302
- needs_review: true,
303
- };
304
- }
305
-
306
- // Strip markdown code fences if model wrapped the JSON
307
- const stripped = raw
308
- .replace(/^```(?:json)?\s*/im, '')
309
- .replace(/\s*```$/im, '')
310
- .trim();
311
-
312
- try {
313
- const parsed = JSON.parse(stripped) as Record<string, unknown>;
314
-
315
- const validActions = new Set<string>(['upgrade', 'merge', 'skip']);
316
- const action = typeof parsed.action === 'string' && validActions.has(parsed.action)
317
- ? (parsed.action as UpgradeAction)
318
- : 'skip';
319
-
320
- const confidence =
321
- typeof parsed.confidence === 'number'
322
- ? Math.max(0, Math.min(100, parsed.confidence))
323
- : 0;
324
-
325
- const reasoning =
326
- typeof parsed.reasoning === 'string' ? parsed.reasoning : '';
327
-
328
- const merged_content =
329
- typeof parsed.merged_content === 'string' ? parsed.merged_content : null;
330
-
331
- return { action, confidence, reasoning, merged_content };
332
- } catch {
333
- return {
334
- action: 'skip',
335
- confidence: 0,
336
- reasoning: `AI 返回内容无法解析为 JSON,需人工审核。原始响应片段: ${stripped.slice(0, 200)}`,
337
- merged_content: null,
338
- needs_review: true,
339
- };
340
- }
341
- }
342
-
343
- /**
344
- * Write the upgrade report as a markdown file with embedded HTML comment
345
- * machine markers for `applyDecisions` to parse.
346
- */
347
- export async function generateReport(
348
- entries: ReportEntry[],
349
- outputPath: string,
350
- stats: { total: number; matched: number; unmatched: number },
351
- ): Promise<void> {
352
- const now = new Date();
353
- const timestamp = now.toISOString().replace('T', ' ').slice(0, 16);
354
-
355
- const actionCounts = { upgrade: 0, merge: 0, skip: 0, error: 0, needs_review: 0 };
356
- for (const e of entries) {
357
- if (e.action in actionCounts) {
358
- actionCounts[e.action as keyof typeof actionCounts]++;
359
- }
360
- }
361
-
362
- const lines: string[] = [
363
- '# Skill Upgrade Report',
364
- '',
365
- `Generated: ${timestamp}`,
366
- '',
367
- '## Summary',
368
- '',
369
- '| Metric | Count |',
370
- '|--------|-------|',
371
- `| Candidates scanned | ${stats.total} |`,
372
- `| Matched to official | ${stats.matched} |`,
373
- `| Action: upgrade | ${actionCounts.upgrade} |`,
374
- `| Action: merge | ${actionCounts.merge} |`,
375
- `| Action: skip | ${actionCounts.skip} |`,
376
- `| Needs review | ${actionCounts.needs_review} |`,
377
- `| Error | ${actionCounts.error} |`,
378
- `| Unmatched | ${stats.unmatched} |`,
379
- '',
380
- '## Per-Skill Decisions',
381
- '',
382
- ];
383
-
384
- for (const entry of entries) {
385
- lines.push(`### ${entry.officialId}`);
386
- lines.push(`- **Action**: ${entry.action}`);
387
- lines.push(`- **Confidence**: ${entry.confidence}%`);
388
- lines.push(`- **Candidate**: \`${entry.candidateSource}/${entry.candidateId}\``);
389
- lines.push(`- **Candidate path**: \`${entry.candidateFilePath}\``);
390
- lines.push(`- **Reasoning**: ${entry.reasoning}`);
391
-
392
- // Machine-readable marker for applyDecisions
393
- lines.push('');
394
- lines.push(`<!-- upgrade-entry: ${entry.officialId} | ${entry.candidateFilePath} | ${entry.action} -->`);
395
-
396
- if (entry.action === 'merge' && entry.merged_content) {
397
- lines.push('');
398
- lines.push('<!-- merged-content-begin -->');
399
- lines.push(entry.merged_content);
400
- lines.push('<!-- merged-content-end -->');
401
- }
402
-
403
- lines.push('');
404
- }
405
-
406
- await fs.mkdir(path.dirname(outputPath), { recursive: true });
407
- await fs.writeFile(outputPath, lines.join('\n'), 'utf-8');
408
- logger.info(`[upgrade] Report written to ${outputPath}`);
409
- }
410
-
411
- /**
412
- * Apply the decisions recorded in a report file to the official skills directory.
413
- *
414
- * Safety checks:
415
- * 1. `git status --porcelain <officialDir>` must be clean
416
- * 2. Full backup created in `backupBaseDir/<YYYYMMDD-HHMM>/` (conflict → -2/-3)
417
- *
418
- * Returns { applied, skipped, backupPath }.
419
- */
420
- export async function applyDecisions(
421
- reportPath: string,
422
- officialDir: string,
423
- backupBaseDir: string,
424
- ): Promise<{ applied: number; skipped: number; backupPath: string }> {
425
- // 1. Check git working tree is clean
426
- try {
427
- const { stdout } = await execAsync(`git status --porcelain "${officialDir}"`);
428
- if (stdout.trim().length > 0) {
429
- throw new Error(
430
- `Working tree is dirty in ${officialDir}. Commit or stash changes before applying.\n${stdout}`,
431
- );
432
- }
433
- } catch (err) {
434
- // If git is not available or it's not a repo, rethrow only for dirty-tree errors
435
- const msg = err instanceof Error ? err.message : String(err);
436
- if (msg.includes('Working tree is dirty')) throw err;
437
- logger.warn(`[upgrade] git status check failed (not a git repo?): ${msg}`);
438
- }
439
-
440
- // 2. Create timestamped backup directory
441
- const ts = new Date()
442
- .toISOString()
443
- .replace(/[-:]/g, '')
444
- .replace('T', '-')
445
- .slice(0, 13); // YYYYMMDD-HHM -> need YYYYMMDD-HHMM format
446
- const tsFormatted = (() => {
447
- const d = new Date();
448
- const YYYY = d.getFullYear();
449
- const MM = String(d.getMonth() + 1).padStart(2, '0');
450
- const DD = String(d.getDate()).padStart(2, '0');
451
- const HH = String(d.getHours()).padStart(2, '0');
452
- const mm = String(d.getMinutes()).padStart(2, '0');
453
- return `${YYYY}${MM}${DD}-${HH}${mm}`;
454
- })();
455
-
456
- let backupPath = path.join(backupBaseDir, tsFormatted);
457
- // Handle conflict: try -2, -3, ...
458
- let suffix = 2;
459
- while (true) {
460
- try {
461
- await fs.access(backupPath);
462
- // Directory exists — try next suffix
463
- backupPath = path.join(backupBaseDir, `${tsFormatted}-${suffix}`);
464
- suffix++;
465
- } catch {
466
- break; // doesn't exist, we can use it
467
- }
468
- }
469
- await fs.mkdir(backupPath, { recursive: true });
470
-
471
- // Copy all .md files from officialDir into backup
472
- const officialFiles = (await fs.readdir(officialDir)).filter((f) => f.endsWith('.md'));
473
- for (const file of officialFiles) {
474
- await fs.copyFile(path.join(officialDir, file), path.join(backupPath, file));
475
- }
476
- logger.info(`[upgrade] Backed up ${officialFiles.length} files to ${backupPath}`);
477
-
478
- // 3. Parse report
479
- const reportContent = await fs.readFile(reportPath, 'utf-8');
480
-
481
- // Parse <!-- upgrade-entry: id | path | action --> markers
482
- const entryPattern = /<!-- upgrade-entry: (.+?) \| (.+?) \| (.+?) -->/g;
483
- let match: RegExpExecArray | null;
484
-
485
- const entries: Array<{ officialId: string; candidatePath: string; action: string }> = [];
486
- while ((match = entryPattern.exec(reportContent)) !== null) {
487
- entries.push({
488
- officialId: match[1].trim(),
489
- candidatePath: match[2].trim(),
490
- action: match[3].trim(),
491
- });
492
- }
493
-
494
- // Parse merged content blocks
495
- const mergedContentMap = new Map<string, string>();
496
- // Associate merged-content blocks with the preceding entry
497
- const mergedPattern =
498
- /<!-- upgrade-entry: (.+?) \| (.+?) \| merge -->[\s\S]*?<!-- merged-content-begin -->\n([\s\S]*?)\n<!-- merged-content-end -->/g;
499
- while ((match = mergedPattern.exec(reportContent)) !== null) {
500
- mergedContentMap.set(match[1].trim(), match[3]);
501
- }
502
-
503
- let applied = 0;
504
- let skipped = 0;
505
-
506
- for (const entry of entries) {
507
- if (entry.action === 'skip' || entry.action === 'error' || entry.action === 'needs_review') {
508
- skipped++;
509
- continue;
510
- }
511
-
512
- const targetFile = path.join(officialDir, `${entry.officialId}.md`);
513
-
514
- try {
515
- if (entry.action === 'upgrade') {
516
- // Copy candidate file content
517
- const candidateContent = await fs.readFile(entry.candidatePath, 'utf-8');
518
- await fs.writeFile(targetFile, candidateContent, 'utf-8');
519
- applied++;
520
- logger.info(`[upgrade] Applied upgrade: ${entry.officialId}`);
521
- } else if (entry.action === 'merge') {
522
- const mergedContent = mergedContentMap.get(entry.officialId);
523
- if (mergedContent) {
524
- await fs.writeFile(targetFile, mergedContent, 'utf-8');
525
- applied++;
526
- logger.info(`[upgrade] Applied merge: ${entry.officialId}`);
527
- } else {
528
- logger.warn(`[upgrade] Merge entry ${entry.officialId} has no merged content; skipping`);
529
- skipped++;
530
- }
531
- }
532
- } catch (err) {
533
- const msg = err instanceof Error ? err.message : String(err);
534
- logger.error(`[upgrade] Failed to apply ${entry.officialId}: ${msg}`);
535
- skipped++;
536
- }
537
- }
538
-
539
- logger.info(`[upgrade] Apply complete: ${applied} applied, ${skipped} skipped`);
540
- return { applied, skipped, backupPath };
541
- }
@@ -1,84 +0,0 @@
1
- /**
2
- * upgrade-prompt.ts
3
- *
4
- * Builds the system + user prompts for AI-assisted skill evaluation.
5
- * Pure functions — no I/O, no side effects.
6
- */
7
-
8
- import type { CandidateSkill } from './upgrade-engine.js';
9
- import type { OfficialSkill } from './official-skills.js';
10
-
11
- const MAX_CONTENT_CHARS = 2000;
12
-
13
- /**
14
- * Truncate content to at most `maxChars` characters, appending an ellipsis
15
- * marker so the model knows the text was cut.
16
- */
17
- function truncate(text: string, maxChars = MAX_CONTENT_CHARS): string {
18
- if (text.length <= maxChars) return text;
19
- return text.slice(0, maxChars) + '\n\n...[content truncated]';
20
- }
21
-
22
- /**
23
- * Build system + user prompts for evaluating whether a candidate skill should
24
- * upgrade, merge with, or skip an official skill.
25
- *
26
- * The system prompt defines the decision criteria and output JSON contract.
27
- * The user prompt contains the two skill bodies (capped at 2000 chars each).
28
- */
29
- export function buildEvaluationPrompt(
30
- candidate: CandidateSkill,
31
- official: OfficialSkill,
32
- ): { system: string; user: string } {
33
- const system = `你是 Claude Code skill 内容评估专家。
34
-
35
- 你的任务是比较"候选 skill"和"官方 skill",决定如何处理。
36
-
37
- ## 评估维度
38
- - **主题重叠度**:两个 skill 覆盖的领域是否高度相关
39
- - **内容质量**:深度、广度、实例丰富程度、可操作性
40
- - **互补性**:候选是否包含官方 skill 未涵盖的独特章节
41
-
42
- ## 决策标准
43
- - **skip**:主题不重叠,或官方 skill 已完整覆盖候选内容,合并无额外价值
44
- - **upgrade**:候选覆盖官方 skill 的全部核心要点,且整体质量明显更高(深度/广度提升 ≥30%),用候选直接替换官方版本
45
- - **merge**:主题相同但各有独特章节,合并后整体价值更高,需要生成合并后完整内容
46
-
47
- ## 输出格式
48
- 必须返回严格的 JSON,不含任何其他文本、代码块标记或注释:
49
- {"action":"upgrade|merge|skip","confidence":0-100,"reasoning":"简短中文说明(<200字)","merged_content":null或合并后完整md字符串}
50
-
51
- ## merged_content 规则
52
- - action = merge → 提供合并后的完整 .md 文件内容(含 frontmatter)
53
- - action = upgrade → null(直接使用候选原文)
54
- - action = skip → null`;
55
-
56
- const user = `## 官方 Skill(目标)
57
-
58
- **ID**: ${official.name}
59
- **描述**: ${official.description}
60
- **关键词**: ${official.keywords.join(', ') || '(无)'}
61
-
62
- \`\`\`markdown
63
- ${truncate(official.content)}
64
- \`\`\`
65
-
66
- ---
67
-
68
- ## 候选 Skill(来源: ${candidate.source})
69
-
70
- **ID**: ${candidate.id}
71
- **名称**: ${candidate.name}
72
- **描述**: ${candidate.description}
73
- **关键词**: ${candidate.keywords.join(', ') || '(无)'}
74
-
75
- \`\`\`markdown
76
- ${truncate(candidate.content)}
77
- \`\`\`
78
-
79
- ---
80
-
81
- 请评估候选 skill 相对于官方 skill 的升级价值,返回 JSON。`;
82
-
83
- return { system, user };
84
- }
@@ -1,53 +0,0 @@
1
- # Go Project Template
2
- # 为 Go 项目提供开箱即用的规则配置
3
-
4
- name: "Go Project"
5
- description: "Go 项目的推荐规则配置,包含 goroutine 管理、错误处理、并发安全等"
6
- version: "1.0.0"
7
-
8
- # 启用的规则文件
9
- conventions:
10
- - go-best-practices
11
- - basic-security
12
- - git-safety
13
-
14
- # 项目配置
15
- config:
16
- # 文件扩展名
17
- file_extensions:
18
- - .go
19
-
20
- # 忽略的目录
21
- ignore_paths:
22
- - vendor/
23
- - bin/
24
- - .git/
25
- - testdata/
26
-
27
- # 推荐的工具
28
- recommended_tools:
29
- - golangci-lint
30
- - gofmt
31
- - go vet
32
- - staticcheck
33
-
34
- # 初始化脚本
35
- init_commands:
36
- - go mod download
37
- - go build ./...
38
-
39
- # 推荐的 Makefile targets
40
- recommended_make_targets:
41
- lint: "golangci-lint run"
42
- fmt: "gofmt -s -w ."
43
- test: "go test -v -race -coverprofile=coverage.out ./..."
44
- build: "go build -o bin/app ./cmd/app"
45
-
46
- # 文档链接
47
- documentation:
48
- - name: "Go 官方文档"
49
- url: "https://go.dev/doc/"
50
- - name: "Effective Go"
51
- url: "https://go.dev/doc/effective_go"
52
- - name: "Go Code Review Comments"
53
- url: "https://github.com/golang/go/wiki/CodeReviewComments"