wayfind 2.0.71 → 2.0.73

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,6 +1,6 @@
1
1
  {
2
2
  "name": "wayfind",
3
- "version": "2.0.71",
3
+ "version": "2.0.73",
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",
@@ -46,7 +46,7 @@
46
46
  "test:all": "npm test && npm run test:sim"
47
47
  },
48
48
  "engines": {
49
- "node": ">=16"
49
+ "node": ">=20"
50
50
  },
51
51
  "dependencies": {
52
52
  "@modelcontextprotocol/sdk": "^1.28.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wayfind",
3
- "version": "2.0.71",
3
+ "version": "2.0.73",
4
4
  "description": "Team decision trail for AI-assisted development. Session memory, decision journals, and team digests.",
5
5
  "author": {
6
6
  "name": "Wayfind",
@@ -7,7 +7,7 @@
7
7
  {
8
8
  "type": "command",
9
9
  "command": "${CLAUDE_PLUGIN_ROOT}/scripts/session-start.sh",
10
- "timeout": 15
10
+ "timeout": 60
11
11
  }
12
12
  ]
13
13
  }
@@ -19,7 +19,7 @@
19
19
  {
20
20
  "type": "command",
21
21
  "command": "${CLAUDE_PLUGIN_ROOT}/scripts/session-end.sh",
22
- "timeout": 30
22
+ "timeout": 20
23
23
  }
24
24
  ]
25
25
  }
@@ -1,16 +1,14 @@
1
1
  #!/usr/bin/env bash
2
2
  # Wayfind plugin — Stop hook
3
- # Runs incremental conversation indexing with journal export after each session.
4
- # Extracted decisions get written to the journal directory so they sync via git
5
- # and the container's journal indexer picks them up.
3
+ # Persists the session: splits journal files by team suffix, then syncs to
4
+ # team-context repo. No LLM calls fast, reliable, durability only.
6
5
  #
7
- # Performance target: <5s for the common case (no new conversations to process).
6
+ # Heavy work (reindex, embeddings, context shift detection) is handled by
7
+ # the container on a schedule, or by the session-start hook for solo users.
8
8
 
9
9
  set -euo pipefail
10
10
 
11
- # Skip export for worker agents in multi-agent swarms.
12
- # Set TEAM_CONTEXT_SKIP_EXPORT=1 when spawning worker agents so only the
13
- # orchestrator's decisions flow into the journal.
11
+ # Skip for worker agents in multi-agent swarms.
14
12
  if [ "${TEAM_CONTEXT_SKIP_EXPORT:-}" = "1" ]; then
15
13
  exit 0
16
14
  fi
@@ -28,29 +26,12 @@ if [ -z "$WAYFIND" ]; then
28
26
  fi
29
27
 
30
28
  if [ -z "$WAYFIND" ]; then
31
- echo "[wayfind] CLI not found — decision extraction skipped. Install: npm install -g wayfind" >&2
32
29
  exit 0
33
30
  fi
34
31
 
35
- # ── Fast path: skip reindex if no conversation files changed ──────────────────
36
- LAST_RUN_FILE="$HOME/.claude/team-context/.last-reindex"
37
- if [ -f "$LAST_RUN_FILE" ]; then
38
- CHANGED=$(find "$HOME/.claude/projects" -name "*.jsonl" -newer "$LAST_RUN_FILE" -print -quit 2>/dev/null)
39
- if [ -z "$CHANGED" ]; then
40
- # No conversation files changed — skip expensive reindex, just split and sync journals
41
- $WAYFIND journal split 2>/dev/null
42
- $WAYFIND journal sync 2>/dev/null &
43
- exit 0
44
- fi
45
- fi
46
-
47
- # Run incremental reindex
48
- $WAYFIND reindex --conversations-only --export --detect-shifts --write-stats 2>/dev/null || true
49
-
50
- # Update the marker so the next session's fast-path check works
51
- mkdir -p "$HOME/.claude/team-context"
52
- touch "$LAST_RUN_FILE"
32
+ # Split any unsuffixed journal files by team (fast, filesystem only)
33
+ $WAYFIND journal split >/dev/null 2>&1 || true
53
34
 
