Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
5 changes: 3 additions & 2 deletions src/commands/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Command } from 'commander';
import { spawn, execSync } from 'node:child_process';
import { spawn } from 'node:child_process';
import * as fs from 'node:fs';
import * as path from 'node:path';
import {
Expand All @@ -22,6 +22,7 @@ import {
import { CORE_WORKFLOWS, ALL_WORKFLOWS, getProfileWorkflows } from '../core/profiles.js';
import { OPENSPEC_DIR_NAME } from '../core/config.js';
import { hasProjectConfigDrift } from '../core/profile-sync-drift.js';
import { UpdateCommand } from '../core/update.js';
import { isPromptCancellationError } from './shared-output.js';

type ProfileAction = 'both' | 'delivery' | 'workflows' | 'keep';
Expand Down Expand Up @@ -621,7 +622,7 @@ export function registerConfigCommand(program: Command): void {

if (applyNow) {
try {
execSync('npx openspec update', { stdio: 'inherit', cwd: projectDir });
await new UpdateCommand().execute(projectDir);
console.log('Run `openspec update` in your other projects to apply.');
} catch {
console.error('`openspec update` failed. Please run it manually to apply the profile changes.');
Expand Down
23 changes: 8 additions & 15 deletions test/commands/config-profile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,6 @@ import { Command } from 'commander';
import * as fs from 'node:fs';
import * as path from 'node:path';
import * as os from 'node:os';
import { execSync } from 'node:child_process';

vi.mock('node:child_process', async () => {
const actual = await vi.importActual<typeof import('node:child_process')>('node:child_process');
return {
...actual,
execSync: vi.fn(),
};
});

vi.mock('@inquirer/prompts', () => ({
select: vi.fn(),
Expand Down Expand Up @@ -150,7 +141,6 @@ describe('config profile interactive flow', () => {

consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
vi.mocked(execSync).mockReset();
});

afterEach(() => {
Expand Down Expand Up @@ -377,12 +367,15 @@ describe('config profile interactive flow', () => {
});
});

it('confirmed project apply should run openspec update in the project', async () => {
it('confirmed project apply should update in process without resolving openspec from PATH', async () => {
const { saveGlobalConfig, getGlobalConfig } = await import('../../src/core/global-config.js');
const { select, confirm } = await getPromptMocks();

saveGlobalConfig({ featureFlags: {}, profile: 'core', delivery: 'both', workflows: ['propose', 'explore', 'apply', 'update', 'sync', 'archive'] });
fs.mkdirSync(path.join(tempDir, 'openspec'), { recursive: true });
const emptyBinDir = path.join(tempDir, 'empty-bin');
fs.mkdirSync(emptyBinDir);
process.env.PATH = emptyBinDir;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

select.mockResolvedValueOnce('delivery');
select.mockResolvedValueOnce('skills');
Expand All @@ -391,10 +384,10 @@ describe('config profile interactive flow', () => {
await runConfigCommand(['profile']);

expect(getGlobalConfig().delivery).toBe('skills');
expect(execSync).toHaveBeenCalledWith('npx openspec update', {
stdio: 'inherit',
cwd: fs.realpathSync(tempDir),
});
expect(process.exitCode).toBeUndefined();
expect(consoleErrorSpy).not.toHaveBeenCalled();
expect(consoleLogSpy).toHaveBeenCalledWith('No configured tools found.');
expect(consoleLogSpy).toHaveBeenCalledWith('Run `openspec update` in your other projects to apply.');
});

it('core preset should preserve delivery setting', async () => {
Expand Down
Loading