issuekit 0.1.5__tar.gz → 0.1.6__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.
Files changed (55) hide show
  1. {issuekit-0.1.5 → issuekit-0.1.6}/LICENSE +21 -21
  2. {issuekit-0.1.5 → issuekit-0.1.6}/PKG-INFO +7 -5
  3. {issuekit-0.1.5 → issuekit-0.1.6}/README.md +5 -3
  4. {issuekit-0.1.5 → issuekit-0.1.6}/pyproject.toml +1 -1
  5. {issuekit-0.1.5 → issuekit-0.1.6}/scripts/release.sh +168 -168
  6. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/__init__.py +1 -1
  7. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/agent_skills.py +73 -55
  8. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/agents/__init__.py +5 -5
  9. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/agents/registry.py +52 -52
  10. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/SKILL.md +379 -0
  11. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/agents/openai.yaml +3 -0
  12. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/references/automation-loop.md +36 -0
  13. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/references/contract-drift.md +26 -0
  14. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/references/data-isolation.md +46 -0
  15. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/references/database-evidence.md +57 -0
  16. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/references/domains/generic-domain.md +18 -0
  17. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/references/execution-context.md +90 -0
  18. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/references/failure-analysis.md +14 -0
  19. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/references/preparation-protocol.md +113 -0
  20. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/references/test-model.md +97 -0
  21. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/references/testcase-schema.md +122 -0
  22. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/scripts/validate_fixture_plan.py +62 -0
  23. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-business-test/scripts/validate_testcase_document.py +121 -0
  24. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-change/SKILL.md +59 -59
  25. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-change/agents/openai.yaml +4 -4
  26. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-coding/SKILL.md +132 -132
  27. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-coding/agents/openai.yaml +4 -4
  28. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-design/SKILL.md +117 -117
  29. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-design/agents/openai.yaml +4 -4
  30. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-knowledge/SKILL.md +158 -158
  31. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-knowledge/agents/openai.yaml +4 -4
  32. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-merge/SKILL.md +74 -0
  33. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-merge/agents/openai.yaml +4 -0
  34. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-release/agents/openai.yaml +4 -4
  35. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-require/SKILL.md +128 -128
  36. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-require/agents/openai.yaml +4 -4
  37. issuekit-0.1.6/src/issuekit/bundled_skills/issuekit-review/SKILL.md +152 -0
  38. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-review/agents/openai.yaml +4 -4
  39. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-test/SKILL.md +79 -78
  40. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-test/agents/openai.yaml +4 -4
  41. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/cli.py +118 -118
  42. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/commands/init.py +184 -191
  43. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/commands/upgrade.py +57 -57
  44. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/templates.py +17 -17
  45. issuekit-0.1.6/tests/test_agent_skills.py +41 -0
  46. issuekit-0.1.5/src/issuekit/bundled_skills/issuekit-review/SKILL.md +0 -89
  47. {issuekit-0.1.5 → issuekit-0.1.6}/.gitignore +0 -0
  48. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_skills/issuekit-release/SKILL.md +0 -0
  49. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_templates/code-review.md +0 -0
  50. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_templates/release-note.md +0 -0
  51. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_templates/requirement.md +0 -0
  52. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_templates/technical-design.md +0 -0
  53. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/bundled_templates/test-plan.md +0 -0
  54. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/commands/__init__.py +0 -0
  55. {issuekit-0.1.5 → issuekit-0.1.6}/src/issuekit/knowledge/__init__.py +0 -0
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: issuekit
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: AI 辅助开发的 Issue 全生命周期工具。从需求分析到代码审核,由你的 AI 编程助手驱动。
5
5
  Project-URL: Homepage, https://github.com/xsg22/issue-kit
6
6
  Project-URL: Repository, https://github.com/xsg22/issue-kit
@@ -44,9 +44,10 @@ IssueKit 为 AI 辅助开发提供结构化的工作流。它提供一组 Skills
44
44
  | 4. 测试方案 | `$issuekit-test` | 黑盒业务测试 + 白盒单测/接口测试用例 |
45
45
  | 5. 发布准备 | `$issuekit-release` | 生成发布文档,创建 Pull Request |
46
46
  | 6. 代码审核 | `$issuekit-review` | 多维度交叉验证(需求、方案、质量) |
