smart-context-mcp 1.16.4 → 1.16.5

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.
package/README.md CHANGED
@@ -56,7 +56,7 @@ Restart your AI client. Done.
56
56
  # Check installed version
57
57
  npm list -g smart-context-mcp
58
58
 
59
- # Should show: smart-context-mcp@1.16.4 (or later)
59
+ # Should show: smart-context-mcp@1.16.5 (or later)
60
60
 
61
61
  # Update to latest version
62
62
  npm update -g smart-context-mcp
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "smart-context-mcp",
3
3
  "mcpName": "io.github.Arrayo/smart-context-mcp",
4
- "version": "1.16.4",
4
+ "version": "1.16.5",
5
5
  "description": "MCP server that reduces agent token usage by 90% with intelligent context compression, task checkpoint persistence, and workflow-aware agent guidance.",
6
6
  "author": "Francisco Caballero Portero <fcp1978@hotmail.com>",
7
7
  "type": "module",
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/Arrayo/smart-context-mcp",
7
7
  "source": "github"
8
8
  },
9
- "version": "1.16.4",
9
+ "version": "1.16.5",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "smart-context-mcp",
14
- "version": "1.16.4",
14
+ "version": "1.16.5",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },
@@ -270,6 +270,45 @@ export const createClaudeAdapter = ({
270
270
  });
271
271
  };
272
272
 
273
+ const maybeAutoCheckpointFromState = async (state, { trigger = 'post_tool_use' } = {}) => {
274
+ if (!state?.projectSessionId || getMutationSafety().shouldBlock) {
275
+ return false;
276
+ }
277
+
278
+ const update = {
279
+ ...(state.promptPreview ? { currentFocus: state.promptPreview } : {}),
280
+ ...(state.touchedFiles.length > 0 ? { touchedFiles: state.touchedFiles } : {}),
281
+ };
282
+
283
+ await summaryTool({
284
+ action: 'checkpoint',
285
+ sessionId: state.projectSessionId,
286
+ event: 'milestone',
287
+ update,
288
+ maxTokens: STOP_MAX_TOKENS,
289
+ force: true,
290
+ });
291
+
292
+ if (state.taskId) {
293
+ await writeTaskHandoff({
294
+ taskId: state.taskId,
295
+ sessionId: state.projectSessionId,
296
+ fromAgentId: state.agentId ?? null,
297
+ toAgentId: null,
298
+ trigger,
299
+ summary: {
300
+ currentFocus: state.promptPreview,
301
+ touchedFiles: state.touchedFiles,
302
+ pending: [],
303
+ nextStep: null,
304
+ evidence: state.touchedFiles.length > 0 ? [`Touched files: ${state.touchedFiles.join(', ')}`] : [],
305
+ },
306
+ });
307
+ }
308
+
309
+ return true;
310
+ };
311
+
273
312
  const handleSessionStart = async () => {
274
313
  const result = await startTurn({
275
314
  phase: 'start',
@@ -350,7 +389,7 @@ export const createClaudeAdapter = ({
350
389
  toolResponse: input.tool_response,
351
390
  });
352
391
 
353
- const nextState = {
392
+ let nextState = {
354
393
  ...existing,
355
394
  checkpointed: checkpoint.matched ? true : existing.checkpointed,
356
395
  checkpointEvent: checkpoint.matched ? checkpoint.event : existing.checkpointEvent,
@@ -359,6 +398,17 @@ export const createClaudeAdapter = ({
359
398
  updatedAt: new Date().toISOString(),
360
399
  };
361
400
 
401
+ if (!checkpoint.matched && touchedFiles.length > 0) {
402
+ const autoCheckpointed = await maybeAutoCheckpointFromState(nextState, { trigger: 'post_tool_use' });
403
+ if (autoCheckpointed) {
404
+ nextState = {
405
+ ...nextState,
406
+ checkpointed: true,
407
+ checkpointEvent: 'milestone',
408
+ };
409
+ }
410
+ }
411
+
362
412
  await maybeSetTrackedTurnState({ hookKey, state: nextState });
363
413
  if (checkpoint.matched || touchedFiles.length > 0) {
364
414
  await recordHookMetrics({
@@ -273,6 +273,45 @@ export const createCursorAdapter = ({
273
273
  });
274
274
  };
275
275
 
276
+ const maybeAutoCheckpointFromState = async (state, { trigger = 'post_tool_use' } = {}) => {
277
+ if (!state?.projectSessionId || getMutationSafety().shouldBlock) {
278
+ return false;
279
+ }
280
+
281
+ const update = {
282
+ ...(state.promptPreview ? { currentFocus: state.promptPreview } : {}),
283
+ ...(state.touchedFiles.length > 0 ? { touchedFiles: state.touchedFiles } : {}),
284
+ };
285
+
286
+ await summaryTool({
287
+ action: 'checkpoint',
288
+ sessionId: state.projectSessionId,
289
+ event: 'milestone',
290
+ update,
291
+ maxTokens: STOP_MAX_TOKENS,
292
+ force: true,
293
+ });
294
+
295
+ if (state.taskId) {
296
+ await writeTaskHandoff({
297
+ taskId: state.taskId,
298
+ sessionId: state.projectSessionId,
299
+ fromAgentId: state.agentId ?? null,
300
+ toAgentId: null,
301
+ trigger,
302
+ summary: {
303
+ currentFocus: state.promptPreview,
304
+ touchedFiles: state.touchedFiles,
305
+ pending: [],
306
+ nextStep: null,
307
+ evidence: state.touchedFiles.length > 0 ? [`Touched files: ${state.touchedFiles.join(', ')}`] : [],
308
+ },
309
+ });
310
+ }
311
+
312
+ return true;
313
+ };
314
+
276
315
  const handleConversationStart = async () => {
277
316
  const result = await startTurn({
278
317
  phase: 'start',
@@ -353,7 +392,7 @@ export const createCursorAdapter = ({
353
392
  toolResponse: input.tool_response,
354
393
  });
355
394
 
356
- const nextState = {
395
+ let nextState = {
357
396
  ...existing,
358
397
  checkpointed: checkpoint.matched ? true : existing.checkpointed,
359
398
  checkpointEvent: checkpoint.matched ? checkpoint.event : existing.checkpointEvent,
@@ -362,6 +401,17 @@ export const createCursorAdapter = ({
362
401
  updatedAt: new Date().toISOString(),
363
402
  };
364
403
 
404
+ if (!checkpoint.matched && touchedFiles.length > 0) {
405
+ const autoCheckpointed = await maybeAutoCheckpointFromState(nextState, { trigger: 'post_tool_use' });
406
+ if (autoCheckpointed) {
407
+ nextState = {
408
+ ...nextState,
409
+ checkpointed: true,
410
+ checkpointEvent: 'milestone',
411
+ };
412
+ }
413
+ }
414
+
365
415
  await maybeSetTrackedTurnState({ hookKey, state: nextState });
366
416
  if (checkpoint.matched || touchedFiles.length > 0) {
367
417
  await recordHookMetrics({