feat(install): symlink myclaude to ~/.local/bin, make uninstall, docs
- Makefile: uv sync or venv pip install -e, then ln -sf to ~/.local/bin/myclaude - Add scripts/rm_user_local_myclaude.py for safe unlink on make uninstall - README: install path, shell completion guarded by command -v - Track uv.lock for reproducible uv sync Made-with: Cursor
This commit is contained in:
@@ -1,15 +1,30 @@
|
|||||||
ROOT_DIR := $(shell pwd)
|
ROOT_DIR := $(shell pwd)
|
||||||
|
VENV_MYCLAUDE := $(ROOT_DIR)/.venv/bin/myclaude
|
||||||
|
USER_LOCAL_MYCLAUDE := $(HOME)/.local/bin/myclaude
|
||||||
|
|
||||||
.PHONY: help install
|
.PHONY: help install uninstall _symlink-myclaude
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Usage: make [target]"
|
@echo "Usage: make [target]"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " install Editable pip install of myclaude (uses uv when available)"
|
@echo " install Sync venv (uv or pip), symlink $(USER_LOCAL_MYCLAUDE) -> .venv/bin/myclaude"
|
||||||
|
@echo " uninstall Remove $(USER_LOCAL_MYCLAUDE) if it is a symlink to this repo"
|
||||||
|
|
||||||
install:
|
install:
|
||||||
@if command -v uv >/dev/null 2>&1; then \
|
@cd "$(ROOT_DIR)" && \
|
||||||
uv pip install -e "$(ROOT_DIR)"; \
|
if command -v uv >/dev/null 2>&1; then \
|
||||||
|
uv sync; \
|
||||||
else \
|
else \
|
||||||
python3 -m pip install -e "$(ROOT_DIR)"; \
|
test -x .venv/bin/pip || python3 -m venv .venv; \
|
||||||
|
.venv/bin/pip install -e .; \
|
||||||
fi
|
fi
|
||||||
|
@$(MAKE) _symlink-myclaude
|
||||||
|
|
||||||
|
_symlink-myclaude:
|
||||||
|
@test -x "$(VENV_MYCLAUDE)" || { echo "error: missing $(VENV_MYCLAUDE)"; exit 1; }
|
||||||
|
@mkdir -p "$(HOME)/.local/bin"
|
||||||
|
@ln -sf "$(VENV_MYCLAUDE)" "$(USER_LOCAL_MYCLAUDE)"
|
||||||
|
@echo "Linked $(USER_LOCAL_MYCLAUDE) -> $(VENV_MYCLAUDE)"
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
@ROOT_DIR="$(ROOT_DIR)" python3 "$(ROOT_DIR)/scripts/rm_user_local_myclaude.py"
|
||||||
|
|||||||
@@ -151,38 +151,23 @@ git --version # 确认已安装
|
|||||||
git clone <repository-url> ~/your-path/myclaude
|
git clone <repository-url> ~/your-path/myclaude
|
||||||
cd ~/your-path/myclaude
|
cd ~/your-path/myclaude
|
||||||
|
|
||||||
# 安装(会自动检测并使用 uv 或 pip)
|
# 安装(uv 则 uv sync,否则创建 .venv 并用 pip install -e)
|
||||||
make install
|
make install
|
||||||
```
|
```
|
||||||
|
|
||||||
> 💡 **提示**:如未安装 uv,会使用系统 pip 安装,速度稍慢
|
会在 `~/.local/bin/myclaude` 创建指向本仓库 `.venv/bin/myclaude` 的符号链接;请保证 `~/.local/bin` 在 `PATH` 中(多数发行版默认已包含)。移除该链接:`make uninstall`(仅当链接目标为本仓库的 `.venv/bin/myclaude` 时才会删除)。
|
||||||
|
|
||||||
**配置快捷命令:**
|
> 💡 **提示**:无 uv 时会创建项目 `.venv` 并用其中的 pip 做可编辑安装。
|
||||||
|
|
||||||
将 `myclaude` 添加到 shell 配置,方便全局调用:
|
**Shell 补全(可选):** 在 `~/.zshrc` 或 `~/.bashrc` 中加入(有命令再注册,避免未安装时报错):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 编辑 ~/.zshrc 或 ~/.bashrc
|
if command -v myclaude >/dev/null 2>&1; then
|
||||||
MYCLAUDE_PATH="$HOME/your-path/myclaude" # 修改为你的实际路径
|
eval "$(_MYCLAUDE_COMPLETE=zsh_source myclaude)"
|
||||||
if [ -d "$MYCLAUDE_PATH/.venv/bin" ]; then
|
|
||||||
alias myclaude=$MYCLAUDE_PATH/.venv/bin/myclaude
|
|
||||||
eval "$(_MYCLAUDE_COMPLETE=zsh_source myclaude)" # zsh 补全
|
|
||||||
# eval "$(_MYCLAUDE_COMPLETE=bash_source myclaude)" # bash 补全
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 使配置生效
|
|
||||||
source ~/.zshrc # 或 source ~/.bashrc
|
|
||||||
```
|
```
|
||||||
|
|
||||||
验证并启动:
|
Bash 将 `zsh_source` 换成 `bash_source`。保存后 `source` 该配置文件。
|
||||||
|
|
||||||
```bash
|
|
||||||
# 验证安装
|
|
||||||
myclaude --version
|
|
||||||
|
|
||||||
# 启动本地交互模式
|
|
||||||
myclaude chat
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. 安装 Metabot
|
### 5. 安装 Metabot
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Remove ~/.local/bin/myclaude if it is a symlink to this repo's .venv/bin/myclaude."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
root = os.path.normpath(os.environ.get("ROOT_DIR", os.getcwd()))
|
||||||
|
link = os.path.expanduser("~/.local/bin/myclaude")
|
||||||
|
want = os.path.normpath(os.path.join(root, ".venv", "bin", "myclaude"))
|
||||||
|
|
||||||
|
if not os.path.islink(link):
|
||||||
|
if os.path.lexists(link):
|
||||||
|
print("Skip: not a symlink, leaving untouched")
|
||||||
|
else:
|
||||||
|
print("Nothing to remove")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
target = os.readlink(link)
|
||||||
|
if not os.path.isabs(target):
|
||||||
|
target = os.path.join(os.path.dirname(link), target)
|
||||||
|
target = os.path.normpath(target)
|
||||||
|
|
||||||
|
if target == want:
|
||||||
|
os.unlink(link)
|
||||||
|
print("Removed", link)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
print("Skip: points to", target, "(not this repo's", want + ")")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
version = 1
|
||||||
|
revision = 3
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "click"
|
||||||
|
version = "8.3.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/57/75/31212c6bf2503fdf920d87fee5d7a86a2e3bcf444984126f13d8e4016804/click-8.3.2.tar.gz", hash = "sha256:14162b8b3b3550a7d479eafa77dfd3c38d9dc8951f6f69c78913a8f9a7540fd5", size = 302856, upload-time = "2026-04-03T19:14:45.118Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e4/20/71885d8b97d4f3dde17b1fdb92dbd4908b00541c5a3379787137285f602e/click-8.3.2-py3-none-any.whl", hash = "sha256:1924d2c27c5653561cd2cae4548d1406039cb79b858b747cfea24924bbc1616d", size = 108379, upload-time = "2026-04-03T19:14:43.505Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorama"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "markdown-it-py"
|
||||||
|
version = "4.0.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "mdurl" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mdurl"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "myclaude"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = { editable = "." }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "click" },
|
||||||
|
{ name = "rich" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [
|
||||||
|
{ name = "click", specifier = ">=8.0.0" },
|
||||||
|
{ name = "rich", specifier = ">=13.0.0" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pygments"
|
||||||
|
version = "2.20.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rich"
|
||||||
|
version = "14.3.3"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "markdown-it-py" },
|
||||||
|
{ name = "pygments" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/b3/c6/f3b320c27991c46f43ee9d856302c70dc2d0fb2dba4842ff739d5f46b393/rich-14.3.3.tar.gz", hash = "sha256:b8daa0b9e4eef54dd8cf7c86c03713f53241884e814f4e2f5fb342fe520f639b", size = 230582, upload-time = "2026-02-19T17:23:12.474Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl", hash = "sha256:793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d", size = 310458, upload-time = "2026-02-19T17:23:13.732Z" },
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user