Skip to content

Commit 3b7c87d

Browse files
oalanicolasclaude
andcommitted
fix: resolve ConfigCache.has() stat inflation and hook system errors (#497, #528)
#497: ConfigCache.has() delegated to get(), inflating hit/miss stats. Reimplemented has() to check Map directly without touching metrics. Applied to both core/config/ and infrastructure/scripts/ copies. #528: precompact-session-digest.cjs failed in installed projects because runner path didn't account for node_modules layout. Added path resolution with fallback candidates. Also fixed: - synapse-engine.cjs: replaced process.exit() with process.exitCode for clean stdout flush - hook-runtime.js: create session file on first prompt when loadSession returns null (prevents silent updateSession failures) Updated tests to match new behavior (process.exitCode, createSession export). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ff711c1 commit 3b7c87d

7 files changed

Lines changed: 127 additions & 100 deletions

File tree

.aiox-core/core/config/config-cache.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,16 @@ class ConfigCache {
7272
* @returns {boolean} True if key exists and is valid
7373
*/
7474
has(key) {
75-
return this.get(key) !== null;
75+
if (!this.cache.has(key)) {
76+
return false;
77+
}
78+
const timestamp = this.timestamps.get(key);
79+
if (Date.now() - timestamp > this.ttl) {
80+
this.cache.delete(key);
81+
this.timestamps.delete(key);
82+
return false;
83+
}
84+
return true;
7685
}
7786

7887
/**

.aiox-core/core/synapse/runtime/hook-runtime.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,24 @@ function resolveHookRuntime(input) {
4646
if (!fs.existsSync(synapsePath)) return null;
4747

4848
try {
49-
const { loadSession, cleanStaleSessions } = require(
49+
const { loadSession, createSession, cleanStaleSessions } = require(
5050
path.join(cwd, '.aiox-core', 'core', 'synapse', 'session', 'session-manager.js'),
5151
);
5252
const { SynapseEngine } = require(
5353
path.join(cwd, '.aiox-core', 'core', 'synapse', 'engine.js'),
5454
);
5555

5656
const sessionsDir = path.join(synapsePath, 'sessions');
57-
const session = loadSession(sessionId, sessionsDir) || { prompt_count: 0 };
57+
58+
// Create session file on first prompt if it doesn't exist.
59+
// Without this, updateSession() silently fails because loadSession() returns null.
60+
let session = loadSession(sessionId, sessionsDir);
61+
if (!session && sessionId) {
62+
session = createSession(sessionId, cwd, sessionsDir);
63+
}
64+
if (!session) {
65+
session = { prompt_count: 0 };
66+
}
5867
const engine = new SynapseEngine(synapsePath);
5968

6069
// AC3: Run cleanup on first prompt only (fire-and-forget)

.aiox-core/infrastructure/scripts/config-cache.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,16 @@ class ConfigCache {
7171
* @returns {boolean} True if key exists and is valid
7272
*/
7373
has(key) {
74-
return this.get(key) !== null;
74+
if (!this.cache.has(key)) {
75+
return false;
76+
}
77+
const timestamp = this.timestamps.get(key);
78+
if (Date.now() - timestamp > this.ttl) {
79+
this.cache.delete(key);
80+
this.timestamps.delete(key);
81+
return false;
82+
}
83+
return true;
7584
}
7685

7786
/**

0 commit comments

Comments
 (0)