agent-flutter 0.1.22 → 0.1.24
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.
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/cli.js +30 -1
- package/templates/shared/TEMPLATES.md +22 -0
- package/templates/shared/github/pull_request_template.md +26 -0
- package/templates/shared/github/workflows/pr-template-gate.yml +102 -0
- package/templates/shared/rules/ci-cd-pr.md +53 -0
package/README.md
CHANGED
|
@@ -76,4 +76,4 @@ npm run release:major
|
|
|
76
76
|
- Cursor: `.cursor/skills/`, `.cursor/rules/shared/`, `.cursor/scripts/`, `.cursor/rules/agent-flutter.mdc`
|
|
77
77
|
- Windsurf: `.windsurf/skills/`, `.windsurf/rules/shared/`, `.windsurf/scripts/`, `.windsurf/rules/agent-flutter.md`
|
|
78
78
|
- Cline: `.clinerules/skills/`, `.clinerules/rules/`, `.clinerules/scripts/`, `.clinerules/agent-flutter.md`
|
|
79
|
-
- GitHub: `.github/skills/`, `.github/rules/`, `.github/scripts/`, `.github/copilot-instructions.md`
|
|
79
|
+
- GitHub: `.github/skills/`, `.github/rules/`, `.github/scripts/`, `.github/copilot-instructions.md`, `.github/pull_request_template.md`, `.github/workflows/pr-template-gate.yml`
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -399,6 +399,25 @@ async function applyPack({
|
|
|
399
399
|
});
|
|
400
400
|
console.log(`${verb} GitHub rules: ${githubRulesPath}`);
|
|
401
401
|
}
|
|
402
|
+
|
|
403
|
+
const githubPrTemplateSource = path.join(templateRoot, 'github', 'pull_request_template.md');
|
|
404
|
+
if (await exists(githubPrTemplateSource)) {
|
|
405
|
+
await syncTemplateFile({
|
|
406
|
+
sourcePath: githubPrTemplateSource,
|
|
407
|
+
destinationPath: path.join(projectRoot, '.github', 'pull_request_template.md'),
|
|
408
|
+
label: 'GitHub PR template',
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const githubPrGateSource = path.join(templateRoot, 'github', 'workflows', 'pr-template-gate.yml');
|
|
413
|
+
if (await exists(githubPrGateSource)) {
|
|
414
|
+
await syncTemplateFile({
|
|
415
|
+
sourcePath: githubPrGateSource,
|
|
416
|
+
destinationPath: path.join(projectRoot, '.github', 'workflows', 'pr-template-gate.yml'),
|
|
417
|
+
label: 'GitHub PR gate workflow',
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
|
|
402
421
|
const githubPath = path.join(projectRoot, '.github', 'copilot-instructions.md');
|
|
403
422
|
const written = await writeTextFile(
|
|
404
423
|
githubPath,
|
|
@@ -697,13 +716,17 @@ Use local instructions from \`.cursor\`.
|
|
|
697
716
|
Priority:
|
|
698
717
|
1. \`.cursor/rules/shared/ui.md\`
|
|
699
718
|
2. \`.cursor/rules/shared/integration-api.md\`
|
|
700
|
-
3. \`.cursor/rules/shared/
|
|
719
|
+
3. \`.cursor/rules/shared/ci-cd-pr.md\`
|
|
720
|
+
4. \`.cursor/rules/shared/unit-test.md\` and \`.cursor/rules/shared/widget-test.md\`
|
|
701
721
|
|
|
702
722
|
When a task matches a skill, load the corresponding \`SKILL.md\` under:
|
|
703
723
|
\`.cursor/skills/<skill>/SKILL.md\`
|
|
704
724
|
|
|
705
725
|
For new project scaffolding, run:
|
|
706
726
|
\`bash .cursor/scripts/bootstrap_flutter_template.sh\`
|
|
727
|
+
|
|
728
|
+
After finishing UI/API tasks, ask user in order:
|
|
729
|
+
\`Commit now?\` -> \`Push now?\` -> \`Create PR now?\`
|
|
707
730
|
`;
|
|
708
731
|
}
|
|
709
732
|
|
|
@@ -717,6 +740,8 @@ Required order:
|
|
|
717
740
|
2. If task matches a skill, load \`.windsurf/skills/<skill>/SKILL.md\`.
|
|
718
741
|
3. For new project scaffolding, run \`bash .windsurf/scripts/bootstrap_flutter_template.sh\`.
|
|
719
742
|
4. Keep spec documentation synchronized after UI/API changes.
|
|
743
|
+
5. For completed UI/API features, follow \`.windsurf/rules/shared/ci-cd-pr.md\`.
|
|
744
|
+
6. Ask user in order: \`Commit now?\` -> \`Push now?\` -> \`Create PR now?\`.
|
|
720
745
|
`;
|
|
721
746
|
}
|
|
722
747
|
|
|
@@ -731,6 +756,8 @@ Execution checklist:
|
|
|
731
756
|
3. For new project scaffolding, run \`bash .clinerules/scripts/bootstrap_flutter_template.sh\`.
|
|
732
757
|
4. Preserve Flutter architecture conventions and localization requirements.
|
|
733
758
|
5. Update docs/specs after behavior changes.
|
|
759
|
+
6. For completed UI/API features, follow \`.clinerules/rules/ci-cd-pr.md\`.
|
|
760
|
+
7. Ask user in order: \`Commit now?\` -> \`Push now?\` -> \`Create PR now?\`.
|
|
734
761
|
`;
|
|
735
762
|
}
|
|
736
763
|
|
|
@@ -745,6 +772,8 @@ Follow this order when generating code:
|
|
|
745
772
|
3. For new project scaffolding, run \`bash .github/scripts/bootstrap_flutter_template.sh\`.
|
|
746
773
|
4. Keep architecture, localization, and UI conventions aligned with local instructions.
|
|
747
774
|
5. Update specs/docs when UI/API behavior changes.
|
|
775
|
+
6. For completed UI/API features, follow \`.github/rules/ci-cd-pr.md\`.
|
|
776
|
+
7. Ask user in order: \`Commit now?\` -> \`Push now?\` -> \`Create PR now?\`.
|
|
748
777
|
`;
|
|
749
778
|
}
|
|
750
779
|
|
|
@@ -52,3 +52,25 @@ Refactor this page: [Path to file]
|
|
|
52
52
|
- Replace raw widgets with `App*` widgets.
|
|
53
53
|
- Fix hardcoded strings/colors.
|
|
54
54
|
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## **4. Finalize Feature (Commit + Push + PR)**
|
|
59
|
+
|
|
60
|
+
Use this after completing UI/API work to trigger CI/CD rule and PR creation:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
Finalize this feature:
|
|
64
|
+
- Branch name: [e.g. feat/login-session-timeout]
|
|
65
|
+
- Commit message: [e.g. feat(auth): handle session timeout]
|
|
66
|
+
- Commit now?: [yes/no]
|
|
67
|
+
- Push now?: [yes/no]
|
|
68
|
+
- Create PR now?: [yes/no]
|
|
69
|
+
- Base branch: [e.g. dev]
|
|
70
|
+
- PR title: [e.g. feat(auth): handle session timeout]
|
|
71
|
+
- Feature summary: [...]
|
|
72
|
+
- UI summary: [...]
|
|
73
|
+
- Reviewer notes: [...]
|
|
74
|
+
- Screenshot evidence: [No UI OR before/after]
|
|
75
|
+
- Paired with: [Solo OR name]
|
|
76
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
### 🗃 Issue Or Explanation for this PR. (What is it supposed to do and Why is needed)
|
|
2
|
+
|
|
3
|
+
- Feature:
|
|
4
|
+
- UI:
|
|
5
|
+
|
|
6
|
+
### ✅ Checklist
|
|
7
|
+
|
|
8
|
+
- [ ] Issue Or Task detail are up to date for people to QA
|
|
9
|
+
- [ ] I have functionally tested all my changes
|
|
10
|
+
- [ ] I handled the code format
|
|
11
|
+
- [ ] I have Tested on Android (only App)
|
|
12
|
+
- [ ] I have Tested on iOS (only App)
|
|
13
|
+
|
|
14
|
+
### 🕵️♂️ Notes for Code Reviewer
|
|
15
|
+
|
|
16
|
+
Example: Change the Subscription Billing Flow with using SetupIntent to collect user billing information first.
|
|
17
|
+
|
|
18
|
+
### 🙈 Screenshots
|
|
19
|
+
|
|
20
|
+
No UI
|
|
21
|
+
or take screenshot before change and after change
|
|
22
|
+
Or take a screenshot of the design if the task is new
|
|
23
|
+
|
|
24
|
+
### 👯♀️ Paired with
|
|
25
|
+
|
|
26
|
+
Solo
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
name: PR Template Gate
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types:
|
|
6
|
+
- opened
|
|
7
|
+
- edited
|
|
8
|
+
- reopened
|
|
9
|
+
- synchronize
|
|
10
|
+
- ready_for_review
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
validate-pr-template:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- name: Validate PR body sections and checklist
|
|
17
|
+
uses: actions/github-script@v7
|
|
18
|
+
with:
|
|
19
|
+
script: |
|
|
20
|
+
const body = (context.payload.pull_request.body || "").trim();
|
|
21
|
+
const errors = [];
|
|
22
|
+
|
|
23
|
+
function escapeRegExp(value) {
|
|
24
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function requirePattern(regex, message) {
|
|
28
|
+
if (!regex.test(body)) {
|
|
29
|
+
errors.push(message);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function sectionBetween(startHeading, endHeading) {
|
|
34
|
+
const start = body.indexOf(startHeading);
|
|
35
|
+
if (start === -1) return "";
|
|
36
|
+
const afterStart = start + startHeading.length;
|
|
37
|
+
const end = endHeading ? body.indexOf(endHeading, afterStart) : body.length;
|
|
38
|
+
const raw = end === -1 ? body.slice(afterStart) : body.slice(afterStart, end);
|
|
39
|
+
return raw.trim();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const requiredHeadings = [
|
|
43
|
+
"### 🗃 Issue Or Explanation for this PR. (What is it supposed to do and Why is needed)",
|
|
44
|
+
"### ✅ Checklist",
|
|
45
|
+
"### 🕵️♂️ Notes for Code Reviewer",
|
|
46
|
+
"### 🙈 Screenshots",
|
|
47
|
+
"### 👯♀️ Paired with",
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
for (const heading of requiredHeadings) {
|
|
51
|
+
if (!body.includes(heading)) {
|
|
52
|
+
errors.push(`Missing section: ${heading}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
requirePattern(/^- Feature:\s*\S.+/m, "Missing or empty `- Feature:` line.");
|
|
57
|
+
requirePattern(/^- UI:\s*\S.+/m, "Missing or empty `- UI:` line.");
|
|
58
|
+
|
|
59
|
+
const checklistItems = [
|
|
60
|
+
"Issue Or Task detail are up to date for people to QA",
|
|
61
|
+
"I have functionally tested all my changes",
|
|
62
|
+
"I handled the code format",
|
|
63
|
+
"I have Tested on Android (only App)",
|
|
64
|
+
"I have Tested on iOS (only App)",
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
for (const item of checklistItems) {
|
|
68
|
+
const regex = new RegExp(`^- \\[(x|X)\\] ${escapeRegExp(item)}\\s*$`, "m");
|
|
69
|
+
if (!regex.test(body)) {
|
|
70
|
+
errors.push(`Checklist item must be checked [x]: ${item}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const notesSection = sectionBetween(
|
|
75
|
+
"### 🕵️♂️ Notes for Code Reviewer",
|
|
76
|
+
"### 🙈 Screenshots",
|
|
77
|
+
);
|
|
78
|
+
if (!notesSection || /^Example:/i.test(notesSection)) {
|
|
79
|
+
errors.push("Notes for Code Reviewer must contain actual reviewer notes, not only the example.");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const screenshotSection = sectionBetween(
|
|
83
|
+
"### 🙈 Screenshots",
|
|
84
|
+
"### 👯♀️ Paired with",
|
|
85
|
+
);
|
|
86
|
+
const hasNoUi = /No UI/i.test(screenshotSection);
|
|
87
|
+
const hasImage = /!\[[^\]]*\]\([^)]+\)/.test(screenshotSection);
|
|
88
|
+
const hasBeforeAfter = /before/i.test(screenshotSection) && /after/i.test(screenshotSection);
|
|
89
|
+
if (!screenshotSection || (!hasNoUi && !hasImage && !hasBeforeAfter)) {
|
|
90
|
+
errors.push("Screenshots section must include `No UI`, markdown image(s), or before/after evidence.");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const pairedSection = sectionBetween("### 👯♀️ Paired with", null);
|
|
94
|
+
if (!pairedSection) {
|
|
95
|
+
errors.push("Paired with section cannot be empty (e.g. `Solo`).");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (errors.length > 0) {
|
|
99
|
+
core.setFailed(["PR template validation failed:", ...errors.map(e => `- ${e}`)].join("\n"));
|
|
100
|
+
} else {
|
|
101
|
+
core.info("PR template validation passed.");
|
|
102
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
alwaysApply: false
|
|
3
|
+
---
|
|
4
|
+
# CI/CD Rule - Commit, Push, Pull Request Gate
|
|
5
|
+
|
|
6
|
+
## 1. Trigger
|
|
7
|
+
Apply this rule after completing any feature that follows:
|
|
8
|
+
- `ui.md`
|
|
9
|
+
- `integration-api.md`
|
|
10
|
+
|
|
11
|
+
This is the required "done" flow before feature handoff.
|
|
12
|
+
|
|
13
|
+
## 2. Required Flow
|
|
14
|
+
1. Verify quality gates:
|
|
15
|
+
- `fvm flutter analyze`
|
|
16
|
+
- Run related tests for the changed scope (unit/widget/integration when available).
|
|
17
|
+
2. Ensure spec/docs are updated if behavior changed.
|
|
18
|
+
3. Ask user explicitly: `Do you want me to commit now? (yes/no)`
|
|
19
|
+
4. If answer is `yes`, create commit with clear scope and summary.
|
|
20
|
+
5. Ask user explicitly: `Do you want me to push now? (yes/no)`
|
|
21
|
+
6. If answer is `yes`, push branch to remote.
|
|
22
|
+
7. Ask user explicitly: `Do you want me to create PR now? (yes/no)`
|
|
23
|
+
8. If answer is `yes`, create PR with mandatory template sections.
|
|
24
|
+
9. If any answer is `no`, stop at that step and return current status.
|
|
25
|
+
|
|
26
|
+
If any step is skipped, feature is not considered complete.
|
|
27
|
+
|
|
28
|
+
## 3. Git Commands (Reference)
|
|
29
|
+
```bash
|
|
30
|
+
git checkout -b feat/<feature-name>
|
|
31
|
+
git add -A
|
|
32
|
+
git commit -m "feat(<scope>): <short summary>"
|
|
33
|
+
git push -u origin HEAD
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 4. PR Body Policy (Mandatory)
|
|
37
|
+
PR must follow `.github/pull_request_template.md` and include all sections:
|
|
38
|
+
- Issue/Explanation (with `Feature` and `UI` lines).
|
|
39
|
+
- Checklist (all required items checked `[x]`).
|
|
40
|
+
- Notes for reviewer.
|
|
41
|
+
- Screenshots section (`No UI` or actual screenshots/evidence).
|
|
42
|
+
- Paired with.
|
|
43
|
+
|
|
44
|
+
## 5. Merge Gate
|
|
45
|
+
- CI workflow `PR Template Gate` validates PR body.
|
|
46
|
+
- If required section/checklist is missing, CI fails.
|
|
47
|
+
- Branch protection must require this check before merge.
|
|
48
|
+
|
|
49
|
+
## 6. Agent Behavior
|
|
50
|
+
- After finishing UI/API tasks, agent must ask in order: commit -> push -> create PR.
|
|
51
|
+
- Agent must execute only steps explicitly confirmed by user (`yes`).
|
|
52
|
+
- If user confirms all steps, agent returns PR URL as final output.
|
|
53
|
+
- If user declines at any step, agent stops and returns current repository status.
|