mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-04 22:49:41 +02:00
review fixes: every claude create path routes through the workspace-hooks decision
Post-#304 follow-ups. The install-vs-refresh decision (workspaceHooksEnabled, default ON) moved from a session-routes-local helper into hooks-config.ts as applyWorkspaceHooks(workspace, install?), and the claude session-create sites that bypassed it now go through it: cron job fires (cron-service), legacy scheduled-run iterations (runScheduledLoop), and the plan-orchestrator research and planner one-shots. A cron or scheduled run firing in a linked case that never had an interactive session ran hook-blind (no stop for completion detection, no tab alert on a blocking dialog). The shared core also carries the two guards every caller needs: a workspace that no longer exists is skipped (ensureCodemanHooks mkdir -p's, so the boot recovery sweep used to resurrect a deleted repo as an empty tree holding only .claude/settings.local.json), and all errors are swallowed since a create must never fail on hooks. Route handlers keep resolving the setting through their ConfigPort and pass it in; non-route callers omit it and the core reads settings.json itself (absent key or unreadable file = ON). Two adjacent gates tightened in session-routes: - the docker quick-start hooks branch excluded the five external CLIs but let `shell` through, contradicting its own rule that only claude reads .claude hooks; it is now gated on mode === 'claude' - the statusLine exporter call in POST /api/sessions got the same !remote && body.workingDir guard the hooks call got in499d355(it mkdirs the same way, so a remote attach created a junk user@host:session dir locally and a cwd-fallback create wrote into $HOME) plan-routes' one-shot deliberately stays out: its workingDir is process.cwd(), exactly the target499d355forbids writing into. restoreMuxSessions stays out too: the boot sweep already covers recovered workspaces. Tests: quick-start existing-case install, docker claude-installs/shell-does-not, and the core directly (default-ON install, OFF add-nothing, OFF still heals a stale block, malformed file untouched, vanished workspace skipped); the remote and cwd-fallback regressions now also send statusLineTelemetry:true to pin the statusLine guard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ import { v4 as uuidv4 } from 'uuid';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { statSync, realpathSync } from 'node:fs';
|
||||
import { Session } from '../session.js';
|
||||
import { applyWorkspaceHooks } from '../hooks-config.js';
|
||||
import { SseEvent } from '../web/sse-events.js';
|
||||
import { CronJobSchema } from '../web/schemas.js';
|
||||
import { getErrorMessage, createErrorResponse, ApiErrorCode } from '../types/api.js';
|
||||
@@ -401,6 +402,15 @@ export class CronService {
|
||||
// clampCronExternalCliConfigs — cron sends no per-CLI config, so the CLI's own
|
||||
// spawn default is what would otherwise apply).
|
||||
const { geminiConfig, piConfig } = clampCronExternalCliConfigs(mode, ownerGranted);
|
||||
// Workspace hooks (see applyWorkspaceHooks in hooks-config): cron jobs are
|
||||
// always local (workingDir was stat-validated above) but used to bypass the
|
||||
// shared install-vs-refresh decision, so a job firing in a linked case that
|
||||
// never had an interactive session ran hook-blind — no `stop` for the
|
||||
// completion detection, no tab alert on a blocking dialog. Claude mode only
|
||||
// (nothing else reads `.claude` hooks); best-effort inside the helper.
|
||||
if (mode === 'claude') {
|
||||
await applyWorkspaceHooks(job.workingDir);
|
||||
}
|
||||
session = new Session({
|
||||
workingDir: job.workingDir,
|
||||
mode,
|
||||
|
||||
Reference in New Issue
Block a user