54
- # Split any unsuffixed journals, then sync to team-context repo (sync backgrounded)
55
- $WAYFIND journal split 2>/dev/null
56
- $WAYFIND journal sync 2>/dev/null &
35
+ # Sync journals to team-context repo the durability guarantee.
36
+ # Runs synchronously so the push completes before the hook exits.
37
+ $WAYFIND journal sync 2>/dev/null || true
@@ -1,14 +1,17 @@
1
1
  #!/usr/bin/env bash
2
2
  # Wayfind plugin — SessionStart hook
3
- # Rebuilds the Active Projects index and checks for version updates.
4
- # Runs on every session start via the plugin hook system.
3
+ # Pulls team context, indexes last session's conversations (solo mode only),
4
+ # rebuilds the Active Projects index, then prompts for the session goal.
5
+ #
6
+ # Runs synchronously so the user sees what Wayfind is doing before they type.
7
+ # Solo mode: no container_endpoint configured — reindex runs here instead of
8
+ # in a background container.
5
9
 
6
10
  set -euo pipefail
7
11
 
8
12
  # Find wayfind binary
9
13
  WAYFIND="$(command -v wayfind 2>/dev/null || echo "")"
10
14
  if [ -z "$WAYFIND" ]; then
11
- # Try common local checkout paths
12
15
  for candidate in \
13
16
  "$HOME/repos/wayfind/bin/team-context.js"; do
14
17
  if [ -f "$candidate" ]; then
@@ -19,17 +22,54 @@ if [ -z "$WAYFIND" ]; then
19
22
  fi
20
23
 
21
24
  if [ -z "$WAYFIND" ]; then
22
- # No CLI availableplugin still works for skills, just no automation
23
- echo "[wayfind] CLI not found. Skills work, but install the CLI for full features: npm install -g wayfind" >&2
25
+ echo "[wayfind] CLI not found install for full features: npm install -g wayfind" >&2
24
26
  exit 0
25
27
  fi
26
28
 
27
- # Pull latest team-context in the background so this session sees
28
- # other engineers' recent work without blocking session start
29
- $WAYFIND context pull --quiet --background 2>/dev/null || true
29
+ echo ""
30
+ echo " ── Wayfind ────────────────────────────────────────"
30
31
 
31
- # Rebuild Active Projects table (idempotent, concurrent-safe)
32
+ # Pull latest team context (synchronous — start with fresh state)
33
+ echo ""
34
+ $WAYFIND context pull 2>/dev/null || true
35
+
36
+ # Detect solo mode: no container_endpoint means no background container running reindex
37
+ CONTEXT_JSON="${WAYFIND_DIR:-$HOME/.claude/team-context}/context.json"
38
+ HAS_CONTAINER=false
39
+ if [ -f "$CONTEXT_JSON" ] && grep -q '"container_endpoint"' "$CONTEXT_JSON" 2>/dev/null; then
40
+ HAS_CONTAINER=true
41
+ fi
42
+
43
+ # Solo mode: index last session's conversations now
44
+ # Teams rely on the container's scheduled reindex instead.
45
+ if [ "$HAS_CONTAINER" = "false" ]; then
46
+ LAST_RUN_FILE="${WAYFIND_DIR:-$HOME/.claude/team-context}/.last-reindex"
47
+ SHOULD_REINDEX=true
48
+
49
+ if [ -f "$LAST_RUN_FILE" ]; then
50
+ CHANGED=$(find "$HOME/.claude/projects" -name "*.jsonl" -newer "$LAST_RUN_FILE" -print -quit 2>/dev/null)
51
+ if [ -z "$CHANGED" ]; then
52
+ SHOULD_REINDEX=false
53
+ fi
54
+ fi
55
+
56
+ if [ "$SHOULD_REINDEX" = "true" ]; then
57
+ echo ""
58
+ echo " Indexing last session's conversations..."
59
+ echo ""
60
+ $WAYFIND reindex --conversations-only --export --write-stats 2>/dev/null || true
61
+ mkdir -p "${WAYFIND_DIR:-$HOME/.claude/team-context}"
62
+ touch "$LAST_RUN_FILE"
63
+ fi
64
+ fi
65
+
66
+ # Rebuild Active Projects index (writes to global-state.md)
32
67
  $WAYFIND status --write --quiet 2>/dev/null || true
