pi-extensions 0.1.30 → 0.1.31

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-extensions",
3
- "version": "0.1.30",
3
+ "version": "0.1.31",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "keywords": [
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.7 - 2026-04-19
4
+
5
+ ### Fixed
6
+ - Ralph loops no longer silently stop after auto-compaction or `/compact`. On session reload, `currentLoop` is now rehydrated from the on-disk state (most-recently-updated active loop wins on ties), so `ralph_done`, `agent_end`, and `before_agent_start` continue to function. Thanks to @elecnix for the detailed report and proposed fix ([#11](https://github.com/tmustier/pi-extensions/issues/11)).
7
+
3
8
  ## 0.1.5 - 2026-02-03
4
9
 
5
10
  ### Added
@@ -92,6 +92,14 @@ export default function (pi: ExtensionAPI) {
92
92
  }
93
93
  }
94
94
 
95
+ function safeMtimeMs(filePath: string): number {
96
+ try {
97
+ return fs.statSync(filePath).mtimeMs;
98
+ } catch {
99
+ return 0;
100
+ }
101
+ }
102
+
95
103
  function tryRemoveDir(dirPath: string): boolean {
96
104
  try {
97
105
  if (fs.existsSync(dirPath)) {
@@ -784,6 +792,21 @@ Examples:
784
792
 
785
793
  pi.on("session_start", async (_event, ctx) => {
786
794
  const active = listLoops(ctx).filter((l) => l.status === "active");
795
+
796
+ // Rehydrate currentLoop from disk. The module is re-initialized on
797
+ // session reload (including auto-compaction and /compact), which would
798
+ // otherwise leave `currentLoop` null and silently break ralph_done,
799
+ // agent_end, and before_agent_start. Pick the most-recently-updated
800
+ // active loop when there are multiple, using the state file mtime.
801
+ if (!currentLoop && active.length > 0) {
802
+ const mostRecent = active.reduce((best, candidate) => {
803
+ const bestMtime = safeMtimeMs(getPath(ctx, best.name, ".state.json"));
804
+ const candidateMtime = safeMtimeMs(getPath(ctx, candidate.name, ".state.json"));
805
+ return candidateMtime > bestMtime ? candidate : best;
806
+ });
807
+ currentLoop = mostRecent.name;
808
+ }
809
+
787
810
  if (active.length > 0 && ctx.hasUI) {
788
811
  const lines = active.map(
789
812
  (l) => ` • ${l.name} (iteration ${l.iteration}${l.maxIterations > 0 ? `/${l.maxIterations}` : ""})`,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmustier/pi-ralph-wiggum",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Long-running agent loops for iterative development in Pi.",
5
5
  "license": "MIT",
6
6
  "author": "Thomas Mustier",