mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-07 17:09:13 -10:00
fix(app-server): keep the hook log beside the state db, not in the cwd
With no config path, the app-server's JSONL hook sink fell back to the relative path `.deepseek/events.jsonl`, so `app-server` started from a project wrote a `.deepseek/` directory into that project. The state db in the same setup already resolves to the Codewhale home. Put the hook log in the state db's directory in both cases. With a config path that is the config's directory, as before; without one it is wherever the state store resolved, honouring $CODEWHALE_HOME. The `legacy_deepseek_compat::default_events_log_path` shim has no callers left and goes. Refs #6513 Signed-off-by: Lstarsky0 <[email protected]>
This commit is contained in:
1 parent
9524531de7
commit
855925bddb
1 file changed
+62
-12
@@ -56,16 +56,8 @@ mod daemon_windows;
|
||||
/// coordinated migration touches exactly one place (repo policy: preserve
|
||||
/// legacy migration care).
|
||||
mod legacy_deepseek_compat {
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Service name advertised by the HTTP and stdio health probes.
|
||||
pub(crate) const SERVICE_NAME: &str = "deepseek-app-server";
|
||||
|
||||
/// Fallback hook-event log location used when no config path is
|
||||
/// provided (legacy `.deepseek/` dot-directory layout).
|
||||
pub(crate) fn default_events_log_path() -> PathBuf {
|
||||
PathBuf::from(".deepseek/events.jsonl")
|
||||
}
|
||||
}
|
||||
|
||||
/// Upper bound on JSON request bodies accepted by the HTTP app-server.
|
||||
@@ -1259,10 +1251,14 @@ fn build_state_with_transport(
|
||||
if transport == AppTransport::Http {
|
||||
hooks.add_sink(Arc::new(StdoutHookSink));
|
||||
}
|
||||
let hook_log_path = config_path
|
||||
.as_ref()
|
||||
.and_then(|p| p.parent().map(|parent| parent.join("events.jsonl")))
|
||||
.unwrap_or_else(legacy_deepseek_compat::default_events_log_path);
|
||||
// The hook log sits beside the state database: next to an explicit
|
||||
// config, otherwise in the directory the state store resolved under the
|
||||
// Codewhale home. Never relative to the process cwd (#6513).
|
||||
let hook_log_path = state_store
|
||||
.db_path()
|
||||
.parent()
|
||||
.unwrap_or_else(|| Path::new("."))
|
||||
.join("events.jsonl");
|
||||
hooks.add_sink(Arc::new(JsonlHookSink::new(hook_log_path)));
|
||||
|
||||
if let Some(socket_path) = config
|
||||
@@ -3688,6 +3684,60 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
// Points CODEWHALE_HOME at a temp dir for one test and restores it after.
|
||||
// The variable is process-global, so these tests hold a lock.
|
||||
static CODEWHALE_HOME_TEST_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
|
||||
|
||||
struct CodewhaleHomeGuard {
|
||||
prior: Option<std::ffi::OsString>,
|
||||
_lock: std::sync::MutexGuard<'static, ()>,
|
||||
}
|
||||
|
||||
impl CodewhaleHomeGuard {
|
||||
fn set(value: &Path) -> Self {
|
||||
let lock = CODEWHALE_HOME_TEST_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
||||
let prior = std::env::var_os("CODEWHALE_HOME");
|
||||
// SAFETY: serialised by CODEWHALE_HOME_TEST_LOCK.
|
||||
unsafe { std::env::set_var("CODEWHALE_HOME", value) };
|
||||
Self { prior, _lock: lock }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for CodewhaleHomeGuard {
|
||||
fn drop(&mut self) {
|
||||
// SAFETY: serialised by CODEWHALE_HOME_TEST_LOCK.
|
||||
unsafe {
|
||||
match &self.prior {
|
||||
Some(value) => std::env::set_var("CODEWHALE_HOME", value),
|
||||
None => std::env::remove_var("CODEWHALE_HOME"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn hook_log_without_config_path_goes_beside_state_db_not_cwd() {
|
||||
let home = tempfile::tempdir().expect("tempdir");
|
||||
let _home = CodewhaleHomeGuard::set(home.path());
|
||||
|
||||
let state = build_state_with_transport(None, None, AppTransport::Stdio).expect("state");
|
||||
state
|
||||
.runtime
|
||||
.read()
|
||||
.await
|
||||
.hooks
|
||||
.emit(codewhale_hooks::HookEvent::ResponseStart {
|
||||
response_id: "resp-6513".to_string(),
|
||||
})
|
||||
.await;
|
||||
|
||||
let log = fs::read_to_string(home.path().join("events.jsonl"))
|
||||
.expect("hook log beside state.db in CODEWHALE_HOME");
|
||||
assert!(log.contains("resp-6513"), "{log}");
|
||||
}
|
||||
|
||||
async fn response_body_json(response: Response) -> Value {
|
||||
let bytes = to_bytes(response.into_body(), usize::MAX)
|
||||
.await
|
||||
|
||||
Reference in new issue
Block a user