internaltool-mcp 1.6.1 → 1.6.3

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.
Files changed (2) hide show
  1. package/index.js +72 -14
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -896,11 +896,16 @@ Use this when a developer says "start task", "brief me on", or "what do I need t
896
896
  if (commitsRes?.success) recentCommits = commitsRes.data.commits || []
897
897
  } catch { /* GitHub may not be linked */ }
898
898
 
899
+ // If the task already has a branch linked, it's safe to move to in_progress now.
900
+ // If not, create_branch will do the move once the branch is created.
901
+ const alreadyHasBranch = !!task.github?.headBranch
899
902
  let moved = false
900
- try {
901
- const moveRes = await api.post(`/api/tasks/${taskId}/move`, { column: 'in_progress', toIndex: 0 })
902
- moved = moveRes?.success ?? false
903
- } catch { /* might already be in_progress */ }
903
+ if (alreadyHasBranch) {
904
+ try {
905
+ const moveRes = await api.post(`/api/tasks/${taskId}/move`, { column: 'in_progress', toIndex: 0 })
906
+ moved = moveRes?.success ?? false
907
+ } catch { /* might already be in_progress */ }
908
+ }
904
909
 
905
910
  return text({
906
911
  started: {
@@ -908,6 +913,7 @@ Use this when a developer says "start task", "brief me on", or "what do I need t
908
913
  title: task.title,
909
914
  priority: task.priority,
910
915
  column: moved ? 'in_progress' : task.column,
916
+ branch: task.github?.headBranch || null,
911
917
  subtasks,
912
918
  },
913
919
  implementationPlan: hasReadme ? task.readmeMarkdown : null,
@@ -918,8 +924,10 @@ Use this when a developer says "start task", "brief me on", or "what do I need t
918
924
  date: c.commit?.author?.date,
919
925
  })),
920
926
  movedToInProgress: moved,
921
- suggestedBranch,
922
- nextStep: `Use create_branch to create "${suggestedBranch}" on GitHub — it will automatically check your local git state before creating.`,
927
+ suggestedBranch: alreadyHasBranch ? null : suggestedBranch,
928
+ nextStep: alreadyHasBranch
929
+ ? `Branch "${task.github.headBranch}" already exists. Task is now In progress — start coding.`
930
+ : `Call create_branch to create "${suggestedBranch}" — it will check your local git state and move the task to In progress automatically.`,
923
931
  })
924
932
  }
925
933
  )
@@ -1519,16 +1527,40 @@ If you have uncommitted tracked changes, it will tell you exactly what to do bef
1519
1527
  })
1520
1528
  }
1521
1529
 
1522
- // Step 3 — create branch on GitHub, then link it to the task
1530
+ // Step 3 — create branch on GitHub (or confirm it already exists), then link + move
1523
1531
  const localState = gitState?.localState || 'unknown'
1524
1532
  try {
1533
+ let branchUrl = null
1534
+ let alreadyExisted = false
1535
+
1525
1536
  const res = await api.post(`/api/projects/${projectId}/github/branches`, { branchName, fromRef })
1526
- if (!res?.success) return errorText(res?.message || 'Could not create branch')
1537
+ if (!res?.success) {
1538
+ // "Reference already exists" means the branch is already on GitHub — treat as success
1539
+ const msg = (res?.message || '').toLowerCase()
1540
+ if (msg.includes('already exists') || msg.includes('reference already exists')) {
1541
+ alreadyExisted = true
1542
+ } else {
1543
+ return errorText(res?.message || 'Could not create branch')
1544
+ }
1545
+ } else {
1546
+ branchUrl = res.data?.url || null
1547
+ }
1527
1548
 
1528
- // Link the branch name back to the task so get_task_context / list_my_tasks reflect it immediately
1549
+ // Link branch to task regardless of whether it was just created or already existed
1529
1550
  try {
1530
1551
  await api.patch(`/api/tasks/${taskId}/github/branch`, { headBranch: branchName })
1531
- } catch { /* non-fatal — branch was still created on GitHub */ }
1552
+ } catch { /* non-fatal */ }
1553
+
1554
+ // Move task to in_progress now that branch is linked
1555
+ let movedToInProgress = false
1556
+ try {
1557
+ const freshTask = await api.get(`/api/tasks/${taskId}`)
1558
+ const col = freshTask?.data?.task?.column
1559
+ if (col && ['todo', 'backlog'].includes(col)) {
1560
+ const moveRes = await api.post(`/api/tasks/${taskId}/move`, { column: 'in_progress', toIndex: 0 })
1561
+ movedToInProgress = moveRes?.success ?? false
1562
+ }
1563
+ } catch { /* non-fatal */ }
1532
1564
 
1533
1565
  const checkoutSteps = [
1534
1566
  'git fetch origin',
@@ -1543,16 +1575,42 @@ If you have uncommitted tracked changes, it will tell you exactly what to do bef
1543
1575
  unknown: null,
1544
1576
  }[localState] || null
1545
1577
 
1578
+ const statusMsg = alreadyExisted
1579
+ ? `Branch "${branchName}" already existed on GitHub — linked to task.${movedToInProgress ? ' Task moved to In progress.' : ''}`
1580
+ : `Branch "${branchName}" created on GitHub.${movedToInProgress ? ' Task moved to In progress.' : ''}`
1581
+
1546
1582
  return text({
1547
1583
  branchName,
1548
- url: res.data.url,
1584
+ url: branchUrl,
1585
+ alreadyExisted,
1549
1586
  localState,
1550
- message: `Branch "${branchName}" created on GitHub.`,
1551
- gitSteps: checkoutSteps,
1587
+ movedToInProgress,
1588
+ message: statusMsg,
1589
+ gitSteps: checkoutSteps,
1552
1590
  localStateNote,
1553
- nextStep: 'Run the git steps above to switch locally, then start coding. When commits are pushed, use raise_pr.',
1591
+ nextStep: 'Run the git steps above to switch locally, then start coding. When commits are pushed, use raise_pr.',
1554
1592
  })
1555
1593
  } catch (e) {
1594
+ // Last-resort catch: if error message indicates branch already exists, still link + move
1595
+ const msg = (e.message || '').toLowerCase()
1596
+ if (msg.includes('already exists') || msg.includes('reference already exists')) {
1597
+ try { await api.patch(`/api/tasks/${taskId}/github/branch`, { headBranch: branchName }) } catch { /* ok */ }
1598
+ try {
1599
+ const freshTask = await api.get(`/api/tasks/${taskId}`)
1600
+ const col = freshTask?.data?.task?.column
1601
+ if (col && ['todo', 'backlog'].includes(col)) {
1602
+ await api.post(`/api/tasks/${taskId}/move`, { column: 'in_progress', toIndex: 0 })
1603
+ }
1604
+ } catch { /* ok */ }
1605
+ return text({
1606
+ branchName,
1607
+ alreadyExisted: true,
1608
+ movedToInProgress: true,
1609
+ message: `Branch "${branchName}" already existed on GitHub — linked to task and moved to In progress.`,
1610
+ gitSteps: ['git fetch origin', `git checkout ${branchName}`],
1611
+ nextStep: 'Run the git steps above to switch locally, then start coding.',
1612
+ })
1613
+ }
1556
1614
  return errorText(e.message)
1557
1615
  }
1558
1616
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "internaltool-mcp",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
4
4
  "description": "MCP server for InternalTool — connect AI assistants (Claude Code, Cursor) to your project and task management platform",
5
5
  "type": "module",
6
6
  "main": "index.js",