From forge
Reference skill for all Linear operations in forge — creating issues from tasks, updating status during execution, and importing issues as tasks. Only active when .forge/config.json exists.
npx claudepluginhub ekelhaft-tools/forge-cursorThis skill uses the workspace's default tool permissions.
Bidirectional sync between forge sessions and Linear. Called by brainstorming, planning, executing, and aborting skills — never directly by the user.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Bidirectional sync between forge sessions and Linear. Called by brainstorming, planning, executing, and aborting skills — never directly by the user.
Activation: Read .forge/config.json. If it doesn't exist or has no linear key, skip all Linear operations silently.
cat .forge/config.json 2>/dev/null
{
"linear": {
"teamId": "TEAM-ID",
"projectId": "PROJECT-ID",
"labelId": "LABEL-ID"
}
}
Linear issue IDs are stored in $SESSION_DIR/integration.json:
{
"linear": {
"issueIds": {
"T1": "issue-uuid-here",
"T2": "issue-uuid-here"
}
}
}
Read this file before any update operations to get the issue ID for a task.
| Tool | Purpose |
|---|---|
mcp__58713d66-4955-4040-9fea-5260fa8f32b9__find_teams | List teams (for init) |
mcp__58713d66-4955-4040-9fea-5260fa8f32b9__find_projects | List projects in a team (for init) |
mcp__58713d66-4955-4040-9fea-5260fa8f32b9__list_issue_statuses | Get status IDs for the team (needed for save_issue) |
mcp__58713d66-4955-4040-9fea-5260fa8f32b9__list_issue_labels | List labels |
mcp__58713d66-4955-4040-9fea-5260fa8f32b9__create_issue_label | Create "forge" label if needed |
mcp__58713d66-4955-4040-9fea-5260fa8f32b9__save_issue | Create or update an issue |
mcp__58713d66-4955-4040-9fea-5260fa8f32b9__list_issues | List issues in a project |
mcp__58713d66-4955-4040-9fea-5260fa8f32b9__get_issue | Get a single issue by ID |
mcp__58713d66-4955-4040-9fea-5260fa8f32b9__save_comment | Add a comment to an issue |
Forge task statuses map to Linear states. Get actual state IDs for the team via list_issue_statuses (once, cache in session):
| Forge status | Linear state name (approximate) |
|---|---|
pending | Todo |
in-progress | In Progress |
done | Done |
failed | Cancelled |
aborted | Cancelled |
blocked | Todo (with a comment explaining the block) |
Called by planning skill after writing $SESSION_DIR/plan.md.
1. Read .forge/config.json → get teamId, projectId, labelId
2. Call list_issue_statuses(teamId) → find "Todo" state ID
3. For each task Tn in the plan:
a. title = "[forge s<id>] Tn: <task title>"
b. description = task description + "\n\n**Files**: " + task files
c. Call save_issue(teamId, projectId, title, description, stateId=todoStateId, labelId?)
d. Store returned issue ID in $SESSION_DIR/integration.json under linear.issueIds.Tn
4. Print summary: "Created N Linear issues in project <name>"
Called by executing skill on each task status change.
1. Read $SESSION_DIR/integration.json → get issueId for Tn
2. If no issueId → skip (session was created without Linear)
3. Map forge status → Linear state name → get state ID via list_issue_statuses
4. Call save_issue(issueId=<id>, stateId=<new state ID>)
5. If status is "done": also call save_comment(issueId, "✅ Implemented by forge. Summary: <implementer report>")
6. If status is "failed": call save_comment(issueId, "❌ Failed: <reviewer feedback>")
Called by planning skill when user chooses to import from Linear.
1. Read .forge/config.json → get projectId
2. Call list_issues(projectId) → get all open issues
3. Present issues to user as a list with titles + descriptions
4. User selects which issues to import (AskQuestion, multi-select)
5. For each selected issue, generate a forge task:
- title = issue.title (strip "[forge s<id>]" prefix if present)
- description = issue.description (first 3 sentences)
- files = [] (user fills in during planning)
- complexity = low|medium|high (infer from issue.estimate if available)
- Store original issueId in $SESSION_DIR/integration.json
6. Return task list to planning skill for inclusion in the plan
Called by aborting skill.
1. Read $SESSION_DIR/integration.json
2. Read $SESSION_DIR/plan.md → find all in-progress tasks
3. For each in-progress task Tn with a known issueId:
a. list_issue_statuses → get "Cancelled" state ID
b. save_issue(issueId, stateId=cancelledId)
c. save_comment(issueId, "⚠️ Forge session aborted. Task was in-progress.")
.forge/config.json missing or has no linear key, return immediatelylist_issue_statuses once per session, not per task