pi-crew 0.8.7 → 0.8.8
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,5 +1,6 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { listRecentRuns } from "../run-index.ts";
|
|
3
|
+
import { findRepoRoot } from "../../utils/paths.ts";
|
|
3
4
|
import { extractSessionId } from "../../utils/session-utils.ts";
|
|
4
5
|
import type { ArtifactDescriptor, TeamRunManifest } from "../../state/types.ts";
|
|
5
6
|
|
|
@@ -69,6 +70,29 @@ function formatCrewArtifactIndex(entries: CrewArtifactIndexEntry[]): string {
|
|
|
69
70
|
return lines.join("\n");
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Project-scope filter: keep `run` only if it belongs to the SAME repo as
|
|
75
|
+
* `queryCwd` (or is a user-level / legacy run with no repo). This is the
|
|
76
|
+
* version-independent, reliable barrier against cross-project leaks: even
|
|
77
|
+
* when the session-id filter below cannot fire (ctx.sessionId is absent on
|
|
78
|
+
* some pi versions — observed on pi 0.79.6 ExtensionContext), the cwd filter
|
|
79
|
+
* stops another project's in-flight runs (e.g. edge-ai-agent) from bleeding
|
|
80
|
+
* into this project's ambient status or compaction-resume directive.
|
|
81
|
+
*
|
|
82
|
+
* Note: listRecentRuns already scopes its filesystem scan via scopedRunRoots,
|
|
83
|
+
* BUT it ALSO merges the GLOBAL activeRunEntries() registry (the cross-
|
|
84
|
+
* project dashboard view). That global merge is intentional for the
|
|
85
|
+
* dashboard but wrong for "what should THIS project's session do" — hence
|
|
86
|
+
* this filter at the consumption site.
|
|
87
|
+
*/
|
|
88
|
+
function isInProjectScope(run: TeamRunManifest, queryCwd: string): boolean {
|
|
89
|
+
const queryRepo = findRepoRoot(queryCwd);
|
|
90
|
+
if (queryRepo === undefined) return true; // viewer not in a repo → user-level view
|
|
91
|
+
const runRepo = typeof run.cwd === "string" && run.cwd.length > 0 ? findRepoRoot(run.cwd) : undefined;
|
|
92
|
+
if (runRepo === undefined) return true; // run is user-level / legacy / not a repo → include
|
|
93
|
+
return runRepo === queryRepo; // same project only
|
|
94
|
+
}
|
|
95
|
+
|
|
72
96
|
/**
|
|
73
97
|
* Collect in-flight (non-terminal) crew runs that must be resumable after
|
|
74
98
|
* compaction. These are runs the agent was actively working on or awaiting.
|
|
@@ -88,7 +112,13 @@ function formatCrewArtifactIndex(entries: CrewArtifactIndexEntry[]): string {
|
|
|
88
112
|
export function collectInFlightRuns(cwd: string, currentSessionId?: string): TeamRunManifest[] {
|
|
89
113
|
return listRecentRuns(cwd, MAX_ARTIFACT_INDEX_RUNS).filter((run) => {
|
|
90
114
|
if (!IN_FLIGHT_RUN_STATUSES.has(run.status)) return false;
|
|
91
|
-
|
|
115
|
+
// Reliable barrier (2026-06-17): never leak another project's runs into
|
|
116
|
+
// THIS project's resume directive / ambient status, regardless of
|
|
117
|
+
// whether the session-id filter is available. This fixes the live
|
|
118
|
+
// cross-session leak that persisted after 4bd6f5b because ctx.sessionId
|
|
119
|
+
// is absent on pi 0.79.6.
|
|
120
|
+
if (!isInProjectScope(run, cwd)) return false;
|
|
121
|
+
if (currentSessionId === undefined) return true; // no session filter → back-compat (still project-scoped)
|
|
92
122
|
return run.ownerSessionId === currentSessionId; // strict: legacy ownerless runs excluded
|
|
93
123
|
});
|
|
94
124
|
}
|
|
@@ -76,7 +76,7 @@ function scopedRunRoots(cwd: string): string[] {
|
|
|
76
76
|
return [...roots];
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
function collectActiveRuns(): TeamRunManifest[] {
|
|
79
|
+
function collectActiveRuns(cwd?: string): TeamRunManifest[] {
|
|
80
80
|
return activeRunEntries()
|
|
81
81
|
.map((entry) => readManifest(entry.manifestPath))
|
|
82
82
|
.filter((manifest): manifest is TeamRunManifest => manifest !== undefined);
|