47
+ | 7. 代码合并 | `$issuekit-merge` | 理解改动背景,保全各分支有效能力,以门禁保障合并结果 |
47
48
 
48
49
 
49
- 还有一个 `$issuekit-knowledge` skill,用于生成项目上下文摘要,让 AI 助手快速理解项目。
50
+ 另有 `$issuekit-knowledge` 生成项目上下文摘要、`$issuekit-change` 管理需求与方案变更,以及 `$issuekit-business-test` 设计并编排真实业务验收,共 10 个 Skill。
50
51
 
51
52
  ## 安装
52
53
 
@@ -116,6 +117,7 @@ AI 助手按技术文档的开发步骤逐步实现,完成后自动交叉校
116
117
  $issuekit-test # 生成测试方案
117
118
  $issuekit-release # 生成发布文档 + 创建 PR
118
119
  $issuekit-review # 多维度代码审核
120
+ $issuekit-merge # 保全各分支有效能力,完成代码集成
119
121
  ```
120
122
 
121
123
  ## `init` 做了什么
@@ -130,7 +132,7 @@ $issuekit-review # 多维度代码审核
130
132
  - Codex → `.agents/skills/`
131
133
  - GitHub Copilot → `.github/skills/`
132
134
 
133
- 每个 Skill 包含 `SKILL.md`(指令)和 `agents/openai.yaml`(元数据)。
135
+ 每个 Skill 包含 `SKILL.md`(指令),并按需携带 `references/`、`scripts/` 和 `assets/`;Codex 还会安装 `agents/openai.yaml` 元数据。
134
136
 
135
137
  ## 更新模板与 Skills(已 init 的项目)
136
138
 
@@ -201,4 +203,4 @@ issues/ # Issue 文档(默认目录,可通过 --issues
201
203
 
202
204
  ## 许可证
203
205
 
204
- MIT
206
+ MIT
@@ -15,9 +15,10 @@ IssueKit 为 AI 辅助开发提供结构化的工作流。它提供一组 Skills
15
15
  | 4. 测试方案 | `$issuekit-test` | 黑盒业务测试 + 白盒单测/接口测试用例 |
16
16
  | 5. 发布准备 | `$issuekit-release` | 生成发布文档,创建 Pull Request |
17
17
  | 6. 代码审核 | `$issuekit-review` | 多维度交叉验证(需求、方案、质量) |
18
+ | 7. 代码合并 | `$issuekit-merge` | 理解改动背景,保全各分支有效能力,以门禁保障合并结果 |
18
19
 
19
20
 
20
- 还有一个 `$issuekit-knowledge` skill,用于生成项目上下文摘要,让 AI 助手快速理解项目。
21
+ 另有 `$issuekit-knowledge` 生成项目上下文摘要、`$issuekit-change` 管理需求与方案变更,以及 `$issuekit-business-test` 设计并编排真实业务验收,共 10 个 Skill。
21
22
 
22
23
  ## 安装
23
24
 
@@ -87,6 +88,7 @@ AI 助手按技术文档的开发步骤逐步实现,完成后自动交叉校
87
88
  $issuekit-test # 生成测试方案
88
89
  $issuekit-release # 生成发布文档 + 创建 PR
89
90
  $issuekit-review # 多维度代码审核
91
+ $issuekit-merge # 保全各分支有效能力,完成代码集成
90
92
  ```
91
93
 
92
94
  ## `init` 做了什么
@@ -101,7 +103,7 @@ $issuekit-review # 多维度代码审核
101
103
  - Codex → `.agents/skills/`
102
104
  - GitHub Copilot → `.github/skills/`
103
105
 
104
- 每个 Skill 包含 `SKILL.md`(指令)和 `agents/openai.yaml`(元数据)。
106
+ 每个 Skill 包含 `SKILL.md`(指令),并按需携带 `references/`、`scripts/` 和 `assets/`;Codex 还会安装 `agents/openai.yaml` 元数据。
105
107
 
106
108
  ## 更新模板与 Skills(已 init 的项目)
107
109
 
@@ -172,4 +174,4 @@ issues/ # Issue 文档(默认目录,可通过 --issues
172
174
 
173
175
  ## 许可证
174
176
 
