Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,13 @@ describe('auth/login', () => {
- Types: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`
- Keep commits atomic and focused

### Blind Review

- After implementation, send the full diff to two independent reviewers. Give them only the requirements, acceptance criteria, and task boundaries; do not reveal the implementation intent or the other reviewer's findings.
- Fix confirmed issues with scoped changes, then repeat the two independent reviews.
- Once reviews converge and only small corrections remain, use one blind reviewer.
- If review and fixes stop converging, pause patching and reconsider the design as a whole. Stop and report the unresolved issue if redesign does not resolve it.

## Project Structure

```
Expand Down
6 changes: 6 additions & 0 deletions src/agent/availability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,9 @@ export function detectAgentsOnPath(env: NodeJS.ProcessEnv = process.env): Set<Ag
})),
)));
}

export function detectAvailableAgents(env: NodeJS.ProcessEnv = process.env): Set<AgentId> {
const agents = detectAgentsOnPath(env);
if (env.CODEX_THREAD_ID?.trim()) agents.add('codex');
return agents;
}
4 changes: 2 additions & 2 deletions src/commands/agent/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
prepareAgentConfigurations,
withAgentSetupLock,
} from '../../agent/configurator';
import { detectAgentsOnPath } from '../../agent/availability';
import { detectAvailableAgents } from '../../agent/availability';
import {
getAgentInstallCommand,
getAgentInstallIssue,
Expand Down Expand Up @@ -412,7 +412,7 @@ export default defineCommand({
'mmx agent setup --agent opencode --api-key <key> --region cn --dry-run',
],
async run(config: Config, flags: GlobalFlags) {
const detectedAgents = detectAgentsOnPath();
const detectedAgents = detectAvailableAgents();
const interactive = isInteractiveInvocation(flags);
const options = interactive
? await interactiveOptions(config, detectedAgents)
Expand Down
24 changes: 23 additions & 1 deletion test/agent/availability.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { chmodSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';

import { detectAgentsOnPath } from '../../src/agent/availability';
import { detectAgentsOnPath, detectAvailableAgents } from '../../src/agent/availability';

describe('agent availability', () => {
const roots: string[] = [];
Expand Down Expand Up @@ -60,4 +60,26 @@ describe('agent availability', () => {

expect(detectAgentsOnPath({ Path: root })).toEqual(new Set());
});

it('recognizes the active Codex runtime without a Codex executable on PATH', () => {
expect(detectAvailableAgents({ CODEX_THREAD_ID: 'thread-id' })).toEqual(new Set(['codex']));
});

it('keeps PATH detection when recognizing the active Codex runtime', () => {
const root = executableDirectory('pi');
expect(detectAvailableAgents({
PATH: root,
PATHEXT: '.COM;.EXE;.BAT;.CMD',
CODEX_THREAD_ID: 'thread-id',
})).toEqual(new Set(['codex', 'pi']));
});

it('does not recognize a Codex runtime when its marker is missing', () => {
expect(detectAvailableAgents({})).toEqual(new Set());
});

it('ignores empty and whitespace-only Codex runtime markers', () => {
expect(detectAvailableAgents({ CODEX_THREAD_ID: '' })).toEqual(new Set());
expect(detectAvailableAgents({ CODEX_THREAD_ID: ' ' })).toEqual(new Set());
});
});
Loading