@phren/cli 0.0.44 → 0.0.45
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.
|
@@ -492,8 +492,8 @@ export async function handleHookStop() {
|
|
|
492
492
|
for (const store of otherStores) {
|
|
493
493
|
if (!fs.existsSync(store.path) || !fs.existsSync(path.join(store.path, ".git")))
|
|
494
494
|
continue;
|
|
495
|
-
if (store.role === "team") {
|
|
496
|
-
// Team stores: stage team-safe files, commit, and push
|
|
495
|
+
if (store.role === "team" && store.sync !== "pull-only") {
|
|
496
|
+
// Team stores with managed-git sync: stage team-safe files, commit, and push
|
|
497
497
|
try {
|
|
498
498
|
const storeStatus = await runBestEffortGit(["status", "--porcelain"], store.path);
|
|
499
499
|
if (storeStatus.ok && storeStatus.output) {
|
package/mcp/dist/shared/index.js
CHANGED
|
@@ -4,6 +4,46 @@ import * as os from "os";
|
|
|
4
4
|
import * as crypto from "crypto";
|
|
5
5
|
import { globSync } from "glob";
|
|
6
6
|
import { debugLog, appendIndexEvent, getProjectDirs, collectNativeMemoryFiles, runtimeFile, homeDir, readRootManifest, } from "../shared.js";
|
|
7
|
+
/**
|
|
8
|
+
* Cached store project dirs to avoid repeated dynamic imports in sync code paths.
|
|
9
|
+
* Populated by `refreshStoreProjectDirs()`, consumed by `getAllStoreProjectDirs()`.
|
|
10
|
+
*/
|
|
11
|
+
let _cachedStoreProjectDirs = null;
|
|
12
|
+
let _cachedStorePhrenPath = null;
|
|
13
|
+
/**
|
|
14
|
+
* Gather project directories from the primary store AND all non-primary stores.
|
|
15
|
+
* This enables the FTS5 index to include team store projects alongside personal ones.
|
|
16
|
+
* Uses a sync cache populated by the async buildIndex path.
|
|
17
|
+
*/
|
|
18
|
+
function getAllStoreProjectDirs(phrenPath, profile) {
|
|
19
|
+
const dirs = [...getProjectDirs(phrenPath, profile)];
|
|
20
|
+
if (_cachedStoreProjectDirs && _cachedStorePhrenPath === phrenPath) {
|
|
21
|
+
dirs.push(..._cachedStoreProjectDirs);
|
|
22
|
+
}
|
|
23
|
+
return dirs;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Refresh the store project dirs cache. Called from async contexts (buildIndex, etc.)
|
|
27
|
+
* before sync code paths that need getAllStoreProjectDirs.
|
|
28
|
+
*/
|
|
29
|
+
async function refreshStoreProjectDirs(phrenPath, profile) {
|
|
30
|
+
try {
|
|
31
|
+
const { getNonPrimaryStores } = await import("../store-registry.js");
|
|
32
|
+
const otherStores = getNonPrimaryStores(phrenPath);
|
|
33
|
+
const dirs = [];
|
|
34
|
+
for (const store of otherStores) {
|
|
35
|
+
if (!fs.existsSync(store.path))
|
|
36
|
+
continue;
|
|
37
|
+
dirs.push(...getProjectDirs(store.path, profile));
|
|
38
|
+
}
|
|
39
|
+
_cachedStoreProjectDirs = dirs;
|
|
40
|
+
_cachedStorePhrenPath = phrenPath;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
_cachedStoreProjectDirs = [];
|
|
44
|
+
_cachedStorePhrenPath = phrenPath;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
7
47
|
import { getIndexPolicy, withFileLock } from "./governance.js";
|
|
8
48
|
import { stripTaskDoneSection } from "./content.js";
|
|
9
49
|
import { isInactiveFindingLine } from "../finding/lifecycle.js";
|
|
@@ -191,7 +231,7 @@ function touchSentinel(phrenPath) {
|
|
|
191
231
|
function computePhrenHash(phrenPath, profile, preGlobbed) {
|
|
192
232
|
const policy = getIndexPolicy(phrenPath);
|
|
193
233
|
const hash = crypto.createHash("sha1");
|
|
194
|
-
const topicConfigEntries =
|
|
234
|
+
const topicConfigEntries = getAllStoreProjectDirs(phrenPath, profile)
|
|
195
235
|
.map((dir) => path.join(dir, "topic-config.json"))
|
|
196
236
|
.filter((configPath) => fs.existsSync(configPath));
|
|
197
237
|
if (preGlobbed) {
|
|
@@ -215,9 +255,9 @@ function computePhrenHash(phrenPath, profile, preGlobbed) {
|
|
|
215
255
|
}
|
|
216
256
|
}
|
|
217
257
|
else {
|
|
218
|
-
const
|
|
258
|
+
const allProjectDirs = getAllStoreProjectDirs(phrenPath, profile);
|
|
219
259
|
const files = [];
|
|
220
|
-
for (const dir of
|
|
260
|
+
for (const dir of allProjectDirs) {
|
|
221
261
|
const projectName = path.basename(dir);
|
|
222
262
|
const config = readProjectConfig(phrenPath, projectName);
|
|
223
263
|
const ownership = getProjectOwnershipMode(phrenPath, projectName, config);
|
|
@@ -399,7 +439,7 @@ function getRepoManagedInstructionEntries(phrenPath, project) {
|
|
|
399
439
|
return entries;
|
|
400
440
|
}
|
|
401
441
|
function globAllFiles(phrenPath, profile) {
|
|
402
|
-
const projectDirs =
|
|
442
|
+
const projectDirs = getAllStoreProjectDirs(phrenPath, profile);
|
|
403
443
|
const indexPolicy = getIndexPolicy(phrenPath);
|
|
404
444
|
const entries = [];
|
|
405
445
|
const allAbsolutePaths = [];
|
|
@@ -826,7 +866,8 @@ function mergeManualLinks(db, phrenPath) {
|
|
|
826
866
|
}
|
|
827
867
|
async function buildIndexImpl(phrenPath, profile) {
|
|
828
868
|
const t0 = Date.now();
|
|
829
|
-
|
|
869
|
+
await refreshStoreProjectDirs(phrenPath, profile);
|
|
870
|
+
const projectDirs = getAllStoreProjectDirs(phrenPath, profile);
|
|
830
871
|
beginUserFragmentBuildCache(phrenPath, projectDirs.map(dir => path.basename(dir)));
|
|
831
872
|
try {
|
|
832
873
|
// ── Cache dir + hash sentinel ─────────────────────────────────────────────
|
|
@@ -1348,12 +1389,16 @@ export function detectProject(phrenPath, cwd, profile) {
|
|
|
1348
1389
|
if (manifest?.installMode === "project-local") {
|
|
1349
1390
|
return manifest.primaryProject || null;
|
|
1350
1391
|
}
|
|
1351
|
-
const projectDirs =
|
|
1392
|
+
const projectDirs = getAllStoreProjectDirs(phrenPath, profile);
|
|
1352
1393
|
const resolvedCwd = path.resolve(cwd);
|
|
1353
1394
|
let bestMatch = null;
|
|
1354
1395
|
for (const dir of projectDirs) {
|
|
1355
1396
|
const projectName = path.basename(dir);
|
|
1356
|
-
|
|
1397
|
+
// Try the project's own store path first (handles team store projects),
|
|
1398
|
+
// then fall back to primary phrenPath
|
|
1399
|
+
const storePhrenPath = path.dirname(dir);
|
|
1400
|
+
const sourcePath = getProjectSourcePath(storePhrenPath, projectName)
|
|
1401
|
+
|| getProjectSourcePath(phrenPath, projectName);
|
|
1357
1402
|
if (!sourcePath)
|
|
1358
1403
|
continue;
|
|
1359
1404
|
const matches = resolvedCwd === sourcePath || resolvedCwd.startsWith(sourcePath + path.sep);
|