feat(cli): add init command with agent instruction generation
This commit is contained in:
parent
830e7af0c7
commit
cd6add215d
41
src/cli/commands/init.ts
Normal file
41
src/cli/commands/init.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { mkdirSync, writeFileSync } from 'fs';
|
||||||
|
import { join } from 'path';
|
||||||
|
import { getAgentHubDir } from '../../core/paths.js';
|
||||||
|
import { saveConfig, defaultConfig } from '../../core/config.js';
|
||||||
|
import { agentsMd, claudeMd, codexMd, kimiMd } from '../../core/templates.js';
|
||||||
|
import { askProjectName, askAgents, askDelegationMode } from '../prompts.js';
|
||||||
|
|
||||||
|
export async function init(cwd: string, options: { projectName?: string; yes?: boolean }): Promise<void> {
|
||||||
|
const projectName = options.projectName ?? (options.yes ? getDefaultProjectName(cwd) : await askProjectName(getDefaultProjectName(cwd)));
|
||||||
|
|
||||||
|
const { claude, codex, kimi } = options.yes
|
||||||
|
? { claude: true, codex: true, kimi: true }
|
||||||
|
: await askAgents();
|
||||||
|
|
||||||
|
const mode = options.yes ? 'suggest' : await askDelegationMode();
|
||||||
|
|
||||||
|
const config = defaultConfig(projectName);
|
||||||
|
config.delegationMode = mode;
|
||||||
|
|
||||||
|
const dir = getAgentHubDir(cwd);
|
||||||
|
mkdirSync(join(dir, 'tasks'), { recursive: true });
|
||||||
|
mkdirSync(join(dir, 'handoffs'), { recursive: true });
|
||||||
|
mkdirSync(join(dir, 'decisions'), { recursive: true });
|
||||||
|
mkdirSync(join(dir, 'memory'), { recursive: true });
|
||||||
|
mkdirSync(join(dir, 'status'), { recursive: true });
|
||||||
|
|
||||||
|
saveConfig(cwd, config);
|
||||||
|
|
||||||
|
writeFileSync(join(cwd, 'AGENTS.md'), agentsMd(projectName), 'utf-8');
|
||||||
|
if (claude) writeFileSync(join(cwd, 'CLAUDE.md'), claudeMd(), 'utf-8');
|
||||||
|
if (codex) writeFileSync(join(cwd, 'CODEX.md'), codexMd(), 'utf-8');
|
||||||
|
if (kimi) writeFileSync(join(cwd, 'KIMI.md'), kimiMd(), 'utf-8');
|
||||||
|
|
||||||
|
console.log(`AgentHub initialized for "${projectName}".`);
|
||||||
|
console.log('Run `agenthub status` to see the current project state.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultProjectName(cwd: string): string {
|
||||||
|
const parts = cwd.split(/[/\\]/);
|
||||||
|
return parts[parts.length - 1] || 'project';
|
||||||
|
}
|
||||||
24
src/cli/prompts.ts
Normal file
24
src/cli/prompts.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { input, confirm, select } from '@inquirer/prompts';
|
||||||
|
|
||||||
|
export async function askProjectName(defaultName: string): Promise<string> {
|
||||||
|
return input({ message: 'Project name:', default: defaultName });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function askAgents(): Promise<{ claude: boolean; codex: boolean; kimi: boolean }> {
|
||||||
|
const claude = await confirm({ message: 'Support Claude Code?', default: true });
|
||||||
|
const codex = await confirm({ message: 'Support Codex CLI?', default: true });
|
||||||
|
const kimi = await confirm({ message: 'Support Kimi Code CLI?', default: true });
|
||||||
|
return { claude, codex, kimi };
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function askDelegationMode(): Promise<'manual' | 'suggest' | 'auto'> {
|
||||||
|
return select({
|
||||||
|
message: 'Default delegation mode:',
|
||||||
|
choices: [
|
||||||
|
{ name: 'suggest', value: 'suggest' },
|
||||||
|
{ name: 'manual', value: 'manual' },
|
||||||
|
{ name: 'auto', value: 'auto' },
|
||||||
|
],
|
||||||
|
default: 'suggest',
|
||||||
|
});
|
||||||
|
}
|
||||||
24
tests/cli-init.test.ts
Normal file
24
tests/cli-init.test.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||||
|
import { mkdtempSync, rmSync, existsSync } from 'fs';
|
||||||
|
import { tmpdir } from 'os';
|
||||||
|
import { join } from 'path';
|
||||||
|
import { init } from '../src/cli/commands/init.js';
|
||||||
|
|
||||||
|
describe('cli init', () => {
|
||||||
|
let cwd: string;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cwd = mkdtempSync(join(tmpdir(), 'agenthub-'));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
rmSync(cwd, { recursive: true, force: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('initializes project with --yes', async () => {
|
||||||
|
await init(cwd, { yes: true, projectName: 'test-proj' });
|
||||||
|
expect(existsSync(join(cwd, '.agenthub', 'agenthub.config.json'))).toBe(true);
|
||||||
|
expect(existsSync(join(cwd, 'AGENTS.md'))).toBe(true);
|
||||||
|
expect(existsSync(join(cwd, 'CLAUDE.md'))).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user