fix: ccw package.json removal - add root build script and fix cli.ts path resolution

- Fix cli.ts loadPackageInfo() to try root package.json first (../../package.json)
- Add build script and devDependencies to root package.json
- Remove ccw/package.json and ccw/package-lock.json (no longer needed)
- CodexLens: add config.json support for index_dir configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
catlog22
2025-12-23 10:25:15 +08:00
parent 86cefa7bda
commit 3cd842ca1a
6 changed files with 155 additions and 3866 deletions

3854
ccw/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -28,20 +28,32 @@ interface PackageInfo {
/**
* Load package.json with error handling
* Tries root package.json first (../../package.json from dist),
* then falls back to ccw package.json (../package.json from dist)
* @returns Package info with version
*/
function loadPackageInfo(): PackageInfo {
const pkgPath = join(__dirname, '../package.json');
// First try root package.json (parent of ccw directory)
const rootPkgPath = join(__dirname, '../../package.json');
// Fallback to ccw package.json
const ccwPkgPath = join(__dirname, '../package.json');
try {
if (!existsSync(pkgPath)) {
console.error('Fatal Error: package.json not found.');
console.error(`Expected location: ${pkgPath}`);
process.exit(1);
// Try root package.json first
if (existsSync(rootPkgPath)) {
const content = readFileSync(rootPkgPath, 'utf8');
return JSON.parse(content) as PackageInfo;
}
const content = readFileSync(pkgPath, 'utf8');
return JSON.parse(content) as PackageInfo;
// Fallback to ccw package.json
if (existsSync(ccwPkgPath)) {
const content = readFileSync(ccwPkgPath, 'utf8');
return JSON.parse(content) as PackageInfo;
}
console.error('Fatal Error: package.json not found.');
console.error(`Tried locations:\n - ${rootPkgPath}\n - ${ccwPkgPath}`);
process.exit(1);
} catch (error) {
if (error instanceof SyntaxError) {
console.error('Fatal Error: package.json contains invalid JSON.');

View File

@@ -62,10 +62,27 @@ def _parse_languages(raw: Optional[List[str]]) -> Optional[List[str]]:
def _get_index_root() -> Path:
"""Get the index root directory from config or default."""
"""Get the index root directory from config or default.
Priority order:
1. CODEXLENS_INDEX_DIR environment variable
2. index_dir from ~/.codexlens/config.json
3. Default: ~/.codexlens/indexes
"""
env_override = os.getenv("CODEXLENS_INDEX_DIR")
if env_override:
return Path(env_override).expanduser().resolve()
# Read from config.json
config_file = Path.home() / ".codexlens" / "config.json"
if config_file.exists():
try:
cfg = json.loads(config_file.read_text(encoding="utf-8"))
if "index_dir" in cfg:
return Path(cfg["index_dir"]).expanduser().resolve()
except (json.JSONDecodeError, OSError):
pass # Fall through to default
return Path.home() / ".codexlens" / "indexes"

View File

@@ -14,11 +14,37 @@ Storage Structure:
└── _index.db # src/ directory index
"""
import json
import os
import platform
from pathlib import Path
from typing import Optional
def _get_configured_index_root() -> Path:
"""Get the index root from environment or config file.
Priority order:
1. CODEXLENS_INDEX_DIR environment variable
2. index_dir from ~/.codexlens/config.json
3. Default: ~/.codexlens/indexes
"""
env_override = os.getenv("CODEXLENS_INDEX_DIR")
if env_override:
return Path(env_override).expanduser().resolve()
config_file = Path.home() / ".codexlens" / "config.json"
if config_file.exists():
try:
cfg = json.loads(config_file.read_text(encoding="utf-8"))
if "index_dir" in cfg:
return Path(cfg["index_dir"]).expanduser().resolve()
except (json.JSONDecodeError, OSError):
pass
return Path.home() / ".codexlens" / "indexes"
class PathMapper:
"""Bidirectional mapping tool for source paths ↔ index paths.
@@ -31,7 +57,7 @@ class PathMapper:
index_root: Configured index root directory
"""
DEFAULT_INDEX_ROOT = Path.home() / ".codexlens" / "indexes"
DEFAULT_INDEX_ROOT = _get_configured_index_root()
INDEX_DB_NAME = "_index.db"
def __init__(self, index_root: Optional[Path] = None):

82
package-lock.json generated
View File

@@ -23,7 +23,15 @@
"zod": "^4.1.13"
},
"bin": {
"ccw": "ccw/bin/ccw.js"
"ccw": "ccw/bin/ccw.js",
"ccw-mcp": "ccw/bin/ccw-mcp.js"
},
"devDependencies": {
"@types/better-sqlite3": "^7.6.12",
"@types/gradient-string": "^1.1.6",
"@types/inquirer": "^9.0.9",
"@types/node": "^25.0.1",
"typescript": "^5.9.3"
},
"engines": {
"node": ">=16.0.0"
@@ -164,6 +172,57 @@
"node": ">=14"
}
},
"node_modules/@types/better-sqlite3": {
"version": "7.6.13",
"resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.13.tgz",
"integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/gradient-string": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@types/gradient-string/-/gradient-string-1.1.6.tgz",
"integrity": "sha512-LkaYxluY4G5wR1M4AKQUal2q61Di1yVVCw42ImFTuaIoQVgmV0WP1xUaLB8zwb47mp82vWTpePI9JmrjEnJ7nQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/tinycolor2": "*"
}
},
"node_modules/@types/inquirer": {
"version": "9.0.9",
"resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.9.tgz",
"integrity": "sha512-/mWx5136gts2Z2e5izdoRCo46lPp5TMs9R15GTSsgg/XnZyxDWVqoVU3R9lWnccKpqwsJLvRoxbCjoJtZB7DSw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/through": "*",
"rxjs": "^7.2.0"
}
},
"node_modules/@types/node": {
"version": "25.0.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz",
"integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"undici-types": "~7.16.0"
}
},
"node_modules/@types/through": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.33.tgz",
"integrity": "sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/tinycolor2": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.6.tgz",
@@ -3069,6 +3128,27 @@
"node": ">= 0.6"
}
},
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
"devOptional": true,
"license": "MIT"
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",

View File

@@ -9,9 +9,10 @@
"ccw-mcp": "./ccw/bin/ccw-mcp.js"
},
"scripts": {
"build": "tsc -p ccw/tsconfig.json",
"start": "node ccw/bin/ccw.js",
"test": "node --test",
"prepublishOnly": "echo 'Ready to publish @dyw/claude-code-workflow'"
"prepublishOnly": "npm run build && echo 'Ready to publish @dyw/claude-code-workflow'"
},
"keywords": [
"claude",
@@ -69,5 +70,12 @@
"bugs": {
"url": "https://github.com/catlog22/Claude-Code-Workflow/issues"
},
"homepage": "https://github.com/catlog22/Claude-Code-Workflow#readme"
"homepage": "https://github.com/catlog22/Claude-Code-Workflow#readme",
"devDependencies": {
"@types/better-sqlite3": "^7.6.12",
"@types/gradient-string": "^1.1.6",
"@types/inquirer": "^9.0.9",
"@types/node": "^25.0.1",
"typescript": "^5.9.3"
}
}