Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
3c37f61
Add the skeleton workflow I'm targetting as pseudocode with some notes.
ssrihari Sep 23, 2025
5b4291c
Add the models / dataclasses that I need, and extract story
ssrihari Sep 23, 2025
9cea449
Setting up the field for workflows
ssrihari Sep 23, 2025
7b59d1c
Get the harness working with the workflow
ssrihari Sep 23, 2025
996beca
Add test-data directory to gitignore
ssrihari Sep 23, 2025
6abcdb6
Ignore local claude settings
ssrihari Sep 23, 2025
531a42a
Implement the feedback activity, and use it in the workflow
ssrihari Sep 23, 2025
4bb9a9a
Complete the tool call ritual.
ssrihari Sep 25, 2025
1e4cee7
Upgrade openai client library to support conversations
ssrihari Sep 25, 2025
1733699
Don't ruff check fix on every edit
ssrihari Sep 25, 2025
98e937f
Iterate on the list of stories based on feedback from user.
ssrihari Sep 25, 2025
108496a
Simplify the problem break down prompt.
ssrihari Sep 26, 2025
2e35e5e
Use new prompt for iterating on stories
ssrihari Sep 26, 2025
7719687
Define acceptance criteria for stories one by one.
ssrihari Sep 29, 2025
eb9993a
Add notes and todos from using the tool
ssrihari Sep 29, 2025
02d3583
Add structured logging to help with debugging
ssrihari Sep 29, 2025
c309799
Show the reasoning output on the CLI.
ssrihari Sep 29, 2025
0bbee33
Remove unused code, and clean up
ssrihari Sep 29, 2025
e623b8b
Minor refactor to clean up the workflow to be a bit more readable
ssrihari Sep 29, 2025
a9bb21f
Add breakdown, reflection instructions to the iteration prompt as well.
ssrihari Sep 29, 2025
2185145
Enrich context for each story based on the PRD and Tech Spec
ssrihari Sep 29, 2025
90c9c5a
First step of getting repo context relevant to the PRD
ssrihari Oct 2, 2025
f2828e8
Get answers for repo questions using claude agent SDK
ssrihari Oct 2, 2025
1f492b7
Add repo context as source to most prompts, wherever appropriate
ssrihari Oct 2, 2025
2970237
Fix tests, add missing repo flag
ssrihari Oct 2, 2025
e0ce033
Minor updates to readme
ssrihari Oct 2, 2025
aad46fb
Use ask-github as a library instead of claude agent SDK
ssrihari Oct 3, 2025
65bfa13
Tweak ask-github prompt
ssrihari Oct 6, 2025
23c03fe
Upgrade ask-github to support gitlab too
ssrihari Oct 7, 2025
a4722bd
Update Readme to use github/gitlab url instead of filesystem path
ssrihari Oct 7, 2025
f3c1ca8
Finish the gitlab integration
ssrihari Oct 7, 2025
942132c
Upgrade ask-github
ssrihari Oct 9, 2025
584a914
Remove claude agent support
ssrihari Oct 9, 2025
e07958c
Use ask-github to get directory listing, and add that to breakdown pr…
ssrihari Oct 9, 2025
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
6 changes: 1 addition & 5 deletions .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@
{
"type": "command",
"command": "uv run ruff format"
},
{
"type": "command",
"command": "uv run ruff check --fix"
}
]
}
]
}
}
}
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ wheels/

# Code coverage file
.coverage

# Local input test data
test-data/

