fraim-framework 1.0.8 → 1.0.10

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.
@@ -0,0 +1,218 @@
1
+ name: Phase Change Handler
2
+
3
+ on:
4
+ issues:
5
+ types: [labeled]
6
+
7
+ permissions:
8
+ issues: write
9
+ pull-requests: write
10
+ contents: write
11
+
12
+ jobs:
13
+ handle-phase-change:
14
+ runs-on: ubuntu-latest
15
+ if: |
16
+ contains(github.event.label.name, 'phase:') ||
17
+ (github.event.action == 'unlabeled' && contains(github.event.label.name, 'phase:'))
18
+
19
+ steps:
20
+ - name: Checkout repository
21
+ uses: actions/checkout@v4
22
+ with:
23
+ token: ${{ secrets.GITHUB_TOKEN }}
24
+ fetch-depth: 0
25
+
26
+ - name: Setup Git
27
+ run: |
28
+ git config --global user.name "github-actions[bot]"
29
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
30
+
31
+ - name: Auth GitHub CLI
32
+ run: echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token
33
+
34
+ - name: Extract issue details
35
+ id: issue-details
36
+ run: |
37
+ ISSUE_NUMBER="${{ github.event.issue.number }}"
38
+ ISSUE_TITLE="${{ github.event.issue.title }}"
39
+ BRANCH_NAME="feature/${ISSUE_NUMBER}-$(echo "$ISSUE_TITLE" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g')"
40
+
41
+ echo "issue_number=$ISSUE_NUMBER" >> $GITHUB_OUTPUT
42
+ echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
43
+ echo "issue_title=$ISSUE_TITLE" >> $GITHUB_OUTPUT
44
+
45
+ - name: Determine current phase
46
+ id: current-phase
47
+ run: |
48
+ LABELS='${{ toJson(github.event.issue.labels) }}'
49
+ CURRENT_PHASE=""
50
+
51
+ # Extract current phase from labels
52
+ for label in $(echo "$LABELS" | jq -r '.[].name'); do
53
+ if [[ $label == phase:* ]]; then
54
+ CURRENT_PHASE=$label
55
+ break
56
+ fi
57
+ done
58
+
59
+ echo "current_phase=$CURRENT_PHASE" >> $GITHUB_OUTPUT
60
+ echo "Current phase: $CURRENT_PHASE"
61
+
62
+ - name: Ensure branch exists and sync
63
+ run: |
64
+ BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
65
+ BASE="master"
66
+
67
+ git fetch origin "$BASE"
68
+
69
+ if git ls-remote --exit-code --heads origin "$BRANCH_NAME" >/dev/null 2>&1; then
70
+ echo "Branch $BRANCH_NAME exists, syncing..."
71
+ git fetch origin "$BRANCH_NAME"
72
+ git switch "$BRANCH_NAME"
73
+ git pull --rebase origin "$BRANCH_NAME"
74
+ else
75
+ echo "Branch $BRANCH_NAME does not exist, creating from $BASE..."
76
+ git switch -c "$BRANCH_NAME" "origin/$BASE"
77
+ git push -u origin "$BRANCH_NAME"
78
+ fi
79
+
80
+ # Design: add EMPTY commit to guarantee a diff
81
+ - name: phase:design → ensure empty commit (commit if missing)
82
+ if: steps.current-phase.outputs.current_phase == 'phase:design'
83
+ shell: bash
84
+ env:
85
+ ISSUE: ${{ github.event.issue.number }}
86
+ run: |
87
+ ISSUE_NUMBER="${{ steps.issue-details.outputs.issue_number }}"
88
+ ISSUE_TITLE="${{ steps.issue-details.outputs.issue_title }}"
89
+ BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
90
+
91
+ # Create empty commit to guarantee branch has commits
92
+ git commit --allow-empty -m "Design phase initiated for Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
93
+ git push origin "$BRANCH_NAME"
94
+
95
+ # Create or update Design PR
96
+ PR_TITLE="[Design] RFC for Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
97
+ PR_BODY="## Design RFC for Issue #$ISSUE_NUMBER
98
+
99
+ This PR contains the design RFC for: $ISSUE_TITLE
100
+
101
+ **Phase:** Design
102
+ **Issue:** #$ISSUE_NUMBER
103
+ **Branch:** \`$BRANCH_NAME\`
104
+
105
+ ### RFC Document
106
+ - 📋 [RFC Document]($RFC_FILE)
107
+
108
+ **Note:** This is a Design PR. Implementation will follow in a separate PR after design approval.
109
+
110
+ "
111
+
112
+ # Check if PR already exists
113
+ EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number' 2>/dev/null || echo "")
114
+
115
+ if [ -n "$EXISTING_PR" ]; then
116
+ echo "Updating existing PR #$EXISTING_PR"
117
+ gh pr edit "$EXISTING_PR" --title "$PR_TITLE" --body "$PR_BODY"
118
+ gh pr edit "$EXISTING_PR" --add-label "phase:design" --remove-label "phase:tests" --remove-label "phase:impl"
119
+ else
120
+ echo "Creating new Design PR"
121
+ gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base master --head "$BRANCH_NAME" --draft
122
+ # Add labels to the new PR
123
+ sleep 2 # Brief delay to ensure PR is created
124
+ NEW_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number')
125
+ gh pr edit "$NEW_PR" --add-label "phase:design" --remove-label "phase:tests" --remove-label "phase:impl"
126
+ fi
127
+
128
+ - name: Handle test phase
129
+ if: steps.current-phase.outputs.current_phase == 'phase:tests'
130
+ run: |
131
+ ISSUE_NUMBER="${{ steps.issue-details.outputs.issue_number }}"
132
+ ISSUE_TITLE="${{ steps.issue-details.outputs.issue_title }}"
133
+ BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
134
+
135
+ # Create or update Test Implementation PR
136
+ PR_TITLE="[Testing] Test Cases for Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
137
+ PR_BODY="## Test cases for Issue #$ISSUE_NUMBER
138
+
139
+ This PR contains the test cases for: $ISSUE_TITLE
140
+
141
+ **Phase:** Tests
142
+ **Issue:** #$ISSUE_NUMBER
143
+ **Branch:** \`$BRANCH_NAME\`
144
+
145
+ ### Test Cases
146
+
147
+
148
+ **Note:** This is a Test PR. Implementation will follow after test approval.
149
+
150
+ "
151
+
152
+ # Check if PR already exists
153
+ EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number' 2>/dev/null || echo "")
154
+
155
+ if [ -n "$EXISTING_PR" ]; then
156
+ echo "Updating existing PR #$EXISTING_PR"
157
+ gh pr edit "$EXISTING_PR" --title "$PR_TITLE" --body "$PR_BODY"
158
+ gh pr edit "$EXISTING_PR" --add-label "phase:tests" --remove-label "phase:design" --remove-label "phase:impl"
159
+ else
160
+ echo "Creating new Test Plan PR"
161
+ gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base master --head "$BRANCH_NAME" --draft
162
+ # Add labels to the new PR
163
+ sleep 2 # Brief delay to ensure PR is created
164
+ NEW_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number')
165
+ gh pr edit "$NEW_PR" --add-label "phase:tests" --remove-label "phase:design" --remove-label "phase:impl"
166
+ fi
167
+
168
+ - name: Handle implementation phase
169
+ if: steps.current-phase.outputs.current_phase == 'phase:impl'
170
+ run: |
171
+ ISSUE_NUMBER="${{ steps.issue-details.outputs.issue_number }}"
172
+ ISSUE_TITLE="${{ steps.issue-details.outputs.issue_title }}"
173
+ BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
174
+
175
+ # Create or update Implementation PR
176
+ PR_TITLE="[Implementation] Fixes for Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
177
+ PR_BODY="## Fixes for Issue #$ISSUE_NUMBER
178
+
179
+ This PR contains the fixes for: $ISSUE_TITLE
180
+
181
+ **Phase:** Implementation
182
+ **Issue:** #$ISSUE_NUMBER
183
+ **Branch:** \`$BRANCH_NAME\`
184
+
185
+ ### Fixes
186
+
187
+
188
+ Closes #$ISSUE_NUMBER
189
+
190
+ "
191
+
192
+ # Check if PR already exists
193
+ EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number' 2>/dev/null || echo "")
194
+
195
+ if [ -n "$EXISTING_PR" ]; then
196
+ echo "Updating existing PR #$EXISTING_PR"
197
+ gh pr edit "$EXISTING_PR" --title "$PR_TITLE" --body "$PR_BODY"
198
+ gh pr edit "$EXISTING_PR" --add-label "phase:impl" --remove-label "phase:design" --remove-label "phase:tests"
199
+ else
200
+ echo "Creating new Implementation PR"
201
+ gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base master --head "$BRANCH_NAME" --draft
202
+ # Add labels to the new PR
203
+ sleep 2 # Brief delay to ensure PR is created
204
+ NEW_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number')
205
+ gh pr edit "$NEW_PR" --add-label "phase:impl" --remove-label "phase:design" --remove-label "phase:tests"
206
+ fi
207
+
208
+ - name: Normalize ISSUE and PR status to WIP (authoritative)
209
+ run: |
210
+ gh issue edit ${{ github.event.issue.number }} --add-label "status:wip" --remove-label "status:needs-review" --remove-label "status:complete" || true
211
+
212
+ # Get the PR number for the current branch and normalize its status
213
+ BRANCH_NAME="${{ steps.issue-details.outputs.branch_name }}"
214
+ PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number' 2>/dev/null || echo "")
215
+
216
+ if [ -n "$PR_NUMBER" ]; then
217
+ gh pr edit "$PR_NUMBER" --add-label "status:wip" --remove-label "status:needs-review" --remove-label "status:complete" || true
218
+ 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": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "FRAIM: Framework for Rigor-based AI Management - Where humans become AI managers through rigorous methodology",
5
5
  "main": "index.js",
6
6
  "bin": {
package/setup.js CHANGED
@@ -167,6 +167,67 @@ Owner: <agent>
167
167
  logSuccess('Project structure created');
168
168
  }
169
169
 
170
+ async function setupGitHubCLI() {
171
+ logStep('GitHub CLI Setup');
172
+ logInfo('To create GitHub labels automatically, you need GitHub CLI installed and authenticated.');
173
+
174
+ // Check if gh is installed
175
+ try {
176
+ execSync('gh --version', { stdio: 'pipe' });
177
+ logSuccess('GitHub CLI is already installed');
178
+ } catch (error) {
179
+ logWarning('GitHub CLI is not installed');
180
+ logInfo('Installing GitHub CLI...');
181
+ logInfo('📥 Download from: https://cli.github.com/');
182
+ logInfo('💻 Or use package manager:');
183
+ logInfo(' Windows: winget install GitHub.cli');
184
+ logInfo(' macOS: brew install gh');
185
+ logInfo(' Ubuntu/Debian: sudo apt install gh');
186
+ logInfo(' CentOS/RHEL: sudo yum install gh');
187
+
188
+ const waitForInstall = await askQuestion('Press Enter after installing GitHub CLI, or type "skip" to continue without it');
189
+ if (waitForInstall === 'skip') {
190
+ return false;
191
+ }
192
+
193
+ // Check again
194
+ try {
195
+ execSync('gh --version', { stdio: 'pipe' });
196
+ logSuccess('GitHub CLI is now available');
197
+ } catch (error) {
198
+ logWarning('GitHub CLI still not available, continuing without it');
199
+ return false;
200
+ }
201
+ }
202
+
203
+ // Check if authenticated
204
+ try {
205
+ execSync('gh auth status', { stdio: 'pipe' });
206
+ logSuccess('GitHub CLI is already authenticated');
207
+ return true;
208
+ } catch (error) {
209
+ logWarning('GitHub CLI is not authenticated');
210
+ logInfo('You need to authenticate with GitHub to create labels automatically.');
211
+ logInfo('🔐 Run: gh auth login');
212
+ logInfo(' This will open a browser for OAuth authentication');
213
+
214
+ const waitForAuth = await askQuestion('Press Enter after authenticating, or type "skip" to continue without authentication');
215
+ if (waitForAuth === 'skip') {
216
+ return false;
217
+ }
218
+
219
+ // Check authentication again
220
+ try {
221
+ execSync('gh auth status', { stdio: 'pipe' });
222
+ logSuccess('GitHub CLI is now authenticated');
223
+ return true;
224
+ } catch (error) {
225
+ logWarning('GitHub CLI authentication failed, continuing without it');
226
+ return false;
227
+ }
228
+ }
229
+ }
230
+
170
231
  function createGitHubLabels() {
171
232
  const labels = [
172
233
  { name: 'phase:design', color: '0e8a16', description: 'Design phase - RFC creation and review' },
@@ -175,7 +236,6 @@ function createGitHubLabels() {
175
236
  { name: 'status:wip', color: 'fbca04', description: 'Work in progress' },
176
237
  { name: 'status:needs-review', color: 'd93f0b', description: 'Ready for review' },
177
238
  { name: 'status:complete', color: '0e8a16', description: 'Completed and approved' },
178
- { name: 'status:approved', color: '0e8a16', description: 'Approved and ready to merge' },
179
239
  { name: 'status:changes-requested', color: 'd93f0b', description: 'Changes requested in review' },
180
240
  { name: 'ai-agent:cursor', color: '5319e7', description: 'Assigned to Cursor AI agent' },
181
241
  { name: 'ai-agent:claude', color: 'c2e0c6', description: 'Assigned to Claude AI agent' },
@@ -209,7 +269,6 @@ function createLabelsConfigFile() {
209
269
  { name: 'status:wip', color: 'fbca04', description: 'Work in progress' },
210
270
  { name: 'status:needs-review', color: 'd93f0b', description: 'Ready for review' },
211
271
  { name: 'status:complete', color: '0e8a16', description: 'Completed and approved' },
212
- { name: 'status:approved', color: '0e8a16', description: 'Approved and ready to merge' },
213
272
  { name: 'status:changes-requested', color: 'd93f0b', description: 'Changes requested in review' },
214
273
  { name: 'ai-agent:cursor', color: '5319e7', description: 'Assigned to Cursor AI agent' },
215
274
  { name: 'ai-agent:claude', color: 'c2e0c6', description: 'Assigned to Claude AI agent' },
@@ -226,98 +285,17 @@ function createLabelsConfigFile() {
226
285
  }
227
286
 
228
287
  function createGitHubWorkflows() {
229
- // Phase change workflow
230
- const phaseChangeWorkflow = `name: Phase Change Automation
231
-
232
- on:
233
- issues:
234
- types: [labeled, unlabeled]
235
-
236
- jobs:
237
- phase-change:
238
- runs-on: ubuntu-latest
239
- if: contains(github.event.issue.labels.*.name, 'phase:') || contains(github.event.label.name, 'phase:')
240
- steps:
241
- - name: Checkout
242
- uses: actions/checkout@v4
243
-
244
- - name: Phase Change Handler
245
- run: |
246
- echo "Phase change detected for issue #\${{ github.event.issue.number }}"
247
- echo "New phase: \${{ github.event.label.name || 'phase removed' }}"
248
-
249
- - name: Update Issue Status
250
- if: contains(github.event.label.name, 'phase:')
251
- run: |
252
- gh issue edit \${{ github.event.issue.number }} --add-label "status:wip"
253
- echo "Status updated to WIP for new phase"
254
- `;
255
-
256
- // Status change workflow
257
- const statusChangeWorkflow = `name: Status Change Automation
258
-
259
- on:
260
- issues:
261
- types: [labeled, unlabeled]
262
-
263
- jobs:
264
- status-change:
265
- runs-on: ubuntu-latest
266
- if: contains(github.event.issue.labels.*.name, 'status:') || contains(github.event.label.name, 'status:')
267
- steps:
268
- - name: Checkout
269
- uses: actions/checkout@v4
270
-
271
- - name: Status Change Handler
272
- run: |
273
- echo "Status change detected for issue #\${{ github.event.issue.number }}"
274
- echo "New status: \${{ github.event.label.name || 'status removed' }}"
275
-
276
- - name: Notify Team
277
- if: contains(github.event.label.name, 'status:needs-review')
278
- run: |
279
- echo "Issue ready for review - notifying team"
280
- `;
281
-
282
- // Sync on PR review workflow
283
- const syncOnPRReviewWorkflow = `name: Sync on PR Review
284
-
285
- on:
286
- pull_request_review:
287
- types: [submitted, edited, dismissed]
288
-
289
- jobs:
290
- sync-review:
291
- runs-on: ubuntu-latest
292
- steps:
293
- - name: Checkout
294
- uses: actions/checkout@v4
295
-
296
- - name: Sync Review Status
297
- env:
298
- GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
299
- run: |
300
- PR_NUMBER="\${{ github.event.pull_request.number }}"
301
- REVIEW_STATE="\${{ github.event.review.state }}"
302
-
303
- echo "PR #\$PR_NUMBER review state: \$REVIEW_STATE"
304
-
305
- if [ "\$REVIEW_STATE" = "approved" ]; then
306
- echo "PR approved - updating status"
307
- gh pr edit \$PR_NUMBER --add-label "status:approved"
308
- elif [ "\$REVIEW_STATE" = "changes_requested" ]; then
309
- echo "Changes requested - updating status"
310
- gh pr edit \$PR_NUMBER --add-label "status:changes-requested"
311
- fi
312
-
313
- echo "Review sync complete"
314
- `;
315
-
316
- writeFile('.github/workflows/phase-change.yml', phaseChangeWorkflow);
317
- writeFile('.github/workflows/status-change.yml', statusChangeWorkflow);
318
- writeFile('.github/workflows/sync-on-pr-review.yml', syncOnPRReviewWorkflow);
288
+ // Get the directory where this script is located (FRAIM package directory)
289
+ const fraimDir = __dirname;
319
290
 
320
- logSuccess('GitHub workflows created');
291
+ // Copy actual workflow files from FRAIM/github folder
292
+ const workflowsSrc = path.join(fraimDir, 'github');
293
+ if (fs.existsSync(workflowsSrc)) {
294
+ copyDirectory(workflowsSrc, '.github/workflows');
295
+ logSuccess('GitHub workflows copied from FRAIM/github folder');
296
+ } else {
297
+ logWarning(`github folder not found at ${workflowsSrc}, skipping workflow creation`);
298
+ }
321
299
  }
322
300
 
323
301
  function createAgentFolders() {
@@ -361,19 +339,6 @@ async function runWizard() {
361
339
  // Check prerequisites
362
340
  logStep('Step 1: Checking Prerequisites');
363
341
 
364
- // Check if gh CLI is available
365
- let ghAvailable = false;
366
- try {
367
- execSync('gh --version', { stdio: 'pipe' });
368
- logSuccess('GitHub CLI (gh) is available');
369
- ghAvailable = true;
370
- } catch (error) {
371
- logWarning('GitHub CLI (gh) is not installed or not available');
372
- logInfo('You can still set up FRAIM, but GitHub labels will need to be created manually');
373
- logInfo('Install GitHub CLI: https://cli.github.com/');
374
- ghAvailable = false;
375
- }
376
-
377
342
  // Check if we're in a git repository
378
343
  try {
379
344
  execSync('git rev-parse --git-dir', { stdio: 'pipe' });
@@ -417,17 +382,18 @@ async function runWizard() {
417
382
 
418
383
  // Step 5: GitHub Labels
419
384
  logStep('Step 5: GitHub Labels');
420
- if (ghAvailable) {
421
- const setupLabels = await askQuestion('Would you like to create GitHub labels for FRAIM?', 'y');
422
-
423
- if (setupLabels === 'y' || setupLabels === 'yes') {
385
+ const setupLabels = await askQuestion('Would you like to create GitHub labels for FRAIM?', 'y');
386
+
387
+ if (setupLabels === 'y' || setupLabels === 'yes') {
388
+ const ghAvailable = await setupGitHubCLI();
389
+ if (ghAvailable) {
424
390
  createGitHubLabels();
425
391
  } else {
426
- logInfo('Skipping GitHub label setup');
392
+ logInfo('GitHub CLI not available - creating labels configuration file instead');
393
+ createLabelsConfigFile();
427
394
  }
428
395
  } else {
429
- logInfo('GitHub CLI not available - creating labels configuration file instead');
430
- createLabelsConfigFile();
396
+ logInfo('Skipping GitHub label setup');
431
397
  }
432
398
 
433
399
  // Step 6: Summary
@@ -436,13 +402,7 @@ async function runWizard() {
436
402
  logSuccess('FRAIM has been successfully set up in your repository!');
437
403
  logInfo('Next steps:');
438
404
  logInfo('1. Commit and push these files to GitHub');
439
-
440
- if (ghAvailable) {
441
- logInfo('2. GitHub labels have been created automatically');
442
- } else {
443
- logInfo('2. Import GitHub labels from .github/labels.json using the web interface');
444
- }
445
-
405
+ logInfo('2. Import GitHub labels from .github/labels.json using the web interface');
446
406
  logInfo('3. Create your first issue with phase labels');
447
407
  logInfo('4. Start coordinating your AI agents!');
448
408
 
@@ -464,14 +424,6 @@ function runSetup() {
464
424
 
465
425
  try {
466
426
  // Check prerequisites
467
- try {
468
- execSync('gh --version', { stdio: 'pipe' });
469
- } catch (error) {
470
- logError('GitHub CLI (gh) is not installed or not available');
471
- logInfo('Please install GitHub CLI: https://cli.github.com/');
472
- process.exit(1);
473
- }
474
-
475
427
  try {
476
428
  execSync('git rev-parse --git-dir', { stdio: 'pipe' });
477
429
  } catch (error) {
@@ -485,13 +437,13 @@ function runSetup() {
485
437
  ensureDirectory('.github/workflows');
486
438
  createAgentFolders();
487
439
  createGitHubWorkflows();
488
- createGitHubLabels();
440
+ createLabelsConfigFile();
489
441
 
490
442
  logHeader('🎉 Setup Complete!');
491
443
  logSuccess('FRAIM has been successfully set up in your repository!');
492
444
  logInfo('Next steps:');
493
445
  logInfo('1. Commit and push these files to GitHub');
494
- logInfo('2. The GitHub labels have been created automatically');
446
+ logInfo('2. Import GitHub labels from .github/labels.json using the web interface');
495
447
  logInfo('3. Create your first issue with phase labels');
496
448
  logInfo('4. Start coordinating your AI agents!');
497
449