Skip to content

Commit f815d3f

Browse files
feature parity workflow (#124)
* feature parity workflow * readme update * readme fix * simplify readme link * formatting * center * update parity workflow to use stagehand-parity-bot app --------- Co-authored-by: Roaring <[email protected]>
1 parent 9342cf8 commit f815d3f

File tree

3 files changed

+174
-3
lines changed

3 files changed

+174
-3
lines changed

.github/workflows/feature-parity.yml

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
name: Feature Parity
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- synchronize
8+
- labeled
9+
- unlabeled
10+
11+
jobs:
12+
check-parity-label:
13+
runs-on: ubuntu-latest
14+
if: github.event.action == 'labeled' && github.event.label.name == 'parity'
15+
permissions:
16+
contents: read
17+
pull-requests: write
18+
issues: write
19+
steps:
20+
- name: Check out repository code
21+
uses: actions/checkout@v4
22+
23+
- name: Check user permissions
24+
uses: actions/github-script@v7
25+
with:
26+
github-token: ${{ secrets.GITHUB_TOKEN }}
27+
script: |
28+
const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({
29+
owner: context.repo.owner,
30+
repo: context.repo.repo,
31+
username: context.actor
32+
});
33+
34+
const hasWriteAccess = ['admin', 'write'].includes(permission.permission);
35+
36+
if (!hasWriteAccess) {
37+
// Remove the parity label if user doesn't have write access
38+
await github.rest.issues.removeLabel({
39+
owner: context.repo.owner,
40+
repo: context.repo.repo,
41+
issue_number: context.issue.number,
42+
name: 'parity'
43+
});
44+
45+
// Add a comment explaining why the label was removed
46+
await github.rest.issues.createComment({
47+
owner: context.repo.owner,
48+
repo: context.repo.repo,
49+
issue_number: context.issue.number,
50+
body: `❌ **Parity Label Removed**\n\n@${context.actor}, you do not have sufficient permissions to add the 'parity' label. Only users with write access can trigger feature parity issues.\n\nIf you believe this feature should be implemented in the Python SDK, please ask a maintainer to add the label.`
51+
});
52+
53+
throw new Error(`User ${context.actor} does not have write access to add parity label`);
54+
}
55+
56+
console.log(`User ${context.actor} has ${permission.permission} access - proceeding with parity workflow`);
57+
58+
- name: Generate GitHub App token
59+
id: generate-token
60+
uses: actions/create-github-app-token@v1
61+
with:
62+
app-id: ${{ secrets.PARITY_APP_ID }}
63+
private-key: ${{ secrets.PARITY_APP_PRIVATE_KEY }}
64+
owner: browserbase
65+
repositories: stagehand
66+
67+
- name: Create issue in Python SDK repository
68+
uses: actions/github-script@v7
69+
with:
70+
github-token: ${{ steps.generate-token.outputs.token }}
71+
script: |
72+
const { data: pullRequest } = await github.rest.pulls.get({
73+
owner: context.repo.owner,
74+
repo: context.repo.repo,
75+
pull_number: context.issue.number,
76+
});
77+
78+
// Get PR comments for additional context
79+
const { data: comments } = await github.rest.issues.listComments({
80+
owner: context.repo.owner,
81+
repo: context.repo.repo,
82+
issue_number: context.issue.number,
83+
});
84+
85+
// Format comments for the issue description
86+
let commentsSection = '';
87+
if (comments.length > 0) {
88+
commentsSection = '\n\n## Recent Comments\n\n';
89+
comments.slice(-3).forEach(comment => {
90+
commentsSection += `**@${comment.user.login}** commented:\n`;
91+
commentsSection += `${comment.body.substring(0, 500)}${comment.body.length > 500 ? '...' : ''}\n\n`;
92+
});
93+
}
94+
95+
// Get list of changed files for context
96+
const { data: files } = await github.rest.pulls.listFiles({
97+
owner: context.repo.owner,
98+
repo: context.repo.repo,
99+
pull_number: context.issue.number,
100+
});
101+
102+
const changedFiles = files.map(file => `- \`${file.filename}\``).join('\n');
103+
104+
const issueTitle = `[Feature Parity] ${pullRequest.title}`;
105+
const issueBody = `## Feature Parity Request
106+
107+
This issue was automatically created from a pull request in the TypeScript Stagehand repository that was labeled with 'parity'.
108+
109+
### Original PR Details
110+
- **PR**: #${context.issue.number} - ${pullRequest.title}
111+
- **Author**: @${pullRequest.user.login}
112+
- **Link**: ${pullRequest.html_url}
113+
114+
### Description
115+
${pullRequest.body || 'No description provided.'}
116+
117+
### Changed Files
118+
${changedFiles}
119+
120+
${commentsSection}
121+
122+
### Action Required
123+
Please review the changes in the original PR and implement equivalent functionality in the Python SDK if applicable.
124+
125+
---
126+
*This issue was automatically generated by the Feature Parity workflow.*`;
127+
128+
// Create the issue in the Python repository
129+
const { data: issue } = await github.rest.issues.create({
130+
owner: 'browserbase',
131+
repo: 'stagehand',
132+
title: issueTitle,
133+
body: issueBody,
134+
labels: ['feature-parity']
135+
});
136+
137+
console.log(`Created issue: ${issue.html_url}`);
138+
139+
// Add a comment to the original PR confirming the issue was created
140+
await github.rest.issues.createComment({
141+
owner: context.repo.owner,
142+
repo: context.repo.repo,
143+
issue_number: context.issue.number,
144+
body: `🔄 **Feature Parity Issue Created**\n\nAn issue has been automatically created in the Python SDK repository to track parity implementation:\n${issue.html_url}`
145+
});

README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,26 @@
3434
</a>
3535
</p>
3636

37-
> Stagehand Python is now available! We're actively seeking feedback from the community and looking for contributors. Join our [Slack community](https://stagehand.dev/slack) to stay updated on the latest updates
37+
<p align="center">
38+
If you're looking for the TypeScript implementation, you can find it
39+
<a href="https://github.com/browserbase/stagehand"> here</a>
40+
</p>
41+
42+
<div align="center" style="display: flex; align-items: center; justify-content: center; gap: 4px; margin-bottom: 0;">
43+
<b>Vibe code</b>
44+
<span style="font-size: 1.05em;"> Stagehand with </span>
45+
<a href="https://director.ai" style="display: flex; align-items: center;">
46+
<span>Director</span>
47+
</a>
48+
<span> </span>
49+
<picture>
50+
<img alt="Director" src="media/director_icon.svg" width="25" />
51+
</picture>
52+
</div>
3853

3954

4055
## Why Stagehand?
4156

42-
*Stagehand is the easiest way to build browser automations with AI-powered interactions.*
43-
4457
Most existing browser automation tools either require you to write low-level code in a framework like Selenium, Playwright, or Puppeteer, or use high-level agents that can be unpredictable in production. By letting developers choose what to write in code vs. natural language, Stagehand is the natural choice for browser automations in production.
4558

4659
1. **Choose when to write code vs. natural language**: use AI when you want to navigate unfamiliar pages, and use code ([Playwright](https://playwright.dev/)) when you know exactly what you want to do.

media/director_icon.svg

Lines changed: 13 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)