33
68
 
34
- # Check if installed version meets team minimum
69
+ # Version check silent unless outdated
35
70
  $WAYFIND check-version 2>/dev/null || true
71
+
72
+ echo ""
73
+ echo " What's the goal for this session?"
74
+ echo " ───────────────────────────────────────────────────"
75
+ echo ""
package/setup.sh CHANGED
@@ -145,7 +145,6 @@ if [ ! -d "$SPEC_DIR" ]; then
145
145
  fi
146
146
 
147
147
  echo ""
148
- echo "Installing Wayfind for: $TOOL"
149
148
  [ "$DRY_RUN" = true ] && warn "Dry-run mode — no files will be modified"
150
149
  [ "$UPDATE" = true ] && warn "Update mode: overwriting hook scripts and commands (memory files untouched)"
151
150
 
@@ -184,23 +183,24 @@ case "$TOOL" in
184
183
  ;;
185
184
  esac
186
185
 
187
- # ── Step 1: Directories ────────────────────────────────────────────────────────
186
+ # ── Counters for aggregate output ─────────────────────────────────────────────
187
+
188
+ CONFIG_FILES=0
189
+ HOOKS_INSTALLED=0
190
+ COMMANDS_INSTALLED=0
191
+ MCP_OK=false
188
192
 
189
- header "Creating directories"
193
+ # ── Step 1: Directories ────────────────────────────────────────────────────────
190
194
 
191
195
  run mkdir -p "$MEMORY_SUBDIR/journal"
192
- log "Memory directories: $MEMORY_SUBDIR/journal"
193
196
 
194
197
  if [ "$TOOL" = "claude-code" ]; then
195
198
  run mkdir -p "$HOME/.claude/hooks"
196
199
  run mkdir -p "$HOME/.claude/commands"
197
- log "Claude Code hooks and commands directories"
198
200
  fi
199
201
 
200
202
  # ── Step 2: Global state file ─────────────────────────────────────────────────
201
203
 
202
- header "Global state file"
203
-
204
204
  if [ ! -f "$GLOBAL_STATE" ]; then
205
205
  if [ "$TOOL" = "claude-code" ]; then
206
206
  if [ "$DRY_RUN" = false ]; then
@@ -214,29 +214,18 @@ if [ ! -f "$GLOBAL_STATE" ]; then
214
214
  else
215
215
  run cp "$SCRIPT_DIR/templates/global.md" "$GLOBAL_STATE"
216
216
  fi
217
- log "Created $GLOBAL_STATE"
218
- else
219
- info "Already exists: $GLOBAL_STATE — skipped"
217
+ CONFIG_FILES=$((CONFIG_FILES + 1))
220
218
  fi
221
219
 
222
220
  # ── Step 3: Admin state file (team/personal split) ───────────────────────────
223
- # For team repos, use templates/team-state.md (committed, shared context).
224
- # For personal notes, use templates/personal-state.md (gitignored, private).
225
- # The admin state file at ADMIN_STATE is the non-repo catch-all (email, admin, misc).
226
-
227
- header "Admin state file"
228
221
 
229
222
  if [ ! -f "$ADMIN_STATE" ]; then
230
223
  run cp "$SCRIPT_DIR/templates/repo-state.md" "$ADMIN_STATE"
231
- log "Created $ADMIN_STATE"
232
- else
233
- info "Already exists: $ADMIN_STATE — skipped"
224
+ CONFIG_FILES=$((CONFIG_FILES + 1))
234
225
  fi
235
226
 
236
227
  # ── Step 3b: Persona configuration ────────────────────────────────────────────
237
228
 
238
- header "Persona configuration"
239
-
240
229
  case "$TOOL" in
241
230
  claude-code) PERSONAS_DIR="$HOME/.claude/team-context" ;;
