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 * 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 * @returns Package info with version
*/ */
function loadPackageInfo(): PackageInfo { 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 { try {
if (!existsSync(pkgPath)) { // Try root package.json first
console.error('Fatal Error: package.json not found.'); if (existsSync(rootPkgPath)) {
console.error(`Expected location: ${pkgPath}`); const content = readFileSync(rootPkgPath, 'utf8');
process.exit(1); return JSON.parse(content) as PackageInfo;
} }
const content = readFileSync(pkgPath, 'utf8'); // Fallback to ccw package.json
if (existsSync(ccwPkgPath)) {
const content = readFileSync(ccwPkgPath, 'utf8');
return JSON.parse(content) as PackageInfo; 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) { } catch (error) {
if (error instanceof SyntaxError) { if (error instanceof SyntaxError) {
console.error('Fatal Error: package.json contains invalid JSON.'); 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: 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") env_override = os.getenv("CODEXLENS_INDEX_DIR")
if env_override: if env_override:
return Path(env_override).expanduser().resolve() 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" return Path.home() / ".codexlens" / "indexes"

View File

@@ -14,11 +14,37 @@ Storage Structure:
└── _index.db # src/ directory index └── _index.db # src/ directory index
""" """
import json
import os
import platform import platform
from pathlib import Path from pathlib import Path
from typing import Optional 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: class PathMapper:
"""Bidirectional mapping tool for source paths ↔ index paths. """Bidirectional mapping tool for source paths ↔ index paths.
@@ -31,7 +57,7 @@ class PathMapper:
index_root: Configured index root directory 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" INDEX_DB_NAME = "_index.db"
def __init__(self, index_root: Optional[Path] = None): def __init__(self, index_root: Optional[Path] = None):

82
package-lock.json generated
View File

@@ -23,7 +23,15 @@
"zod": "^4.1.13" "zod": "^4.1.13"
}, },
"bin": { "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": { "engines": {
"node": ">=16.0.0" "node": ">=16.0.0"
@@ -164,6 +172,57 @@
"node": ">=14" "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": { "node_modules/@types/tinycolor2": {
"version": "1.4.6", "version": "1.4.6",
"resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.6.tgz", "resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.6.tgz",
@@ -3069,6 +3128,27 @@
"node": ">= 0.6" "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": { "node_modules/unpipe": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",

View File

@@ -9,9 +9,10 @@
"ccw-mcp": "./ccw/bin/ccw-mcp.js" "ccw-mcp": "./ccw/bin/ccw-mcp.js"
}, },
"scripts": { "scripts": {
"build": "tsc -p ccw/tsconfig.json",
"start": "node ccw/bin/ccw.js", "start": "node ccw/bin/ccw.js",
"test": "node --test", "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": [ "keywords": [
"claude", "claude",
@@ -69,5 +70,12 @@
"bugs": { "bugs": {
"url": "https://github.com/catlog22/Claude-Code-Workflow/issues" "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"
}
} }