diff --git a/README.md b/README.md index a72e928..72d6b87 100644 --- a/README.md +++ b/README.md @@ -266,7 +266,7 @@ To install the real companion into local VS Code from a GitGuardex-wired repo: node scripts/install-vscode-active-agents-extension.js ``` -It adds an `Active Agents` view to the Source Control container, groups each live repo into `ACTIVE AGENTS` and `CHANGES` sections, splits `ACTIVE AGENTS` into `BLOCKED`, `WORKING NOW`, `IDLE`, `STALLED`, and `DEAD` when those states are present, mirrors the selected session or active-agent count in the VS Code status bar, reads `.omx/state/active-sessions/*.json`, derives session state from git conflict markers, dirty worktree status, PID liveness, and recent file mtimes, and surfaces working/dead counts in the repo/header affordances. Reload the VS Code window after install. +It adds a dedicated `Active Agents` Activity Bar container with a hive icon, shows the live active-agent count as a badge on that icon, groups each live repo into `ACTIVE AGENTS` and `CHANGES` sections, splits `ACTIVE AGENTS` into `BLOCKED`, `WORKING NOW`, `IDLE`, `STALLED`, and `DEAD` when those states are present, mirrors the selected session or active-agent count in the VS Code status bar, reads `.omx/state/active-sessions/*.json`, derives session state from git conflict markers, dirty worktree status, PID liveness, and recent file mtimes, and surfaces working/dead counts in the repo/header affordances. Reload the VS Code window after install. --- diff --git a/openspec/changes/agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13/.openspec.yaml b/openspec/changes/agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13/.openspec.yaml new file mode 100644 index 0000000..8b394c6 --- /dev/null +++ b/openspec/changes/agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-04-23 diff --git a/openspec/changes/agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13/proposal.md b/openspec/changes/agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13/proposal.md new file mode 100644 index 0000000..14a2223 --- /dev/null +++ b/openspec/changes/agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13/proposal.md @@ -0,0 +1,15 @@ +## Why + +- The shipped Active Agents companion lives inside Source Control, so it competes with the repo graph and SCM surfaces instead of giving agents their own lane. +- Operators need a dedicated Activity Bar icon with a count badge so active sandboxes stay visible at a glance without taking over the SCM container. + +## What Changes + +- Move the `gitguardex.activeAgents` view into a dedicated Activity Bar container with a hive-style icon. +- Keep the existing tree-based runtime badge wiring so the new container shows the live active-agent count on its icon. +- Update focus text, extension copy, mirrored template assets, and focused regression coverage for the new sidebar location. + +## Impact + +- Affected surfaces: `vscode/guardex-active-agents/*`, `templates/vscode/guardex-active-agents/*`, `test/vscode-active-agents-session-state.test.js`, `README.md`, and this change workspace. +- Risk is narrow because the runtime tree data stays the same; the change is mainly manifest placement, icon assets, and focus-copy alignment. diff --git a/openspec/changes/agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13/specs/vscode-active-agents-sidebar-icon/spec.md b/openspec/changes/agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13/specs/vscode-active-agents-sidebar-icon/spec.md new file mode 100644 index 0000000..d23bf41 --- /dev/null +++ b/openspec/changes/agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13/specs/vscode-active-agents-sidebar-icon/spec.md @@ -0,0 +1,23 @@ +## ADDED Requirements + +### Requirement: Active Agents uses a dedicated sidebar container +The Guardex Active Agents VS Code companion SHALL render its primary tree in a dedicated Activity Bar container instead of contributing the view to the built-in Source Control container. + +#### Scenario: Active Agents container ships with branded hive icon +- **WHEN** VS Code loads the extension manifest +- **THEN** the extension contributes a custom Activity Bar container for Active Agents +- **AND** that container references the bundled hive icon asset +- **AND** the `gitguardex.activeAgents` view is registered inside that custom container. + +#### Scenario: Focus command opens the Active Agents sidebar +- **WHEN** an operator runs `gitguardex.activeAgents.focus` +- **THEN** the command opens the dedicated Active Agents sidebar container +- **AND** status-bar and tooltip copy refer to Active Agents rather than Source Control. + +### Requirement: Active Agents container badge stays truthful +The Guardex Active Agents VS Code companion SHALL keep the live session count badge visible after the view moves into its own Activity Bar container. + +#### Scenario: Active sessions show a badge on the sidebar icon +- **WHEN** one or more live Guardex sessions are present +- **THEN** the `TreeView` badge value equals the live session count +- **AND** the new Active Agents container icon surfaces that badge in VS Code. diff --git a/openspec/changes/agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13/tasks.md b/openspec/changes/agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13/tasks.md new file mode 100644 index 0000000..ca85e8f --- /dev/null +++ b/openspec/changes/agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13/tasks.md @@ -0,0 +1,32 @@ +## Definition of Done + +This change is complete only when **all** of the following are true: + +- Every checkbox below is checked. +- The agent branch reaches `MERGED` state on `origin` and the PR URL + state are recorded in the completion handoff. +- If any step blocks (test failure, conflict, ambiguous result), append a `BLOCKED:` line under section 4 explaining the blocker and **STOP**. Do not tick remaining cleanup boxes; do not silently skip the cleanup pipeline. + +Handoff: 2026-04-23 14:20Z codex owns the Active Agents live/template manifests, runtime focus text, hive icon assets, focused tests/docs, and this change workspace for the new sidebar container move. + +## 1. Specification + +- [x] 1.1 Finalize proposal scope and acceptance criteria for `agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13`. +- [x] 1.2 Define normative requirements in `specs/vscode-active-agents-sidebar-icon/spec.md`. + +## 2. Implementation + +- [x] 2.1 Move the Active Agents view from the SCM container into a dedicated Activity Bar container with a hive icon. +- [x] 2.2 Preserve the live badge count on the new container and update focus/welcome/docs copy to match the new location. +- [x] 2.3 Add/update focused regression coverage plus mirrored template parity. + +## 3. Verification + +- [x] 3.1 Run `node --test test/vscode-active-agents-session-state.test.js`. +- [x] 3.2 Run `openspec validate agent-codex-move-active-agents-to-own-sidebar-icon-2026-04-23-14-13 --type change --strict`. +- [x] 3.3 Run `openspec validate --specs`. Result: command exited 0 with `No items found to validate.` + +## 4. Cleanup (mandatory; run before claiming completion) + +- [ ] 4.1 Run the cleanup pipeline: `gx branch finish --branch agent/codex/move-active-agents-to-own-sidebar-icon-2026-04-23-14-13 --base main --via-pr --wait-for-merge --cleanup`. +- [ ] 4.2 Record the PR URL and final merge state (`MERGED`) in the completion handoff. +- [ ] 4.3 Confirm the sandbox worktree is gone (`git worktree list` no longer shows the agent path; `git branch -a` shows no surviving local/remote refs for the branch). diff --git a/templates/vscode/guardex-active-agents/README.md b/templates/vscode/guardex-active-agents/README.md index 9b0c580..dec7f80 100644 --- a/templates/vscode/guardex-active-agents/README.md +++ b/templates/vscode/guardex-active-agents/README.md @@ -4,7 +4,7 @@ Local VS Code companion for Guardex-managed repos. ## Quick Start -Use the welcome view in Source Control to create or inspect Guardex sandboxes quickly. +Use the dedicated Active Agents sidebar icon to create or inspect Guardex sandboxes quickly. 1. Install from a Guardex-wired repo: @@ -13,13 +13,13 @@ node scripts/install-vscode-active-agents-extension.js ``` 2. Reload the VS Code window. -3. In Source Control -> `Active Agents`, use `Start agent` to enter a task + agent name and launch the repo Guardex agent runner. The companion prefers `bash scripts/codex-agent.sh` when present, falls back to `npm run agent:codex --`, and only uses `gx branch start` as a last resort. +3. In the Activity Bar, open the `Active Agents` hive icon under Source Control. Use `Start agent` to enter a task + agent name and launch the repo Guardex agent runner. The companion prefers `bash scripts/codex-agent.sh` when present, falls back to `npm run agent:codex --`, and only uses `gx branch start` as a last resort. What it does: - Bundles a local GitGuardex icon so repo installs show branded extension metadata inside VS Code. - Bundles the optional `GitGuardex File Icons` theme for OpenSpec, agent worktree, and hook files in Explorer. -- Adds an `Active Agents` view to the Source Control container. +- Adds a dedicated `Active Agents` Activity Bar container with a hive icon and live badge count for active sessions. - Renders one repo node per live Guardex workspace with grouped `ACTIVE AGENTS` and `CHANGES` sections. - Splits live sessions inside `ACTIVE AGENTS` into `BLOCKED`, `WORKING NOW`, `THINKING`, `STALLED`, and `DEAD` groups so stuck, active, and inactive lanes stand out immediately. - Mirrors the same live state in the VS Code status bar so the selected session or active-agent count stays visible outside the tree. diff --git a/templates/vscode/guardex-active-agents/extension.js b/templates/vscode/guardex-active-agents/extension.js index 0f9a096..fcd9d29 100644 --- a/templates/vscode/guardex-active-agents/extension.js +++ b/templates/vscode/guardex-active-agents/extension.js @@ -331,7 +331,7 @@ function buildActiveAgentsStatusTooltip(selectedSession, summary) { sessionIdentityLabel(selectedSession), formatCountLabel(selectedSession.lockCount || 0, 'lock'), selectedSession.worktreePath, - 'Click to open Source Control.', + 'Click to open Active Agents.', ].filter(Boolean).join('\n'); } @@ -343,7 +343,7 @@ function buildActiveAgentsStatusTooltip(selectedSession, summary) { formatCountLabel(summary?.unassignedChangeCount || 0, 'unassigned change'), formatCountLabel(summary?.lockedFileCount || 0, 'locked file'), summary?.deadCount ? formatCountLabel(summary.deadCount, 'dead session') : '', - 'Click to open Source Control.', + 'Click to open Active Agents.', ].filter(Boolean).join('\n'); } @@ -2638,7 +2638,7 @@ function activate(context) { vscode.commands.registerCommand('gitguardex.activeAgents.startAgent', () => startAgentFromPrompt(refresh)), vscode.commands.registerCommand('gitguardex.activeAgents.refresh', refresh), vscode.commands.registerCommand('gitguardex.activeAgents.focus', async () => { - await vscode.commands.executeCommand('workbench.view.scm'); + await vscode.commands.executeCommand('workbench.view.extension.gitguardex.activeAgentsContainer'); }), vscode.commands.registerCommand('gitguardex.activeAgents.commitSelectedSession', commitSelectedSession), vscode.commands.registerCommand('gitguardex.activeAgents.openWorktree', async (session) => { diff --git a/templates/vscode/guardex-active-agents/media/active-agents-hivemind.svg b/templates/vscode/guardex-active-agents/media/active-agents-hivemind.svg new file mode 100644 index 0000000..e966b0b --- /dev/null +++ b/templates/vscode/guardex-active-agents/media/active-agents-hivemind.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/templates/vscode/guardex-active-agents/package.json b/templates/vscode/guardex-active-agents/package.json index f9fad4f..2666a83 100644 --- a/templates/vscode/guardex-active-agents/package.json +++ b/templates/vscode/guardex-active-agents/package.json @@ -1,9 +1,9 @@ { "name": "gitguardex-active-agents", "displayName": "GitGuardex Active Agents", - "description": "Shows live Guardex sandbox sessions and repo changes inside VS Code Source Control.", + "description": "Shows live Guardex sandbox sessions and repo changes in a dedicated VS Code Active Agents sidebar.", "publisher": "recodeee", - "version": "0.0.10", + "version": "0.0.11", "license": "MIT", "icon": "icon.png", "engines": { @@ -73,11 +73,22 @@ "icon": "$(diff)" } ], + "viewsContainers": { + "activitybar": [ + { + "id": "gitguardex.activeAgentsContainer", + "title": "Active Agents", + "icon": "media/active-agents-hivemind.svg" + } + ] + }, "views": { - "scm": [ + "gitguardex.activeAgentsContainer": [ { "id": "gitguardex.activeAgents", "name": "Active Agents", + "contextualTitle": "Active Agents", + "icon": "media/active-agents-hivemind.svg", "visibility": "visible" } ] @@ -85,7 +96,7 @@ "viewsWelcome": [ { "view": "gitguardex.activeAgents", - "contents": "No live Guardex agents are visible in this workspace yet.\n\nThis view tracks Guardex session files and managed worktree telemetry, not every repo visible in Source Control.\n\n[Start agent](command:gitguardex.activeAgents.startAgent)\n[Open guide](https://github.com/recodeee/gitguardex/blob/main/vscode/guardex-active-agents/README.md#quick-start)\n[Refresh](command:gitguardex.activeAgents.refresh)" + "contents": "No live Guardex agents are visible in this workspace yet.\n\nThis sidebar tracks Guardex session files and managed worktree telemetry without taking over Source Control.\n\n[Start agent](command:gitguardex.activeAgents.startAgent)\n[Open guide](https://github.com/recodeee/gitguardex/blob/main/vscode/guardex-active-agents/README.md#quick-start)\n[Refresh](command:gitguardex.activeAgents.refresh)" } ], "menus": { diff --git a/test/vscode-active-agents-session-state.test.js b/test/vscode-active-agents-session-state.test.js index 49185fd..6c83f23 100644 --- a/test/vscode-active-agents-session-state.test.js +++ b/test/vscode-active-agents-session-state.test.js @@ -1255,6 +1255,11 @@ test('active-agents extension edits require a higher manifest version than the b templateManifest.contributes.iconThemes, 'Live and template Active Agents icon theme contributions must stay in sync.', ); + assert.deepEqual( + liveManifest.contributes.viewsContainers, + templateManifest.contributes.viewsContainers, + 'Live and template Active Agents view containers must stay in sync.', + ); assert.equal( liveManifest.activationEvents.includes('onStartupFinished'), true, @@ -1269,6 +1274,28 @@ test('active-agents extension edits require a higher manifest version than the b ); }); +test('active-agents manifest uses a dedicated activity bar container with a hive icon', () => { + const manifest = readExtensionManifest(); + const activitybarContainers = manifest.contributes.viewsContainers?.activitybar || []; + const activeAgentsContainer = activitybarContainers.find( + (entry) => entry.id === 'gitguardex.activeAgentsContainer', + ); + assert.ok(activeAgentsContainer, 'Expected the Active Agents activity bar container.'); + assert.equal(activeAgentsContainer.title, 'Active Agents'); + assert.equal(activeAgentsContainer.icon, 'media/active-agents-hivemind.svg'); + + const activeAgentsViews = manifest.contributes.views?.['gitguardex.activeAgentsContainer'] || []; + assert.deepEqual(activeAgentsViews, [ + { + id: 'gitguardex.activeAgents', + name: 'Active Agents', + contextualTitle: 'Active Agents', + icon: 'media/active-agents-hivemind.svg', + visibility: 'visible', + }, + ]); +}); + test('active-agents file icon theme maps Guardex workflow paths and ships referenced assets', () => { const manifest = readExtensionManifest(); const themeContribution = manifest.contributes.iconThemes.find((entry) => entry.id === 'gitguardex-file-icons'); @@ -1407,6 +1434,28 @@ test('active-agents extension registers tree and decoration providers', async () } }); +test('active-agents focus command opens the dedicated sidebar container', async () => { + const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'guardex-vscode-focus-view-')); + const { registrations, vscode } = createMockVscode(tempRoot); + const extension = loadExtensionWithMockVscode(vscode); + const context = { subscriptions: [] }; + + extension.activate(context); + await flushAsyncWork(); + await vscode.commands.executeCommand('gitguardex.activeAgents.focus'); + + assert.equal( + registrations.executedCommands.some((entry) => ( + entry.command === 'workbench.view.extension.gitguardex.activeAgentsContainer' + )), + true, + ); + + for (const subscription of context.subscriptions) { + subscription.dispose?.(); + } +}); + test('active-agents extension self-heals managed repo-scan ignores on activation and workspace changes', async () => { const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'guardex-vscode-scan-ignores-')); const secondRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'guardex-vscode-scan-ignores-second-')); diff --git a/vscode/guardex-active-agents/README.md b/vscode/guardex-active-agents/README.md index 9b0c580..dec7f80 100644 --- a/vscode/guardex-active-agents/README.md +++ b/vscode/guardex-active-agents/README.md @@ -4,7 +4,7 @@ Local VS Code companion for Guardex-managed repos. ## Quick Start -Use the welcome view in Source Control to create or inspect Guardex sandboxes quickly. +Use the dedicated Active Agents sidebar icon to create or inspect Guardex sandboxes quickly. 1. Install from a Guardex-wired repo: @@ -13,13 +13,13 @@ node scripts/install-vscode-active-agents-extension.js ``` 2. Reload the VS Code window. -3. In Source Control -> `Active Agents`, use `Start agent` to enter a task + agent name and launch the repo Guardex agent runner. The companion prefers `bash scripts/codex-agent.sh` when present, falls back to `npm run agent:codex --`, and only uses `gx branch start` as a last resort. +3. In the Activity Bar, open the `Active Agents` hive icon under Source Control. Use `Start agent` to enter a task + agent name and launch the repo Guardex agent runner. The companion prefers `bash scripts/codex-agent.sh` when present, falls back to `npm run agent:codex --`, and only uses `gx branch start` as a last resort. What it does: - Bundles a local GitGuardex icon so repo installs show branded extension metadata inside VS Code. - Bundles the optional `GitGuardex File Icons` theme for OpenSpec, agent worktree, and hook files in Explorer. -- Adds an `Active Agents` view to the Source Control container. +- Adds a dedicated `Active Agents` Activity Bar container with a hive icon and live badge count for active sessions. - Renders one repo node per live Guardex workspace with grouped `ACTIVE AGENTS` and `CHANGES` sections. - Splits live sessions inside `ACTIVE AGENTS` into `BLOCKED`, `WORKING NOW`, `THINKING`, `STALLED`, and `DEAD` groups so stuck, active, and inactive lanes stand out immediately. - Mirrors the same live state in the VS Code status bar so the selected session or active-agent count stays visible outside the tree. diff --git a/vscode/guardex-active-agents/extension.js b/vscode/guardex-active-agents/extension.js index 0f9a096..fcd9d29 100644 --- a/vscode/guardex-active-agents/extension.js +++ b/vscode/guardex-active-agents/extension.js @@ -331,7 +331,7 @@ function buildActiveAgentsStatusTooltip(selectedSession, summary) { sessionIdentityLabel(selectedSession), formatCountLabel(selectedSession.lockCount || 0, 'lock'), selectedSession.worktreePath, - 'Click to open Source Control.', + 'Click to open Active Agents.', ].filter(Boolean).join('\n'); } @@ -343,7 +343,7 @@ function buildActiveAgentsStatusTooltip(selectedSession, summary) { formatCountLabel(summary?.unassignedChangeCount || 0, 'unassigned change'), formatCountLabel(summary?.lockedFileCount || 0, 'locked file'), summary?.deadCount ? formatCountLabel(summary.deadCount, 'dead session') : '', - 'Click to open Source Control.', + 'Click to open Active Agents.', ].filter(Boolean).join('\n'); } @@ -2638,7 +2638,7 @@ function activate(context) { vscode.commands.registerCommand('gitguardex.activeAgents.startAgent', () => startAgentFromPrompt(refresh)), vscode.commands.registerCommand('gitguardex.activeAgents.refresh', refresh), vscode.commands.registerCommand('gitguardex.activeAgents.focus', async () => { - await vscode.commands.executeCommand('workbench.view.scm'); + await vscode.commands.executeCommand('workbench.view.extension.gitguardex.activeAgentsContainer'); }), vscode.commands.registerCommand('gitguardex.activeAgents.commitSelectedSession', commitSelectedSession), vscode.commands.registerCommand('gitguardex.activeAgents.openWorktree', async (session) => { diff --git a/vscode/guardex-active-agents/media/active-agents-hivemind.svg b/vscode/guardex-active-agents/media/active-agents-hivemind.svg new file mode 100644 index 0000000..e966b0b --- /dev/null +++ b/vscode/guardex-active-agents/media/active-agents-hivemind.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/vscode/guardex-active-agents/package.json b/vscode/guardex-active-agents/package.json index f9fad4f..2666a83 100644 --- a/vscode/guardex-active-agents/package.json +++ b/vscode/guardex-active-agents/package.json @@ -1,9 +1,9 @@ { "name": "gitguardex-active-agents", "displayName": "GitGuardex Active Agents", - "description": "Shows live Guardex sandbox sessions and repo changes inside VS Code Source Control.", + "description": "Shows live Guardex sandbox sessions and repo changes in a dedicated VS Code Active Agents sidebar.", "publisher": "recodeee", - "version": "0.0.10", + "version": "0.0.11", "license": "MIT", "icon": "icon.png", "engines": { @@ -73,11 +73,22 @@ "icon": "$(diff)" } ], + "viewsContainers": { + "activitybar": [ + { + "id": "gitguardex.activeAgentsContainer", + "title": "Active Agents", + "icon": "media/active-agents-hivemind.svg" + } + ] + }, "views": { - "scm": [ + "gitguardex.activeAgentsContainer": [ { "id": "gitguardex.activeAgents", "name": "Active Agents", + "contextualTitle": "Active Agents", + "icon": "media/active-agents-hivemind.svg", "visibility": "visible" } ] @@ -85,7 +96,7 @@ "viewsWelcome": [ { "view": "gitguardex.activeAgents", - "contents": "No live Guardex agents are visible in this workspace yet.\n\nThis view tracks Guardex session files and managed worktree telemetry, not every repo visible in Source Control.\n\n[Start agent](command:gitguardex.activeAgents.startAgent)\n[Open guide](https://github.com/recodeee/gitguardex/blob/main/vscode/guardex-active-agents/README.md#quick-start)\n[Refresh](command:gitguardex.activeAgents.refresh)" + "contents": "No live Guardex agents are visible in this workspace yet.\n\nThis sidebar tracks Guardex session files and managed worktree telemetry without taking over Source Control.\n\n[Start agent](command:gitguardex.activeAgents.startAgent)\n[Open guide](https://github.com/recodeee/gitguardex/blob/main/vscode/guardex-active-agents/README.md#quick-start)\n[Refresh](command:gitguardex.activeAgents.refresh)" } ], "menus": {