@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.
- package/DEVELOPMENT.md +290 -221
- package/README.md +50 -8
- package/dist/cli/commands/skills.d.ts.map +1 -1
- package/dist/cli/commands/skills.js +121 -2
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/init/hook-manager.d.ts +1 -1
- package/dist/cli/init/hook-manager.d.ts.map +1 -1
- package/dist/cli/init/hook-manager.js +1 -0
- package/dist/cli/init/hook-manager.js.map +1 -1
- package/dist/core/constants.d.ts +2 -0
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +4 -0
- package/dist/core/constants.js.map +1 -1
- package/dist/core/storage/events.d.ts.map +1 -1
- package/dist/core/storage/events.js +0 -1
- package/dist/core/storage/events.js.map +1 -1
- package/dist/core/storage/maintenance.d.ts +25 -3
- package/dist/core/storage/maintenance.d.ts.map +1 -1
- package/dist/core/storage/maintenance.js +33 -4
- package/dist/core/storage/maintenance.js.map +1 -1
- package/dist/core/storage/routing.d.ts +4 -0
- package/dist/core/storage/routing.d.ts.map +1 -1
- package/dist/core/storage/routing.js +10 -4
- package/dist/core/storage/routing.js.map +1 -1
- package/dist/core/storage/sessions.d.ts +17 -0
- package/dist/core/storage/sessions.d.ts.map +1 -1
- package/dist/core/storage/sessions.js +64 -0
- package/dist/core/storage/sessions.js.map +1 -1
- package/dist/core/storage/skills.d.ts +4 -0
- package/dist/core/storage/skills.d.ts.map +1 -1
- package/dist/core/storage/skills.js +10 -2
- package/dist/core/storage/skills.js.map +1 -1
- package/dist/core/storage/sqlite.d.ts +5 -0
- package/dist/core/storage/sqlite.d.ts.map +1 -1
- package/dist/core/storage/sqlite.js +6 -0
- package/dist/core/storage/sqlite.js.map +1 -1
- package/dist/core/storage/tasks.d.ts.map +1 -1
- package/dist/core/storage/tasks.js +2 -0
- package/dist/core/storage/tasks.js.map +1 -1
- package/dist/core/types.d.ts +7 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +30 -5
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/skill-sync.d.ts +21 -0
- package/dist/daemon/skill-sync.d.ts.map +1 -0
- package/dist/daemon/skill-sync.js +75 -0
- package/dist/daemon/skill-sync.js.map +1 -0
- package/dist/hooks/notification.sh +1 -1
- package/dist/hooks/post-tool-use.sh +1 -1
- package/dist/hooks/pre-tool-use.sh +1 -1
- package/dist/hooks/stop.sh +1 -1
- package/dist/hooks/user-prompt-submit.sh +1 -1
- package/dist/skills/official/code-simplifier.md +37 -1
- package/dist/skills/official/find-skills.md +120 -1
- package/dist/skills/official/official-api-design.md +14 -1
- package/dist/skills/official/official-architecture-decision.md +22 -1
- package/dist/skills/official/official-db-schema-design.md +19 -1
- package/dist/skills/official/official-debug.md +9 -1
- package/dist/skills/official/official-pr-review.md +1 -1
- package/dist/skills/official/official-security-hardening.md +7 -1
- package/dist/skills/official/planning-with-files.md +206 -2
- package/dist/skills/official/ui-ux-pro-max.md +88 -1
- package/dist/skills/official/webapp-testing.md +85 -1
- package/dist/skills/registry.d.ts +1 -1
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +15 -4
- package/dist/skills/registry.js.map +1 -1
- package/dist/skills/semantic-matcher.d.ts +4 -3
- package/dist/skills/semantic-matcher.d.ts.map +1 -1
- package/dist/skills/semantic-matcher.js +20 -22
- package/dist/skills/semantic-matcher.js.map +1 -1
- package/dist/skills/upgrade-engine.d.ts +93 -0
- package/dist/skills/upgrade-engine.d.ts.map +1 -0
- package/dist/skills/upgrade-engine.js +447 -0
- package/dist/skills/upgrade-engine.js.map +1 -0
- package/dist/skills/upgrade-prompt.d.ts +20 -0
- package/dist/skills/upgrade-prompt.d.ts.map +1 -0
- package/dist/skills/upgrade-prompt.js +75 -0
- package/dist/skills/upgrade-prompt.js.map +1 -0
- package/dist/web/analytics/weekly-report.d.ts.map +1 -1
- package/dist/web/analytics/weekly-report.js +21 -29
- package/dist/web/analytics/weekly-report.js.map +1 -1
- package/dist/web/routes/patch.d.ts.map +1 -1
- package/dist/web/routes/patch.js +32 -2
- package/dist/web/routes/patch.js.map +1 -1
- package/dist/web/routes/sessions.d.ts.map +1 -1
- package/dist/web/routes/sessions.js +9 -7
- package/dist/web/routes/sessions.js.map +1 -1
- package/dist/web/routes/trace.d.ts.map +1 -1
- package/dist/web/routes/trace.js +2 -3
- package/dist/web/routes/trace.js.map +1 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +3 -2
- package/dist/web/server.js.map +1 -1
- package/package.json +12 -2
- package/scripts/postinstall.cjs +21 -0
- package/.claude/CLAUDE.md +0 -17
- package/.eslintrc.js +0 -23
- package/.prettierrc +0 -8
- package/ARCHITECTURE_ISSUES.md +0 -249
- package/CLAUDE.md +0 -265
- package/CLAUDE.md.backup +0 -488
- package/docs/concurrent-agents.md +0 -129
- package/docs/design/architecture-review-20260516.md +0 -232
- package/docs/design/fix-skills-data-and-set-leak-spec-20260516-1300.md +0 -219
- package/docs/design/h1-storage-aggregation-spec-20260518-1121.md +0 -299
- package/docs/design/h2-getdatabase-encapsulation-spec-20260518-1450.md +0 -191
- package/docs/design/h3-fallback-removal-spec-20260518-1245.md +0 -76
- package/docs/design/h4-index-dedup-spec-20260518-1230.md +0 -109
- package/docs/design/h6-services-migration-spec-20260518-1355.md +0 -82
- package/docs/design/hook-failure-queue-spec-20260516-1530.md +0 -204
- package/docs/design/l1-swarm-protocol-extract-spec-20260518-1605.md +0 -106
- package/docs/design/m10-forge-paths-spec-20260518-1320.md +0 -121
- package/docs/design/m2-m3-tool-input-spec-20260518-1425.md +0 -131
- package/docs/design/m7-routing-event-association-spec-20260518-1545.md +0 -103
- package/docs/design/project-path-gitroot-spec-20260518-1715.md +0 -134
- package/docs/design/refactor-phase1-spec-20260515-1600.md +0 -543
- package/docs/design/refactor-phase2-spec-20260515-1700.md +0 -424
- package/docs/design/task-active-gc-spec-20260518-1745.md +0 -146
- package/docs/design/tasks-list-filter-pagination-spec-20260518-0930.md +0 -208
- package/docs/implementation/fix-skills-data-and-set-leak-changelog-20260516-1300.md +0 -104
- package/docs/implementation/h1-storage-aggregation-changelog-20260518-1121.md +0 -82
- package/docs/implementation/h2-final-changelog-20260518-1530.md +0 -61
- package/docs/implementation/h2-phase1-safety-net-changelog-20260518-1450.md +0 -70
- package/docs/implementation/h2-phase2-operations-changelog-20260518-1450.md +0 -120
- package/docs/implementation/h2-phase3-callsites-changelog-20260518-1450.md +0 -71
- package/docs/implementation/h3-fallback-removal-changelog-20260518-1245.md +0 -71
- package/docs/implementation/h4-index-dedup-changelog-20260518-1230.md +0 -60
- package/docs/implementation/h6-services-migration-changelog-20260518-1355.md +0 -46
- package/docs/implementation/h7-m9-defaults-changelog-20260518-1300.md +0 -46
- package/docs/implementation/hook-failure-queue-changelog-20260516-1530.md +0 -196
- package/docs/implementation/hotfix-daemon-event-reject-20260516-1430.md +0 -56
- package/docs/implementation/l1-swarm-protocol-extract-changelog-20260518-1605.md +0 -45
- package/docs/implementation/l3-l4-daemon-perf-changelog-20260518-1410.md +0 -63
- package/docs/implementation/l6-l8-final-cleanup-changelog-20260518-1640.md +0 -38
- package/docs/implementation/m1-m4-m5-l7-cleanup-changelog-20260518-1310.md +0 -58
- package/docs/implementation/m10-forge-paths-changelog-20260518-1320.md +0 -60
- package/docs/implementation/m2-m3-tool-input-changelog-20260518-1425.md +0 -43
- package/docs/implementation/m6-m8-naming-shutdown-changelog-20260518-1340.md +0 -56
- package/docs/implementation/m7-routing-association-changelog-20260518-1545.md +0 -69
- package/docs/implementation/project-path-gitroot-changelog-20260518-1715.md +0 -63
- package/docs/implementation/refactor-phase1-changelog-20260515-1630.md +0 -354
- package/docs/implementation/refactor-phase2-changelog-20260515-1705.md +0 -421
- package/docs/implementation/task-active-gc-changelog-20260518-1745.md +0 -35
- package/docs/implementation/task-title-summary-changelog-20260518-1130.md +0 -39
- package/docs/implementation/tasks-detail-back-loses-filters-changelog-20260518-1100.md +0 -22
- package/docs/implementation/tasks-list-filter-pagination-changelog-20260518-0930.md +0 -72
- package/docs/implementation/tasks-page-white-screen-hotfix-changelog-20260518-1015.md +0 -56
- package/docs/reviews/claudemd-template-sync.md +0 -54
- package/docs/reviews/task-title-summary.md +0 -92
- package/docs/reviews/tasks-detail-back-loses-filters.md +0 -58
- package/docs/reviews/tasks-filter-pagination.md +0 -80
- package/docs/reviews/tasks-page-white-screen-hotfix.md +0 -126
- package/docs/ruflo-learning-strategy.md +0 -322
- package/docs/skills-deduplication-analysis.md +0 -83
- package/docs/skills-multiformat-support.md +0 -177
- package/docs/skills-third-party.md +0 -183
- package/docs/testing/tasks-filter-pagination-test-report.md +0 -86
- package/forge +0 -321
- package/playwright.config.ts +0 -40
- package/scripts/demo-v2.ts +0 -91
- package/scripts/dev-daemon.sh +0 -232
- package/scripts/dev-web.ts +0 -109
- package/scripts/e2e-mcp-link.ts +0 -423
- package/scripts/e2e-methodology-quality.ts +0 -253
- package/scripts/e2e-routing.ts +0 -456
- package/scripts/e2e-user-methodology.ts +0 -326
- package/scripts/e2e-web-workflows.ts +0 -299
- package/scripts/migrate-legacy-to-dynamic.sql +0 -108
- package/scripts/regenerate-execution-docs.ts +0 -116
- package/scripts/sync-agent-skills.ts +0 -193
- package/scripts/test-hook.sh +0 -71
- package/scripts/verify-skill-loading.ts +0 -62
- package/src/claudemd/claudemd-generator.ts +0 -568
- package/src/claudemd/convention-extractor.ts +0 -69
- package/src/claudemd/index.ts +0 -35
- package/src/claudemd/persona-manager.ts +0 -88
- package/src/claudemd/resume-manager.ts +0 -236
- package/src/claudemd/tech-detector.ts +0 -220
- package/src/claudemd/templates/swarm-protocol.md +0 -222
- package/src/cli/commands/claudemd.ts +0 -84
- package/src/cli/commands/config.ts +0 -46
- package/src/cli/commands/daemon.ts +0 -310
- package/src/cli/commands/executions.ts +0 -115
- package/src/cli/commands/init.ts +0 -204
- package/src/cli/commands/logs.ts +0 -181
- package/src/cli/commands/mcp.ts +0 -242
- package/src/cli/commands/menu.ts +0 -357
- package/src/cli/commands/skills.ts +0 -185
- package/src/cli/commands/stats.ts +0 -73
- package/src/cli/commands/status.ts +0 -69
- package/src/cli/commands/template.ts +0 -77
- package/src/cli/commands/trace.ts +0 -148
- package/src/cli/index.ts +0 -42
- package/src/cli/init/hook-manager.ts +0 -132
- package/src/core/ai/provider.ts +0 -308
- package/src/core/ai/types.ts +0 -51
- package/src/core/config.ts +0 -124
- package/src/core/constants.ts +0 -62
- package/src/core/event-fields.ts +0 -32
- package/src/core/queue/index.ts +0 -192
- package/src/core/storage/base.ts +0 -302
- package/src/core/storage/events.ts +0 -434
- package/src/core/storage/injections.ts +0 -78
- package/src/core/storage/maintenance.ts +0 -59
- package/src/core/storage/migrations/002_add_skill_tracking.sql +0 -6
- package/src/core/storage/migrations/003_add_skill_invocations.sql +0 -23
- package/src/core/storage/performance-indexes.sql +0 -23
- package/src/core/storage/routing.ts +0 -322
- package/src/core/storage/rows.ts +0 -112
- package/src/core/storage/schema.sql +0 -224
- package/src/core/storage/sessions.ts +0 -168
- package/src/core/storage/skills.ts +0 -233
- package/src/core/storage/sqlite.ts +0 -293
- package/src/core/storage/tasks.ts +0 -318
- package/src/core/storage/token-usage.ts +0 -93
- package/src/core/types.ts +0 -181
- package/src/core/utils/error-handler.ts +0 -257
- package/src/core/utils/forge-resume-block.ts +0 -74
- package/src/core/utils/format.ts +0 -69
- package/src/core/utils/git.ts +0 -23
- package/src/core/utils/logger.ts +0 -134
- package/src/core/utils/lru-cache.ts +0 -54
- package/src/core/utils/path.ts +0 -19
- package/src/core/utils/session.ts +0 -26
- package/src/core/utils/time.ts +0 -37
- package/src/core/utils/token-tracker.ts +0 -97
- package/src/daemon/event-parser.ts +0 -36
- package/src/daemon/handlers/history-exporter.ts +0 -117
- package/src/daemon/handlers/post-tool-use.ts +0 -54
- package/src/daemon/handlers/stop.ts +0 -208
- package/src/daemon/handlers/user-prompt.ts +0 -178
- package/src/daemon/hook-sync.ts +0 -91
- package/src/daemon/index.ts +0 -302
- package/src/daemon/launchd/com.claude-forge.daemon.plist.template +0 -47
- package/src/daemon/launchd-installer.ts +0 -260
- package/src/daemon/lifecycle.ts +0 -128
- package/src/daemon/router.ts +0 -40
- package/src/daemon/server.ts +0 -196
- package/src/daemon/services/task-segmenter.ts +0 -112
- package/src/hooks/hook-lib.sh +0 -118
- package/src/hooks/notification.sh +0 -35
- package/src/hooks/post-tool-use.sh +0 -61
- package/src/hooks/pre-tool-use.sh +0 -63
- package/src/hooks/stop.sh +0 -43
- package/src/hooks/user-prompt-submit.sh +0 -69
- package/src/mcp/server.ts +0 -322
- package/src/skills/index.ts +0 -2
- package/src/skills/invocation-guard.ts +0 -177
- package/src/skills/matcher.ts +0 -148
- package/src/skills/official/code-simplifier.md +0 -16
- package/src/skills/official/find-skills.md +0 -23
- package/src/skills/official/official-api-design.md +0 -17
- package/src/skills/official/official-architecture-decision.md +0 -20
- package/src/skills/official/official-bmad.md +0 -118
- package/src/skills/official/official-db-schema-design.md +0 -16
- package/src/skills/official/official-debug.md +0 -17
- package/src/skills/official/official-doc-driven.md +0 -31
- package/src/skills/official/official-harness-engineering.md +0 -108
- package/src/skills/official/official-performance-optimization.md +0 -30
- package/src/skills/official/official-pr-review.md +0 -35
- package/src/skills/official/official-release-checklist.md +0 -30
- package/src/skills/official/official-security-hardening.md +0 -26
- package/src/skills/official/official-spec-driven-design.md +0 -31
- package/src/skills/official/planning-with-files.md +0 -37
- package/src/skills/official/ui-ux-pro-max.md +0 -18
- package/src/skills/official/webapp-testing.md +0 -12
- package/src/skills/official-skills.ts +0 -89
- package/src/skills/registry.ts +0 -355
- package/src/skills/semantic-matcher.ts +0 -231
- package/src/skills/tools/pipeline-suggest.ts +0 -226
- package/src/skills/tools/skill-invoke.ts +0 -168
- package/src/skills/tools/skill-list.ts +0 -59
- package/src/templates/go.yaml +0 -53
- package/src/templates/python.yaml +0 -59
- package/src/templates/react.yaml +0 -55
- package/src/templates/template-manager.ts +0 -170
- package/src/web/analytics/anti-pattern-detector.ts +0 -367
- package/src/web/analytics/drift-detector.ts +0 -219
- package/src/web/analytics/weekly-report.ts +0 -431
- package/src/web/auth-middleware.ts +0 -54
- package/src/web/routes/_helpers.ts +0 -34
- package/src/web/routes/ai.ts +0 -204
- package/src/web/routes/auth.ts +0 -22
- package/src/web/routes/drift.ts +0 -25
- package/src/web/routes/error-handler.ts +0 -120
- package/src/web/routes/events.ts +0 -47
- package/src/web/routes/insights.ts +0 -43
- package/src/web/routes/patch.ts +0 -117
- package/src/web/routes/reports.ts +0 -34
- package/src/web/routes/rules.ts +0 -76
- package/src/web/routes/sessions.ts +0 -250
- package/src/web/routes/skill-stats.ts +0 -92
- package/src/web/routes/skills.ts +0 -350
- package/src/web/routes/static.ts +0 -67
- package/src/web/routes/stats.ts +0 -50
- package/src/web/routes/status.ts +0 -30
- package/src/web/routes/tasks.ts +0 -193
- package/src/web/routes/token-usage.ts +0 -20
- package/src/web/routes/trace.ts +0 -126
- package/src/web/routes/types.ts +0 -57
- package/src/web/server.ts +0 -134
- package/src/web/ssrf-guard.ts +0 -112
- package/src/web/static/index.html +0 -3251
- package/src/web/static/vendor/chart.umd.min.js +0 -20
- package/tests/e2e/dashboard.spec.ts +0 -205
- package/tests/e2e/routing-skill-e2e.test.ts +0 -39
- package/tests/helpers/mock-ai.ts +0 -92
- package/tests/helpers/mock-storage.ts +0 -159
- package/tests/integration/claudemd-generator.test.ts +0 -90
- package/tests/integration/queue-replay.integration.test.ts +0 -193
- package/tests/integration/tasks-filter.integration.test.ts +0 -154
- package/tests/integration/web-analytics.integration.test.ts +0 -133
- package/tests/integration/web-stats.integration.test.ts +0 -135
- package/tests/integration/web-trace.integration.test.ts +0 -175
- package/tests/performance/database.benchmark.ts +0 -161
- package/tests/semantic-matcher.test.ts +0 -99
- package/tests/skill-matcher.test.ts +0 -110
- package/tests/unit/ai-provider-retry.test.ts +0 -194
- package/tests/unit/ai-provider-vision.test.ts +0 -224
- package/tests/unit/claudemd-generator.test.ts +0 -68
- package/tests/unit/cli-mcp.test.ts +0 -141
- package/tests/unit/core/forge-paths.test.ts +0 -99
- package/tests/unit/daemon/hook-sync.test.ts +0 -71
- package/tests/unit/daemon/post-tool-use.test.ts +0 -121
- package/tests/unit/daemon/stop-handler-behavior-summary.test.ts +0 -202
- package/tests/unit/daemon/task-segmenter-recover.test.ts +0 -84
- package/tests/unit/event-fields.test.ts +0 -88
- package/tests/unit/event-parser.test.ts +0 -55
- package/tests/unit/handlers.test.ts +0 -171
- package/tests/unit/hooks/resolve-project-path.test.ts +0 -122
- package/tests/unit/invocation-guard.test.ts +0 -125
- package/tests/unit/queue.test.ts +0 -272
- package/tests/unit/router.test.ts +0 -138
- package/tests/unit/security.test.ts +0 -128
- package/tests/unit/skill-invocations-workflow.test.ts +0 -495
- package/tests/unit/skill-registry.test.ts +0 -94
- package/tests/unit/skills/invocation-guard-ttl.test.ts +0 -211
- package/tests/unit/skills/official-skills-loader.test.ts +0 -126
- package/tests/unit/skills/registry-multiformat.test.ts +0 -92
- package/tests/unit/socket-server.test.ts +0 -183
- package/tests/unit/storage/event-operations-aggregates.test.ts +0 -342
- package/tests/unit/storage/migration-idempotent.test.ts +0 -304
- package/tests/unit/storage/routing-aggregates.test.ts +0 -276
- package/tests/unit/storage/routing.test.ts +0 -117
- package/tests/unit/storage/schema-missing.test.ts +0 -81
- package/tests/unit/storage/session-operations-aggregates.test.ts +0 -120
- package/tests/unit/storage/sessions-aggregate.test.ts +0 -435
- package/tests/unit/storage/skill-operations-counts.test.ts +0 -106
- package/tests/unit/storage/skills-aggregates.test.ts +0 -104
- package/tests/unit/storage/sqlite-refactor-harness.test.ts +0 -314
- package/tests/unit/storage/task-operations-counts.test.ts +0 -46
- package/tests/unit/storage/tasks-getById.test.ts +0 -343
- package/tests/unit/storage/tasks-stale-gc.test.ts +0 -86
- package/tests/unit/storage.test.ts +0 -172
- package/tests/unit/token-usage.test.ts +0 -144
- package/tests/unit/type-guards.test.ts +0 -201
- package/tests/unit/utils/format.test.ts +0 -189
- package/tests/unit/utils/session.test.ts +0 -89
- package/tests/unit/utils/time.test.ts +0 -112
- package/tests/unit/web/navigation-back-contract.test.ts +0 -134
- package/tests/unit/web/routes-auth.test.ts +0 -93
- package/tests/unit/web/routes-events.test.ts +0 -101
- package/tests/unit/web/routes-rules.test.ts +0 -182
- package/tests/unit/web/routes-sessions.test.ts +0 -181
- package/tests/unit/web/routes-skill-stats.test.ts +0 -179
- package/tests/unit/web/routes-stats.test.ts +0 -92
- package/tests/unit/web/routes-tasks.test.ts +0 -385
- package/tests/unit/web/task-title-contract.test.ts +0 -210
- package/tests/unit/web/tasks-component-contract.test.ts +0 -179
- package/tsconfig.json +0 -22
- package/vitest.config.ts +0 -21
- package/vitest.integration.config.ts +0 -16
- package/web/CLAUDE.md +0 -20
- package/web/index.html +0 -13
- package/web/package-lock.json +0 -4854
- package/web/package.json +0 -35
- package/web/postcss.config.js +0 -6
- package/web/src/App.tsx +0 -110
- package/web/src/components/CodeBlock.tsx +0 -31
- package/web/src/components/Confirm.tsx +0 -96
- package/web/src/components/Drawer.tsx +0 -60
- package/web/src/components/Layout.tsx +0 -145
- package/web/src/components/MarkdownRenderer.tsx +0 -77
- package/web/src/components/SearchInput.tsx +0 -31
- package/web/src/components/SessionDetailContent.tsx +0 -157
- package/web/src/components/Toast.tsx +0 -92
- package/web/src/index.css +0 -19
- package/web/src/main.tsx +0 -31
- package/web/src/pages/AIConfig.tsx +0 -233
- package/web/src/pages/Dashboard.tsx +0 -572
- package/web/src/pages/Events.tsx +0 -271
- package/web/src/pages/Reports.tsx +0 -428
- package/web/src/pages/SessionDetail.tsx +0 -162
- package/web/src/pages/Sessions.tsx +0 -205
- package/web/src/pages/Skills.tsx +0 -180
- package/web/src/pages/TaskDetail.tsx +0 -515
- package/web/src/pages/Tasks.tsx +0 -415
- package/web/src/utils/auth.ts +0 -59
- package/web/src/utils/export.ts +0 -54
- package/web/src/utils/navigation.ts +0 -25
- package/web/src/utils/task-title.ts +0 -49
- package/web/src/utils/time.ts +0 -13
- package/web/tailwind.config.js +0 -11
- package/web/tsconfig.json +0 -21
- package/web/tsconfig.node.json +0 -10
- package/web/vite.config.ts +0 -76
- package/winspan-claude-forge-8.43.0.tgz +0 -0
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: planning-with-files
|
|
3
|
-
description: Implements Manus-style file-based planning to organize and track progress on complex tasks. Creates task_plan.md, findings.md, and progress.md. Use when asked to plan out, break down, or organize a multi-step project, research task, or any work requiring 5+ tool calls. Supports automatic session recovery after /clear.
|
|
4
|
-
user-invocable: true
|
|
5
|
-
allowed-tools: "Read Write Edit Bash Glob Grep"
|
|
6
|
-
hooks:
|
|
7
|
-
UserPromptSubmit:
|
|
8
|
-
- hooks:
|
|
9
|
-
- type: command
|
|
10
|
-
command: "if [ -f task_plan.md ]; then echo '[planning-with-files] ACTIVE PLAN — current state:'; head -50 task_plan.md; echo ''; echo '=== recent progress ==='; tail -20 progress.md 2>/dev/null; echo ''; echo '[planning-with-files] Read findings.md for research context. Continue from the current phase.'; fi"
|
|
11
|
-
PreToolUse:
|
|
12
|
-
- matcher: "Write|Edit|Bash|Read|Glob|Grep"
|
|
13
|
-
hooks:
|
|
14
|
-
- type: command
|
|
15
|
-
command: "cat task_plan.md 2>/dev/null | head -30 || true"
|
|
16
|
-
PostToolUse:
|
|
17
|
-
- matcher: "Write|Edit"
|
|
18
|
-
hooks:
|
|
19
|
-
- type: command
|
|
20
|
-
command: "if [ -f task_plan.md ]; then echo '[planning-with-files] Update progress.md with what you just did. If a phase is now complete, update task_plan.md status.'; fi"
|
|
21
|
-
Stop:
|
|
22
|
-
- hooks:
|
|
23
|
-
- type: command
|
|
24
|
-
command: "powershell.exe -NoProfile -ExecutionPolicy Bypass -Command \\\"& (Get-ChildItem -Path (Join-Path ~ '.claude/plugins/cache') -Filter check-complete.ps1 -Recurse -EA 0 | Select-Object -First 1).FullName\\\" 2>/dev/null || sh \\\"$(ls $HOME/.claude/plugins/cache/*/*/*/scripts/check-complete.sh 2>/dev/null | head -1)\\\" 2>/dev/null || true"
|
|
25
|
-
metadata:
|
|
26
|
-
version: "2.35.0"
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
# Planning with Files
|
|
30
|
-
|
|
31
|
-
Work like Manus: Use persistent markdown files as your "working memory on disk."
|
|
32
|
-
|
|
33
|
-
## FIRST: Restore Context (v2.2.0)
|
|
34
|
-
|
|
35
|
-
**Before doing anything else**, check if planning files exist and read them:
|
|
36
|
-
|
|
37
|
-
1. If `
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ui-ux-pro-max
|
|
3
|
-
version: 2.5.0
|
|
4
|
-
description: "AI 驱动的设计智能工具:67 种 UI 风格、161 种配色、57 种字体搭配、99 条 UX 准则"
|
|
5
|
-
tags: [ui, ux, design, color, typography, accessibility]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# CLAUDE.md
|
|
9
|
-
|
|
10
|
-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
11
|
-
|
|
12
|
-
## Project Overview
|
|
13
|
-
|
|
14
|
-
Antigravity Kit is an AI-powered design intelligence toolkit providing searchable databases of UI styles, color palettes, font pairings, chart types, and UX guidelines. It works as a skill/workflow for AI coding assistants (Claude Code, Windsurf, Cursor, etc.).
|
|
15
|
-
|
|
16
|
-
## Search Command
|
|
17
|
-
|
|
18
|
-
`
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: webapp-testing
|
|
3
|
-
description: Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
|
|
4
|
-
license: Complete terms in LICENSE.txt
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Web Application Testing
|
|
8
|
-
|
|
9
|
-
To test local web applications, write native Python Playwright scripts.
|
|
10
|
-
|
|
11
|
-
**Helper Scripts Available**:
|
|
12
|
-
- `
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Official built-in skills for claude-forge
|
|
3
|
-
* Skill content is stored in src/skills/official/*.md files.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import fs from 'node:fs';
|
|
7
|
-
import path from 'node:path';
|
|
8
|
-
import matter from 'gray-matter';
|
|
9
|
-
|
|
10
|
-
export interface OfficialSkill {
|
|
11
|
-
name: string;
|
|
12
|
-
version: string;
|
|
13
|
-
description: string;
|
|
14
|
-
keywords: string[];
|
|
15
|
-
content: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Official skill keyword mappings
|
|
20
|
-
* Used for skill matching and orchestration
|
|
21
|
-
*/
|
|
22
|
-
export const OFFICIAL_SKILL_KEYWORDS: Record<string, string[]> = {
|
|
23
|
-
'official-tdd': ['tdd', 'test-driven', '测试驱动'],
|
|
24
|
-
'official-debug': ['debug', '调试', 'bug', '修复', 'fix', 'hotfix', '报错', '异常', 'error', '不工作', '失败', 'failed', 'crash', '问题'],
|
|
25
|
-
'official-refactor': ['refactor', '重构', 'cleanup', 'reorganize', 'restructure'],
|
|
26
|
-
'official-pr-review': ['review', '审查', 'pr review', 'code review', '检查', '看看代码', '帮我看', '评审'],
|
|
27
|
-
'official-harness-engineering': ['harness', 'legacy', '遗留代码', '特征测试', 'characterization', '重构', 'refactor', '改造', '老代码'],
|
|
28
|
-
'official-bmad': ['bmad', 'agile', 'four-role', '敏捷', '四角色', 'story', 'user story', 'sprint', '迭代'],
|
|
29
|
-
'official-spec-driven-design': ['spec', 'sdd', 'spec-driven', '规格', '需求文档', 'requirements'],
|
|
30
|
-
'official-architecture-decision': ['adr', 'architecture decision', '架构决策', '技术选型'],
|
|
31
|
-
'official-api-design': ['api design', 'api 设计', 'restful', 'openapi', '接口设计'],
|
|
32
|
-
'official-db-schema-design': ['schema', 'database', '数据库设计', 'migration', '迁移', 'sql'],
|
|
33
|
-
'official-performance-optimization': ['performance', '性能', 'optimize', '优化', 'profiling', '瓶颈', '慢', 'slow', 'timeout', '超时', '卡顿', 'latency'],
|
|
34
|
-
'official-security-hardening': ['security', '安全', 'owasp', 'hardening', '加固', 'vulnerability', '漏洞', '注入', 'injection', 'xss', 'csrf', '权限', 'auth'],
|
|
35
|
-
'official-release-checklist': ['release', 'deploy', '发布', '上线', 'checklist', '部署'],
|
|
36
|
-
'official-doc-driven': ['doc-driven', 'documentation', '文档驱动', '写文档', 'readme'],
|
|
37
|
-
'planning-with-files': ['plan', 'planning', '规划', 'task plan', 'organize', '组织任务', '怎么做', '方案', '步骤', '计划'],
|
|
38
|
-
'code-simplifier': ['simplify', 'refine', '简化', 'cleanup', 'code quality'],
|
|
39
|
-
'find-skills': ['find skill', 'search skill', '查找技能', 'discover', 'install skill'],
|
|
40
|
-
'webapp-testing': ['test webapp', 'playwright', 'browser test', 'e2e', 'frontend test'],
|
|
41
|
-
'ui-ux-pro-max': ['ui', 'ux', 'design', 'color', 'typography', 'palette', '设计'],
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Load official skills from a directory of .md files.
|
|
46
|
-
* Each .md file should have frontmatter with at minimum a `name` field.
|
|
47
|
-
* The `keywords` or `tags` field in frontmatter provides keyword matching hints.
|
|
48
|
-
*
|
|
49
|
-
* @param builtinDir - Path to the directory containing official skill .md files
|
|
50
|
-
* @returns Array of OfficialSkill objects
|
|
51
|
-
*/
|
|
52
|
-
export function loadOfficialSkills(builtinDir: string): OfficialSkill[] {
|
|
53
|
-
if (!fs.existsSync(builtinDir)) {
|
|
54
|
-
throw new Error(`Official skills directory not found: ${builtinDir}`);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const entries = fs.readdirSync(builtinDir);
|
|
58
|
-
const skills: OfficialSkill[] = [];
|
|
59
|
-
|
|
60
|
-
for (const filename of entries) {
|
|
61
|
-
if (!filename.endsWith('.md')) continue;
|
|
62
|
-
|
|
63
|
-
const filePath = path.join(builtinDir, filename);
|
|
64
|
-
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
65
|
-
const parsed = matter(raw);
|
|
66
|
-
const { data, content: body } = parsed;
|
|
67
|
-
|
|
68
|
-
const id = path.basename(filename, '.md');
|
|
69
|
-
const name = typeof data.name === 'string' ? data.name : id;
|
|
70
|
-
const version = typeof data.version === 'string' ? data.version : '1.0.0';
|
|
71
|
-
const description = typeof data.description === 'string' ? data.description : '';
|
|
72
|
-
|
|
73
|
-
// Support both `keywords` (claude-forge standard) and `tags` (Claude Code official skill convention)
|
|
74
|
-
const rawKeywords: unknown = data.keywords ?? data.tags;
|
|
75
|
-
const keywords: string[] = Array.isArray(rawKeywords)
|
|
76
|
-
? rawKeywords.filter((k): k is string => typeof k === 'string')
|
|
77
|
-
: [];
|
|
78
|
-
|
|
79
|
-
skills.push({
|
|
80
|
-
name,
|
|
81
|
-
version,
|
|
82
|
-
description,
|
|
83
|
-
keywords,
|
|
84
|
-
content: raw, // full file content including frontmatter
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return skills;
|
|
89
|
-
}
|
package/src/skills/registry.ts
DELETED
|
@@ -1,355 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { homedir } from 'node:os';
|
|
4
|
-
import matter from 'gray-matter';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { logger } from '../core/utils/logger.js';
|
|
7
|
-
import { loadOfficialSkills, OFFICIAL_SKILL_KEYWORDS } from './official-skills.js';
|
|
8
|
-
import { SemanticSkillMatcher } from './semantic-matcher.js';
|
|
9
|
-
|
|
10
|
-
const SKILLS_DIR = path.join(homedir(), '.claude', 'skills');
|
|
11
|
-
|
|
12
|
-
export interface Skill {
|
|
13
|
-
id: string;
|
|
14
|
-
name: string;
|
|
15
|
-
keywords: string[];
|
|
16
|
-
content: string;
|
|
17
|
-
path: string;
|
|
18
|
-
isOfficial?: boolean; // Mark official built-in skills
|
|
19
|
-
description?: string; // Optional description from frontmatter (used by agent-skills format)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Simple skill registry that scans ~/.claude/skills/*.md
|
|
24
|
-
* and matches by keywords in frontmatter
|
|
25
|
-
*/
|
|
26
|
-
export class SkillRegistry {
|
|
27
|
-
private skills: Map<string, Skill> = new Map();
|
|
28
|
-
private semanticMatcher: SemanticSkillMatcher | null = null;
|
|
29
|
-
|
|
30
|
-
constructor(apiKey?: string) {
|
|
31
|
-
this.scan();
|
|
32
|
-
|
|
33
|
-
// Initialize semantic matcher if API key is provided
|
|
34
|
-
if (apiKey) {
|
|
35
|
-
this.semanticMatcher = new SemanticSkillMatcher(apiKey);
|
|
36
|
-
logger.info('[SkillRegistry] Semantic matching enabled');
|
|
37
|
-
} else {
|
|
38
|
-
logger.debug('[SkillRegistry] Semantic matching disabled (no API key)');
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Resolve the directory containing official built-in skill .md files.
|
|
44
|
-
* Uses import.meta.url for ESM compatibility (works in both dev and npm-installed environments).
|
|
45
|
-
*/
|
|
46
|
-
private resolveBuiltinDir(): string {
|
|
47
|
-
const thisFile = fileURLToPath(import.meta.url);
|
|
48
|
-
return path.join(path.dirname(thisFile), 'official');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Scan ~/.claude/skills/ for markdown files with frontmatter
|
|
53
|
-
* Official skills are loaded first, then user skills (which can override)
|
|
54
|
-
*
|
|
55
|
-
* Supports two formats:
|
|
56
|
-
* 1. Flat format: ~/.claude/skills/skill-name.md
|
|
57
|
-
* 2. Directory format: ~/.claude/skills/skill-name/SKILL.md (agent-skills format)
|
|
58
|
-
*/
|
|
59
|
-
private scan(): void {
|
|
60
|
-
// 1. Load official built-in skills from src/skills/official/*.md
|
|
61
|
-
let officialCount = 0;
|
|
62
|
-
try {
|
|
63
|
-
const officialSkills = loadOfficialSkills(this.resolveBuiltinDir());
|
|
64
|
-
for (const officialSkill of officialSkills) {
|
|
65
|
-
// Merge extended keywords from OFFICIAL_SKILL_KEYWORDS if available
|
|
66
|
-
const extendedKeywords = OFFICIAL_SKILL_KEYWORDS[officialSkill.name] || officialSkill.keywords;
|
|
67
|
-
this.skills.set(officialSkill.name, {
|
|
68
|
-
id: officialSkill.name,
|
|
69
|
-
name: officialSkill.name,
|
|
70
|
-
keywords: extendedKeywords,
|
|
71
|
-
content: officialSkill.content,
|
|
72
|
-
path: this.resolveBuiltinDir() + '/' + officialSkill.name + '.md',
|
|
73
|
-
isOfficial: true,
|
|
74
|
-
description: officialSkill.description,
|
|
75
|
-
});
|
|
76
|
-
officialCount++;
|
|
77
|
-
}
|
|
78
|
-
} catch (err) {
|
|
79
|
-
logger.warn(`[SkillRegistry] Failed to load official skills: ${err}`);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
logger.info(`Loaded ${officialCount} official skill(s)`);
|
|
83
|
-
|
|
84
|
-
// 2. Load user skills from ~/.claude/skills/ (can override official skills)
|
|
85
|
-
if (!fs.existsSync(SKILLS_DIR)) {
|
|
86
|
-
logger.debug(`Skills directory not found: ${SKILLS_DIR}`);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const entries = fs.readdirSync(SKILLS_DIR, { withFileTypes: true });
|
|
91
|
-
let userCount = 0;
|
|
92
|
-
|
|
93
|
-
for (const entry of entries) {
|
|
94
|
-
try {
|
|
95
|
-
let filePath: string;
|
|
96
|
-
let id: string;
|
|
97
|
-
|
|
98
|
-
if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
99
|
-
// Format 1: Flat .md file
|
|
100
|
-
filePath = path.join(SKILLS_DIR, entry.name);
|
|
101
|
-
id = path.basename(entry.name, '.md');
|
|
102
|
-
} else if (entry.isDirectory()) {
|
|
103
|
-
// Format 2: Directory with SKILL.md
|
|
104
|
-
const skillMdPath = path.join(SKILLS_DIR, entry.name, 'SKILL.md');
|
|
105
|
-
if (!fs.existsSync(skillMdPath)) {
|
|
106
|
-
continue; // Skip directories without SKILL.md
|
|
107
|
-
}
|
|
108
|
-
filePath = skillMdPath;
|
|
109
|
-
id = entry.name;
|
|
110
|
-
} else {
|
|
111
|
-
continue; // Skip other file types
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const content = fs.readFileSync(filePath, 'utf-8');
|
|
115
|
-
const parsed = matter(content);
|
|
116
|
-
const { data, content: body } = parsed;
|
|
117
|
-
|
|
118
|
-
const name = typeof data.name === 'string' ? data.name : id;
|
|
119
|
-
// 兼容两种字段名:keywords(claude-forge 标准)和 tags(Claude Code 官方 skill 约定)
|
|
120
|
-
const rawKeywords: unknown = data.keywords ?? data.tags;
|
|
121
|
-
const keywords: string[] = Array.isArray(rawKeywords)
|
|
122
|
-
? rawKeywords.filter((k): k is string => typeof k === 'string')
|
|
123
|
-
: [];
|
|
124
|
-
const description = typeof data.description === 'string' ? data.description : undefined;
|
|
125
|
-
|
|
126
|
-
// User skills override official skills, but merge keywords from OFFICIAL_SKILL_KEYWORDS
|
|
127
|
-
const extendedKeywords = OFFICIAL_SKILL_KEYWORDS[id];
|
|
128
|
-
const mergedKeywords = extendedKeywords
|
|
129
|
-
? [...new Set([...keywords, ...extendedKeywords])]
|
|
130
|
-
: keywords;
|
|
131
|
-
|
|
132
|
-
this.skills.set(id, {
|
|
133
|
-
id,
|
|
134
|
-
name,
|
|
135
|
-
keywords: mergedKeywords,
|
|
136
|
-
content: body.trim(),
|
|
137
|
-
path: filePath,
|
|
138
|
-
isOfficial: false,
|
|
139
|
-
description,
|
|
140
|
-
});
|
|
141
|
-
userCount++;
|
|
142
|
-
} catch (err) {
|
|
143
|
-
logger.warn(`Failed to parse skill ${entry.name}: ${err}`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (userCount > 0) {
|
|
148
|
-
logger.info(`Loaded ${userCount} user skill(s) from ${SKILLS_DIR}`);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Match a prompt against skill keywords with hybrid approach:
|
|
154
|
-
* 1. Try semantic matching (AI-powered) if available
|
|
155
|
-
* 2. Fall back to keyword matching if semantic fails or not configured
|
|
156
|
-
*/
|
|
157
|
-
async match(prompt: string, keywords: string[] = [], context?: { recentFiles?: string[] }): Promise<Skill | null> {
|
|
158
|
-
const result = await this.matchWithConfidence(prompt, keywords, context);
|
|
159
|
-
return result?.skill ?? null;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Like match(), but also returns the confidence score (0-100) so callers
|
|
164
|
-
* can compare across alternatives (e.g. agent vs skill routing).
|
|
165
|
-
*/
|
|
166
|
-
async matchWithConfidence(
|
|
167
|
-
prompt: string,
|
|
168
|
-
keywords: string[] = [],
|
|
169
|
-
context?: { recentFiles?: string[] },
|
|
170
|
-
): Promise<{ skill: Skill; confidence: number; source: 'semantic' | 'keyword' } | null> {
|
|
171
|
-
// Try semantic matching first
|
|
172
|
-
if (this.semanticMatcher) {
|
|
173
|
-
try {
|
|
174
|
-
const semanticResult = await this.semanticMatcher.match(
|
|
175
|
-
Array.from(this.skills.values()),
|
|
176
|
-
{
|
|
177
|
-
prompt,
|
|
178
|
-
intentKeywords: keywords,
|
|
179
|
-
recentFiles: context?.recentFiles,
|
|
180
|
-
}
|
|
181
|
-
);
|
|
182
|
-
|
|
183
|
-
if (semanticResult) {
|
|
184
|
-
logger.info(`[SkillRegistry] Semantic match: ${semanticResult.skill.id} (${semanticResult.confidence}%)`);
|
|
185
|
-
return { skill: semanticResult.skill, confidence: semanticResult.confidence, source: 'semantic' };
|
|
186
|
-
}
|
|
187
|
-
} catch (err) {
|
|
188
|
-
logger.warn(`[SkillRegistry] Semantic matching failed, falling back to keyword matching: ${err}`);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Fall back to keyword matching
|
|
193
|
-
const kwSkill = await this.matchKeywords(prompt, keywords, context);
|
|
194
|
-
if (kwSkill) {
|
|
195
|
-
// Keyword matching has no real confidence; assign a conservative 60%
|
|
196
|
-
return { skill: kwSkill, confidence: 60, source: 'keyword' };
|
|
197
|
-
}
|
|
198
|
-
return null;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Keyword-based matching (fallback method)
|
|
203
|
-
* Supports fallback to description-based substring matching when keywords are empty
|
|
204
|
-
*/
|
|
205
|
-
private async matchKeywords(
|
|
206
|
-
prompt: string,
|
|
207
|
-
keywords: string[] = [],
|
|
208
|
-
context?: { recentFiles?: string[] }
|
|
209
|
-
): Promise<Skill | null> {
|
|
210
|
-
const promptLower = prompt.toLowerCase();
|
|
211
|
-
const extraLower = keywords.map(k => k.toLowerCase());
|
|
212
|
-
|
|
213
|
-
let bestSkill: Skill | null = null;
|
|
214
|
-
let bestScore = 0;
|
|
215
|
-
let bestCandidate: Skill | null = null;
|
|
216
|
-
let bestCandidateScore = 0;
|
|
217
|
-
|
|
218
|
-
for (const skill of this.skills.values()) {
|
|
219
|
-
let score = 0;
|
|
220
|
-
|
|
221
|
-
// If skill has keywords, use keyword matching
|
|
222
|
-
if (skill.keywords.length > 0) {
|
|
223
|
-
for (const kw of skill.keywords) {
|
|
224
|
-
const kwLower = kw.toLowerCase();
|
|
225
|
-
|
|
226
|
-
// Check if keyword appears in prompt or intent keywords
|
|
227
|
-
if (this.matchKeywordFlexible(promptLower, kwLower)) {
|
|
228
|
-
score += 1;
|
|
229
|
-
}
|
|
230
|
-
if (extraLower.some(ek => this.matchKeywordFlexible(ek, kwLower))) {
|
|
231
|
-
score += 1;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
} else if (skill.description) {
|
|
235
|
-
// Fallback path 1: Use description substring matching when keywords are empty
|
|
236
|
-
const descLower = skill.description.toLowerCase();
|
|
237
|
-
if (descLower.includes(promptLower) || promptLower.includes(descLower)) {
|
|
238
|
-
score = 1; // Give a base score for description match
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
// Fallback path 2: If no keywords and no description, score remains 0
|
|
242
|
-
// This allows SemanticSkillMatcher to take over
|
|
243
|
-
|
|
244
|
-
// Track best candidate regardless of threshold
|
|
245
|
-
if (score > bestCandidateScore) {
|
|
246
|
-
bestCandidateScore = score;
|
|
247
|
-
bestCandidate = skill;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// Official skills get priority: require 1+ match, user skills require 2+ matches
|
|
251
|
-
const threshold = skill.isOfficial ? 1 : 2;
|
|
252
|
-
|
|
253
|
-
if (score >= threshold && score > bestScore) {
|
|
254
|
-
bestScore = score;
|
|
255
|
-
bestSkill = skill;
|
|
256
|
-
} else if (
|
|
257
|
-
score === bestScore &&
|
|
258
|
-
score >= threshold &&
|
|
259
|
-
skill.isOfficial &&
|
|
260
|
-
!bestSkill?.isOfficial
|
|
261
|
-
) {
|
|
262
|
-
// Tie-break: prefer official skill when both meet threshold
|
|
263
|
-
bestSkill = skill;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (bestSkill) {
|
|
268
|
-
logger.info(`[SkillRegistry] Keyword match: ${bestSkill.id} (score: ${bestScore})`);
|
|
269
|
-
} else {
|
|
270
|
-
logger.debug(`[SkillRegistry] Best keyword candidate: ${bestCandidate?.id ?? 'none'} (score: ${bestCandidateScore})`);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return bestSkill;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Flexible keyword matching with word boundary for English, substring for Chinese
|
|
278
|
-
*/
|
|
279
|
-
private matchKeywordFlexible(text: string, keyword: string): boolean {
|
|
280
|
-
// For Chinese or multi-word keywords, use simple includes
|
|
281
|
-
if (/[一-龥]/.test(keyword) || keyword.includes(' ')) {
|
|
282
|
-
return text.includes(keyword);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// For single English words, require word boundaries to avoid false positives
|
|
286
|
-
// e.g., "test" won't match "latest"
|
|
287
|
-
const regex = new RegExp(`\\b${keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`);
|
|
288
|
-
return regex.test(text);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Match with full result details (for debugging/logging)
|
|
293
|
-
*/
|
|
294
|
-
async matchWithDetails(prompt: string, keywords: string[] = [], context?: { recentFiles?: string[] }) {
|
|
295
|
-
const promptLower = prompt.toLowerCase();
|
|
296
|
-
const extraLower = keywords.map(k => k.toLowerCase());
|
|
297
|
-
|
|
298
|
-
const results = [];
|
|
299
|
-
for (const skill of this.skills.values()) {
|
|
300
|
-
let score = 0;
|
|
301
|
-
const matchedKeywords: string[] = [];
|
|
302
|
-
|
|
303
|
-
for (const kw of skill.keywords) {
|
|
304
|
-
const kwLower = kw.toLowerCase();
|
|
305
|
-
|
|
306
|
-
if (this.matchKeywordFlexible(promptLower, kwLower)) {
|
|
307
|
-
score += 1;
|
|
308
|
-
matchedKeywords.push(kw);
|
|
309
|
-
}
|
|
310
|
-
if (extraLower.some(ek => this.matchKeywordFlexible(ek, kwLower))) {
|
|
311
|
-
score += 1;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if (score >= 1) {
|
|
316
|
-
results.push({
|
|
317
|
-
skill,
|
|
318
|
-
confidence: Math.min(100, score * 20), // Simple scoring: 1 match = 20%, 5 matches = 100%
|
|
319
|
-
matchedKeywords,
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
results.sort((a, b) => b.confidence - a.confidence);
|
|
325
|
-
return results;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/** Return all loaded skills */
|
|
329
|
-
getAll(): Skill[] {
|
|
330
|
-
return Array.from(this.skills.values());
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/** Get a skill by ID */
|
|
334
|
-
get(id: string): Skill | undefined {
|
|
335
|
-
return this.skills.get(id);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Get skill manifest (id + description + keywords) for Agent pre-declaration
|
|
340
|
-
*/
|
|
341
|
-
getManifest(): Array<{ id: string; name: string; description: string; keywords: string[] }> {
|
|
342
|
-
return this.getAll().map(skill => ({
|
|
343
|
-
id: skill.id,
|
|
344
|
-
name: skill.name,
|
|
345
|
-
description: skill.description || '',
|
|
346
|
-
keywords: skill.keywords,
|
|
347
|
-
}));
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/** Re-scan the skills directory */
|
|
351
|
-
reload(): void {
|
|
352
|
-
this.skills.clear();
|
|
353
|
-
this.scan();
|
|
354
|
-
}
|
|
355
|
-
}
|