diff --git a/.agent/workflows/branch.md b/.agent/workflows/branch.md index 8a8d409d..84e447ef 100644 --- a/.agent/workflows/branch.md +++ b/.agent/workflows/branch.md @@ -92,6 +92,11 @@ git checkout -b {type}/{description} - Use lowercase with hyphens: `feature/user-authentication` - Be descriptive but concise: `bugfix/login-timeout` not `bugfix/fix` +- Start with an action verb for clarity: + - New functionality: `feature/add-user-dashboard` + - Enhancing existing: `feature/improve-search-filters` + - Fixing: `bugfix/fix-login-timeout` + - Removing: `feature/remove-legacy-api` - Include issue number if applicable: `bugfix/123-login-timeout` - Release branches use version: `release/1.2.0` (semver format) diff --git a/.agent/workflows/git-workflow.md b/.agent/workflows/git-workflow.md index a33e0725..3f1a715e 100644 --- a/.agent/workflows/git-workflow.md +++ b/.agent/workflows/git-workflow.md @@ -21,6 +21,7 @@ tools: - **Purpose**: Ensure safe, traceable git workflow for all file changes - **Trigger**: Read this when conversation indicates file creation/modification in a git repo - **Principle**: Every change on a branch, never directly on main +- **CRITICAL**: With parallel sessions, ALWAYS verify branch state before ANY file operation **First Actions** (before any code changes): @@ -33,8 +34,42 @@ git remote -v | head -1 # 3. Check for uncommitted work git status --short + +# 4. Check for remote updates (parallel session safety) +git fetch origin +git log --oneline HEAD..origin/$(git branch --show-current) 2>/dev/null ``` +**Parallel Session Safety**: + +When running multiple OpenCode sessions on the same repo: + +| Situation | Action | +|-----------|--------| +| Remote has new commits | Pull/rebase before continuing | +| Uncommitted local changes | Stash or commit before switching | +| Different session on same branch | Coordinate or use separate branches | +| Starting new work | Always create a new branch first | + +**Session-Branch Tracking**: + +OpenCode auto-generates session titles from the first prompt. To sync session names with branches: + +| Command | Purpose | +|---------|---------| +| `/sync-branch` | Rename session to match current git branch | +| `/rename feature/xyz` | Rename session to any title | +| `/sessions` (Ctrl+x l) | List all sessions by name | + +| Workflow | How to Track | +|----------|--------------| +| **New session, known work** | Start with: `opencode --title "feature/my-feature"` | +| **Existing session, new branch** | Run `/sync-branch` after creating branch | +| **Multiple sessions** | Each session named after its branch | +| **Resume work** | `opencode -c` continues last session, or `-s ` for specific | + +**Best Practice**: After creating a branch, run `/sync-branch` to rename the session to match. + **Decision Tree**: | Situation | Action | diff --git a/.agent/workflows/release.md b/.agent/workflows/release.md index fe6eb358..dab7e904 100644 --- a/.agent/workflows/release.md +++ b/.agent/workflows/release.md @@ -54,6 +54,58 @@ Before running the release command: The release script will **refuse to release** if there are uncommitted changes. This prevents accidentally releasing without your session's work. +## Merging Work Branch to Main + +Before releasing, merge your work branch to main (or create PR/MR if collaborating): + +### Direct Merge (Solo Work) + +```bash +# 1. Ensure branch is up to date +git checkout {your-branch} +git fetch origin +git rebase origin/main # or merge + +# 2. Switch to main and merge +git checkout main +git pull origin main +git merge --no-ff {your-branch} -m "Merge {your-branch} into main" + +# 3. Push merged main +git push origin main + +# 4. Delete branch after merge +git branch -d {your-branch} +git push origin --delete {your-branch} +``` + +### PR/MR Workflow (Collaborative) + +When working with others or requiring review: + +```bash +# 1. Push branch +git push -u origin {your-branch} + +# 2. Create PR/MR +gh pr create --fill --base main # GitHub +glab mr create --fill --target-branch main # GitLab + +# 3. After approval and merge, continue with release +git checkout main +git pull origin main +``` + +### Decision Tree + +| Situation | Action | +|-----------|--------| +| Solo work, simple changes | Direct merge to main | +| Team collaboration | Create PR/MR for review | +| Multiple branches to release | Merge each to main, then release | +| Hotfix on production | Use `hotfix/` branch, merge to main + release | +| Parallel sessions, same feature | Coordinate via PR to avoid conflicts | + ## Release Workflow Overview The release script handles everything automatically: diff --git a/.opencode/command/rename.md b/.opencode/command/rename.md new file mode 100644 index 00000000..dab8df99 --- /dev/null +++ b/.opencode/command/rename.md @@ -0,0 +1,7 @@ +--- +description: Rename this session +--- + +Rename this session to: $ARGUMENTS + +Use the session-rename tool to update the session title. diff --git a/.opencode/command/sync-branch.md b/.opencode/command/sync-branch.md new file mode 100644 index 00000000..c9f10334 --- /dev/null +++ b/.opencode/command/sync-branch.md @@ -0,0 +1,5 @@ +--- +description: Sync session title with current git branch +--- + +Use the session-rename_sync_branch tool to rename this session to match the current git branch name. diff --git a/.opencode/tool/session-rename.ts b/.opencode/tool/session-rename.ts new file mode 100644 index 00000000..5151b214 --- /dev/null +++ b/.opencode/tool/session-rename.ts @@ -0,0 +1,78 @@ +import { tool } from "@opencode-ai/plugin" + +export default tool({ + description: "Rename the current session to a new title. Use this after creating a git branch to sync the session name with the branch name.", + args: { + title: tool.schema.string().describe("New title for the session (e.g., branch name like 'feature/my-feature')"), + }, + async execute(args, context) { + const { sessionID } = context + const { title } = args + + // Call the OpenCode API to update the session + // The server runs on localhost:4096 by default + const port = process.env.OPENCODE_PORT || "4096" + const baseUrl = `http://localhost:${port}` + + try { + const response = await fetch(`${baseUrl}/session/${sessionID}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ title }), + }) + + if (!response.ok) { + const error = await response.text() + return `Failed to rename session: ${error}` + } + + const session = await response.json() + return `Session renamed to: ${session.title || title}` + } catch (error) { + return `Error renaming session: ${error instanceof Error ? error.message : String(error)}` + } + }, +}) + +// Also export a tool that syncs with the current git branch +export const sync_branch = tool({ + description: "Rename the current session to match the current git branch name. Call this after creating or switching branches.", + args: {}, + async execute(_args, context) { + const { sessionID } = context + + // Get current branch name + const branchResult = await Bun.$`git branch --show-current`.text() + const branch = branchResult.trim() + + if (!branch) { + return "Not in a git repository or no branch checked out" + } + + // Call the OpenCode API to update the session + const port = process.env.OPENCODE_PORT || "4096" + const baseUrl = `http://localhost:${port}` + + try { + const response = await fetch(`${baseUrl}/session/${sessionID}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ title: branch }), + }) + + if (!response.ok) { + const error = await response.text() + return `Failed to sync session with branch: ${error}` + } + + const session = await response.json() + return `Session synced with branch: ${session.title || branch}` + } catch (error) { + return `Error syncing session: ${error instanceof Error ? error.message : String(error)}` + } + }, +})