242
231
  *) PERSONAS_DIR="$HOME/.ai-memory/team-context" ;;
@@ -246,15 +235,11 @@ PERSONAS_DEST="$PERSONAS_DIR/personas.json"
246
235
  if [ ! -f "$PERSONAS_DEST" ]; then
247
236
  run mkdir -p "$PERSONAS_DIR"
248
237
  run cp "$SCRIPT_DIR/templates/personas.json" "$PERSONAS_DEST"
249
- log "Created $PERSONAS_DEST (default personas — edit to customize)"
250
- else
251
- info "Already exists: $PERSONAS_DEST — skipped (your customizations are preserved)"
238
+ CONFIG_FILES=$((CONFIG_FILES + 1))
252
239
  fi
253
240
 
254
241
  # ── Step 4: Tool-specific files ───────────────────────────────────────────────
255
242
 
256
- header "Tool-specific files ($TOOL)"
257
-
258
243
  case "$TOOL" in
259
244
  claude-code)
260
245
  # Global CLAUDE.md fragment
@@ -263,9 +248,10 @@ case "$TOOL" in
263
248
  info "[dry-run] Would append Session State Protocol to $GLOBAL_CLAUDE_MD"
264
249
  else
265
250
  touch "$GLOBAL_CLAUDE_MD"
266
- append_if_missing "Session State Protocol" \
267
- "$(cat "$SPEC_DIR/CLAUDE.md-global-fragment.md")" \
268
- "$GLOBAL_CLAUDE_MD"
251
+ if ! grep -qF "Session State Protocol" "$GLOBAL_CLAUDE_MD" 2>/dev/null; then
252
+ cat "$SPEC_DIR/CLAUDE.md-global-fragment.md" >> "$GLOBAL_CLAUDE_MD"
253
+ CONFIG_FILES=$((CONFIG_FILES + 1))
254
+ fi
269
255
  fi
270
256
  fi
271
257
 
@@ -274,88 +260,63 @@ case "$TOOL" in
274
260
  if [ ! -f "$HOOK_DEST" ] || [ "$UPDATE" = true ]; then
275
261
  run cp "$SPEC_DIR/hooks/check-global-state.sh" "$HOOK_DEST"
276
262
  run chmod +x "$HOOK_DEST"
277
- log "Installed hook: $HOOK_DEST"
278
- else
279
- info "Hook already exists: $HOOK_DEST — skipped"
263
+ HOOKS_INSTALLED=$((HOOKS_INSTALLED + 1))
280
264
  fi
281
265
 
282
266
  SESSION_END_DEST="$HOME/.claude/hooks/session-end.sh"
283
267
  if [ ! -f "$SESSION_END_DEST" ] || [ "$UPDATE" = true ]; then
284
268
  run cp "$SPEC_DIR/hooks/session-end.sh" "$SESSION_END_DEST"
285
269
  run chmod +x "$SESSION_END_DEST"
286
- log "Installed hook: $SESSION_END_DEST"
287
- else
288
- info "Hook already exists: $SESSION_END_DEST — skipped"
270
+ HOOKS_INSTALLED=$((HOOKS_INSTALLED + 1))
289
271
  fi
290
272
 
291
- # init-memory command
273
+ # Commands
292
274
  CMD_DEST="$HOME/.claude/commands/init-memory.md"
293
275
  if [ ! -f "$CMD_DEST" ] || [ "$UPDATE" = true ]; then
294
276
  run cp "$SPEC_DIR/commands/init-memory.md" "$CMD_DEST"
295
- log "Installed command: /init-memory"
296
- else
297
- info "/init-memory command already exists — skipped"
277
+ COMMANDS_INSTALLED=$((COMMANDS_INSTALLED + 1))
298
278
  fi
299
279
 
300
- # doctor command
301
280
  DOCTOR_CMD_DEST="$HOME/.claude/commands/doctor.md"
302
281
  if [ ! -f "$DOCTOR_CMD_DEST" ] || [ "$UPDATE" = true ]; then