# Local claude settings
.claude/settings.local.json
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,34 @@ cd storymachine
uv sync
```

3. Set up your OpenAI API key in a `.env` file:
3. Set up your API keys in a `.env` file:
```bash
echo "OPENAI_API_KEY=your-api-key-here" > .env
# For GitHub repositories:
echo "GITHUB_TOKEN=ghp_your_token_here" >> .env
# For GitLab repositories:
echo "GITLAB_TOKEN=glpat_your_token_here" >> .env
```

**Token Requirements:**
- **GitHub**: Create a Personal Access Token with `repo` scope (Settings → Developer settings → Personal access tokens)
- **GitLab**: Create a Personal Access Token with `read_api` and `read_repository` scopes (User Settings → Access Tokens)

## Usage

Run StoryMachine with your PRD and technical specification files:
Run StoryMachine with your PRD, technical specification, and repository URL:

**For GitHub repositories:**
```bash
uv run storymachine --prd path/to/your/prd.md --tech-spec path/to/your/tech-spec.md
uv run storymachine --prd path/to/your/prd.md --tech-spec path/to/your/tech-spec.md --repo https://github.com/owner/repo
```

Example using your own files:
**For GitLab repositories:**
```bash
uv run storymachine --prd path/to/your/prd.md --tech-spec path/to/your/tech-spec.md
uv run storymachine --prd path/to/your/prd.md --tech-spec path/to/your/tech-spec.md --repo https://gitlab.com/owner/repo
```

The tool will generate user stories with acceptance criteria based on the provided documents and output them to the console.
The tool will generate user stories with acceptance criteria based on the provided documents, work with your feedback through a workflow, and output well specified stories to the console.

## Development

Expand Down
77 changes: 77 additions & 0 deletions doc/workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# What should the workflow look like?

It should be a graph, so, code? Temporal workflows are written imperatively. Imperative shell, functional core... that makes sense here. It's a now readstateful workflow. The state of the whole, and the parts keep changing as it progresses.

It's ideally concurrent, dealing with the stories independently and in parallel to the extent possible. There will also be some coordination then, to wait / bring the threads together. To begin with, we can do it serially, just to keep it simple. Parallel is mostly for performance and true representation. That can wait.

```
inputs = [PRD, ERD, Repo]

stories = [] # output is a list of stories, but we're iterating on them, improving them as we go.
response = (nil, nil) # (approved/rejected, comment) tuple of approval status, and an optional comment
feedback = nil

relevant_files = find_relevant_files(inputs)
while true:
prd_erd_questions = understand_prd_erd_and_ask_questions(inputs, response.comment)
response = get_human_input(prd_questions)
if response.rejected?
continue to iterate on understanding inputs
else
break


while true: ## chopping board
stories = problem_break_down(inputs, stories, feedback) # small, independent, valuable, verifiable, with some basic t-shirt sizing
feedback = get_human_input(stories)
if iteration_needed?(feedback)
continue to iterate on stories with feedback
else
break


for each story in stories:
story.define_acceptance_criteria(inputs)
story.enrich_context(inputs)
story.add_implementation_context(inputs)
story.estimate(inputs)
internal_feedback = story.is_ready_for_implementation?
if(internal_feedback.approved?)
response = get_human_input(story)
if response.approved?
next
else
iterate with response.comments
else
iterate with internal_feedback.comments

self_eval_result =
do_stories_add_up_to_prd_acs(stories)
+ are_stories_small(stories)
```

# Organising the work
## TODO prioritised
- [c] add unit tests

## notes from some prompt tweaking and iterating on the list of stories:
- the reflection section seems to help in reminding all the instructions
- iteration speed in conversations is quite important.

### interface
- feedback needs to be given about multiple stories, or about various things in general. would be great if comments could be made against each story, or the lsit of them.
- need to at least enable multi-line feedback in the cli.
- story numbers are useful to refer: story 7 should be broken-down / deprioritised
- some assurance that the other stories don’t regress is going to be useful.
- seeing “what changed” with each iteration would be useful
- would love to drag drop to reorder, and preserve that order on iteration
- some story grouping seems nice to have, like analytics, import, etc. mini-epics. using story prefixes is fine.

### functionality
- most comments need to be interpreted as operations on stories. need to tweak the prompt to reflect this.
- bogus comments work anyway, should ideally ask for clarification. conversations semantics already exist in the responses API. how to leverage that? the tool has to then differentiate between conversational response and the stories output
- workflow could use temporal style state persistence to continue conversations etc.

## Interface ideas
- integrate with JIRA
- build step-wise custom workflow interface
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"ask-github",
"fastapi>=0.116.1",
"openai>=0.100.2",
"pydantic-settings>=2.10.1",
"python-fasthtml>=0.12.25",
"structlog>=25.4.0",
"websockets>=15.0.1",
]

Expand Down Expand Up @@ -38,3 +40,6 @@ enable_ruff = true

[tool.marimo.diagnostics]
enabled = true

[tool.uv.sources]
ask-github = { git = "https://github.com/nilenso/ask-github.git" }
Loading