@keepgoingdev/cli 1.3.0 → 1.3.2

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.
Files changed (2) hide show
  1. package/dist/index.js +34 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -297,7 +297,8 @@ function generateEnrichedBriefing(opts) {
297
297
  timestamp: s.timestamp,
298
298
  summary: s.summary || "",
299
299
  nextStep: s.nextStep || "",
300
- branch: s.gitBranch
300
+ branch: s.gitBranch,
301
+ sessionPhase: s.sessionPhase
301
302
  }));
302
303
  }
303
304
  if (opts.recentCommits && opts.recentCommits.length > 0) {
@@ -330,10 +331,13 @@ function buildCurrentFocus(lastSession, projectState, gitBranch) {
330
331
  function buildRecentActivity(lastSession, recentSessions, recentCommitMessages) {
331
332
  const parts = [];
332
333
  const sessionCount = recentSessions.length;
334
+ const planCount = recentSessions.filter((s) => s.sessionPhase === "planning").length;
333
335
  if (sessionCount > 1) {
334
- parts.push(`${sessionCount} recent sessions`);
336
+ const planSuffix = planCount > 0 ? ` (${planCount} plan-only)` : "";
337
+ parts.push(`${sessionCount} recent sessions${planSuffix}`);
335
338
  } else if (sessionCount === 1) {
336
- parts.push("1 recent session");
339
+ const planSuffix = planCount === 1 ? " (plan-only)" : "";
340
+ parts.push(`1 recent session${planSuffix}`);
337
341
  }
338
342
  if (lastSession.summary) {
339
343
  const brief = lastSession.summary.length > 120 ? lastSession.summary.slice(0, 117) + "..." : lastSession.summary;
@@ -786,7 +790,7 @@ function registerProject(projectPath, projectName) {
786
790
  data.projects.push({ path: projectPath, name, lastSeen: now });
787
791
  }
788
792
  const cutoff = Date.now() - STALE_PROJECT_MS;
789
- data.projects = data.projects.filter((p) => new Date(p.lastSeen).getTime() > cutoff);
793
+ data.projects = data.projects.filter((p) => new Date(p.lastSeen).getTime() > cutoff && fs2.existsSync(p.path));
790
794
  writeKnownProjects(data);
791
795
  } catch {
792
796
  }
@@ -807,14 +811,15 @@ function pruneStaleTasks(tasks) {
807
811
  });
808
812
  }
809
813
  var KeepGoingWriter = class {
814
+ mainRoot;
810
815
  storagePath;
811
816
  sessionsFilePath;
812
817
  stateFilePath;
813
818
  metaFilePath;
814
819
  currentTasksFilePath;
815
820
  constructor(workspacePath) {
816
- const mainRoot = resolveStorageRoot(workspacePath);
817
- this.storagePath = path5.join(mainRoot, STORAGE_DIR);
821
+ this.mainRoot = resolveStorageRoot(workspacePath);
822
+ this.storagePath = path5.join(this.mainRoot, STORAGE_DIR);
818
823
  this.sessionsFilePath = path5.join(this.storagePath, SESSIONS_FILE);
819
824
  this.stateFilePath = path5.join(this.storagePath, STATE_FILE);
820
825
  this.metaFilePath = path5.join(this.storagePath, META_FILE);
@@ -856,8 +861,7 @@ var KeepGoingWriter = class {
856
861
  };
857
862
  fs3.writeFileSync(this.stateFilePath, JSON.stringify(state, null, 2), "utf-8");
858
863
  this.updateMeta(checkpoint.timestamp);
859
- const mainRoot = resolveStorageRoot(this.storagePath);
860
- registerProject(mainRoot, projectName);
864
+ registerProject(this.mainRoot, projectName);
861
865
  }
862
866
  updateMeta(timestamp) {
863
867
  let meta;
@@ -924,8 +928,7 @@ var KeepGoingWriter = class {
924
928
  upsertSession(update) {
925
929
  this.ensureDir();
926
930
  this.upsertSessionCore(update);
927
- const mainRoot = resolveStorageRoot(this.storagePath);
928
- registerProject(mainRoot);
931
+ registerProject(this.mainRoot);
929
932
  }
930
933
  /** Core upsert logic: merges the update into current-tasks.json and returns the pruned task list. */
931
934
  upsertSessionCore(update) {
@@ -1693,6 +1696,15 @@ var POST_TOOL_USE_HOOK = {
1693
1696
  }
1694
1697
  ]
1695
1698
  };
1699
+ var PLAN_MODE_HOOK = {
1700
+ matcher: "Read|Grep|Glob|Bash|WebSearch",
1701
+ hooks: [
1702
+ {
1703
+ type: "command",
1704
+ command: "npx -y @keepgoingdev/mcp-server --heartbeat"
1705
+ }
1706
+ ]
1707
+ };
1696
1708
  var SESSION_END_HOOK = {
1697
1709
  matcher: "",
1698
1710
  hooks: [
@@ -1702,7 +1714,7 @@ var SESSION_END_HOOK = {
1702
1714
  }
1703
1715
  ]
1704
1716
  };
1705
- var KEEPGOING_RULES_VERSION = 2;
1717
+ var KEEPGOING_RULES_VERSION = 3;
1706
1718
  var KEEPGOING_RULES_CONTENT = `<!-- @keepgoingdev/mcp-server v${KEEPGOING_RULES_VERSION} -->
1707
1719
  ## KeepGoing
1708
1720
 
@@ -1712,6 +1724,8 @@ After completing a task or meaningful piece of work, call the \`save_checkpoint\
1712
1724
  - \`summary\`: 1-2 sentences. What changed and why, no file paths, no implementation details (those are captured from git).
1713
1725
  - \`nextStep\`: What to do next
1714
1726
  - \`blocker\`: Any blocker (if applicable)
1727
+
1728
+ When working in plan mode (investigating, designing, iterating on an approach before any edits), call \`save_checkpoint\` when you reach a significant milestone or conclusion. Use the summary to capture what was investigated and decided. This preserves planning context for future sessions.
1715
1729
  `;
1716
1730
  function getRulesFileVersion(content) {
1717
1731
  const match = content.match(/<!-- @keepgoingdev\/mcp-server v(\d+) -->/);
@@ -1772,6 +1786,13 @@ function writeHooksToSettings(settings) {
1772
1786
  settings.hooks.PostToolUse.push(POST_TOOL_USE_HOOK);
1773
1787
  changed = true;
1774
1788
  }
1789
+ const hasHeartbeat = settings.hooks.PostToolUse.some(
1790
+ (entry) => entry?.hooks?.some((h) => typeof h?.command === "string" && h.command.includes("--heartbeat"))
1791
+ );
1792
+ if (!hasHeartbeat) {
1793
+ settings.hooks.PostToolUse.push(PLAN_MODE_HOOK);
1794
+ changed = true;
1795
+ }
1775
1796
  if (!Array.isArray(settings.hooks.SessionEnd)) {
1776
1797
  settings.hooks.SessionEnd = [];
1777
1798
  }
@@ -2377,7 +2398,7 @@ import { spawn } from "child_process";
2377
2398
  import { readFileSync, existsSync } from "fs";
2378
2399
  import path10 from "path";
2379
2400
  import os4 from "os";
2380
- var CLI_VERSION = "1.3.0";
2401
+ var CLI_VERSION = "1.3.2";
2381
2402
  var NPM_REGISTRY_URL = "https://registry.npmjs.org/@keepgoingdev/cli/latest";
2382
2403
  var FETCH_TIMEOUT_MS = 5e3;
2383
2404
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
@@ -3918,7 +3939,7 @@ async function main() {
3918
3939
  }
3919
3940
  break;
3920
3941
  case "version":
3921
- console.log(`keepgoing v${"1.3.0"}`);
3942
+ console.log(`keepgoing v${"1.3.2"}`);
3922
3943
  break;
3923
3944
  case "activate":
3924
3945
  await activateCommand({ licenseKey: subcommand });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keepgoingdev/cli",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "Terminal CLI for KeepGoing. Resume side projects without the mental friction.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",