wayfind 2.0.46 → 2.0.48
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/bin/memory-report.sh +1 -1
- package/bin/team-context.js +147 -13
- package/doctor.sh +2 -6
- package/package.json +1 -1
- package/plugin/scripts/session-end.sh +0 -1
- package/plugin/scripts/session-start.sh +0 -1
- package/specializations/claude-code/commands/journal.md +4 -4
- package/specializations/claude-code/commands/standup.md +1 -7
- package/specializations/claude-code/hooks/check-global-state.sh +2 -6
package/bin/memory-report.sh
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# Daily memory systems comparison report — posts to Slack via bot token.
|
|
3
|
-
# Add to crontab: 43 8 * * *
|
|
3
|
+
# Add to crontab: 43 8 * * * $(which wayfind | xargs dirname)/memory-report.sh
|
|
4
4
|
#
|
|
5
5
|
# Runs on host (needs access to ~/.claude/projects for auto-memory).
|
|
6
6
|
# Pulls SLACK_BOT_TOKEN from the wayfind container if not set locally.
|
package/bin/team-context.js
CHANGED
|
@@ -327,28 +327,134 @@ async function teamCreate() {
|
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
async function teamJoin(args) {
|
|
330
|
-
const
|
|
330
|
+
const input = args[0];
|
|
331
|
+
if (!input) {
|
|
332
|
+
console.error('Error: repo URL or path is required.');
|
|
333
|
+
console.error('Usage: wayfind team join <repo-url-or-path>');
|
|
334
|
+
console.error('Example: wayfind team join https://github.com/acme/team-context');
|
|
335
|
+
process.exit(1);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Determine if input is a URL to clone or a local path
|
|
339
|
+
const isUrl = /^https?:\/\/|^git@|^github\.com\//.test(input);
|
|
340
|
+
let repoPath;
|
|
341
|
+
|
|
342
|
+
if (isUrl) {
|
|
343
|
+
// Parse org/repo from URL for clone destination suggestion
|
|
344
|
+
const urlMatch = input.match(/[:/]([^/]+)\/([^/.]+?)(?:\.git)?$/);
|
|
345
|
+
if (!urlMatch) {
|
|
346
|
+
console.error(`Could not parse org/repo from URL: ${input}`);
|
|
347
|
+
process.exit(1);
|
|
348
|
+
}
|
|
349
|
+
const [, org, repo] = urlMatch;
|
|
350
|
+
const orgDir = path.join(HOME, 'repos', org);
|
|
351
|
+
const suggested = fs.existsSync(orgDir)
|
|
352
|
+
? path.join(orgDir, repo)
|
|
353
|
+
: path.join(HOME, '.claude', 'team-context', repo);
|
|
354
|
+
|
|
355
|
+
let dest = suggested;
|
|
356
|
+
if (fs.existsSync(suggested)) {
|
|
357
|
+
console.log(`\nRepo already cloned at: ${suggested}`);
|
|
358
|
+
const useExisting = await ask(`Use existing clone? [Y/n]: `);
|
|
359
|
+
if (useExisting.toLowerCase() === 'n') {
|
|
360
|
+
const custom = await ask(`Clone to [${suggested}]: `);
|
|
361
|
+
dest = custom ? path.resolve(custom.replace(/^~/, HOME)) : suggested;
|
|
362
|
+
}
|
|
363
|
+
} else {
|
|
364
|
+
const confirm = await ask(`\nClone to ${suggested}? [Y/n]: `);
|
|
365
|
+
if (confirm.toLowerCase() === 'n') {
|
|
366
|
+
const custom = await ask(`Clone to: `);
|
|
367
|
+
if (!custom) { console.error('Destination required.'); process.exit(1); }
|
|
368
|
+
dest = path.resolve(custom.replace(/^~/, HOME));
|
|
369
|
+
}
|
|
370
|
+
console.log(`Cloning ${input}...`);
|
|
371
|
+
const cloneUrl = /^https?:\/\//.test(input) ? input : `https://${input}`;
|
|
372
|
+
const result = spawnSync('git', ['clone', cloneUrl, dest], { stdio: 'inherit' });
|
|
373
|
+
if (result.status !== 0) {
|
|
374
|
+
console.error('Clone failed.');
|
|
375
|
+
process.exit(1);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
repoPath = dest;
|
|
379
|
+
} else {
|
|
380
|
+
repoPath = path.resolve(input.replace(/^~/, HOME));
|
|
381
|
+
if (!fs.existsSync(repoPath)) {
|
|
382
|
+
console.error(`Directory not found: ${repoPath}`);
|
|
383
|
+
process.exit(1);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Read wayfind.json from the repo
|
|
388
|
+
const sharedConfig = readJSONFile(path.join(repoPath, 'wayfind.json')) || {};
|
|
389
|
+
const teamId = sharedConfig.team_id;
|
|
331
390
|
if (!teamId) {
|
|
332
|
-
console.error('
|
|
333
|
-
console.error(
|
|
391
|
+
console.error('');
|
|
392
|
+
console.error(`Error: wayfind.json in that repo has no team_id.`);
|
|
393
|
+
console.error('Ask your team admin to run:');
|
|
394
|
+
console.error(` wayfind context add <team-id> ${repoPath}`);
|
|
334
395
|
process.exit(1);
|
|
335
396
|
}
|
|
397
|
+
const teamName = sharedConfig.team_name || teamId;
|
|
398
|
+
const containerEndpoint = sharedConfig.container_endpoint || null;
|
|
336
399
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
400
|
+
// Register in local context.json
|
|
401
|
+
const config = readContextConfig();
|
|
402
|
+
if (!config.teams) config.teams = {};
|
|
403
|
+
const existing = config.teams[teamId];
|
|
404
|
+
config.teams[teamId] = {
|
|
405
|
+
path: repoPath,
|
|
406
|
+
name: teamName,
|
|
407
|
+
configured_at: new Date().toISOString(),
|
|
408
|
+
...(containerEndpoint ? { container_endpoint: containerEndpoint } : {}),
|
|
409
|
+
...(existing && existing.bound_repos ? { bound_repos: existing.bound_repos } : {}),
|
|
340
410
|
};
|
|
411
|
+
if (!config.default) config.default = teamId;
|
|
412
|
+
writeContextConfig(config);
|
|
341
413
|
|
|
342
|
-
|
|
414
|
+
// Check API key status
|
|
415
|
+
const keyFile = path.join(repoPath, '.wayfind-api-key');
|
|
416
|
+
const keyReady = fs.existsSync(keyFile) && (() => {
|
|
417
|
+
try { return fs.readFileSync(keyFile, 'utf8').trim().length >= 32; } catch { return false; }
|
|
418
|
+
})();
|
|
419
|
+
|
|
420
|
+
// Print confirmation
|
|
421
|
+
console.log('');
|
|
422
|
+
console.log(`Joined team '${teamName}' (${teamId})`);
|
|
423
|
+
console.log(` Repo: ${repoPath}`);
|
|
424
|
+
if (containerEndpoint) {
|
|
425
|
+
console.log(` Semantic search: available | ${containerEndpoint}`);
|
|
426
|
+
} else {
|
|
427
|
+
console.log(` Semantic search: not configured`);
|
|
428
|
+
console.log(` Ask your team admin: wayfind deploy set-endpoint ${teamId} <url>`);
|
|
429
|
+
}
|
|
430
|
+
if (keyReady) {
|
|
431
|
+
console.log(` Search API key: ready — rotates daily, committed to team repo`);
|
|
432
|
+
} else {
|
|
433
|
+
console.log(` Search API key: pending — will appear after the container's first key rotation`);
|
|
434
|
+
console.log(` Run \`git pull\` in ${repoPath} after the container starts`);
|
|
435
|
+
}
|
|
436
|
+
console.log('');
|
|
437
|
+
console.log('How the search key works:');
|
|
438
|
+
console.log(' The container rotates this key every 24 hours and commits it to the team repo.');
|
|
439
|
+
console.log(' Your Claude Code sessions read the latest key automatically from the cloned repo.');
|
|
440
|
+
console.log(' You never need to manage it — just keep the repo up to date (git pull).');
|
|
343
441
|
console.log('');
|
|
344
|
-
console.log(
|
|
442
|
+
console.log('Next: bind your repos to this team with:');
|
|
443
|
+
console.log(` wayfind context bind ${teamId} (run from each repo you work in)`);
|
|
345
444
|
|
|
445
|
+
if (existing) {
|
|
446
|
+
console.log('');
|
|
447
|
+
console.log(` (Updated existing registration for team ${teamId})`);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// Register profile in team directory
|
|
346
451
|
const profile = readJSONFile(PROFILE_FILE);
|
|
347
452
|
if (profile) {
|
|
348
453
|
syncMemberToRegistry(profile, teamId);
|
|
349
454
|
await announceToSlack(profile, teamId);
|
|
350
455
|
} else {
|
|
351
|
-
console.log(
|
|
456
|
+
console.log('');
|
|
457
|
+
console.log("Run 'wayfind whoami --setup' to register your profile in the team directory.");
|
|
352
458
|
}
|
|
353
459
|
console.log('');
|
|
354
460
|
}
|
|
@@ -3549,9 +3655,20 @@ function contextAdd(args) {
|
|
|
3549
3655
|
const config = readContextConfig();
|
|
3550
3656
|
if (!config.teams) config.teams = {};
|
|
3551
3657
|
|
|
3552
|
-
//
|
|
3553
|
-
|
|
3658
|
+
// Read and update wayfind.json in the repo — write team_id/team_name so joiners
|
|
3659
|
+
// can read them without needing to know the ID out of band
|
|
3660
|
+
const sharedConfigPath = path.join(resolved, 'wayfind.json');
|
|
3661
|
+
const sharedConfig = readJSONFile(sharedConfigPath) || {};
|
|
3554
3662
|
const teamName = sharedConfig.team_name || teamId;
|
|
3663
|
+
if (!sharedConfig.team_id || !sharedConfig.team_name) {
|
|
3664
|
+
sharedConfig.team_id = teamId;
|
|
3665
|
+
sharedConfig.team_name = teamName;
|
|
3666
|
+
try {
|
|
3667
|
+
fs.writeFileSync(sharedConfigPath, JSON.stringify(sharedConfig, null, 2) + '\n');
|
|
3668
|
+
} catch (err) {
|
|
3669
|
+
console.error(`Warning: could not write wayfind.json: ${err.message}`);
|
|
3670
|
+
}
|
|
3671
|
+
}
|
|
3555
3672
|
|
|
3556
3673
|
config.teams[teamId] = {
|
|
3557
3674
|
path: resolved,
|
|
@@ -3566,6 +3683,23 @@ function contextAdd(args) {
|
|
|
3566
3683
|
if (Object.keys(config.teams).length === 1) {
|
|
3567
3684
|
console.log(' Set as default (only team).');
|
|
3568
3685
|
}
|
|
3686
|
+
|
|
3687
|
+
// Generate first search API key if one doesn't exist yet
|
|
3688
|
+
const keyFile = path.join(resolved, '.wayfind-api-key');
|
|
3689
|
+
if (!fs.existsSync(keyFile)) {
|
|
3690
|
+
const key = crypto.randomBytes(32).toString('hex');
|
|
3691
|
+
try {
|
|
3692
|
+
fs.writeFileSync(keyFile, key + '\n', 'utf8');
|
|
3693
|
+
// Resolve token for git push (CLI context — use gh CLI)
|
|
3694
|
+
const token = detectGitHubToken();
|
|
3695
|
+
if (token && !process.env.GITHUB_TOKEN) process.env.GITHUB_TOKEN = token;
|
|
3696
|
+
pushApiKey(resolved);
|
|
3697
|
+
console.log(' Generated initial search API key → committed to team repo.');
|
|
3698
|
+
console.log(' Teammates who join will read it automatically. It rotates daily.');
|
|
3699
|
+
} catch (err) {
|
|
3700
|
+
console.error(` Warning: could not generate API key: ${err.message}`);
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3569
3703
|
}
|
|
3570
3704
|
|
|
3571
3705
|
function contextBind(args) {
|
|
@@ -5932,8 +6066,8 @@ function showHelp() {
|
|
|
5932
6066
|
console.log(' /doctor Check installation health');
|
|
5933
6067
|
console.log('');
|
|
5934
6068
|
console.log('Team setup:');
|
|
5935
|
-
console.log(' wayfind team create
|
|
5936
|
-
console.log(' wayfind team join <
|
|
6069
|
+
console.log(' wayfind team create Create a new team');
|
|
6070
|
+
console.log(' wayfind team join <repo-url-or-path> Join an existing team');
|
|
5937
6071
|
console.log(' wayfind team status Show current team info');
|
|
5938
6072
|
console.log(' wayfind whoami Show your profile');
|
|
5939
6073
|
console.log(' wayfind whoami --setup Set up your profile and personas');
|
package/doctor.sh
CHANGED
|
@@ -275,9 +275,7 @@ check_team_context_freshness() {
|
|
|
275
275
|
|
|
276
276
|
# Find team-context path via wayfind CLI
|
|
277
277
|
local TEAM_PATH=""
|
|
278
|
-
if
|
|
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
|
|
278
|
+
if command -v wayfind >/dev/null 2>&1; then
|
|
281
279
|
TEAM_PATH=$(wayfind context show 2>/dev/null | grep 'Path:' | head -1 | sed 's/.*Path: *//' || true)
|
|
282
280
|
fi
|
|
283
281
|
|
|
@@ -337,9 +335,7 @@ check_team_versions() {
|
|
|
337
335
|
|
|
338
336
|
# Check min_version from check-version command output
|
|
339
337
|
local CHECK_OUTPUT=""
|
|
340
|
-
if
|
|
341
|
-
CHECK_OUTPUT=$(node "$HOME/repos/greg/wayfind/bin/team-context.js" check-version 2>&1 || true)
|
|
342
|
-
elif command -v wayfind >/dev/null 2>&1; then
|
|
338
|
+
if command -v wayfind >/dev/null 2>&1; then
|
|
343
339
|
CHECK_OUTPUT=$(wayfind check-version 2>&1 || true)
|
|
344
340
|
fi
|
|
345
341
|
|
package/package.json
CHANGED
|
@@ -19,7 +19,6 @@ fi
|
|
|
19
19
|
WAYFIND="$(command -v wayfind 2>/dev/null || echo "")"
|
|
20
20
|
if [ -z "$WAYFIND" ]; then
|
|
21
21
|
for candidate in \
|
|
22
|
-
"$HOME/repos/greg/wayfind/bin/team-context.js" \
|
|
23
22
|
"$HOME/repos/wayfind/bin/team-context.js"; do
|
|
24
23
|
if [ -f "$candidate" ]; then
|
|
25
24
|
WAYFIND="node $candidate"
|
|
@@ -10,7 +10,6 @@ WAYFIND="$(command -v wayfind 2>/dev/null || echo "")"
|
|
|
10
10
|
if [ -z "$WAYFIND" ]; then
|
|
11
11
|
# Try common local checkout paths
|
|
12
12
|
for candidate in \
|
|
13
|
-
"$HOME/repos/greg/wayfind/bin/team-context.js" \
|
|
14
13
|
"$HOME/repos/wayfind/bin/team-context.js"; do
|
|
15
14
|
if [ -f "$candidate" ]; then
|
|
16
15
|
WAYFIND="node $candidate"
|
|
@@ -32,14 +32,14 @@ bash ~/.claude/team-context/journal-summary.sh --dir ~/.ai-memory/memory/journal
|
|
|
32
32
|
|
|
33
33
|
## Step 2: If journal-summary.sh is not installed
|
|
34
34
|
|
|
35
|
-
Run
|
|
35
|
+
Run `wayfind update` to install it:
|
|
36
36
|
```bash
|
|
37
|
-
|
|
37
|
+
wayfind update
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
Or install manually:
|
|
40
|
+
Or install manually from the npm package:
|
|
41
41
|
```bash
|
|
42
|
-
cp
|
|
42
|
+
cp "$(npm root -g)/wayfind/journal-summary.sh" ~/.claude/team-context/journal-summary.sh
|
|
43
43
|
chmod +x ~/.claude/team-context/journal-summary.sh
|
|
44
44
|
```
|
|
45
45
|
|
|
@@ -10,15 +10,9 @@ Show a daily standup summary from journals and state files.
|
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
# Current repo only (default)
|
|
13
|
-
|
|
13
|
+
wayfind standup
|
|
14
14
|
|
|
15
15
|
# All repos
|
|
16
|
-
node ~/repos/greg/wayfind/bin/team-context.js standup --all
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
If the local checkout isn't available:
|
|
20
|
-
```bash
|
|
21
|
-
wayfind standup
|
|
22
16
|
wayfind standup --all
|
|
23
17
|
```
|
|
24
18
|
|
|
@@ -9,12 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
set -euo pipefail
|
|
11
11
|
|
|
12
|
-
# Use
|
|
13
|
-
|
|
14
|
-
if [ -f "$WAYFIND_BIN" ]; then
|
|
15
|
-
node "$WAYFIND_BIN" status --write --quiet 2>/dev/null || true
|
|
16
|
-
node "$WAYFIND_BIN" check-version 2>/dev/null || true
|
|
17
|
-
elif command -v wayfind >/dev/null 2>&1; then
|
|
12
|
+
# Use installed wayfind CLI
|
|
13
|
+
if command -v wayfind >/dev/null 2>&1; then
|
|
18
14
|
wayfind status --write --quiet 2>/dev/null || true
|
|
19
15
|
wayfind check-version 2>/dev/null || true
|
|
20
16
|
fi
|