fraim-framework 2.0.4 → 2.0.7

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.
@@ -1,90 +1,90 @@
1
- # Testing Phase
2
-
3
- ## INTENT
4
- To create comprehensive test coverage that accurately reproduces issues and validates solutions, ensuring robust testing through proper test structure, failure verification, and systematic test execution.
5
-
6
- ## PRINCIPLES
7
- - **Test-Driven**: Write tests that reproduce the issue before fixing
8
- - **Comprehensive Coverage**: Ensure all scenarios are tested
9
- - **Failure Verification**: Confirm tests fail before implementation
10
- - **Proper Structure**: Use established test patterns and frameworks
11
- - **Systematic Execution**: Follow consistent testing procedures
12
-
13
- ## TESTING WORKFLOW
14
-
15
- ### Step 1: Issue Identification
16
- Ask for {issue_number} (and optional {slug}); confirm target branch feature/{issue_number}-{slug}.
17
-
18
- ### Step 2: Phase Initiation
19
- Label the issue 'phase:tests'. (GitHub Action will automatically label the issue `status:wip` and update the existing draft PR)
20
-
21
- ### Step 3: Environment Setup
22
- **IMPORTANT**: The user has already run `prep-issue.sh` which has:
23
- - ✅ Created the feature branch
24
- - ✅ Checked out the branch
25
- - ✅ Created draft PR
26
- - ✅ Indexed the codebase with Serena
27
- - ✅ Opened the editor in the prepared workspace
28
-
29
- You can start working immediately in the prepared environment. No need to create branches or wait for GitHub Actions.
30
-
31
- ### Step 4: Work Location
32
- You are already in the correct workspace prepared by the user. Confirm you're on the right branch and start working.
33
-
34
- ### Step 5: Testing Work
35
- Your work entails the following:
36
-
37
- - Review the RFC associated with this issue.
38
- - Determine whether tests need to be added to an existing test suite, or a new one needs to be created.
39
- - **CRITICAL: Write INTEGRATION tests that demonstrate the REAL USER SCENARIO**
40
- - Test the actual end-to-end user experience, not unit tests for hypothetical fixes
41
- - Use real services and APIs where possible (not mocks)
42
- - Verify the issue occurs in the real system as described in the issue
43
- - Example: For messaging threading issues, actually send messages and verify they appear as new messages vs replies
44
- - Run the test cases to ensure they fail (demonstrating the issue exists)
45
- - Flip issue to 'status:needs-review' and remove 'status:wip'
46
-
47
- **❌ DO NOT:**
48
- - Write unit tests for code that doesn't exist yet
49
- - Test hypothetical fixes or solutions
50
- - Create mock tests that don't use real services
51
- - Test individual components in isolation
52
-
53
- **✅ DO:**
54
- - Test the complete user workflow end-to-end
55
- - Use real APIs and services when possible
56
- - Verify the actual problem described in the issue
57
- - Create tests that will pass AFTER the fix is implemented
58
-
59
- ### Step 6: Iteration
60
- If workflow actions or reviewer feedback indicates more work is needed, ensure the issue is set back to `status:wip` and continue working as above.
61
-
62
- ## EXAMPLES
63
-
64
- ### Good: Comprehensive Testing Process
65
- ```
66
- Issue #84: "Fix API integration timeout"
67
- 1. ✅ Identified: Issue #84, branch feature/84-fix-api
68
- 2. ✅ Phase: Set phase:tests, PR created
69
- 3. ✅ Environment: User ran prep-issue.sh, ready to work
70
- 4. ✅ Location: Working in prepared workspace with Serena indexing
71
- 5. ✅ RFC Review: Read docs/rfcs/84-fix-api-timeout.md
72
- 6. ✅ Analysis: Determined need to add timeout tests
73
- 7. ✅ Test Creation: Added test cases for timeout scenarios
74
- 8. ✅ Failure Verification: Confirmed tests fail before fix
75
- 9. ✅ Review: Set status:needs-review
76
- 10. ✅ Iteration: Incorporated feedback, updated tests
77
- Result: Comprehensive test coverage with proper structure
78
- ```
79
-
80
- ### Bad: Incomplete Testing Process
81
- ```
82
- Issue #84: "Fix API integration timeout"
83
- 1. ✅ Identified: Issue #84
84
- 2. ❌ Skip: Didn't review RFC
85
- 3. ❌ Skip: Started testing without understanding requirements
86
- 4. ❌ Skip: No test cases written
87
- 5. ❌ Skip: Didn't verify tests fail
88
- 6. ❌ Skip: No test structure followed
89
- Result: Incomplete, ineffective testing
1
+ # Testing Phase
2
+
3
+ ## INTENT
4
+ To create comprehensive test coverage that accurately reproduces issues and validates solutions, ensuring robust testing through proper test structure, failure verification, and systematic test execution.
5
+
6
+ ## PRINCIPLES
7
+ - **Test-Driven**: Write tests that reproduce the issue before fixing
8
+ - **Comprehensive Coverage**: Ensure all scenarios are tested
9
+ - **Failure Verification**: Confirm tests fail before implementation
10
+ - **Proper Structure**: Use established test patterns and frameworks
11
+ - **Systematic Execution**: Follow consistent testing procedures
12
+
13
+ ## TESTING WORKFLOW
14
+
15
+ ### Step 1: Issue Identification
16
+ Ask for {issue_number} (and optional {slug}); confirm target branch feature/{issue_number}-{slug}.
17
+
18
+ ### Step 2: Phase Initiation
19
+ Label the issue 'phase:tests'. (GitHub Action will automatically label the issue `status:wip` and update the existing draft PR)
20
+
21
+ ### Step 3: Environment Setup
22
+ **IMPORTANT**: The user has already run `prep-issue.sh` which has:
23
+ - ✅ Created the feature branch
24
+ - ✅ Checked out the branch
25
+ - ✅ Created draft PR
26
+ - ✅ Indexed the codebase with Serena
27
+ - ✅ Opened the editor in the prepared workspace
28
+
29
+ You can start working immediately in the prepared environment. No need to create branches or wait for GitHub Actions.
30
+
31
+ ### Step 4: Work Location
32
+ You are already in the correct workspace prepared by the user. Confirm you're on the right branch and start working.
33
+
34
+ ### Step 5: Testing Work
35
+ Your work entails the following:
36
+
37
+ - Review the RFC associated with this issue.
38
+ - Determine whether tests need to be added to an existing test suite, or a new one needs to be created.
39
+ - **CRITICAL: Write INTEGRATION tests that demonstrate the REAL USER SCENARIO**
40
+ - Test the actual end-to-end user experience, not unit tests for hypothetical fixes
41
+ - Use real services and APIs where possible (not mocks)
42
+ - Verify the issue occurs in the real system as described in the issue
43
+ - Example: For messaging threading issues, actually send messages and verify they appear as new messages vs replies
44
+ - Run the test cases to ensure they fail (demonstrating the issue exists)
45
+ - Flip issue to 'status:needs-review' and remove 'status:wip'
46
+
47
+ **❌ DO NOT:**
48
+ - Write unit tests for code that doesn't exist yet
49
+ - Test hypothetical fixes or solutions
50
+ - Create mock tests that don't use real services
51
+ - Test individual components in isolation
52
+
53
+ **✅ DO:**
54
+ - Test the complete user workflow end-to-end
55
+ - Use real APIs and services when possible
56
+ - Verify the actual problem described in the issue
57
+ - Create tests that will pass AFTER the fix is implemented
58
+
59
+ ### Step 6: Iteration
60
+ If workflow actions or reviewer feedback indicates more work is needed, ensure the issue is set back to `status:wip` and continue working as above.
61
+
62
+ ## EXAMPLES
63
+
64
+ ### Good: Comprehensive Testing Process
65
+ ```
66
+ Issue #84: "Fix API integration timeout"
67
+ 1. ✅ Identified: Issue #84, branch feature/84-fix-api
68
+ 2. ✅ Phase: Set phase:tests, PR created
69
+ 3. ✅ Environment: User ran prep-issue.sh, ready to work
70
+ 4. ✅ Location: Working in prepared workspace with Serena indexing
71
+ 5. ✅ RFC Review: Read docs/rfcs/84-fix-api-timeout.md
72
+ 6. ✅ Analysis: Determined need to add timeout tests
73
+ 7. ✅ Test Creation: Added test cases for timeout scenarios
74
+ 8. ✅ Failure Verification: Confirmed tests fail before fix
75
+ 9. ✅ Review: Set status:needs-review
76
+ 10. ✅ Iteration: Incorporated feedback, updated tests
77
+ Result: Comprehensive test coverage with proper structure
78
+ ```
79
+
80
+ ### Bad: Incomplete Testing Process
81
+ ```
82
+ Issue #84: "Fix API integration timeout"
83
+ 1. ✅ Identified: Issue #84
84
+ 2. ❌ Skip: Didn't review RFC
85
+ 3. ❌ Skip: Started testing without understanding requirements
86
+ 4. ❌ Skip: No test cases written
87
+ 5. ❌ Skip: Didn't verify tests fail
88
+ 6. ❌ Skip: No test structure followed
89
+ Result: Incomplete, ineffective testing
90
90
  ```
@@ -0,0 +1,51 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - 'master'
7
+ schedule:
8
+ - cron: '0 6 * * *' # 11 PM PST is 6 AM UTC
9
+
10
+ # Sets permissions of the GITHUB_TOKEN
11
+ permissions:
12
+ contents: read
13
+ checks: write
14
+
15
+ # Cancel in-progress runs on same branch
16
+ concurrency:
17
+ group: ci-${{ github.workflow }}-${{ github.ref }}
18
+ cancel-in-progress: true
19
+
20
+ jobs:
21
+ build:
22
+ if: github.event_name == 'push'
23
+ runs-on: ubuntu-latest
24
+ timeout-minutes: 15
25
+
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+ - uses: actions/setup-node@v4
29
+ with:
30
+ node-version: 20
31
+ - run: npm install
32
+ - name: Build
33
+ run: npm run build
34
+ - name: Test Smoke CI
35
+ run: npm run test-smoke-ci
36
+
37
+ full-test:
38
+ runs-on: ubuntu-latest
39
+ if: github.event_name == 'schedule' && github.ref == 'refs/heads/master'
40
+
41
+ steps:
42
+ - uses: actions/checkout@v4
43
+ - uses: actions/setup-node@v4
44
+ with:
45
+ node-version: 20
46
+ - run: npm install
47
+ - name: Build
48
+ run: npm run build
49
+ - name: Test All CI
50
+ run: npm run test-all-ci
51
+ timeout-minutes: 30
@@ -0,0 +1,251 @@
1
+ name: Phase Change Handler
2
+
3
+ # This workflow now assumes branches are created by prep-issue.sh
4
+ # It only handles PR creation/updating and status management
5
+
6
+ on:
7
+ issues:
8
+ types: [labeled]
9
+
10
+ permissions:
11
+ issues: write
12
+ pull-requests: write
13
+ contents: write
14
+
15
+ jobs:
16
+ handle-phase-change:
17
+ runs-on: ubuntu-latest
18
+ if: |
19
+ contains(github.event.label.name, 'phase:') ||
20
+ (github.event.action == 'unlabeled' && contains(github.event.label.name, 'phase:'))
21
+
22
+ steps:
23
+ - name: Checkout repository
24
+ uses: actions/checkout@v4
25
+ with:
26
+ token: ${{ secrets.GITHUB_TOKEN }}
27
+ fetch-depth: 0
28
+
29
+ - name: Setup Git
30
+ run: |
31
+ git config --global user.name "github-actions[bot]"
32
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
33
+
34
+ - name: Auth GitHub CLI
35
+ run: echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token
36
+
37
+ - name: Extract issue details
38
+ id: issue-details
39
+ run: |
40
+ ISSUE_NUMBER="${{ github.event.issue.number }}"
41
+ ISSUE_TITLE="${{ github.event.issue.title }}"
42
+ BRANCH_NAME="feature/${ISSUE_NUMBER}-$(echo "$ISSUE_TITLE" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g')"
43
+
44
+ echo "issue_number=$ISSUE_NUMBER" >> $GITHUB_OUTPUT
45
+ echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
46
+ echo "issue_title=$ISSUE_TITLE" >> $GITHUB_OUTPUT
47
+
48
+ - name: Determine current phase
49
+ id: current-phase
50
+ run: |
51
+ LABELS='${{ toJson(github.event.issue.labels) }}'
52
+ CURRENT_PHASE=""
53
+
54
+ # Extract current phase from labels
55
+ for label in $(echo "$LABELS" | jq -r '.[].name'); do
56
+ if [[ $label == phase:* ]]; then
57
+ CURRENT_PHASE=$label
58
+ break
59
+ fi
60
+ done
61
+
62
+ echo "current_phase=$CURRENT_PHASE" >> $GITHUB_OUTPUT
63
+ echo "Current phase: $CURRENT_PHASE"
64
+
65
+ - name: Verify branch exists (created by prep-issue.sh)
66
+ run: |
67
+ BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
68
+
69
+ # Check if branch exists remotely
70
+ if git ls-remote --exit-code --heads origin "$BRANCH_NAME" >/dev/null 2>&1; then
71
+ echo "✓ Branch $BRANCH_NAME exists remotely"
72
+ git fetch origin "$BRANCH_NAME"
73
+ else
74
+ echo "⚠️ Branch $BRANCH_NAME does not exist remotely"
75
+ echo " This should have been created by prep-issue.sh"
76
+ echo " Please run prep-issue.sh before invoking agent workflows"
77
+ exit 1
78
+ fi
79
+
80
+ - name: Check if PR already exists
81
+ id: pr-check
82
+ run: |
83
+ BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
84
+ EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number' 2>/dev/null || echo "")
85
+ echo "existing_pr=$EXISTING_PR" >> $GITHUB_OUTPUT
86
+ if [ -n "$EXISTING_PR" ]; then
87
+ echo "✓ PR #$EXISTING_PR already exists"
88
+ else
89
+ echo "ℹ️ No PR exists yet, will create one for phase: ${{ steps.current-phase.outputs.current_phase }}"
90
+ fi
91
+
92
+ - name: phase:spec → create/update PR for Specification phase
93
+ if: steps.current-phase.outputs.current_phase == 'phase:spec'
94
+ shell: bash
95
+ env:
96
+ ISSUE: ${{ github.event.issue.number }}
97
+ run: |
98
+ ISSUE_NUMBER="${{ steps.issue-details.outputs.issue_number }}"
99
+ ISSUE_TITLE="${{ steps.issue-details.outputs.issue_title }}"
100
+ BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
101
+
102
+ # Create or update PR for Specification phase
103
+ PR_TITLE="[Specification] Feature Spec for Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
104
+ PR_BODY="## Feature Specification for Issue #$ISSUE_NUMBER
105
+
106
+ This PR contains the feature specification for: $ISSUE_TITLE
107
+
108
+ **Phase:** Specification
109
+ **Issue:** #$ISSUE_NUMBER
110
+ **Branch:** \`$BRANCH_NAME\`
111
+
112
+ ### Specification Document
113
+ - 📋 [Feature Specification]($SPEC_FILE)
114
+
115
+ **Note:** This is a Specification PR. Design and Implementation will follow after specification approval.
116
+
117
+ "
118
+
119
+ EXISTING_PR="${{ steps.pr-check.outputs.existing_pr }}"
120
+
121
+ if [ -n "$EXISTING_PR" ]; then
122
+ echo "Updating existing PR #$EXISTING_PR for Specification phase"
123
+ gh pr edit "$EXISTING_PR" --title "$PR_TITLE" --body "$PR_BODY"
124
+ gh pr edit "$EXISTING_PR" --add-label "phase:spec" --remove-label "phase:design" --remove-label "phase:tests" --remove-label "phase:impl"
125
+ else
126
+ echo "Creating new PR for Specification phase"
127
+ gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base master --head "$BRANCH_NAME" --draft
128
+ gh pr edit --add-label "phase:spec"
129
+ fi
130
+
131
+ - name: phase:design → create/update PR for Design phase
132
+ if: steps.current-phase.outputs.current_phase == 'phase:design'
133
+ shell: bash
134
+ env:
135
+ ISSUE: ${{ github.event.issue.number }}
136
+ run: |
137
+ ISSUE_NUMBER="${{ steps.issue-details.outputs.issue_number }}"
138
+ ISSUE_TITLE="${{ steps.issue-details.outputs.issue_title }}"
139
+ BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
140
+
141
+ # Create or update PR for Design phase
142
+ PR_TITLE="[Design] RFC for Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
143
+ PR_BODY="## Design RFC for Issue #$ISSUE_NUMBER
144
+
145
+ This PR contains the design RFC for: $ISSUE_TITLE
146
+
147
+ **Phase:** Design
148
+ **Issue:** #$ISSUE_NUMBER
149
+ **Branch:** \`$BRANCH_NAME\`
150
+
151
+ ### RFC Document
152
+ - 📋 [RFC Document]($RFC_FILE)
153
+
154
+ **Note:** This is a Design PR. Implementation will follow in a separate PR after design approval.
155
+
156
+ "
157
+
158
+ EXISTING_PR="${{ steps.pr-check.outputs.existing_pr }}"
159
+
160
+ if [ -n "$EXISTING_PR" ]; then
161
+ echo "Updating existing PR #$EXISTING_PR for Design phase"
162
+ gh pr edit "$EXISTING_PR" --title "$PR_TITLE" --body "$PR_BODY"
163
+ gh pr edit "$EXISTING_PR" --add-label "phase:design" --remove-label "phase:spec" --remove-label "phase:tests" --remove-label "phase:impl"
164
+ else
165
+ echo "Creating new PR for Design phase"
166
+ gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base master --head "$BRANCH_NAME" --draft
167
+ gh pr edit --add-label "phase:design"
168
+ fi
169
+
170
+ - name: phase:tests → create/update PR for Test phase
171
+ if: steps.current-phase.outputs.current_phase == 'phase:tests'
172
+ run: |
173
+ ISSUE_NUMBER="${{ steps.issue-details.outputs.issue_number }}"
174
+ ISSUE_TITLE="${{ steps.issue-details.outputs.issue_title }}"
175
+ BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
176
+
177
+ # Create or update PR for Test phase
178
+ PR_TITLE="[Testing] Test Cases for Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
179
+ PR_BODY="## Test cases for Issue #$ISSUE_NUMBER
180
+
181
+ This PR contains the test cases for: $ISSUE_TITLE
182
+
183
+ **Phase:** Tests
184
+ **Issue:** #$ISSUE_NUMBER
185
+ **Branch:** \`$BRANCH_NAME\`
186
+
187
+ ### Test Cases
188
+
189
+
190
+ **Note:** This is a Test PR. Implementation will follow after test approval.
191
+
192
+ "
193
+
194
+ EXISTING_PR="${{ steps.pr-check.outputs.existing_pr }}"
195
+
196
+ if [ -n "$EXISTING_PR" ]; then
197
+ echo "Updating existing PR #$EXISTING_PR for Test phase"
198
+ gh pr edit "$EXISTING_PR" --title "$PR_TITLE" --body "$PR_BODY"
199
+ gh pr edit "$EXISTING_PR" --add-label "phase:tests" --remove-label "phase:spec" --remove-label "phase:design" --remove-label "phase:impl"
200
+ else
201
+ echo "Creating new PR for Test phase"
202
+ gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base master --head "$BRANCH_NAME" --draft
203
+ gh pr edit --add-label "phase:tests"
204
+ fi
205
+
206
+ - name: phase:impl → create/update PR for Implementation phase
207
+ if: steps.current-phase.outputs.current_phase == 'phase:impl'
208
+ run: |
209
+ ISSUE_NUMBER="${{ steps.issue-details.outputs.issue_number }}"
210
+ ISSUE_TITLE="${{ steps.issue-details.outputs.issue_title }}"
211
+ BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
212
+
213
+ # Create or update PR for Implementation phase
214
+ PR_TITLE="[Implementation] Fixes for Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
215
+ PR_BODY="## Fixes for Issue #$ISSUE_NUMBER
216
+
217
+ This PR contains the fixes for: $ISSUE_TITLE
218
+
219
+ **Phase:** Implementation
220
+ **Issue:** #$ISSUE_NUMBER
221
+ **Branch:** \`$BRANCH_NAME\`
222
+
223
+ ### Fixes
224
+
225
+
226
+ Closes #$ISSUE_NUMBER
227
+
228
+ "
229
+
230
+ EXISTING_PR="${{ steps.pr-check.outputs.existing_pr }}"
231
+
232
+ if [ -n "$EXISTING_PR" ]; then
233
+ echo "Updating existing PR #$EXISTING_PR for Implementation phase"
234
+ gh pr edit "$EXISTING_PR" --title "$PR_TITLE" --body "$PR_BODY"
235
+ gh pr edit "$EXISTING_PR" --add-label "phase:impl" --remove-label "phase:spec" --remove-label "phase:design" --remove-label "phase:tests"
236
+ else
237
+ echo "Creating new PR for Implementation phase"
238
+ gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base master --head "$BRANCH_NAME" --draft
239
+ gh pr edit --add-label "phase:impl"
240
+ fi
241
+
242
+ - name: Normalize ISSUE and PR status to WIP (authoritative)
243
+ run: |
244
+ gh issue edit ${{ github.event.issue.number }} --add-label "status:wip" --remove-label "status:needs-review" --remove-label "status:complete" || true
245
+
246
+ # Use the PR number from the check step
247
+ EXISTING_PR="${{ steps.pr-check.outputs.existing_pr }}"
248
+
249
+ if [ -n "$EXISTING_PR" ]; then
250
+ gh pr edit "$EXISTING_PR" --add-label "status:wip" --remove-label "status:needs-review" --remove-label "status:complete" || true
251
+ fi
@@ -0,0 +1,68 @@
1
+ name: Status Change → Flip PR Draft/Ready
2
+
3
+ on:
4
+ issues:
5
+ types: [labeled]
6
+
7
+ permissions:
8
+ pull-requests: write
9
+ issues: read
10
+ contents: write
11
+
12
+ # Serialize per ISSUE; last status wins
13
+ concurrency:
14
+ group: status-change-${{ github.event.issue.number }}
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ status-change:
19
+ if: startsWith(github.event.label.name, 'status:')
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - name: Checkout repository
23
+ uses: actions/checkout@v4
24
+ with:
25
+ token: ${{ secrets.GITHUB_TOKEN }}
26
+ fetch-depth: 0
27
+
28
+ - name: Setup Git
29
+ run: |
30
+ git config --global user.name "github-actions[bot]"
31
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
32
+
33
+ - name: Auth GitHub CLI
34
+ run: echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token
35
+
36
+ - name: Derive branch + find PR
37
+ id: pr
38
+ shell: bash
39
+ env:
40
+ ISSUE_NUMBER: ${{ github.event.issue.number }}
41
+ ISSUE_TITLE: ${{ github.event.issue.title }}
42
+ run: |
43
+ set -euo pipefail
44
+ slug=$(echo "$ISSUE_TITLE" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g;s/^-+|-+$//g')
45
+ BR="feature/${ISSUE_NUMBER}-${slug}"
46
+ PR=$(gh pr list --state open --head "$BR" --json number --jq '.[0].number')
47
+ echo "pr=$PR" >> $GITHUB_OUTPUT
48
+ echo "label=${{ github.event.label.name }}" >> $GITHUB_OUTPUT
49
+
50
+ - name: Flip PR state (Draft/Ready) based on label
51
+ if: steps.pr.outputs.pr != ''
52
+ shell: bash
53
+ env:
54
+ PR: ${{ steps.pr.outputs.pr }}
55
+ LABEL: ${{ steps.pr.outputs.label }}
56
+ run: |
57
+ set -euo pipefail
58
+ case "$LABEL" in
59
+ status:needs-review)
60
+ gh pr ready "$PR"
61
+ gh pr edit "$PR" --add-label "status:needs-review" --remove-label "status:wip" --remove-label "status:complete" || true
62
+ ;;
63
+ status:wip)
64
+ gh pr edit "$PR" --add-label "status:wip" --remove-label "status:needs-review" --remove-label "status:complete" || true
65
+ ;;
66
+ *)
67
+ echo "No action for label: $LABEL" ;;
68
+ esac
@@ -0,0 +1,66 @@
1
+ name: Sync Issue on PR Review
2
+ on:
3
+ pull_request_review:
4
+ types: [submitted]
5
+
6
+ permissions:
7
+ pull-requests: write
8
+ issues: write
9
+
10
+ concurrency:
11
+ group: review-sync-${{ github.event.pull_request.number }}
12
+ cancel-in-progress: true
13
+
14
+ jobs:
15
+ sync-on-review:
16
+ runs-on: ubuntu-latest
17
+ # no job-level `if` — we branch inside the script
18
+ env:
19
+ GH_TOKEN: ${{ secrets.PR_AUTOMATION_TOKEN || secrets.GITHUB_TOKEN }}
20
+ REPO: ${{ github.repository }}
21
+ steps:
22
+ - name: Derive review state, issue number, and branch
23
+ id: vars
24
+ shell: bash
25
+ run: |
26
+ set -euo pipefail
27
+ STATE="${{ github.event.review.state }}"
28
+ BR="${{ github.event.pull_request.head.ref }}" # e.g., feature/26-slug
29
+ ISSUE="$(sed -nE 's#^feature/([0-9]+)-.*#\1#p' <<< "$BR" || true)"
30
+ echo "state=$STATE" >> $GITHUB_OUTPUT
31
+ echo "issue=$ISSUE" >> $GITHUB_OUTPUT
32
+ echo "branch=$BR" >> $GITHUB_OUTPUT
33
+ echo "Detected review state: $STATE; branch: $BR; issue: $ISSUE"
34
+
35
+ - name: Handle review states
36
+ if: steps.vars.outputs.issue != ''
37
+ shell: bash
38
+ env:
39
+ STATE: ${{ steps.vars.outputs.state }}
40
+ ISSUE: ${{ steps.vars.outputs.issue }}
41
+ PRNUM: ${{ github.event.pull_request.number }}
42
+ REPO: ${{ env.REPO }}
43
+ run: |
44
+ set -euo pipefail
45
+ case "$STATE" in
46
+ changes_requested)
47
+ # Flip to WIP
48
+ gh issue edit "$ISSUE" --repo "$REPO" \
49
+ --add-label "status:wip" --remove-label "status:needs-review" --remove-label "status:complete" || true
50
+ gh pr edit "$PRNUM" --repo "$REPO" \
51
+ --add-label "status:wip" --remove-label "status:needs-review" --remove-label "status:complete" || true
52
+ ;;
53
+ approved)
54
+ # Flip to Complete
55
+ gh issue edit "$ISSUE" --repo "$REPO" \
56
+ --add-label "status:complete" --remove-label "status:wip" --remove-label "status:needs-review" || true
57
+ gh pr edit "$PRNUM" --repo "$REPO" --add-label "status:complete" --remove-label "status:wip" --remove-label "status:needs-review" || true
58
+ ;;
59
+ commented)
60
+ # No-op; comments don't change state
61
+ echo "Review was 'commented' — no state change."
62
+ ;;
63
+ *)
64
+ echo "Unknown review state: $STATE"
65
+ ;;
66
+ esac
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fraim-framework",
3
- "version": "2.0.4",
3
+ "version": "2.0.7",
4
4
  "description": "FRAIM v2: Framework for Rigor-based AI Management - Transform from solo developer to AI manager orchestrating production-ready code with enterprise-grade discipline",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -51,6 +51,7 @@
51
51
  },
52
52
  "files": [
53
53
  ".ai-agents/",
54
+ ".github/",
54
55
  "examples/",
55
56
  "bin/",
56
57
  "*.js",