303
282
  run cp "$SPEC_DIR/commands/doctor.md" "$DOCTOR_CMD_DEST"
304
- log "Installed command: /doctor"
305
- else
306
- info "/doctor command already exists — skipped"
283
+ COMMANDS_INSTALLED=$((COMMANDS_INSTALLED + 1))
307
284
  fi
308
285
 
309
- # doctor.sh script
286
+ # Support scripts
310
287
  run mkdir -p "$HOME/.claude/team-context"
311
288
  DOCTOR_DEST="$HOME/.claude/team-context/doctor.sh"
312
289
  if [ ! -f "$DOCTOR_DEST" ] || [ "$UPDATE" = true ]; then
313
290
  run cp "$SCRIPT_DIR/doctor.sh" "$DOCTOR_DEST"
314
291
  run chmod +x "$DOCTOR_DEST"
315
- log "Installed doctor script: $DOCTOR_DEST"
316
- else
317
- info "doctor.sh already exists: $DOCTOR_DEST — skipped"
318
292
  fi
319
293
 
320
- # journal-summary.sh script
321
294
  JOURNAL_DEST="$HOME/.claude/team-context/journal-summary.sh"
322
295
  if [ ! -f "$JOURNAL_DEST" ] || [ "$UPDATE" = true ]; then
323
296
  run cp "$SCRIPT_DIR/journal-summary.sh" "$JOURNAL_DEST"
324
297
  run chmod +x "$JOURNAL_DEST"
325
- log "Installed journal summary script: $JOURNAL_DEST"
326
- else
327
- info "journal-summary.sh already exists: $JOURNAL_DEST — skipped"
328
298
  fi
329
299
 
330
- # /journal command
331
300
  JOURNAL_CMD_DEST="$HOME/.claude/commands/journal.md"
332
301
  if [ ! -f "$JOURNAL_CMD_DEST" ] || [ "$UPDATE" = true ]; then
333
302
  run cp "$SPEC_DIR/commands/journal.md" "$JOURNAL_CMD_DEST"
334
- log "Installed command: /journal"
335
- else
336
- info "/journal command already exists — skipped"
303
+ COMMANDS_INSTALLED=$((COMMANDS_INSTALLED + 1))
337
304
  fi
338
305
 
339
- # /init-team command
340
306
  TEAM_CMD_DEST="$HOME/.claude/commands/init-team.md"
341
307
  if [ ! -f "$TEAM_CMD_DEST" ] || [ "$UPDATE" = true ]; then
342
308
  if [ -f "$SPEC_DIR/commands/init-team.md" ]; then
343
309
  run cp "$SPEC_DIR/commands/init-team.md" "$TEAM_CMD_DEST"
344
- log "Installed command: /init-team"
310
+ COMMANDS_INSTALLED=$((COMMANDS_INSTALLED + 1))
345
311
  fi
346
- else
347
- info "/init-team command already exists — skipped"
348
312
  fi
349
313
 
350
- # /review-prs command
351
314
  REVIEW_CMD_DEST="$HOME/.claude/commands/review-prs.md"
352
315
  if [ ! -f "$REVIEW_CMD_DEST" ] || [ "$UPDATE" = true ]; then
353
316
  if [ -f "$SPEC_DIR/commands/review-prs.md" ]; then
354
317
  run cp "$SPEC_DIR/commands/review-prs.md" "$REVIEW_CMD_DEST"
355
- log "Installed command: /review-prs"
318
+ COMMANDS_INSTALLED=$((COMMANDS_INSTALLED + 1))
356
319
  fi
357
- else
358
- info "/review-prs command already exists — skipped"
359
320
  fi
360
321
 
361
322
  # settings.json — merge hooks, don't overwrite
@@ -365,7 +326,7 @@ case "$TOOL" in
365
326
 
366
327
  if [ ! -f "$SETTINGS" ]; then
367
328
  run cp "$SPEC_DIR/settings.json" "$SETTINGS"
368
- log "Created $SETTINGS with hook registration"
329
+ CONFIG_FILES=$((CONFIG_FILES + 1))
369
330
  else
370
331
  # Merge both hooks into existing settings.json using Python
