mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 18:39:33 +01:00
fix: apply the review items for #719 at merge
- src/web/settings-writer.ts:110: export assertSettingsWritable(), the writer's own read-for-write rule run on its own - src/web/routes/case-routes.ts:1860: an admin's rename checks settings.json before it ends any session or moves the folder, and answers 409 CONFLICT with the writer's message (placed before the session-starting check, so nothing is awaited between it and the lock) - test/routes/case-rename-routes.test.ts:314: the torn-file pin now expects 409 CONFLICT (no stoppedSessions, like the other pre-checks) - test/routes/case-rename-routes.test.ts:331: new test, a live session with stopSessions and a torn file: 409 CONFLICT, cleanupSession not called - docs/api-reference.md: the Settings paragraph says an admin's rename answers this refusal as 409 CONFLICT before ending sessions - src/hooks-config.ts:1161, src/prompt-cache-keepwarm.ts:341: comments describe the atomic writer, not an in-place rewrite Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8fa5b340c1
commit
8574e3c880
6 files changed
+57
-10
No files matched your search
@@ -317,18 +317,35 @@ describe('POST /api/cases/:name/rename (a linked case)', () => {
|
||||
const torn = '{\n "agentSkillEnabled": true\n}tail"\n}';
|
||||
writeFileSync(SETTINGS_PATH, torn);
|
||||
const res = await rename(app, 'alpha', { newName: 'beta' });
|
||||
expect(res.statusCode).toBe(500);
|
||||
expect(res.statusCode).toBe(409);
|
||||
expect(res.json()).toEqual({
|
||||
success: false,
|
||||
errorCode: 'OPERATION_FAILED',
|
||||
errorCode: 'CONFLICT',
|
||||
error: `${SETTINGS_PATH} is not a valid JSON object, so this change was not saved (saving would have replaced every other setting in it). Fix or delete the file, or restore it from a config backup, then try again.`,
|
||||
stoppedSessions: 0,
|
||||
});
|
||||
expect(existsSync(oldDir)).toBe(true);
|
||||
expect(existsSync(join(CASES_DIR(), 'beta'))).toBe(false);
|
||||
expect(readFileSync(SETTINGS_PATH, 'utf8')).toBe(torn);
|
||||
});
|
||||
|
||||
it('checks settings.json before it stops any session, so none is ended for a rename that cannot complete', async () => {
|
||||
const { app, ctx } = await createRouteTestHarness(registerCaseRoutes);
|
||||
const oldDir = localCase('alpha');
|
||||
const torn = '{\n "agentSkillEnabled": true\n}tail"\n}';
|
||||
writeFileSync(SETTINGS_PATH, torn);
|
||||
(ctx.sessions as Map<string, unknown>).set('s1', { id: 's1', name: 'w1', workingDir: oldDir });
|
||||
|
||||
const res = await rename(app, 'alpha', { newName: 'beta', stopSessions: true });
|
||||
|
||||
expect(res.statusCode).toBe(409);
|
||||
expect(res.json().errorCode).toBe('CONFLICT');
|
||||
expect(res.json().error).toContain('is not a valid JSON object');
|
||||
expect(ctx.cleanupSession).not.toHaveBeenCalled();
|
||||
expect(existsSync(oldDir)).toBe(true);
|
||||
expect(existsSync(join(CASES_DIR(), 'beta'))).toBe(false);
|
||||
expect(readFileSync(SETTINGS_PATH, 'utf8')).toBe(torn);
|
||||
});
|
||||
|
||||
it('says where the folder is when it cannot be moved back', async () => {
|
||||
const { app } = await createRouteTestHarness(registerCaseRoutes);
|
||||
const real = join(work, 'my-project');
|
||||
|
||||
Reference in new issue
Block a user