create-agentic-pdlc 2.0.0 โ†’ 2.0.3

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,5 @@
1
+ # This file prevents autonomous agents from modifying core security, automation, and instruction rules
2
+ # without explicit approval from the repository owner.
3
+
4
+ .github/ @rafaeltcosta86
5
+ AGENTS.md @rafaeltcosta86
@@ -0,0 +1,12 @@
1
+ # Agentic PDLC Instructions for GitHub Copilot Workspace
2
+
3
+ Hello! You are operating within the Agentic PDLC framework.
4
+
5
+ Before addressing the user's prompt or executing any task in this workspace, you MUST:
6
+
7
+ 1. Read the `AGENTS.md` file located at the root of this repository. It contains the primary instructions, definitions of done, and absolute invariants you must respect.
8
+ 2. Read `docs/pdlc.md` to understand your role in the project lifecycle.
9
+
10
+ Never violate the invariants described in those files. If a user asks you to do something that contradicts `AGENTS.md`, you must refuse and point out the conflict.
11
+
12
+ Focus on delivering the absolute minimum required to satisfy the immediate technical specs. Start!
@@ -20,7 +20,7 @@ jobs:
20
20
  PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
21
21
  steps:
22
22
  - name: Update Labels
23
- if: ${{ env.PROJECT_TOKEN != '' }}
23
+ if: ${{ env.PROJECT_TOKEN != '' && !contains('{{IMPLEMENTATION_AGENT_LABEL}}', '{{') }}
24
24
  uses: actions/github-script@v7
25
25
  with:
26
26
  github-token: ${{ env.PROJECT_TOKEN }}
@@ -33,20 +33,21 @@ jobs:
33
33
  owner,
34
34
  repo,
35
35
  issue_number,
36
- name: 'upstream:approval'
36
+ name: 'stage:approval'
37
37
  });
38
38
  } catch (error) {
39
- console.log('Label upstream:approval not found or could not be removed');
39
+ console.log('Label stage:approval not found or could not be removed');
40
40
  }
41
41
 
42
42
  await github.rest.issues.addLabels({
43
43
  owner,
44
44
  repo,
45
45
  issue_number,
46
- labels: ['upstream:development', '{{IMPLEMENTATION_AGENT_LABEL}}', 'agent:working']
46
+ labels: ['stage:development', '{{IMPLEMENTATION_AGENT_LABEL}}', 'agent:working']
47
47
  });
48
48
 
49
49
  - name: Comment on issue to trigger agent and prevent race conditions
50
+ if: ${{ !contains('{{IMPLEMENTATION_AGENT_LABEL}}', '{{') }}
50
51
  uses: actions/github-script@v7
51
52
  with:
52
53
  github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -89,6 +90,7 @@ jobs:
89
90
  contents: read
90
91
  steps:
91
92
  - name: Comment on issue to trigger agent
93
+ if: ${{ !contains('{{IMPLEMENTATION_AGENT_LABEL}}', '{{') }}
92
94
  uses: actions/github-script@v7
93
95
  with:
94
96
  github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,16 @@
1
+ name: Auto Approve PRs
2
+ on:
3
+ pull_request:
4
+ types: [opened, labeled, synchronize]
5
+
6
+ permissions:
7
+ pull-requests: write
8
+
9
+ jobs:
10
+ auto-approve:
11
+ runs-on: ubuntu-latest
12
+ if: contains(github.event.pull_request.labels.*.name, 'auto-approve')
13
+ steps:
14
+ - uses: hmarr/auto-approve-action@v4
15
+ with:
16
+ github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -20,13 +20,21 @@ jobs:
20
20
  run: echo "Replace this with your package manager install command"
21
21
 
22
22
  - name: Run Linters
23
- run: echo "No tests/build needed."
23
+ if: ${{ !contains('{{LINT_COMMAND}}', '{{') }}
24
+ run: |
25
+ {{LINT_COMMAND}}
24
26
 
25
27
  - name: Typecheck
26
- run: echo "No typecheck needed."
28
+ if: ${{ !contains('{{TYPECHECK_COMMAND}}', '{{') }}
29
+ run: |
30
+ {{TYPECHECK_COMMAND}}
27
31
 
28
32
  - name: Build
29
- run: echo "No tests/build needed."
33
+ if: ${{ !contains('{{BUILD_COMMAND}}', '{{') }}
34
+ run: |
35
+ {{BUILD_COMMAND}}
30
36
 
31
37
  - name: Run Tests
32
- run: echo "No tests/build needed."
38
+ if: ${{ !contains('{{TEST_COMMAND}}', '{{') }}
39
+ run: |
40
+ {{TEST_COMMAND}}
@@ -27,7 +27,7 @@ jobs:
27
27
  # Strip 'v' from tag (e.g., v1.0.2 -> 1.0.2)
