@esso0428/pi-subagents 0.17.35 → 0.17.37

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/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.17.37] - 2026-10-05
11
+
12
+ ### Fixed
13
+ - **The `/agents` menu no longer undercounts the project-wide history**: the entry advertised the in-memory record count while the list it opened also merged records recovered from older session files, so the label read 150 against 230 rows. Both now read one cached, filtered legacy set per cwd — cached because the scan is not cheap, and shared because separate reads would let the count and the list drift apart again.
14
+
15
+ ## [0.17.36] - 2026-10-05
16
+
17
+ ### Fixed
18
+ - **Legacy session history no longer lists records that cannot be opened**: recovering `subagents:record` entries from older sessions bypassed the `canOpenAgentHistory` check that the this-session list, the project-wide list, and the roster all apply, so entries with no durable transcript were offered and could only ever answer "No agent history." They now clear the same bar, which drops roughly half of what the scan recovers.
19
+
10
20
  ## [0.17.35] - 2026-10-05
11
21
 
12
22
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esso0428/pi-subagents",
3
- "version": "0.17.35",
3
+ "version": "0.17.37",
4
4
  "description": "A pi extension that brings smart Claude Code-style autonomous sub-agents to pi, with npm:pi-subagents-style JSON agent overrides.",
5
5
  "author": "ESSO0428",
6
6
  "repository": {
@@ -83,6 +83,8 @@ export function buildAgentStatusMenuEntries(
83
83
  records: readonly AgentRecord[],
84
84
  cwd: string | undefined,
85
85
  sessionId?: string,
86
+ /** Recovered legacy records, already filtered to the openable ones. */
87
+ legacy: readonly AgentRecord[] = [],
86
88
  ): string[] {
87
89
  const { active, history } = splitAgentRecords(records, cwd);
88
90
  // This-session history is what you almost always want, so it is the default
@@ -91,9 +93,14 @@ export function buildAgentStatusMenuEntries(
91
93
  // branch or checkpoint are stamped with the current session, so an inherited
92
94
  // agent counts as present here rather than disappearing into the other bucket.
93
95
  const inSession = sessionId ? history.filter((record) => record.sessionId === sessionId) : [];
96
+ // Legacy records are merged into this list when it opens, so the count has to
97
+ // include the ones the in-memory set does not already carry — otherwise the
98
+ // menu advertises fewer entries than the list actually shows.
99
+ const inMemory = new Set(history.map((record) => record.id));
100
+ const allSessions = history.length + legacy.filter((record) => !inMemory.has(record.id)).length;
94
101
  return [
95
102
  ...(active.length > 0 ? [`Running agents (${active.length})`] : []),
96
103
  ...(inSession.length > 0 ? [`Agent history this session (${inSession.length})`] : []),
97
- ...(history.length > 0 ? [`Agent history all sessions (${history.length})`] : []),
104
+ ...(allSessions > 0 ? [`Agent history all sessions (${allSessions})`] : []),
98
105
  ];
99
106
  }
package/src/index.ts CHANGED
@@ -675,7 +675,25 @@ export default function (pi: ExtensionAPI) {
675
675
  }
676
676
  }
677
677
 
678
+ /**
679
+ * Legacy `subagents:record` entries recovered from session files, per cwd.
680
+ *
681
+ * The scan is not cheap, and both the menu's counts and the history list need
682
+ * it — reading it twice would double the cost on every `/agents` visit, and a
683
+ * stale count in the menu is worse than a slow one.
684
+ */
685
+ const legacyHistoryCache = new Map<string, AgentRecord[]>();
686
+ async function legacyHistoryFor(ctx: ExtensionCommandContext): Promise<AgentRecord[]> {
687
+ const key = ctx.cwd;
688
+ const cached = legacyHistoryCache.get(key);
689
+ if (cached) return cached;
690
+ const records = (await readLegacySessionRecords(key)).filter(record => canOpenAgentHistory(record, key));
691
+ legacyHistoryCache.set(key, records);
692
+ return records;
693
+ }
694
+
678
695
  function setWidgetMode(m: WidgetMode): void {
696
+ legacyHistoryCache.clear();
679
697
  widgetMode = m;
680
698
  widget.update();
681
699
  }
@@ -1701,7 +1719,8 @@ Terse command-style prompts produce shallow, generic work.
1701
1719
  // Keep active agents and terminal history in separate menu entries.
1702
1720
  const records = manager.listAgents();
1703
1721
  const { active, history } = splitAgentRecords(records, ctx.cwd);
1704
- options.push(...buildAgentStatusMenuEntries(records, ctx.cwd, ctx.sessionManager?.getSessionId?.()));
1722
+ const legacy = await legacyHistoryFor(ctx);
1723
+ options.push(...buildAgentStatusMenuEntries(records, ctx.cwd, ctx.sessionManager?.getSessionId?.(), legacy));
1705
1724
 
1706
1725
  // Agent types list
1707
1726
  if (allNames.length > 0) {
@@ -1931,9 +1950,13 @@ Terse command-style prompts produce shallow, generic work.
1931
1950
  // Sessions recorded before durable checkpoints only exist as
1932
1951
  // `subagents:record` entries in their session file. They are merged here for
1933
1952
  // the project-wide view; the this-session view never needs the scan.
1953
+ //
1954
+ // They must clear the same `canOpenAgentHistory` bar as everything else:
1955
+ // most carry no durable transcript, and listing an entry that can only ever
1956
+ // answer "No agent history." is a dead link, not history.
1934
1957
  const merged = scope === "this-session"
1935
1958
  ? scoped
1936
- : mergeLegacyRecords(scoped, await readLegacySessionRecords(ctx.cwd));
1959
+ : mergeLegacyRecords(scoped, await legacyHistoryFor(ctx));
1937
1960
  const pairs = merged.map((record) => ({ record, label: formatAgentHistoryOption(record, Date.now()) }));
1938
1961
  makeUniqueAgentOptionLabels(pairs);
1939
1962
  const title = scope === "this-session" ? "Agent history — this session" : "Agent history — all sessions";