371
332
  NEEDS_MERGE=false
@@ -426,7 +387,6 @@ with open(out_path, "w") as f:
426
387
  f.write("\n")
427
388
  PYEOF
428
389
  mv "$TMP_SETTINGS" "$SETTINGS"
429
- log "Merged hooks into existing $SETTINGS"
430
390
  else
431
391
  rm -f "$TMP_SETTINGS"
432
392
  warn "Could not auto-merge hooks into $SETTINGS (malformed JSON or python3 unavailable)."
@@ -435,8 +395,6 @@ PYEOF
435
395
  else
436
396
  info "[dry-run] Would merge hooks into $SETTINGS"
437
397
  fi
438
- else
439
- info "Hooks already registered in settings.json — skipped"
440
398
  fi
441
399
  fi
442
400
 
@@ -469,20 +427,19 @@ with open(out_path, "w") as f:
469
427
  f.write("\n")
470
428
  PYEOF
471
429
  mv "$TMP_SETTINGS" "$SETTINGS"
472
- log "Registered wayfind MCP server in ~/.claude/settings.json"
430
+ MCP_OK=true
473
431
  else
474
432
  rm -f "$TMP_SETTINGS"
475
- warn "Could not register MCP server — add manually to ~/.claude/settings.json:"
476
- warn " \"mcpServers\": { \"wayfind\": { \"command\": \"$MCP_BIN\" } }"
433
+ warn "Could not register MCP server — add manually to ~/.claude/settings.json"
477
434
  fi
478
435
  else
479
436
  info "[dry-run] Would register wayfind MCP server ($MCP_BIN) in $SETTINGS"
480
437
  fi
481
438
  else
482
- info "MCP server already registered in settings.json — skipped"
439
+ MCP_OK=true
483
440
  fi
484
441
  else
485
- warn "wayfind-mcp binary not found — skipping MCP registration. Re-run after npm install."
442
+ warn "wayfind-mcp not found — MCP registration skipped. Re-run setup after npm install."
486
443
  fi
487
444
 
488
445
  ;;
@@ -493,9 +450,7 @@ PYEOF
493
450
  GLOBAL_RULE="$HOME/.cursor/rules/ai-memory.mdc"
494
451
  if [ ! -f "$GLOBAL_RULE" ] || [ "${UPDATE:-false}" = true ]; then
495
452
  run cp "$SPEC_DIR/global-rule.mdc" "$GLOBAL_RULE"
496
- log "Installed global Cursor rule: $GLOBAL_RULE"
497
- else
498
- info "Global Cursor rule already exists — skipped"
453
+ CONFIG_FILES=$((CONFIG_FILES + 1))
499
454
  fi
500
455
 
501
456
  # Per-repo rule (if --repo was passed)
@@ -505,8 +460,7 @@ PYEOF
505
460
  run mkdir -p "$RULE_DIR"
506
461
  if [ ! -f "$RULE_DIR/memory.mdc" ] || [ "${UPDATE:-false}" = true ]; then
507
462
  run cp "$SPEC_DIR/repo-rule.mdc" "$RULE_DIR/memory.mdc"
508
- log "Installed repo rule: $RULE_DIR/memory.mdc"
509
- warn "Edit $RULE_DIR/memory.mdc to add repo name and initial status"
463
+ CONFIG_FILES=$((CONFIG_FILES + 1))
510
464
  else
511
465
  info "Repo rule already exists — skipped"
512
466
  fi
@@ -530,7 +484,7 @@ PYEOF
530
484
  if [ "$DRY_RUN" = false ]; then
531
485
  if [ ! -f "$CURSOR_MCP" ]; then
532
486
  printf '{\n "mcpServers": {\n "wayfind": {\n "command": "%s",\n "args": []\n }\n }\n}\n' "$CURSOR_MCP_BIN" > "$CURSOR_MCP"
533
- log "Created ~/.cursor/mcp.json with wayfind MCP server"
487
+ MCP_OK=true
534
488
  else
535
489
  TMP_MCP="$(mktemp)"
