mirror of
https://github.com/lukaszraczylo/claude-adam.git
synced 2026-10-20 06:27:13 +00:00
feat(nudge): ReContext-grounded cue reactivation + analyst refinements
Analyse claude-adam through ReContext (arXiv:2607.02509): close the access!=utilization gap with query-conditioned nudge replay + analyst tweaks. - nudge: optional cue.cwd gates SessionStart replay (adam-nudge.mjs) and new mid-session reactivation on UserPromptSubmit (adam-observe.mjs, cwd-gated, once/session, ADAM_NO_MIDSESSION_NUDGE opt-out). - new adam-apply-nudge.mjs builds message + cue deterministically from proposal frontmatter (wired into SKILL.md, install.sh, pending-check). - adam-batch: optional --max-batches/--top-fraction output cap (default off), reports capped. - analyst: utility-lift rubric penalty + skill_utility_path fed to both stages; adaptive re-diagnose for unclear/top-severity clusters; cross-type associative pass (agents/adam.md, SKILL.md). - tests: 140 -> 144 (cue gate, batch cap, apply-nudge, mid-session).
This commit is contained in:
+22
-7
@@ -3,7 +3,9 @@
|
||||
// 1. Pending proposals (≥3 queued in adam/proposals/).
|
||||
// 2. Cross-session nudges (entries in adam/active-nudges.json whose
|
||||
// source_session differs from the current session and that haven't
|
||||
// expired or exhausted their max_displays).
|
||||
// expired or exhausted their max_displays). An entry may carry an optional
|
||||
// `cue.cwd`; when set, it only surfaces in a session whose cwd matches
|
||||
// (otherwise it is deferred, not consumed).
|
||||
// 3. Pending local-edit upgrades (`.adam-new` sidecars).
|
||||
// 4. New-release notice: if a newer GitHub release exists than the installed
|
||||
// `.version`, print a notify-only one-line update prompt. Cached + checked
|
||||
@@ -47,6 +49,7 @@ const PENDING_CHECK_PATHS = [
|
||||
"adam/scripts/adam-score.mjs",
|
||||
"adam/scripts/adam-ab-measure.mjs",
|
||||
"adam/scripts/adam-apply-reinforcement.mjs",
|
||||
"adam/scripts/adam-apply-nudge.mjs",
|
||||
"adam/scripts/adam-utils.mjs",
|
||||
"adam/scripts/adam-batch.mjs",
|
||||
"adam/scripts/adam-rollback.mjs",
|
||||
@@ -59,13 +62,13 @@ function readJson(path, fallback) {
|
||||
}
|
||||
|
||||
function readSessionInput() {
|
||||
// SessionStart payload arrives on stdin; capture session_id if present.
|
||||
// We don't block on stdin — best-effort, non-blocking.
|
||||
// SessionStart payload arrives on stdin; return the parsed object so callers
|
||||
// can read both session_id and cwd. We don't block on stdin — best-effort.
|
||||
try {
|
||||
const buf = readFileSync(0, "utf8");
|
||||
if (!buf) return null;
|
||||
const parsed = JSON.parse(buf);
|
||||
return parsed && typeof parsed.session_id === "string" ? parsed.session_id : null;
|
||||
return parsed && typeof parsed === "object" ? parsed : null;
|
||||
} catch { return null; }
|
||||
}
|
||||
|
||||
@@ -79,7 +82,7 @@ function emitProposalReminder() {
|
||||
} catch { /* proposals dir absent → silent */ }
|
||||
}
|
||||
|
||||
function emitActiveNudges(currentSession) {
|
||||
function emitActiveNudges(currentSession, currentCwd) {
|
||||
if (!existsSync(NUDGES_FILE)) return;
|
||||
const raw = readJson(NUDGES_FILE, null);
|
||||
if (!Array.isArray(raw)) return;
|
||||
@@ -99,6 +102,16 @@ function emitActiveNudges(currentSession) {
|
||||
kept.push(entry);
|
||||
continue;
|
||||
}
|
||||
// Cue gate (optional, additive): a nudge may carry `cue.cwd` binding it to
|
||||
// the project it originated in. When set and the current session's cwd does
|
||||
// not match, defer it — keep the entry, do NOT consume a display — instead of
|
||||
// surfacing an irrelevant reminder. Nudges without a cue print unconditionally,
|
||||
// exactly as before (ReContext P5/P7: replay should be conditioned on the cue).
|
||||
if (entry.cue && typeof entry.cue === "object" && entry.cue.cwd &&
|
||||
currentCwd && entry.cue.cwd !== currentCwd) {
|
||||
kept.push(entry);
|
||||
continue;
|
||||
}
|
||||
if (typeof entry.message === "string" && entry.message) {
|
||||
process.stdout.write(entry.message + "\n");
|
||||
const nextUsed = used + 1;
|
||||
@@ -201,14 +214,16 @@ async function emitUpdateCheck() {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const stdinSession = readSessionInput();
|
||||
const payload = readSessionInput();
|
||||
const stdinSession = payload && typeof payload.session_id === "string" ? payload.session_id : null;
|
||||
const stateSession = (() => {
|
||||
const st = readJson(STATE_FILE, null);
|
||||
return st && typeof st.session_id === "string" ? st.session_id : null;
|
||||
})();
|
||||
const currentSession = stdinSession || stateSession || "";
|
||||
const currentCwd = (payload && typeof payload.cwd === "string" && payload.cwd) || process.cwd();
|
||||
emitProposalReminder();
|
||||
emitActiveNudges(currentSession);
|
||||
emitActiveNudges(currentSession, currentCwd);
|
||||
emitPendingUpgrades();
|
||||
await emitUpdateCheck();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user