claude-code-workflow 6.2.6 → 6.2.9
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/ccw/dist/cli.d.ts.map +1 -1
- package/ccw/dist/cli.js +18 -7
- package/ccw/dist/cli.js.map +1 -1
- package/ccw/dist/core/routes/system-routes.js +1 -1
- package/ccw/dist/core/routes/system-routes.js.map +1 -1
- package/ccw/src/cli.ts +256 -244
- package/ccw/src/core/routes/system-routes.ts +1 -1
- package/ccw/src/templates/dashboard-js/components/cli-status.js +35 -2
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +45 -6
- 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/commands.py +41 -15
- package/codex-lens/src/codexlens/cli/embedding_manager.py +15 -0
- package/codex-lens/src/codexlens/cli/model_manager.py +337 -311
- package/codex-lens/src/codexlens/search/__pycache__/chain_search.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/chain_search.py +14 -1
- package/codex-lens/src/codexlens/search/hybrid_search.py +25 -12
- package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/vector_store.py +97 -0
- package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/path_mapper.py +27 -1
- package/package.json +13 -5
- package/ccw/package.json +0 -65
|
Binary file
|
|
Binary file
|
|
@@ -396,7 +396,20 @@ class ChainSearchEngine:
|
|
|
396
396
|
all_results = []
|
|
397
397
|
stats = SearchStats()
|
|
398
398
|
|
|
399
|
-
|
|
399
|
+
# Force single-threaded execution for vector/hybrid search to avoid GPU crashes
|
|
400
|
+
# DirectML/ONNX have threading issues when multiple threads access GPU resources
|
|
401
|
+
effective_workers = options.max_workers
|
|
402
|
+
if options.enable_vector or options.hybrid_mode:
|
|
403
|
+
effective_workers = 1
|
|
404
|
+
self.logger.debug("Using single-threaded mode for vector search (GPU safety)")
|
|
405
|
+
# Pre-load embedder to avoid initialization overhead per-search
|
|
406
|
+
try:
|
|
407
|
+
from codexlens.semantic.embedder import get_embedder
|
|
408
|
+
get_embedder(profile="code", use_gpu=True)
|
|
409
|
+
except Exception:
|
|
410
|
+
pass # Ignore pre-load failures
|
|
411
|
+
|
|
412
|
+
executor = self._get_executor(effective_workers)
|
|
400
413
|
# Submit all search tasks
|
|
401
414
|
future_to_path = {
|
|
402
415
|
executor.submit(
|
|
@@ -274,19 +274,32 @@ class HybridSearchEngine:
|
|
|
274
274
|
)
|
|
275
275
|
return []
|
|
276
276
|
|
|
277
|
-
#
|
|
278
|
-
|
|
279
|
-
if
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
profile = "code"
|
|
286
|
-
elif detected_dim == 1024:
|
|
287
|
-
profile = "multilingual" # or balanced, both are 1024
|
|
277
|
+
# Get stored model configuration (preferred) or auto-detect from dimension
|
|
278
|
+
model_config = vector_store.get_model_config()
|
|
279
|
+
if model_config:
|
|
280
|
+
profile = model_config["model_profile"]
|
|
281
|
+
self.logger.debug(
|
|
282
|
+
"Using stored model config: %s (%s, %dd)",
|
|
283
|
+
profile, model_config["model_name"], model_config["embedding_dim"]
|
|
284
|
+
)
|
|
288
285
|
else:
|
|
289
|
-
|
|
286
|
+
# Fallback: auto-detect from embedding dimension
|
|
287
|
+
detected_dim = vector_store.dimension
|
|
288
|
+
if detected_dim is None:
|
|
289
|
+
self.logger.info("Vector store dimension unknown, using default profile")
|
|
290
|
+
profile = "code" # Default fallback
|
|
291
|
+
elif detected_dim == 384:
|
|
292
|
+
profile = "fast"
|
|
293
|
+
elif detected_dim == 768:
|
|
294
|
+
profile = "code"
|
|
295
|
+
elif detected_dim == 1024:
|
|
296
|
+
profile = "multilingual" # or balanced, both are 1024
|
|
297
|
+
else:
|
|
298
|
+
profile = "code" # Default fallback
|
|
299
|
+
self.logger.debug(
|
|
300
|
+
"No stored model config, auto-detected profile '%s' from dimension %s",
|
|
301
|
+
profile, detected_dim
|
|
302
|
+
)
|
|
290
303
|
|
|
291
304
|
# Use cached embedder (singleton) for performance
|
|
292
305
|
embedder = get_embedder(profile=profile)
|
|
Binary file
|
|
@@ -116,6 +116,17 @@ class VectorStore:
|
|
|
116
116
|
CREATE INDEX IF NOT EXISTS idx_chunks_file
|
|
117
117
|
ON semantic_chunks(file_path)
|
|
118
118
|
""")
|
|
119
|
+
# Model configuration table - tracks which model generated the embeddings
|
|
120
|
+
conn.execute("""
|
|
121
|
+
CREATE TABLE IF NOT EXISTS embeddings_config (
|
|
122
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
123
|
+
model_profile TEXT NOT NULL,
|
|
124
|
+
model_name TEXT NOT NULL,
|
|
125
|
+
embedding_dim INTEGER NOT NULL,
|
|
126
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
127
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
128
|
+
)
|
|
129
|
+
""")
|
|
119
130
|
conn.commit()
|
|
120
131
|
|
|
121
132
|
def _init_ann_index(self) -> None:
|
|
@@ -932,6 +943,92 @@ class VectorStore:
|
|
|
932
943
|
return self._ann_index.count()
|
|
933
944
|
return 0
|
|
934
945
|
|
|
946
|
+
def get_model_config(self) -> Optional[Dict[str, Any]]:
|
|
947
|
+
"""Get the model configuration used for embeddings in this store.
|
|
948
|
+
|
|
949
|
+
Returns:
|
|
950
|
+
Dictionary with model_profile, model_name, embedding_dim, or None if not set.
|
|
951
|
+
"""
|
|
952
|
+
with sqlite3.connect(self.db_path) as conn:
|
|
953
|
+
row = conn.execute(
|
|
954
|
+
"SELECT model_profile, model_name, embedding_dim, created_at, updated_at "
|
|
955
|
+
"FROM embeddings_config WHERE id = 1"
|
|
956
|
+
).fetchone()
|
|
957
|
+
if row:
|
|
958
|
+
return {
|
|
959
|
+
"model_profile": row[0],
|
|
960
|
+
"model_name": row[1],
|
|
961
|
+
"embedding_dim": row[2],
|
|
962
|
+
"created_at": row[3],
|
|
963
|
+
"updated_at": row[4],
|
|
964
|
+
}
|
|
965
|
+
return None
|
|
966
|
+
|
|
967
|
+
def set_model_config(
|
|
968
|
+
self, model_profile: str, model_name: str, embedding_dim: int
|
|
969
|
+
) -> None:
|
|
970
|
+
"""Set the model configuration for embeddings in this store.
|
|
971
|
+
|
|
972
|
+
This should be called when generating new embeddings. If a different
|
|
973
|
+
model was previously used, this will update the configuration.
|
|
974
|
+
|
|
975
|
+
Args:
|
|
976
|
+
model_profile: Model profile name (fast, code, minilm, etc.)
|
|
977
|
+
model_name: Full model name (e.g., jinaai/jina-embeddings-v2-base-code)
|
|
978
|
+
embedding_dim: Embedding dimension (e.g., 768)
|
|
979
|
+
"""
|
|
980
|
+
with sqlite3.connect(self.db_path) as conn:
|
|
981
|
+
conn.execute(
|
|
982
|
+
"""
|
|
983
|
+
INSERT INTO embeddings_config (id, model_profile, model_name, embedding_dim)
|
|
984
|
+
VALUES (1, ?, ?, ?)
|
|
985
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
986
|
+
model_profile = excluded.model_profile,
|
|
987
|
+
model_name = excluded.model_name,
|
|
988
|
+
embedding_dim = excluded.embedding_dim,
|
|
989
|
+
updated_at = CURRENT_TIMESTAMP
|
|
990
|
+
""",
|
|
991
|
+
(model_profile, model_name, embedding_dim)
|
|
992
|
+
)
|
|
993
|
+
conn.commit()
|
|
994
|
+
|
|
995
|
+
def check_model_compatibility(
|
|
996
|
+
self, model_profile: str, model_name: str, embedding_dim: int
|
|
997
|
+
) -> Tuple[bool, Optional[str]]:
|
|
998
|
+
"""Check if the given model is compatible with existing embeddings.
|
|
999
|
+
|
|
1000
|
+
Args:
|
|
1001
|
+
model_profile: Model profile to check
|
|
1002
|
+
model_name: Model name to check
|
|
1003
|
+
embedding_dim: Embedding dimension to check
|
|
1004
|
+
|
|
1005
|
+
Returns:
|
|
1006
|
+
Tuple of (is_compatible, warning_message).
|
|
1007
|
+
is_compatible is True if no existing config or configs match.
|
|
1008
|
+
warning_message is a user-friendly message if incompatible.
|
|
1009
|
+
"""
|
|
1010
|
+
existing = self.get_model_config()
|
|
1011
|
+
if existing is None:
|
|
1012
|
+
return True, None
|
|
1013
|
+
|
|
1014
|
+
# Check dimension first (most critical)
|
|
1015
|
+
if existing["embedding_dim"] != embedding_dim:
|
|
1016
|
+
return False, (
|
|
1017
|
+
f"Dimension mismatch: existing embeddings use {existing['embedding_dim']}d "
|
|
1018
|
+
f"({existing['model_profile']}), but requested model uses {embedding_dim}d "
|
|
1019
|
+
f"({model_profile}). Use --force to regenerate all embeddings."
|
|
1020
|
+
)
|
|
1021
|
+
|
|
1022
|
+
# Check model (different models with same dimension may have different semantic spaces)
|
|
1023
|
+
if existing["model_profile"] != model_profile:
|
|
1024
|
+
return False, (
|
|
1025
|
+
f"Model mismatch: existing embeddings use '{existing['model_profile']}' "
|
|
1026
|
+
f"({existing['model_name']}), but requested '{model_profile}' "
|
|
1027
|
+
f"({model_name}). Use --force to regenerate all embeddings."
|
|
1028
|
+
)
|
|
1029
|
+
|
|
1030
|
+
return True, None
|
|
1031
|
+
|
|
935
1032
|
def close(self) -> None:
|
|
936
1033
|
"""Close the vector store and release resources.
|
|
937
1034
|
|
|
Binary file
|
|
@@ -14,11 +14,37 @@ Storage Structure:
|
|
|
14
14
|
└── _index.db # src/ directory index
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
|
+
import json
|
|
18
|
+
import os
|
|
17
19
|
import platform
|
|
18
20
|
from pathlib import Path
|
|
19
21
|
from typing import Optional
|
|
20
22
|
|
|
21
23
|
|
|
24
|
+
def _get_configured_index_root() -> Path:
|
|
25
|
+
"""Get the index root from environment or config file.
|
|
26
|
+
|
|
27
|
+
Priority order:
|
|
28
|
+
1. CODEXLENS_INDEX_DIR environment variable
|
|
29
|
+
2. index_dir from ~/.codexlens/config.json
|
|
30
|
+
3. Default: ~/.codexlens/indexes
|
|
31
|
+
"""
|
|
32
|
+
env_override = os.getenv("CODEXLENS_INDEX_DIR")
|
|
33
|
+
if env_override:
|
|
34
|
+
return Path(env_override).expanduser().resolve()
|
|
35
|
+
|
|
36
|
+
config_file = Path.home() / ".codexlens" / "config.json"
|
|
37
|
+
if config_file.exists():
|
|
38
|
+
try:
|
|
39
|
+
cfg = json.loads(config_file.read_text(encoding="utf-8"))
|
|
40
|
+
if "index_dir" in cfg:
|
|
41
|
+
return Path(cfg["index_dir"]).expanduser().resolve()
|
|
42
|
+
except (json.JSONDecodeError, OSError):
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
return Path.home() / ".codexlens" / "indexes"
|
|
46
|
+
|
|
47
|
+
|
|
22
48
|
class PathMapper:
|
|
23
49
|
"""Bidirectional mapping tool for source paths ↔ index paths.
|
|
24
50
|
|
|
@@ -31,7 +57,7 @@ class PathMapper:
|
|
|
31
57
|
index_root: Configured index root directory
|
|
32
58
|
"""
|
|
33
59
|
|
|
34
|
-
DEFAULT_INDEX_ROOT =
|
|
60
|
+
DEFAULT_INDEX_ROOT = _get_configured_index_root()
|
|
35
61
|
INDEX_DB_NAME = "_index.db"
|
|
36
62
|
|
|
37
63
|
def __init__(self, index_root: Optional[Path] = None):
|
package/package.json
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-code-workflow",
|
|
3
|
-
"version": "6.2.
|
|
3
|
+
"version": "6.2.9",
|
|
4
4
|
"description": "JSON-driven multi-agent development framework with intelligent CLI orchestration (Gemini/Qwen/Codex), context-first architecture, and automated workflow execution",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "ccw/src/index.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"ccw": "./ccw/bin/ccw.js"
|
|
8
|
+
"ccw": "./ccw/bin/ccw.js",
|
|
9
|
+
"ccw-mcp": "./ccw/bin/ccw-mcp.js"
|
|
9
10
|
},
|
|
10
11
|
"scripts": {
|
|
12
|
+
"build": "tsc -p ccw/tsconfig.json",
|
|
11
13
|
"start": "node ccw/bin/ccw.js",
|
|
12
14
|
"test": "node --test",
|
|
13
|
-
"prepublishOnly": "echo 'Ready to publish @dyw/claude-code-workflow'"
|
|
15
|
+
"prepublishOnly": "npm run build && echo 'Ready to publish @dyw/claude-code-workflow'"
|
|
14
16
|
},
|
|
15
17
|
"keywords": [
|
|
16
18
|
"claude",
|
|
@@ -45,7 +47,6 @@
|
|
|
45
47
|
"ccw/bin/",
|
|
46
48
|
"ccw/dist/",
|
|
47
49
|
"ccw/src/",
|
|
48
|
-
"ccw/package.json",
|
|
49
50
|
".claude/agents/",
|
|
50
51
|
".claude/commands/",
|
|
51
52
|
".claude/output-styles/",
|
|
@@ -69,5 +70,12 @@
|
|
|
69
70
|
"bugs": {
|
|
70
71
|
"url": "https://github.com/catlog22/Claude-Code-Workflow/issues"
|
|
71
72
|
},
|
|
72
|
-
"homepage": "https://github.com/catlog22/Claude-Code-Workflow#readme"
|
|
73
|
+
"homepage": "https://github.com/catlog22/Claude-Code-Workflow#readme",
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"@types/better-sqlite3": "^7.6.12",
|
|
76
|
+
"@types/gradient-string": "^1.1.6",
|
|
77
|
+
"@types/inquirer": "^9.0.9",
|
|
78
|
+
"@types/node": "^25.0.1",
|
|
79
|
+
"typescript": "^5.9.3"
|
|
80
|
+
}
|
|
73
81
|
}
|
package/ccw/package.json
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "claude-code-workflow",
|
|
3
|
-
"version": "6.2.6",
|
|
4
|
-
"description": "Claude Code Workflow CLI - Dashboard viewer for workflow sessions and reviews",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
|
-
"bin": {
|
|
9
|
-
"ccw": "./bin/ccw.js",
|
|
10
|
-
"ccw-mcp": "./bin/ccw-mcp.js"
|
|
11
|
-
},
|
|
12
|
-
"scripts": {
|
|
13
|
-
"build": "tsc",
|
|
14
|
-
"dev": "tsx watch src/cli.ts",
|
|
15
|
-
"test": "node --test tests/*.test.js",
|
|
16
|
-
"test:codexlens": "node --test tests/codex-lens*.test.js",
|
|
17
|
-
"test:mcp": "node --test tests/mcp-server.test.js",
|
|
18
|
-
"lint": "eslint src/"
|
|
19
|
-
},
|
|
20
|
-
"keywords": [
|
|
21
|
-
"claude",
|
|
22
|
-
"workflow",
|
|
23
|
-
"cli",
|
|
24
|
-
"dashboard",
|
|
25
|
-
"code-review"
|
|
26
|
-
],
|
|
27
|
-
"author": "Claude Code Workflow",
|
|
28
|
-
"license": "MIT",
|
|
29
|
-
"engines": {
|
|
30
|
-
"node": ">=16.0.0"
|
|
31
|
-
},
|
|
32
|
-
"dependencies": {
|
|
33
|
-
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
34
|
-
"better-sqlite3": "^11.7.0",
|
|
35
|
-
"boxen": "^7.1.0",
|
|
36
|
-
"chalk": "^5.3.0",
|
|
37
|
-
"commander": "^11.0.0",
|
|
38
|
-
"figlet": "^1.7.0",
|
|
39
|
-
"glob": "^10.3.0",
|
|
40
|
-
"gradient-string": "^2.0.2",
|
|
41
|
-
"inquirer": "^9.2.0",
|
|
42
|
-
"open": "^9.1.0",
|
|
43
|
-
"ora": "^7.0.0",
|
|
44
|
-
"zod": "^4.1.13"
|
|
45
|
-
},
|
|
46
|
-
"files": [
|
|
47
|
-
"bin/",
|
|
48
|
-
"dist/",
|
|
49
|
-
"src/",
|
|
50
|
-
"README.md",
|
|
51
|
-
"LICENSE"
|
|
52
|
-
],
|
|
53
|
-
"repository": {
|
|
54
|
-
"type": "git",
|
|
55
|
-
"url": "https://github.com/claude-code-workflow/ccw"
|
|
56
|
-
},
|
|
57
|
-
"devDependencies": {
|
|
58
|
-
"@types/better-sqlite3": "^7.6.12",
|
|
59
|
-
"@types/gradient-string": "^1.1.6",
|
|
60
|
-
"@types/inquirer": "^9.0.9",
|
|
61
|
-
"@types/node": "^25.0.1",
|
|
62
|
-
"tsx": "^4.21.0",
|
|
63
|
-
"typescript": "^5.9.3"
|
|
64
|
-
}
|
|
65
|
-
}
|