spidersan 0.20.1 → 0.20.2
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/CHANGELOG.md +8 -0
- package/dist/bin/command-registry.d.ts +25 -0
- package/dist/bin/command-registry.d.ts.map +1 -0
- package/dist/bin/command-registry.js +29 -0
- package/dist/bin/command-registry.js.map +1 -0
- package/dist/bin/spidersan.d.ts +16 -0
- package/dist/bin/spidersan.d.ts.map +1 -0
- package/dist/bin/spidersan.js +98 -0
- package/dist/bin/spidersan.js.map +1 -0
- package/dist/commands/abandon.d.ts +8 -0
- package/dist/commands/abandon.d.ts.map +1 -0
- package/dist/commands/abandon.js +43 -0
- package/dist/commands/abandon.js.map +1 -0
- package/dist/commands/cleanup.d.ts +8 -0
- package/dist/commands/cleanup.d.ts.map +1 -0
- package/dist/commands/cleanup.js +50 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/config.d.ts +15 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +309 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/conflicts.d.ts +34 -0
- package/dist/commands/conflicts.d.ts.map +1 -0
- package/dist/commands/conflicts.js +773 -0
- package/dist/commands/conflicts.js.map +1 -0
- package/dist/commands/context.d.ts +8 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +104 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/cross-conflicts.d.ts +17 -0
- package/dist/commands/cross-conflicts.d.ts.map +1 -0
- package/dist/commands/cross-conflicts.js +273 -0
- package/dist/commands/cross-conflicts.js.map +1 -0
- package/dist/commands/depends.d.ts +11 -0
- package/dist/commands/depends.d.ts.map +1 -0
- package/dist/commands/depends.js +63 -0
- package/dist/commands/depends.js.map +1 -0
- package/dist/commands/doctor.d.ts +30 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +558 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/git-watch.d.ts +24 -0
- package/dist/commands/git-watch.d.ts.map +1 -0
- package/dist/commands/git-watch.js +84 -0
- package/dist/commands/git-watch.js.map +1 -0
- package/dist/commands/github-sync.d.ts +42 -0
- package/dist/commands/github-sync.d.ts.map +1 -0
- package/dist/commands/github-sync.js +191 -0
- package/dist/commands/github-sync.js.map +1 -0
- package/dist/commands/index.d.ts +25 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +29 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +23 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +45 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/log.d.ts +7 -0
- package/dist/commands/log.d.ts.map +1 -0
- package/dist/commands/log.js +110 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/merge-order.d.ts +9 -0
- package/dist/commands/merge-order.d.ts.map +1 -0
- package/dist/commands/merge-order.js +100 -0
- package/dist/commands/merge-order.js.map +1 -0
- package/dist/commands/merged.d.ts +8 -0
- package/dist/commands/merged.d.ts.map +1 -0
- package/dist/commands/merged.js +37 -0
- package/dist/commands/merged.js.map +1 -0
- package/dist/commands/pr-check.d.ts +24 -0
- package/dist/commands/pr-check.d.ts.map +1 -0
- package/dist/commands/pr-check.js +85 -0
- package/dist/commands/pr-check.js.map +1 -0
- package/dist/commands/ready-check.d.ts +11 -0
- package/dist/commands/ready-check.d.ts.map +1 -0
- package/dist/commands/ready-check.js +150 -0
- package/dist/commands/ready-check.js.map +1 -0
- package/dist/commands/rebase-helper.d.ts +3 -0
- package/dist/commands/rebase-helper.d.ts.map +1 -0
- package/dist/commands/rebase-helper.js +52 -0
- package/dist/commands/rebase-helper.js.map +1 -0
- package/dist/commands/register.d.ts +10 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +176 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/registry-sync.d.ts +9 -0
- package/dist/commands/registry-sync.d.ts.map +1 -0
- package/dist/commands/registry-sync.js +129 -0
- package/dist/commands/registry-sync.js.map +1 -0
- package/dist/commands/stale.d.ts +17 -0
- package/dist/commands/stale.d.ts.map +1 -0
- package/dist/commands/stale.js +136 -0
- package/dist/commands/stale.js.map +1 -0
- package/dist/commands/sync.d.ts +21 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +78 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/verify-trunk.d.ts +18 -0
- package/dist/commands/verify-trunk.d.ts.map +1 -0
- package/dist/commands/verify-trunk.js +77 -0
- package/dist/commands/verify-trunk.js.map +1 -0
- package/dist/commands/watch.d.ts +8 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +509 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/activity.d.ts +53 -0
- package/dist/lib/activity.d.ts.map +1 -0
- package/dist/lib/activity.js +271 -0
- package/dist/lib/activity.js.map +1 -0
- package/dist/lib/agent-errors.d.ts +41 -0
- package/dist/lib/agent-errors.d.ts.map +1 -0
- package/dist/lib/agent-errors.js +145 -0
- package/dist/lib/agent-errors.js.map +1 -0
- package/dist/lib/ai/context-builder.d.ts +16 -0
- package/dist/lib/ai/context-builder.d.ts.map +1 -0
- package/dist/lib/ai/context-builder.js +229 -0
- package/dist/lib/ai/context-builder.js.map +1 -0
- package/dist/lib/ai/event-handler.d.ts +21 -0
- package/dist/lib/ai/event-handler.d.ts.map +1 -0
- package/dist/lib/ai/event-handler.js +111 -0
- package/dist/lib/ai/event-handler.js.map +1 -0
- package/dist/lib/ai/index.d.ts +13 -0
- package/dist/lib/ai/index.d.ts.map +1 -0
- package/dist/lib/ai/index.js +11 -0
- package/dist/lib/ai/index.js.map +1 -0
- package/dist/lib/ai/llm-client.d.ts +37 -0
- package/dist/lib/ai/llm-client.d.ts.map +1 -0
- package/dist/lib/ai/llm-client.js +225 -0
- package/dist/lib/ai/llm-client.js.map +1 -0
- package/dist/lib/ai/reasoner.d.ts +11 -0
- package/dist/lib/ai/reasoner.d.ts.map +1 -0
- package/dist/lib/ai/reasoner.js +227 -0
- package/dist/lib/ai/reasoner.js.map +1 -0
- package/dist/lib/ai/setup.d.ts +40 -0
- package/dist/lib/ai/setup.d.ts.map +1 -0
- package/dist/lib/ai/setup.js +154 -0
- package/dist/lib/ai/setup.js.map +1 -0
- package/dist/lib/ai/types.d.ts +135 -0
- package/dist/lib/ai/types.d.ts.map +1 -0
- package/dist/lib/ai/types.js +42 -0
- package/dist/lib/ai/types.js.map +1 -0
- package/dist/lib/ast.d.ts +44 -0
- package/dist/lib/ast.d.ts.map +1 -0
- package/dist/lib/ast.js +160 -0
- package/dist/lib/ast.js.map +1 -0
- package/dist/lib/carries.d.ts +22 -0
- package/dist/lib/carries.d.ts.map +1 -0
- package/dist/lib/carries.js +56 -0
- package/dist/lib/carries.js.map +1 -0
- package/dist/lib/colony-subscriber.d.ts +56 -0
- package/dist/lib/colony-subscriber.d.ts.map +1 -0
- package/dist/lib/colony-subscriber.js +265 -0
- package/dist/lib/colony-subscriber.js.map +1 -0
- package/dist/lib/config.d.ts +62 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +235 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/conflict-analyzer.d.ts +33 -0
- package/dist/lib/conflict-analyzer.d.ts.map +1 -0
- package/dist/lib/conflict-analyzer.js +114 -0
- package/dist/lib/conflict-analyzer.js.map +1 -0
- package/dist/lib/conflict-renderer.d.ts +7 -0
- package/dist/lib/conflict-renderer.d.ts.map +1 -0
- package/dist/lib/conflict-renderer.js +145 -0
- package/dist/lib/conflict-renderer.js.map +1 -0
- package/dist/lib/conflict-tier.d.ts +20 -0
- package/dist/lib/conflict-tier.d.ts.map +1 -0
- package/dist/lib/conflict-tier.js +49 -0
- package/dist/lib/conflict-tier.js.map +1 -0
- package/dist/lib/crypto.d.ts +71 -0
- package/dist/lib/crypto.d.ts.map +1 -0
- package/dist/lib/crypto.js +176 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/ecosystem-env.d.ts +33 -0
- package/dist/lib/ecosystem-env.d.ts.map +1 -0
- package/dist/lib/ecosystem-env.js +62 -0
- package/dist/lib/ecosystem-env.js.map +1 -0
- package/dist/lib/errors.d.ts +35 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +71 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/git-events-subscriber.d.ts +86 -0
- package/dist/lib/git-events-subscriber.d.ts.map +1 -0
- package/dist/lib/git-events-subscriber.js +870 -0
- package/dist/lib/git-events-subscriber.js.map +1 -0
- package/dist/lib/git-merge-analyzer.d.ts +38 -0
- package/dist/lib/git-merge-analyzer.d.ts.map +1 -0
- package/dist/lib/git-merge-analyzer.js +23 -0
- package/dist/lib/git-merge-analyzer.js.map +1 -0
- package/dist/lib/git.d.ts +103 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +670 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/github.d.ts +151 -0
- package/dist/lib/github.d.ts.map +1 -0
- package/dist/lib/github.js +425 -0
- package/dist/lib/github.js.map +1 -0
- package/dist/lib/graph.d.ts +38 -0
- package/dist/lib/graph.d.ts.map +1 -0
- package/dist/lib/graph.js +165 -0
- package/dist/lib/graph.js.map +1 -0
- package/dist/lib/machine.d.ts +14 -0
- package/dist/lib/machine.d.ts.map +1 -0
- package/dist/lib/machine.js +38 -0
- package/dist/lib/machine.js.map +1 -0
- package/dist/lib/notify.d.ts +68 -0
- package/dist/lib/notify.d.ts.map +1 -0
- package/dist/lib/notify.js +111 -0
- package/dist/lib/notify.js.map +1 -0
- package/dist/lib/outline.d.ts +6 -0
- package/dist/lib/outline.d.ts.map +1 -0
- package/dist/lib/outline.js +60 -0
- package/dist/lib/outline.js.map +1 -0
- package/dist/lib/push-registry.d.ts +22 -0
- package/dist/lib/push-registry.d.ts.map +1 -0
- package/dist/lib/push-registry.js +21 -0
- package/dist/lib/push-registry.js.map +1 -0
- package/dist/lib/reconcile.d.ts +100 -0
- package/dist/lib/reconcile.d.ts.map +1 -0
- package/dist/lib/reconcile.js +121 -0
- package/dist/lib/reconcile.js.map +1 -0
- package/dist/lib/regex-utils.d.ts +6 -0
- package/dist/lib/regex-utils.d.ts.map +1 -0
- package/dist/lib/regex-utils.js +24 -0
- package/dist/lib/regex-utils.js.map +1 -0
- package/dist/lib/register-renderer.d.ts +10 -0
- package/dist/lib/register-renderer.d.ts.map +1 -0
- package/dist/lib/register-renderer.js +19 -0
- package/dist/lib/register-renderer.js.map +1 -0
- package/dist/lib/remote-drift.d.ts +61 -0
- package/dist/lib/remote-drift.d.ts.map +1 -0
- package/dist/lib/remote-drift.js +227 -0
- package/dist/lib/remote-drift.js.map +1 -0
- package/dist/lib/security.d.ts +72 -0
- package/dist/lib/security.d.ts.map +1 -0
- package/dist/lib/security.js +180 -0
- package/dist/lib/security.js.map +1 -0
- package/dist/lib/semantic-analysis.d.ts +31 -0
- package/dist/lib/semantic-analysis.d.ts.map +1 -0
- package/dist/lib/semantic-analysis.js +120 -0
- package/dist/lib/semantic-analysis.js.map +1 -0
- package/dist/lib/supabase-credentials.d.ts +36 -0
- package/dist/lib/supabase-credentials.d.ts.map +1 -0
- package/dist/lib/supabase-credentials.js +43 -0
- package/dist/lib/supabase-credentials.js.map +1 -0
- package/dist/lib/trunk.d.ts +39 -0
- package/dist/lib/trunk.d.ts.map +1 -0
- package/dist/lib/trunk.js +116 -0
- package/dist/lib/trunk.js.map +1 -0
- package/dist/lib/update-check.d.ts +11 -0
- package/dist/lib/update-check.d.ts.map +1 -0
- package/dist/lib/update-check.js +113 -0
- package/dist/lib/update-check.js.map +1 -0
- package/dist/lib/watch-renderer.d.ts +13 -0
- package/dist/lib/watch-renderer.d.ts.map +1 -0
- package/dist/lib/watch-renderer.js +35 -0
- package/dist/lib/watch-renderer.js.map +1 -0
- package/dist/storage/adapter.d.ts +81 -0
- package/dist/storage/adapter.d.ts.map +1 -0
- package/dist/storage/adapter.js +8 -0
- package/dist/storage/adapter.js.map +1 -0
- package/dist/storage/branch-registry-store.d.ts +13 -0
- package/dist/storage/branch-registry-store.d.ts.map +1 -0
- package/dist/storage/branch-registry-store.js +2 -0
- package/dist/storage/branch-registry-store.js.map +1 -0
- package/dist/storage/factory.d.ts +6 -0
- package/dist/storage/factory.d.ts.map +1 -0
- package/dist/storage/factory.js +14 -0
- package/dist/storage/factory.js.map +1 -0
- package/dist/storage/index.d.ts +10 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +11 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/json-branch-registry-store.d.ts +19 -0
- package/dist/storage/json-branch-registry-store.d.ts.map +1 -0
- package/dist/storage/json-branch-registry-store.js +138 -0
- package/dist/storage/json-branch-registry-store.js.map +1 -0
- package/dist/storage/local.d.ts +20 -0
- package/dist/storage/local.d.ts.map +1 -0
- package/dist/storage/local.js +40 -0
- package/dist/storage/local.js.map +1 -0
- package/dist/storage/memory-branch-registry-store.d.ts +16 -0
- package/dist/storage/memory-branch-registry-store.d.ts.map +1 -0
- package/dist/storage/memory-branch-registry-store.js +68 -0
- package/dist/storage/memory-branch-registry-store.js.map +1 -0
- package/dist/storage/supabase-registry-sync-client-impl.d.ts +40 -0
- package/dist/storage/supabase-registry-sync-client-impl.d.ts.map +1 -0
- package/dist/storage/supabase-registry-sync-client-impl.js +278 -0
- package/dist/storage/supabase-registry-sync-client-impl.js.map +1 -0
- package/dist/storage/supabase-registry-sync-client.d.ts +9 -0
- package/dist/storage/supabase-registry-sync-client.d.ts.map +1 -0
- package/dist/storage/supabase-registry-sync-client.js +2 -0
- package/dist/storage/supabase-registry-sync-client.js.map +1 -0
- package/dist/storage/supabase.d.ts +28 -0
- package/dist/storage/supabase.d.ts.map +1 -0
- package/dist/storage/supabase.js +56 -0
- package/dist/storage/supabase.js.map +1 -0
- package/dist/types/cloud.d.ts +102 -0
- package/dist/types/cloud.d.ts.map +1 -0
- package/dist/types/cloud.js +13 -0
- package/dist/types/cloud.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { getStorage } from '../storage/index.js';
|
|
3
|
+
import * as readline from 'readline';
|
|
4
|
+
import { loadConfig } from '../lib/config.js';
|
|
5
|
+
import { getChangedFiles, getCurrentBranch } from '../lib/git.js';
|
|
6
|
+
import { getTrunkBranch } from '../lib/trunk.js';
|
|
7
|
+
import { validateAgentId, sanitizeFilePaths, validateFilePath } from '../lib/security.js';
|
|
8
|
+
import { logActivity } from '../lib/activity.js';
|
|
9
|
+
import { renderRegisterResult } from '../lib/register-renderer.js';
|
|
10
|
+
// Git execution is centralized in ../lib/git.js via execFileSync('git', [...]).
|
|
11
|
+
// Path segments that are never meaningful for conflict tracking (matched anywhere in the path)
|
|
12
|
+
const EXCLUDED_PATH_SEGMENTS = [
|
|
13
|
+
'/node_modules/',
|
|
14
|
+
'/.git/',
|
|
15
|
+
'/dist/',
|
|
16
|
+
'/build/',
|
|
17
|
+
'/.next/',
|
|
18
|
+
'/target/', // Rust/Cargo build output
|
|
19
|
+
'/.turbo/',
|
|
20
|
+
'/.cache/',
|
|
21
|
+
];
|
|
22
|
+
export function isExcludedPath(file) {
|
|
23
|
+
// Normalise: wrap in slashes so segment patterns match at the start too
|
|
24
|
+
const normalised = `/${file}/`;
|
|
25
|
+
return EXCLUDED_PATH_SEGMENTS.some(seg => normalised.includes(seg));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The Claude Code session running this command, or undefined. The id is written to the
|
|
29
|
+
* registry and later printed into agent context, so accept only a plain UUID-ish token.
|
|
30
|
+
*/
|
|
31
|
+
export function resolveSessionId(env = process.env) {
|
|
32
|
+
const id = env.CLAUDE_CODE_SESSION_ID?.trim();
|
|
33
|
+
return id && /^[0-9a-f][0-9a-f-]{7,63}$/i.test(id) ? id : undefined;
|
|
34
|
+
}
|
|
35
|
+
export function validateRegistrationFiles(files) {
|
|
36
|
+
for (const file of files) {
|
|
37
|
+
validateFilePath(file);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function getRelevantChangedFiles() {
|
|
41
|
+
return getChangedFiles({ base: getTrunkBranch() }).filter((file) => !isExcludedPath(file));
|
|
42
|
+
}
|
|
43
|
+
async function promptForFiles(detectedFiles) {
|
|
44
|
+
const rl = readline.createInterface({
|
|
45
|
+
input: process.stdin,
|
|
46
|
+
output: process.stdout
|
|
47
|
+
});
|
|
48
|
+
return new Promise((resolve) => {
|
|
49
|
+
if (detectedFiles.length > 0) {
|
|
50
|
+
console.log('\n🕷️ Detected changed files:');
|
|
51
|
+
detectedFiles.forEach((f, i) => console.log(` ${i + 1}. ${f}`));
|
|
52
|
+
console.log('');
|
|
53
|
+
rl.question('Use these files? [Y/n/edit]: ', (answer) => {
|
|
54
|
+
rl.close();
|
|
55
|
+
const a = answer.toLowerCase().trim();
|
|
56
|
+
if (a === '' || a === 'y' || a === 'yes') {
|
|
57
|
+
resolve(detectedFiles);
|
|
58
|
+
}
|
|
59
|
+
else if (a === 'n' || a === 'no') {
|
|
60
|
+
resolve([]);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// Let them enter custom files
|
|
64
|
+
console.log(' Enter comma-separated files, or leave empty:');
|
|
65
|
+
const rl2 = readline.createInterface({
|
|
66
|
+
input: process.stdin,
|
|
67
|
+
output: process.stdout
|
|
68
|
+
});
|
|
69
|
+
rl2.question(' Files: ', (files) => {
|
|
70
|
+
rl2.close();
|
|
71
|
+
resolve(files ? files.split(',').map(f => f.trim()) : []);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
rl.question('Enter files (comma-separated) or leave empty: ', (files) => {
|
|
78
|
+
rl.close();
|
|
79
|
+
resolve(files ? files.split(',').map(f => f.trim()) : []);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
export const registerCommand = new Command('register')
|
|
85
|
+
.description('Register the current branch with files being modified')
|
|
86
|
+
.option('-f, --files <files>', 'Comma-separated list of files being modified')
|
|
87
|
+
.option('-d, --description <desc>', 'Description of what this branch does')
|
|
88
|
+
.option('-a, --agent <agent>', 'Agent identifier (e.g., claude-code, cursor)')
|
|
89
|
+
.option('-i, --interactive', 'Interactive mode (prompt for files)')
|
|
90
|
+
.option('--auto', 'Auto-detect files from git diff')
|
|
91
|
+
.action(async (options) => {
|
|
92
|
+
const storage = await getStorage();
|
|
93
|
+
const config = await loadConfig();
|
|
94
|
+
if (!await storage.isInitialized()) {
|
|
95
|
+
console.error('❌ Spidersan not initialized. Run: spidersan init');
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
const branchName = getCurrentBranch();
|
|
99
|
+
let files = [];
|
|
100
|
+
if (options.files) {
|
|
101
|
+
files = sanitizeFilePaths(options.files.split(',').map((f) => f.trim()).filter((f) => f && !isExcludedPath(f)));
|
|
102
|
+
}
|
|
103
|
+
else if (options.auto) {
|
|
104
|
+
files = getRelevantChangedFiles();
|
|
105
|
+
}
|
|
106
|
+
else if (options.interactive) {
|
|
107
|
+
const detected = getRelevantChangedFiles();
|
|
108
|
+
files = await promptForFiles(detected);
|
|
109
|
+
}
|
|
110
|
+
// Security: Validate ALL file paths before storing (Sentinel 2026-02-18)
|
|
111
|
+
try {
|
|
112
|
+
validateRegistrationFiles(files);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
if (err instanceof Error) {
|
|
116
|
+
console.error(`❌ Security Error: ${err.message}`);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
console.error('❌ Security Error: Invalid file path');
|
|
120
|
+
}
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
const configuredAgent = config.agent.name?.trim();
|
|
124
|
+
const rawAgent = (options.agent || process.env.SPIDERSAN_AGENT || configuredAgent || '').trim() || undefined;
|
|
125
|
+
let resolvedAgent = rawAgent;
|
|
126
|
+
if (resolvedAgent) {
|
|
127
|
+
try {
|
|
128
|
+
resolvedAgent = validateAgentId(resolvedAgent);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
console.error(`❌ Invalid agent ID: "${resolvedAgent}". Must be alphanumeric with - or _.`);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const sessionId = resolveSessionId();
|
|
136
|
+
// Check if branch already registered
|
|
137
|
+
const existing = await storage.get(branchName);
|
|
138
|
+
if (existing) {
|
|
139
|
+
// Update existing registration
|
|
140
|
+
await storage.update(branchName, {
|
|
141
|
+
files: [...new Set([...existing.files, ...files])],
|
|
142
|
+
description: options.description || existing.description,
|
|
143
|
+
agent: resolvedAgent ?? existing.agent,
|
|
144
|
+
// latest session to touch the branch is the live one
|
|
145
|
+
sessionId: sessionId ?? existing.sessionId,
|
|
146
|
+
});
|
|
147
|
+
console.log(renderRegisterResult({
|
|
148
|
+
branchName,
|
|
149
|
+
files,
|
|
150
|
+
isUpdate: true,
|
|
151
|
+
autoDetected: !!options.auto,
|
|
152
|
+
autoDetectedFiles: files,
|
|
153
|
+
}));
|
|
154
|
+
logActivity({ event: 'register', branch: branchName, agent: resolvedAgent ?? undefined, details: { files, description: options.description, updated: true } });
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// New registration
|
|
158
|
+
await storage.register({
|
|
159
|
+
name: branchName,
|
|
160
|
+
files,
|
|
161
|
+
status: 'active',
|
|
162
|
+
description: options.description,
|
|
163
|
+
agent: resolvedAgent,
|
|
164
|
+
...(sessionId ? { sessionId } : {}),
|
|
165
|
+
});
|
|
166
|
+
console.log(renderRegisterResult({
|
|
167
|
+
branchName,
|
|
168
|
+
files,
|
|
169
|
+
isUpdate: false,
|
|
170
|
+
autoDetected: !!options.auto,
|
|
171
|
+
autoDetectedFiles: files,
|
|
172
|
+
}));
|
|
173
|
+
logActivity({ event: 'register', branch: branchName, agent: resolvedAgent ?? undefined, details: { files, description: options.description } });
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spidersan registry-sync
|
|
3
|
+
*
|
|
4
|
+
* Sync local registry to/from Supabase for cross-machine awareness.
|
|
5
|
+
* Part of F1: Supabase Registry Sync (spidersan-github-dashboard).
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
export declare const registrySyncCommand: Command;
|
|
9
|
+
//# sourceMappingURL=registry-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-sync.d.ts","sourceRoot":"","sources":["../../src/commands/registry-sync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmCpC,eAAO,MAAM,mBAAmB,SA4G1B,CAAC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spidersan registry-sync
|
|
3
|
+
*
|
|
4
|
+
* Sync local registry to/from Supabase for cross-machine awareness.
|
|
5
|
+
* Part of F1: Supabase Registry Sync (spidersan-github-dashboard).
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { execFileSync } from 'child_process';
|
|
9
|
+
import { LocalStorage } from '../storage/local.js';
|
|
10
|
+
import { SupabaseStorage } from '../storage/supabase.js';
|
|
11
|
+
import { resolveSupabaseCredentials } from '../lib/supabase-credentials.js';
|
|
12
|
+
import { loadMachineIdentity } from '../lib/machine.js';
|
|
13
|
+
import { getRepoName, registryRepoNames } from '../lib/git.js';
|
|
14
|
+
/**
|
|
15
|
+
* Get the repo root path.
|
|
16
|
+
*/
|
|
17
|
+
function getRepoPath() {
|
|
18
|
+
try {
|
|
19
|
+
return execFileSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf-8' }).trim();
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return process.cwd();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get a SupabaseStorage instance, or null if not configured.
|
|
27
|
+
*/
|
|
28
|
+
async function getSupabaseStorage() {
|
|
29
|
+
// COLONY_SUPABASE_* used to sit in this chain as a last-resort fallback. It
|
|
30
|
+
// is gone deliberately: colony is a different Supabase project, so that
|
|
31
|
+
// fallback could push spider_registries into the wrong database (tb-ly0b).
|
|
32
|
+
const creds = await resolveSupabaseCredentials();
|
|
33
|
+
if (!creds)
|
|
34
|
+
return null;
|
|
35
|
+
return new SupabaseStorage(creds);
|
|
36
|
+
}
|
|
37
|
+
export const registrySyncCommand = new Command('registry-sync')
|
|
38
|
+
.description('Sync local registry to/from Supabase (cross-machine awareness)')
|
|
39
|
+
.option('--push', 'Push local registry to Supabase')
|
|
40
|
+
.option('--pull', 'Pull other machines\' registries from Supabase')
|
|
41
|
+
.option('--status', 'Show sync status across all machines')
|
|
42
|
+
.option('--repo <name>', 'Limit to specific repo (default: current)')
|
|
43
|
+
.action(async (options) => {
|
|
44
|
+
const supabase = await getSupabaseStorage();
|
|
45
|
+
if (!supabase) {
|
|
46
|
+
console.error('❌ Supabase not configured. Set SUPABASE_URL and SUPABASE_KEY.');
|
|
47
|
+
console.error(' Registry sync requires cloud storage for cross-machine awareness.');
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
const machine = await loadMachineIdentity();
|
|
51
|
+
const repoName = options.repo || getRepoName();
|
|
52
|
+
// Default to --status if no flag specified
|
|
53
|
+
if (!options.push && !options.pull && !options.status) {
|
|
54
|
+
options.status = true;
|
|
55
|
+
}
|
|
56
|
+
// ── PUSH ──
|
|
57
|
+
if (options.push) {
|
|
58
|
+
console.log(`🕷️ Pushing registry from ${machine.name} (${repoName})...\n`);
|
|
59
|
+
const localStorage = new LocalStorage();
|
|
60
|
+
if (!await localStorage.isInitialized()) {
|
|
61
|
+
console.error('❌ Spidersan not initialized. Run: spidersan init');
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
const branches = await localStorage.list();
|
|
65
|
+
const repoPath = getRepoPath();
|
|
66
|
+
const result = await supabase.pushRegistry(machine, repoName, repoPath, branches);
|
|
67
|
+
if (result.errors.length > 0) {
|
|
68
|
+
for (const err of result.errors) {
|
|
69
|
+
console.error(` ❌ ${err}`);
|
|
70
|
+
}
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
console.log(` ✅ Pushed ${result.pushed} active branch(es)`);
|
|
74
|
+
if (result.updated > 0)
|
|
75
|
+
console.log(` 🔄 Updated ${result.updated} non-active branch(es)`);
|
|
76
|
+
if (result.abandoned > 0)
|
|
77
|
+
console.log(` 🗑️ Marked ${result.abandoned} removed branch(es) as abandoned`);
|
|
78
|
+
for (const name of result.abandonedBranches)
|
|
79
|
+
console.log(` - ${name}`);
|
|
80
|
+
console.log(`\n Machine: ${machine.name} (${machine.hostname})`);
|
|
81
|
+
console.log(` Repo: ${repoName}`);
|
|
82
|
+
}
|
|
83
|
+
// ── PULL ──
|
|
84
|
+
if (options.pull) {
|
|
85
|
+
console.log(`🕷️ Pulling registries for ${repoName} (excluding ${machine.name})...\n`);
|
|
86
|
+
const views = await supabase.pullRegistries(options.repo ? [options.repo] : registryRepoNames(), machine.id);
|
|
87
|
+
if (views.length === 0) {
|
|
88
|
+
console.log(' No other machines have registered branches for this repo.');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
for (const view of views) {
|
|
92
|
+
console.log(` 📡 ${view.machine_name} (${view.hostname}) — ${view.branches.length} branch(es)`);
|
|
93
|
+
console.log(` Last sync: ${new Date(view.last_synced).toLocaleString()}\n`);
|
|
94
|
+
for (const branch of view.branches) {
|
|
95
|
+
const files = branch.files.length > 0 ? ` [${branch.files.length} files]` : '';
|
|
96
|
+
const agent = branch.agent ? ` (${branch.agent})` : '';
|
|
97
|
+
console.log(` • ${branch.name}${agent}${files}`);
|
|
98
|
+
if (branch.description) {
|
|
99
|
+
console.log(` ${branch.description}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
console.log('');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// ── STATUS ──
|
|
106
|
+
if (options.status) {
|
|
107
|
+
console.log(`🕷️ Registry sync status${options.repo ? ` (${repoName})` : ' (all repos)'}:\n`);
|
|
108
|
+
const statuses = await supabase.getRegistryStatus(options.repo ? repoName : undefined);
|
|
109
|
+
if (statuses.length === 0) {
|
|
110
|
+
console.log(' No registries synced yet. Run: spidersan registry-sync --push');
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
// Table header
|
|
114
|
+
console.log(' Machine Hostname Branches Active Repos Last Sync');
|
|
115
|
+
console.log(' ───────── ────────── ──────── ────── ───── ─────────');
|
|
116
|
+
for (const s of statuses) {
|
|
117
|
+
const isSelf = s.machine_id === machine.id ? ' ⭐' : '';
|
|
118
|
+
const repos = s.repos.join(', ');
|
|
119
|
+
const lastSync = new Date(s.last_sync).toLocaleString();
|
|
120
|
+
console.log(` ${(s.machine_name + isSelf).padEnd(14)}` +
|
|
121
|
+
`${s.hostname.padEnd(15)}` +
|
|
122
|
+
`${String(s.branch_count).padEnd(10)}` +
|
|
123
|
+
`${String(s.active_count).padEnd(8)}` +
|
|
124
|
+
`${repos.padEnd(17)}` +
|
|
125
|
+
`${lastSync}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
//# sourceMappingURL=registry-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-sync.js","sourceRoot":"","sources":["../../src/commands/registry-sync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE/D;;GAEG;AACH,SAAS,WAAW;IAChB,IAAI,CAAC;QACD,OAAO,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/F,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;IACzB,CAAC;AACL,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,kBAAkB;IAC7B,4EAA4E;IAC5E,wEAAwE;IACxE,2EAA2E;IAC3E,MAAM,KAAK,GAAG,MAAM,0BAA0B,EAAE,CAAC;IACjD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,OAAO,CAAC,eAAe,CAAC;KAC1D,WAAW,CAAC,gEAAgE,CAAC;KAC7E,MAAM,CAAC,QAAQ,EAAE,iCAAiC,CAAC;KACnD,MAAM,CAAC,QAAQ,EAAE,gDAAgD,CAAC;KAClE,MAAM,CAAC,UAAU,EAAE,sCAAsC,CAAC;KAC1D,MAAM,CAAC,eAAe,EAAE,2CAA2C,CAAC;KACpE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,MAAM,QAAQ,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC5C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;QAC/E,OAAO,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;QACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC;IAE/C,2CAA2C;IAC3C,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED,aAAa;IACb,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,6BAA6B,OAAO,CAAC,IAAI,KAAK,QAAQ,QAAQ,CAAC,CAAC;QAE5E,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,YAAY,CAAC,aAAa,EAAE,EAAE,CAAC;YACtC,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;YAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAE/B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAElF,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC9B,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;YAChC,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,MAAM,oBAAoB,CAAC,CAAC;QAC7D,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,OAAO,wBAAwB,CAAC,CAAC;QAC5F,IAAI,MAAM,CAAC,SAAS,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,SAAS,kCAAkC,CAAC,CAAC;QAC3G,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,iBAAiB;YAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,WAAW,QAAQ,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,aAAa;IACb,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,8BAA8B,QAAQ,eAAe,OAAO,CAAC,IAAI,QAAQ,CAAC,CAAC;QAEvF,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,iBAAiB,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QAE7G,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;YAC3E,OAAO;QACX,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,aAAa,CAAC,CAAC;YACjG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;YAEhF,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvD,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,IAAI,GAAG,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC;gBACrD,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;oBACrB,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;gBAChD,CAAC;YACL,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;IACL,CAAC;IAED,eAAe;IACf,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,2BAA2B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,GAAG,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,CAAC;QAE9F,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAEvF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;YAC/E,OAAO;QACX,CAAC;QAED,eAAe;QACf,OAAO,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAC;QAC1F,OAAO,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAC;QAE1F,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,CAAC,CAAC,UAAU,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjC,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAC;YACxD,OAAO,CAAC,GAAG,CACP,KAAK,CAAC,CAAC,CAAC,YAAY,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;gBAC3C,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;gBAC1B,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;gBACtC,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;gBACrC,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;gBACrB,GAAG,QAAQ,EAAE,CAChB,CAAC;QACN,CAAC;IACL,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spidersan stale
|
|
3
|
+
*
|
|
4
|
+
* Show branches that haven't been updated recently.
|
|
5
|
+
* With --notify flag: sends notifications to branch owners via .pending_task.md updates.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
/**
|
|
9
|
+
* Update agent's .pending_task.md file
|
|
10
|
+
* ⚡ Bolt: Batched updates to avoid N+1 file I/O
|
|
11
|
+
*/
|
|
12
|
+
export declare function updatePendingTaskFile(agentId: string, branches: {
|
|
13
|
+
name: string;
|
|
14
|
+
daysOld: number;
|
|
15
|
+
}[]): boolean;
|
|
16
|
+
export declare const staleCommand: Command;
|
|
17
|
+
//# sourceMappingURL=stale.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stale.d.ts","sourceRoot":"","sources":["../../src/commands/stale.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,OAAO,CAiD7G;AAED,eAAO,MAAM,YAAY,SAwFnB,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spidersan stale
|
|
3
|
+
*
|
|
4
|
+
* Show branches that haven't been updated recently.
|
|
5
|
+
* With --notify flag: sends notifications to branch owners via .pending_task.md updates.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { getStorage } from '../storage/index.js';
|
|
9
|
+
import { existsSync, readFileSync, appendFileSync } from 'fs';
|
|
10
|
+
import { resolve } from 'path';
|
|
11
|
+
import { validateAgentId, validateBranchName } from '../lib/security.js';
|
|
12
|
+
/**
|
|
13
|
+
* Update agent's .pending_task.md file
|
|
14
|
+
* ⚡ Bolt: Batched updates to avoid N+1 file I/O
|
|
15
|
+
*/
|
|
16
|
+
export function updatePendingTaskFile(agentId, branches) {
|
|
17
|
+
if (branches.length === 0)
|
|
18
|
+
return true;
|
|
19
|
+
try {
|
|
20
|
+
// Security: Validate inputs
|
|
21
|
+
validateAgentId(agentId);
|
|
22
|
+
for (const b of branches) {
|
|
23
|
+
validateBranchName(b.name);
|
|
24
|
+
}
|
|
25
|
+
// Agent-OWNED locations only. The cwd's .pending_task.md belongs to
|
|
26
|
+
// whoever runs `stale --notify`, not to `agentId` — writing there
|
|
27
|
+
// "delivers" every agent's notifications to the wrong file.
|
|
28
|
+
const possiblePaths = [
|
|
29
|
+
resolve(process.env.HOME || '~', `Dev/treebird/agents/${agentId}/.pending_task.md`),
|
|
30
|
+
resolve(process.cwd(), `../${agentId}/.pending_task.md`),
|
|
31
|
+
resolve(process.env.HOME || '~', `Dev/${agentId}/.pending_task.md`),
|
|
32
|
+
];
|
|
33
|
+
let taskFilePath = null;
|
|
34
|
+
for (const path of possiblePaths) {
|
|
35
|
+
if (existsSync(path)) {
|
|
36
|
+
taskFilePath = path;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (!taskFilePath) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
const content = readFileSync(taskFilePath, 'utf-8');
|
|
44
|
+
let newEntries = '';
|
|
45
|
+
for (const b of branches) {
|
|
46
|
+
// Check if entry already exists
|
|
47
|
+
if (!content.includes(b.name)) {
|
|
48
|
+
newEntries += `- [ ] 🕷️ Stale branch: \`${b.name}\` (${b.daysOld}d inactive) - run \`spidersan cleanup\`\n`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (newEntries.length > 0) {
|
|
52
|
+
appendFileSync(taskFilePath, newEntries, 'utf-8');
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export const staleCommand = new Command('stale')
|
|
61
|
+
.description('Show stale branches (not updated recently)')
|
|
62
|
+
.option('--days <n>', 'Days threshold for staleness', '7')
|
|
63
|
+
.option('--notify', 'Send notifications to branch owners')
|
|
64
|
+
.option('--auto-cleanup', 'Automatically remove stale branches after listing')
|
|
65
|
+
.option('--json', 'Output as JSON')
|
|
66
|
+
.action(async (options) => {
|
|
67
|
+
const storage = await getStorage();
|
|
68
|
+
if (!await storage.isInitialized()) {
|
|
69
|
+
console.error('❌ Spidersan not initialized. Run: spidersan init');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
const days = parseInt(options.days, 10);
|
|
73
|
+
if (!Number.isFinite(days) || days < 0) {
|
|
74
|
+
console.error(`❌ Invalid --days value: ${options.days}`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
const threshold = new Date();
|
|
78
|
+
threshold.setDate(threshold.getDate() - days);
|
|
79
|
+
const branches = await storage.list();
|
|
80
|
+
const stale = branches.filter(b => new Date(b.registeredAt) < threshold);
|
|
81
|
+
// Group by agent if notifying
|
|
82
|
+
const byAgent = new Map();
|
|
83
|
+
if (options.notify) {
|
|
84
|
+
for (const branch of stale) {
|
|
85
|
+
const agent = branch.agent || 'unknown';
|
|
86
|
+
if (!byAgent.has(agent)) {
|
|
87
|
+
byAgent.set(agent, []);
|
|
88
|
+
}
|
|
89
|
+
byAgent.get(agent).push(branch);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (options.json) {
|
|
93
|
+
console.log(JSON.stringify(stale, null, 2));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (stale.length === 0) {
|
|
97
|
+
console.log(`🕷️ No stale branches (older than ${days} days)`);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
console.log(`🕷️ Stale Branches (>${days} days old):\n`);
|
|
101
|
+
for (const branch of stale) {
|
|
102
|
+
const age = Math.floor((Date.now() - new Date(branch.registeredAt).getTime()) / 86400000);
|
|
103
|
+
const agentTag = branch.agent ? ` [@${branch.agent}]` : '';
|
|
104
|
+
console.log(` ⚠️ ${branch.name}${agentTag} (${age} days old)`);
|
|
105
|
+
}
|
|
106
|
+
// Send notifications if requested
|
|
107
|
+
if (options.notify) {
|
|
108
|
+
console.log(`\n📨 Sending notifications...`);
|
|
109
|
+
let fileSuccess = 0;
|
|
110
|
+
for (const [agent, branches] of byAgent) {
|
|
111
|
+
if (agent === 'unknown')
|
|
112
|
+
continue;
|
|
113
|
+
// ⚡ Bolt: Batch notification per agent to avoid N+1 slow calls
|
|
114
|
+
const branchData = branches.map(branch => ({
|
|
115
|
+
name: branch.name,
|
|
116
|
+
daysOld: Math.floor((Date.now() - new Date(branch.registeredAt).getTime()) / 86400000)
|
|
117
|
+
}));
|
|
118
|
+
// Try .pending_task.md update
|
|
119
|
+
if (updatePendingTaskFile(agent, branchData)) {
|
|
120
|
+
fileSuccess += branches.length;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
console.log(`✅ Notifications sent:`);
|
|
124
|
+
console.log(` - File updates: ${fileSuccess}/${stale.length}`);
|
|
125
|
+
}
|
|
126
|
+
if (options.autoCleanup) {
|
|
127
|
+
console.log(`\n🗑️ Auto-cleaning ${stale.length} stale branch(es)...`);
|
|
128
|
+
const removedNames = await storage.cleanup(threshold);
|
|
129
|
+
removedNames.forEach(name => console.log(` Removed: ${name}`));
|
|
130
|
+
console.log(`✅ Cleaned up ${removedNames.length} branch(es).`);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
console.log(`\nRun 'spidersan cleanup' to remove these.`);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=stale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stale.js","sourceRoot":"","sources":["../../src/commands/stale.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spidersan sync
|
|
3
|
+
*
|
|
4
|
+
* Reconcile the local registry against git truth and prune dead entries.
|
|
5
|
+
*
|
|
6
|
+
* Prunes BOTH:
|
|
7
|
+
* - orphaned — no local or tracking ref AND `git ls-remote` confirms the
|
|
8
|
+
* branch is gone from origin (or status `abandoned`)
|
|
9
|
+
* - merged — branch tip is an ancestor of trunk (or status `completed`)
|
|
10
|
+
*
|
|
11
|
+
* A missing ref alone only proves "not fetched here": the branch may be live on
|
|
12
|
+
* another machine. Those entries are kept, and so is every orphan when origin
|
|
13
|
+
* can't be asked (sp-slemub).
|
|
14
|
+
*
|
|
15
|
+
* Previously sync only removed orphans, so a merged branch lingered in the
|
|
16
|
+
* registry forever and kept producing phantom conflicts (tb-8sa.1 / §1.2).
|
|
17
|
+
* Merged entries are now deleted, not just marked.
|
|
18
|
+
*/
|
|
19
|
+
import { Command } from 'commander';
|
|
20
|
+
export declare const syncCommand: Command;
|
|
21
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,WAAW,SA0DlB,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spidersan sync
|
|
3
|
+
*
|
|
4
|
+
* Reconcile the local registry against git truth and prune dead entries.
|
|
5
|
+
*
|
|
6
|
+
* Prunes BOTH:
|
|
7
|
+
* - orphaned — no local or tracking ref AND `git ls-remote` confirms the
|
|
8
|
+
* branch is gone from origin (or status `abandoned`)
|
|
9
|
+
* - merged — branch tip is an ancestor of trunk (or status `completed`)
|
|
10
|
+
*
|
|
11
|
+
* A missing ref alone only proves "not fetched here": the branch may be live on
|
|
12
|
+
* another machine. Those entries are kept, and so is every orphan when origin
|
|
13
|
+
* can't be asked (sp-slemub).
|
|
14
|
+
*
|
|
15
|
+
* Previously sync only removed orphans, so a merged branch lingered in the
|
|
16
|
+
* registry forever and kept producing phantom conflicts (tb-8sa.1 / §1.2).
|
|
17
|
+
* Merged entries are now deleted, not just marked.
|
|
18
|
+
*/
|
|
19
|
+
import { Command } from 'commander';
|
|
20
|
+
import { getStorage } from '../storage/index.js';
|
|
21
|
+
import { logActivity } from '../lib/activity.js';
|
|
22
|
+
import { reconcileBranches, splitOrphans } from '../lib/reconcile.js';
|
|
23
|
+
export const syncCommand = new Command('sync')
|
|
24
|
+
.description('Sync registry with actual git branches')
|
|
25
|
+
.option('--dry-run', 'Show what would be synced without syncing')
|
|
26
|
+
.action(async (options) => {
|
|
27
|
+
const storage = await getStorage();
|
|
28
|
+
if (!await storage.isInitialized()) {
|
|
29
|
+
console.error('❌ Spidersan not initialized. Run: spidersan init');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
const branches = await storage.list();
|
|
33
|
+
const { merged, orphaned: noRef } = reconcileBranches(branches);
|
|
34
|
+
// `abandoned` is terminal registry status — prune it without asking origin.
|
|
35
|
+
const abandoned = new Set(branches.filter(b => b.status === 'abandoned').map(b => b.name));
|
|
36
|
+
const { gone, kept, remoteChecked } = splitOrphans(noRef.filter(n => !abandoned.has(n)));
|
|
37
|
+
const orphaned = [...noRef.filter(n => abandoned.has(n)), ...gone];
|
|
38
|
+
if (kept.length > 0) {
|
|
39
|
+
console.log(remoteChecked
|
|
40
|
+
? `🕷️ Kept ${kept.length} entr${kept.length === 1 ? 'y' : 'ies'} with no ref here but still on origin (unfetched): ${kept.join(', ')}`
|
|
41
|
+
: `⚠️ Could not reach origin — kept ${kept.length} entr${kept.length === 1 ? 'y' : 'ies'} with no ref here (deleted, or just unfetched). Fetch and re-run to prune.`);
|
|
42
|
+
}
|
|
43
|
+
const stale = [
|
|
44
|
+
...merged.map(name => ({ name, reason: 'merged' })),
|
|
45
|
+
...orphaned.map(name => ({ name, reason: 'orphaned' })),
|
|
46
|
+
];
|
|
47
|
+
if (stale.length === 0) {
|
|
48
|
+
console.log('🕷️ Registry is in sync with git.');
|
|
49
|
+
logActivity({ event: 'sync', details: { merged: 0, orphaned: 0, action: 'clean' } });
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
console.log(`🕷️ Found ${stale.length} stale entr${stale.length === 1 ? 'y' : 'ies'} (${merged.length} merged, ${orphaned.length} orphaned):\n`);
|
|
53
|
+
let failed = 0;
|
|
54
|
+
for (const { name, reason } of stale) {
|
|
55
|
+
if (options.dryRun) {
|
|
56
|
+
console.log(` Would remove (${reason}): ${name}`);
|
|
57
|
+
}
|
|
58
|
+
else if (await storage.unregister(name)) {
|
|
59
|
+
console.log(` 🗑️ Removed (${reason}): ${name}`);
|
|
60
|
+
logActivity({ event: 'sync', branch: name, details: { action: `removed_${reason}` } });
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// Don't claim "Removed" for a no-op — a delete that misses means
|
|
64
|
+
// the entry vanished mid-sync or the registry is corrupt (tb-orpt).
|
|
65
|
+
failed++;
|
|
66
|
+
console.log(` ⚠️ Could not remove (${reason}): ${name} — not found in registry`);
|
|
67
|
+
logActivity({ event: 'sync', branch: name, details: { action: `remove_failed_${reason}` } });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!options.dryRun) {
|
|
71
|
+
if (failed > 0) {
|
|
72
|
+
console.log(`\n⚠️ Synced with ${failed} failed removal${failed === 1 ? '' : 's'} — registry may be corrupt (check .spidersan/registry.json).`);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
console.log(`\n✅ Synced registry with git.`);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spidersan verify-trunk
|
|
3
|
+
*
|
|
4
|
+
* Detect (and optionally fix) registry "trunk-poison": the trunk branch
|
|
5
|
+
* (main/master/develop…) claiming files in the spidersan registry. A clean
|
|
6
|
+
* auto-merge can silently re-poison main, so the post-merge hook gates on this.
|
|
7
|
+
*
|
|
8
|
+
* Promotes the 2026-06-15 `spidersan-post.sh` hook into a first-class command.
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
/**
|
|
12
|
+
* The set of branch names that MUST claim no files: the resolved trunk plus the
|
|
13
|
+
* literal `main`/`master` (a repo can have stray entries for either even when
|
|
14
|
+
* trunk resolves to something else). De-duplicated, order-stable.
|
|
15
|
+
*/
|
|
16
|
+
export declare function trunkEquivalentNames(trunk: string): string[];
|
|
17
|
+
export declare const verifyTrunkCommand: Command;
|
|
18
|
+
//# sourceMappingURL=verify-trunk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-trunk.d.ts","sourceRoot":"","sources":["../../src/commands/verify-trunk.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAG5D;AAED,eAAO,MAAM,kBAAkB,SA2DzB,CAAC"}
|