Files
kochetkov-ma__claude-brewcode/.codex/plugins/brewcode/hooks/lib/prompt-cadence.mjs
T
kochetkov-ma ea944a32fe v4.1.0: add /brewdoc:docsync doc-staleness tracker, remove auto-sync
- New /brewdoc:docsync skill: user-run generator installs project-local hooks
  (track/watch/gate) + config; tracks stale docs by last_updated date; modes
  init/status/sync/reread/frontmatter/uninstall; confirm-before-sync gate
- Removed auto-sync skill, bd-auto-sync-processor agent, auto-sync:* frontmatter
  tags (~44 files), and skill-creator template injection
- Docs updated at all levels (README, MDX, navigation, guide catalog, CLAUDE.md)
2026-07-19 13:16:50 +01:00

69 lines
2.1 KiB
JavaScript

import { createHash } from 'node:crypto';
import { appendFileSync, chmodSync, mkdirSync, readdirSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
import os from 'node:os';
import path from 'node:path';
const STATE_DIR = process.env.CODEX_BREWCODE_HOOK_STATE_DIR
|| process.env.PLUGIN_DATA
|| path.join(os.tmpdir(), 'codex-brewcode-hooks');
const PROMPT_INTERVAL = 5;
const STALE_MS = 24 * 60 * 60 * 1000;
export const PROMPT_CONTEXT = [
'[SKILL?] Check the available Codex skills and invoke every matching skill before acting.',
'[HINT] Use Codex sub-agent collaboration for substantial independent work.',
'[ROLE] Coordinate specialized work when delegation is requested; keep simple tasks direct.'
].join('\n');
function sessionKey(sessionId) {
if (typeof sessionId !== 'string' || !sessionId || sessionId.length > 4096) return null;
return createHash('sha256').update(sessionId, 'utf8').digest('hex');
}
function ensureStateDir() {
mkdirSync(STATE_DIR, { recursive: true, mode: 0o700 });
chmodSync(STATE_DIR, 0o700);
}
function counterPath(key) {
return path.join(STATE_DIR, `${key}.counter`);
}
function pruneStaleCounters() {
const cutoff = Date.now() - STALE_MS;
for (const name of readdirSync(STATE_DIR)) {
if (!name.endsWith('.counter')) continue;
const file = path.join(STATE_DIR, name);
try {
if (statSync(file).mtimeMs < cutoff) unlinkSync(file);
} catch {}
}
}
export function resetPromptCounter(sessionId) {
const key = sessionKey(sessionId);
if (!key) return;
try {
ensureStateDir();
const file = counterPath(key);
writeFileSync(file, '', { mode: 0o600 });
chmodSync(file, 0o600);
pruneStaleCounters();
} catch {}
}
export function promptIsDue(sessionId) {
const key = sessionKey(sessionId);
if (!key) return false;
try {
ensureStateDir();
const file = counterPath(key);
appendFileSync(file, 'x', { mode: 0o600 });
chmodSync(file, 0o600);
const count = statSync(file).size;
return Number.isSafeInteger(count) && count > 0 && count % PROMPT_INTERVAL === 0;
} catch {
return false;
}
}