story-lifecycle 0.1.0__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.
- story_lifecycle-0.1.0/.github/workflows/ci.yml +69 -0
- story_lifecycle-0.1.0/.github/workflows/release.yml +105 -0
- story_lifecycle-0.1.0/.gitignore +24 -0
- story_lifecycle-0.1.0/LICENSE +21 -0
- story_lifecycle-0.1.0/PKG-INFO +99 -0
- story_lifecycle-0.1.0/README.md +68 -0
- story_lifecycle-0.1.0/profiles/minimal.yaml +34 -0
- story_lifecycle-0.1.0/prompts/design.md +33 -0
- story_lifecycle-0.1.0/prompts/implement.md +26 -0
- story_lifecycle-0.1.0/prompts/test.md +26 -0
- story_lifecycle-0.1.0/pyproject.toml +49 -0
- story_lifecycle-0.1.0/scripts/wsl-setup.sh +56 -0
- story_lifecycle-0.1.0/scripts/wsl-test.sh +46 -0
- story_lifecycle-0.1.0/src/story_lifecycle/__init__.py +2 -0
- story_lifecycle-0.1.0/src/story_lifecycle/adapters/__init__.py +17 -0
- story_lifecycle-0.1.0/src/story_lifecycle/adapters/base.py +32 -0
- story_lifecycle-0.1.0/src/story_lifecycle/adapters/claude.py +37 -0
- story_lifecycle-0.1.0/src/story_lifecycle/cli/doctor.py +165 -0
- story_lifecycle-0.1.0/src/story_lifecycle/cli/main.py +305 -0
- story_lifecycle-0.1.0/src/story_lifecycle/cli/setup.py +184 -0
- story_lifecycle-0.1.0/src/story_lifecycle/db/models.py +150 -0
- story_lifecycle-0.1.0/src/story_lifecycle/orchestrator/api.py +191 -0
- story_lifecycle-0.1.0/src/story_lifecycle/orchestrator/graph.py +104 -0
- story_lifecycle-0.1.0/src/story_lifecycle/orchestrator/nodes.py +382 -0
- story_lifecycle-0.1.0/src/story_lifecycle/orchestrator/router.py +104 -0
- story_lifecycle-0.1.0/src/story_lifecycle/terminal/ttyd.py +137 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_call:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
lint:
|
|
12
|
+
name: Lint & type check
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: '3.12'
|
|
21
|
+
|
|
22
|
+
- name: Install with dev dependencies
|
|
23
|
+
run: pip install -e ".[dev]"
|
|
24
|
+
|
|
25
|
+
- name: Ruff lint
|
|
26
|
+
run: pipx run ruff check src/
|
|
27
|
+
|
|
28
|
+
- name: Ruff format check
|
|
29
|
+
run: pipx run ruff format --check src/
|
|
30
|
+
|
|
31
|
+
test:
|
|
32
|
+
name: Test (Python ${{ matrix.python-version }} on ${{ matrix.os }})
|
|
33
|
+
needs: lint
|
|
34
|
+
runs-on: ${{ matrix.os }}
|
|
35
|
+
strategy:
|
|
36
|
+
matrix:
|
|
37
|
+
os: [ubuntu-latest, macos-latest]
|
|
38
|
+
python-version: ['3.10', '3.12']
|
|
39
|
+
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v4
|
|
42
|
+
|
|
43
|
+
- uses: actions/setup-python@v5
|
|
44
|
+
with:
|
|
45
|
+
python-version: ${{ matrix.python-version }}
|
|
46
|
+
|
|
47
|
+
- name: Install with dev dependencies
|
|
48
|
+
run: pip install -e ".[dev]"
|
|
49
|
+
|
|
50
|
+
- name: Run tests
|
|
51
|
+
run: pytest -v
|
|
52
|
+
|
|
53
|
+
build-check:
|
|
54
|
+
name: Verify build
|
|
55
|
+
needs: lint
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
|
|
61
|
+
- uses: actions/setup-python@v5
|
|
62
|
+
with:
|
|
63
|
+
python-version: '3.12'
|
|
64
|
+
|
|
65
|
+
- name: Build package
|
|
66
|
+
run: pipx run build
|
|
67
|
+
|
|
68
|
+
- name: Twine check
|
|
69
|
+
run: pipx run twine check dist/*
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
ci:
|
|
10
|
+
uses: ./.github/workflows/ci.yml
|
|
11
|
+
|
|
12
|
+
build:
|
|
13
|
+
name: Build package
|
|
14
|
+
needs: ci
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: '3.12'
|
|
23
|
+
|
|
24
|
+
- name: Build package
|
|
25
|
+
run: pipx run build
|
|
26
|
+
|
|
27
|
+
- name: Twine check
|
|
28
|
+
run: pipx run twine check dist/*
|
|
29
|
+
|
|
30
|
+
- uses: actions/upload-artifact@v4
|
|
31
|
+
with:
|
|
32
|
+
name: dist
|
|
33
|
+
path: dist/
|
|
34
|
+
|
|
35
|
+
testpypi-publish:
|
|
36
|
+
name: Publish to TestPyPI
|
|
37
|
+
needs: build
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
environment:
|
|
40
|
+
name: testpypi
|
|
41
|
+
url: https://test.pypi.org/project/story-lifecycle/
|
|
42
|
+
permissions:
|
|
43
|
+
id-token: write
|
|
44
|
+
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/download-artifact@v4
|
|
47
|
+
with:
|
|
48
|
+
name: dist
|
|
49
|
+
path: dist/
|
|
50
|
+
|
|
51
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
52
|
+
with:
|
|
53
|
+
repository-url: https://test.pypi.org/legacy/
|
|
54
|
+
password: ${{ secrets.TESTPYPI_TOKEN }}
|
|
55
|
+
|
|
56
|
+
pypi-publish:
|
|
57
|
+
name: Publish to PyPI
|
|
58
|
+
needs: testpypi-publish
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
environment:
|
|
61
|
+
name: pypi
|
|
62
|
+
url: https://pypi.org/project/story-lifecycle/
|
|
63
|
+
permissions:
|
|
64
|
+
id-token: write
|
|
65
|
+
|
|
66
|
+
steps:
|
|
67
|
+
- uses: actions/download-artifact@v4
|
|
68
|
+
with:
|
|
69
|
+
name: dist
|
|
70
|
+
path: dist/
|
|
71
|
+
|
|
72
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
73
|
+
with:
|
|
74
|
+
password: ${{ secrets.PYPI_TOKEN }}
|
|
75
|
+
|
|
76
|
+
github-release:
|
|
77
|
+
name: Create GitHub Release
|
|
78
|
+
needs: pypi-publish
|
|
79
|
+
runs-on: ubuntu-latest
|
|
80
|
+
permissions:
|
|
81
|
+
contents: write
|
|
82
|
+
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/checkout@v4
|
|
85
|
+
with:
|
|
86
|
+
fetch-depth: 0
|
|
87
|
+
|
|
88
|
+
- uses: actions/download-artifact@v4
|
|
89
|
+
with:
|
|
90
|
+
name: dist
|
|
91
|
+
path: dist/
|
|
92
|
+
|
|
93
|
+
- name: Generate release notes
|
|
94
|
+
run: |
|
|
95
|
+
PREV_TAG=$(git tag --sort=-creatordate | grep -A1 "${{ github.ref_name }}" | tail -1)
|
|
96
|
+
if [ -z "$PREV_TAG" ]; then
|
|
97
|
+
PREV_TAG=$(git rev-list --max-parents=0 HEAD)
|
|
98
|
+
fi
|
|
99
|
+
git log "${PREV_TAG}..${{ github.ref_name }}" --pretty=format:"- %s (%h)" > CHANGELOG.md
|
|
100
|
+
|
|
101
|
+
- uses: softprops/action-gh-release@v2
|
|
102
|
+
with:
|
|
103
|
+
body_path: CHANGELOG.md
|
|
104
|
+
files: dist/*
|
|
105
|
+
generate_release_notes: false
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
*.egg
|
|
8
|
+
|
|
9
|
+
# Virtual env
|
|
10
|
+
.venv/
|
|
11
|
+
venv/
|
|
12
|
+
|
|
13
|
+
# IDE
|
|
14
|
+
.vscode/
|
|
15
|
+
.idea/
|
|
16
|
+
|
|
17
|
+
# Story Lifecycle local data (user-level, not in repo)
|
|
18
|
+
.story/
|
|
19
|
+
story.db
|
|
20
|
+
checkpoint.db
|
|
21
|
+
|
|
22
|
+
# OS
|
|
23
|
+
.DS_Store
|
|
24
|
+
Thumbs.db
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zihao Zhao
|
|
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.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: story-lifecycle
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI-powered development workflow orchestrator — from TAPD/Jira story to production
|
|
5
|
+
Author: zhaozihao
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: ai,claude-code,devtools,orchestrator,workflow
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Requires-Dist: click>=8.1.0
|
|
17
|
+
Requires-Dist: fastapi>=0.115.0
|
|
18
|
+
Requires-Dist: httpx>=0.27.0
|
|
19
|
+
Requires-Dist: langgraph-checkpoint-sqlite>=3.0
|
|
20
|
+
Requires-Dist: langgraph>=0.2.0
|
|
21
|
+
Requires-Dist: pyyaml>=6.0
|
|
22
|
+
Requires-Dist: rich>=13.0.0
|
|
23
|
+
Requires-Dist: uvicorn[standard]>=0.30.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: ruff>=0.11.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: twine>=6.0; extra == 'dev'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# Story Lifecycle Manager
|
|
33
|
+
|
|
34
|
+
AI-powered development workflow orchestrator — from TAPD/Jira story to production.
|
|
35
|
+
|
|
36
|
+
> **Work in progress — Phase 1 development.**
|
|
37
|
+
|
|
38
|
+
## Platform Support
|
|
39
|
+
|
|
40
|
+
| Platform | CLI + DB | AI Execution (tmux/ttyd) |
|
|
41
|
+
|----------|----------|--------------------------|
|
|
42
|
+
| **Linux** | Full | Full |
|
|
43
|
+
| **macOS** | Full | Full (install tmux: `brew install tmux ttyd`) |
|
|
44
|
+
| **Windows (native)** | Full | Not supported — use WSL2 |
|
|
45
|
+
| **Windows (WSL2)** | Full | Full |
|
|
46
|
+
|
|
47
|
+
### Why Windows native doesn't support AI execution
|
|
48
|
+
|
|
49
|
+
tmux and ttyd depend on Unix pseudo-terminals (PTY), `fork()`, and POSIX signals — APIs not available on native Windows. All major AI coding CLI tools (Claude Code, Aider) have the same limitation.
|
|
50
|
+
|
|
51
|
+
**Recommended setup on Windows:**
|
|
52
|
+
|
|
53
|
+
```powershell
|
|
54
|
+
# In WSL2 Ubuntu
|
|
55
|
+
sudo apt install tmux ttyd
|
|
56
|
+
pip install story-lifecycle
|
|
57
|
+
story serve
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Quick Start
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Install
|
|
64
|
+
pip install story-lifecycle # not yet on PyPI — use `pip install -e .`
|
|
65
|
+
|
|
66
|
+
# Start orchestrator in one terminal
|
|
67
|
+
story serve
|
|
68
|
+
|
|
69
|
+
# Create a story in another terminal
|
|
70
|
+
story new STORY-123 --title "Add login feature"
|
|
71
|
+
|
|
72
|
+
# Watch progress
|
|
73
|
+
story board
|
|
74
|
+
|
|
75
|
+
# Interact with the AI (Linux/macOS/WSL only)
|
|
76
|
+
story enter STORY-123
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Profiles
|
|
80
|
+
|
|
81
|
+
- `minimal` (default): design → implement → test (3 stages)
|
|
82
|
+
- `standard`: full 14-stage flow (coming in Phase 2)
|
|
83
|
+
- Custom: drop a YAML in `~/.story-lifecycle/profiles/`
|
|
84
|
+
|
|
85
|
+
## CLI Commands
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
story new <KEY> --title "..." Create a new story
|
|
89
|
+
story board Show all active stories
|
|
90
|
+
story enter <KEY> Open terminal to interact with AI
|
|
91
|
+
story status <KEY> Show story details
|
|
92
|
+
story skip <KEY> --stage <NAME> Skip a stage
|
|
93
|
+
story fail <KEY> Mark as blocked
|
|
94
|
+
story serve Start the orchestrator server
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## License
|
|
98
|
+
|
|
99
|
+
MIT
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Story Lifecycle Manager
|
|
2
|
+
|
|
3
|
+
AI-powered development workflow orchestrator — from TAPD/Jira story to production.
|
|
4
|
+
|
|
5
|
+
> **Work in progress — Phase 1 development.**
|
|
6
|
+
|
|
7
|
+
## Platform Support
|
|
8
|
+
|
|
9
|
+
| Platform | CLI + DB | AI Execution (tmux/ttyd) |
|
|
10
|
+
|----------|----------|--------------------------|
|
|
11
|
+
| **Linux** | Full | Full |
|
|
12
|
+
| **macOS** | Full | Full (install tmux: `brew install tmux ttyd`) |
|
|
13
|
+
| **Windows (native)** | Full | Not supported — use WSL2 |
|
|
14
|
+
| **Windows (WSL2)** | Full | Full |
|
|
15
|
+
|
|
16
|
+
### Why Windows native doesn't support AI execution
|
|
17
|
+
|
|
18
|
+
tmux and ttyd depend on Unix pseudo-terminals (PTY), `fork()`, and POSIX signals — APIs not available on native Windows. All major AI coding CLI tools (Claude Code, Aider) have the same limitation.
|
|
19
|
+
|
|
20
|
+
**Recommended setup on Windows:**
|
|
21
|
+
|
|
22
|
+
```powershell
|
|
23
|
+
# In WSL2 Ubuntu
|
|
24
|
+
sudo apt install tmux ttyd
|
|
25
|
+
pip install story-lifecycle
|
|
26
|
+
story serve
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Install
|
|
33
|
+
pip install story-lifecycle # not yet on PyPI — use `pip install -e .`
|
|
34
|
+
|
|
35
|
+
# Start orchestrator in one terminal
|
|
36
|
+
story serve
|
|
37
|
+
|
|
38
|
+
# Create a story in another terminal
|
|
39
|
+
story new STORY-123 --title "Add login feature"
|
|
40
|
+
|
|
41
|
+
# Watch progress
|
|
42
|
+
story board
|
|
43
|
+
|
|
44
|
+
# Interact with the AI (Linux/macOS/WSL only)
|
|
45
|
+
story enter STORY-123
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Profiles
|
|
49
|
+
|
|
50
|
+
- `minimal` (default): design → implement → test (3 stages)
|
|
51
|
+
- `standard`: full 14-stage flow (coming in Phase 2)
|
|
52
|
+
- Custom: drop a YAML in `~/.story-lifecycle/profiles/`
|
|
53
|
+
|
|
54
|
+
## CLI Commands
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
story new <KEY> --title "..." Create a new story
|
|
58
|
+
story board Show all active stories
|
|
59
|
+
story enter <KEY> Open terminal to interact with AI
|
|
60
|
+
story status <KEY> Show story details
|
|
61
|
+
story skip <KEY> --stage <NAME> Skip a stage
|
|
62
|
+
story fail <KEY> Mark as blocked
|
|
63
|
+
story serve Start the orchestrator server
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## License
|
|
67
|
+
|
|
68
|
+
MIT
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Story Lifecycle — Minimal Profile (3 stages)
|
|
2
|
+
# Default profile for quick iterations
|
|
3
|
+
version: 2
|
|
4
|
+
cli: claude
|
|
5
|
+
|
|
6
|
+
stages:
|
|
7
|
+
design:
|
|
8
|
+
order: 1
|
|
9
|
+
description: "需求分析与方案设计"
|
|
10
|
+
skill: "/brainstorming"
|
|
11
|
+
confirm: false
|
|
12
|
+
max_retries: 2
|
|
13
|
+
allowed_providers: [deepseek, zhipu]
|
|
14
|
+
expected_outputs:
|
|
15
|
+
- spec_path
|
|
16
|
+
- complexity
|
|
17
|
+
next_default: [implement]
|
|
18
|
+
|
|
19
|
+
implement:
|
|
20
|
+
order: 2
|
|
21
|
+
description: "编码实现"
|
|
22
|
+
confirm: false
|
|
23
|
+
max_retries: 3
|
|
24
|
+
allowed_providers: [deepseek, zhipu, anthropic]
|
|
25
|
+
expected_outputs: []
|
|
26
|
+
next_default: [test]
|
|
27
|
+
|
|
28
|
+
test:
|
|
29
|
+
order: 3
|
|
30
|
+
description: "编译验证与冒烟测试"
|
|
31
|
+
confirm: false
|
|
32
|
+
max_retries: 2
|
|
33
|
+
expected_outputs: []
|
|
34
|
+
next_default: []
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
对需求进行分析与方案设计。
|
|
2
|
+
|
|
3
|
+
## 任务信息
|
|
4
|
+
|
|
5
|
+
- Story Key: {story_key}
|
|
6
|
+
- 标题: {title}
|
|
7
|
+
{prd_path_section}
|
|
8
|
+
{no_prd_section}
|
|
9
|
+
|
|
10
|
+
## 步骤
|
|
11
|
+
|
|
12
|
+
{requirement_source}
|
|
13
|
+
分析需求范围,确定复杂度(S=小需求≤3文件, M=中等4-8文件, L=大需求>8文件或跨服务)和影响范围。
|
|
14
|
+
将设计文档写入项目 `docs/` 目录。
|
|
15
|
+
|
|
16
|
+
## 完成后
|
|
17
|
+
|
|
18
|
+
将结果写入项目根目录下的 `.story-done/design.json`:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"spec_path": "设计文档路径",
|
|
23
|
+
"complexity": "S|M|L",
|
|
24
|
+
"summary": "简要分析摘要"
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
> CRITICAL: The file must contain ONLY raw JSON. No markdown code blocks, no explanations. Pure JSON only — otherwise the system fails.
|
|
29
|
+
|
|
30
|
+
## 边界
|
|
31
|
+
|
|
32
|
+
- 只做分析和文档,写完 `.story-done/design.json` 就停止
|
|
33
|
+
- 不要安装依赖、不要修改代码、不要执行后续阶段
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
根据设计文档进行编码实现。
|
|
2
|
+
|
|
3
|
+
## 任务信息
|
|
4
|
+
|
|
5
|
+
- Story Key: {story_key}
|
|
6
|
+
- 标题: {title}
|
|
7
|
+
{spec_path_section}
|
|
8
|
+
|
|
9
|
+
## 步骤
|
|
10
|
+
|
|
11
|
+
1. 如果存在设计文档,先阅读理解
|
|
12
|
+
2. 按设计文档实现代码
|
|
13
|
+
3. 完成后记录修改的文件列表
|
|
14
|
+
|
|
15
|
+
## 完成后
|
|
16
|
+
|
|
17
|
+
将结果写入项目根目录下的 `.story-done/implement.json`:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"files_changed": ["改动的文件列表"],
|
|
22
|
+
"summary": "实现了哪些功能"
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
> CRITICAL: The file must contain ONLY raw JSON. No markdown code blocks.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
运行编译验证和测试。
|
|
2
|
+
|
|
3
|
+
## 任务信息
|
|
4
|
+
|
|
5
|
+
- Story Key: {story_key}
|
|
6
|
+
- 标题: {title}
|
|
7
|
+
|
|
8
|
+
## 步骤
|
|
9
|
+
|
|
10
|
+
1. 确认代码已正确修改
|
|
11
|
+
2. 运行项目编译命令,确认无编译错误
|
|
12
|
+
3. 如果有测试,运行冒烟测试
|
|
13
|
+
|
|
14
|
+
## 完成后
|
|
15
|
+
|
|
16
|
+
将结果写入项目根目录下的 `.story-done/test.json`:
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"build_passed": true,
|
|
21
|
+
"tests_passed": true,
|
|
22
|
+
"summary": "编译和测试结果"
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
> CRITICAL: The file must contain ONLY raw JSON. No markdown code blocks.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "story-lifecycle"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "AI-powered development workflow orchestrator — from TAPD/Jira story to production"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "zhaozihao"},
|
|
14
|
+
]
|
|
15
|
+
keywords = ["ai", "claude-code", "orchestrator", "workflow", "devtools"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
dependencies = [
|
|
26
|
+
"fastapi>=0.115.0",
|
|
27
|
+
"uvicorn[standard]>=0.30.0",
|
|
28
|
+
"click>=8.1.0",
|
|
29
|
+
"rich>=13.0.0",
|
|
30
|
+
"pyyaml>=6.0",
|
|
31
|
+
"langgraph>=0.2.0",
|
|
32
|
+
"langgraph-checkpoint-sqlite>=3.0",
|
|
33
|
+
"httpx>=0.27.0",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
dev = [
|
|
38
|
+
"pytest>=8.0",
|
|
39
|
+
"pytest-asyncio>=0.24.0",
|
|
40
|
+
"ruff>=0.11.0",
|
|
41
|
+
"build>=1.0",
|
|
42
|
+
"twine>=6.0",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[project.scripts]
|
|
46
|
+
story = "story_lifecycle.cli.main:cli"
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.wheel]
|
|
49
|
+
packages = ["src/story_lifecycle"]
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Story Lifecycle Manager — WSL2 setup & test
|
|
3
|
+
# Run this inside your WSL2 terminal
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
echo "=== 1. Check environment ==="
|
|
8
|
+
python3 --version
|
|
9
|
+
echo "tmux: $(which tmux 2>/dev/null || echo 'NOT FOUND — install: sudo apt install tmux')"
|
|
10
|
+
echo "ttyd: $(which ttyd 2>/dev/null || echo 'NOT FOUND — install: sudo apt install ttyd')"
|
|
11
|
+
echo "git: $(which git)"
|
|
12
|
+
|
|
13
|
+
echo ""
|
|
14
|
+
echo "=== 2. Install tmux/ttyd if missing ==="
|
|
15
|
+
if ! command -v tmux &>/dev/null; then
|
|
16
|
+
sudo apt update && sudo apt install -y tmux
|
|
17
|
+
fi
|
|
18
|
+
if ! command -v ttyd &>/dev/null; then
|
|
19
|
+
sudo apt update && sudo apt install -y ttyd
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
echo ""
|
|
23
|
+
echo "=== 3. Clone & setup project ==="
|
|
24
|
+
cd ~
|
|
25
|
+
if [ ! -d story-lifecycle ]; then
|
|
26
|
+
git clone https://github.com/iceCloudZ/story-lifecycle.git
|
|
27
|
+
fi
|
|
28
|
+
cd story-lifecycle
|
|
29
|
+
git pull --rebase
|
|
30
|
+
|
|
31
|
+
python3 -m venv .venv
|
|
32
|
+
source .venv/bin/activate
|
|
33
|
+
pip install -e ".[dev]"
|
|
34
|
+
|
|
35
|
+
echo ""
|
|
36
|
+
echo "=== 4. Start orchestrator ==="
|
|
37
|
+
pkill -f "story serve" 2>/dev/null || true
|
|
38
|
+
nohup story serve --host 127.0.0.1 --port 8180 > /tmp/story-server.log 2>&1 &
|
|
39
|
+
sleep 3
|
|
40
|
+
curl -s http://127.0.0.1:8180/api/session/health
|
|
41
|
+
|
|
42
|
+
echo ""
|
|
43
|
+
echo "=== 5. Create test story ==="
|
|
44
|
+
story new STORY-1065520 --title "职业邮箱限制" --profile minimal --workspace ~
|
|
45
|
+
|
|
46
|
+
echo ""
|
|
47
|
+
echo "=== 6. Check tmux session ==="
|
|
48
|
+
sleep 5
|
|
49
|
+
tmux list-sessions 2>/dev/null || echo "(no tmux sessions)"
|
|
50
|
+
tmux capture-pane -t s-STORY-1065520 -p -S -20 2>/dev/null || echo "(session not ready yet)"
|
|
51
|
+
|
|
52
|
+
echo ""
|
|
53
|
+
echo "=== Done! ==="
|
|
54
|
+
echo "Dashboard: story board"
|
|
55
|
+
echo "Terminal: story enter STORY-1065520"
|
|
56
|
+
echo "Or attach: tmux attach -t s-STORY-1065520"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Quick test of story-lifecycle in WSL2
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
echo "=== Install tmux/ttyd ==="
|
|
6
|
+
sudo apt update -qq && sudo apt install -y -qq tmux ttyd 2>/dev/null
|
|
7
|
+
|
|
8
|
+
echo ""
|
|
9
|
+
echo "=== Setup project ==="
|
|
10
|
+
cd /mnt/d/story-lifecycle
|
|
11
|
+
python3 -m venv .venv 2>/dev/null || true
|
|
12
|
+
source .venv/bin/activate
|
|
13
|
+
pip install -e ".[dev]" -q
|
|
14
|
+
|
|
15
|
+
echo ""
|
|
16
|
+
echo "=== Clean old data ==="
|
|
17
|
+
pkill -f "story serve" 2>/dev/null || true
|
|
18
|
+
tmux kill-session -t s-STORY-TEST 2>/dev/null || true
|
|
19
|
+
rm -f ~/.story-lifecycle/story.db
|
|
20
|
+
|
|
21
|
+
echo ""
|
|
22
|
+
echo "=== Start server ==="
|
|
23
|
+
nohup story serve --host 127.0.0.1 --port 8180 > /tmp/story-server.log 2>&1 &
|
|
24
|
+
sleep 3
|
|
25
|
+
curl -s http://127.0.0.1:8180/api/session/health
|
|
26
|
+
echo ""
|
|
27
|
+
|
|
28
|
+
echo ""
|
|
29
|
+
echo "=== Create test story ==="
|
|
30
|
+
WS=$(pwd)
|
|
31
|
+
curl -s -X POST http://127.0.0.1:8180/api/story \
|
|
32
|
+
-H 'Content-Type: application/json' \
|
|
33
|
+
-d "{\"key\":\"STORY-TEST\",\"title\":\"Test Feature\",\"profile\":\"minimal\",\"workspace\":\"$WS\"}"
|
|
34
|
+
|
|
35
|
+
echo ""
|
|
36
|
+
echo "=== Check tmux ==="
|
|
37
|
+
sleep 8
|
|
38
|
+
tmux list-sessions 2>/dev/null || echo "(no tmux sessions)"
|
|
39
|
+
echo ""
|
|
40
|
+
echo "=== CC output ==="
|
|
41
|
+
tmux capture-pane -t s-STORY-TEST -p -S -20 2>/dev/null || echo "(session not ready)"
|
|
42
|
+
|
|
43
|
+
echo ""
|
|
44
|
+
echo "=== Done ==="
|
|
45
|
+
echo "Server log: cat /tmp/story-server.log"
|
|
46
|
+
echo "Attach: tmux attach -t s-STORY-TEST"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""CLI adapters — abstract AI coding tools behind a uniform interface."""
|
|
2
|
+
|
|
3
|
+
from .base import BaseAdapter
|
|
4
|
+
from .claude import ClaudeAdapter
|
|
5
|
+
|
|
6
|
+
__all__ = ["BaseAdapter", "ClaudeAdapter", "get_adapter"]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_adapter(name: str) -> BaseAdapter:
|
|
10
|
+
"""Get adapter by name. Case-insensitive."""
|
|
11
|
+
adapters = {
|
|
12
|
+
"claude": ClaudeAdapter,
|
|
13
|
+
}
|
|
14
|
+
cls = adapters.get(name.lower())
|
|
15
|
+
if not cls:
|
|
16
|
+
raise ValueError(f"Unknown CLI adapter: {name}. Available: {list(adapters.keys())}")
|
|
17
|
+
return cls()
|