536
490
  if python3 - "$CURSOR_MCP" "$CURSOR_MCP_BIN" "$TMP_MCP" <<'PYEOF' 2>/dev/null; then
@@ -549,21 +503,20 @@ with open(out_path, "w") as f:
549
503
  f.write("\n")
550
504
  PYEOF
551
505
  mv "$TMP_MCP" "$CURSOR_MCP"
552
- log "Registered wayfind MCP server in ~/.cursor/mcp.json"
506
+ MCP_OK=true
553
507
  else
554
508
  rm -f "$TMP_MCP"
555
- warn "Could not register MCP server — add manually to ~/.cursor/mcp.json:"
556
- warn " \"mcpServers\": { \"wayfind\": { \"command\": \"$CURSOR_MCP_BIN\", \"args\": [] } }"
509
+ warn "Could not register MCP server — add manually to ~/.cursor/mcp.json"
557
510
  fi
558
511
  fi
559
512
  else
560
513
  info "[dry-run] Would register wayfind MCP server ($CURSOR_MCP_BIN) in ~/.cursor/mcp.json"
561
514
  fi
562
515
  else
563
- info "MCP server already registered in ~/.cursor/mcp.json — skipped"
516
+ MCP_OK=true
564
517
  fi
565
518
  else
566
- warn "wayfind-mcp binary not found — skipping Cursor MCP registration. Re-run after npm install."
519
+ warn "wayfind-mcp not found — MCP registration skipped. Re-run setup after npm install."
567
520
  fi
568
521
  ;;
569
522
 
@@ -591,7 +544,6 @@ if [ -n "$INSTALL_VERSION" ]; then
591
544
  TMP_VER="$(mktemp)"
592
545
  echo "$INSTALL_VERSION" > "$TMP_VER"
593
546
  mv "$TMP_VER" "$VERSION_DEST"
594
- log "Version v${INSTALL_VERSION} written to $VERSION_DEST"
595
547
  else
596
548
  info "[dry-run] Would write v${INSTALL_VERSION} to $KIT_DEST_DIR/.wayfind-version"
597
549
  fi
@@ -658,7 +610,27 @@ fi
658
610
  # ── Summary ──────────────────────────────────────────────────────────────────
659
611
 
660
612
  echo ""
661
- echo -e "${GREEN}✓${RESET} Wayfind installed."
613
+
614
+ # Aggregate summary of what was installed
615
+ SUMMARY_PARTS=""
616
+ [ "$CONFIG_FILES" -gt 0 ] && SUMMARY_PARTS="${SUMMARY_PARTS}${CONFIG_FILES} config files"
617
+ if [ "$HOOKS_INSTALLED" -gt 0 ]; then
618
+ [ -n "$SUMMARY_PARTS" ] && SUMMARY_PARTS="${SUMMARY_PARTS}, "
619
+ SUMMARY_PARTS="${SUMMARY_PARTS}${HOOKS_INSTALLED} hooks"
620
+ fi
621
+ if [ "$COMMANDS_INSTALLED" -gt 0 ]; then
622
+ [ -n "$SUMMARY_PARTS" ] && SUMMARY_PARTS="${SUMMARY_PARTS}, "
623
+ SUMMARY_PARTS="${SUMMARY_PARTS}${COMMANDS_INSTALLED} commands"
624
+ fi
625
+ if [ "$MCP_OK" = true ]; then
626
+ [ -n "$SUMMARY_PARTS" ] && SUMMARY_PARTS="${SUMMARY_PARTS}, "
627
+ SUMMARY_PARTS="${SUMMARY_PARTS}MCP server"
628
+ fi
629
+ if [ -n "$SUMMARY_PARTS" ]; then
630
+ log "Created ${SUMMARY_PARTS}"
631
+ fi
632
+
633
+ echo -e "${GREEN}✓${RESET} Wayfind installed for ${TOOL}."
662
634
  echo ""
663
635
 
664
636
  if [ "$TOOL" = "claude-code" ]; then
@@ -1,16 +1,14 @@
1
1
  #!/usr/bin/env bash
