wayfind 2.0.67 → 2.0.69

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.
@@ -816,7 +816,7 @@ function applyFilters(entry, filters) {
816
816
  if (filters.since && entry.date < filters.since) return false;
817
817
  if (filters.until && entry.date > filters.until) return false;
818
818
  if (filters.drifted !== undefined && entry.drifted !== filters.drifted) return false;
819
- if (filters.user && entry.user && entry.user.toLowerCase() !== filters.user.toLowerCase()) return false;
819
+ if (filters.user && (!entry.user || entry.user.toLowerCase() !== filters.user.toLowerCase())) return false;
820
820
  return true;
821
821
  }
822
822
 
package/bin/slack-bot.js CHANGED
@@ -554,6 +554,47 @@ function stripTemporalWords(query) {
554
554
  .join(' ');
555
555
  }
556
556
 
557
+ /**
558
+ * Detect a person's name in a query and resolve it to an author slug.
559
+ * Looks in members/ profiles for a name match. Falls back to naive first-name match.
560
+ * Returns lowercase slug or null.
561
+ */
562
+ function resolveAuthorFromQuery(query, config) {
563
+ const membersDir = resolveMembersDir(config);
564
+ const knownAuthors = [];
565
+
566
+ if (membersDir) {
567
+ try {
568
+ const files = fs.readdirSync(membersDir).filter(f => f.endsWith('.json'));
569
+ for (const file of files) {
570
+ try {
571
+ const m = JSON.parse(fs.readFileSync(path.join(membersDir, file), 'utf8'));
572
+ const slug = file.replace('.json', '').toLowerCase();
573
+ const name = (m.name || '').toLowerCase();
574
+ const firstName = name.split(/\s+/)[0];
575
+ knownAuthors.push({ slug, name, firstName });
576
+ } catch {}
577
+ }
578
+ } catch {}
579
+ }
580
+
581
+ const q = query.toLowerCase();
582
+ // Check for person-directed query patterns
583
+ const personMatch = q.match(/\b(?:did|has|have|from|by|about|for)\s+([a-z]+)\b/i);
584
+ if (!personMatch) return null;
585
+ const candidate = personMatch[1].toLowerCase();
586
+
587
+ // Match against known members
588
+ for (const a of knownAuthors) {
589
+ if (a.slug === candidate || a.firstName === candidate || a.name === candidate) {
590
+ return a.slug;
591
+ }
592
+ }
593
+
594
+ // If no members dir, just use the extracted name as a slug
595
+ return candidate.length > 2 ? candidate : null;
596
+ }
597
+
557
598
  async function searchDecisionTrail(query, config) {
558
599
  const searchOpts = {
559
600
  limit: MAX_SEARCH_RESULTS,
@@ -568,6 +609,10 @@ async function searchDecisionTrail(query, config) {
568
609
  searchOpts.repos = config._repoFilter;
569
610
  }
570
611
 
612
+ // If query is about a specific person, filter to their entries
613
+ const authorFilter = resolveAuthorFromQuery(query, config);
614
+ if (authorFilter) searchOpts.user = authorFilter;
615
+
571
616
  // Resolve temporal references to date filters
572
617
  const dateFilters = resolveDateFilters(query);
573
618
  if (dateFilters.since) searchOpts.since = dateFilters.since;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wayfind",
3
- "version": "2.0.67",
3
+ "version": "2.0.69",
4
4
  "description": "Team decision trail for AI-assisted development. The connective tissue between product, engineering, and strategy.",
5
5
  "bin": {
6
6
  "wayfind": "./bin/team-context.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wayfind",
3
- "version": "2.0.67",
3
+ "version": "2.0.69",
4
4
  "description": "Team decision trail for AI-assisted development. Session memory, decision journals, and team digests.",
5
5
  "author": {
6
6
  "name": "Wayfind",