175
- MIT
177
+ MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "issuekit"
3
- version = "0.1.5"
3
+ version = "0.1.6"
4
4
  description = "AI 辅助开发的 Issue 全生命周期工具。从需求分析到代码审核,由你的 AI 编程助手驱动。"
5
5
  requires-python = ">=3.10"
6
6
  license = "MIT"
@@ -1,168 +1,168 @@
1
- #!/usr/bin/env bash
2
- # PyPI 发布(纯 shell,不依赖额外 Python 发布脚本)
3
- #
4
- # 依赖:pip install -e ".[release]" ;凭据见 ~/.pypirc 或 TWINE_* 环境变量
5
- #
6
- # 用法:
7
- # ./scripts/release.sh patch|minor|major # 升版并发布
8
- # ./scripts/release.sh --set 1.0.0 # 指定版本并发布
9
- # ./scripts/release.sh # 不升版,按当前版本构建并上传
10
- # ./scripts/release.sh patch --dry-run --repository testpypi
11
- #
12
- set -euo pipefail
13
-
14
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
- ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
16
- cd "$ROOT"
17
-
18
- PYPROJECT="$ROOT/pyproject.toml"
19
- INIT_PY="$ROOT/src/issuekit/__init__.py"
20
-
21
- usage() {
22
- cat <<'EOF'
23
- PyPI 发布:./scripts/release.sh [patch|minor|major] [选项]
24
-
25
- 选项:
26
- --set VERSION 指定版本(x.y.z)
27
- --repository NAME pypi(默认)或 testpypi
28
- --skip-tests 跳过 pytest
29
- --dry-run 构建并检查,不上传
30
- -h, --help 显示本说明
31
- EOF
32
- }
33
-
34
- read_pyproject_version() {
35
- grep -E '^version[[:space:]]*=' "$PYPROJECT" | head -1 \
36
- | sed -E 's/^version[[:space:]]*=[[:space:]]*"([^"]*)".*/\1/'
37
- }
38
-
39
- write_versions() {
40
- local v="$1"
41
- local tmp
42
- tmp="$(mktemp)"
43
- sed "s/^version = \".*\"/version = \"${v}\"/" "$PYPROJECT" >"$tmp" && mv "$tmp" "$PYPROJECT"
44
- tmp="$(mktemp)"
45
- sed "s/^__version__[[:space:]]*=[[:space:]]*\".*\"/__version__ = \"${v}\"/" "$INIT_PY" >"$tmp" && mv "$tmp" "$INIT_PY"
46
- }
47
-
48
- bump_semver() {
49
- local ver="$1" kind="$2"
50
- local major minor patch
51
- if [[ ! "$ver" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
52
- echo "无法自动升版(仅支持纯 x.y.z,请用 --set):$ver" >&2
53
- exit 1
54
- fi
55
- IFS='.' read -r major minor patch <<<"$ver"
56
- case "$kind" in
57
- patch) patch=$((patch + 1)) ;;
58
- minor) minor=$((minor + 1)); patch=0 ;;
59
- major) major=$((major + 1)); minor=0; patch=0 ;;
60
- *) echo "invalid bump: $kind" >&2; exit 1 ;;
61
- esac
62
- echo "${major}.${minor}.${patch}"
63
- }
64
-
65
- BUMP=""
66
- SET_VERSION=""
67
- REPOSITORY="pypi"
68
- SKIP_TESTS=0
69
- DRY_RUN=0
70
-
71
- # 首参 patch|minor|major 快捷方式
72
- if [[ "${1:-}" =~ ^(patch|minor|major)$ ]]; then
73
- BUMP="$1"
74
- shift
75
- fi
76
-
77
- while [[ $# -gt 0 ]]; do
78
- case "$1" in
79
- --set)
80
- SET_VERSION="${2:?--set 需要版本号}"
81
- shift 2
82
- ;;
83
- --repository)
84
- REPOSITORY="${2:?--repository 需要 pypi 或 testpypi}"
85
- shift 2
86
- ;;
87
- --skip-tests) SKIP_TESTS=1; shift ;;
88
- --dry-run) DRY_RUN=1; shift ;;
89
- -h|--help) usage; exit 0 ;;
90
- *)
91
- echo "未知参数: $1" >&2
92
- usage >&2
93
- exit 1
94
- ;;
95
- esac
96
- done
97
-
98
- if [[ -n "$BUMP" && -n "$SET_VERSION" ]]; then
99
- echo "不要同时使用升版档位与 --set" >&2
100
- exit 1
101
- fi
102
-
103
- CURRENT="$(read_pyproject_version)"
104
- NEW_VERSION=""
105
-
106
- if [[ -n "$BUMP" ]]; then
107
- NEW_VERSION="$(bump_semver "$CURRENT" "$BUMP")"
108
- elif [[ -n "$SET_VERSION" ]]; then
109
- if [[ ! "$SET_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
110
- echo "--set 仅支持 x.y.z 格式: $SET_VERSION" >&2
111
- exit 1
112
- fi
113
- NEW_VERSION="$SET_VERSION"
114
- fi
115
-
116
- if [[ -n "$NEW_VERSION" ]]; then
117
- write_versions "$NEW_VERSION"
118
- echo "Version: ${CURRENT} -> ${NEW_VERSION}"
119
- else
120
- echo "Version: ${CURRENT} (unchanged)"
121
- fi
122
-
123
- if [[ "$SKIP_TESTS" -eq 0 ]]; then
124
- if ! python -c "import pytest" 2>/dev/null; then
125
- echo "未检测到 pytest,正在安装发布依赖: pip install -e \".[release]\""
126
- python -m pip install -q -e ".[release]"
127
- fi
128
- echo "+ python -m pytest"
129
- # 退出码 5 = 未收集到测试(旧版 pytest 或未开 suppress_no_test_exit_code 时仍视为可继续发布)
130
- set +e
131
- python -m pytest
132
- pytest_ec=$?
133
- set -e
134
- if [[ "$pytest_ec" -ne 0 && "$pytest_ec" -ne 5 ]]; then
135
- exit "$pytest_ec"
136
- fi
137
- if [[ "$pytest_ec" -eq 5 ]]; then
138
- echo "提示: pytest 未收集到任何测试(退出码 5),继续构建与上传。" >&2
139
- fi
140
- fi
141
-
142
- echo "+ clean dist/build artifacts"
143
- rm -rf dist build ./*.egg-info src/issuekit.egg-info 2>/dev/null || true
144
-
145
- echo "+ python -m build"
146
- python -m build
147
-
148
- echo "+ twine check dist/*"
149
- python -m twine check dist/*
150
-
151
- # 使用 -r pypi|testpypi(勿用 --repository-url),Twine 才会按名称读取 ~/.pypirc 里对应段落及凭据
152
- if [[ "$REPOSITORY" == "testpypi" ]]; then
153
- TWINE_REPO=( -r testpypi )
154
- else
155
- TWINE_REPO=( -r pypi )
156
- fi
157
-
158
- VER_FOR_MSG="${NEW_VERSION:-$CURRENT}"
159
- if [[ "$DRY_RUN" -eq 1 ]]; then
160
- echo "+ (dry-run) skipping: python -m twine upload ${TWINE_REPO[*]} dist/*"
161
- echo "Done (dry-run)."
162
- exit 0
163
- fi
164
-
165
- echo "+ python -m twine upload ${TWINE_REPO[*]} dist/*"
166
- python -m twine upload "${TWINE_REPO[@]}" dist/*
167
-
168
- echo "Uploaded to ${REPOSITORY}. Verify: pip install issuekit==${VER_FOR_MSG}"
1
+ #!/usr/bin/env bash
2
+ # PyPI 发布(纯 shell,不依赖额外 Python 发布脚本)
3
+ #
4
+ # 依赖:pip install -e ".[release]" ;凭据见 ~/.pypirc 或 TWINE_* 环境变量
5
+ #
6
+ # 用法:
7
+ # ./scripts/release.sh patch|minor|major # 升版并发布
8
+ # ./scripts/release.sh --set 1.0.0 # 指定版本并发布
9
+ # ./scripts/release.sh # 不升版,按当前版本构建并上传
10
+ # ./scripts/release.sh patch --dry-run --repository testpypi
11
+ #
12
+ set -euo pipefail
13
+
14
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
+ ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
16
+ cd "$ROOT"
17
+
18
+ PYPROJECT="$ROOT/pyproject.toml"
19
+ INIT_PY="$ROOT/src/issuekit/__init__.py"
20
+
21
+ usage() {
22
+ cat <<'EOF'
23
+ PyPI 发布:./scripts/release.sh [patch|minor|major] [选项]
24
+
25
+ 选项:
26
+ --set VERSION 指定版本(x.y.z)
27
+ --repository NAME pypi(默认)或 testpypi
28
+ --skip-tests 跳过 pytest
29
+ --dry-run 构建并检查,不上传
30
+ -h, --help 显示本说明
31
+ EOF
32
+ }
33
+
34
+ read_pyproject_version() {
35
+ grep -E '^version[[:space:]]*=' "$PYPROJECT" | head -1 \
36
+ | sed -E 's/^version[[:space:]]*=[[:space:]]*"([^"]*)".*/\1/'
37
+ }
38
+
39
+ write_versions() {
40
+ local v="$1"
41
+ local tmp
42
+ tmp="$(mktemp)"
43
+ sed "s/^version = \".*\"/version = \"${v}\"/" "$PYPROJECT" >"$tmp" && mv "$tmp" "$PYPROJECT"
44
+ tmp="$(mktemp)"
45
+ sed "s/^__version__[[:space:]]*=[[:space:]]*\".*\"/__version__ = \"${v}\"/" "$INIT_PY" >"$tmp" && mv "$tmp" "$INIT_PY"
46
+ }
47
+
48
+ bump_semver() {
49
+ local ver="$1" kind="$2"
50
+ local major minor patch
51
+ if [[ ! "$ver" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
52
+ echo "无法自动升版(仅支持纯 x.y.z,请用 --set):$ver" >&2
53
+ exit 1
54
+ fi
55
+ IFS='.' read -r major minor patch <<<"$ver"
56
+ case "$kind" in
57
+ patch) patch=$((patch + 1)) ;;
58
+ minor) minor=$((minor + 1)); patch=0 ;;
59
+ major) major=$((major + 1)); minor=0; patch=0 ;;
60
+ *) echo "invalid bump: $kind" >&2; exit 1 ;;
61
+ esac
62
+ echo "${major}.${minor}.${patch}"
63
+ }
64
+
65
+ BUMP=""
66
+ SET_VERSION=""
67
+ REPOSITORY="pypi"
68
+ SKIP_TESTS=0
69
+ DRY_RUN=0
70
+
71
+ # 首参 patch|minor|major 快捷方式
72
+ if [[ "${1:-}" =~ ^(patch|minor|major)$ ]]; then
73
+ BUMP="$1"
74
+ shift
75
+ fi
76
+
77
+ while [[ $# -gt 0 ]]; do
78
+ case "$1" in
79
+ --set)
80
+ SET_VERSION="${2:?--set 需要版本号}"
81
+ shift 2
82
+ ;;
83
+ --repository)
84
+ REPOSITORY="${2:?--repository 需要 pypi 或 testpypi}"
85
+ shift 2
86
+ ;;
87
+ --skip-tests) SKIP_TESTS=1; shift ;;
88
+ --dry-run) DRY_RUN=1; shift ;;
89
+ -h|--help) usage; exit 0 ;;
90
+ *)
91
+ echo "未知参数: $1" >&2
92
+ usage >&2
93
+ exit 1
94
+ ;;
95
+ esac
96
+ done
97
+
98
+ if [[ -n "$BUMP" && -n "$SET_VERSION" ]]; then
99
+ echo "不要同时使用升版档位与 --set" >&2
100
+ exit 1
101
+ fi
102
+
103
+ CURRENT="$(read_pyproject_version)"
104
+ NEW_VERSION=""
105
+
106
+ if [[ -n "$BUMP" ]]; then
107
+ NEW_VERSION="$(bump_semver "$CURRENT" "$BUMP")"
108
+ elif [[ -n "$SET_VERSION" ]]; then
109
+ if [[ ! "$SET_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
110
+ echo "--set 仅支持 x.y.z 格式: $SET_VERSION" >&2
111
+ exit 1
112
+ fi
113
+ NEW_VERSION="$SET_VERSION"
114
+ fi
115
+
116
+ if [[ -n "$NEW_VERSION" ]]; then
117
+ write_versions "$NEW_VERSION"
118
+ echo "Version: ${CURRENT} -> ${NEW_VERSION}"
119
+ else
120
+ echo "Version: ${CURRENT} (unchanged)"
121
+ fi
122
+
123
+ if [[ "$SKIP_TESTS" -eq 0 ]]; then
124
+ if ! python -c "import pytest" 2>/dev/null; then
125
+ echo "未检测到 pytest,正在安装发布依赖: pip install -e \".[release]\""
126
+ python -m pip install -q -e ".[release]"
127
+ fi
128
+ echo "+ python -m pytest"
129
+ # 退出码 5 = 未收集到测试(旧版 pytest 或未开 suppress_no_test_exit_code 时仍视为可继续发布)
130
+ set +e
131
+ python -m pytest
132
+ pytest_ec=$?
133
+ set -e
134
+ if [[ "$pytest_ec" -ne 0 && "$pytest_ec" -ne 5 ]]; then
135
+ exit "$pytest_ec"
136
+ fi
137
+ if [[ "$pytest_ec" -eq 5 ]]; then
138
+ echo "提示: pytest 未收集到任何测试(退出码 5),继续构建与上传。" >&2
139
+ fi
140
+ fi
141
+
142
+ echo "+ clean dist/build artifacts"
143
+ rm -rf dist build ./*.egg-info src/issuekit.egg-info 2>/dev/null || true
144
+
145
+ echo "+ python -m build"
146
+ python -m build
147
+
148
+ echo "+ twine check dist/*"
149
+ python -m twine check dist/*
150
+
151
+ # 使用 -r pypi|testpypi(勿用 --repository-url),Twine 才会按名称读取 ~/.pypirc 里对应段落及凭据
152
+ if [[ "$REPOSITORY" == "testpypi" ]]; then
153
+ TWINE_REPO=( -r testpypi )
154
+ else
155
+ TWINE_REPO=( -r pypi )
156
+ fi
157
+
158
+ VER_FOR_MSG="${NEW_VERSION:-$CURRENT}"
159
+ if [[ "$DRY_RUN" -eq 1 ]]; then
160
+ echo "+ (dry-run) skipping: python -m twine upload ${TWINE_REPO[*]} dist/*"
161
+ echo "Done (dry-run)."
162
+ exit 0
163
+ fi
164
+
165
+ echo "+ python -m twine upload ${TWINE_REPO[*]} dist/*"
166
+ python -m twine upload "${TWINE_REPO[@]}" dist/*
167
+
168
+ echo "Uploaded to ${REPOSITORY}. Verify: pip install issuekit==${VER_FOR_MSG}"
@@ -1,3 +1,3 @@
1
1
  """IssueKit - AI 辅助开发的 Issue 全生命周期工具。"""
2
2
 
3
- __version__ = "0.1.5"
3
+ __version__ = "0.1.6"
@@ -1,55 +1,73 @@
1
- """将 issuekit skills 安装到目标目录。
2
-
3
- 每个 skill 是一个独立目录,包含 SKILL.md。
4
- Codex 额外需要 agents/openai.yaml 元数据文件。
5
- 源模板在 bundled_skills/ 下,按 skill-name/{SKILL.md, agents/openai.yaml} 组织。
6
- """
7
-
8
- from importlib import resources
9
- from pathlib import Path
10
-
11
- SKILL_DIRS = [
12
- "issuekit-require",
13
- "issuekit-design",
14
- "issuekit-coding",
15
- "issuekit-test",
16
- "issuekit-release",
17
- "issuekit-review",
18
- "issuekit-change",
19
- "issuekit-knowledge",
20
- ]
21
-
22
-
23
- def install_agent_skills(skills_dir: Path, *, include_openai_yaml: bool = False) -> int:
24
- """将所有 bundled skills 安装到目标目录,返回安装数。
25
-
26
- Args:
27
- skills_dir: 目标 skills 目录。
28
- include_openai_yaml: 是否同时复制 agents/openai.yaml(仅 Codex 需要)。
29
- """
30
- bundled = resources.files("issuekit") / "bundled_skills"
31
- count = 0
32
-
33
- for skill_name in SKILL_DIRS:
34
- source_dir = bundled / skill_name
35
- skill_md = source_dir / "SKILL.md"
36
- if not skill_md.is_file():
37
- continue
38
-
39
- dest_dir = skills_dir / skill_name
40
- dest_dir.mkdir(parents=True, exist_ok=True)
41
-
42
- content = skill_md.read_text(encoding="utf-8")
43
- (dest_dir / "SKILL.md").write_text(content, encoding="utf-8")
44
-
45
- if include_openai_yaml:
46
- openai_yaml = source_dir / "agents" / "openai.yaml"
47
- if openai_yaml.is_file():
48
- agents_dir = dest_dir / "agents"
49
- agents_dir.mkdir(parents=True, exist_ok=True)
50
- yaml_content = openai_yaml.read_text(encoding="utf-8")
51
- (agents_dir / "openai.yaml").write_text(yaml_content, encoding="utf-8")
52
-
53
- count += 1
54
-
55
- return count
1
+ """将 issuekit skills 安装到目标目录。
2
+
3
+ 每个 skill 是一个独立目录,包含 SKILL.md。
4
+ Codex 额外需要 agents/openai.yaml 元数据文件。
5
+ 源模板在 bundled_skills/ 下,包含入口、元数据及可选的引用文档和脚本。
6
+ """
7
+
8
+ from importlib import resources
9
+ from pathlib import Path
10
+
11
+ SKILL_DIRS = [
12
+ "issuekit-require",
13
+ "issuekit-design",
14
+ "issuekit-coding",
15
+ "issuekit-test",
16
+ "issuekit-business-test",
17
+ "issuekit-release",
18
+ "issuekit-review",
19
+ "issuekit-merge",
20
+ "issuekit-change",
21
+ "issuekit-knowledge",
22
+ ]
23
+
24
+
25
+ def _copy_skill_resources(source, destination: Path) -> None:
26
+ """递归复制包内 Skill 资源,兼容 importlib 的资源接口。"""
27
+ destination.mkdir(parents=True, exist_ok=True)
28
+ for item in source.iterdir():
29
+ target = destination / item.name
30
+ if item.is_dir():
31
+ _copy_skill_resources(item, target)
32
+ else:
33
+ target.write_bytes(item.read_bytes())
34
+
35
+
36
+ def install_agent_skills(skills_dir: Path, *, include_openai_yaml: bool = False) -> int:
37
+ """将所有 bundled skills 安装到目标目录,返回安装数。
38
+
39
+ Args:
40
+ skills_dir: 目标 skills 目录。
41
+ include_openai_yaml: 是否同时复制 agents/openai.yaml(仅 Codex 需要)。
42
+ """
43
+ bundled = resources.files("issuekit") / "bundled_skills"
44
+ count = 0
45
+
46
+ for skill_name in SKILL_DIRS:
47
+ source_dir = bundled / skill_name
48
+ skill_md = source_dir / "SKILL.md"
49
+ if not skill_md.is_file():
50
+ continue
51
+
52
+ dest_dir = skills_dir / skill_name
53
+ dest_dir.mkdir(parents=True, exist_ok=True)
54
+
55
+ content = skill_md.read_text(encoding="utf-8")
56
+ (dest_dir / "SKILL.md").write_text(content, encoding="utf-8")
57
+
58
+ for resource_name in ("references", "scripts", "assets"):
59
+ resource_dir = source_dir / resource_name
60
+ if resource_dir.is_dir():
61
+ _copy_skill_resources(resource_dir, dest_dir / resource_name)
62
+
63
+ if include_openai_yaml:
64
+ openai_yaml = source_dir / "agents" / "openai.yaml"
65
+ if openai_yaml.is_file():
66
+ agents_dir = dest_dir / "agents"
67
+ agents_dir.mkdir(parents=True, exist_ok=True)
68
+ yaml_content = openai_yaml.read_text(encoding="utf-8")
69
+ (agents_dir / "openai.yaml").write_text(yaml_content, encoding="utf-8")
70
+
71
+ count += 1
72
+
73
+ return count
@@ -1,5 +1,5 @@
1
- """AI 助手适配层,支持不同编程助手的 Skills 安装。"""
2
-
3
- from .registry import AGENT_REGISTRY, get_agent_config
4
-
5
- __all__ = ["AGENT_REGISTRY", "get_agent_config"]
1
+ """AI 助手适配层,支持不同编程助手的 Skills 安装。"""
2
+
3
+ from .registry import AGENT_REGISTRY, get_agent_config
4
+
5
+ __all__ = ["AGENT_REGISTRY", "get_agent_config"]