2
- # Wayfind session-end hook
3
- # Runs incremental conversation indexing with journal export after each session.
4
- # Extracted decisions get written to the journal directory so they sync via git
5
- # and the container's journal indexer picks them up.
2
+ # Wayfind session-end hook (standalone / pre-plugin install)
3
+ # Persists the session: splits journal files by team suffix, then syncs to
4
+ # team-context repo. No LLM calls fast, reliable, durability only.
6
5
  #
7
- # Performance target: <5s for the common case (no new conversations to process).
6
+ # Heavy work (reindex, embeddings, context shift detection) is handled by
7
+ # the container on a schedule, or by the session-start hook for solo users.
8
8
 
9
9
  set -euo pipefail
10
10
 
11
- # Skip export for worker agents in multi-agent swarms.
12
- # Set TEAM_CONTEXT_SKIP_EXPORT=1 when spawning worker agents so only the
13
- # orchestrator's decisions flow into the journal.
11
+ # Skip for worker agents in multi-agent swarms.
14
12
  if [ "${TEAM_CONTEXT_SKIP_EXPORT:-}" = "1" ]; then
15
13
  exit 0
16
14
  fi
@@ -18,39 +16,23 @@ fi
18
16
  # Find wayfind binary
19
17
  WAYFIND="$(command -v wayfind 2>/dev/null || echo "")"
20
18
  if [ -z "$WAYFIND" ]; then
21
- # Try npx
22
- if command -v npx &>/dev/null; then
23
- WAYFIND="npx --yes wayfind"
24
- else
25
- exit 0
26
- fi
19
+ for candidate in \
20
+ "$HOME/repos/wayfind/bin/team-context.js"; do
21
+ if [ -f "$candidate" ]; then
22
+ WAYFIND="node $candidate"
23
+ break
24
+ fi
25
+ done
27
26
  fi
28
27
 
29
- # ── Fast path: skip reindex if no conversation files changed ──────────────────
30
- # The full reindex pipeline (load store, scan transcripts, hash check, LLM calls)
31
- # has a ~2-3s baseline cost even when nothing changed. This filesystem check
32
- # short-circuits in <50ms for the common case.
33
- LAST_RUN_FILE="$HOME/.claude/team-context/.last-reindex"
34
- if [ -f "$LAST_RUN_FILE" ]; then
35
- CHANGED=$(find "$HOME/.claude/projects" -name "*.jsonl" -newer "$LAST_RUN_FILE" 2>/dev/null | head -1)
36
- if [ -z "$CHANGED" ]; then
37
- # No conversation files changed — skip expensive reindex, just sync journals
38
- $WAYFIND journal sync 2>/dev/null &
39
- exit 0
40
- fi
28
+ if [ -z "$WAYFIND" ]; then
29
+ echo "[wayfind] CLI not found decision extraction skipped. Install: npm install -g wayfind" >&2
30
+ exit 0
41
31
  fi
42
32
 
43
- # Run incremental reindex (conversations only — journals are handled by the journal write itself)
44
- # --conversations-only: skip journals (just written by the session, no need to re-index)
45
- # --export: write extracted decisions as journal entries for git sync
46
- # --detect-shifts: auto-update state files when significant context shifts are detected
47
- # --write-stats: write session stats JSON for status line display
48
- $WAYFIND reindex --conversations-only --export --detect-shifts --write-stats 2>/dev/null || true
49
-
50
- # Update the marker so the next session's fast-path check works
51
- mkdir -p "$HOME/.claude/team-context"
52
- touch "$LAST_RUN_FILE"
33
+ # Split any unsuffixed journal files by team (fast, filesystem only)
34
+ $WAYFIND journal split >/dev/null 2>&1 || true
53
35
 
54
- # Sync authored journals to team-context repo (commit + push) — backgrounded
55
- # so the session can exit immediately. Git push is the slowest part (~1-3s).
56
- $WAYFIND journal sync 2>/dev/null &
36
+ # Sync journals to team-context repo the durability guarantee.
37
+ # Runs synchronously so the push completes before the hook exits.
38
+ $WAYFIND journal sync 2>/dev/null || true