claude-code-workflow 6.1.4 → 6.2.2
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/.claude/CLAUDE.md +10 -0
- package/.claude/agents/action-planning-agent.md +857 -778
- package/.claude/agents/cli-execution-agent.md +266 -269
- package/.claude/agents/cli-explore-agent.md +2 -2
- package/.claude/agents/cli-lite-planning-agent.md +142 -92
- package/.claude/agents/cli-planning-agent.md +4 -4
- package/.claude/agents/code-developer.md +7 -6
- package/.claude/agents/conceptual-planning-agent.md +2 -2
- package/.claude/agents/context-search-agent.md +31 -32
- package/.claude/agents/doc-generator.md +4 -4
- package/.claude/agents/memory-bridge.md +93 -93
- package/.claude/agents/test-context-search-agent.md +8 -7
- package/.claude/agents/test-fix-agent.md +7 -6
- package/.claude/commands/clean.md +516 -0
- package/.claude/commands/memory/compact.md +383 -0
- package/.claude/commands/memory/docs-full-cli.md +471 -471
- package/.claude/commands/memory/docs-related-cli.md +386 -386
- package/.claude/commands/memory/docs.md +615 -615
- package/.claude/commands/memory/load.md +5 -5
- package/.claude/commands/memory/tech-research-rules.md +310 -0
- package/.claude/commands/memory/update-full.md +332 -332
- package/.claude/commands/memory/workflow-skill-memory.md +4 -4
- package/.claude/commands/task/create.md +151 -151
- package/.claude/commands/version.md +254 -254
- package/.claude/commands/workflow/brainstorm/api-designer.md +587 -585
- package/.claude/commands/workflow/brainstorm/artifacts.md +1 -0
- package/.claude/commands/workflow/brainstorm/auto-parallel.md +443 -443
- package/.claude/commands/workflow/brainstorm/data-architect.md +220 -220
- package/.claude/commands/workflow/brainstorm/product-manager.md +200 -200
- package/.claude/commands/workflow/brainstorm/product-owner.md +200 -200
- package/.claude/commands/workflow/brainstorm/scrum-master.md +200 -200
- package/.claude/commands/workflow/brainstorm/subject-matter-expert.md +200 -200
- package/.claude/commands/workflow/brainstorm/system-architect.md +389 -387
- package/.claude/commands/workflow/brainstorm/ui-designer.md +221 -221
- package/.claude/commands/workflow/brainstorm/ux-expert.md +221 -221
- package/.claude/commands/workflow/debug.md +321 -0
- package/.claude/commands/workflow/execute.md +13 -0
- package/.claude/commands/workflow/init.md +165 -164
- package/.claude/commands/workflow/lite-execute.md +119 -13
- package/.claude/commands/workflow/lite-fix.md +623 -621
- package/.claude/commands/workflow/lite-plan.md +610 -592
- package/.claude/commands/workflow/plan.md +5 -5
- package/.claude/commands/workflow/review-module-cycle.md +2 -0
- package/.claude/commands/workflow/review-session-cycle.md +2 -0
- package/.claude/commands/workflow/review.md +297 -291
- package/.claude/commands/workflow/session/complete.md +153 -500
- package/.claude/commands/workflow/session/list.md +95 -95
- package/.claude/commands/workflow/session/resume.md +60 -60
- package/.claude/commands/workflow/session/start.md +199 -199
- package/.claude/commands/workflow/tdd-plan.md +3 -3
- package/.claude/commands/workflow/tdd-verify.md +23 -9
- package/.claude/commands/workflow/test-cycle-execute.md +2 -0
- package/.claude/commands/workflow/test-fix-gen.md +699 -699
- package/.claude/commands/workflow/tools/conflict-resolution.md +104 -18
- package/.claude/commands/workflow/tools/context-gather.md +436 -434
- package/.claude/commands/workflow/tools/task-generate-agent.md +490 -291
- package/.claude/commands/workflow/tools/task-generate-tdd.md +18 -10
- package/.claude/commands/workflow/tools/test-concept-enhanced.md +2 -1
- package/.claude/commands/workflow/tools/test-context-gather.md +1 -0
- package/.claude/commands/workflow/tools/test-task-generate.md +1 -0
- package/.claude/commands/workflow/ui-design/import-from-code.md +9 -6
- package/.claude/skills/command-guide/SKILL.md +5 -5
- package/.claude/skills/command-guide/index/all-commands.json +1 -1
- package/.claude/skills/command-guide/index/by-category.json +1 -1
- package/.claude/skills/command-guide/index/by-use-case.json +1 -1
- package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +857 -778
- package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +266 -269
- package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +2 -2
- package/.claude/skills/command-guide/reference/agents/cli-lite-planning-agent.md +142 -92
- package/.claude/skills/command-guide/reference/agents/cli-planning-agent.md +4 -4
- package/.claude/skills/command-guide/reference/agents/code-developer.md +7 -6
- package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +2 -2
- package/.claude/skills/command-guide/reference/agents/context-search-agent.md +31 -32
- package/.claude/skills/command-guide/reference/agents/doc-generator.md +4 -4
- package/.claude/skills/command-guide/reference/agents/memory-bridge.md +93 -93
- package/.claude/skills/command-guide/reference/agents/test-context-search-agent.md +8 -7
- package/.claude/skills/command-guide/reference/agents/test-fix-agent.md +7 -6
- package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +471 -471
- package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +386 -386
- package/.claude/skills/command-guide/reference/commands/memory/docs.md +17 -16
- package/.claude/skills/command-guide/reference/commands/memory/load.md +5 -5
- package/.claude/skills/command-guide/reference/commands/memory/tech-research.md +194 -357
- package/.claude/skills/command-guide/reference/commands/memory/update-full.md +332 -332
- package/.claude/skills/command-guide/reference/commands/memory/workflow-skill-memory.md +4 -4
- package/.claude/skills/command-guide/reference/commands/task/create.md +151 -151
- package/.claude/skills/command-guide/reference/commands/version.md +254 -254
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/api-designer.md +585 -585
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +443 -443
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/data-architect.md +220 -220
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-manager.md +200 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-owner.md +200 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/scrum-master.md +200 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/subject-matter-expert.md +200 -200
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/system-architect.md +387 -387
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ui-designer.md +221 -221
- package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ux-expert.md +221 -221
- package/.claude/skills/command-guide/reference/commands/workflow/execute.md +25 -20
- package/.claude/skills/command-guide/reference/commands/workflow/init.md +164 -164
- package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +748 -686
- package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +664 -621
- package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +645 -592
- package/.claude/skills/command-guide/reference/commands/workflow/plan.md +5 -5
- package/.claude/skills/command-guide/reference/commands/workflow/review.md +25 -18
- package/.claude/skills/command-guide/reference/commands/workflow/session/complete.md +547 -500
- package/.claude/skills/command-guide/reference/commands/workflow/session/list.md +45 -27
- package/.claude/skills/command-guide/reference/commands/workflow/session/resume.md +35 -19
- package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +90 -33
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +3 -3
- package/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md +23 -9
- package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +699 -699
- package/.claude/skills/command-guide/reference/commands/workflow/tools/conflict-resolution.md +103 -17
- package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +434 -434
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +487 -291
- package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +17 -10
- package/.claude/skills/command-guide/reference/commands/workflow/tools/test-concept-enhanced.md +1 -1
- package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +6 -6
- package/.claude/workflows/chinese-response.md +38 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-api.txt +122 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-components.txt +122 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-config.txt +89 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-core.txt +60 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-patterns.txt +70 -0
- package/.claude/workflows/cli-templates/prompts/rules/rule-testing.txt +81 -0
- package/.claude/workflows/cli-templates/prompts/rules/tech-rules-agent-prompt.txt +89 -0
- package/.claude/workflows/cli-templates/prompts/workflow/gemini-solution-design.txt +131 -131
- package/.claude/workflows/cli-templates/prompts/workflow/skill-conflict-patterns.txt +5 -9
- package/.claude/workflows/cli-templates/prompts/workflow/skill-lessons-learned.txt +5 -9
- package/.claude/workflows/cli-templates/protocols/analysis-protocol.md +112 -0
- package/.claude/workflows/cli-templates/protocols/write-protocol.md +201 -0
- package/.claude/workflows/cli-templates/schemas/conflict-resolution-schema.json +137 -0
- package/.claude/workflows/cli-templates/schemas/debug-log-json-schema.json +127 -0
- package/.claude/workflows/cli-templates/schemas/fix-plan-json-schema.json +25 -0
- package/.claude/workflows/cli-templates/schemas/plan-json-schema.json +25 -0
- package/.claude/workflows/cli-tools-usage.md +526 -0
- package/{CLAUDE.md → .claude/workflows/coding-philosophy.md} +24 -45
- package/.claude/workflows/context-tools.md +84 -0
- package/.claude/workflows/file-modification.md +64 -0
- package/.claude/workflows/tool-strategy.md +216 -79
- package/.claude/workflows/windows-platform.md +16 -0
- package/.claude/workflows/workflow-architecture.md +942 -942
- package/.codex/AGENTS.md +63 -330
- package/.codex/prompts/debug.md +318 -0
- package/.codex/prompts/execute.md +273 -0
- package/.codex/prompts/lite-execute.md +164 -0
- package/.codex/prompts/lite-plan.md +469 -0
- package/.codex/prompts.zip +0 -0
- package/.gemini/GEMINI.md +25 -164
- package/.qwen/QWEN.md +0 -139
- package/README.md +29 -9
- package/ccw/README.md +30 -6
- package/ccw/bin/ccw-mcp.js +7 -0
- package/ccw/bin/ccw.js +9 -9
- package/ccw/package.json +65 -47
- package/ccw/src/.workflow/.cli-history/history.db +0 -0
- package/ccw/src/.workflow/.cli-history/history.db-shm +0 -0
- package/ccw/src/.workflow/.cli-history/history.db-wal +0 -0
- package/ccw/src/cli.ts +244 -0
- package/ccw/src/commands/cli.ts +740 -0
- package/ccw/src/commands/core-memory.ts +770 -0
- package/ccw/src/commands/hook.ts +315 -0
- package/ccw/src/commands/install.ts +519 -0
- package/ccw/src/commands/{list.js → list.ts} +1 -1
- package/ccw/src/commands/memory.ts +1090 -0
- package/ccw/src/commands/{serve.js → serve.ts} +14 -5
- package/ccw/src/commands/session-path-resolver.ts +372 -0
- package/ccw/src/commands/session.ts +1141 -0
- package/ccw/src/commands/{stop.js → stop.ts} +16 -6
- package/ccw/src/commands/tool.ts +201 -0
- package/ccw/src/commands/{uninstall.js → uninstall.ts} +89 -40
- package/ccw/src/commands/{upgrade.js → upgrade.ts} +68 -23
- package/ccw/src/commands/{view.js → view.ts} +22 -8
- package/ccw/src/config/storage-paths.ts +670 -0
- package/ccw/src/core/cache-manager.ts +294 -0
- package/ccw/src/core/claude-freshness.ts +319 -0
- package/ccw/src/core/core-memory-store.ts +1528 -0
- package/ccw/src/core/{dashboard-generator-patch.js → dashboard-generator-patch.ts} +18 -0
- package/ccw/src/core/{dashboard-generator.js → dashboard-generator.ts} +69 -12
- package/ccw/src/core/data-aggregator.ts +584 -0
- package/ccw/src/core/history-importer.ts +625 -0
- package/ccw/src/core/{lite-scanner.js → lite-scanner-complete.ts} +162 -66
- package/ccw/src/core/lite-scanner.ts +469 -0
- package/ccw/src/core/{manifest.js → manifest.ts} +104 -34
- package/ccw/src/core/memory-embedder-bridge.ts +262 -0
- package/ccw/src/core/memory-store.ts +978 -0
- package/ccw/src/core/routes/ccw-routes.ts +96 -0
- package/ccw/src/core/routes/claude-routes.ts +1183 -0
- package/ccw/src/core/routes/cli-routes.ts +561 -0
- package/ccw/src/core/routes/codexlens-routes.ts +806 -0
- package/ccw/src/core/routes/core-memory-routes.ts +605 -0
- package/ccw/src/core/routes/files-routes.ts +428 -0
- package/ccw/src/core/routes/graph-routes.md +164 -0
- package/ccw/src/core/routes/graph-routes.ts +626 -0
- package/ccw/src/core/routes/help-routes.ts +308 -0
- package/ccw/src/core/routes/hooks-routes.ts +405 -0
- package/ccw/src/core/routes/mcp-routes.ts +1271 -0
- package/ccw/src/core/routes/mcp-routes.ts.backup +550 -0
- package/ccw/src/core/routes/mcp-templates-db.ts +268 -0
- package/ccw/src/core/routes/memory-routes.ts +1206 -0
- package/ccw/src/core/routes/rules-routes.ts +526 -0
- package/ccw/src/core/routes/session-routes.ts +467 -0
- package/ccw/src/core/routes/skills-routes.ts +599 -0
- package/ccw/src/core/routes/status-routes.ts +57 -0
- package/ccw/src/core/routes/system-routes.ts +427 -0
- package/ccw/src/core/server.ts +431 -0
- package/ccw/src/core/session-clustering-service.ts +1258 -0
- package/ccw/src/core/session-scanner.ts +283 -0
- package/ccw/src/core/websocket.ts +190 -0
- package/ccw/src/{index.js → index.ts} +1 -0
- package/ccw/src/mcp-server/index.ts +186 -0
- package/ccw/src/templates/assets/css/github-dark.min.css +10 -0
- package/ccw/src/templates/assets/css/github.min.css +10 -0
- package/ccw/src/templates/assets/js/cytoscape.min.js +32 -0
- package/ccw/src/templates/assets/js/d3.min.js +2 -0
- package/ccw/src/templates/assets/js/highlight.min.js +1244 -0
- package/ccw/src/templates/assets/js/lucide.min.js +12 -0
- package/ccw/src/templates/assets/js/marked.min.js +69 -0
- package/ccw/src/templates/assets/js/tailwind.js +83 -0
- package/ccw/src/templates/dashboard-css/01-base.css +11 -0
- package/ccw/src/templates/dashboard-css/02-session.css +22 -0
- package/ccw/src/templates/dashboard-css/04-lite-tasks.css +10 -0
- package/ccw/src/templates/dashboard-css/06-cards.css +10 -4
- package/ccw/src/templates/dashboard-css/07-managers.css +1178 -7
- package/ccw/src/templates/dashboard-css/09-explorer.css +23 -12
- package/ccw/src/templates/dashboard-css/10-cli-status.css +337 -0
- package/ccw/src/templates/dashboard-css/11-cli-history.css +271 -0
- package/ccw/src/templates/dashboard-css/12-cli-legacy.css +796 -0
- package/ccw/src/templates/dashboard-css/13-cli-ccw.css +199 -0
- package/ccw/src/templates/dashboard-css/14-cli-modals.css +258 -0
- package/ccw/src/templates/dashboard-css/15-cli-endpoints.css +305 -0
- package/ccw/src/templates/dashboard-css/16-cli-session.css +241 -0
- package/ccw/src/templates/dashboard-css/17-cli-conversation.css +283 -0
- package/ccw/src/templates/dashboard-css/18-cli-settings.css +160 -0
- package/ccw/src/templates/dashboard-css/19-cli-native-session.css +496 -0
- package/ccw/src/templates/dashboard-css/20-cli-taskqueue.css +188 -0
- package/ccw/src/templates/dashboard-css/21-cli-toolmgmt.css +310 -0
- package/ccw/src/templates/dashboard-css/22-cli-semantic.css +240 -0
- package/ccw/src/templates/dashboard-css/23-memory.css +2390 -0
- package/ccw/src/templates/dashboard-css/24-prompt-history.css +1089 -0
- package/ccw/src/templates/dashboard-css/25-skills-rules.css +326 -0
- package/ccw/src/templates/dashboard-css/26-claude-manager.css +908 -0
- package/ccw/src/templates/dashboard-css/27-graph-explorer.css +1678 -0
- package/ccw/src/templates/dashboard-css/28-mcp-manager.css +748 -0
- package/ccw/src/templates/dashboard-css/29-help.css +264 -0
- package/ccw/src/templates/dashboard-css/30-core-memory.css +1700 -0
- package/ccw/src/templates/dashboard-js/api.js +162 -142
- package/ccw/src/templates/dashboard-js/components/carousel.js +4 -4
- package/ccw/src/templates/dashboard-js/components/cli-history.js +876 -0
- package/ccw/src/templates/dashboard-js/components/cli-status.js +978 -0
- package/ccw/src/templates/dashboard-js/components/global-notifications.js +508 -219
- package/ccw/src/templates/dashboard-js/components/hook-manager.js +1277 -282
- package/ccw/src/templates/dashboard-js/components/index-manager.js +302 -0
- package/ccw/src/templates/dashboard-js/components/mcp-manager.js +718 -27
- package/ccw/src/templates/dashboard-js/components/modals.js +66 -0
- package/ccw/src/templates/dashboard-js/components/navigation.js +80 -12
- package/ccw/src/templates/dashboard-js/components/notifications.js +758 -194
- package/ccw/src/templates/dashboard-js/components/storage-manager.js +478 -0
- package/ccw/src/templates/dashboard-js/components/tabs-other.js +157 -6
- package/ccw/src/templates/dashboard-js/components/task-queue-sidebar.js +716 -0
- package/ccw/src/templates/dashboard-js/help-i18n.js +272 -0
- package/ccw/src/templates/dashboard-js/i18n.js +2807 -0
- package/ccw/src/templates/dashboard-js/main.js +15 -0
- package/ccw/src/templates/dashboard-js/state.js +243 -42
- package/ccw/src/templates/dashboard-js/utils.js +47 -1
- package/ccw/src/templates/dashboard-js/views/claude-manager.js +912 -0
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +2272 -0
- package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +964 -0
- package/ccw/src/templates/dashboard-js/views/core-memory-clusters.js +503 -0
- package/ccw/src/templates/dashboard-js/views/core-memory.js +782 -0
- package/ccw/src/templates/dashboard-js/views/explorer.js +888 -852
- package/ccw/src/templates/dashboard-js/views/graph-explorer.js +1157 -0
- package/ccw/src/templates/dashboard-js/views/help.js +856 -0
- package/ccw/src/templates/dashboard-js/views/history.js +337 -0
- package/ccw/src/templates/dashboard-js/views/home.js +61 -15
- package/ccw/src/templates/dashboard-js/views/hook-manager.js +311 -43
- package/ccw/src/templates/dashboard-js/views/lite-tasks.js +204 -28
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js +2187 -411
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js.backup +1729 -0
- package/ccw/src/templates/dashboard-js/views/mcp-manager.js.new +928 -0
- package/ccw/src/templates/dashboard-js/views/memory.js +1221 -0
- package/ccw/src/templates/dashboard-js/views/prompt-history.js +713 -0
- package/ccw/src/templates/dashboard-js/views/rules-manager.js +828 -0
- package/ccw/src/templates/dashboard-js/views/session-detail.js +54 -53
- package/ccw/src/templates/dashboard-js/views/skills-manager.js +819 -0
- package/ccw/src/templates/dashboard.html +185 -85
- package/ccw/src/templates/hooks-config-example.json +60 -0
- package/ccw/src/tools/classify-folders.ts +245 -0
- package/ccw/src/tools/cli-config-manager.ts +268 -0
- package/ccw/src/tools/cli-executor.ts +2014 -0
- package/ccw/src/tools/cli-history-store.ts +1195 -0
- package/ccw/src/tools/codex-lens.ts +1141 -0
- package/ccw/src/tools/{convert-tokens-to-css.js → convert-tokens-to-css.ts} +73 -23
- package/ccw/src/tools/core-memory.ts +444 -0
- package/ccw/src/tools/detect-changed-modules.ts +325 -0
- package/ccw/src/tools/{discover-design-files.js → discover-design-files.ts} +74 -24
- package/ccw/src/tools/edit-file.ts +568 -0
- package/ccw/src/tools/{generate-module-docs.js → generate-module-docs.ts} +207 -185
- package/ccw/src/tools/{get-modules-by-depth.js → get-modules-by-depth.ts} +120 -79
- package/ccw/src/tools/index.ts +370 -0
- package/ccw/src/tools/native-session-discovery.ts +795 -0
- package/ccw/src/tools/notifier.ts +129 -0
- package/ccw/src/tools/read-file.ts +410 -0
- package/ccw/src/tools/resume-strategy.ts +345 -0
- package/ccw/src/tools/session-content-parser.ts +619 -0
- package/ccw/src/tools/session-manager.ts +1026 -0
- package/ccw/src/tools/smart-context.ts +228 -0
- package/ccw/src/tools/smart-search.ts +2065 -0
- package/ccw/src/tools/smart-search.ts.backup +1233 -0
- package/ccw/src/tools/storage-manager.ts +455 -0
- package/ccw/src/tools/write-file.ts +222 -0
- package/ccw/src/types/config.ts +11 -0
- package/ccw/src/types/index.ts +3 -0
- package/ccw/src/types/session.ts +25 -0
- package/ccw/src/types/tool.ts +41 -0
- package/ccw/src/utils/{browser-launcher.js → browser-launcher.ts} +10 -8
- package/ccw/src/utils/file-utils.ts +48 -0
- package/ccw/src/utils/{path-resolver.js → path-resolver.ts} +114 -78
- package/ccw/src/utils/path-validator.ts +153 -0
- package/ccw/src/utils/{ui.js → ui.ts} +32 -25
- package/codex-lens/pyproject.toml +48 -0
- package/codex-lens/src/codexlens/.workflow/.cli-history/history.db +0 -0
- package/codex-lens/src/codexlens/__init__.py +28 -0
- package/codex-lens/src/codexlens/__main__.py +14 -0
- package/codex-lens/src/codexlens/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/__main__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/entities.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/errors.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__init__.py +27 -0
- package/codex-lens/src/codexlens/cli/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/commands.py +1931 -0
- package/codex-lens/src/codexlens/cli/embedding_manager.py +620 -0
- package/codex-lens/src/codexlens/cli/model_manager.py +289 -0
- package/codex-lens/src/codexlens/cli/output.py +124 -0
- package/codex-lens/src/codexlens/config.py +201 -0
- package/codex-lens/src/codexlens/entities.py +121 -0
- package/codex-lens/src/codexlens/errors.py +55 -0
- package/codex-lens/src/codexlens/indexing/README.md +77 -0
- package/codex-lens/src/codexlens/indexing/__init__.py +4 -0
- package/codex-lens/src/codexlens/indexing/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/indexing/__pycache__/symbol_extractor.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/indexing/symbol_extractor.py +243 -0
- package/codex-lens/src/codexlens/parsers/__init__.py +8 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/encoding.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/tokenizer.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/encoding.py +202 -0
- package/codex-lens/src/codexlens/parsers/factory.py +256 -0
- package/codex-lens/src/codexlens/parsers/tokenizer.py +98 -0
- package/codex-lens/src/codexlens/parsers/treesitter_parser.py +335 -0
- package/codex-lens/src/codexlens/search/__init__.py +15 -0
- package/codex-lens/src/codexlens/search/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/enrichment.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/query_parser.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/chain_search.py +647 -0
- package/codex-lens/src/codexlens/search/enrichment.py +150 -0
- package/codex-lens/src/codexlens/search/hybrid_search.py +313 -0
- package/codex-lens/src/codexlens/search/query_parser.py +242 -0
- package/codex-lens/src/codexlens/search/ranking.py +274 -0
- package/codex-lens/src/codexlens/semantic/__init__.py +39 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/code_extractor.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/graph_analyzer.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/llm_enhancer.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/ann_index.py +414 -0
- package/codex-lens/src/codexlens/semantic/chunker.py +448 -0
- package/codex-lens/src/codexlens/semantic/code_extractor.py +274 -0
- package/codex-lens/src/codexlens/semantic/embedder.py +185 -0
- package/codex-lens/src/codexlens/semantic/vector_store.py +955 -0
- package/codex-lens/src/codexlens/storage/__init__.py +29 -0
- package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/file_cache.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/migration_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/registry.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/sqlite_utils.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/dir_index.py +1850 -0
- package/codex-lens/src/codexlens/storage/file_cache.py +32 -0
- package/codex-lens/src/codexlens/storage/index_tree.py +776 -0
- package/codex-lens/src/codexlens/storage/migration_manager.py +154 -0
- package/codex-lens/src/codexlens/storage/migrations/__init__.py +1 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_001_normalize_keywords.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_002_add_token_metadata.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_003_code_relationships.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_004_dual_fts.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_005_cleanup_unused_fields.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_001_normalize_keywords.py +123 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_002_add_token_metadata.py +48 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_004_dual_fts.py +232 -0
- package/codex-lens/src/codexlens/storage/migrations/migration_005_cleanup_unused_fields.py +196 -0
- package/codex-lens/src/codexlens/storage/path_mapper.py +274 -0
- package/codex-lens/src/codexlens/storage/registry.py +670 -0
- package/codex-lens/src/codexlens/storage/sqlite_store.py +576 -0
- package/codex-lens/src/codexlens/storage/sqlite_utils.py +64 -0
- package/package.json +4 -1
- package/.claude/commands/memory/tech-research.md +0 -477
- package/.claude/scripts/classify-folders.sh +0 -39
- package/.claude/scripts/convert_tokens_to_css.sh +0 -229
- package/.claude/scripts/detect_changed_modules.sh +0 -161
- package/.claude/scripts/discover-design-files.sh +0 -87
- package/.claude/scripts/extract-animations.js +0 -243
- package/.claude/scripts/extract-computed-styles.js +0 -118
- package/.claude/scripts/extract-layout-structure.js +0 -411
- package/.claude/scripts/generate_module_docs.sh +0 -717
- package/.claude/scripts/get_modules_by_depth.sh +0 -170
- package/.claude/scripts/ui-generate-preview.sh +0 -395
- package/.claude/scripts/ui-instantiate-prototypes.sh +0 -815
- package/.claude/scripts/update_module_claude.sh +0 -337
- package/.claude/workflows/context-search-strategy.md +0 -77
- package/.claude/workflows/intelligent-tools-strategy.md +0 -662
- package/ccw/src/cli.js +0 -119
- package/ccw/src/commands/install.js +0 -324
- package/ccw/src/commands/tool.js +0 -138
- package/ccw/src/core/data-aggregator.js +0 -409
- package/ccw/src/core/server.js +0 -2063
- package/ccw/src/core/session-scanner.js +0 -235
- package/ccw/src/tools/classify-folders.js +0 -204
- package/ccw/src/tools/detect-changed-modules.js +0 -288
- package/ccw/src/tools/edit-file.js +0 -266
- package/ccw/src/tools/index.js +0 -176
- package/ccw/src/utils/file-utils.js +0 -48
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* Skills Routes Module
|
|
4
|
+
* Handles all Skills-related API endpoints
|
|
5
|
+
*/
|
|
6
|
+
import type { IncomingMessage, ServerResponse } from 'http';
|
|
7
|
+
import { readFileSync, existsSync, readdirSync, statSync, unlinkSync, promises as fsPromises } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { homedir } from 'os';
|
|
10
|
+
import { executeCliTool } from '../../tools/cli-executor.js';
|
|
11
|
+
|
|
12
|
+
export interface RouteContext {
|
|
13
|
+
pathname: string;
|
|
14
|
+
url: URL;
|
|
15
|
+
req: IncomingMessage;
|
|
16
|
+
res: ServerResponse;
|
|
17
|
+
initialPath: string;
|
|
18
|
+
handlePostRequest: (req: IncomingMessage, res: ServerResponse, handler: (body: unknown) => Promise<any>) => void;
|
|
19
|
+
broadcastToClients: (data: unknown) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ========== Skills Helper Functions ==========
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Parse skill frontmatter (YAML header)
|
|
26
|
+
* @param {string} content - Skill file content
|
|
27
|
+
* @returns {Object} Parsed frontmatter and content
|
|
28
|
+
*/
|
|
29
|
+
function parseSkillFrontmatter(content) {
|
|
30
|
+
const result = {
|
|
31
|
+
name: '',
|
|
32
|
+
description: '',
|
|
33
|
+
version: null,
|
|
34
|
+
allowedTools: [],
|
|
35
|
+
content: ''
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Check for YAML frontmatter
|
|
39
|
+
if (content.startsWith('---')) {
|
|
40
|
+
const endIndex = content.indexOf('---', 3);
|
|
41
|
+
if (endIndex > 0) {
|
|
42
|
+
const frontmatter = content.substring(3, endIndex).trim();
|
|
43
|
+
result.content = content.substring(endIndex + 3).trim();
|
|
44
|
+
|
|
45
|
+
// Parse frontmatter lines
|
|
46
|
+
const lines = frontmatter.split('\n');
|
|
47
|
+
for (const line of lines) {
|
|
48
|
+
const colonIndex = line.indexOf(':');
|
|
49
|
+
if (colonIndex > 0) {
|
|
50
|
+
const key = line.substring(0, colonIndex).trim().toLowerCase();
|
|
51
|
+
const value = line.substring(colonIndex + 1).trim();
|
|
52
|
+
|
|
53
|
+
if (key === 'name') {
|
|
54
|
+
result.name = value.replace(/^["']|["']$/g, '');
|
|
55
|
+
} else if (key === 'description') {
|
|
56
|
+
result.description = value.replace(/^["']|["']$/g, '');
|
|
57
|
+
} else if (key === 'version') {
|
|
58
|
+
result.version = value.replace(/^["']|["']$/g, '');
|
|
59
|
+
} else if (key === 'allowed-tools' || key === 'allowedtools') {
|
|
60
|
+
// Parse as comma-separated or YAML array
|
|
61
|
+
result.allowedTools = value.replace(/^\[|\]$/g, '').split(',').map(t => t.trim()).filter(Boolean);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
result.content = content;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get list of supporting files for a skill
|
|
75
|
+
* @param {string} skillDir
|
|
76
|
+
* @returns {string[]}
|
|
77
|
+
*/
|
|
78
|
+
function getSupportingFiles(skillDir) {
|
|
79
|
+
const files = [];
|
|
80
|
+
try {
|
|
81
|
+
const entries = readdirSync(skillDir, { withFileTypes: true });
|
|
82
|
+
for (const entry of entries) {
|
|
83
|
+
if (entry.name !== 'SKILL.md') {
|
|
84
|
+
if (entry.isFile()) {
|
|
85
|
+
files.push(entry.name);
|
|
86
|
+
} else if (entry.isDirectory()) {
|
|
87
|
+
files.push(entry.name + '/');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
} catch (e) {
|
|
92
|
+
// Ignore errors
|
|
93
|
+
}
|
|
94
|
+
return files;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get skills configuration from project and user directories
|
|
99
|
+
* @param {string} projectPath
|
|
100
|
+
* @returns {Object}
|
|
101
|
+
*/
|
|
102
|
+
function getSkillsConfig(projectPath) {
|
|
103
|
+
const result = {
|
|
104
|
+
projectSkills: [],
|
|
105
|
+
userSkills: []
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
// Project skills: .claude/skills/
|
|
110
|
+
const projectSkillsDir = join(projectPath, '.claude', 'skills');
|
|
111
|
+
if (existsSync(projectSkillsDir)) {
|
|
112
|
+
const skills = readdirSync(projectSkillsDir, { withFileTypes: true });
|
|
113
|
+
for (const skill of skills) {
|
|
114
|
+
if (skill.isDirectory()) {
|
|
115
|
+
const skillMdPath = join(projectSkillsDir, skill.name, 'SKILL.md');
|
|
116
|
+
if (existsSync(skillMdPath)) {
|
|
117
|
+
const content = readFileSync(skillMdPath, 'utf8');
|
|
118
|
+
const parsed = parseSkillFrontmatter(content);
|
|
119
|
+
|
|
120
|
+
// Get supporting files
|
|
121
|
+
const skillDir = join(projectSkillsDir, skill.name);
|
|
122
|
+
const supportingFiles = getSupportingFiles(skillDir);
|
|
123
|
+
|
|
124
|
+
result.projectSkills.push({
|
|
125
|
+
name: parsed.name || skill.name,
|
|
126
|
+
description: parsed.description,
|
|
127
|
+
version: parsed.version,
|
|
128
|
+
allowedTools: parsed.allowedTools,
|
|
129
|
+
location: 'project',
|
|
130
|
+
path: skillDir,
|
|
131
|
+
supportingFiles
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// User skills: ~/.claude/skills/
|
|
139
|
+
const userSkillsDir = join(homedir(), '.claude', 'skills');
|
|
140
|
+
if (existsSync(userSkillsDir)) {
|
|
141
|
+
const skills = readdirSync(userSkillsDir, { withFileTypes: true });
|
|
142
|
+
for (const skill of skills) {
|
|
143
|
+
if (skill.isDirectory()) {
|
|
144
|
+
const skillMdPath = join(userSkillsDir, skill.name, 'SKILL.md');
|
|
145
|
+
if (existsSync(skillMdPath)) {
|
|
146
|
+
const content = readFileSync(skillMdPath, 'utf8');
|
|
147
|
+
const parsed = parseSkillFrontmatter(content);
|
|
148
|
+
|
|
149
|
+
// Get supporting files
|
|
150
|
+
const skillDir = join(userSkillsDir, skill.name);
|
|
151
|
+
const supportingFiles = getSupportingFiles(skillDir);
|
|
152
|
+
|
|
153
|
+
result.userSkills.push({
|
|
154
|
+
name: parsed.name || skill.name,
|
|
155
|
+
description: parsed.description,
|
|
156
|
+
version: parsed.version,
|
|
157
|
+
allowedTools: parsed.allowedTools,
|
|
158
|
+
location: 'user',
|
|
159
|
+
path: skillDir,
|
|
160
|
+
supportingFiles
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
} catch (error) {
|
|
167
|
+
console.error('Error reading skills config:', error);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Get single skill detail
|
|
175
|
+
* @param {string} skillName
|
|
176
|
+
* @param {string} location - 'project' or 'user'
|
|
177
|
+
* @param {string} projectPath
|
|
178
|
+
* @returns {Object}
|
|
179
|
+
*/
|
|
180
|
+
function getSkillDetail(skillName, location, projectPath) {
|
|
181
|
+
try {
|
|
182
|
+
const baseDir = location === 'project'
|
|
183
|
+
? join(projectPath, '.claude', 'skills')
|
|
184
|
+
: join(homedir(), '.claude', 'skills');
|
|
185
|
+
|
|
186
|
+
const skillDir = join(baseDir, skillName);
|
|
187
|
+
const skillMdPath = join(skillDir, 'SKILL.md');
|
|
188
|
+
|
|
189
|
+
if (!existsSync(skillMdPath)) {
|
|
190
|
+
return { error: 'Skill not found' };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const content = readFileSync(skillMdPath, 'utf8');
|
|
194
|
+
const parsed = parseSkillFrontmatter(content);
|
|
195
|
+
const supportingFiles = getSupportingFiles(skillDir);
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
skill: {
|
|
199
|
+
name: parsed.name || skillName,
|
|
200
|
+
description: parsed.description,
|
|
201
|
+
version: parsed.version,
|
|
202
|
+
allowedTools: parsed.allowedTools,
|
|
203
|
+
content: parsed.content,
|
|
204
|
+
location,
|
|
205
|
+
path: skillDir,
|
|
206
|
+
supportingFiles
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
} catch (error) {
|
|
210
|
+
return { error: (error as Error).message };
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Delete a skill
|
|
216
|
+
* @param {string} skillName
|
|
217
|
+
* @param {string} location
|
|
218
|
+
* @param {string} projectPath
|
|
219
|
+
* @returns {Object}
|
|
220
|
+
*/
|
|
221
|
+
function deleteSkill(skillName, location, projectPath) {
|
|
222
|
+
try {
|
|
223
|
+
const baseDir = location === 'project'
|
|
224
|
+
? join(projectPath, '.claude', 'skills')
|
|
225
|
+
: join(homedir(), '.claude', 'skills');
|
|
226
|
+
|
|
227
|
+
const skillDir = join(baseDir, skillName);
|
|
228
|
+
|
|
229
|
+
if (!existsSync(skillDir)) {
|
|
230
|
+
return { error: 'Skill not found' };
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Recursively delete directory
|
|
234
|
+
const deleteRecursive = (dirPath) => {
|
|
235
|
+
if (existsSync(dirPath)) {
|
|
236
|
+
readdirSync(dirPath).forEach((file) => {
|
|
237
|
+
const curPath = join(dirPath, file);
|
|
238
|
+
if (statSync(curPath).isDirectory()) {
|
|
239
|
+
deleteRecursive(curPath);
|
|
240
|
+
} else {
|
|
241
|
+
unlinkSync(curPath);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
fsPromises.rmdir(dirPath);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
deleteRecursive(skillDir);
|
|
249
|
+
|
|
250
|
+
return { success: true, skillName, location };
|
|
251
|
+
} catch (error) {
|
|
252
|
+
return { error: (error as Error).message };
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Validate skill folder structure
|
|
258
|
+
* @param {string} folderPath - Path to skill folder
|
|
259
|
+
* @returns {Object} Validation result with skill info
|
|
260
|
+
*/
|
|
261
|
+
function validateSkillFolder(folderPath) {
|
|
262
|
+
const errors = [];
|
|
263
|
+
|
|
264
|
+
// Check if folder exists
|
|
265
|
+
if (!existsSync(folderPath)) {
|
|
266
|
+
return { valid: false, errors: ['Folder does not exist'], skillInfo: null };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Check if it's a directory
|
|
270
|
+
try {
|
|
271
|
+
const stat = statSync(folderPath);
|
|
272
|
+
if (!stat.isDirectory()) {
|
|
273
|
+
return { valid: false, errors: ['Path is not a directory'], skillInfo: null };
|
|
274
|
+
}
|
|
275
|
+
} catch (e) {
|
|
276
|
+
return { valid: false, errors: ['Cannot access folder'], skillInfo: null };
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Check SKILL.md exists
|
|
280
|
+
const skillMdPath = join(folderPath, 'SKILL.md');
|
|
281
|
+
if (!existsSync(skillMdPath)) {
|
|
282
|
+
errors.push('SKILL.md file not found');
|
|
283
|
+
return { valid: false, errors, skillInfo: null };
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Parse and validate frontmatter
|
|
287
|
+
try {
|
|
288
|
+
const content = readFileSync(skillMdPath, 'utf8');
|
|
289
|
+
const parsed = parseSkillFrontmatter(content);
|
|
290
|
+
|
|
291
|
+
if (!parsed.name) {
|
|
292
|
+
errors.push('name field is required in frontmatter');
|
|
293
|
+
}
|
|
294
|
+
if (!parsed.description) {
|
|
295
|
+
errors.push('description field is required in frontmatter');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Get supporting files
|
|
299
|
+
const supportingFiles = getSupportingFiles(folderPath);
|
|
300
|
+
|
|
301
|
+
// If validation passed
|
|
302
|
+
if (errors.length === 0) {
|
|
303
|
+
return {
|
|
304
|
+
valid: true,
|
|
305
|
+
errors: [],
|
|
306
|
+
skillInfo: {
|
|
307
|
+
name: parsed.name,
|
|
308
|
+
description: parsed.description,
|
|
309
|
+
version: parsed.version,
|
|
310
|
+
allowedTools: parsed.allowedTools,
|
|
311
|
+
supportingFiles
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
} else {
|
|
315
|
+
return { valid: false, errors, skillInfo: null };
|
|
316
|
+
}
|
|
317
|
+
} catch (error) {
|
|
318
|
+
return { valid: false, errors: ['Failed to parse SKILL.md: ' + (error as Error).message], skillInfo: null };
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Recursively copy directory
|
|
324
|
+
* @param {string} source - Source directory path
|
|
325
|
+
* @param {string} target - Target directory path
|
|
326
|
+
*/
|
|
327
|
+
async function copyDirectoryRecursive(source, target) {
|
|
328
|
+
await fsPromises.mkdir(target, { recursive: true });
|
|
329
|
+
|
|
330
|
+
const entries = await fsPromises.readdir(source, { withFileTypes: true });
|
|
331
|
+
|
|
332
|
+
for (const entry of entries) {
|
|
333
|
+
const sourcePath = join(source, entry.name);
|
|
334
|
+
const targetPath = join(target, entry.name);
|
|
335
|
+
|
|
336
|
+
if (entry.isDirectory()) {
|
|
337
|
+
await copyDirectoryRecursive(sourcePath, targetPath);
|
|
338
|
+
} else {
|
|
339
|
+
await fsPromises.copyFile(sourcePath, targetPath);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Import skill from folder
|
|
346
|
+
* @param {string} sourcePath - Source skill folder path
|
|
347
|
+
* @param {string} location - 'project' or 'user'
|
|
348
|
+
* @param {string} projectPath - Project root path
|
|
349
|
+
* @param {string} customName - Optional custom name for skill
|
|
350
|
+
* @returns {Object}
|
|
351
|
+
*/
|
|
352
|
+
async function importSkill(sourcePath, location, projectPath, customName) {
|
|
353
|
+
try {
|
|
354
|
+
// Validate source folder
|
|
355
|
+
const validation = validateSkillFolder(sourcePath);
|
|
356
|
+
if (!validation.valid) {
|
|
357
|
+
return { error: validation.errors.join(', ') };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const baseDir = location === 'project'
|
|
361
|
+
? join(projectPath, '.claude', 'skills')
|
|
362
|
+
: join(homedir(), '.claude', 'skills');
|
|
363
|
+
|
|
364
|
+
// Ensure base directory exists
|
|
365
|
+
if (!existsSync(baseDir)) {
|
|
366
|
+
await fsPromises.mkdir(baseDir, { recursive: true });
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Determine target folder name
|
|
370
|
+
const skillName = customName || validation.skillInfo.name;
|
|
371
|
+
const targetPath = join(baseDir, skillName);
|
|
372
|
+
|
|
373
|
+
// Check if already exists
|
|
374
|
+
if (existsSync(targetPath)) {
|
|
375
|
+
return { error: `Skill '${skillName}' already exists in ${location} location` };
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Copy entire folder recursively
|
|
379
|
+
await copyDirectoryRecursive(sourcePath, targetPath);
|
|
380
|
+
|
|
381
|
+
return {
|
|
382
|
+
success: true,
|
|
383
|
+
skillName,
|
|
384
|
+
location,
|
|
385
|
+
path: targetPath
|
|
386
|
+
};
|
|
387
|
+
} catch (error) {
|
|
388
|
+
return { error: (error as Error).message };
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Generate skill via CLI tool (Gemini)
|
|
394
|
+
* @param {Object} params - Generation parameters
|
|
395
|
+
* @param {string} params.generationType - 'description' or 'template'
|
|
396
|
+
* @param {string} params.description - Skill description from user
|
|
397
|
+
* @param {string} params.skillName - Name for the skill
|
|
398
|
+
* @param {string} params.location - 'project' or 'user'
|
|
399
|
+
* @param {string} params.projectPath - Project root path
|
|
400
|
+
* @returns {Object}
|
|
401
|
+
*/
|
|
402
|
+
async function generateSkillViaCLI({ generationType, description, skillName, location, projectPath }) {
|
|
403
|
+
try {
|
|
404
|
+
// Validate inputs
|
|
405
|
+
if (!skillName) {
|
|
406
|
+
return { error: 'Skill name is required' };
|
|
407
|
+
}
|
|
408
|
+
if (generationType === 'description' && !description) {
|
|
409
|
+
return { error: 'Description is required for description-based generation' };
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Determine target directory
|
|
413
|
+
const baseDir = location === 'project'
|
|
414
|
+
? join(projectPath, '.claude', 'skills')
|
|
415
|
+
: join(homedir(), '.claude', 'skills');
|
|
416
|
+
|
|
417
|
+
const targetPath = join(baseDir, skillName);
|
|
418
|
+
|
|
419
|
+
// Check if already exists
|
|
420
|
+
if (existsSync(targetPath)) {
|
|
421
|
+
return { error: `Skill '${skillName}' already exists in ${location} location` };
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Ensure base directory exists
|
|
425
|
+
if (!existsSync(baseDir)) {
|
|
426
|
+
await fsPromises.mkdir(baseDir, { recursive: true });
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Build CLI prompt
|
|
430
|
+
const targetLocationDisplay = location === 'project'
|
|
431
|
+
? '.claude/skills/'
|
|
432
|
+
: '~/.claude/skills/';
|
|
433
|
+
|
|
434
|
+
const prompt = `PURPOSE: Generate a complete Claude Code skill from description
|
|
435
|
+
TASK: • Parse skill requirements • Create SKILL.md with proper frontmatter (name, description, version, allowed-tools) • Generate supporting files if needed in skill folder
|
|
436
|
+
MODE: write
|
|
437
|
+
CONTEXT: @**/*
|
|
438
|
+
EXPECTED: Complete skill folder structure with SKILL.md and all necessary files
|
|
439
|
+
RULES: $(cat ~/.claude/workflows/cli-templates/prompts/universal/00-universal-rigorous-style.txt) | Follow Claude Code skill format | Include name, description in frontmatter | write=CREATE
|
|
440
|
+
|
|
441
|
+
SKILL DESCRIPTION:
|
|
442
|
+
${description || 'Generate a basic skill template'}
|
|
443
|
+
|
|
444
|
+
SKILL NAME: ${skillName}
|
|
445
|
+
TARGET LOCATION: ${targetLocationDisplay}
|
|
446
|
+
TARGET PATH: ${targetPath}
|
|
447
|
+
|
|
448
|
+
REQUIREMENTS:
|
|
449
|
+
1. Create SKILL.md with frontmatter containing:
|
|
450
|
+
- name: "${skillName}"
|
|
451
|
+
- description: Brief description of the skill
|
|
452
|
+
- version: "1.0.0"
|
|
453
|
+
- allowed-tools: List of tools this skill can use (e.g., [Read, Write, Edit, Bash])
|
|
454
|
+
2. Add skill content below frontmatter explaining what the skill does and how to use it
|
|
455
|
+
3. If the skill requires supporting files (e.g., templates, scripts), create them in the skill folder
|
|
456
|
+
4. Ensure all files are properly formatted and follow best practices`;
|
|
457
|
+
|
|
458
|
+
// Execute CLI tool (Gemini) with write mode
|
|
459
|
+
const result = await executeCliTool({
|
|
460
|
+
tool: 'gemini',
|
|
461
|
+
prompt,
|
|
462
|
+
mode: 'write',
|
|
463
|
+
cd: baseDir,
|
|
464
|
+
timeout: 600000, // 10 minutes
|
|
465
|
+
category: 'internal'
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
// Check if execution was successful
|
|
469
|
+
if (!result.success) {
|
|
470
|
+
return {
|
|
471
|
+
error: `CLI generation failed: ${result.stderr || 'Unknown error'}`,
|
|
472
|
+
stdout: result.stdout,
|
|
473
|
+
stderr: result.stderr
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// Validate the generated skill
|
|
478
|
+
const validation = validateSkillFolder(targetPath);
|
|
479
|
+
if (!validation.valid) {
|
|
480
|
+
return {
|
|
481
|
+
error: `Generated skill is invalid: ${validation.errors.join(', ')}`,
|
|
482
|
+
stdout: result.stdout,
|
|
483
|
+
stderr: result.stderr
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return {
|
|
488
|
+
success: true,
|
|
489
|
+
skillName: validation.skillInfo.name,
|
|
490
|
+
location,
|
|
491
|
+
path: targetPath,
|
|
492
|
+
stdout: result.stdout,
|
|
493
|
+
stderr: result.stderr
|
|
494
|
+
};
|
|
495
|
+
} catch (error) {
|
|
496
|
+
return { error: (error as Error).message };
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// ========== Skills API Routes ==========
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Handle Skills routes
|
|
504
|
+
* @returns true if route was handled, false otherwise
|
|
505
|
+
*/
|
|
506
|
+
export async function handleSkillsRoutes(ctx: RouteContext): Promise<boolean> {
|
|
507
|
+
const { pathname, url, req, res, initialPath, handlePostRequest } = ctx;
|
|
508
|
+
|
|
509
|
+
// API: Get all skills (project and user)
|
|
510
|
+
if (pathname === '/api/skills') {
|
|
511
|
+
const projectPathParam = url.searchParams.get('path') || initialPath;
|
|
512
|
+
const skillsData = getSkillsConfig(projectPathParam);
|
|
513
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
514
|
+
res.end(JSON.stringify(skillsData));
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// API: Get single skill detail
|
|
519
|
+
if (pathname.startsWith('/api/skills/') && req.method === 'GET' && !pathname.endsWith('/skills/')) {
|
|
520
|
+
const skillName = decodeURIComponent(pathname.replace('/api/skills/', ''));
|
|
521
|
+
const location = url.searchParams.get('location') || 'project';
|
|
522
|
+
const projectPathParam = url.searchParams.get('path') || initialPath;
|
|
523
|
+
const skillDetail = getSkillDetail(skillName, location, projectPathParam);
|
|
524
|
+
if (skillDetail.error) {
|
|
525
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
526
|
+
res.end(JSON.stringify(skillDetail));
|
|
527
|
+
} else {
|
|
528
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
529
|
+
res.end(JSON.stringify(skillDetail));
|
|
530
|
+
}
|
|
531
|
+
return true;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// API: Delete skill
|
|
535
|
+
if (pathname.startsWith('/api/skills/') && req.method === 'DELETE') {
|
|
536
|
+
const skillName = decodeURIComponent(pathname.replace('/api/skills/', ''));
|
|
537
|
+
handlePostRequest(req, res, async (body) => {
|
|
538
|
+
const { location, projectPath: projectPathParam } = body;
|
|
539
|
+
return deleteSkill(skillName, location, projectPathParam || initialPath);
|
|
540
|
+
});
|
|
541
|
+
return true;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// API: Validate skill import
|
|
545
|
+
if (pathname === '/api/skills/validate-import' && req.method === 'POST') {
|
|
546
|
+
handlePostRequest(req, res, async (body) => {
|
|
547
|
+
const { sourcePath } = body;
|
|
548
|
+
if (!sourcePath) {
|
|
549
|
+
return { valid: false, errors: ['Source path is required'], skillInfo: null };
|
|
550
|
+
}
|
|
551
|
+
return validateSkillFolder(sourcePath);
|
|
552
|
+
});
|
|
553
|
+
return true;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// API: Create/Import skill
|
|
557
|
+
if (pathname === '/api/skills/create' && req.method === 'POST') {
|
|
558
|
+
handlePostRequest(req, res, async (body) => {
|
|
559
|
+
const { mode, location, sourcePath, skillName, description, generationType, projectPath: projectPathParam } = body;
|
|
560
|
+
|
|
561
|
+
if (!mode) {
|
|
562
|
+
return { error: 'Mode is required (import or cli-generate)' };
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (!location) {
|
|
566
|
+
return { error: 'Location is required (project or user)' };
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
const projectPath = projectPathParam || initialPath;
|
|
570
|
+
|
|
571
|
+
if (mode === 'import') {
|
|
572
|
+
// Import mode: copy existing skill folder
|
|
573
|
+
if (!sourcePath) {
|
|
574
|
+
return { error: 'Source path is required for import mode' };
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
return await importSkill(sourcePath, location, projectPath, skillName);
|
|
578
|
+
} else if (mode === 'cli-generate') {
|
|
579
|
+
// CLI generate mode: use Gemini to generate skill
|
|
580
|
+
if (!skillName) {
|
|
581
|
+
return { error: 'Skill name is required for CLI generation mode' };
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
return await generateSkillViaCLI({
|
|
585
|
+
generationType: generationType || 'description',
|
|
586
|
+
description,
|
|
587
|
+
skillName,
|
|
588
|
+
location,
|
|
589
|
+
projectPath
|
|
590
|
+
});
|
|
591
|
+
} else {
|
|
592
|
+
return { error: 'Invalid mode. Must be "import" or "cli-generate"' };
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
return true;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
return false;
|
|
599
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* Status Routes Module
|
|
4
|
+
* Aggregated status endpoint for faster dashboard loading
|
|
5
|
+
*/
|
|
6
|
+
import type { IncomingMessage, ServerResponse } from 'http';
|
|
7
|
+
import { getCliToolsStatus } from '../../tools/cli-executor.js';
|
|
8
|
+
import { checkVenvStatus, checkSemanticStatus } from '../../tools/codex-lens.js';
|
|
9
|
+
|
|
10
|
+
export interface RouteContext {
|
|
11
|
+
pathname: string;
|
|
12
|
+
url: URL;
|
|
13
|
+
req: IncomingMessage;
|
|
14
|
+
res: ServerResponse;
|
|
15
|
+
initialPath: string;
|
|
16
|
+
handlePostRequest: (req: IncomingMessage, res: ServerResponse, handler: (body: unknown) => Promise<any>) => void;
|
|
17
|
+
broadcastToClients: (data: unknown) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Handle status routes
|
|
22
|
+
* @returns true if route was handled, false otherwise
|
|
23
|
+
*/
|
|
24
|
+
export async function handleStatusRoutes(ctx: RouteContext): Promise<boolean> {
|
|
25
|
+
const { pathname, res } = ctx;
|
|
26
|
+
|
|
27
|
+
// API: Aggregated Status (all statuses in one call)
|
|
28
|
+
if (pathname === '/api/status/all') {
|
|
29
|
+
try {
|
|
30
|
+
// Execute all status checks in parallel
|
|
31
|
+
const [cliStatus, codexLensStatus, semanticStatus] = await Promise.all([
|
|
32
|
+
getCliToolsStatus(),
|
|
33
|
+
checkVenvStatus(),
|
|
34
|
+
// Always check semantic status (will return available: false if CodexLens not ready)
|
|
35
|
+
checkSemanticStatus().catch(() => ({ available: false, backend: null }))
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
const response = {
|
|
39
|
+
cli: cliStatus,
|
|
40
|
+
codexLens: codexLensStatus,
|
|
41
|
+
semantic: semanticStatus,
|
|
42
|
+
timestamp: new Date().toISOString()
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
46
|
+
res.end(JSON.stringify(response));
|
|
47
|
+
return true;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error('[Status Routes] Error fetching aggregated status:', error);
|
|
50
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
51
|
+
res.end(JSON.stringify({ error: (error as Error).message }));
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return false;
|
|
57
|
+
}
|