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
1 change: 0 additions & 1 deletion .ai-devkit.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
"antigravity"
],
"createdAt": "2025-12-28T13:35:45.251Z",
"updatedAt": "2026-06-14T11:53:00.073Z",
"phases": [
"requirements",
"design",
Expand Down
15 changes: 5 additions & 10 deletions e2e/cli.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,7 @@ describe('memory commands', () => {
memory: {
path: '.ai-devkit/memory.db'
},
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
createdAt: new Date().toISOString()
});
});

Expand Down Expand Up @@ -335,8 +334,7 @@ describe('install command', () => {
version: '1.0.0',
environments: ['claude'],
phases: ['requirements', 'design'],
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
createdAt: new Date().toISOString()
});

const result = run('install', { cwd: projectDir });
Expand All @@ -359,8 +357,7 @@ describe('install command', () => {
skills: [
{ registry: 'codeaholicguy/ai-devkit', name: 'dev-lifecycle' }
],
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
createdAt: new Date().toISOString()
});

const result = run('install', { cwd: projectDir });
Expand Down Expand Up @@ -398,8 +395,7 @@ describe('skill command', () => {
skills: [
{ registry: 'codeaholicguy/ai-devkit', name: 'dev-lifecycle' }
],
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
createdAt: new Date().toISOString()
});

// Create the skill directory so the remove command finds it
Expand Down Expand Up @@ -427,8 +423,7 @@ describe('skill command', () => {
{ registry: 'codeaholicguy/ai-devkit', name: 'dev-lifecycle' },
{ registry: 'codeaholicguy/ai-devkit', name: 'memory' }
],
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
createdAt: new Date().toISOString()
});

const skillDir = join(projectDir, '.claude', 'skills', 'dev-lifecycle');
Expand Down
76 changes: 42 additions & 34 deletions packages/cli/src/__tests__/lib/Config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ describe('ConfigManager', () => {
environments: ['cursor' as any],
phases: ['requirements' as any],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand Down Expand Up @@ -123,7 +122,6 @@ describe('ConfigManager', () => {
environments: [],
phases: [],
createdAt: expect.any(String),
updatedAt: expect.any(String)
};

(mockFs.writeJson as any).mockResolvedValue(undefined);
Expand All @@ -136,17 +134,17 @@ describe('ConfigManager', () => {
expectedConfig,
{ spaces: 2 }
);
expect(result).not.toHaveProperty('updatedAt');
});
});

