Skip to content

feat: add GitHub Copilot CLI as 7th supported agent#207

Open
ABIvan-Tech wants to merge 12 commits intovakovalskii:mainfrom
ABIvan-Tech:feat/copilot-cli-agent
Open

feat: add GitHub Copilot CLI as 7th supported agent#207
ABIvan-Tech wants to merge 12 commits intovakovalskii:mainfrom
ABIvan-Tech:feat/copilot-cli-agent

Conversation

@ABIvan-Tech
Copy link
Copy Markdown

Summary

  • Adds GitHub Copilot CLI as a 7th supported agent for codbash
  • Reads VS Code sessions from ~/.copilot/session-state//
  • Reads JetBrains sessions from ~/.copilot/jb//partition-1.jsonl
  • Parses workspace.yaml (flat + block scalar) for metadata
  • Active session detection via inuse..lock files

Changes

  • Added copilot paths to data.js (COPILOT_SESSION_DIR, COPILOT_JB_DIR)
  • Added load/scan functions for Copilot sessions
  • Added badge styles (.badge-copilot, .tool-copilot)
  • Updated findSessionFile, loadSessionDetail, loadSessions
  • Added "Open in VS Code" button handler

Testing

  • Local testing with copilot session directories
  • All existing agent tests pass

ABIvan-Tech and others added 6 commits April 10, 2026 18:39
- Reads VS Code sessions from ~/.copilot/session-state/<uuid>/
- Reads JetBrains sessions from ~/.copilot/jb/<uuid>/partition-1.jsonl
- Parses workspace.yaml (flat + block scalar) for metadata
- Active detection via inuse.<pid>.lock files
- Wires into loadSessions(), loadSessionDetail(), findSessionFile()
- Cache invalidation via COPILOT_SESSION_DIR mtime tracking
- Badge: .badge-copilot and .tool-copilot styles
- Detail: 'Open in VS Code' button instead of Focus Terminal
- Adds openInVSCode() frontend function + vscode IDE handler

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…assistant turns

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 1, 2026 15:50
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to add GitHub Copilot CLI as an additional supported agent by scanning Copilot session directories, surfacing them in the sessions list, and adding UI affordances to open related projects in VS Code.

Changes:

  • Add Copilot session directory constants and new scan/detail loaders for Copilot sessions (VS Code/CLI + JetBrains) in src/data.js.
  • Add a Copilot-specific “Open in VS Code” button in the session detail panel.
  • Extend IDE-launch handling and update ignore patterns.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 6 comments.

File Description
src/server.js Adds additional IDE launch handling for Cursor/VS Code in /api/open-ide.
src/frontend/detail.js Adds a Copilot-only launch button intended to open projects in VS Code.
src/data.js Introduces Copilot CLI/JetBrains session scanning + detail parsing, and wires Copilot into session loading/detail logic.
.gitignore Adds ignores for several directories (including .github/).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/data.js Outdated
Comment on lines +3008 to +3013
// Copilot Chat (JSON/JSONL)
if (found.format === 'copilot-chat') {
>>>>>>> main
return loadCopilotDetail(sessionId);
}

Comment thread src/data.js Outdated
Comment on lines +3514 to +3534
// Load Copilot CLI sessions
try {
const copilotSessions = scanCopilotSessions();
for (const cs of copilotSessions) sessions[cs.id] = cs;
} catch {}

// Try Copilot Chat (file-based, prefixed IDs)
if (sessionId.startsWith('copilot-')) {
const baseName = sessionId.replace(/^copilot-/, '');
const wsMap = buildCopilotWorkspaceMap();
for (const hash of Object.keys(wsMap)) {
const { chatDir } = wsMap[hash];
for (const ext of ['.json', '.jsonl']) {
const candidate = path.join(chatDir, baseName + ext);
if (fs.existsSync(candidate)) return { file: candidate, format: 'copilot-chat' };
}
// Load Kilo CLI sessions
try {
const kiloSessions = scanKiloCliSessions();
for (const ks of kiloSessions) {
sessions[ks.id] = ks;
}
}
} catch {}

// Load Copilot Chat sessions
try {
const copilotSessions = scanCopilotSessions();
for (const cs of copilotSessions) {
sessions[cs.id] = cs;
}
} catch {}
Comment thread src/data.js Outdated
QWEN_DIR,
OPENCODE_DB,
KIRO_DB,
KIRO_DB,
Comment thread src/server.js Outdated
Comment on lines +204 to +208
if (ide === 'cursor') {
exec(`cursor "${target || '.'}"`);
} else if (ide === 'code' || ide === 'vscode') {
exec(`code "${target || '.'}"`);
}
Comment thread src/frontend/detail.js Outdated
Comment on lines +72 to +73
} else if (s.tool === 'copilot') {
infoHtml += '<button class="launch-btn" style="background:#1f6feb" onclick="openInVSCode(\'' + escHtml(s.project || '') + '\')">Open in VS Code</button>';
Comment thread src/data.js Outdated
return result;
}

