Skip to content
Open
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
6 changes: 5 additions & 1 deletion src/core/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -700,8 +700,12 @@ export class InitCommand {
const globalCfg = getGlobalConfig();
const activeProfile: Profile = (this.profileOverride as Profile) ?? globalCfg.profile ?? 'core';
const activeWorkflows = [...getProfileWorkflows(activeProfile, globalCfg.workflows)];
const hasConfiguredTools = results.createdTools.length > 0 || results.refreshedTools.length > 0;
console.log();
if (activeWorkflows.includes('propose')) {
if (!hasConfiguredTools) {
console.log('OpenSpec structure created, but no agent integrations were installed.');
console.log(' Install integrations later with: openspec init --tools <tool>');
} else if (activeWorkflows.includes('propose')) {
console.log(chalk.bold('Getting started:'));
console.log(' Start your first change: /opsx:propose "your idea"');
} else if (activeWorkflows.includes('new')) {
Expand Down
4 changes: 4 additions & 0 deletions test/cli-e2e/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ describe('openspec CLI e2e basics', () => {
expect(result.exitCode).toBe(0);
expect(result.stdout).toContain('OpenSpec Setup Complete');
expect(result.stdout).toContain('Claude Code');
expect(result.stdout).toContain('/opsx:propose');

// New init creates skills, not CLAUDE.md
const claudeSkillPath = path.join(emptyProjectDir, '.claude/skills/openspec-explore/SKILL.md');
Expand All @@ -172,6 +173,9 @@ describe('openspec CLI e2e basics', () => {
const result = await runCLI(['init', '--tools', 'none'], { cwd: emptyProjectDir });
expect(result.exitCode).toBe(0);
expect(result.stdout).toContain('OpenSpec Setup Complete');
expect(result.stdout).toContain('no agent integrations were installed');
expect(result.stdout).toContain('openspec init --tools <tool>');
expect(result.stdout).not.toContain('/opsx:propose');

// With --tools none, no tool skills should be created
const claudeSkillPath = path.join(emptyProjectDir, '.claude/skills/openspec-explore/SKILL.md');
Expand Down
5 changes: 5 additions & 0 deletions test/core/init.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ describe('InitCommand', () => {
// No tool-specific directories should be created
const claudeSkillsDir = path.join(testDir, '.claude', 'skills');
expect(await directoryExists(claudeSkillsDir)).toBe(false);

const logCalls = (console.log as unknown as { mock: { calls: unknown[][] } }).mock.calls.flat().map(String);
expect(logCalls.some((entry) => entry.includes('no agent integrations were installed'))).toBe(true);
expect(logCalls.some((entry) => entry.includes('openspec init --tools <tool>'))).toBe(true);
expect(logCalls.some((entry) => entry.includes('/opsx:propose'))).toBe(false);
});

it('should throw error for invalid tool names', async () => {
Expand Down