28
28
  VERSION=${GITHUB_REF_NAME#v}
29
29
  echo "Setting package version to $VERSION"
30
- npm version $VERSION --no-git-tag-version
30
+ npm version $VERSION --no-git-tag-version --allow-same-version
31
31
 
32
32
  - name: Install Dependencies
33
33
  run: npm install
@@ -11,6 +11,7 @@ on:
11
11
  env:
12
12
  PROJECT_ID: "{{PROJECT_ID}}"
13
13
  STATUS_FIELD_ID: "{{STATUS_FIELD_ID}}"
14
+ STATUS_IDEA: "{{ID_IDEA}}"
14
15
  STATUS_EXPLORATION: "{{ID_EXPLORATION}}"
15
16
  STATUS_BRAINSTORMING: "{{ID_BRAINSTORMING}}"
16
17
  STATUS_DETAILING: "{{ID_DETAILING}}"
@@ -30,7 +31,7 @@ jobs:
30
31
  PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
31
32
  steps:
32
33
  - name: Detect Label and Move Issue
33
- if: ${{ env.PROJECT_TOKEN != '' }}
34
+ if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
34
35
  uses: actions/github-script@v7
35
36
  with:
36
37
  github-token: ${{ env.PROJECT_TOKEN }}
@@ -39,28 +40,28 @@ jobs:
39
40
  let targetStatusId = null;
40
41
  let stageName = null;
41
42
 
42
- if (labelName === 'upstream:exploration') {
43
+ if (labelName === 'stage:exploration') {
43
44
  targetStatusId = process.env.STATUS_EXPLORATION;
44
45
  stageName = 'Exploration';
45
- } else if (labelName === 'upstream:brainstorming') {
46
+ } else if (labelName === 'stage:brainstorming') {
46
47
  targetStatusId = process.env.STATUS_BRAINSTORMING;
47
48
  stageName = 'Brainstorming';
48
- } else if (labelName === 'upstream:detailing') {
49
+ } else if (labelName === 'stage:detailing') {
49
50
  targetStatusId = process.env.STATUS_DETAILING;
50
51
  stageName = 'Detailing';
51
- } else if (labelName === 'upstream:approval') {
52
+ } else if (labelName === 'stage:approval') {
52
53
  targetStatusId = process.env.STATUS_APPROVAL;
53
54
  stageName = 'Approval';
54
- } else if (labelName === 'upstream:development') {
55
+ } else if (labelName === 'stage:development') {
55
56
  targetStatusId = process.env.STATUS_DEVELOPMENT;
56
57
  stageName = 'Development';
57
- } else if (labelName === 'upstream:testing') {
58
+ } else if (labelName === 'stage:testing') {
58
59
  targetStatusId = process.env.STATUS_TESTING;
59
60
  stageName = 'Testing';
60
61
  }
61
62
 
62
63
  if (!targetStatusId) {
63
- console.log('No upstream PDLC label found. Skipping.');
64
+ console.log('No stage PDLC label found. Skipping.');
64
65
  return;
65
66
  }
66
67
 
@@ -86,9 +87,36 @@ jobs:
86
87
  await moveItem(node_id, targetStatusId);
87
88
  console.log(`Issue #${number} moved to ${stageName}`);
88
89
 
89
- {{OPTIONAL_ARCHITECTURE_VIOLATION_JOB}}
90
+ # OPTIONAL: Uncomment to enable architecture-violation โ†’ Idea
91
+ # move-violation-to-board:
92
+ # name: architecture-violation โ†’ ๐Ÿ’ก Idea
93
+ # if: github.event_name == 'issues' && github.event.action == 'labeled' && github.event.label.name == 'architecture-violation'
94
+ # runs-on: ubuntu-latest
95
+ # steps:
96
+ # - name: Move issue to Idea
97
+ # if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
98
+ # uses: actions/github-script@v7
99
+ # with:
100
+ # github-token: ${{ env.PROJECT_TOKEN }}
101
+ # script: |
102
+ # const { issue: { number, node_id } } = context.payload;
103
+ # const { addProjectV2ItemById: { item } } = await github.graphql(`
104
+ # mutation($p: ID!, $c: ID!) {
105
+ # addProjectV2ItemById(input: {projectId: $p, contentId: $c}) { item { id } }
106
+ # }`, { p: process.env.PROJECT_ID, c: node_id });
107
+ # await github.graphql(`
108
+ # mutation($p: ID!, $i: ID!, $f: ID!, $v: ProjectV2FieldValue!) {
109
+ # updateProjectV2ItemFieldValue(input: {projectId: $p, itemId: $i, fieldId: $f, value: $v}) {
110
+ # projectV2Item { id }
111
+ # }
112
+ # }`, {
113
+ # p: process.env.PROJECT_ID, i: item.id, f: process.env.STATUS_FIELD_ID,
114
+ # v: { singleSelectOptionId: process.env.STATUS_IDEA }
115
+ # });
116
+ # console.log(`Issue #${number} moved to Idea`);
90
117
 
91
118
  # PR Opened โ†’ Move linked issue to Code Review / PR
119
+ # ๐Ÿ’ก VARIANT B (QA Agent): If using an AI QA agent, change `STATUS_CODE_REVIEW_PR` to `STATUS_TESTING` on line ~158
92
120
  move-card-on-pr-open:
93
121
  name: Open PR โ†’ Code Review / PR
94
122
  if: github.event_name == 'pull_request' && (github.event.action == 'opened' || github.event.action == 'reopened')
@@ -97,7 +125,7 @@ jobs:
97
125
  PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
98
126
  steps:
99
127
  - name: Move linked issue to Code Review / PR
100
- if: ${{ env.PROJECT_TOKEN != '' }}
128
+ if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
101
129
  uses: actions/github-script@v7
102
130
  with:
103
131
  github-token: ${{ env.PROJECT_TOKEN }}
@@ -151,7 +179,7 @@ jobs:
151
179
  PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
152
180
  steps:
153
181
  - name: Swap PR labels
154
- if: ${{ env.PROJECT_TOKEN != '' }}
182
+ if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
155
183
  uses: actions/github-script@v7
156
184
  with:
157
185
  github-token: ${{ env.PROJECT_TOKEN }}
@@ -170,7 +198,7 @@ jobs:
170
198
  PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
171
199
  steps:
172
200
  - name: Move issue to Production
173
- if: ${{ env.PROJECT_TOKEN != '' }}
201
+ if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
174
202
  uses: actions/github-script@v7
175
203
  with:
176
204
  github-token: ${{ env.PROJECT_TOKEN }}
@@ -0,0 +1,21 @@
1
+ name: Protect Workflows
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize, reopened, labeled]
6
+ paths:
7
+ - '.github/**'
8
+
9
+ jobs:
10
+ block-unauthorized-edits:
11
+ name: Protect .github directory
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - name: Check for Human Approval
15
+ if: ${{ !contains(github.event.pull_request.labels.*.name, 'human-approved') }}
16
+ run: |
17
+ echo "๐Ÿšจ Modifications in the .github/ directory detected."
18
+ echo "As a security measure, this repository blocks workflow edits by default."
19
+ echo "If you are an AI Agent, do not add the approval label yourself."
20
+ echo "If you are the human owner, please add the 'human-approved' label to this PR to allow merging."
21
+ exit 1
@@ -0,0 +1,27 @@
1
+ name: AI QA Agent
2
+ on:
3
+ pull_request:
4
+ types: [opened, synchronize, reopened]
5
+
6
+ permissions:
7
+ pull-requests: write
8
+ contents: read
9
+
10
+ jobs:
11
+ qa:
12
+ name: Run AI QA Agent
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - name: Execute QA Tests
17
+ run: |
18
+ echo "Run your QA Agent here."
19
+ echo "This could be QAWolf, a custom LLM script, or a secondary agent."
20
+ echo "If tests pass: gh pr edit $PR_URL --add-label 'qa:pass'"
21
+ echo "If tests fail: gh pr edit $PR_URL --add-label 'qa:fail'"
22
+
23
+ # Example success:
24
+ # gh pr edit ${{ github.event.pull_request.html_url }} --add-label "qa:pass"
25
+ env:
26
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27
+ PR_URL: ${{ github.event.pull_request.html_url }}
package/AGENTS.md CHANGED
@@ -27,13 +27,14 @@ Always start from the current `main` HEAD. Never work over stale snapshots.
27
27
  ## Mandatory Workflow
28
28
 
29
29
  0. **Identity**: Always prefix your GitHub comments with `๐Ÿค– **Agent:** ` to distinguish yourself.
30
- 1. Read the issue entirely โ€” understand its type (US/BUG/TASK/SPIKE) and the Acceptance Criteria.
31
- 2. Read `docs/pdlc.md` โ€” understand the PDLC and the Definition of Done in this project.
32
- 3. Read all files mentioned in the issue's technical context.
33
- 4. Implement the **minimum viable change** that satisfies the ACs โ€” do not refactor beyond scope.
34
- 5. Run tests: `echo "No tests/build needed."`
35
- 6. Run typecheck: `echo "No typecheck needed."`
36
- 7. Create a Pull Request with `Closes #N` in the body โ€” automation moves the board.
30
+ 1. **Initial State**: When beginning work on a new issue, your very first action must be to apply the `stage:exploration` label using the GitHub CLI (`gh issue edit <N> --add-label "stage:exploration"`).
31
+ 2. Read the issue entirely โ€” understand its type (US/BUG/TASK/SPIKE) and the Acceptance Criteria.
32
+ 3. Read `docs/pdlc.md` โ€” understand the PDLC and the Definition of Done in this project.
33
+ 4. Read all files mentioned in the issue's technical context.
34
+ 5. Implement the **minimum viable change** that satisfies the ACs โ€” do not refactor beyond scope.
35
+ 6. Run tests: `echo "No tests/build needed."`
36
+ 7. Run typecheck: `echo "No typecheck needed."`
37
+ 8. Create a Pull Request with `Closes #N` in the body โ€” automation moves the board.
37
38
 
38
39
  ## What NOT to do
39
40
 
package/SETUP.md CHANGED
@@ -137,34 +137,21 @@ Move the issues to the `Idea` column on the board matching your setup.
137
137
 
138
138
  ## (Optional) Architecture Violation Integration
139
139
 
140
- If your project uses an automated architecture auditing tool (e.g., a CI job that creates issues with an `architecture-violation` label), the Setup Mode can automatically add a GitHub Actions job to `project-automation.yml` that moves these issues to the `Idea` column.
141
-
142
- If you skipped this during setup but want to add it later, you can append the following job to `.github/workflows/project-automation.yml` under the `jobs` section:
143
-
144
- ```yaml
145
- move-violation-to-board:
146
- name: architecture-violation โ†’ ๐Ÿ’ก Idea
147
- if: github.event_name == 'issues' && github.event.label.name == 'architecture-violation'
148
- runs-on: ubuntu-latest
149
- steps:
150
- - uses: actions/github-script@v7
151
- with:
152
- github-token: ${{ secrets.PROJECT_TOKEN }}
153
- script: |
154
- const issueNodeId = context.payload.issue.node_id;
155
- const addResult = await github.graphql(`
156
- mutation($p: ID!, $c: ID!) {
157
- addProjectV2ItemById(input: {projectId: $p, contentId: $c}) { item { id } }
158
- }`, { p: process.env.PROJECT_ID, c: issueNodeId });
159
- const itemId = addResult.addProjectV2ItemById.item.id;
160
- await github.graphql(`
161
- mutation($p: ID!, $i: ID!, $f: ID!, $v: ProjectV2FieldValue!) {
162
- updateProjectV2ItemFieldValue(input: {projectId: $p, itemId: $i, fieldId: $f, value: $v}) {
163
- projectV2Item { id }
164
- }
165
- }`, { p: process.env.PROJECT_ID, i: itemId, f: process.env.STATUS_FIELD_ID,
166
- v: { singleSelectOptionId: process.env.STATUS_IDEA } });
167
- ```
140
+ If your project uses an automated architecture auditing tool (e.g., a CI job that creates issues with an `architecture-violation` label), you can easily integrate it with your project board.
141
+
142
+ Simply open `.github/workflows/project-automation.yml` and uncomment the `move-violation-to-board` job in the `jobs` section. This will automatically move any issues labeled with `architecture-violation` to the `Idea` column on your board.
143
+
144
+ ---
145
+
146
+ ## (Optional) AI QA Agent Integration (Variant B)
147
+
148
+ If you use an AI QA Agent (e.g., QAWolf, a secondary AI script) to test your PRs before Code Review, you can switch to **Variant B**.
149
+
150
+ Simply open `.github/workflows/project-automation.yml`:
151
+ 1. In the `move-card-on-pr-open` job, change the PR destination from `STATUS_CODE_REVIEW_PR` to `STATUS_TESTING`.
152
+ 2. Uncomment the `move-card-on-qa-pass` job at the bottom of the file to move tested issues to `Code Review / PR` upon receiving a `qa:pass` label.
153
+
154
+ If you don't use this, you can safely delete `templates/.github/workflows/qa-agent.yml`.
168
155
 
169
156
  ---
170
157
 
@@ -24,8 +24,9 @@ If any of these files are missing, you are in **Setup Mode**. Do not proceed wit
24
24
  - **Project basics:** Project Name, Description, Technical Stack (Structure), and GitHub Username (for CODEOWNERS security).
25
25
  - **Commands:** Test command, Lint command, Build command.
26
26
  - **Invariants:** Critical business rules agents must never violate (e.g. Human-in-the-loop).
27
- - **Board IDs:** PROJECT_ID, STATUS_FIELD_ID, column option IDs (provide standard PDLC options: Idea, Exploration, Brainstorming, Detail Solution, Approval, Development, Testing, Code Review / PR, Merge, Production). Allow user to answer "skip", which means you leave the placeholders intact.
28
- - **Architecture Violation:** Ask "Does your project use an automated architecture auditing tool (e.g., a CI job that creates issues with an `architecture-violation` label)?". If yes, replace `{{OPTIONAL_ARCHITECTURE_VIOLATION_JOB}}` in `project-automation.yml` with the job definition (available in the framework documentation). If no, ask if they would like help implementing one, reminding them that it significantly improves their agentic development process. If they decline, remove the placeholder.
27
+ - **Board IDs:** PROJECT_ID, STATUS_FIELD_ID, column option IDs (provide standard PDLC options: Idea, Exploration, Brainstorming, Detail Solution, Approval, Development, Testing, Code Review / PR, Production). Allow user to answer "skip", which means you leave the placeholders intact.
28
+ - **Architecture Violation:** Ask "Does your project use an automated architecture auditing tool (e.g., a CI job that creates issues with an `architecture-violation` label)?". If yes, uncomment the `move-violation-to-board` job inside `project-automation.yml`. If no, ask if they would like help implementing one, reminding them that it significantly improves their agentic development process. If they decline, you can leave the job commented out.
29
+ - **QA Agent (Variant B):** Ask "Do you plan to use an AI QA Agent (e.g. QAWolf or a secondary script) to verify your PRs before Code Review?". If yes, explain you will adopt Variant B: you will change `STATUS_CODE_REVIEW_PR` to `STATUS_TESTING` inside the `move-card-on-pr-open` job in `project-automation.yml` and uncomment the `move-card-on-qa-pass` job. If no, leave the workflow as Variant A (default) and delete the optional `.github/workflows/qa-agent.yml` template.
29
30
  - **Implementation agent handle:** e.g., `@google-labs-jules`, or "none".
30
31
  3. Generate and write the missing files replacing the `{{SCREAMING_SNAKE_CASE}}` placeholders using the templates logic you know (usually they reside in standard Agentic PDLC templates).
31
32
  4. Offer to run the `gh` commands for labels (`spec:approved`, `pr:in-review`, `pr:approved`, `architecture-violation`).
package/bin/cli.js CHANGED
@@ -63,8 +63,10 @@ rl.question('Which AI Agent will you use for the setup? (e.g. claude, cursor, co
63
63
  fs.copyFileSync(claudeSetupSrc, dest);
64
64
  console.log(`โœ… Setup agent profile written to .agentic-setup.md`);
65
65
  console.log(`\n${green}๐ŸŽ‰ Done! To start the conversational setup:${reset}`);
66
- console.log(`${cyan}\t1. Type 'claude'${reset}`);
67
- console.log(`${cyan}\t2. Ask Claude to "read .agentic-setup.md to enter Setup Mode."${reset}`);
66
+ console.log(`${cyan}\tStep 1: Open the Claude Code CLI in your terminal (type 'claude')${reset}`);
67
+ console.log(`${cyan}\t [Or open your preferred IDE Agent chat, like Antigravity, Cursor, Codex, GitHub Copilot, etc]${reset}`);
68
+ console.log(`${cyan}\tStep 2: Paste this exact prompt:${reset}`);
69
+ console.log(`${yellow}\t "read .agentic-setup.md to enter Setup Mode."${reset}`);
68
70
  console.log(`\nNote: Once setup is completed, the agent will typically delete .agentic-setup.md to keep your root clean.\n`);
69
71
  } else {
70
72
  console.error(`โŒ Could not find claude instruction file at ${claudeSetupSrc}`);
package/docs/flow.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  This document describes the full lifecycle of a card on the agentic-pdlc board โ€” who acts at each stage, what triggers each transition, which labels are added or removed, and where human gates are required.
4
4
 
5
+ ```mermaid
6
+ stateDiagram-v2
7
+ direction LR
8
+ Idea --> Exploration : stage:exploration
9
+ Exploration --> Brainstorming : stage:brainstorming
10
+ Brainstorming --> Detailing : Gate 1 (PM)
11
+ Detailing --> Approval : stage:approval
12
+ Approval --> Development : Gate 2 (spec:approved)
13
+ Development --> Testing : stage:testing
14
+ Testing --> CodeReview : PR Opened
15
+ CodeReview --> Production : Gate 3 (PR Merged)
16
+ ```
17
+
5
18
  ---
6
19
 
7
20
  ## Roles
@@ -21,17 +34,17 @@ This document describes the full lifecycle of a card on the agentic-pdlc board
21
34
  ## Step-by-Step Flow
22
35
 
23
36
  ### ๐Ÿ’ก Idea
24
- Issue exists in the backlog with no `upstream:` label.
37
+ Issue exists in the backlog with no `stage:` label.
25
38
 
26
39
  ---
27
40
 
28
41
  ### ๐Ÿ” Exploration
29
42
 
30
43
  **Trigger (two equivalent paths):**
31
- - PM tells Claude directly in chat โ†’ Claude adds `upstream:exploration` to the issue, OR
32
- - PM adds `upstream:exploration` directly to the issue
44
+ - PM tells Claude directly in chat โ†’ Claude adds `stage:exploration` to the issue, OR
45
+ - PM adds `stage:exploration` directly to the issue
33
46
 
34
- **Workflow:** `project-automation.yml` detects `upstream:exploration` โ†’ moves card to Exploration.
47
+ **Workflow:** `project-automation.yml` detects `stage:exploration` โ†’ moves card to Exploration.
35
48
 
36
49
  **Who works:** Claude reads relevant code and context.
37
50
 
@@ -43,7 +56,7 @@ Issue exists in the backlog with no `upstream:` label.
43
56
 
44
57
  **Actions:**
45
58
  - Claude posts a comment on the issue with findings and 2โ€“3 proposed approaches
46
- - Claude swaps `upstream:exploration` โ†’ `upstream:brainstorming`
59
+ - Claude swaps `stage:exploration` โ†’ `stage:brainstorming`
47
60
 
48
61
  **Workflow:** `project-automation.yml` moves card to Brainstorming.
49
62
 
@@ -57,14 +70,14 @@ Issue exists in the backlog with no `upstream:` label.
57
70
 
58
71
  ### ๐Ÿ“ Detail Solution โ† Gate 1
59
72
 
60
- **Trigger:** `upstream-gate.yml` detects PM approval comment on a `upstream:brainstorming` issue โ†’ swaps `upstream:brainstorming` โ†’ `upstream:detailing` via `PROJECT_TOKEN`.
73
+ **Trigger:** `upstream-gate.yml` detects PM approval comment on a `stage:brainstorming` issue โ†’ swaps `stage:brainstorming` โ†’ `stage:detailing` via `PROJECT_TOKEN`.
61
74
 
62
75
  **Who works:** Claude rewrites the issue body with:
63
76
  1. User story (`Asโ€ฆ I wantโ€ฆ So thatโ€ฆ`)
64
77
  2. Acceptance Criteria (AC1, AC2, โ€ฆ)
65
78
  3. Files to modify
66
79
 
67
- **After spec is written:** Claude swaps `upstream:detailing` โ†’ `upstream:approval`.
80
+ **After spec is written:** Claude swaps `stage:detailing` โ†’ `stage:approval`.
68
81
 
69
82
  **Workflow:** `project-automation.yml` moves card to Approval.
70
83
 
@@ -75,8 +88,8 @@ Issue exists in the backlog with no `upstream:` label.
75
88
  **โธ Human gate (Gate 2 โ€” PM + TL):** Both PM (business decisions) and TL (technical decisions) review the spec. When both are satisfied, PM adds label `spec:approved`.
76
89
 
77
90
  **Workflow:** `agent-trigger.yml` detects `spec:approved` โ†’
78
- 1. Removes `upstream:approval`
79
- 2. Adds `upstream:development`
91
+ 1. Removes `stage:approval`
92
+ 2. Adds `stage:development`
80
93
  3. Adds specific agent label (e.g., `jules`)
81
94
  4. Posts a structured comment with implementation instructions for the Agent
82
95
 
@@ -88,7 +101,7 @@ Issue exists in the backlog with no `upstream:` label.
88
101
 
89
102
  **Who works:** Implementation Agent implements the spec strictly within the Acceptance Criteria.
90
103
 
91
- **When done:** Agent adds `upstream:testing` before running tests.
104
+ **When done:** Agent adds `stage:testing` before running tests.
92
105
 
93
106
  **Workflow:** `project-automation.yml` moves card to Testing.
94
107
 
@@ -128,12 +141,12 @@ Issue exists in the backlog with no `upstream:` label.
128
141
 
129
142
  | Label | Added by | Removed by |
130
143
  |-------|----------|------------|
131
- | `upstream:exploration` | PM (human) or Claude | Claude |
132
- | `upstream:brainstorming` | Claude | `upstream-gate.yml` |
133
- | `upstream:detailing` | `upstream-gate.yml` | Claude |
134
- | `upstream:approval` | Claude | `agent-trigger.yml` |
135
- | `upstream:development` | `agent-trigger.yml` | Impl. Agent |
136
- | `upstream:testing` | Impl. Agent | `project-automation.yml` (on PR open) |
144
+ | `stage:exploration` | PM (human) or Claude | Claude |
145
+ | `stage:brainstorming` | Claude | `upstream-gate.yml` |
146
+ | `stage:detailing` | `upstream-gate.yml` | Claude |
147
+ | `stage:approval` | Claude | `agent-trigger.yml` |
148
+ | `stage:development` | `agent-trigger.yml` | Impl. Agent |
149
+ | `stage:testing` | Impl. Agent | `project-automation.yml` (on PR open) |
137
150
  | `spec:approved` | PM (human) | โ€” |
138
151
  | `agent_label` (e.g. `jules`, `sweep`) | `agent-trigger.yml` | โ€” |
139
152
  | `pr:in-review` | `project-automation.yml` | `project-automation.yml` |
package/docs/pdlc.md CHANGED
@@ -12,7 +12,6 @@
12
12
  | โš™๏ธ Development | Agent implementing the spec | Label `stage:development` |
13
13
  | ๐Ÿงช Testing | CI pipeline running | GitHub Actions |
14
14
  | ๐Ÿ‘ Code Review / PR | PR opened, awaiting human review | GitHub Actions |
15
- | ๐Ÿ”€ Merge | PR approved, awaiting merge | GitHub Actions |
16
15
  | ๐Ÿš€ Production | Merged | GitHub Actions |
17
16
 
18
17
  <!--
@@ -40,7 +39,6 @@ REPO = {{REPO_OWNER}}/{{REPO_NAME}}
40
39
  | โš™๏ธ Development | `{{ID_DEVELOPMENT}}` |
41
40
  | ๐Ÿงช Testing | `{{ID_TESTING}}` |
42
41
  | ๐Ÿ‘ Code Review / PR | `{{ID_CODE_REVIEW_PR}}` |
43
- | ๐Ÿ”€ Merge | `{{ID_MERGE}}` |
44
42
  | ๐Ÿš€ Production | `{{ID_PRODUCTION}}` |
45
43
 
46
44
  ## Agent ร— Phase Mapping
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-agentic-pdlc",
3
- "version": "2.0.0",
4
- "description": "Scaffold the Agentic PDLC framework effortlessly",
3
+ "version": "2.0.3",
4
+ "description": "Agentic PDLC Framework - Conversational setup for your AI coding assistants",
5
5
  "type": "commonjs",
6
6
  "bin": {
7
7
  "create-agentic-pdlc": "./bin/cli.js"
@@ -20,7 +20,7 @@ jobs:
20
20
  PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
21
21
  steps:
22
22
  - name: Update Labels
23
- if: ${{ env.PROJECT_TOKEN != '' }}
23
+ if: ${{ env.PROJECT_TOKEN != '' && !contains('{{IMPLEMENTATION_AGENT_LABEL}}', '{{') }}
24
24
  uses: actions/github-script@v7
25
25
  with:
26
26
  github-token: ${{ env.PROJECT_TOKEN }}
@@ -33,20 +33,21 @@ jobs:
33
33
  owner,
34
34
  repo,
35
35
  issue_number,
36
- name: 'upstream:approval'
36
+ name: 'stage:approval'
37
37
  });
38
38
  } catch (error) {
39
- console.log('Label upstream:approval not found or could not be removed');
39
+ console.log('Label stage:approval not found or could not be removed');
40
40
  }
