mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-03 14:09:42 +02:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82fe3cf684 | ||
|
|
499d35566b |
@@ -793,8 +793,12 @@ export function registerSessionRoutes(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hooks for the workspace this session runs in (install vs refresh-only is the
|
// Hooks for the workspace this session runs in (install vs refresh-only is the
|
||||||
// `workspaceHooksEnabled` setting; see applyWorkspaceHooks).
|
// `workspaceHooksEnabled` setting; see applyWorkspaceHooks). Never for a remote
|
||||||
if ((body.mode ?? 'claude') === 'claude') {
|
// attach (workingDir is a user@host:session pseudo-path — mkdir would create it
|
||||||
|
// as a junk local dir), and only when the caller named a workingDir: the
|
||||||
|
// process-cwd fallback is $HOME under installer-created services, and hooks
|
||||||
|
// materializing in ~/.claude/settings.local.json was never asked for.
|
||||||
|
if (!remote && body.workingDir && (body.mode ?? 'claude') === 'claude') {
|
||||||
await applyWorkspaceHooks(ctx, workingDir);
|
await applyWorkspaceHooks(ctx, workingDir);
|
||||||
// Agent skill (docs/agent-control-plan.md §2): ADD-ONLY on create, same shared-
|
// Agent skill (docs/agent-control-plan.md §2): ADD-ONLY on create, same shared-
|
||||||
// .claude rationale as the statusLine above: a create must never remove the
|
// .claude rationale as the statusLine above: a create must never remove the
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import { createMockRouteContext } from '../mocks/index.js';
|
|||||||
import { installRouteErrorHandler } from '../../src/web/route-error-handler.js';
|
import { installRouteErrorHandler } from '../../src/web/route-error-handler.js';
|
||||||
import { registerSessionRoutes } from '../../src/web/routes/session-routes.js';
|
import { registerSessionRoutes } from '../../src/web/routes/session-routes.js';
|
||||||
import { generateHooksConfig } from '../../src/hooks-config.js';
|
import { generateHooksConfig } from '../../src/hooks-config.js';
|
||||||
|
import { getDataDir } from '../../src/config/instance.js';
|
||||||
|
|
||||||
interface HooksFile {
|
interface HooksFile {
|
||||||
hooks?: Record<string, Array<{ matcher?: string; hooks?: Array<{ command?: string }> }>>;
|
hooks?: Record<string, Array<{ matcher?: string; hooks?: Array<{ command?: string }> }>>;
|
||||||
@@ -138,6 +139,37 @@ describe('POST /api/sessions workspace hooks', () => {
|
|||||||
expect(existsSync(settingsPath())).toBe(false);
|
expect(existsSync(settingsPath())).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('leaves the server cwd alone when workingDir is omitted', async () => {
|
||||||
|
// workingDir falls back to process.cwd(), which is $HOME under installer-created
|
||||||
|
// services — hooks must not materialize in ~/.claude/settings.local.json.
|
||||||
|
const cwdSettings = join(process.cwd(), '.claude', 'settings.local.json');
|
||||||
|
const before = existsSync(cwdSettings) ? await readFile(cwdSettings, 'utf-8') : null;
|
||||||
|
|
||||||
|
expect((await createSession({ name: 'hooks-no-dir', mode: 'claude' })).statusCode).toBe(200);
|
||||||
|
|
||||||
|
const after = existsSync(cwdSettings) ? await readFile(cwdSettings, 'utf-8') : null;
|
||||||
|
expect(after).toBe(before);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('never writes hooks for a remote attach (workingDir is a user@host pseudo-path)', async () => {
|
||||||
|
// A claude-mode attachRemoteSession create overwrites workingDir with
|
||||||
|
// `user@host:session` — locally a RELATIVE path, so a mkdir would create it
|
||||||
|
// as a junk directory under the server cwd.
|
||||||
|
await mkdir(getDataDir(), { recursive: true });
|
||||||
|
await writeFile(
|
||||||
|
join(getDataDir(), 'remote-hosts.json'),
|
||||||
|
JSON.stringify([{ id: 'h1', label: 'box', host: '10.0.0.5', username: 'dev' }])
|
||||||
|
);
|
||||||
|
|
||||||
|
const res = await createSession({
|
||||||
|
name: 'hooks-remote',
|
||||||
|
mode: 'claude',
|
||||||
|
attachRemoteSession: { hostId: 'h1', remoteSessionName: 'codeman-ssh-abc123' },
|
||||||
|
});
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
expect(existsSync(join(process.cwd(), 'dev@10.0.0.5:codeman-ssh-abc123'))).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
it('leaves a malformed settings file untouched rather than replacing it', async () => {
|
it('leaves a malformed settings file untouched rather than replacing it', async () => {
|
||||||
await mkdir(join(workingDir, '.claude'), { recursive: true });
|
await mkdir(join(workingDir, '.claude'), { recursive: true });
|
||||||
await writeFile(settingsPath(), '{ not json');
|
await writeFile(settingsPath(), '{ not json');
|
||||||
|
|||||||
Reference in New Issue
Block a user