wayfind 2.0.31 → 2.0.32

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.
@@ -3283,9 +3283,12 @@ async function runContext(args) {
3283
3283
  case 'default':
3284
3284
  contextSetDefault(subArgs);
3285
3285
  break;
3286
+ case 'pull':
3287
+ contextPull(subArgs);
3288
+ break;
3286
3289
  default:
3287
3290
  console.error(`Unknown context subcommand: ${sub}`);
3288
- console.error('Available: init, sync, show, add, bind, list, default');
3291
+ console.error('Available: init, sync, show, add, bind, list, default, pull');
3289
3292
  process.exit(1);
3290
3293
  }
3291
3294
  }
@@ -3428,6 +3431,61 @@ function contextSync() {
3428
3431
  console.log(`\nSynced ${synced} file(s) to .claude/context/`);
3429
3432
  }
3430
3433
 
3434
+ /**
3435
+ * Pull latest from the team-context repo so session state reflects
3436
+ * other engineers' recent work. Called by the session-start hook.
3437
+ *
3438
+ * Behavior:
3439
+ * - Pulls the team-context repo (journals, signals, shared context)
3440
+ * - Skips gracefully if offline, if pull fails, or if repo is dirty
3441
+ * - Does NOT touch the current working repo — devs handle that themselves
3442
+ * - Designed to run within the session-start hook's timeout
3443
+ *
3444
+ * @param {string[]} args - CLI arguments (--quiet suppresses output)
3445
+ */
3446
+ function contextPull(args) {
3447
+ const quiet = args.includes('--quiet');
3448
+ const background = args.includes('--background');
3449
+ const log = quiet ? () => {} : console.log;
3450
+
3451
+ const teamPath = getTeamContextPath();
3452
+ if (!teamPath || !fs.existsSync(path.join(teamPath, '.git'))) {
3453
+ if (!quiet) log('[wayfind] No team-context repo configured — skipping pull');
3454
+ return;
3455
+ }
3456
+
3457
+ const markerFile = path.join(teamPath, '.last-pull');
3458
+
3459
+ if (background) {
3460
+ // Fire-and-forget — don't block session start
3461
+ const child = require('child_process').spawn(
3462
+ process.execPath,
3463
+ [__filename, 'context', 'pull', '--quiet'],
3464
+ { stdio: 'ignore', detached: true, env: { ...process.env } }
3465
+ );
3466
+ child.unref();
3467
+ return;
3468
+ }
3469
+
3470
+ const result = spawnSync('git', ['-C', teamPath, 'pull', '--rebase', '--autostash', '--quiet'], {
3471
+ stdio: 'pipe',
3472
+ timeout: 10000,
3473
+ });
3474
+
3475
+ if (result.status === 0) {
3476
+ log('[wayfind] Pulled latest team-context');
3477
+ // Mark success — doctor checks this to warn on prolonged failures
3478
+ try { fs.writeFileSync(markerFile, new Date().toISOString()); } catch {}
3479
+ } else if (result.error && result.error.code === 'ETIMEDOUT') {
3480
+ log('[wayfind] Team-context pull timed out — using local state');
3481
+ } else {
3482
+ const stderr = (result.stderr || '').toString().trim();
3483
+ if (stderr && !quiet) {
3484
+ console.error(`[wayfind] Team-context pull skipped: ${stderr.split('\n')[0]}`);
3485
+ }
3486
+ }
3487
+ }
3488
+
3431
3489
  function contextShow() {
3432
3490
  const config = readContextConfig();
3433
3491
  const repoBinding = readRepoTeamBinding();
@@ -5001,8 +5059,9 @@ const COMMANDS = {
5001
5059
  }
5002
5060
  console.log('Sanitization passed — no proprietary content detected.');
5003
5061
 
5004
- // Show what changed
5005
- const diffResult = spawnSync('git', ['status', '--short'], { cwd: tmpDir, stdio: 'pipe' });
5062
+ // Refresh git index so status detects copied files reliably
5063
+ spawnSync('git', ['add', '-A'], { cwd: tmpDir, stdio: 'pipe' });
5064
+ const diffResult = spawnSync('git', ['diff', '--cached', '--name-only'], { cwd: tmpDir, stdio: 'pipe' });
5006
5065
  const changes = (diffResult.stdout || '').toString().trim();
5007
5066
 
5008
5067
  if (!changes) {
package/doctor.sh CHANGED
@@ -269,6 +269,54 @@ check_memory_files() {
269
269
  [ "$COUNT" -gt 0 ] && ok "$COUNT memory file(s) found" || info "No memory files yet"
270
270
  }
271
271
 
272
+ check_team_context_freshness() {
273
+ echo ""
274
+ echo "Team context sync"
275
+
276
+ # Find team-context path via wayfind CLI
277
+ local TEAM_PATH=""
278
+ if [ -f "$HOME/repos/greg/wayfind/bin/team-context.js" ]; then
279
+ TEAM_PATH=$(node "$HOME/repos/greg/wayfind/bin/team-context.js" context show 2>/dev/null | grep 'Path:' | head -1 | sed 's/.*Path: *//' || true)
280
+ elif command -v wayfind >/dev/null 2>&1; then
281
+ TEAM_PATH=$(wayfind context show 2>/dev/null | grep 'Path:' | head -1 | sed 's/.*Path: *//' || true)
282
+ fi
283
+
284
+ if [ -z "$TEAM_PATH" ] || [ ! -d "$TEAM_PATH" ]; then
285
+ info "No team-context repo configured (optional)"
286
+ return
287
+ fi
288
+
289
+ local MARKER="$TEAM_PATH/.last-pull"
290
+ if [ ! -f "$MARKER" ]; then
291
+ # No pull has ever succeeded — check if this is a fresh install
292
+ # by looking at the git log age instead
293
+ local LAST_COMMIT
294
+ LAST_COMMIT=$(git -C "$TEAM_PATH" log -1 --format='%ci' 2>/dev/null || echo "")
295
+ if [ -z "$LAST_COMMIT" ]; then
296
+ info "Team-context repo exists but has no commits"
297
+ else
298
+ ok "Team-context configured (pull marker will appear after next session start)"
299
+ fi
300
+ return
301
+ fi
302
+
303
+ local PULL_TIME
304
+ PULL_TIME=$(cat "$MARKER")
305
+ local PULL_EPOCH
306
+ PULL_EPOCH=$(date -d "$PULL_TIME" +%s 2>/dev/null || date -j -f "%Y-%m-%dT%H:%M:%S" "${PULL_TIME%%.*}" +%s 2>/dev/null || echo 0)
307
+ local NOW_EPOCH
308
+ NOW_EPOCH=$(date +%s)
309
+ local AGE_HOURS=$(( (NOW_EPOCH - PULL_EPOCH) / 3600 ))
310
+
311
+ if [ "$AGE_HOURS" -gt 24 ]; then
312
+ warn "Team-context last pulled ${AGE_HOURS}h ago — other engineers' context may be stale"
313
+ info "Run: wayfind context pull"
314
+ ISSUES=$((ISSUES + 1))
315
+ else
316
+ ok "Team-context pulled ${AGE_HOURS}h ago"
317
+ fi
318
+ }
319
+
272
320
  check_team_versions() {
273
321
  echo ""
274
322
  echo "Team version compliance"
@@ -330,6 +378,7 @@ echo "══════════════════════"
330
378
  check_hook_registered
331
379
  check_global_state
332
380
  check_backup
381
+ check_team_context_freshness
333
382
  check_team_versions
334
383
  check_storage_backend
335
384
  check_memory_files
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wayfind",
3
- "version": "2.0.31",
3
+ "version": "2.0.32",
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"
@@ -25,6 +25,10 @@ if [ -z "$WAYFIND" ]; then
25
25
  exit 0
26
26
  fi
27
27
 
28
+ # Pull latest team-context in the background so this session sees
29
+ # other engineers' recent work without blocking session start
30
+ $WAYFIND context pull --quiet --background 2>/dev/null || true
31
+
28
32
  # Rebuild Active Projects table (idempotent, concurrent-safe)
29
33
  $WAYFIND status --write --quiet 2>/dev/null || true
30
34