feat(targets): support CCS_DROID_ALIASES argv0 mapping

- extend argv[0] target resolution with env-configurable aliases

- normalize alias matching to lowercase with safe-name filtering

- add tests for custom aliases, invalid entries, and case-insensitivity
This commit is contained in:
Tam Nhu Tran
2026-02-17 20:53:03 +07:00
parent 15d6c06dbc
commit 025218a706
2 changed files with 46 additions and 2 deletions
+22 -2
View File
@@ -18,6 +18,25 @@ import { TargetType } from './target-adapter';
const ARGV0_TARGET_MAP: Record<string, TargetType> = {
ccsd: 'droid',
};
const ALIAS_NAME_REGEX = /^[a-z0-9._-]+$/;
function buildArgv0TargetMap(): Record<string, TargetType> {
const map: Record<string, TargetType> = { ...ARGV0_TARGET_MAP };
const envAliases = process.env['CCS_DROID_ALIASES'];
if (!envAliases) {
return map;
}
for (const rawAlias of envAliases.split(',')) {
const alias = rawAlias.trim().toLowerCase();
if (!alias || !ALIAS_NAME_REGEX.test(alias)) {
continue;
}
map[alias] = 'droid';
}
return map;
}
/**
* Valid target types for --target flag validation.
@@ -108,8 +127,9 @@ export function resolveTargetType(
// 3. Check argv[0] (busybox pattern)
// Strip common wrapper extensions for Windows shims/wrappers
const rawBin = path.basename(process.argv[1] || process.argv0 || '');
const binName = rawBin.replace(/\.(cmd|bat|ps1|exe)$/i, '');
const argv0Target = ARGV0_TARGET_MAP[binName];
const binName = rawBin.replace(/\.(cmd|bat|ps1|exe)$/i, '').toLowerCase();
const argv0TargetMap = buildArgv0TargetMap();
const argv0Target = argv0TargetMap[binName];
if (argv0Target) {
return argv0Target;
}
@@ -6,9 +6,15 @@ import { resolveTargetType, stripTargetFlag } from '../../../src/targets/target-
describe('resolveTargetType', () => {
const originalArgv = process.argv;
const originalDroidAliases = process.env.CCS_DROID_ALIASES;
afterEach(() => {
process.argv = originalArgv;
if (originalDroidAliases === undefined) {
delete process.env.CCS_DROID_ALIASES;
} else {
process.env.CCS_DROID_ALIASES = originalDroidAliases;
}
});
it('should return claude as default', () => {
@@ -41,6 +47,24 @@ describe('resolveTargetType', () => {
expect(resolveTargetType([])).toBe('droid');
});
it('should detect custom argv[0] aliases from CCS_DROID_ALIASES', () => {
process.env.CCS_DROID_ALIASES = 'droidx,my-droid';
process.argv = ['node', 'my-droid'];
expect(resolveTargetType([])).toBe('droid');
});
it('should ignore invalid custom alias entries', () => {
process.env.CCS_DROID_ALIASES = 'valid_alias,../bad,';
process.argv = ['node', '../bad'];
expect(resolveTargetType([])).toBe('claude');
});
it('should normalize argv[0] and custom aliases case-insensitively', () => {
process.env.CCS_DROID_ALIASES = 'DroidCaps';
process.argv = ['node', 'DROIDCAPS'];
expect(resolveTargetType([])).toBe('droid');
});
it('should strip .cmd extension on Windows argv[0]', () => {
process.argv = ['node', 'ccsd.cmd'];
expect(resolveTargetType([])).toBe('droid');