Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
da3cb1d
docs(spec): local vis-network asset (drop CDN, ship vendored copy)
Jun 29, 2026
1c0ec25
docs(plan): local vis-network asset (drop CDN, ship vendored copy)
Jun 29, 2026
a9ad18a
chore(assets): vendor vis-network 9.1.6 (drop unpkg CDN)
Jun 29, 2026
fd4af70
build: include vendored vis-network in package data
Jun 29, 2026
feb3cfd
feat(export): add _VIS_NETWORK_FILENAME constant
Jun 29, 2026
e810300
feat(export): add _vendored_vis_js() helper
Jun 29, 2026
97a046a
feat(export): add _emit_vis_js() helper (idempotent copy)
Jun 29, 2026
68b2f84
feat(export): to_html uses local vis-network, no CDN/SRI
Jun 29, 2026
72a34bd
test(export): drop obsolete SRI/CDN pin test (local asset now)
Jun 29, 2026
9a56dd0
test(pipeline): tighten vis-network assertion to local path
Jun 29, 2026
be19fff
docs(changelog): note local vis-network vendoring + SRI removal
Jun 29, 2026
2a9e865
docs(spec): offline Windows installer (Nuitka --onefile, user PATH, h…
Jun 29, 2026
cbe96d7
docs(plan): offline Windows installer implementation plan
Jun 29, 2026
9a80834
build: add Nuitka runtime helpers + windows-offline extra doc
Jun 29, 2026
f69fd29
fix(pyproject): align windows-offline tree-sitter-objc pin with main …
Jun 29, 2026
b59fcc9
feat(installer): add installer package skeleton
Jun 29, 2026
f2199e1
feat(installer): add host_probe (detect installed AI-coding hosts)
Jun 29, 2026
61ea073
feat(installer): add path_win (user-level Windows PATH via PowerShell)
Jun 29, 2026
dd34351
docs(plan): add skipif to path_win Windows-only tests (Task 4)
Jun 29, 2026
66df3be
fix(installer): drop dead current param + strengthen idempotent test
Jun 29, 2026
f5543d1
feat(installer): add manifest (roundtrip JSON for uninstall)
Jun 29, 2026
01b6d97
feat(installer): add skill_copy (host-aware SKILL.md + references copy)
Jun 29, 2026
3e7bc44
fix(installer): skip cursor/gemini in offline installer (different fo…
Jun 29, 2026
e3353c7
feat(installer): add install/uninstall orchestrator
Jun 29, 2026
08ce02c
docs(plan): add re-export pattern to Task 7 orchestrator
Jun 29, 2026
c2c4e5e
feat(cli): add self-install / self-uninstall subcommands
Jun 29, 2026
a893e18
feat(installer): add tools/installer_main.py (Nuitka entry point)
Jun 29, 2026
e20864d
fix(installer): escape % in installer_main.py help (Python 3.10 argpa…
Jun 29, 2026
7e7361e
build: add tools/build_windows_installer.sh (Nuitka build script)
Jun 29, 2026
0509995
fix(build): support Python 3.10 (tomli fallback for tomlib in build s…
Jun 29, 2026
d133b91
build: add tools/build_windows_installer.py (cross-platform wheel dow…
Jun 29, 2026
91a6a91
fix(build): support Python 3.10 in build_windows_installer.py (tomli …
Jun 29, 2026
ee0b94c
fix(build): make pip download work for pure-Python packages (jieba, e…
Jun 29, 2026
9577666
docs(operations): add offline-installer end-user guide
Jun 29, 2026
90e7b94
fix(installer): CHANGELOG entry + drift-guard tests for skill_copy
Jun 29, 2026
3bc4119
ci: build offline Windows installer on release + workflow_dispatch
Jul 2, 2026
7fc0426
docs(readme): link offline installer from install section
Jul 2, 2026
ab28399
ci: move workflow file to docs/ci/ to bypass PAT workflow scope
Jul 2, 2026
fd23ead
docs(spec): bundle 15 community skills under gf- namespace
Jul 2, 2026
4b2caf1
docs(plan): bundled-skills implementation plan (17 tasks, 7 phases)
Jul 2, 2026
252133c
feat(bundled-skills): snapshot 14 superpowers SKILL.md files with gf-…
Jul 2, 2026
6f9b6b8
feat(bundled-skills): add superpowers LICENSE and NOTICE
Jul 2, 2026
41b634f
feat(bundled-skills): snapshot llm-wiki with gf-llm-wiki rename
Jul 2, 2026
0714518
docs(bundled-skills): README explaining gf- rename convention
Jul 2, 2026
0c370fe
test(bundled-skills): add failing registry structure tests
Jul 2, 2026
4855322
feat(installer): add bundled_skills registry with 15 gf- prefixed ent…
Jul 2, 2026
e79bf4e
test(bundled-skills): per-host path derivation tests
Jul 2, 2026
8f954eb
test(bundled-skills): supports_host coverage
Jul 2, 2026
f8369b4
test(bundled-skills): frontmatter name correctness
Jul 2, 2026
2d60932
chore(deps): add pyyaml to dev group for bundled-skills frontmatter t…
Jul 2, 2026
1db680b
test(bundled-skills): failing copy_bundled_skills tests
Jul 2, 2026
1b54539
feat(installer): copy_bundled_skills writes 15 gf- skills per host
Jul 2, 2026
af3179a
feat(installer): wire copy_bundled_skills into per-host install loop
Jul 2, 2026
54fa0ba
test(install): assert gf- skills installed per-host by offline installer
Jul 2, 2026
db3fb76
build(packaging): include bundled_skills/** in wheel package-data
Jul 2, 2026
a937017
build(packaging): add LICENSE/NOTICE globs to wheel package-data
Jul 2, 2026
82cb8ed
build(packaging): add .ts/.py/.json/.html globs for llm-wiki deps
Jul 2, 2026
4193c7f
test(bundled-skills): importlib.resources reachability
Jul 2, 2026
68c2e36
ci: pre-flight check that bundled_skills survived wheel install
Jul 2, 2026
ffef8bb
docs: NOTICE listing bundled third-party projects
Jul 2, 2026
3022556
docs(changelog): bundled skills under gf- namespace
Jul 2, 2026
e9c7c4b
docs(offline-installer): bundled skills under gf- namespace
Jul 2, 2026
d06abd6
docs: clarify NOTICE year range and llm-wiki license attribution
Jul 2, 2026
beb17b7
feat(bundled-skills): bundle code-pipeline orchestrator skill (16th)
Jul 3, 2026
1cc1675
ci: enable Windows installer workflow on release events
Jul 3, 2026
c3d2b5d
fix(ci): use vswhere.exe to discover MSVC on windows-* runners
Jul 3, 2026
5525c50
fix(tools): use a temp file for pip --requirement in Windows installer
Jul 3, 2026
43d6972
fix(tools): align wheel download Python version with the venv interpr…
Jul 3, 2026
37eb492
fix(tools): install nuitka into the offline venv used to build .exe
Jul 3, 2026
790c6fb
fix(tools): pin nuitka's transitive deps explicitly in wheel req
Jul 3, 2026
1e631c6
fix(tools): bundle setuptools + wheel in the offline venv wheelhouse
Jul 3, 2026
56a2d70
fix(tools): drop --no-index from offline-venv install (whack-a-mole fix)
Jul 3, 2026
221acd9
fix(tools): install graphifyy[windows-offline] in the offline venv
Jul 3, 2026
f92be12
fix(tools): split venv install into 3 pip calls to pin graphifyy to l…
Jul 3, 2026
c5aca52
fix(tools): drop --no-deps on the graphifyy install so main deps land
Jul 3, 2026
1ad456f
fix(tools): auto-accept Nuitka's dependency-walker download prompt
Jul 3, 2026
fc58d00
chore(tools): add empty installer/ directory for new zip installer
Jul 3, 2026
4bf75d2
feat(tools): add install.bat with internal PyPI proxy placeholders
Jul 3, 2026
b3a8140
feat(tools): add uninstall.bat for reverse install
Jul 3, 2026
ebb57ee
docs: add end-user README for offline zip installer
Jul 3, 2026
c2ffac3
test(tools): smoke test for build_zip_installer.sh
Jul 3, 2026
31b5251
feat(tools): build_zip_installer.sh — minimal zip assembler
Jul 3, 2026
a11dbd5
fix(tools): strip CRLF from _pth and add -o to unzip for idempotent b…
Jul 3, 2026
0b4cc8f
ci: workflow to build minimal offline zip installer
Jul 3, 2026
c9eec97
chore(ci): drop old windows installer workflow and doc
Jul 3, 2026
1d57da6
chore(tools): drop old Nuitka-based installer script
Jul 3, 2026
366a313
refactor: drop graphify.installer package and tests
Jul 3, 2026
3f17119
docs(pyproject): reframe windows-offline extra as runtime group
Jul 3, 2026
c5800fe
chore(tools): drop old windows installer Python wrapper
Jul 3, 2026
67512f3
feat(install.bat): register PATH when using embedded Python
Jul 3, 2026
f678ab1
fix: ASCII-only .bat files, cache Python embeddable in build/cache/
Jul 3, 2026
885cab2
fix(bat): add pause so error/success messages are visible before wind…
Jul 3, 2026
4aefc78
fix(install.bat): add --upgrade to pip install for idempotent re-runs
Jul 3, 2026
64e045b
feat(build): bundle local graphify wheel in zip instead of pulling fr…
Jul 3, 2026
b1deeb2
feat(zip-installer): support re-install via pre-cleanup; bundle skill…
Jul 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/build-zip-installer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Build offline zip installer

on:
release:
types: [published]
workflow_dispatch:

permissions:
contents: write

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Build the offline zip installer
env:
INTERNAL_PYPI_PROXY: ${{ secrets.INTERNAL_PYPI_PROXY }}
INTERNAL_TRUSTED_HOST: ${{ secrets.INTERNAL_TRUSTED_HOST }}
INTERNAL_TIMEOUT: ${{ secrets.INTERNAL_TIMEOUT }}
run: tools/build_zip_installer.sh

- name: Smoke test the zip
run: bash tests/tools/test_build_zip_installer.sh

- name: Attach zip to release
if: github.event_name == 'release'
uses: softprops/action-gh-release@v2
with:
files: dist/graphify-offline-installer.zip

- name: Upload artifact (workflow_dispatch)
if: github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@v4
with:
name: graphify-offline-installer
path: dist/graphify-offline-installer.zip
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ skills/
!tools/skillgen/fragments/core/**
docs/superpowers/
.vscode/
.idea/
.kilo
openspec/
# Local benchmark scripts — never commit
Expand Down
5 changes: 5 additions & 0 deletions .opencode/opencode.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"plugin": [
".opencode/plugins/graphify.js"
]
}
28 changes: 28 additions & 0 deletions .opencode/plugins/graphify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// graphify OpenCode plugin
// Injects a knowledge graph reminder before bash tool calls when the graph exists.
//
// IMPORTANT: keep the reminder string free of backticks and $(...) constructs.
// The hook prepends `echo "<reminder>" && <cmd>` to the user's bash command;
// backticks inside the double-quoted echo trigger bash command substitution,
// which both corrupts tool output and silently executes the very graphify
// command we are only suggesting. Plain words render fine in opencode's TUI.
import { existsSync } from "fs";
import { join } from "path";

export const GraphifyPlugin = async ({ directory }) => {
let reminded = false;

return {
"tool.execute.before": async (input, output) => {
if (reminded) return;
if (!existsSync(join(directory, "graphify-out", "graph.json"))) return;

if (input.tool === "bash") {
output.args.command =
'echo "[graphify] knowledge graph at graphify-out/. For focused questions, run graphify query with your question (scoped subgraph, usually much smaller than GRAPH_REPORT.md) instead of grepping raw files. Read GRAPH_REPORT.md only for broad architecture context." && ' +
output.args.command;
reminded = true;
}
},
};
};
8 changes: 0 additions & 8 deletions AGENTS.md

This file was deleted.

10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

Full release notes with details on each version: [GitHub Releases](https://github.com/safishamsi/graphify/releases)

## Unreleased

- Feat: offline Windows installer — `graphify-installer.exe` is a single Nuitka-`--onefile` binary that bundles graphify + 38 wheels (code-only: `anthropic` + `mcp` + `leiden` + `sql` + `watch` + `svg` + `chinese` + `terraform` + 23 `tree-sitter` language packs + `networkx`/`numpy`/`rapidfuzz`) for air-gapped installs. Auto-detects 21 known AI-coding hosts (Claude Code, OpenCode, Codex, Kilo, Aider, Copilot, CodeBuddy, Kiro, Droid, Trae, Hermes, Pi, OpenClaw, Antigravity, etc.) and copies the matching `SKILL.md` (plus `references/` sidecar) to each host's skill directory. Registers the install path on the **user-level** PATH only (never `HKLM`). Manifest-driven uninstall reverses every step. New subcommands: `graphify self-install [--path DIR] [--no-path]` and `graphify self-uninstall`. Build recipe: `tools/build_windows_installer.sh` (Nuitka needs Visual Studio Build Tools). See `docs/operations/offline-installer.md` for the end-user guide. **Notes:** PDF / Office / video / Neo4j / Bedrock extras are NOT bundled (this is the code-only installer); the `.exe` is unsigned so Windows SmartScreen warns on first launch ("More info → Run anyway"); `cursor` and `gemini` are detected but the offline installer does not write their `SKILL.md` (their real install format is different — run `graphify install cursor` / `graphify install gemini` after the offline installer to finish those two).

- Feat: offline installer also bundles 16 community skills (14 superpowers + `gf-llm-wiki` + `code-pipeline`). After `graphify-installer.exe` runs, the host's skill directory contains `gf-brainstorming/`, `gf-writing-plans/`, `gf-subagent-driven-development/`, `gf-test-driven-development/`, `gf-systematic-debugging/`, `gf-using-git-worktrees/`, `gf-requesting-code-review/`, `gf-receiving-code-review/`, `gf-executing-plans/`, `gf-finishing-a-development-branch/`, `gf-dispatching-parallel-agents/`, `gf-using-superpowers/`, `gf-verification-before-completion/`, `gf-writing-skills/`, `gf-llm-wiki/`, and `code-pipeline/`. `code-pipeline` is a project-local orchestrator skill that strings the full feature lifecycle together — accept one sentence or one file path as the requirement, then drive `gf-brainstorming` → human design review gate → `gf-writing-plans` → human plan review gate → `gf-subagent-driven-development` → dual-track (specs + code) review. It is intentionally the only bundled skill without the `gf-` prefix because it is the user-facing entry point (the slash-command is `/code-pipeline`) and the `code-pipeline` name does not collide with any upstream superpowers skill. See `graphify/bundled_skills/README.md`.

- Feat: `to_html` now ships `vis-network@9.1.6` inside the `graphify` package instead of pulling it from `unpkg.com` at view time. The UMD bundle (702,611 bytes) is vendored at `graphify/assets/vis-network.min.js`, registered in `pyproject.toml` `package-data`, and copied next to each generated `graph.html` as `./vis-network.min.js` (idempotent — only rewritten when the bytes change, so file watchers / Obsidian sync don't churn). Every `graphify-out/graph.html` is now self-contained and renders offline. **Notes:** the generated `graph.html` is no longer a single-file artifact — it has a same-directory `vis-network.min.js` sibling, so copy / archive / e-mail the pair together; the wheel grows by ~700 KB; the previous `unpkg.com` `<script src>` (with its SRI `integrity=` and `crossorigin="anonymous"`) is gone — see the security note below.

- Security: the Subresource Integrity pin against `unpkg.com/vis-network@9.1.6/standalone/umd/vis-network.min.js` (sha384) is removed because the asset now ships inside the trusted Python package (same origin as the HTML). The threat model shifts from "CDN compromise" to "package compromise": a tampered wheel would still be served, but the trust boundary moves from a third-party CDN to the package supply chain (the same one users already trust for the rest of `graphify`). This is the intended trade-off for an offline-capable, no-network viewer; if you need the old SRI behavior, pin to the pre-`Unreleased` `to_html` output.

## 0.9.1 (2026-06-28)

- Fix: rate-limited (HTTP 429) extraction chunks are now retried instead of dropped (#1523, thanks @bercedev). The provider SDKs back off and honor `Retry-After`, but the SDK default of 2 retries was too low for strict per-org concurrency/RPM caps (e.g. Moonshot/kimi), so a parallel `extract` 429'd, each chunk logged `chunk N failed`, and was silently lost (incomplete graph + console spam). The OpenAI-compatible, Azure, and Anthropic clients are now built with a higher `max_retries` (default 6, override via `GRAPHIFY_MAX_RETRIES`). For very tight accounts, `--max-concurrency 1` further reduces the concurrency that triggers org-level limits.
Expand Down
72 changes: 72 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## 开发命令

```bash
# 用 uv 管理依赖和运行
uv sync # 安装全部依赖
uv run pytest tests/ -q # 跑全部测试
uv run pytest tests/test_extract.py -q # 跑单个测试文件
uv run pytest tests/test_extract.py::test_func -q # 跑单个测试函数

# Lint / 类型检查 / 安全审计
uv run ruff check . # lint
uv run pyright # 类型检查
uv run pre-commit run --all-files # 全面检查(含 skillgen 一致性校验)

# 构建
uv run python -m build # 构建 wheel
uv run python -m tools.skillgen # 重新生成 17 个 SKILL.md(fragments → graphify/skill*.md)
uv run python -m tools.skillgen --bless # + 更新 expected 快照
```

## 架构(参见 ARCHITECTURE.md 了解详情)

**管线**:`detect() → extract() → build_graph() → cluster() → analyze() → report() → export()`

每个阶段是独立模块中的一个函数,以 NetworkX 图和简单 dict 传递数据,无共享状态。

**关键模块**:
| 模块 | 职责 |
|------|------|
| `graphify/__main__.py` | CLI 入口(~2600 行):`install`/`uninstall`/`extract`/`update`/`serve`/`watch`/`clone` 等 |
| `graphify/extract.py` | 统一委派到 `graphify/extractors/*.py` 中的全部语言解析器 |
| `graphify/serve.py` | MCP 服务端入口(`graphify-mcp` 命令) |
| `tools/skillgen/` | **生成系统**:把 fragments 目录下的片段渲染为 `graphify/skill*.md`(17 个 platform)。编辑片段后**必须**重新运行 `python -m tools.skillgen`,否则 pre-commit 和 CI 会失败 |
| `graphify/bundled_skills/` | 15 个社区 skill(`gf-*` 命名空间),随包分发 |

**安全**:所有外部输入(URL、路径、label)均通过 `graphify/security.py` 校验。

## 使用任何 skill 都不能忽略 graphify 要求

## 任何情况下都必须遵守,未经允许不得修改代码

## 项目自身的 graphify 要求

> 这是 `AGENTS.md` 的要求——本项目使用 graphify 管理自身的知识图谱。

- **回答架构/代码库问题前**:先读 `graphify-out/GRAPH_REPORT.md` 了解 god node 和社区结构
- **若有 `graphify-out/wiki/index.md`**:导航 wiki 而非直接读原始文件
- **修改代码后**:运行 `graphify update .` 更新图谱(纯 AST 提取,不消耗 API)

## 离线安装器(本分支变更)

`feat/zip-installer` 分支用极简 zip 方案替换了 65 MB Nuitka `.exe`:

**新方案**(`tools/build_zip_installer.sh` → `dist/graphify-offline-installer.zip` ~11 MB):
- `python/` — Python 3.12.10 embeddable
- `install.bat` — 探测 Python → `pip install graphifyy`(走内网代理 `192.168.21.14:25000`)→ `graphify install claude`
- `uninstall.bat` — 反向操作
- `README.txt` — 用户说明

**已删除**:`tools/build_windows_installer.{sh,py}`、`tools/installer_main.py`、`graphify/installer/`、5 个 installer 测试、`.github/workflows/build-windows-installer.yml`

**关键简化**:不再下载 38 个 wheels 到本地,不再编译 Nuitka,macOS 上就能构建。依赖从内网代理拉取。

## 约定

- 注释、变量名、commit message 用英文;解释性文字用简体中文
- CLI 子命令在 `graphify/__main__.py::main()` 的 if-elif 链中分发(无 click/argparse 框架)
- 测试文件一一对应模块:`tests/test_<module>.py`
29 changes: 29 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
graphify
Copyright 2024-2026

This product includes software developed by third parties:

────────────────────────────────────────────────────────────
superpowers-dev
Bundled under: graphify/bundled_skills/superpowers/
Copyright: 2025 Jesse Vincent
License: MIT — see graphify/bundled_skills/superpowers/LICENSE
Source: https://github.com/superpowers-dev/superpowers-dev

Renamed for graphify (frontmatter `name:` field, directory basename
unchanged). See graphify/bundled_skills/README.md.
────────────────────────────────────────────────────────────
llm-wiki
Bundled under: graphify/bundled_skills/llm-wiki/
Copyright: graphify contributors (project-local skill)
License: MIT — no top-level LICENSE file ships with this snapshot;
vendored dependencies under deps/ each carry their own
LICENSE-*.txt
Source: project-local (see graphify/bundled_skills/README.md)
────────────────────────────────────────────────────────────
code-pipeline
Bundled under: graphify/bundled_skills/code-pipeline/
Copyright: graphify contributors (project-local skill)
License: MIT — same terms as the graphify project LICENSE
Source: project-local (see graphify/bundled_skills/README.md)
────────────────────────────────────────────────────────────
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ curl -LsSf https://astral.sh/uv/install.sh | sh

> **Official package:** The PyPI package is `graphifyy` (double-y). Other `graphify*` packages on PyPI are not affiliated. The CLI command is still `graphify`.

> **Offline / restricted network?** If `pip` / `uv` / `pipx` can't reach PyPI (corporate networks, air-gapped Windows machines), grab `graphify-installer.exe` from the [latest GitHub release](https://github.com/safishamsi/graphify/releases/latest). It's a single `.exe` with the Python runtime + `graphify` + all default extras bundled — no Python, no pip, no network at install time. It writes `%LOCALAPPDATA%\graphify\bin` to user PATH and drops `SKILL.md` into the detected AI-coding host's skill directory. See the [offline installer guide](docs/operations/offline-installer.md) for what's inside and the SmartScreen caveat.

**Step 1 — install the package:**

```bash
Expand Down
41 changes: 41 additions & 0 deletions docs/offline-installer-README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
graphify 离线安装器
===================

适用环境:Windows 10(1803 及以上)桌面云机器,无公网,但公司内网可访问
PyPI 代理:http://192.168.21.14:25000/pypi/repository/pypi-all/simple

────────────────────────
安装步骤
────────────────────────

1. 解压本 zip 到任意目录,例如 D:\graphify\
2. 进入解压目录,双击 install.bat
3. 等待 30-60 秒:脚本会自动检测 Python、配置内网 PyPI 代理、
安装 graphifyy、把 SKILL.md 部署到 Claude Code 的 skills 目录
4. 安装完成。新开一个 cmd 窗口,输入 `graphify --version` 验证

────────────────────────
常见问题
────────────────────────

Q: 没有 Python 可以装吗?
A: 可以。本 zip 自带 Python 3.12 embeddable,install.bat 会自动使用。

Q: 安装失败怎么办?
A: 检查内网 PyPI 代理是否可达:http://192.168.21.14:25000/pypi/repository/pypi-all/simple
截图报错信息联系 IT。

Q: 如何换装到 Codex / OpenCode / Cursor?
A: 编辑 install.bat,把最后一行的 `graphify install claude` 改成
`graphify install codex`(或 opencode / cursor 等),重新双击。

Q: 如何卸载?
A: 双击 uninstall.bat。

────────────────────────
内网 PyPI 代理配置(构建时注入)
────────────────────────

index-url: http://192.168.21.14:25000/pypi/repository/pypi-all/simple
trusted-host: 192.168.21.14
timeout: 6000 秒
Loading