engrm 0.4.16 → 0.4.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1154,7 +1154,7 @@ import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync
1154
1154
  import { join as join3 } from "node:path";
1155
1155
  import { homedir } from "node:os";
1156
1156
  var STATE_PATH = join3(homedir(), ".engrm", "config-fingerprint.json");
1157
- var CLIENT_VERSION = "0.4.16";
1157
+ var CLIENT_VERSION = "0.4.17";
1158
1158
  function hashFile(filePath) {
1159
1159
  try {
1160
1160
  if (!existsSync3(filePath))
@@ -2535,7 +2535,7 @@ function buildBeacon(db, config, sessionId, metrics) {
2535
2535
  sentinel_used: valueSignals.security_findings_count > 0,
2536
2536
  risk_score: riskScore,
2537
2537
  stacks_detected: stacks,
2538
- client_version: "0.4.16",
2538
+ client_version: "0.4.17",
2539
2539
  context_observations_injected: metrics?.contextObsInjected ?? 0,
2540
2540
  context_total_available: metrics?.contextTotalAvailable ?? 0,
2541
2541
  recall_attempts: metrics?.recallAttempts ?? 0,
@@ -3558,42 +3558,40 @@ async function main() {
3558
3558
  try {
3559
3559
  if (event.session_id) {
3560
3560
  db.completeSession(event.session_id);
3561
+ if (event.last_assistant_message) {
3562
+ try {
3563
+ createAssistantCheckpoint(db, event.session_id, event.cwd, event.last_assistant_message);
3564
+ } catch {}
3565
+ }
3561
3566
  const existing = db.getSessionSummary(event.session_id);
3562
3567
  if (!existing) {
3563
3568
  const observations = db.getObservationsBySession(event.session_id);
3564
- if (observations.length > 0) {
3565
- const session = db.getSessionMetrics(event.session_id);
3566
- const summary = extractRetrospective(observations, event.session_id, session?.project_id ?? null, config.user_id);
3567
- if (summary) {
3568
- const row = db.insertSessionSummary(summary);
3569
- db.addToOutbox("summary", row.id);
3570
- let securityFindings = [];
3571
- try {
3572
- if (session?.project_id) {
3573
- securityFindings = db.getSecurityFindings(session.project_id, { limit: 100 }).filter((f) => f.session_id === event.session_id);
3574
- }
3575
- } catch {}
3576
- const riskResult = computeRiskScore({
3577
- observations,
3578
- securityFindings,
3579
- filesTouchedCount: session?.files_touched_count ?? 0,
3580
- toolCallsCount: session?.tool_calls_count ?? 0
3581
- });
3582
- try {
3583
- db.setSessionRiskScore(event.session_id, riskResult.score);
3584
- } catch {}
3585
- printRetrospective(summary);
3586
- console.log(formatRiskTrafficLight(riskResult));
3587
- }
3569
+ const session = db.getSessionMetrics(event.session_id);
3570
+ const summary = extractRetrospective(observations, event.session_id, session?.project_id ?? null, config.user_id) ?? buildFallbackSessionSummary(db, event.session_id, session?.project_id ?? null, config.user_id, event.last_assistant_message);
3571
+ if (summary) {
3572
+ const row = db.insertSessionSummary(summary);
3573
+ db.addToOutbox("summary", row.id);
3574
+ let securityFindings = [];
3575
+ try {
3576
+ if (session?.project_id) {
3577
+ securityFindings = db.getSecurityFindings(session.project_id, { limit: 100 }).filter((f) => f.session_id === event.session_id);
3578
+ }
3579
+ } catch {}
3580
+ const riskResult = computeRiskScore({
3581
+ observations,
3582
+ securityFindings,
3583
+ filesTouchedCount: session?.files_touched_count ?? 0,
3584
+ toolCallsCount: session?.tool_calls_count ?? 0
3585
+ });
3586
+ try {
3587
+ db.setSessionRiskScore(event.session_id, riskResult.score);
3588
+ } catch {}
3589
+ printRetrospective(summary);
3590
+ console.log(formatRiskTrafficLight(riskResult));
3588
3591
  }
3589
3592
  }
3590
3593
  }
3591
3594
  if (event.last_assistant_message) {
3592
- if (event.session_id) {
3593
- try {
3594
- createAssistantCheckpoint(db, event.session_id, event.cwd, event.last_assistant_message);
3595
- } catch {}
3596
- }
3597
3595
  const unsaved = detectUnsavedPlans(event.last_assistant_message);
3598
3596
  if (unsaved.length > 0) {
3599
3597
  console.error("");
@@ -3640,6 +3638,44 @@ async function main() {
3640
3638
  }
3641
3639
  process.exit(0);
3642
3640
  }
3641
+ function buildFallbackSessionSummary(db, sessionId, projectId, userId, lastAssistantMessage) {
3642
+ const prompts = db.getSessionUserPrompts(sessionId, 10).filter((prompt) => isMeaningfulSummaryPrompt(prompt));
3643
+ const checkpoint = lastAssistantMessage ? extractAssistantCheckpoint(lastAssistantMessage) : null;
3644
+ const request = selectFallbackRequest(prompts);
3645
+ const completed = checkpoint ? buildCheckpointCompleted(checkpoint) : null;
3646
+ if (!request && !completed)
3647
+ return null;
3648
+ return {
3649
+ session_id: sessionId,
3650
+ project_id: projectId,
3651
+ user_id: userId,
3652
+ request,
3653
+ investigated: null,
3654
+ learned: null,
3655
+ completed,
3656
+ next_steps: null
3657
+ };
3658
+ }
3659
+ function selectFallbackRequest(prompts) {
3660
+ const preferred = [...prompts].reverse().find((prompt) => !/^\[;ease$/i.test(prompt.prompt.trim()));
3661
+ return preferred?.prompt?.replace(/\s+/g, " ").trim() ?? null;
3662
+ }
3663
+ function isMeaningfulSummaryPrompt(prompt) {
3664
+ const compact = prompt.prompt.replace(/\s+/g, " ").trim();
3665
+ if (compact.length < 8)
3666
+ return false;
3667
+ if (/^\[;ease$/i.test(compact))
3668
+ return false;
3669
+ return /[a-z]{3,}/i.test(compact);
3670
+ }
3671
+ function buildCheckpointCompleted(checkpoint) {
3672
+ const lines = [`- ${checkpoint.title}`];
3673
+ for (const fact of checkpoint.facts.slice(0, 2)) {
3674
+ lines.push(` - ${fact}`);
3675
+ }
3676
+ return lines.join(`
3677
+ `);
3678
+ }
3643
3679
  function createSessionDigest(db, sessionId, cwd) {
3644
3680
  const observations = db.getObservationsBySession(sessionId);
3645
3681
  if (observations.length < 2)
package/dist/server.js CHANGED
@@ -19764,7 +19764,7 @@ process.on("SIGTERM", () => {
19764
19764
  });
19765
19765
  var server = new McpServer({
19766
19766
  name: "engrm",
19767
- version: "0.4.16"
19767
+ version: "0.4.17"
19768
19768
  });
19769
19769
  server.tool("save_observation", "Save an observation to memory", {
19770
19770
  type: exports_external.enum([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "engrm",
3
- "version": "0.4.16",
3
+ "version": "0.4.17",
4
4
  "description": "Shared memory across devices, sessions, and coding agents",
5
5
  "mcpName": "io.github.dr12hes/engrm",
6
6
  "type": "module",