function scanCopilotSessions() {
…n, remove redundant exec(), add openInVSCode
Copy link
Copy Markdown
Collaborator

@NovakPAai NovakPAai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review + Security Review

Thanks for the effort on adding Copilot CLI support! The approach is solid and the May 1 fixes addressed the bot comments. However, I found 2 critical bugs that will crash at runtime, 1 regression that breaks existing agents, and 1 security issue. All need to be fixed before merge.


🔴 CRITICAL — Runtime crash: loadCopilotDetail is not defined

In loadSessionDetail() you call:

return loadCopilotDetail(sessionId);

…and export loadCopilotDetail. But the actual function defined in this PR is named loadCopilotCliDetail.
loadCopilotDetail does not exist anywhere → ReferenceError every time a Copilot session detail is opened.

Fix: rename the function to loadCopilotDetail everywhere it is defined, or update the call/export to loadCopilotCliDetail.


🔴 CRITICAL — Regression: Kilo CLI and Copilot Chat sessions broken

findSessionFile() previously had two blocks that are deleted in this PR but never replaced:

// DELETED — Kilo CLI lookup
if (fs.existsSync(KILO_DB) && sessionId.startsWith('ses_')) {  }

// DELETED — Copilot Chat lookup
if (sessionId.startsWith('copilot-')) {  }

loadSessionDetail() still routes format === 'kilo' and format === 'copilot-chat' through findSessionFile, but findSessionFile can no longer return those formats. Result: all existing Kilo and Copilot Chat session details return null / crash after this PR.

Fix: restore both removed blocks (they are not in conflict with the new Copilot CLI blocks).


🔴 SECURITY — Path traversal via unvalidated sessionId

In loadCopilotCliDetail() and findSessionFile():

const eventsPath = path.join(COPILOT_SESSION_DIR, sessionId, 'events.jsonl');

sessionId comes from an HTTP request parameter. A value like ../../.env or ../../etc/passwd traverses outside ~/.copilot/session-state/. The UUID-length check (uuid.length !== 36) is only applied during scanning in scanCopilotCliSessions()not in the lookup path.

Fix: validate sessionId against a strict UUID regex before using it in path construction:

if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(sessionId)) {
  return { messages: [] };
}

🟡 MEDIUM — findSessionFile JB scan is O(N×file_size) on every detail request

For JetBrains sessions, findSessionFile reads and parses every partition file line-by-line to match a conversationId. This scan runs on every session detail open, with no caching. With many sessions this will be noticeably slow.

Suggestion: build the conversationId → uuid map once (lazily, same pattern as buildCopilotWorkspaceMap()) and cache it with an mtime guard.


🟡 MEDIUM — COPILOT_JB_DIR not tracked in cache invalidation

_sessionsNeedRescan() watches COPILOT_SESSION_DIR mtime, but not COPILOT_JB_DIR. New JetBrains sessions will not trigger a cache refresh until something else changes.

Fix: add the same statSync(COPILOT_JB_DIR) check in both _sessionsNeedRescan() and _updateScanMarkers().


🟡 MEDIUM — Broken indentation in loadSessions() disrupts readability

After the merge, several comment lines and the closing } catch {} for the Kiro block lost their leading spaces. The block is no longer consistently indented with the rest of the function. Not a runtime bug, but it signals a messy merge that should be cleaned up.


🟢 Minor — homedir vs ALL_HOMES[0] inconsistency in scanCopilotCliSessions

The VS Code section uses cwd.replace(homedir, '~') (local const homedir = ALL_HOMES[0]), but the JetBrains section uses cwd.replace(ALL_HOMES[0], '~') directly. Either use homedir consistently or remove the local variable.


Summary

# Severity Issue
1 🔴 Critical loadCopilotDetail not defined → ReferenceError
2 🔴 Critical Kilo CLI + Copilot Chat lookup deleted from findSessionFile
3 🔴 Security Path traversal via unsanitized sessionId
4 🟡 Medium JB session lookup O(N) with no cache
5 🟡 Medium COPILOT_JB_DIR not watched in cache invalidation
6 🟡 Medium Indentation breakage in loadSessions()
7 🟢 Minor homedir / ALL_HOMES[0] inconsistency

Issues 1–3 are blockers. 4–6 should be fixed in the same PR since the code is fresh. 7 can be a follow-up.

@ABIvan-Tech please address the blockers and force-push (or add a fixup commit) — happy to re-review quickly.

@vakovalskii
Copy link
Copy Markdown
Owner

Hi @ABIvan-Tech, thanks again for the contribution! 🙏

We're holding off on merging until the three blockers from @NovakPAai's review are addressed:

  1. 🔴 Runtime crashloadCopilotDetail vs loadCopilotCliDetail mismatch
  2. 🔴 Regression — restore the Kilo CLI and Copilot Chat lookup blocks deleted from findSessionFile()
  3. 🔴 Path traversal — validate sessionId against a strict UUID regex before path.join

The medium-priority items (4–6 in the review) would be great to fix in the same PR while the code is fresh, but they're not strictly blocking. Item 7 can be a follow-up.

Once you push the fixes, ping us and we'll re-review quickly. Looking forward to landing this!

…versal, cache tracking

- Fix loadCopilotDetail vs loadCopilotCliDetail mismatch (runtime crash)
- Add UUID validation in loadCopilotCliDetail to prevent path traversal
- Add COPILOT_JB_DIR mtime tracking for cache invalidation
@ABIvan-Tech
Copy link
Copy Markdown
Author

@vakovalskii pls check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants