@phren/cli 0.0.52 → 0.0.53

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/README.md CHANGED
@@ -68,6 +68,17 @@ phren team join git@github.com:org/phren-team.git
68
68
 
69
69
  Each team store syncs independently. Run `phren team list` to see all registered stores.
70
70
 
71
+ ### Filtering Team Store Projects
72
+
73
+ Subscribe to only the projects you care about:
74
+
75
+ ```bash
76
+ phren store subscribe qualus-shared arc intranet ogrid
77
+ phren store unsubscribe qualus-shared dendron powergrid-api
78
+ ```
79
+
80
+ Unsubscribed projects still exist in the store but won't appear in search, UI, or context injection.
81
+
71
82
  ---
72
83
 
73
84
  MIT License. Made by [Ala Arab](https://github.com/alaarab).
@@ -1535,6 +1535,8 @@ function printStoreUsage() {
1535
1535
  console.log(" phren store remove <name> Remove a store (local only)");
1536
1536
  console.log(" phren store sync Pull all stores");
1537
1537
  console.log(" phren store activity [--limit N] Recent team findings");
1538
+ console.log(" phren store subscribe <name> <project...> Subscribe store to projects");
1539
+ console.log(" phren store unsubscribe <name> <project...> Unsubscribe store from projects");
1538
1540
  }
1539
1541
  export async function handleStoreNamespace(args) {
1540
1542
  const subcommand = args[0];
@@ -1669,7 +1671,8 @@ export async function handleStoreNamespace(args) {
1669
1671
  for (const store of teamStores) {
1670
1672
  if (!fs.existsSync(store.path))
1671
1673
  continue;
1672
- const projectDirs = getProjectDirs(store.path);
1674
+ const { getStoreProjectDirs } = await import("../store-registry.js");
1675
+ const projectDirs = getStoreProjectDirs(store);
1673
1676
  for (const dir of projectDirs) {
1674
1677
  const projectName = path.basename(dir);
1675
1678
  const journalEntries = readTeamJournalEntries(store.path, projectName);
@@ -1728,6 +1731,42 @@ export async function handleStoreNamespace(args) {
1728
1731
  }
1729
1732
  return;
1730
1733
  }
1734
+ if (subcommand === "subscribe") {
1735
+ const storeName = args[1];
1736
+ const projects = args.slice(2);
1737
+ if (!storeName || projects.length === 0) {
1738
+ console.error("Usage: phren store subscribe <store-name> <project1> [project2...]");
1739
+ process.exit(1);
1740
+ }
1741
+ try {
1742
+ const { subscribeStoreProjects } = await import("../store-registry.js");
1743
+ subscribeStoreProjects(phrenPath, storeName, projects);
1744
+ console.log(`Added ${projects.length} project(s) to "${storeName}"`);
1745
+ }
1746
+ catch (err) {
1747
+ console.error(`Failed to subscribe: ${errorMessage(err)}`);
1748
+ process.exit(1);
1749
+ }
1750
+ return;
1751
+ }
1752
+ if (subcommand === "unsubscribe") {
1753
+ const storeName = args[1];
1754
+ const projects = args.slice(2);
1755
+ if (!storeName || projects.length === 0) {
1756
+ console.error("Usage: phren store unsubscribe <store-name> <project1> [project2...]");
1757
+ process.exit(1);
1758
+ }
1759
+ try {
1760
+ const { unsubscribeStoreProjects } = await import("../store-registry.js");
1761
+ unsubscribeStoreProjects(phrenPath, storeName, projects);
1762
+ console.log(`Removed ${projects.length} project(s) from "${storeName}"`);
1763
+ }
1764
+ catch (err) {
1765
+ console.error(`Failed to unsubscribe: ${errorMessage(err)}`);
1766
+ process.exit(1);
1767
+ }
1768
+ return;
1769
+ }
1731
1770
  console.error(`Unknown store subcommand: ${subcommand}`);
1732
1771
  printStoreUsage();
1733
1772
  process.exit(1);
@@ -1801,7 +1840,8 @@ function countStoreProjects(store) {
1801
1840
  if (!fs.existsSync(store.path))
1802
1841
  return 0;
1803
1842
  try {
1804
- return getProjectDirs(store.path).length;
1843
+ const storeRegistry = require("../store-registry.js");
1844
+ return storeRegistry.getStoreProjectDirs(store).length;
1805
1845
  }
1806
1846
  catch {
1807
1847
  return 0;
@@ -7,6 +7,7 @@ import { errorMessage } from "../utils.js";
7
7
  import { countActiveFindings } from "./archive.js";
8
8
  import { isTaskFileName } from "../data/tasks.js";
9
9
  import { METADATA_REGEX } from "./metadata.js";
10
+ import { getNonPrimaryStores, getStoreProjectDirs } from "../store-registry.js";
10
11
  /** Maximum allowed length for a single finding entry (token budget protection). */
11
12
  export const MAX_FINDING_LENGTH = 2000;
12
13
  function safeParseDate(s) {
@@ -76,12 +77,10 @@ export function checkConsolidationNeeded(phrenPath, profile) {
76
77
  }
77
78
  // Include projects from team stores
78
79
  try {
79
- const storeRegistry = require("../store-registry.js");
80
- const { getNonPrimaryStores } = storeRegistry;
81
80
  for (const store of getNonPrimaryStores(phrenPath)) {
82
81
  if (!fs.existsSync(store.path))
83
82
  continue;
84
- for (const dir of getProjectDirs(store.path)) {
83
+ for (const dir of getStoreProjectDirs(store)) {
85
84
  const status = getProjectConsolidationStatus(dir);
86
85
  if (status && status.recommended) {
87
86
  results.push(status);
@@ -12,6 +12,7 @@ import { parseCitationComment, parseSourceComment, } from "../content/citation.j
12
12
  import { parseFindingLifecycle, } from "../finding/lifecycle.js";
13
13
  import { METADATA_REGEX, isCitationLine, isArchiveStart, isArchiveEnd, parseFindingId, parseAllContradictions, stripComments, normalizeFindingText, } from "../content/metadata.js";
14
14
  import { withSafeLock, ensureProject } from "../shared/data-utils.js";
15
+ import { getNonPrimaryStores, getStoreProjectDirs } from "../store-registry.js";
15
16
  export { readTasks, readTasksAcrossProjects, resolveTaskItem, addTask, addTasks, completeTasks, completeTask, removeTask, removeTasks, updateTask, linkTaskIssue, pinTask, unpinTask, workNextTask, tidyDoneTasks, taskMarkdown, appendChildFinding, promoteTask, TASKS_FILENAME, TASK_FILE_ALIASES, canonicalTaskFilePath, resolveTaskFilePath, isTaskFileName, } from "./tasks.js";
16
17
  export { addProjectToProfile, listMachines, listProfiles, listProjectCards, removeProjectFromProfile, setMachineProfile, } from "../profile-store.js";
17
18
  export { loadShellState, resetShellState, saveShellState, } from "../shell/state-store.js";
@@ -570,12 +571,10 @@ export function readReviewQueueAcrossProjects(phrenPath, profile) {
570
571
  }
571
572
  // Include projects from team stores
572
573
  try {
573
- const storeRegistry = require("../store-registry.js");
574
- const { getNonPrimaryStores } = storeRegistry;
575
574
  for (const store of getNonPrimaryStores(phrenPath)) {
576
575
  if (!fs.existsSync(store.path))
577
576
  continue;
578
- const storeDirs = getProjectDirs(store.path)
577
+ const storeDirs = getStoreProjectDirs(store)
579
578
  .map((d) => path.basename(d))
580
579
  .filter((p) => p !== "global");
581
580
  for (const storeProject of storeDirs) {
@@ -5,6 +5,7 @@ import { phrenErr, PhrenError, phrenOk, forwardErr, getProjectDirs, } from "../s
5
5
  import { validateTaskFormat } from "../shared/content.js";
6
6
  import { safeProjectPath } from "../utils.js";
7
7
  import { withSafeLock, ensureProject } from "../shared/data-utils.js";
8
+ import { getNonPrimaryStores, getStoreProjectDirs } from "../store-registry.js";
8
9
  const ACTIVE_HEADINGS = new Set(["active", "in progress", "in-progress", "current", "wip"]);
9
10
  const QUEUE_HEADINGS = new Set(["queue", "queued", "task", "todo", "upcoming", "next"]);
10
11
  const DONE_HEADINGS = new Set(["done", "completed", "finished", "archived"]);
@@ -368,11 +369,10 @@ export function readTasksAcrossProjects(phrenPath, profile) {
368
369
  }
369
370
  // Non-primary store projects (no profile — team stores don't have profiles)
370
371
  try {
371
- const { getNonPrimaryStores } = require("../store-registry.js");
372
372
  for (const store of getNonPrimaryStores(phrenPath)) {
373
373
  if (!fs.existsSync(store.path))
374
374
  continue;
375
- const storeProjects = getProjectDirs(store.path).map((dir) => path.basename(dir));
375
+ const storeProjects = getStoreProjectDirs(store).map((dir) => path.basename(dir));
376
376
  for (const project of storeProjects) {
377
377
  if (seen.has(project))
378
378
  continue;