41
41
 
42
42
  await github.rest.issues.addLabels({
43
43
  owner,
44
44
  repo,
45
45
  issue_number,
46
- labels: ['upstream:development', '{{IMPLEMENTATION_AGENT_LABEL}}', 'agent:working']
46
+ labels: ['stage:development', '{{IMPLEMENTATION_AGENT_LABEL}}', 'agent:working']
47
47
  });
48
48
 
49
49
  - name: Comment on issue to trigger agent and prevent race conditions
50
+ if: ${{ !contains('{{IMPLEMENTATION_AGENT_LABEL}}', '{{') }}
50
51
  uses: actions/github-script@v7
51
52
  with:
52
53
  github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -89,6 +90,7 @@ jobs:
89
90
  contents: read
90
91
  steps:
91
92
  - name: Comment on issue to trigger agent
93
+ if: ${{ !contains('{{IMPLEMENTATION_AGENT_LABEL}}', '{{') }}
92
94
  uses: actions/github-script@v7
93
95
  with:
94
96
  github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,16 @@
1
+ name: Auto Approve PRs
2
+ on:
3
+ pull_request:
4
+ types: [opened, labeled, synchronize]
5
+
6
+ permissions:
7
+ pull-requests: write
8
+
9
+ jobs:
10
+ auto-approve:
11
+ runs-on: ubuntu-latest
12
+ if: contains(github.event.pull_request.labels.*.name, 'auto-approve')
13
+ steps:
14
+ - uses: hmarr/auto-approve-action@v4
15
+ with:
16
+ github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -20,13 +20,21 @@ jobs:
20
20
  run: echo "Replace this with your package manager install command"
