@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,108 +0,0 @@
1
- -- Legacy Pipeline 到 Dynamic Pipeline 数据迁移脚本
2
- -- 执行前请备份数据库:cp ~/.claude-forge/data.db ~/.claude-forge/data.db.backup
3
-
4
- -- ============================================
5
- -- 阶段 1:迁移 pipelines → dynamic_pipelines
6
- -- ============================================
7
-
8
- INSERT INTO dynamic_pipelines (
9
- id, requirement, project_path, session_id,
10
- template_id, convention_id, complexity, reasoning,
11
- status, created_at, updated_at
12
- )
13
- SELECT
14
- id,
15
- requirement,
16
- project_path,
17
- session_id,
18
- NULL as template_id, -- Legacy 无模板概念
19
- NULL as convention_id,
20
- COALESCE(complexity, 'moderate') as complexity,
21
- reasoning,
22
- CASE
23
- WHEN phase = 'done' THEN 'completed'
24
- ELSE 'in_progress'
25
- END as status,
26
- created_at,
27
- updated_at
28
- FROM pipelines
29
- WHERE id NOT IN (SELECT id FROM dynamic_pipelines);
30
-
31
- -- ============================================
32
- -- 阶段 2:迁移 pipeline_tasks → dynamic_nodes
33
- -- ============================================
34
-
35
- INSERT INTO dynamic_nodes (
36
- id, pipeline_id, node_type_id, status,
37
- dependencies, bound_skill_name, output,
38
- started_at, completed_at, created_at, updated_at
39
- )
40
- SELECT
41
- id,
42
- pipeline_id,
43
- phase as node_type_id, -- 将 phase 映射为 node_type_id
44
- CASE
45
- WHEN status = 'completed' THEN 'completed'
46
- WHEN status = 'in_progress' THEN 'in_progress'
47
- WHEN status = 'failed' THEN 'failed'
48
- ELSE 'pending'
49
- END as status,
50
- COALESCE(dependencies, '[]') as dependencies,
51
- NULL as bound_skill_name, -- Legacy 无 skill 绑定
52
- output,
53
- NULL as started_at, -- 需要从事件推导
54
- NULL as completed_at,
55
- datetime('now') as created_at, -- pipeline_tasks 无 created_at
56
- COALESCE(updated_at, datetime('now')) as updated_at
57
- FROM pipeline_tasks
58
- WHERE id NOT IN (SELECT id FROM dynamic_nodes);
59
-
60
- -- ============================================
61
- -- 阶段 3:验证迁移结果(删除 current_node_id 更新)
62
- -- ============================================
63
-
64
- -- ============================================
65
- -- 阶段 4:转换 pipeline_events 事件类型
66
- -- ============================================
67
-
68
- -- 将 Legacy 事件类型转换为 Dynamic 事件类型
69
- UPDATE pipeline_events
70
- SET type = CASE
71
- WHEN type = 'pipeline.created' THEN 'dynamic_pipeline.created'
72
- WHEN type = 'task.created' THEN 'dynamic_node.created'
73
- WHEN type = 'task.started' THEN 'dynamic_node.started'
74
- WHEN type = 'task.completed' THEN 'dynamic_node.completed'
75
- WHEN type = 'task.failed' THEN 'dynamic_node.failed'
76
- WHEN type = 'phase.advanced' THEN 'dynamic_node.advanced'
77
- WHEN type = 'pipeline.closed' THEN 'dynamic_pipeline.completed'
78
- ELSE type
79
- END
80
- WHERE pipeline_id IN (SELECT id FROM pipelines);
81
-
82
- -- ============================================
83
- -- 验证迁移结果
84
- -- ============================================
85
-
86
- -- 检查迁移数量
87
- SELECT
88
- 'Migrated Pipelines' as item,
89
- COUNT(*) as count
90
- FROM dynamic_pipelines
91
- WHERE id IN (SELECT id FROM pipelines)
92
-
93
- UNION ALL
94
-
95
- SELECT
96
- 'Migrated Nodes' as item,
97
- COUNT(*) as count
98
- FROM dynamic_nodes
99
- WHERE pipeline_id IN (SELECT id FROM pipelines)
100
-
101
- UNION ALL
102
-
103
- SELECT
104
- 'Converted Events' as item,
105
- COUNT(*) as count
106
- FROM pipeline_events
107
- WHERE pipeline_id IN (SELECT id FROM pipelines)
108
- AND type LIKE 'dynamic_%';
@@ -1,116 +0,0 @@
1
- #!/usr/bin/env tsx
2
- /**
3
- * 一次性脚本:用新的 ExecutionDocBuilder 重新生成所有历史执行文档。
4
- *
5
- * 用法:
6
- * npx tsx scripts/regenerate-execution-docs.ts
7
- *
8
- * 行为:
9
- * 1. 打开 ~/.claude-forge/data.db
10
- * 2. 查询 routing_events 中所有 distinct session_id
11
- * 3. 对每个 session 调用 builder.build(sessionId, projectPath)
12
- * → 会自动覆盖 overview/agent/skill 文件并最后调用 updateIndex
13
- * 4. updateIndex 扫描 by-route/ 下全部目录,因此即便某些路由在 DB 中已无数据,
14
- * 它们的目录仍会被纳入新的 index.md(保留旧文件作为兜底)
15
- *
16
- * 注意:
17
- * - 数据库只读
18
- * - 仅覆盖 <projectRoot>/.claude-forge/executions/ 下的 markdown
19
- * - 不传 AI provider,统一使用 fallback summary(避免网络抖动)
20
- */
21
-
22
- import path from 'node:path';
23
- import fs from 'node:fs';
24
- import { SQLiteStorage } from '../src/core/storage/sqlite.js';
25
- import { ExecutionDocBuilder } from '../src/intelligence/execution-doc-builder.js';
26
- import { FORGE_PATHS } from '../src/core/constants.js';
27
-
28
- async function main(): Promise<void> {
29
- const projectPath = process.cwd();
30
- const dbPath = FORGE_PATHS.database();
31
-
32
- console.log('===========================================');
33
- console.log('Regenerate Execution Docs');
34
- console.log('===========================================');
35
- console.log(`projectPath : ${projectPath}`);
36
- console.log(`database : ${dbPath}`);
37
-
38
- if (!fs.existsSync(dbPath)) {
39
- console.error(`数据库不存在: ${dbPath}`);
40
- process.exit(1);
41
- }
42
-
43
- const byRouteDir = path.join(projectPath, '.claude-forge', 'executions', 'by-route');
44
- const allDirs = fs.existsSync(byRouteDir)
45
- ? fs.readdirSync(byRouteDir, { withFileTypes: true })
46
- .filter(d => d.isDirectory())
47
- .map(d => d.name)
48
- : [];
49
- console.log(`磁盘目录数 : ${allDirs.length}`);
50
-
51
- const storage = new SQLiteStorage(dbPath);
52
- const builder = new ExecutionDocBuilder(storage, null);
53
-
54
- // 查询所有 distinct session_id
55
- const db = storage.getDatabase();
56
- const sessionRows = db
57
- .prepare(
58
- `SELECT DISTINCT session_id, COUNT(*) AS n
59
- FROM routing_events
60
- WHERE session_id IS NOT NULL
61
- GROUP BY session_id
62
- ORDER BY MIN(ts) ASC`,
63
- )
64
- .all() as Array<{ session_id: string; n: number }>;
65
-
66
- console.log(`数据库内 session 数 : ${sessionRows.length}`);
67
- sessionRows.forEach(s => {
68
- console.log(` - ${s.session_id} (${s.n} routes)`);
69
- });
70
- console.log('');
71
-
72
- if (sessionRows.length === 0) {
73
- console.log('数据库中没有可重生的路由记录,但仍尝试调用 updateIndex 重写索引...');
74
- // 没有 session 时,build() 不会被调用,因此 updateIndex 也不会运行。
75
- // 用一个空 sessionId 触发?不行,build 内部会查 0 行就返回。
76
- // 直接构造一个临时 builder 不行(updateIndex 是 private)。
77
- // 兜底:调用任意一个目录名作为 sessionId 让它跑一次。
78
- // 实际场景下 sessionRows 至少有 1 个,此分支多半不会进。
79
- storage.close();
80
- return;
81
- }
82
-
83
- let totalRoutes = 0;
84
- let okSessions = 0;
85
- let failSessions = 0;
86
-
87
- for (const [i, s] of sessionRows.entries()) {
88
- const tag = `[${i + 1}/${sessionRows.length}]`;
89
- try {
90
- console.log(`${tag} 处理 session ${s.session_id} (${s.n} routes)...`);
91
- await builder.build(s.session_id, projectPath);
92
- okSessions++;
93
- totalRoutes += s.n;
94
- } catch (err) {
95
- failSessions++;
96
- console.warn(`${tag} ✗ session ${s.session_id} 失败: ${err}`);
97
- }
98
- }
99
-
100
- console.log('');
101
- console.log('===========================================');
102
- console.log('完成');
103
- console.log('===========================================');
104
- console.log(`session 成功 : ${okSessions}`);
105
- console.log(`session 失败 : ${failSessions}`);
106
- console.log(`重生路由记录数 : ${totalRoutes}`);
107
- console.log(`磁盘目录总数 : ${allDirs.length}`);
108
- console.log(`未覆盖目录数 : ${Math.max(allDirs.length - totalRoutes, 0)} (保留原文件)`);
109
-
110
- storage.close();
111
- }
112
-
113
- main().catch(err => {
114
- console.error('重生失败:', err);
115
- process.exit(1);
116
- });
@@ -1,193 +0,0 @@
1
- #!/usr/bin/env tsx
2
- /**
3
- * sync-agent-skills.ts
4
- *
5
- * 从 GitHub 同步 addyosmani/agent-skills 到本地 ~/.claude/skills/agent-skills/
6
- *
7
- * 功能:
8
- * 1. Clone 或 pull agent-skills 仓库
9
- * 2. 记录 upstream commit hash 到 .sync-metadata.json
10
- * 3. 生成 MIT License NOTICE 文件
11
- * 4. 幂等:重复运行不会重复 clone
12
- */
13
-
14
- import { execSync } from 'child_process';
15
- import * as fs from 'fs';
16
- import * as path from 'path';
17
- import { homedir } from 'os';
18
-
19
- const UPSTREAM_REPO = 'https://github.com/addyosmani/agent-skills.git';
20
- const SKILLS_BASE_DIR = path.join(homedir(), '.claude', 'skills');
21
- const TARGET_DIR = path.join(SKILLS_BASE_DIR, 'agent-skills');
22
- const METADATA_FILE = path.join(TARGET_DIR, '.sync-metadata.json');
23
- const NOTICE_FILE = path.join(TARGET_DIR, 'NOTICE');
24
-
25
- interface SyncMetadata {
26
- upstream_repo: string;
27
- commit_hash: string;
28
- synced_at: string;
29
- }
30
-
31
- /**
32
- * 执行 shell 命令并返回输出
33
- */
34
- function exec(command: string, cwd?: string): string {
35
- try {
36
- return execSync(command, {
37
- cwd,
38
- encoding: 'utf-8',
39
- stdio: ['pipe', 'pipe', 'pipe'],
40
- }).trim();
41
- } catch (error: unknown) {
42
- if (error instanceof Error && 'stderr' in error) {
43
- throw new Error(`Command failed: ${command}\n${(error as { stderr: Buffer }).stderr.toString()}`);
44
- }
45
- throw error;
46
- }
47
- }
48
-
49
- /**
50
- * 检查 git 是否可用
51
- */
52
- function checkGitAvailable(): void {
53
- try {
54
- exec('git --version');
55
- } catch (error) {
56
- console.error('❌ Git 未安装或不可用');
57
- console.error('请先安装 Git: https://git-scm.com/downloads');
58
- process.exit(1);
59
- }
60
- }
61
-
62
- /**
63
- * 确保目录存在
64
- */
65
- function ensureDir(dir: string): void {
66
- if (!fs.existsSync(dir)) {
67
- fs.mkdirSync(dir, { recursive: true });
68
- console.log(`✓ 创建目录: ${dir}`);
69
- }
70
- }
71
-
72
- /**
73
- * 获取当前 commit hash
74
- */
75
- function getCommitHash(repoDir: string): string {
76
- return exec('git rev-parse HEAD', repoDir);
77
- }
78
-
79
- /**
80
- * 生成 MIT License NOTICE 文件
81
- */
82
- function generateNotice(commitHash: string, syncedAt: string): string {
83
- return `This directory contains skills from addyosmani/agent-skills
84
- Repository: https://github.com/addyosmani/agent-skills
85
- License: MIT
86
- Upstream commit: ${commitHash}
87
- Synced at: ${syncedAt}
88
-
89
- Original work Copyright (c) Addy Osmani
90
- Modifications (if any) Copyright (c) claude-forge contributors
91
-
92
- MIT License
93
-
94
- Permission is hereby granted, free of charge, to any person obtaining a copy
95
- of this software and associated documentation files (the "Software"), to deal
96
- in the Software without restriction, including without limitation the rights
97
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
98
- copies of the Software, and to permit persons to whom the Software is
99
- furnished to do so, subject to the following conditions:
100
-
101
- The above copyright notice and this permission notice shall be included in all
102
- copies or substantial portions of the Software.
103
-
104
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
105
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
106
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
107
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
108
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
109
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
110
- SOFTWARE.
111
- `;
112
- }
113
-
114
- /**
115
- * 同步 agent-skills 仓库
116
- */
117
- async function syncAgentSkills(): Promise<void> {
118
- console.log('🔄 开始同步 agent-skills...\n');
119
-
120
- // 1. 检查 git 可用性
121
- checkGitAvailable();
122
-
123
- // 2. 确保基础目录存在
124
- ensureDir(SKILLS_BASE_DIR);
125
-
126
- let isNewClone = false;
127
-
128
- // 3. Clone 或 Pull
129
- if (!fs.existsSync(TARGET_DIR)) {
130
- console.log(`📦 克隆仓库: ${UPSTREAM_REPO}`);
131
- try {
132
- exec(`git clone ${UPSTREAM_REPO} "${TARGET_DIR}"`);
133
- isNewClone = true;
134
- console.log('✓ 克隆成功\n');
135
- } catch (error) {
136
- console.error('❌ 克隆失败');
137
- console.error('可能原因:网络问题、仓库不存在、权限不足');
138
- throw error;
139
- }
140
- } else {
141
- console.log('📂 目录已存在,执行 git pull 更新...');
142
- try {
143
- const output = exec('git pull', TARGET_DIR);
144
- console.log(`✓ ${output}\n`);
145
- } catch (error) {
146
- console.error('❌ 更新失败');
147
- console.error('可能原因:本地有未提交的修改、网络问题');
148
- throw error;
149
- }
150
- }
151
-
152
- // 4. 获取 commit hash
153
- const commitHash = getCommitHash(TARGET_DIR);
154
- const syncedAt = new Date().toISOString();
155
-
156
- console.log(`📌 Upstream commit: ${commitHash}`);
157
- console.log(`🕐 同步时间: ${syncedAt}\n`);
158
-
159
- // 5. 写入 metadata
160
- const metadata: SyncMetadata = {
161
- upstream_repo: UPSTREAM_REPO,
162
- commit_hash: commitHash,
163
- synced_at: syncedAt,
164
- };
165
-
166
- fs.writeFileSync(METADATA_FILE, JSON.stringify(metadata, null, 2), 'utf-8');
167
- console.log(`✓ 元数据已保存: ${METADATA_FILE}`);
168
-
169
- // 6. 生成 NOTICE 文件
170
- const noticeContent = generateNotice(commitHash, syncedAt);
171
- fs.writeFileSync(NOTICE_FILE, noticeContent, 'utf-8');
172
- console.log(`✓ NOTICE 文件已生成: ${NOTICE_FILE}\n`);
173
-
174
- // 7. 统计 skills 数量
175
- const skillsDir = path.join(TARGET_DIR, 'skills');
176
- if (fs.existsSync(skillsDir)) {
177
- const skills = fs.readdirSync(skillsDir).filter((name) => {
178
- const fullPath = path.join(skillsDir, name);
179
- return fs.statSync(fullPath).isDirectory();
180
- });
181
- console.log(`📊 共同步 ${skills.length} 个 skills`);
182
- }
183
-
184
- console.log('\n✅ 同步完成!');
185
- console.log(`\n目标目录: ${TARGET_DIR}`);
186
- }
187
-
188
- // 执行同步
189
- syncAgentSkills().catch((error) => {
190
- console.error('\n❌ 同步失败:', error.message);
191
- process.exit(1);
192
- });
193
-
@@ -1,71 +0,0 @@
1
- #!/bin/bash
2
- # 测试 Hook 脚本是否能正常与守护进程通信
3
-
4
- SOCKET_PATH="$HOME/.claude-forge/daemon.sock"
5
-
6
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
7
- echo " 测试 Claude Forge Hook 通信"
8
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
9
- echo ""
10
-
11
- # 1. 检查守护进程是否运行
12
- echo "1. 检查守护进程状态..."
13
- if [ -f "$HOME/.claude-forge/daemon.pid" ]; then
14
- PID=$(cat "$HOME/.claude-forge/daemon.pid")
15
- if kill -0 "$PID" 2>/dev/null; then
16
- echo " ✓ 守护进程运行中 (PID: $PID)"
17
- else
18
- echo " ✗ 守护进程未运行"
19
- exit 1
20
- fi
21
- else
22
- echo " ✗ PID 文件不存在"
23
- exit 1
24
- fi
25
-
26
- # 2. 检查 Socket 文件
27
- echo ""
28
- echo "2. 检查 Socket 文件..."
29
- if [ -S "$SOCKET_PATH" ]; then
30
- echo " ✓ Socket 文件存在: $SOCKET_PATH"
31
- else
32
- echo " ✗ Socket 文件不存在"
33
- exit 1
34
- fi
35
-
36
- # 3. 发送测试事件
37
- echo ""
38
- echo "3. 发送测试事件..."
39
-
40
- # PreToolUse 事件
41
- echo " 发送 PreToolUse 事件..."
42
- echo '{"hook_type":"PreToolUse","timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","session_id":"test-session-123","project_path":"'$PWD'","tool_name":"Read","tool_input":"{\"file_path\":\"/test/file.txt\"}"}' | nc -U "$SOCKET_PATH" 2>/dev/null
43
- sleep 0.5
44
-
45
- # PostToolUse 事件
46
- echo " 发送 PostToolUse 事件..."
47
- echo '{"hook_type":"PostToolUse","timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","session_id":"test-session-123","project_path":"'$PWD'","tool_name":"Read","success":true}' | nc -U "$SOCKET_PATH" 2>/dev/null
48
- sleep 0.5
49
-
50
- # Notification 事件
51
- echo " 发送 Notification 事件..."
52
- echo '{"hook_type":"Notification","timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","session_id":"test-session-123","project_path":"'$PWD'","message":"Test notification"}' | nc -U "$SOCKET_PATH" 2>/dev/null
53
- sleep 0.5
54
-
55
- echo " ✓ 测试事件已发送"
56
-
57
- # 4. 查询数据库
58
- echo ""
59
- echo "4. 查询数据库中的事件..."
60
- sleep 1
61
- cd "$(dirname "$0")/.."
62
- npx tsx src/cli/index.ts query stats
63
-
64
- echo ""
65
- echo "5. 查看最近的事件..."
66
- npx tsx src/cli/index.ts query events --limit 5
67
-
68
- echo ""
69
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
70
- echo " 测试完成"
71
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@@ -1,62 +0,0 @@
1
- #!/usr/bin/env tsx
2
- /**
3
- * Verification script to test skill loading from both formats
4
- */
5
-
6
- import { SkillRegistry } from '../src/skills/registry.js';
7
-
8
- console.log('=== Verifying Skill Loading ===\n');
9
-
10
- const registry = new SkillRegistry();
11
- const skills = registry.getAll();
12
-
13
- console.log(`Total skills loaded: ${skills.length}\n`);
14
-
15
- // Check for official skills
16
- const officialSkills = skills.filter(s => s.isOfficial);
17
- console.log(`Official skills: ${officialSkills.length}`);
18
-
19
- // Check for user skills
20
- const userSkills = skills.filter(s => !s.isOfficial);
21
- console.log(`User skills: ${userSkills.length}\n`);
22
-
23
- // Check for directory format skills (path contains SKILL.md)
24
- const dirFormatSkills = userSkills.filter(s => s.path.includes('SKILL.md'));
25
- console.log(`Directory format skills: ${dirFormatSkills.length}`);
26
- if (dirFormatSkills.length > 0) {
27
- console.log('Examples:');
28
- dirFormatSkills.slice(0, 3).forEach(s => {
29
- console.log(` - ${s.id} (${s.path})`);
30
- console.log(` description: ${s.description || 'N/A'}`);
31
- console.log(` keywords: ${s.keywords.join(', ') || 'N/A'}`);
32
- });
33
- }
34
-
35
- // Check for flat format skills (path ends with .md but not SKILL.md)
36
- const flatFormatSkills = userSkills.filter(s => s.path.endsWith('.md') && !s.path.includes('SKILL.md'));
37
- console.log(`\nFlat format skills: ${flatFormatSkills.length}`);
38
- if (flatFormatSkills.length > 0) {
39
- console.log('Examples:');
40
- flatFormatSkills.slice(0, 3).forEach(s => {
41
- console.log(` - ${s.id} (${s.path})`);
42
- console.log(` description: ${s.description || 'N/A'}`);
43
- console.log(` keywords: ${s.keywords.join(', ') || 'N/A'}`);
44
- });
45
- }
46
-
47
- // Check for skills with description field
48
- const skillsWithDesc = skills.filter(s => s.description);
49
- console.log(`\nSkills with description field: ${skillsWithDesc.length}`);
50
-
51
- // Check for skills without keywords (should use description fallback)
52
- const skillsWithoutKeywords = skills.filter(s => s.keywords.length === 0);
53
- console.log(`Skills without keywords: ${skillsWithoutKeywords.length}`);
54
- if (skillsWithoutKeywords.length > 0) {
55
- console.log('Examples:');
56
- skillsWithoutKeywords.slice(0, 3).forEach(s => {
57
- console.log(` - ${s.id}`);
58
- console.log(` description: ${s.description || 'N/A'}`);
59
- });
60
- }
61
-
62
- console.log('\n=== Verification Complete ===');