code-abyss 1.6.2 → 1.6.4

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/README.md CHANGED
@@ -23,7 +23,7 @@ npx code-abyss
23
23
  交互式菜单(方向键选择,回车确认):
24
24
 
25
25
  ```
26
- ☠️ Code Abyss v1.6.1
26
+ ☠️ Code Abyss v1.6.3
27
27
 
28
28
  ? 请选择操作 (Use arrow keys)
29
29
  ❯ 安装到 Claude Code (~/.claude/)
package/bin/install.js CHANGED
@@ -4,7 +4,7 @@ const fs = require('fs');
4
4
  const path = require('path');
5
5
  const os = require('os');
6
6
 
7
- const VERSION = '1.6.2';
7
+ const VERSION = require(path.join(__dirname, '..', 'package.json')).version;
8
8
  const HOME = os.homedir();
9
9
  const SKIP = ['__pycache__', '.pyc', '.pyo', '.egg-info', '.DS_Store', 'Thumbs.db', '.git'];
10
10
  const PKG_ROOT = path.join(__dirname, '..');
@@ -118,7 +118,7 @@ function detectClaudeAuth(settings) {
118
118
  try {
119
119
  const cc = JSON.parse(fs.readFileSync(cred, 'utf8'));
120
120
  if (cc.claudeAiOauth || cc.apiKey) return { type: 'login', detail: 'claude login' };
121
- } catch (e) {}
121
+ } catch (e) { warn(`凭证文件损坏: ${cred}`); }
122
122
  }
123
123
  return null;
124
124
  }
@@ -130,7 +130,7 @@ function detectCodexAuth() {
130
130
  try {
131
131
  const a = JSON.parse(fs.readFileSync(auth, 'utf8'));
132
132
  if (a.token || a.api_key) return { type: 'login', detail: 'codex login' };
133
- } catch (e) {}
133
+ } catch (e) { warn(`凭证文件损坏: ${auth}`); }
134
134
  }
135
135
  const cfg = path.join(HOME, '.codex', 'config.toml');
136
136
  if (fs.existsSync(cfg)) {
@@ -160,10 +160,11 @@ const SETTINGS_TEMPLATE = {
160
160
  }
161
161
  };
162
162
 
163
+ const CCLINE_CMD = process.platform === 'win32' ? 'ccline' : '~/.claude/ccline/ccline';
163
164
  const CCLINE_STATUS_LINE = {
164
165
  statusLine: {
165
166
  type: 'command',
166
- command: path.join(HOME, '.claude', 'ccline', 'ccline'),
167
+ command: CCLINE_CMD,
167
168
  padding: 0
168
169
  }
169
170
  };
@@ -262,7 +263,7 @@ function installCore(tgt) {
262
263
  const settingsPath = path.join(targetDir, 'settings.json');
263
264
  let settings = {};
264
265
  if (fs.existsSync(settingsPath)) {
265
- try { settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8')); } catch (e) { settings = {}; }
266
+ try { settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8')); } catch (e) { warn(`settings.json 解析失败,将使用空配置`); settings = {}; }
266
267
  fs.copyFileSync(settingsPath, path.join(backupDir, 'settings.json'));
267
268
  manifest.backups.push('settings.json');
268
269
  }
@@ -342,11 +343,13 @@ async function installCcline(ctx) {
342
343
  console.log('');
343
344
  info('安装 ccline 状态栏...');
344
345
  const { execSync } = require('child_process');
345
- const cclineBin = path.join(HOME, '.claude', 'ccline', 'ccline');
346
346
 
347
347
  let installed = false;
348
348
  try { execSync('ccline --version', { stdio: 'pipe' }); installed = true; } catch (e) {}
349
- if (!installed && fs.existsSync(cclineBin)) installed = true;
349
+ if (!installed) {
350
+ const cclineBin = path.join(HOME, '.claude', 'ccline', 'ccline');
351
+ if (fs.existsSync(cclineBin)) installed = true;
352
+ }
350
353
 
351
354
  if (!installed) {
352
355
  info('ccline 未检测到,正在安装...');
package/bin/uninstall.js CHANGED
@@ -12,7 +12,13 @@ if (!fs.existsSync(manifestPath)) {
12
12
  process.exit(1);
13
13
  }
14
14
 
15
- const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
15
+ let manifest;
16
+ try {
17
+ manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
18
+ } catch (e) {
19
+ console.error('❌ manifest.json 解析失败:', e.message);
20
+ process.exit(1);
21
+ }
16
22
 
17
23
  console.log(`\n🗑️ 卸载 Code Abyss v${manifest.version}...\n`);
18
24
 
@@ -16,8 +16,7 @@ base_url = "https://your-api-endpoint.com/v1"
16
16
  wire_api = "responses"
17
17
  requires_openai_auth = true
18
18
 
19
- [tools]
20
- web_search = true
19
+ web_search = "live"
21
20
 
22
21
  [features]
23
22
  unified_exec = true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-abyss",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "description": "邪修红尘仙·宿命深渊 - 一键为 Claude Code / Codex CLI 注入邪修人格与安全工程知识体系",
5
5
  "keywords": [
6
6
  "claude",
@@ -36,7 +36,7 @@
36
36
  "node": ">=14.0.0"
37
37
  },
38
38
  "scripts": {
39
- "test": "echo \"No tests yet\" && exit 0"
39
+ "test": "python3 -m unittest discover skills/tests/ -v"
40
40
  },
41
41
  "dependencies": {
42
42
  "@inquirer/prompts": "^8.2.0"
@@ -136,7 +136,7 @@ def analyze_module(path: Path) -> ModuleInfo:
136
136
  return info
137
137
 
138
138
 
139
- def generate_readme(info: ModuleInfo, existing_content: str = None) -> str:
139
+ def generate_readme(info: ModuleInfo) -> str:
140
140
  """生成 README.md"""
141
141
  lines = []
142
142
 
@@ -313,7 +313,7 @@ console.log(result);''',
313
313
  return "\n".join(lines)
314
314
 
315
315
 
316
- def generate_design(info: ModuleInfo, existing_content: str = None) -> str:
316
+ def generate_design(info: ModuleInfo) -> str:
317
317
  """生成 DESIGN.md"""
318
318
  lines = []
319
319
  today = datetime.now().strftime("%Y-%m-%d")
@@ -441,7 +441,7 @@ def generate_docs(path: str, force: bool = False) -> Dict[str, str]:
441
441
  result["messages"].append("README.md 已存在,跳过(使用 --force 覆盖)")
442
442
  else:
443
443
  existing = readme_path.read_text() if readme_path.exists() else None
444
- content = generate_readme(info, existing)
444
+ content = generate_readme(info)
445
445
  readme_path.write_text(content)
446
446
  result["readme"] = str(readme_path)
447
447
  result["messages"].append(f"已生成 README.md")
@@ -452,7 +452,7 @@ def generate_docs(path: str, force: bool = False) -> Dict[str, str]:
452
452
  result["messages"].append("DESIGN.md 已存在,跳过(使用 --force 覆盖)")
453
453
  else:
454
454
  existing = design_path.read_text() if design_path.exists() else None
455
- content = generate_design(info, existing)
455
+ content = generate_design(info)
456
456
  design_path.write_text(content)
457
457
  result["design"] = str(design_path)
458
458
  result["messages"].append(f"已生成 DESIGN.md")
@@ -11,7 +11,7 @@ import json
11
11
  import ast
12
12
  from pathlib import Path
13
13
  from dataclasses import dataclass, field
14
- from typing import List, Dict, Optional, Set
14
+ from typing import List, Dict, Optional, Set, Tuple
15
15
  from enum import Enum
16
16
  from collections import defaultdict
17
17
 
@@ -90,7 +90,7 @@ class PythonAnalyzer(ast.NodeVisitor):
90
90
  self.classes: List[Dict] = []
91
91
  self.complexity = 0
92
92
 
93
- def analyze(self) -> tuple[List[Issue], List[Dict], List[Dict], int]:
93
+ def analyze(self) -> Tuple[List[Issue], List[Dict], List[Dict], int]:
94
94
  try:
95
95
  tree = ast.parse(self.source)
96
96
  self.visit(tree)
@@ -222,7 +222,7 @@ class PythonAnalyzer(ast.NodeVisitor):
222
222
  return complexity
223
223
 
224
224
 
225
- def analyze_python_file(file_path: Path) -> tuple[FileMetrics, List[Issue]]:
225
+ def analyze_python_file(file_path: Path) -> Tuple[FileMetrics, List[Issue]]:
226
226
  """分析 Python 文件"""
227
227
  metrics = FileMetrics(path=str(file_path))
228
228
  issues = []
@@ -296,7 +296,7 @@ def analyze_python_file(file_path: Path) -> tuple[FileMetrics, List[Issue]]:
296
296
  return metrics, issues
297
297
 
298
298
 
299
- def analyze_generic_file(file_path: Path) -> tuple[FileMetrics, List[Issue]]:
299
+ def analyze_generic_file(file_path: Path) -> Tuple[FileMetrics, List[Issue]]:
300
300
  """分析通用代码文件"""
301
301
  metrics = FileMetrics(path=str(file_path))
302
302
  issues = []