describe('update', () => {
it('should update existing config and set updatedAt', async () => {
it('should update existing config without adding updatedAt', async () => {
const existingConfig: DevKitConfig = {
version: '1.0.0',
environments: ['cursor'],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

const updates = { environments: ['cursor' as any, 'claude' as any] };
Expand All @@ -158,8 +156,47 @@ describe('ConfigManager', () => {
const result = await configManager.update(updates);

expect(result.environments).toEqual(['cursor', 'claude']);
expect(result.updatedAt).not.toBe(existingConfig.updatedAt);
expect(result.createdAt).toBe(existingConfig.createdAt);
expect(result).not.toHaveProperty('updatedAt');
});

it('should not rewrite config when updates are unchanged and updatedAt is absent', async () => {
const existingConfig: DevKitConfig = {
version: '1.0.0',
environments: ['cursor'],
phases: [],
skills: [{ registry: 'codeaholicguy/ai-devkit', name: 'debug' }],
createdAt: '2024-01-01T00:00:00.000Z',
};

(mockFs.pathExists as any).mockResolvedValue(true);
(mockFs.readJson as any).mockResolvedValue(existingConfig);

const result = await configManager.update({
environments: ['cursor'],
skills: [{ registry: 'codeaholicguy/ai-devkit', name: 'debug' }]
});

expect(result).toEqual(existingConfig);
expect(mockFs.writeJson).not.toHaveBeenCalled();
});

it('should not rewrite config when only legacy updatedAt is present and updates are unchanged', async () => {
const existingConfig = {
version: '1.0.0',
environments: ['cursor'],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
(mockFs.readJson as any).mockResolvedValue(existingConfig);

const result = await configManager.update({});

expect(result).toEqual(existingConfig);
expect(mockFs.writeJson).not.toHaveBeenCalled();
});

it('should throw error when config file not found', async () => {
Expand All @@ -178,7 +215,6 @@ describe('ConfigManager', () => {
environments: [],
phases: ['requirements'],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -196,7 +232,6 @@ describe('ConfigManager', () => {
environments: [],
phases: ['requirements'],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -213,7 +248,6 @@ describe('ConfigManager', () => {
version: '1.0.0',
environments: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -233,7 +267,6 @@ describe('ConfigManager', () => {
environments: [],
phases: ['requirements', 'design'],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -250,7 +283,6 @@ describe('ConfigManager', () => {
environments: [],
phases: ['requirements'],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -274,7 +306,6 @@ describe('ConfigManager', () => {
version: '1.0.0',
environments: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -294,7 +325,6 @@ describe('ConfigManager', () => {
environments: [],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -311,7 +341,6 @@ describe('ConfigManager', () => {
environments: [],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -338,7 +367,6 @@ describe('ConfigManager', () => {
environments: [],
phases: ['requirements', 'deployment'],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -355,7 +383,6 @@ describe('ConfigManager', () => {
environments: [],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -374,7 +401,6 @@ describe('ConfigManager', () => {
environments: [],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -395,7 +421,6 @@ describe('ConfigManager', () => {
environments: ['cursor', 'claude'],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -420,7 +445,6 @@ describe('ConfigManager', () => {
environments: [],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -439,7 +463,6 @@ describe('ConfigManager', () => {
environments: ['cursor'],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -460,7 +483,6 @@ describe('ConfigManager', () => {
environments: ['cursor', 'claude'],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -477,7 +499,6 @@ describe('ConfigManager', () => {
environments: ['cursor'],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -497,7 +518,6 @@ describe('ConfigManager', () => {
phases: [],
skills: [{ registry: 'codeaholicguy/ai-devkit', name: 'debug' }],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -523,7 +543,6 @@ describe('ConfigManager', () => {
phases: [],
skills: [{ registry: 'codeaholicguy/ai-devkit', name: 'debug' }],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -544,7 +563,6 @@ describe('ConfigManager', () => {
environments: ['cursor'],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand Down Expand Up @@ -574,7 +592,6 @@ describe('ConfigManager', () => {
{ registry: 'codeaholicguy/ai-devkit', name: 'memory' }
],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -598,7 +615,6 @@ describe('ConfigManager', () => {
{ registry: 'codeaholicguy/ai-devkit', name: 'dev-lifecycle' }
],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand All @@ -620,7 +636,6 @@ describe('ConfigManager', () => {
{ registry: 'codeaholicguy/ai-devkit', name: 'memory' }
],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
};

(mockFs.pathExists as any).mockResolvedValue(true);
Expand Down Expand Up @@ -655,7 +670,6 @@ describe('ConfigManager', () => {
'invalid/value': false
},
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
});

const registries = await configManager.getSkillRegistries();
Expand All @@ -673,7 +687,6 @@ describe('ConfigManager', () => {
phases: [],
skills: [{ registry: 'codeaholicguy/ai-devkit', name: 'debug' }],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
});

const registries = await configManager.getSkillRegistries();
Expand All @@ -698,7 +711,6 @@ describe('ConfigManager', () => {
environments: [],
phases: [],
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
});

const result = await configManager.getMemoryDbPath();
Expand All @@ -714,7 +726,6 @@ describe('ConfigManager', () => {
phases: [],
memory: { path: ' ' },
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
});

await expect(configManager.getMemoryDbPath()).resolves.toBeUndefined();
Expand All @@ -725,7 +736,6 @@ describe('ConfigManager', () => {
phases: [],
memory: { path: 42 },
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
});

await expect(configManager.getMemoryDbPath()).resolves.toBeUndefined();
Expand All @@ -739,7 +749,6 @@ describe('ConfigManager', () => {
phases: [],
memory: { path: '/custom/memory.db' },
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
});

const result = await configManager.getMemoryDbPath();
Expand All @@ -756,7 +765,6 @@ describe('ConfigManager', () => {
phases: [],
memory: { path: '.ai-devkit/project-memory.db' },
createdAt: '2024-01-01T00:00:00.000Z',
updatedAt: '2024-01-01T00:00:00.000Z'
});

const result = await configManager.getMemoryDbPath();
Expand Down
Loading
Loading