cancanneed 0.1.1 → 0.2.0
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 +24 -35
- package/cancanneed-indexer +0 -0
- package/cancanneed.js +23 -0
- package/cancanneed.py +10 -8
- package/package.json +6 -3
- package/cancanneed.sh +0 -13
package/README.md
CHANGED
|
@@ -5,43 +5,46 @@
|
|
|
5
5
|
|
|
6
6
|
## 一条命令安装
|
|
7
7
|
|
|
8
|
-
**npx(推荐,无需 clone
|
|
8
|
+
**npx(推荐,无需 clone,首次自动下载):**
|
|
9
9
|
```bash
|
|
10
10
|
npx cancanneed /path/to/project
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
**全局安装:**
|
|
14
14
|
```bash
|
|
15
|
-
|
|
15
|
+
npm install -g cancanneed
|
|
16
|
+
cancanneed /path/to/project
|
|
16
17
|
```
|
|
17
18
|
|
|
18
|
-
**
|
|
19
|
-
直接走 codebase-memory-mcp MCP server,然后用 `cancanneed.py` CLI:
|
|
19
|
+
**Hermes Agent(将 cancanneed 注册为工具):**
|
|
20
20
|
```bash
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
npm install -g cancanneed
|
|
22
|
+
# 复制适配器到 Hermes 工具目录(路径对所有 Node.js 安装方式通用)
|
|
23
|
+
ADAPTER="$(npm root -g)/cancanneed/hermes_adapter.py"
|
|
24
|
+
mkdir -p ~/.hermes/tools && cp "$ADAPTER" ~/.hermes/tools/
|
|
25
|
+
# 重启 hermes 后生效
|
|
26
|
+
```
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
**Claude Code / Codex CLI:**
|
|
29
|
+
```bash
|
|
30
|
+
npm install -g cancanneed
|
|
31
|
+
cancanneed /path/to/project --json
|
|
28
32
|
```
|
|
29
33
|
|
|
30
|
-
|
|
34
|
+
**无 npm 直接下载:**
|
|
31
35
|
```bash
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
python3
|
|
35
|
-
python3 ~/cancanneed/cancanneed.py --json /path/to/project # JSON 输出
|
|
36
|
-
python3 ~/cancanneed/cancanneed.py --skill # 输出 SKILL.md
|
|
36
|
+
curl -O https://registry.npmjs.org/cancanneed/-/cancanneed-0.1.2.tgz
|
|
37
|
+
tar xzf cancanneed-0.1.2.tgz
|
|
38
|
+
python3 package/cancanneed.py /path/to/project
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
## 前置条件
|
|
40
42
|
|
|
41
|
-
- Python 3.9
|
|
42
|
-
- [codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp) 二进制(用于首次索引)
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
- **Python 3.9+**(npm 安装时会自动提示)
|
|
44
|
+
- **[codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp)** 二进制(用于首次索引)
|
|
45
|
+
```bash
|
|
46
|
+
curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash
|
|
47
|
+
```
|
|
45
48
|
- 首次索引需要 10-60s,后续对同一目录秒级返回(增量索引)
|
|
46
49
|
|
|
47
50
|
## 输出示例
|
|
@@ -49,7 +52,6 @@ python3 ~/cancanneed/cancanneed.py --skill # 输出 SKILL.md
|
|
|
49
52
|
```
|
|
50
53
|
project: Users-lyx-ai-runtime-trace
|
|
51
54
|
root: /Users/lyx/ai-runtime-trace
|
|
52
|
-
indexed: 2026-07-11T02:54:07Z
|
|
53
55
|
nodes: 2255, edges: 4486
|
|
54
56
|
|
|
55
57
|
languages: Python 62, Markdown 57, YAML 21, Bash 11
|
|
@@ -57,19 +59,16 @@ languages: Python 62, Markdown 57, YAML 21, Bash 11
|
|
|
57
59
|
entry points:
|
|
58
60
|
hermes_flow/cli/analyze.py:main
|
|
59
61
|
experiments/agent-pool/cli.py:main
|
|
60
|
-
...
|
|
61
62
|
|
|
62
63
|
routes: ANY /api/admin/agents, ANY /api/admin/skills
|
|
63
64
|
|
|
64
65
|
hotspots:
|
|
65
66
|
connect (56 in) -- hermes_flow/storage.py
|
|
66
67
|
span (22 in) -- hermes_flow/trace.py
|
|
67
|
-
...
|
|
68
68
|
|
|
69
69
|
layers:
|
|
70
70
|
core: storage(55 in), schemas(23 in), trace(30 in)
|
|
71
71
|
entry: agent-pool, cli, observer, tools
|
|
72
|
-
...
|
|
73
72
|
|
|
74
73
|
complexity:
|
|
75
74
|
flow_init -- O(n^5) (hermes_flow/tools.py)
|
|
@@ -82,16 +81,6 @@ call chains:
|
|
|
82
81
|
|
|
83
82
|
(~2500 chars / ~600 tokens)
|
|
84
83
|
|
|
85
|
-
## 项目结构
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
~/cancanneed/
|
|
89
|
-
cancanneed.py # 核心模块 (纯 Python, 零依赖)
|
|
90
|
-
hermes_adapter.py # Hermes Agent 适配器 (复制到 ~/hermes-agent/tools/)
|
|
91
|
-
skills/SKILL.md # Hermes skill
|
|
92
|
-
README.md # 本文件
|
|
93
|
-
```
|
|
94
|
-
|
|
95
84
|
## License
|
|
96
85
|
|
|
97
86
|
MIT
|
|
Binary file
|
package/cancanneed.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// cancanneed npx wrapper — delegates to python3 cancanneed.py
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
|
|
7
|
+
const dir = __dirname;
|
|
8
|
+
const pyScript = fs.existsSync(path.join(dir, 'cancanneed.py'))
|
|
9
|
+
? path.join(dir, 'cancanneed.py')
|
|
10
|
+
: path.join(dir, '..', 'cancanneed.py');
|
|
11
|
+
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
const py = process.env.PYTHON || 'python3';
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const result = execSync(`"${py}" "${pyScript}" ${args.map(a => `"${a}"`).join(' ')}`, {
|
|
17
|
+
stdio: 'inherit',
|
|
18
|
+
timeout: 600000,
|
|
19
|
+
});
|
|
20
|
+
process.exit(0);
|
|
21
|
+
} catch (e) {
|
|
22
|
+
process.exit(e.status || 1);
|
|
23
|
+
}
|
package/cancanneed.py
CHANGED
|
@@ -13,13 +13,15 @@ from collections import Counter, defaultdict
|
|
|
13
13
|
CACHE_DIR = os.path.expanduser("~/.cache/codebase-memory-mcp")
|
|
14
14
|
|
|
15
15
|
def _find_cbm_binary():
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
"""查找 cancanneed 自带的索引器二进制(不依赖系统 PATH)。"""
|
|
17
|
+
# 1. cancanneed 包内(npm 安装后 node_modules/cancanneed/ 下)
|
|
18
|
+
own = os.path.join(os.path.dirname(os.path.abspath(__file__)), "cancanneed-indexer")
|
|
19
|
+
if os.path.isfile(own) and os.access(own, os.X_OK):
|
|
20
|
+
return own
|
|
21
|
+
# 2. 开发环境 ~/cancanneed/ 下
|
|
22
|
+
dev = os.path.expanduser("~/cancanneed/cancanneed-indexer")
|
|
23
|
+
if os.path.isfile(dev) and os.access(dev, os.X_OK):
|
|
24
|
+
return dev
|
|
23
25
|
return None
|
|
24
26
|
|
|
25
27
|
def _cbm_project_name(repo_path):
|
|
@@ -30,7 +32,7 @@ def _cbm_project_name(repo_path):
|
|
|
30
32
|
def _ensure_indexed(repo_path):
|
|
31
33
|
cbm = _find_cbm_binary()
|
|
32
34
|
if not cbm:
|
|
33
|
-
return None, "CBM binary not found.
|
|
35
|
+
return None, "CBM binary not found."
|
|
34
36
|
repo_path = os.path.abspath(repo_path)
|
|
35
37
|
if not os.path.isdir(repo_path):
|
|
36
38
|
return None, "Not a directory: %s" % repo_path
|
package/package.json
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cancanneed",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "代码仓库压缩骨架提取器 — ~2K tokens 看清项目全貌",
|
|
5
5
|
"bin": {
|
|
6
|
-
"cancanneed": "./cancanneed.
|
|
6
|
+
"cancanneed": "./cancanneed.js"
|
|
7
7
|
},
|
|
8
8
|
"files": [
|
|
9
9
|
"cancanneed.py",
|
|
10
|
-
"cancanneed.
|
|
10
|
+
"cancanneed.js",
|
|
11
|
+
"cancanneed-indexer",
|
|
11
12
|
"skills/SKILL.md",
|
|
12
13
|
"README.md"
|
|
13
14
|
],
|
|
15
|
+
"os": ["darwin", "linux"],
|
|
16
|
+
"cpu": ["arm64"],
|
|
14
17
|
"keywords": ["codebase", "skeleton", "architecture", "agent", "cbm"],
|
|
15
18
|
"license": "MIT"
|
|
16
19
|
}
|
package/cancanneed.sh
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
# cancanneed npx wrapper — finds cancanneed.py next to this script
|
|
3
|
-
DIR=$(cd "$(dirname "$0")" && pwd)
|
|
4
|
-
PY=${PYTHON:-python3}
|
|
5
|
-
if [ -f "$DIR/cancanneed.py" ]; then
|
|
6
|
-
exec "$PY" "$DIR/cancanneed.py" "$@"
|
|
7
|
-
elif [ -f "$DIR/../cancanneed.py" ]; then
|
|
8
|
-
# npx places bin scripts in node_modules/.bin/, files in node_modules/cancanneed/
|
|
9
|
-
exec "$PY" "$DIR/../cancanneed.py" "$@"
|
|
10
|
-
else
|
|
11
|
-
echo "cancanneed: cannot find cancanneed.py" >&2
|
|
12
|
-
exit 1
|
|
13
|
-
fi
|