Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 45 additions & 3 deletions .roo/commands/cli-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,58 @@ mode: code
- Include links to relevant source files where helpful
- Describe changes from the user's perspective

5. Commit the version bump and changelog update:
5. Create a release branch and commit the changes:

```bash
# Ensure you're on main and up to date
git checkout main
git pull origin main

# Create a new branch for the release
git checkout -b cli-release-v<version>

# Commit the version bump and changelog update
git add apps/cli/package.json apps/cli/CHANGELOG.md
git commit -m "chore(cli): prepare release v<version>"

# Push the branch to origin
git push -u origin cli-release-v<version>
```

6. Run the release script from the monorepo root:
6. Create a pull request for the release:

```bash
gh pr create --title "chore(cli): prepare release v<version>" \
--body "## CLI Release v<version>

This PR prepares the CLI release v<version>.

### Changes
- Version bump in package.json
- Changelog update

### Checklist
- [ ] Version number is correct
- [ ] Changelog entry is complete and accurate
- [ ] All CI checks pass" \
--base main
```

7. Wait for PR approval and merge:

- Request review if required by your workflow
- Ensure CI checks pass
- Merge the PR using: `gh pr merge --squash --delete-branch`
- Or merge via the GitHub UI

8. Run the release script from the monorepo root:

```bash
# Ensure you're on the updated main branch after the PR merge
git checkout main
git pull origin main

# Run the release script
./apps/cli/scripts/release.sh
```

Expand All @@ -69,7 +111,7 @@ mode: code
- Extract changelog content and include it in the GitHub release notes
- Create the GitHub release with the tarball attached

7. After a successful release, verify:
9. After a successful release, verify:
- Check the release page: https://github.com/RooCodeInc/Roo-Code/releases
- Verify the "What's New" section contains the changelog content
- Test installation: `curl -fsSL https://raw.githubusercontent.com/RooCodeInc/Roo-Code/main/apps/cli/install.sh | sh`
Expand Down
5 changes: 1 addition & 4 deletions apps/cli/scripts/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -536,11 +536,8 @@ ROO_VERSION=$VERSION curl -fsSL https://raw.githubusercontent.com/RooCodeInc/Roo
## Usage

\`\`\`bash
# Set your API key
export OPENROUTER_API_KEY=sk-or-v1-...

# Run a task
roo "What is this project?" ~/my-project
roo "What is this project?"

# See all options
roo --help
Expand Down
45 changes: 15 additions & 30 deletions apps/cli/src/commands/auth/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,58 +32,43 @@ export async function login({ timeout = 5 * 60 * 1000, verbose = false }: LoginO
console.log(`[Auth] Starting local callback server on port ${port}`)
}

const corsHeaders = {
"Access-Control-Allow-Origin": AUTH_BASE_URL,
"Access-Control-Allow-Methods": "POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
}

// Create promise that will be resolved when we receive the callback.
const tokenPromise = new Promise<{ token: string; state: string }>((resolve, reject) => {
const server = http.createServer((req, res) => {
const url = new URL(req.url!, host)

// Handle CORS preflight request.
if (req.method === "OPTIONS") {
res.writeHead(204, corsHeaders)
res.end()
return
}

if (url.pathname === "/callback" && req.method === "POST") {
if (url.pathname === "/callback") {
const receivedState = url.searchParams.get("state")
const token = url.searchParams.get("token")
const error = url.searchParams.get("error")

const sendJsonResponse = (status: number, body: object) => {
res.writeHead(status, {
...corsHeaders,
"Content-Type": "application/json",
})
res.end(JSON.stringify(body))
}

if (error) {
sendJsonResponse(400, { success: false, error })
res.on("close", () => {
const errorUrl = new URL(`${AUTH_BASE_URL}/cli/sign-in?error=error-in-callback`)
errorUrl.searchParams.set("message", error)
res.writeHead(302, { Location: errorUrl.toString() })
res.end(() => {
server.close()
reject(new Error(error))
})
} else if (!token) {
sendJsonResponse(400, { success: false, error: "Missing token in callback" })
res.on("close", () => {
const errorUrl = new URL(`${AUTH_BASE_URL}/cli/sign-in?error=missing-token`)
errorUrl.searchParams.set("message", "Missing token in callback")
res.writeHead(302, { Location: errorUrl.toString() })
res.end(() => {
server.close()
reject(new Error("Missing token in callback"))
})
} else if (receivedState !== state) {
sendJsonResponse(400, { success: false, error: "Invalid state parameter" })
res.on("close", () => {
const errorUrl = new URL(`${AUTH_BASE_URL}/cli/sign-in?error=invalid-state-parameter`)
errorUrl.searchParams.set("message", "Invalid state parameter")
res.writeHead(302, { Location: errorUrl.toString() })
res.end(() => {
server.close()
reject(new Error("Invalid state parameter"))
})
} else {
sendJsonResponse(200, { success: true })
res.on("close", () => {
res.writeHead(302, { Location: `${AUTH_BASE_URL}/cli/sign-in?success=true` })
res.end(() => {
server.close()
resolve({ token, state: receivedState })
})
Expand Down
Loading