21
21
 
22
22
  - name: Run Linters
23
- run: {{LINT_COMMAND}}
23
+ if: ${{ !contains('{{LINT_COMMAND}}', '{{') }}
24
+ run: |
25
+ {{LINT_COMMAND}}
24
26
 
25
27
  - name: Typecheck
26
- run: {{TYPECHECK_COMMAND}}
28
+ if: ${{ !contains('{{TYPECHECK_COMMAND}}', '{{') }}
29
+ run: |
30
+ {{TYPECHECK_COMMAND}}
27
31
 
28
32
  - name: Build
29
- run: {{BUILD_COMMAND}}
33
+ if: ${{ !contains('{{BUILD_COMMAND}}', '{{') }}
34
+ run: |
35
+ {{BUILD_COMMAND}}
30
36
 
31
37
  - name: Run Tests
32
- run: {{TEST_COMMAND}}
38
+ if: ${{ !contains('{{TEST_COMMAND}}', '{{') }}
39
+ run: |
40
+ {{TEST_COMMAND}}
@@ -11,6 +11,7 @@ on:
11
11
  env:
12
12
  PROJECT_ID: "{{PROJECT_ID}}"
13
13
  STATUS_FIELD_ID: "{{STATUS_FIELD_ID}}"
14
+ STATUS_IDEA: "{{ID_IDEA}}"
14
15
  STATUS_EXPLORATION: "{{ID_EXPLORATION}}"
