napcat-cli 2.0.0__tar.gz → 2.0.1__tar.gz
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.
- napcat_cli-2.0.1/.github/workflows/release.yml +138 -0
- napcat_cli-2.0.0/README.md → napcat_cli-2.0.1/PKG-INFO +34 -1
- napcat_cli-2.0.0/PKG-INFO → napcat_cli-2.0.1/README.md +19 -12
- napcat_cli-2.0.1/napcat-cli-fs/pyproject.toml +13 -0
- napcat_cli-2.0.1/napcat-cli-fs/scripts/build-wheel.py +128 -0
- napcat_cli-2.0.1/napcat-cli-fs/src/napcat_cli_fs/__init__.py +23 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/daemon/watch.py +17 -6
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/pyproject.toml +3 -1
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/.gitignore +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/.gitmodules +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/docs/HERMES_WAKE.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/__init__.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/cli.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/daemon/__init__.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/daemon/schemas.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/SKILL.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/__init__.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/persona.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/references/mounting.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/skills-fs-config.json +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/skills-fs-fragment.json +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/skills-fs.d/agents-friend-time.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/skills-fs.d/agents-friend.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/skills-fs.d/agents-friends.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/skills-fs.d/agents-group-time.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/skills-fs.d/agents-group.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/skills-fs.d/agents-groups.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/skills-fs.d/agents-napcat.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/skills-fs.d/persona.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/skills-fs.d/skill-agents.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/data/skills-fs.d/skill-body.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/lib/__init__.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/lib/api.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/lib/config.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/lib/events.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/lib/events_sqlite.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/lib/message.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/setup_wizard.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/tui/__init__.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/tui/__main__.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/tui/api.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/tui/app.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/tui/chat_list.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/tui/chat_view.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/tui/styles.tcss +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/wake.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/wake_backend.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/wake_orchestrator.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/napcat_cli/wake_presets.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/persona.md +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/skills-fs-config.json +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/tests/conftest.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/tests/test_config.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/tests/test_fs.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/tests/test_setup.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/tests/test_wake.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/tests/test_wake_backend.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/tests/test_wake_orchestrator.py +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/tools/agents-md.json +0 -0
- {napcat_cli-2.0.0 → napcat_cli-2.0.1}/tools/gen_mounts.py +0 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Unified release workflow for napcat-cli + napcat-cli-fs
|
|
2
|
+
#
|
|
3
|
+
# Trigger: manual (workflow_dispatch).
|
|
4
|
+
# - Builds napcat-cli (pure Python wheel) and napcat-cli-fs (platform wheels
|
|
5
|
+
# for linux/macos/windows × amd64/arm64).
|
|
6
|
+
# - Uploads all artifacts.
|
|
7
|
+
# - If ``publish`` is checked AND ``PYPI_TOKEN`` secret exists, publishes
|
|
8
|
+
# everything to PyPI.
|
|
9
|
+
#
|
|
10
|
+
# Setup (one time):
|
|
11
|
+
# 1. Go to repo Settings → Secrets and variables → Actions
|
|
12
|
+
# 2. Add repository secret ``PYPI_TOKEN`` with your PyPI API token
|
|
13
|
+
# (user: __token__, password: pypi-...)
|
|
14
|
+
---
|
|
15
|
+
name: Release
|
|
16
|
+
|
|
17
|
+
on:
|
|
18
|
+
workflow_dispatch:
|
|
19
|
+
inputs:
|
|
20
|
+
publish:
|
|
21
|
+
description: "Upload to PyPI (requires PYPI_TOKEN secret)"
|
|
22
|
+
type: boolean
|
|
23
|
+
default: false
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
# ── napcat-cli (pure Python wheel) ──────────────────────────────────
|
|
27
|
+
build-napcat-cli:
|
|
28
|
+
name: Build napcat-cli wheel
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v4
|
|
32
|
+
with:
|
|
33
|
+
fetch-depth: 1
|
|
34
|
+
|
|
35
|
+
- uses: actions/setup-python@v5
|
|
36
|
+
with:
|
|
37
|
+
python-version: "3.13"
|
|
38
|
+
|
|
39
|
+
- name: Build wheel + sdist
|
|
40
|
+
run: |
|
|
41
|
+
pip install build
|
|
42
|
+
python -m build
|
|
43
|
+
|
|
44
|
+
- uses: actions/upload-artifact@v4
|
|
45
|
+
with:
|
|
46
|
+
name: wheel-napcat-cli
|
|
47
|
+
path: dist/*.whl dist/*.tar.gz
|
|
48
|
+
|
|
49
|
+
# ── napcat-cli-fs (platform wheels) ────────────────────────────────
|
|
50
|
+
build-fs:
|
|
51
|
+
name: skills-fs ${{ matrix.label }}
|
|
52
|
+
runs-on: ${{ matrix.runner }}
|
|
53
|
+
strategy:
|
|
54
|
+
fail-fast: false
|
|
55
|
+
matrix:
|
|
56
|
+
include:
|
|
57
|
+
- label: linux-amd64
|
|
58
|
+
runner: ubuntu-latest
|
|
59
|
+
goos: linux; goarch: amd64
|
|
60
|
+
binary: skills-fs
|
|
61
|
+
tag: manylinux_2_17_x86_64.manylinux2014_x86_64
|
|
62
|
+
|
|
63
|
+
- label: linux-arm64
|
|
64
|
+
runner: ubuntu-latest
|
|
65
|
+
goos: linux; goarch: arm64
|
|
66
|
+
binary: skills-fs
|
|
67
|
+
tag: manylinux_2_17_aarch64.manylinux2014_aarch64
|
|
68
|
+
|
|
69
|
+
- label: macos-amd64
|
|
70
|
+
runner: macos-13
|
|
71
|
+
goos: darwin; goarch: amd64
|
|
72
|
+
binary: skills-fs
|
|
73
|
+
tag: macosx_10_9_x86_64
|
|
74
|
+
|
|
75
|
+
- label: macos-arm64
|
|
76
|
+
runner: macos-14
|
|
77
|
+
goos: darwin; goarch: arm64
|
|
78
|
+
binary: skills-fs
|
|
79
|
+
tag: macosx_11_0_arm64
|
|
80
|
+
|
|
81
|
+
- label: windows-amd64
|
|
82
|
+
runner: windows-latest
|
|
83
|
+
goos: windows; goarch: amd64
|
|
84
|
+
binary: skills-fs.exe
|
|
85
|
+
tag: win_amd64
|
|
86
|
+
|
|
87
|
+
env:
|
|
88
|
+
GOOS: ${{ matrix.goos }}
|
|
89
|
+
GOARCH: ${{ matrix.goarch }}
|
|
90
|
+
|
|
91
|
+
steps:
|
|
92
|
+
- uses: actions/checkout@v4
|
|
93
|
+
with:
|
|
94
|
+
submodules: recursive
|
|
95
|
+
fetch-depth: 1
|
|
96
|
+
|
|
97
|
+
- uses: actions/setup-go@v5
|
|
98
|
+
with:
|
|
99
|
+
go-version: "~1.24"
|
|
100
|
+
check-latest: true
|
|
101
|
+
cache-dependency-path: skills-fs/go.sum
|
|
102
|
+
|
|
103
|
+
- name: Build skills-fs binary
|
|
104
|
+
working-directory: skills-fs
|
|
105
|
+
run: CGO_ENABLED=0 go build -o ../napcat-cli-fs/${{ matrix.binary }} ./cmd/skills-fs
|
|
106
|
+
|
|
107
|
+
- name: Build platform wheel
|
|
108
|
+
working-directory: napcat-cli-fs
|
|
109
|
+
run: python scripts/build-wheel.py ${{ matrix.binary }} "${{ matrix.tag }}" --output-dir dist
|
|
110
|
+
|
|
111
|
+
- uses: actions/upload-artifact@v4
|
|
112
|
+
with:
|
|
113
|
+
name: wheel-fs-${{ matrix.label }}
|
|
114
|
+
path: napcat-cli-fs/dist/*.whl
|
|
115
|
+
|
|
116
|
+
# ── Publish to PyPI (only when publish=true) ────────────────────────
|
|
117
|
+
publish:
|
|
118
|
+
name: Publish to PyPI
|
|
119
|
+
needs: [build-napcat-cli, build-fs]
|
|
120
|
+
if: inputs.publish
|
|
121
|
+
runs-on: ubuntu-latest
|
|
122
|
+
environment:
|
|
123
|
+
name: pypi
|
|
124
|
+
url: https://pypi.org/project/napcat-cli/${{ github.ref_name }}
|
|
125
|
+
permissions:
|
|
126
|
+
id-token: write
|
|
127
|
+
steps:
|
|
128
|
+
- uses: actions/download-artifact@v4
|
|
129
|
+
with:
|
|
130
|
+
pattern: wheel-*
|
|
131
|
+
merge-multiple: true
|
|
132
|
+
path: dist
|
|
133
|
+
|
|
134
|
+
- name: Upload napcat-cli (pure) + napcat-cli-fs (platform wheels)
|
|
135
|
+
uses: pypa/gh-action-pypi-publish@v1.12.4
|
|
136
|
+
with:
|
|
137
|
+
password: ${{ secrets.PYPI_TOKEN }}
|
|
138
|
+
packages-dir: dist
|
|
@@ -1,7 +1,25 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: napcat-cli
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: Standalone CLI and daemon for NapCat QQ bot management with skills-fs integration
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: textual>=0.40
|
|
8
|
+
Provides-Extra: all
|
|
9
|
+
Requires-Dist: napcat-cli-fs>=2.0.0; extra == 'all'
|
|
10
|
+
Provides-Extra: dev
|
|
11
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
|
12
|
+
Provides-Extra: fs
|
|
13
|
+
Requires-Dist: napcat-cli-fs>=2.0.0; extra == 'fs'
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
1
16
|
# napcat-cli
|
|
2
17
|
|
|
3
18
|
Standalone CLI and daemon for NapCat QQ bot management with skills-fs integration.
|
|
4
19
|
|
|
20
|
+
[](https://pypi.org/project/napcat-cli/)
|
|
21
|
+
[](https://pypi.org/project/napcat-cli/)
|
|
22
|
+
|
|
5
23
|
> 📝 **介绍博文:** [napcat-cli 群配置与管理速查](https://yvxi.pages.dev/blog/napcat-cli-group-config/) — 从零配置、群消息收发、Agent Wake 的完整链路。
|
|
6
24
|
|
|
7
25
|
---
|
|
@@ -48,7 +66,7 @@ napcat wake --reason NEW_MESSAGE
|
|
|
48
66
|
## Setup
|
|
49
67
|
|
|
50
68
|
```bash
|
|
51
|
-
uv tool install napcat-cli
|
|
69
|
+
uv tool install napcat-cli # recommended — isolated install via uv (alternative: pip install napcat-cli)
|
|
52
70
|
napcat setup # interactive — guides token, data dir, skills-fs, wake
|
|
53
71
|
napcat daemon start
|
|
54
72
|
```
|
|
@@ -165,6 +183,21 @@ to read/write NapCat API endpoints through the virtual filesystem.
|
|
|
165
183
|
When `skills_fs_enabled` is true in `daemon.json`, the daemon spawns skills-fs
|
|
166
184
|
automatically with the configured mountpoint and config file.
|
|
167
185
|
|
|
186
|
+
> ⚙️ **Distribution note:** `skills-fs` is a **compiled Go binary** (git submodule
|
|
187
|
+
> pinned at [`cb13f37`](https://github.com/yandu-app/skills-fs/tree/cb13f37)).
|
|
188
|
+
> It is **not bundled** in the pip/uv install of `napcat-cli`. If you need the
|
|
189
|
+
> FUSE mount (optional), build it separately:
|
|
190
|
+
>
|
|
191
|
+
> ```bash
|
|
192
|
+
> git clone https://github.com/yandu-app/skills-fs
|
|
193
|
+
> cd skills-fs && make build # produces ./skills-fs
|
|
194
|
+
> napcat config set skills_fs_binary /path/to/skills-fs
|
|
195
|
+
> napcat daemon stop && napcat daemon start
|
|
196
|
+
> ```
|
|
197
|
+
>
|
|
198
|
+
> Or place `skills-fs` on your `PATH` and the daemon will find it. This feature
|
|
199
|
+
> is **optional** — the CLI, daemon, and wake system work without it.
|
|
200
|
+
|
|
168
201
|
Manual start:
|
|
169
202
|
|
|
170
203
|
```bash
|
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: napcat-cli
|
|
3
|
-
Version: 2.0.0
|
|
4
|
-
Summary: Standalone CLI and daemon for NapCat QQ bot management with skills-fs integration
|
|
5
|
-
License-Expression: MIT
|
|
6
|
-
Requires-Python: >=3.10
|
|
7
|
-
Requires-Dist: textual>=0.40
|
|
8
|
-
Provides-Extra: dev
|
|
9
|
-
Requires-Dist: pytest>=7; extra == 'dev'
|
|
10
|
-
Description-Content-Type: text/markdown
|
|
11
|
-
|
|
12
1
|
# napcat-cli
|
|
13
2
|
|
|
14
3
|
Standalone CLI and daemon for NapCat QQ bot management with skills-fs integration.
|
|
15
4
|
|
|
5
|
+
[](https://pypi.org/project/napcat-cli/)
|
|
6
|
+
[](https://pypi.org/project/napcat-cli/)
|
|
7
|
+
|
|
16
8
|
> 📝 **介绍博文:** [napcat-cli 群配置与管理速查](https://yvxi.pages.dev/blog/napcat-cli-group-config/) — 从零配置、群消息收发、Agent Wake 的完整链路。
|
|
17
9
|
|
|
18
10
|
---
|
|
@@ -59,7 +51,7 @@ napcat wake --reason NEW_MESSAGE
|
|
|
59
51
|
## Setup
|
|
60
52
|
|
|
61
53
|
```bash
|
|
62
|
-
uv tool install napcat-cli
|
|
54
|
+
uv tool install napcat-cli # recommended — isolated install via uv (alternative: pip install napcat-cli)
|
|
63
55
|
napcat setup # interactive — guides token, data dir, skills-fs, wake
|
|
64
56
|
napcat daemon start
|
|
65
57
|
```
|
|
@@ -176,6 +168,21 @@ to read/write NapCat API endpoints through the virtual filesystem.
|
|
|
176
168
|
When `skills_fs_enabled` is true in `daemon.json`, the daemon spawns skills-fs
|
|
177
169
|
automatically with the configured mountpoint and config file.
|
|
178
170
|
|
|
171
|
+
> ⚙️ **Distribution note:** `skills-fs` is a **compiled Go binary** (git submodule
|
|
172
|
+
> pinned at [`cb13f37`](https://github.com/yandu-app/skills-fs/tree/cb13f37)).
|
|
173
|
+
> It is **not bundled** in the pip/uv install of `napcat-cli`. If you need the
|
|
174
|
+
> FUSE mount (optional), build it separately:
|
|
175
|
+
>
|
|
176
|
+
> ```bash
|
|
177
|
+
> git clone https://github.com/yandu-app/skills-fs
|
|
178
|
+
> cd skills-fs && make build # produces ./skills-fs
|
|
179
|
+
> napcat config set skills_fs_binary /path/to/skills-fs
|
|
180
|
+
> napcat daemon stop && napcat daemon start
|
|
181
|
+
> ```
|
|
182
|
+
>
|
|
183
|
+
> Or place `skills-fs` on your `PATH` and the daemon will find it. This feature
|
|
184
|
+
> is **optional** — the CLI, daemon, and wake system work without it.
|
|
185
|
+
|
|
179
186
|
Manual start:
|
|
180
187
|
|
|
181
188
|
```bash
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "napcat-cli-fs"
|
|
7
|
+
version = "2.0.0"
|
|
8
|
+
description = "Pre-built skills-fs FUSE binary for napcat-cli"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
# No runtime Python dependencies — the package is a shipping vehicle for the
|
|
13
|
+
# compiled Go binary, which napcat-cli's SkillsFsManager discovers at runtime.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Build a platform-specific wheel that wraps a compiled skills-fs binary.
|
|
2
|
+
|
|
3
|
+
Usage::
|
|
4
|
+
|
|
5
|
+
python scripts/build-wheel.py <binary> <wheel-tag> [--version X.Y.Z] [--output-dir dist]
|
|
6
|
+
|
|
7
|
+
Example::
|
|
8
|
+
|
|
9
|
+
# After building skills-fs for linux/amd64:
|
|
10
|
+
python scripts/build-wheel.py skills-fs manylinux_2_17_x86_64.manylinux2014_x86_64
|
|
11
|
+
|
|
12
|
+
The output wheel is named ``napcat_cli_fs-{version}-py3-none-{tag}.whl`` and
|
|
13
|
+
contains::
|
|
14
|
+
|
|
15
|
+
napcat_cli_fs/
|
|
16
|
+
__init__.py
|
|
17
|
+
bin/skills-fs (or skills-fs.exe on Windows)
|
|
18
|
+
napcat_cli_fs-{version}.dist-info/
|
|
19
|
+
METADATA
|
|
20
|
+
WHEEL
|
|
21
|
+
RECORD
|
|
22
|
+
"""
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import argparse
|
|
26
|
+
import hashlib
|
|
27
|
+
import os
|
|
28
|
+
import shutil
|
|
29
|
+
import tempfile
|
|
30
|
+
import zipfile
|
|
31
|
+
|
|
32
|
+
PACKAGE = "napcat_cli_fs"
|
|
33
|
+
VERSION = "2.0.0"
|
|
34
|
+
|
|
35
|
+
WHEEL_METADATA = """\
|
|
36
|
+
Metadata-Version: 2.1
|
|
37
|
+
Name: napcat-cli-fs
|
|
38
|
+
Version: {version}
|
|
39
|
+
Summary: Pre-built skills-fs FUSE binary for napcat-cli
|
|
40
|
+
License: MIT
|
|
41
|
+
Requires-Python: >=3.10
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def build_wheel(
|
|
46
|
+
binary_path: str,
|
|
47
|
+
wheel_tag: str,
|
|
48
|
+
version: str = VERSION,
|
|
49
|
+
output_dir: str = "dist",
|
|
50
|
+
) -> str:
|
|
51
|
+
"""Build a single platform wheel.
|
|
52
|
+
|
|
53
|
+
Returns the path to the created .whl file.
|
|
54
|
+
"""
|
|
55
|
+
is_win = wheel_tag.startswith("win")
|
|
56
|
+
bin_name = "skills-fs.exe" if is_win else "skills-fs"
|
|
57
|
+
|
|
58
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
59
|
+
wheel_name = f"{PACKAGE}-{version}-py3-none-{wheel_tag}.whl"
|
|
60
|
+
wheel_path = os.path.join(output_dir, wheel_name)
|
|
61
|
+
|
|
62
|
+
records: list[str] = []
|
|
63
|
+
|
|
64
|
+
def add_file(zf: zipfile.ZipFile, arcname: str, content: bytes, path: str = "") -> None:
|
|
65
|
+
"""Add a file to the wheel and record its hash."""
|
|
66
|
+
if path:
|
|
67
|
+
arcname = os.path.join(path, arcname)
|
|
68
|
+
else:
|
|
69
|
+
arcname = arcname
|
|
70
|
+
info = zipfile.ZipInfo(arcname)
|
|
71
|
+
info.date_time = (2026, 1, 1, 0, 0, 0)
|
|
72
|
+
info.external_attr = 0o644 << 16
|
|
73
|
+
zf.writestr(info, content)
|
|
74
|
+
sha = hashlib.sha256(content).hexdigest()
|
|
75
|
+
records.append(f"{arcname},sha256={sha},{len(content)}")
|
|
76
|
+
|
|
77
|
+
def add_data_file(zf: zipfile.ZipFile, src_path: str, arcname: str) -> None:
|
|
78
|
+
"""Read *src_path* (disk) and write into *arcname* inside the wheel."""
|
|
79
|
+
with open(src_path, "rb") as f:
|
|
80
|
+
data = f.read()
|
|
81
|
+
info = zipfile.ZipInfo(arcname)
|
|
82
|
+
info.date_time = (2026, 1, 1, 0, 0, 0)
|
|
83
|
+
info.external_attr = 0o755 << 16 # executable
|
|
84
|
+
zf.writestr(info, data)
|
|
85
|
+
sha = hashlib.sha256(data).hexdigest()
|
|
86
|
+
records.append(f"{arcname},sha256={sha},{len(data)}")
|
|
87
|
+
|
|
88
|
+
with zipfile.ZipFile(wheel_path, "w", zipfile.ZIP_DEFLATED) as zf:
|
|
89
|
+
# WHEEL
|
|
90
|
+
wheel_content = (
|
|
91
|
+
"Wheel-Version: 1.0\n"
|
|
92
|
+
f"Generator: napcat-cli-fs build-wheel.py\n"
|
|
93
|
+
"Root-Is-Purelib: false\n"
|
|
94
|
+
f"Tag: py3-none-{wheel_tag}\n"
|
|
95
|
+
)
|
|
96
|
+
add_file(zf, "WHEEL", wheel_content.encode(), f"{PACKAGE}-{version}.dist-info")
|
|
97
|
+
|
|
98
|
+
# METADATA
|
|
99
|
+
meta = WHEEL_METADATA.format(version=version)
|
|
100
|
+
add_file(zf, "METADATA", meta.encode(), f"{PACKAGE}-{version}.dist-info")
|
|
101
|
+
|
|
102
|
+
# napcat_cli_fs/__init__.py
|
|
103
|
+
init_py = f'"""skills-fs binary bundle (platform: {wheel_tag})."""\n__version__ = "{version}"\n'
|
|
104
|
+
add_file(zf, "__init__.py", init_py.encode(), PACKAGE)
|
|
105
|
+
|
|
106
|
+
# napcat_cli_fs/bin/skills-fs
|
|
107
|
+
add_data_file(zf, binary_path, f"{PACKAGE}/bin/{bin_name}")
|
|
108
|
+
|
|
109
|
+
# RECORD (must be last)
|
|
110
|
+
record_content = "\n".join(records) + "\n"
|
|
111
|
+
add_file(zf, "RECORD", record_content.encode(), f"{PACKAGE}-{version}.dist-info")
|
|
112
|
+
|
|
113
|
+
print(f"Built: {wheel_path} ({os.path.getsize(wheel_path)} bytes)")
|
|
114
|
+
return wheel_path
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def main() -> None:
|
|
118
|
+
parser = argparse.ArgumentParser(description="Build a skills-fs platform wheel")
|
|
119
|
+
parser.add_argument("binary", help="Path to compiled skills-fs binary")
|
|
120
|
+
parser.add_argument("tag", help="Wheel platform tag (e.g. manylinux_2_17_x86_64)")
|
|
121
|
+
parser.add_argument("--version", default=VERSION, help=f"Version (default {VERSION})")
|
|
122
|
+
parser.add_argument("--output-dir", default="dist", help="Output directory (default dist/)")
|
|
123
|
+
args = parser.parse_args()
|
|
124
|
+
build_wheel(args.binary, args.tag, version=args.version, output_dir=args.output_dir)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if __name__ == "__main__":
|
|
128
|
+
main()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""napcat_cli_fs — compiled skills-fs Go binary for napcat-cli.
|
|
2
|
+
|
|
3
|
+
This package contains a pre-built ``skills-fs`` (or ``skills-fs.exe`` on
|
|
4
|
+
Windows) binary. It is installed automatically when you choose the ``[fs]``
|
|
5
|
+
extra::
|
|
6
|
+
|
|
7
|
+
pip install napcat-cli[fs]
|
|
8
|
+
# or
|
|
9
|
+
uv tool install napcat-cli --with napcat-cli-fs
|
|
10
|
+
|
|
11
|
+
The daemon's ``SkillsFsManager`` finds the binary via this package and uses it
|
|
12
|
+
to mount a FUSE overlay on the napcat-cli skill directory.
|
|
13
|
+
|
|
14
|
+
Platform support
|
|
15
|
+
----------------
|
|
16
|
+
- **Linux** (builds tested on amd64; arm64 via CI)
|
|
17
|
+
- **macOS** (amd64 + arm64 via CI; FUSE is **untested** — open a PR if
|
|
18
|
+
you hit issues)
|
|
19
|
+
- **Windows** (amd64 via CI; FUSE is **untested** — open a PR if you hit
|
|
20
|
+
issues)
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
__version__ = "2.0.0"
|
|
@@ -672,12 +672,23 @@ class SkillsFsManager:
|
|
|
672
672
|
shipped = Path(_resolve_shipped_binary())
|
|
673
673
|
if shipped.exists() and shipped.is_file():
|
|
674
674
|
self.binary = str(shipped)
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
675
|
+
# Try the bundled napcat_cli_fs package (pip install napcat-cli[fs])
|
|
676
|
+
if not self.binary:
|
|
677
|
+
try:
|
|
678
|
+
import napcat_cli_fs as _nfs
|
|
679
|
+
import importlib.resources as _ir
|
|
680
|
+
_bin = "skills-fs.exe" if os.name == "nt" else "skills-fs"
|
|
681
|
+
_p = _ir.files("napcat_cli_fs").joinpath("bin", _bin)
|
|
682
|
+
if _p.exists():
|
|
683
|
+
self.binary = str(_p)
|
|
684
|
+
except (ImportError, ModuleNotFoundError, Exception):
|
|
685
|
+
pass
|
|
686
|
+
# Search PATH
|
|
687
|
+
if not self.binary:
|
|
688
|
+
import shutil
|
|
689
|
+
found = shutil.which("skills-fs")
|
|
690
|
+
if found:
|
|
691
|
+
self.binary = found
|
|
681
692
|
self._pid: int | None = None
|
|
682
693
|
self._status: str = "stopped" # healthy | degraded | stopped
|
|
683
694
|
self._max_restarts = 3
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "napcat-cli"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.1"
|
|
8
8
|
description = "Standalone CLI and daemon for NapCat QQ bot management with skills-fs integration"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -16,6 +16,8 @@ napcat = "napcat_cli.cli:main"
|
|
|
16
16
|
|
|
17
17
|
[project.optional-dependencies]
|
|
18
18
|
dev = ["pytest>=7"]
|
|
19
|
+
fs = ["napcat-cli-fs>=2.0.0"]
|
|
20
|
+
all = ["napcat-cli[fs]"]
|
|
19
21
|
|
|
20
22
|
[tool.hatch.build.targets.wheel]
|
|
21
23
|
packages = ["napcat_cli"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|