spidersan 0.4.5 → 0.6.0
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 +67 -0
- package/README.md +60 -5
- package/dist/bin/spidersan.d.ts.map +1 -1
- package/dist/bin/spidersan.js +12 -1
- package/dist/bin/spidersan.js.map +1 -1
- package/dist/commands/abandon.d.ts.map +1 -1
- package/dist/commands/abandon.js +4 -2
- package/dist/commands/abandon.js.map +1 -1
- package/dist/commands/auto.js +6 -6
- package/dist/commands/auto.js.map +1 -1
- package/dist/commands/cleanup.d.ts.map +1 -1
- package/dist/commands/cleanup.js +3 -8
- package/dist/commands/cleanup.js.map +1 -1
- package/dist/commands/config.js +1 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/conflicts.d.ts.map +1 -1
- package/dist/commands/conflicts.js +209 -56
- package/dist/commands/conflicts.js.map +1 -1
- 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 +308 -0
- package/dist/commands/cross-conflicts.js.map +1 -0
- package/dist/commands/daily.d.ts +7 -0
- package/dist/commands/daily.d.ts.map +1 -0
- package/dist/commands/daily.js +171 -0
- package/dist/commands/daily.js.map +1 -0
- package/dist/commands/dashboard.d.ts +22 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +401 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/depends.js +2 -2
- package/dist/commands/depends.js.map +1 -1
- package/dist/commands/doctor.d.ts +22 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +320 -61
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/github-sync.d.ts +9 -0
- package/dist/commands/github-sync.d.ts.map +1 -0
- package/dist/commands/github-sync.js +180 -0
- package/dist/commands/github-sync.js.map +1 -0
- package/dist/commands/index.d.ts +10 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +16 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/log.d.ts +3 -4
- package/dist/commands/log.d.ts.map +1 -1
- package/dist/commands/log.js +102 -87
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/merge-order.js +8 -1
- package/dist/commands/merge-order.js.map +1 -1
- package/dist/commands/merged.d.ts.map +1 -1
- package/dist/commands/merged.js +4 -2
- package/dist/commands/merged.js.map +1 -1
- package/dist/commands/pulse.d.ts +6 -2
- package/dist/commands/pulse.d.ts.map +1 -1
- package/dist/commands/pulse.js +144 -202
- package/dist/commands/pulse.js.map +1 -1
- package/dist/commands/queen.d.ts +25 -0
- package/dist/commands/queen.d.ts.map +1 -0
- package/dist/commands/queen.js +322 -0
- package/dist/commands/queen.js.map +1 -0
- package/dist/commands/ready-check.d.ts.map +1 -1
- package/dist/commands/ready-check.js +42 -27
- package/dist/commands/ready-check.js.map +1 -1
- package/dist/commands/rebase-helper.d.ts.map +1 -1
- package/dist/commands/rebase-helper.js +13 -5
- package/dist/commands/rebase-helper.js.map +1 -1
- package/dist/commands/register.d.ts +1 -0
- package/dist/commands/register.d.ts.map +1 -1
- package/dist/commands/register.js +46 -19
- package/dist/commands/register.js.map +1 -1
- 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 +163 -0
- package/dist/commands/registry-sync.js.map +1 -0
- package/dist/commands/rescue.d.ts.map +1 -1
- package/dist/commands/rescue.js +42 -6
- package/dist/commands/rescue.js.map +1 -1
- package/dist/commands/stale.d.ts +9 -1
- package/dist/commands/stale.d.ts.map +1 -1
- package/dist/commands/stale.js +38 -45
- package/dist/commands/stale.js.map +1 -1
- package/dist/commands/sync-advisor.d.ts +14 -0
- package/dist/commands/sync-advisor.d.ts.map +1 -0
- package/dist/commands/sync-advisor.js +110 -0
- package/dist/commands/sync-advisor.js.map +1 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +16 -5
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/torrent.d.ts.map +1 -1
- package/dist/commands/torrent.js +16 -14
- package/dist/commands/torrent.js.map +1 -1
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +197 -6
- package/dist/commands/watch.js.map +1 -1
- package/dist/lib/activity.d.ts +53 -0
- package/dist/lib/activity.d.ts.map +1 -0
- package/dist/lib/activity.js +267 -0
- package/dist/lib/activity.js.map +1 -0
- package/dist/lib/agent-errors.d.ts.map +1 -1
- package/dist/lib/agent-errors.js +5 -3
- package/dist/lib/agent-errors.js.map +1 -1
- package/dist/lib/ast.d.ts.map +1 -1
- package/dist/lib/ast.js +66 -19
- package/dist/lib/ast.js.map +1 -1
- package/dist/lib/colony-subscriber.d.ts +53 -0
- package/dist/lib/colony-subscriber.d.ts.map +1 -0
- package/dist/lib/colony-subscriber.js +184 -0
- package/dist/lib/colony-subscriber.js.map +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +5 -4
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/crypto.d.ts.map +1 -1
- package/dist/lib/crypto.js +7 -3
- package/dist/lib/crypto.js.map +1 -1
- package/dist/lib/daily-bridge.d.ts +41 -0
- package/dist/lib/daily-bridge.d.ts.map +1 -0
- package/dist/lib/daily-bridge.js +186 -0
- package/dist/lib/daily-bridge.js.map +1 -0
- package/dist/lib/github.d.ts +83 -0
- package/dist/lib/github.d.ts.map +1 -0
- package/dist/lib/github.js +206 -0
- package/dist/lib/github.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/repo-scanner.d.ts +32 -0
- package/dist/lib/repo-scanner.d.ts.map +1 -0
- package/dist/lib/repo-scanner.js +160 -0
- package/dist/lib/repo-scanner.js.map +1 -0
- package/dist/lib/salvage-analyzer.d.ts +29 -0
- package/dist/lib/salvage-analyzer.d.ts.map +1 -0
- package/dist/lib/salvage-analyzer.js +122 -0
- package/dist/lib/salvage-analyzer.js.map +1 -0
- package/dist/lib/security.d.ts +11 -0
- package/dist/lib/security.d.ts.map +1 -1
- package/dist/lib/security.js +20 -0
- package/dist/lib/security.js.map +1 -1
- package/dist/lib/symbol-extractor.d.ts +41 -0
- package/dist/lib/symbol-extractor.d.ts.map +1 -0
- package/dist/lib/symbol-extractor.js +78 -0
- package/dist/lib/symbol-extractor.js.map +1 -0
- package/dist/storage/adapter.d.ts +1 -1
- package/dist/storage/adapter.d.ts.map +1 -1
- package/dist/storage/index.d.ts +0 -5
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +0 -6
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/local.d.ts +1 -1
- package/dist/storage/local.d.ts.map +1 -1
- package/dist/storage/local.js +7 -5
- package/dist/storage/local.js.map +1 -1
- package/dist/storage/supabase.d.ts +21 -1
- package/dist/storage/supabase.d.ts.map +1 -1
- package/dist/storage/supabase.js +171 -6
- package/dist/storage/supabase.js.map +1 -1
- package/dist/tui/dashboard.d.ts.map +1 -1
- package/dist/tui/dashboard.js +15 -6
- package/dist/tui/dashboard.js.map +1 -1
- package/dist/types/cloud.d.ts +101 -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 +90 -91
- package/dist/commands/sync-all.d.ts +0 -9
- package/dist/commands/sync-all.d.ts.map +0 -1
- package/dist/commands/sync-all.js +0 -180
- package/dist/commands/sync-all.js.map +0 -1
- package/dist/storage/git-messages.d.ts +0 -53
- package/dist/storage/git-messages.d.ts.map +0 -1
- package/dist/storage/git-messages.js +0 -374
- package/dist/storage/git-messages.js.map +0 -1
- package/dist/storage/local-messages.d.ts +0 -37
- package/dist/storage/local-messages.d.ts.map +0 -1
- package/dist/storage/local-messages.js +0 -151
- package/dist/storage/local-messages.js.map +0 -1
- package/dist/storage/message-adapter.d.ts +0 -86
- package/dist/storage/message-adapter.d.ts.map +0 -1
- package/dist/storage/message-adapter.js +0 -28
- package/dist/storage/message-adapter.js.map +0 -1
- package/dist/storage/message-factory.d.ts +0 -36
- package/dist/storage/message-factory.d.ts.map +0 -1
- package/dist/storage/message-factory.js +0 -99
- package/dist/storage/message-factory.js.map +0 -1
- package/dist/storage/mycmail-adapter.d.ts +0 -38
- package/dist/storage/mycmail-adapter.d.ts.map +0 -1
- package/dist/storage/mycmail-adapter.js +0 -297
- package/dist/storage/mycmail-adapter.js.map +0 -1
|
@@ -1,29 +1,56 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import {
|
|
2
|
+
import { execFileSync } from 'child_process';
|
|
3
3
|
import { getStorage } from '../storage/index.js';
|
|
4
4
|
import * as readline from 'readline';
|
|
5
5
|
import { loadConfig } from '../lib/config.js';
|
|
6
|
-
import {
|
|
6
|
+
import { validateAgentId, sanitizeFilePaths, validateFilePath } from '../lib/security.js';
|
|
7
|
+
import { logActivity } from '../lib/activity.js';
|
|
7
8
|
function getCurrentBranch() {
|
|
8
9
|
try {
|
|
9
|
-
return
|
|
10
|
+
return execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { encoding: 'utf-8' }).trim();
|
|
10
11
|
}
|
|
11
12
|
catch {
|
|
12
13
|
throw new Error('Not in a git repository');
|
|
13
14
|
}
|
|
14
15
|
}
|
|
16
|
+
// Path segments that are never meaningful for conflict tracking (matched anywhere in the path)
|
|
17
|
+
const EXCLUDED_PATH_SEGMENTS = [
|
|
18
|
+
'/node_modules/',
|
|
19
|
+
'/.git/',
|
|
20
|
+
'/dist/',
|
|
21
|
+
'/build/',
|
|
22
|
+
'/.next/',
|
|
23
|
+
'/target/', // Rust/Cargo build output
|
|
24
|
+
'/.turbo/',
|
|
25
|
+
'/.cache/',
|
|
26
|
+
];
|
|
27
|
+
export function isExcludedPath(file) {
|
|
28
|
+
// Normalise: wrap in slashes so segment patterns match at the start too
|
|
29
|
+
const normalised = `/${file}/`;
|
|
30
|
+
return EXCLUDED_PATH_SEGMENTS.some(seg => normalised.includes(seg));
|
|
31
|
+
}
|
|
15
32
|
function getChangedFiles() {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
33
|
+
const diffStrategies = [
|
|
34
|
+
['diff', '--name-only', 'main...HEAD'],
|
|
35
|
+
['diff', '--name-only', 'HEAD~1'],
|
|
36
|
+
['diff', '--name-only', 'HEAD'],
|
|
37
|
+
];
|
|
38
|
+
for (const args of diffStrategies) {
|
|
39
|
+
try {
|
|
40
|
+
const output = execFileSync('git', args, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
41
|
+
if (output)
|
|
42
|
+
return output.trim().split('\n').filter(f => f && !isExcludedPath(f));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
23
47
|
}
|
|
48
|
+
return [];
|
|
24
49
|
}
|
|
25
50
|
export function validateRegistrationFiles(files) {
|
|
26
|
-
|
|
51
|
+
for (const file of files) {
|
|
52
|
+
validateFilePath(file);
|
|
53
|
+
}
|
|
27
54
|
}
|
|
28
55
|
async function promptForFiles(detectedFiles) {
|
|
29
56
|
const rl = readline.createInterface({
|
|
@@ -83,7 +110,7 @@ export const registerCommand = new Command('register')
|
|
|
83
110
|
const branchName = getCurrentBranch();
|
|
84
111
|
let files = [];
|
|
85
112
|
if (options.files) {
|
|
86
|
-
files = options.files.split(',').map((f) => f.trim());
|
|
113
|
+
files = sanitizeFilePaths(options.files.split(',').map((f) => f.trim()).filter((f) => f && !isExcludedPath(f)));
|
|
87
114
|
}
|
|
88
115
|
else if (options.auto) {
|
|
89
116
|
files = getChangedFiles();
|
|
@@ -109,16 +136,14 @@ export const registerCommand = new Command('register')
|
|
|
109
136
|
process.exit(1);
|
|
110
137
|
}
|
|
111
138
|
const configuredAgent = config.agent.name?.trim();
|
|
112
|
-
const
|
|
113
|
-
|
|
139
|
+
const rawAgent = (options.agent || process.env.SPIDERSAN_AGENT || configuredAgent || '').trim() || undefined;
|
|
140
|
+
let resolvedAgent = rawAgent;
|
|
114
141
|
if (resolvedAgent) {
|
|
115
142
|
try {
|
|
116
|
-
validateAgentId(resolvedAgent);
|
|
143
|
+
resolvedAgent = validateAgentId(resolvedAgent);
|
|
117
144
|
}
|
|
118
|
-
catch
|
|
119
|
-
|
|
120
|
-
console.error(`❌ Security Error: ${err.message}`);
|
|
121
|
-
}
|
|
145
|
+
catch {
|
|
146
|
+
console.error(`❌ Invalid agent ID: "${resolvedAgent}". Must be alphanumeric with - or _.`);
|
|
122
147
|
process.exit(1);
|
|
123
148
|
}
|
|
124
149
|
}
|
|
@@ -132,6 +157,7 @@ export const registerCommand = new Command('register')
|
|
|
132
157
|
agent: resolvedAgent ?? existing.agent,
|
|
133
158
|
});
|
|
134
159
|
console.log(`🕷️ Updated branch: ${branchName}`);
|
|
160
|
+
logActivity({ event: 'register', branch: branchName, agent: resolvedAgent ?? undefined, details: { files, description: options.description, updated: true } });
|
|
135
161
|
}
|
|
136
162
|
else {
|
|
137
163
|
// New registration
|
|
@@ -143,6 +169,7 @@ export const registerCommand = new Command('register')
|
|
|
143
169
|
agent: resolvedAgent,
|
|
144
170
|
});
|
|
145
171
|
console.log(`🕷️ Registered branch: ${branchName}`);
|
|
172
|
+
logActivity({ event: 'register', branch: branchName, agent: resolvedAgent ?? undefined, details: { files, description: options.description } });
|
|
146
173
|
}
|
|
147
174
|
if (files.length > 0) {
|
|
148
175
|
console.log(` Files: ${files.join(', ')}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,
|
|
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;AAuEpC,eAAO,MAAM,mBAAmB,SA2G1B,CAAC"}
|
|
@@ -0,0 +1,163 @@
|
|
|
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 { readFile } from 'fs/promises';
|
|
9
|
+
import { existsSync } from 'fs';
|
|
10
|
+
import { join, basename } from 'path';
|
|
11
|
+
import { homedir } from 'os';
|
|
12
|
+
import { execFileSync } from 'child_process';
|
|
13
|
+
import { LocalStorage } from '../storage/local.js';
|
|
14
|
+
import { SupabaseStorage } from '../storage/supabase.js';
|
|
15
|
+
import { loadConfig } from '../lib/config.js';
|
|
16
|
+
/**
|
|
17
|
+
* Load machine identity from ~/.envoak/machine.json.
|
|
18
|
+
* Falls back to hostname + generated ID if envoak is not configured.
|
|
19
|
+
*/
|
|
20
|
+
async function loadMachineIdentity() {
|
|
21
|
+
const configPath = join(homedir(), '.envoak', 'machine.json');
|
|
22
|
+
if (existsSync(configPath)) {
|
|
23
|
+
const raw = await readFile(configPath, 'utf-8');
|
|
24
|
+
const data = JSON.parse(raw);
|
|
25
|
+
return {
|
|
26
|
+
id: data.id || data.machine_id,
|
|
27
|
+
name: data.name || data.machine_name || 'unknown',
|
|
28
|
+
hostname: data.hostname || 'unknown',
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// Fallback: use hostname
|
|
32
|
+
const hostname = execFileSync('hostname', [], { encoding: 'utf-8' }).trim();
|
|
33
|
+
return {
|
|
34
|
+
id: `fallback-${hostname}`,
|
|
35
|
+
name: hostname,
|
|
36
|
+
hostname,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the current repo name from git or cwd.
|
|
41
|
+
*/
|
|
42
|
+
function getRepoName() {
|
|
43
|
+
try {
|
|
44
|
+
const toplevel = execFileSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf-8' }).trim();
|
|
45
|
+
return basename(toplevel);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return basename(process.cwd());
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get the repo root path.
|
|
53
|
+
*/
|
|
54
|
+
function getRepoPath() {
|
|
55
|
+
try {
|
|
56
|
+
return execFileSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf-8' }).trim();
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return process.cwd();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get a SupabaseStorage instance, or null if not configured.
|
|
64
|
+
*/
|
|
65
|
+
async function getSupabaseStorage() {
|
|
66
|
+
const config = await loadConfig();
|
|
67
|
+
const url = process.env.SUPABASE_URL || process.env.COLONY_SUPABASE_URL || config.storage.supabaseUrl;
|
|
68
|
+
const key = process.env.SUPABASE_KEY || process.env.COLONY_SUPABASE_KEY || config.storage.supabaseKey;
|
|
69
|
+
if (!url || !key)
|
|
70
|
+
return null;
|
|
71
|
+
return new SupabaseStorage({ url, key });
|
|
72
|
+
}
|
|
73
|
+
export const registrySyncCommand = new Command('registry-sync')
|
|
74
|
+
.description('Sync local registry to/from Supabase (cross-machine awareness)')
|
|
75
|
+
.option('--push', 'Push local registry to Supabase')
|
|
76
|
+
.option('--pull', 'Pull other machines\' registries from Supabase')
|
|
77
|
+
.option('--status', 'Show sync status across all machines')
|
|
78
|
+
.option('--repo <name>', 'Limit to specific repo (default: current)')
|
|
79
|
+
.action(async (options) => {
|
|
80
|
+
const supabase = await getSupabaseStorage();
|
|
81
|
+
if (!supabase) {
|
|
82
|
+
console.error('❌ Supabase not configured. Set SUPABASE_URL and SUPABASE_KEY.');
|
|
83
|
+
console.error(' Registry sync requires cloud storage for cross-machine awareness.');
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
const machine = await loadMachineIdentity();
|
|
87
|
+
const repoName = options.repo || getRepoName();
|
|
88
|
+
// Default to --status if no flag specified
|
|
89
|
+
if (!options.push && !options.pull && !options.status) {
|
|
90
|
+
options.status = true;
|
|
91
|
+
}
|
|
92
|
+
// ── PUSH ──
|
|
93
|
+
if (options.push) {
|
|
94
|
+
console.log(`🕷️ Pushing registry from ${machine.name} (${repoName})...\n`);
|
|
95
|
+
const localStorage = new LocalStorage();
|
|
96
|
+
if (!await localStorage.isInitialized()) {
|
|
97
|
+
console.error('❌ Spidersan not initialized. Run: spidersan init');
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
const branches = await localStorage.list();
|
|
101
|
+
const repoPath = getRepoPath();
|
|
102
|
+
const result = await supabase.pushRegistry(machine, repoName, repoPath, branches);
|
|
103
|
+
if (result.errors.length > 0) {
|
|
104
|
+
for (const err of result.errors) {
|
|
105
|
+
console.error(` ❌ ${err}`);
|
|
106
|
+
}
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
console.log(` ✅ Pushed ${result.pushed} active branch(es)`);
|
|
110
|
+
if (result.updated > 0)
|
|
111
|
+
console.log(` 🔄 Updated ${result.updated} non-active branch(es)`);
|
|
112
|
+
if (result.abandoned > 0)
|
|
113
|
+
console.log(` 🗑️ Marked ${result.abandoned} removed branch(es) as abandoned`);
|
|
114
|
+
console.log(`\n Machine: ${machine.name} (${machine.hostname})`);
|
|
115
|
+
console.log(` Repo: ${repoName}`);
|
|
116
|
+
}
|
|
117
|
+
// ── PULL ──
|
|
118
|
+
if (options.pull) {
|
|
119
|
+
console.log(`🕷️ Pulling registries for ${repoName} (excluding ${machine.name})...\n`);
|
|
120
|
+
const views = await supabase.pullRegistries(repoName, machine.id);
|
|
121
|
+
if (views.length === 0) {
|
|
122
|
+
console.log(' No other machines have registered branches for this repo.');
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
for (const view of views) {
|
|
126
|
+
console.log(` 📡 ${view.machine_name} (${view.hostname}) — ${view.branches.length} branch(es)`);
|
|
127
|
+
console.log(` Last sync: ${new Date(view.last_synced).toLocaleString()}\n`);
|
|
128
|
+
for (const branch of view.branches) {
|
|
129
|
+
const files = branch.files.length > 0 ? ` [${branch.files.length} files]` : '';
|
|
130
|
+
const agent = branch.agent ? ` (${branch.agent})` : '';
|
|
131
|
+
console.log(` • ${branch.name}${agent}${files}`);
|
|
132
|
+
if (branch.description) {
|
|
133
|
+
console.log(` ${branch.description}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
console.log('');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// ── STATUS ──
|
|
140
|
+
if (options.status) {
|
|
141
|
+
console.log(`🕷️ Registry sync status${options.repo ? ` (${repoName})` : ' (all repos)'}:\n`);
|
|
142
|
+
const statuses = await supabase.getRegistryStatus(options.repo ? repoName : undefined);
|
|
143
|
+
if (statuses.length === 0) {
|
|
144
|
+
console.log(' No registries synced yet. Run: spidersan registry-sync --push');
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
// Table header
|
|
148
|
+
console.log(' Machine Hostname Branches Active Repos Last Sync');
|
|
149
|
+
console.log(' ───────── ────────── ──────── ────── ───── ─────────');
|
|
150
|
+
for (const s of statuses) {
|
|
151
|
+
const isSelf = s.machine_id === machine.id ? ' ⭐' : '';
|
|
152
|
+
const repos = s.repos.join(', ');
|
|
153
|
+
const lastSync = new Date(s.last_sync).toLocaleString();
|
|
154
|
+
console.log(` ${(s.machine_name + isSelf).padEnd(14)}` +
|
|
155
|
+
`${s.hostname.padEnd(15)}` +
|
|
156
|
+
`${String(s.branch_count).padEnd(10)}` +
|
|
157
|
+
`${String(s.active_count).padEnd(8)}` +
|
|
158
|
+
`${repos.padEnd(17)}` +
|
|
159
|
+
`${lastSync}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
//# sourceMappingURL=registry-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-sync.js","sourceRoot":"","sources":["../../src/commands/registry-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rescue.d.ts","sourceRoot":"","sources":["../../src/commands/rescue.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"rescue.d.ts","sourceRoot":"","sources":["../../src/commands/rescue.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,aAAa,SA0IpB,CAAC"}
|
package/dist/commands/rescue.js
CHANGED
|
@@ -7,40 +7,43 @@
|
|
|
7
7
|
* 3. Triage & Salvage
|
|
8
8
|
*/
|
|
9
9
|
import { Command } from 'commander';
|
|
10
|
-
import {
|
|
10
|
+
import { execFileSync } from 'child_process';
|
|
11
11
|
import { getStorage } from '../storage/index.js';
|
|
12
12
|
import { existsSync, mkdirSync, copyFileSync } from 'fs';
|
|
13
13
|
import { join, basename } from 'path';
|
|
14
|
-
import { validateRepoPath } from '../lib/security.js';
|
|
14
|
+
import { validateRepoPath, validateBranchName } from '../lib/security.js';
|
|
15
|
+
import { analyzeSalvage, formatSalvageReport } from '../lib/salvage-analyzer.js';
|
|
15
16
|
export const rescueCommand = new Command('rescue')
|
|
16
17
|
.description('🚑 Rescue Mode - Scan for and salvage rogue work')
|
|
17
18
|
.option('--scan', 'Scan for problems')
|
|
18
19
|
.option('--salvage <file>', 'Salvage a specific file to ./salvage/')
|
|
19
20
|
.option('--abandon <file>', 'Delete a rogue file')
|
|
21
|
+
.option('--symbols <branch>', 'Analyse abandoned branch for salvageable symbols (Phase C3)')
|
|
22
|
+
.option('--json', 'Output as JSON (use with --symbols for Rust bridge parsing)')
|
|
20
23
|
.action(async (options) => {
|
|
21
24
|
const storage = await getStorage();
|
|
22
25
|
console.log('\n🚑 SPIDERSAN RESCUE MISSION\n━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
23
26
|
// 1. Scan for Untracked Files
|
|
24
27
|
let untracked = [];
|
|
25
28
|
try {
|
|
26
|
-
const output =
|
|
29
|
+
const output = execFileSync('git', ['status', '--porcelain'], { encoding: 'utf-8' });
|
|
27
30
|
untracked = output.split('\n')
|
|
28
31
|
.filter(line => line.startsWith('?? '))
|
|
29
32
|
.map(line => line.substring(3));
|
|
30
33
|
}
|
|
31
|
-
catch
|
|
34
|
+
catch {
|
|
32
35
|
console.error('❌ Failed to scan git status');
|
|
33
36
|
}
|
|
34
37
|
// 2. Scan for Unregistered Branches
|
|
35
38
|
let ghosts = [];
|
|
36
39
|
try {
|
|
37
|
-
const localBranches =
|
|
40
|
+
const localBranches = execFileSync('git', ['branch', '--format=%(refname:short)'], { encoding: 'utf-8' })
|
|
38
41
|
.split('\n').filter(Boolean);
|
|
39
42
|
const registered = await storage.list();
|
|
40
43
|
const registeredNames = new Set(registered.map(b => b.name));
|
|
41
44
|
ghosts = localBranches.filter(b => !registeredNames.has(b) && b !== 'main' && b !== 'master');
|
|
42
45
|
}
|
|
43
|
-
catch
|
|
46
|
+
catch {
|
|
44
47
|
console.error('❌ Failed to scan branches');
|
|
45
48
|
}
|
|
46
49
|
if (options.scan) {
|
|
@@ -105,6 +108,39 @@ export const rescueCommand = new Command('rescue')
|
|
|
105
108
|
console.log(`🗑️ Abandoned '${basename(target)}'`);
|
|
106
109
|
return;
|
|
107
110
|
}
|
|
111
|
+
// Symbol salvage analysis (Phase C3)
|
|
112
|
+
if (options.symbols) {
|
|
113
|
+
let branch;
|
|
114
|
+
try {
|
|
115
|
+
branch = validateBranchName(options.symbols);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
console.error(`❌ ${err.message}`);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
if (!options.json) {
|
|
122
|
+
console.log(`\n🔬 Analysing salvageable symbols in "${branch}"...\n`);
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const report = await analyzeSalvage(branch);
|
|
126
|
+
if (options.json) {
|
|
127
|
+
console.log(JSON.stringify(report, null, 2));
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
console.log(formatSalvageReport(report));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
if (options.json) {
|
|
135
|
+
console.log(JSON.stringify({ error: err.message }));
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
console.error(`❌ ${err.message}`);
|
|
139
|
+
}
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
108
144
|
// Default: Run scan
|
|
109
145
|
console.log('Use --scan to see anomalies.');
|
|
110
146
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rescue.js","sourceRoot":"","sources":["../../src/commands/rescue.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"rescue.js","sourceRoot":"","sources":["../../src/commands/rescue.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/stale.d.ts
CHANGED
|
@@ -2,8 +2,16 @@
|
|
|
2
2
|
* spidersan stale
|
|
3
3
|
*
|
|
4
4
|
* Show branches that haven't been updated recently.
|
|
5
|
-
* With --notify flag: sends notifications to branch owners via
|
|
5
|
+
* With --notify flag: sends notifications to branch owners via .pending_task.md updates.
|
|
6
6
|
*/
|
|
7
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;
|
|
8
16
|
export declare const staleCommand: Command;
|
|
9
17
|
//# sourceMappingURL=stale.d.ts.map
|
|
@@ -1 +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;
|
|
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,CAgD7G;AAED,eAAO,MAAM,YAAY,SAoFnB,CAAC"}
|
package/dist/commands/stale.js
CHANGED
|
@@ -2,41 +2,26 @@
|
|
|
2
2
|
* spidersan stale
|
|
3
3
|
*
|
|
4
4
|
* Show branches that haven't been updated recently.
|
|
5
|
-
* With --notify flag: sends notifications to branch owners via
|
|
5
|
+
* With --notify flag: sends notifications to branch owners via .pending_task.md updates.
|
|
6
6
|
*/
|
|
7
7
|
import { Command } from 'commander';
|
|
8
8
|
import { getStorage } from '../storage/index.js';
|
|
9
|
-
import { spawnSync } from 'child_process';
|
|
10
9
|
import { existsSync, readFileSync, appendFileSync } from 'fs';
|
|
11
10
|
import { resolve } from 'path';
|
|
12
|
-
|
|
13
|
-
* Send notification to agent via mycmail
|
|
14
|
-
*/
|
|
15
|
-
function notifyAgentViaMycmail(agentId, branchName, daysOld) {
|
|
16
|
-
try {
|
|
17
|
-
const subject = `⚠️ Stale branch: ${branchName}`;
|
|
18
|
-
const message = `Your branch "${branchName}" has been inactive for ${daysOld} days.\n\nActions:\n- Run: spidersan cleanup\n- Or resume work and push updates`;
|
|
19
|
-
const result = spawnSync('mycmail', [
|
|
20
|
-
'send',
|
|
21
|
-
agentId,
|
|
22
|
-
subject,
|
|
23
|
-
'--message',
|
|
24
|
-
message
|
|
25
|
-
], {
|
|
26
|
-
encoding: 'utf-8',
|
|
27
|
-
env: { ...process.env, MYCELIUMAIL_AGENT_ID: 'spidersan' }
|
|
28
|
-
});
|
|
29
|
-
return result.status === 0;
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
11
|
+
import { validateAgentId, validateBranchName } from '../lib/security.js';
|
|
35
12
|
/**
|
|
36
13
|
* Update agent's .pending_task.md file
|
|
14
|
+
* ⚡ Bolt: Batched updates to avoid N+1 file I/O
|
|
37
15
|
*/
|
|
38
|
-
function updatePendingTaskFile(agentId,
|
|
16
|
+
export function updatePendingTaskFile(agentId, branches) {
|
|
17
|
+
if (branches.length === 0)
|
|
18
|
+
return true;
|
|
39
19
|
try {
|
|
20
|
+
// Security: Validate inputs
|
|
21
|
+
validateAgentId(agentId);
|
|
22
|
+
for (const b of branches) {
|
|
23
|
+
validateBranchName(b.name);
|
|
24
|
+
}
|
|
40
25
|
// Try common locations for .pending_task.md
|
|
41
26
|
const possiblePaths = [
|
|
42
27
|
resolve(process.cwd(), '.pending_task.md'),
|
|
@@ -54,14 +39,17 @@ function updatePendingTaskFile(agentId, branchName, daysOld) {
|
|
|
54
39
|
if (!taskFilePath) {
|
|
55
40
|
return false;
|
|
56
41
|
}
|
|
57
|
-
const entry = `- [ ] 🕷️ Stale branch: \`${branchName}\` (${daysOld}d inactive) - run \`spidersan cleanup\`\n`;
|
|
58
|
-
// Read file and check if entry already exists
|
|
59
42
|
const content = readFileSync(taskFilePath, 'utf-8');
|
|
60
|
-
|
|
61
|
-
|
|
43
|
+
let newEntries = '';
|
|
44
|
+
for (const b of branches) {
|
|
45
|
+
// Check if entry already exists
|
|
46
|
+
if (!content.includes(b.name)) {
|
|
47
|
+
newEntries += `- [ ] 🕷️ Stale branch: \`${b.name}\` (${b.daysOld}d inactive) - run \`spidersan cleanup\`\n`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (newEntries.length > 0) {
|
|
51
|
+
appendFileSync(taskFilePath, newEntries, 'utf-8');
|
|
62
52
|
}
|
|
63
|
-
// Append to the file
|
|
64
|
-
appendFileSync(taskFilePath, entry, 'utf-8');
|
|
65
53
|
return true;
|
|
66
54
|
}
|
|
67
55
|
catch {
|
|
@@ -72,6 +60,7 @@ export const staleCommand = new Command('stale')
|
|
|
72
60
|
.description('Show stale branches (not updated recently)')
|
|
73
61
|
.option('--days <n>', 'Days threshold for staleness', '7')
|
|
74
62
|
.option('--notify', 'Send notifications to branch owners')
|
|
63
|
+
.option('--auto-cleanup', 'Automatically remove stale branches after listing')
|
|
75
64
|
.option('--json', 'Output as JSON')
|
|
76
65
|
.action(async (options) => {
|
|
77
66
|
const storage = await getStorage();
|
|
@@ -112,27 +101,31 @@ export const staleCommand = new Command('stale')
|
|
|
112
101
|
// Send notifications if requested
|
|
113
102
|
if (options.notify) {
|
|
114
103
|
console.log(`\n📨 Sending notifications...`);
|
|
115
|
-
let mycmailSuccess = 0;
|
|
116
104
|
let fileSuccess = 0;
|
|
117
105
|
for (const [agent, branches] of byAgent) {
|
|
118
106
|
if (agent === 'unknown')
|
|
119
107
|
continue;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
fileSuccess++;
|
|
129
|
-
}
|
|
108
|
+
// ⚡ Bolt: Batch notification per agent to avoid N+1 slow calls
|
|
109
|
+
const branchData = branches.map(branch => ({
|
|
110
|
+
name: branch.name,
|
|
111
|
+
daysOld: Math.floor((Date.now() - new Date(branch.registeredAt).getTime()) / 86400000)
|
|
112
|
+
}));
|
|
113
|
+
// Try .pending_task.md update
|
|
114
|
+
if (updatePendingTaskFile(agent, branchData)) {
|
|
115
|
+
fileSuccess += branches.length;
|
|
130
116
|
}
|
|
131
117
|
}
|
|
132
118
|
console.log(`✅ Notifications sent:`);
|
|
133
|
-
console.log(` - Mycmail: ${mycmailSuccess}/${stale.length}`);
|
|
134
119
|
console.log(` - File updates: ${fileSuccess}/${stale.length}`);
|
|
135
120
|
}
|
|
136
|
-
|
|
121
|
+
if (options.autoCleanup) {
|
|
122
|
+
console.log(`\n🗑️ Auto-cleaning ${stale.length} stale branch(es)...`);
|
|
123
|
+
const removedNames = await storage.cleanup(threshold);
|
|
124
|
+
removedNames.forEach(name => console.log(` Removed: ${name}`));
|
|
125
|
+
console.log(`✅ Cleaned up ${removedNames.length} branch(es).`);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
console.log(`\nRun 'spidersan cleanup' to remove these.`);
|
|
129
|
+
}
|
|
137
130
|
});
|
|
138
131
|
//# sourceMappingURL=stale.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stale.js","sourceRoot":"","sources":["../../src/commands/stale.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"stale.js","sourceRoot":"","sources":["../../src/commands/stale.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEzE;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe,EAAE,QAA6C;IAChG,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvC,IAAI,CAAC;QACD,4BAA4B;QAC5B,eAAe,CAAC,OAAO,CAAC,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACvB,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,4CAA4C;QAC5C,MAAM,aAAa,GAAG;YAClB,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,kBAAkB,CAAC;YAC1C,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,OAAO,mBAAmB,CAAC;YACxD,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE,OAAO,OAAO,mBAAmB,CAAC;YACnE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE,wCAAwC,CAAC;SAC7E,CAAC;QAEF,IAAI,YAAY,GAAkB,IAAI,CAAC;QACvC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YAC/B,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnB,YAAY,GAAG,IAAI,CAAC;gBACpB,MAAM;YACV,CAAC;QACL,CAAC;QAED,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACpD,IAAI,UAAU,GAAG,EAAE,CAAC;QAEpB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACvB,gCAAgC;YAChC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,UAAU,IAAI,6BAA6B,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,2CAA2C,CAAC;YACjH,CAAC;QACL,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,cAAc,CAAC,YAAY,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC3C,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,YAAY,EAAE,8BAA8B,EAAE,GAAG,CAAC;KACzD,MAAM,CAAC,UAAU,EAAE,qCAAqC,CAAC;KACzD,MAAM,CAAC,gBAAgB,EAAE,mDAAmD,CAAC;KAC7E,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IAEnC,IAAI,CAAC,MAAM,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,CAAC;IAEzE,8BAA8B;IAC9B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC5C,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACjB,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,SAAS,CAAC;YACxC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC3B,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5C,OAAO;IACX,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,qCAAqC,IAAI,QAAQ,CAAC,CAAC;QAC/D,OAAO;IACX,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,eAAe,CAAC,CAAC;IAEzD,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC1F,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,IAAI,GAAG,QAAQ,KAAK,GAAG,YAAY,CAAC,CAAC;IACrE,CAAC;IAED,kCAAkC;IAClC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAE7C,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,OAAO,EAAE,CAAC;YACtC,IAAI,KAAK,KAAK,SAAS;gBAAE,SAAS;YAElC,+DAA+D;YAC/D,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACvC,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,CAAC;aACzF,CAAC,CAAC,CAAC;YAEJ,8BAA8B;YAC9B,IAAI,qBAAqB,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;gBAC3C,WAAW,IAAI,QAAQ,CAAC,MAAM,CAAC;YACnC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,sBAAsB,WAAW,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,MAAM,sBAAsB,CAAC,CAAC;QACxE,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACtD,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,gBAAgB,YAAY,CAAC,MAAM,cAAc,CAAC,CAAC;IACnE,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC9D,CAAC;AACL,CAAC,CAAC,CAAC"}
|