15
16
  STATUS_BRAINSTORMING: "{{ID_BRAINSTORMING}}"
16
17
  STATUS_DETAILING: "{{ID_DETAILING}}"
@@ -30,7 +31,7 @@ jobs:
30
31
  PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
31
32
  steps:
32
33
  - name: Detect Label and Move Issue
33
- if: ${{ env.PROJECT_TOKEN != '' }}
34
+ if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
34
35
  uses: actions/github-script@v7
35
36
  with:
36
37
  github-token: ${{ env.PROJECT_TOKEN }}
@@ -39,28 +40,28 @@ jobs:
39
40
  let targetStatusId = null;
40
41
  let stageName = null;
41
42
 
42
- if (labelName === 'upstream:exploration') {
43
+ if (labelName === 'stage:exploration') {
43
44
  targetStatusId = process.env.STATUS_EXPLORATION;
44
45
  stageName = 'Exploration';
45
- } else if (labelName === 'upstream:brainstorming') {
46
+ } else if (labelName === 'stage:brainstorming') {
46
47
  targetStatusId = process.env.STATUS_BRAINSTORMING;
47
48
  stageName = 'Brainstorming';
48
- } else if (labelName === 'upstream:detailing') {
49
+ } else if (labelName === 'stage:detailing') {
49
50
  targetStatusId = process.env.STATUS_DETAILING;
50
51
  stageName = 'Detailing';
51
- } else if (labelName === 'upstream:approval') {
52
+ } else if (labelName === 'stage:approval') {
52
53
  targetStatusId = process.env.STATUS_APPROVAL;
53
54
  stageName = 'Approval';
54
- } else if (labelName === 'upstream:development') {
55
+ } else if (labelName === 'stage:development') {
55
56
  targetStatusId = process.env.STATUS_DEVELOPMENT;
56
57
  stageName = 'Development';
57
- } else if (labelName === 'upstream:testing') {
58
+ } else if (labelName === 'stage:testing') {
58
59
  targetStatusId = process.env.STATUS_TESTING;
59
60
  stageName = 'Testing';
60
61
  }
61
62
 
62
63
  if (!targetStatusId) {
63
- console.log('No upstream PDLC label found. Skipping.');
64
+ console.log('No stage PDLC label found. Skipping.');
64
65
  return;
65
66
  }
66
67
 
@@ -86,9 +87,36 @@ jobs:
86
87
  await moveItem(node_id, targetStatusId);
87
88
  console.log(`Issue #${number} moved to ${stageName}`);
88
89
 
89
- {{OPTIONAL_ARCHITECTURE_VIOLATION_JOB}}
90
+ # OPTIONAL: Uncomment to enable architecture-violation โ†’ Idea
91
+ # move-violation-to-board:
92
+ # name: architecture-violation โ†’ ๐Ÿ’ก Idea
93
+ # if: github.event_name == 'issues' && github.event.action == 'labeled' && github.event.label.name == 'architecture-violation'
94
+ # runs-on: ubuntu-latest
95
+ # steps:
96
+ # - name: Move issue to Idea
97
+ # if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
98
+ # uses: actions/github-script@v7
99
+ # with:
100
+ # github-token: ${{ env.PROJECT_TOKEN }}
101
+ # script: |
102
+ # const { issue: { number, node_id } } = context.payload;
103
+ # const { addProjectV2ItemById: { item } } = await github.graphql(`
104
+ # mutation($p: ID!, $c: ID!) {
105
+ # addProjectV2ItemById(input: {projectId: $p, contentId: $c}) { item { id } }
106
+ # }`, { p: process.env.PROJECT_ID, c: node_id });
107
+ # await github.graphql(`
108
+ # mutation($p: ID!, $i: ID!, $f: ID!, $v: ProjectV2FieldValue!) {
109
+ # updateProjectV2ItemFieldValue(input: {projectId: $p, itemId: $i, fieldId: $f, value: $v}) {
110
+ # projectV2Item { id }
111
+ # }
112
+ # }`, {
113
+ # p: process.env.PROJECT_ID, i: item.id, f: process.env.STATUS_FIELD_ID,
114
+ # v: { singleSelectOptionId: process.env.STATUS_IDEA }
115
+ # });
116
+ # console.log(`Issue #${number} moved to Idea`);
90
117
 
91
118
  # PR Opened โ†’ Move linked issue to Code Review / PR
119
+ # ๐Ÿ’ก VARIANT B (QA Agent): If using an AI QA agent, change `STATUS_CODE_REVIEW_PR` to `STATUS_TESTING` on line ~158
92
120
  move-card-on-pr-open:
93
121
  name: Open PR โ†’ Code Review / PR
94
122
  if: github.event_name == 'pull_request' && (github.event.action == 'opened' || github.event.action == 'reopened')
@@ -97,7 +125,7 @@ jobs:
97
125
  PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
98
126
  steps:
99
127
  - name: Move linked issue to Code Review / PR
100
- if: ${{ env.PROJECT_TOKEN != '' }}
128
+ if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
101
129
  uses: actions/github-script@v7
102
130
  with:
103
131
  github-token: ${{ env.PROJECT_TOKEN }}
@@ -151,7 +179,7 @@ jobs:
151
179
  PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
152
180
  steps:
153
181
  - name: Swap PR labels
154
- if: ${{ env.PROJECT_TOKEN != '' }}
182
+ if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
155
183
  uses: actions/github-script@v7
156
184
  with:
157
185
  github-token: ${{ env.PROJECT_TOKEN }}
@@ -170,7 +198,7 @@ jobs:
170
198
  PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
171
199
  steps:
172
200
  - name: Move issue to Production
173
- if: ${{ env.PROJECT_TOKEN != '' }}
201
+ if: ${{ env.PROJECT_TOKEN != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
174
202
  uses: actions/github-script@v7
175
203
  with:
176
204
  github-token: ${{ env.PROJECT_TOKEN }}
@@ -0,0 +1,21 @@
1
+ name: Protect Workflows
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize, reopened, labeled]
6
+ paths:
7
+ - '.github/**'
8
+
9
+ jobs:
10
+ block-unauthorized-edits:
11
+ name: Protect .github directory
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - name: Check for Human Approval
15
+ if: ${{ !contains(github.event.pull_request.labels.*.name, 'human-approved') }}
16
+ run: |
17
+ echo "๐Ÿšจ Modifications in the .github/ directory detected."
18
+ echo "As a security measure, this repository blocks workflow edits by default."
19
+ echo "If you are an AI Agent, do not add the approval label yourself."
20
+ echo "If you are the human owner, please add the 'human-approved' label to this PR to allow merging."
21
+ exit 1
@@ -0,0 +1,27 @@
1
+ name: AI QA Agent
2
+ on:
3
+ pull_request:
4
+ types: [opened, synchronize, reopened]
5
+
6
+ permissions:
7
+ pull-requests: write
8
+ contents: read
9
+
10
+ jobs:
11
+ qa:
12
+ name: Run AI QA Agent
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - name: Execute QA Tests
17
+ run: |
18
+ echo "Run your QA Agent here."
19
+ echo "This could be QAWolf, a custom LLM script, or a secondary agent."
20
+ echo "If tests pass: gh pr edit $PR_URL --add-label 'qa:pass'"
21
+ echo "If tests fail: gh pr edit $PR_URL --add-label 'qa:fail'"
22
+
23
+ # Example success:
24
+ # gh pr edit ${{ github.event.pull_request.html_url }} --add-label "qa:pass"
25
+ env:
26
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27
+ PR_URL: ${{ github.event.pull_request.html_url }}
@@ -30,13 +30,14 @@ Always start from the current `main` HEAD. Never work over stale snapshots.
30
30
  ## Mandatory Workflow
31
31
 
32
32
  0. **Identity**: Always prefix your GitHub comments with `๐Ÿค– **Agent:** ` to distinguish yourself.
33
- 1. Read the issue entirely โ€” understand its type (US/BUG/TASK/SPIKE) and the Acceptance Criteria.
34
- 2. Read `docs/pdlc.md` โ€” understand the PDLC and the Definition of Done in this project.
35
- 3. Read all files mentioned in the issue's technical context.
36
- 4. Implement the **minimum viable change** that satisfies the ACs โ€” do not refactor beyond scope.
37
- 5. Run tests: `{{TEST_COMMAND}}`
38
- 6. Run typecheck (if applicable): `{{TYPECHECK_COMMAND}}`
39
- 7. Create a Pull Request with `Closes #N` in the body โ€” automation moves the board.
33
+ 1. **Initial State**: When beginning work on a new issue, your very first action must be to apply the `stage:exploration` label using the GitHub CLI (`gh issue edit <N> --add-label "stage:exploration"`).
34
+ 2. Read the issue entirely โ€” understand its type (US/BUG/TASK/SPIKE) and the Acceptance Criteria.
35
+ 3. Read `docs/pdlc.md` โ€” understand the PDLC and the Definition of Done in this project.
36
+ 4. Read all files mentioned in the issue's technical context.
37
+ 5. Implement the **minimum viable change** that satisfies the ACs โ€” do not refactor beyond scope.
38
+ 6. Run tests: `{{TEST_COMMAND}}`
39
+ 7. Run typecheck (if applicable): `{{TYPECHECK_COMMAND}}`
40
+ 8. Create a Pull Request with `Closes #N` in the body โ€” automation moves the board.
40
41
 
41
42
  ### Spec format (Upstream Agents)
42
43
 
@@ -10,9 +10,8 @@
10
10
  | ๐Ÿ“ Detail Solution | Claude is writing the technical spec | Label `stage:detailing` |
11
11
  | โœ… Approval | Spec ready, awaiting `spec:approved` label | Label `spec:approved` |
12
12
  | โš™๏ธ Development | Agent implementing the spec | Label `stage:development` |
13
- | ๐Ÿงช Testing | CI pipeline running | GitHub Actions |
14
- | ๐Ÿ‘ Code Review / PR | PR opened, awaiting human review | GitHub Actions |
15
- | ๐Ÿ”€ Merge | PR approved, awaiting merge | GitHub Actions |
13
+ | ๐Ÿงช Testing | CI pipeline or AI QA Agent running (Variant B) | GitHub Actions / QA Agent |
14
+ | ๐Ÿ‘ Code Review / PR | PR opened (Variant A) or QA passed (Variant B) | GitHub Actions |
16
15
  | ๐Ÿš€ Production | Merged | GitHub Actions |
17
16
 
18
17
  <!--
@@ -20,6 +19,11 @@ Adapt columns as needed. The functional baseline is:
20
19
  ๐Ÿ’ก Idea โ†’ โš™๏ธ Development โ†’ ๐Ÿ‘ Code Review / PR โ†’ ๐Ÿš€ Production
21
20
  -->
22
21
 
22
+ ## Workflow Variants (QA Agent)
23
+
24
+ - **Variant A (Default):** PRs bypass the `Testing` column and land directly in `Code Review / PR`.
25
+ - **Variant B (QA Agent Enabled):** PRs land in the `Testing` column first. An AI QA agent verifies the PR, adding `qa:pass` or `qa:fail`. Only after a `qa:pass` is the issue moved to `Code Review / PR`.
26
+
23
27
  ## Board Identifiers (GitHub Projects)
24
28
 
25
29
  ```
@@ -40,7 +44,6 @@ REPO = {{REPO_OWNER}}/{{REPO_NAME}}
40
44
  | โš™๏ธ Development | `{{ID_DEVELOPMENT}}` |
41
45
  | ๐Ÿงช Testing | `{{ID_TESTING}}` |
42
46
  | ๐Ÿ‘ Code Review / PR | `{{ID_CODE_REVIEW_PR}}` |
43
- | ๐Ÿ”€ Merge | `{{ID_MERGE}}` |
44
47
  | ๐Ÿš€ Production | `{{ID_PRODUCTION}}` |
45
48
 
46
49
  ## Agent ร— Phase Mapping
@@ -1,54 +0,0 @@
1
- name: Upstream Gate 1
2
-
3
- on:
4
- issue_comment:
5
- types: [created]
6
-
7
- jobs:
8
- evaluate-gate:
9
- name: Evaluate Brainstorming Approval
10
- if: ${{ !github.event.issue.pull_request && contains(github.event.issue.labels.*.name, 'upstream:brainstorming') }}
11
- runs-on: ubuntu-latest
12
- env:
13
- PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
14
- steps:
15
- - name: Check for approval and swap label
16
- if: ${{ env.PROJECT_TOKEN != '' }}
17
- uses: actions/github-script@v7
18
- with:
19
- github-token: ${{ env.PROJECT_TOKEN }}
20
- script: |
21
- const comment = context.payload.comment.body.toLowerCase();
22
- const isApproved =
23
- comment.includes('approved') ||
24
- comment.includes('lgtm') ||
25
- /option\s+[a-z0-9]/i.test(comment) ||
26
- /go\s+with\s+[a-z0-9]/i.test(comment) ||
27
- /proceed/i.test(comment);
28
-
29
- if (isApproved) {
30
- const { owner, repo } = context.repo;
31
- const issue_number = context.payload.issue.number;
32
-
33
- console.log('Approval detected, swapping labels...');
34
-
35
- try {
36
- await github.rest.issues.removeLabel({
37
- owner,
38
- repo,
39
- issue_number,
40
- name: 'upstream:brainstorming'
41
- });
42
- } catch (e) {
43
- console.log('Could not remove upstream:brainstorming label');
44
- }
45
-
46
- await github.rest.issues.addLabels({
47
- owner,
48
- repo,
49
- issue_number,
50
- labels: ['upstream:detailing']
51
- });
52
- } else {
53
- console.log('No approval pattern detected in the comment.');
54
- }