spidersan 0.4.3 → 0.5.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 +124 -0
- package/README.md +95 -23
- package/dist/bin/spidersan.d.ts.map +1 -1
- package/dist/bin/spidersan.js +22 -2
- 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.d.ts +7 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +12 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/conflicts.d.ts.map +1 -1
- package/dist/commands/conflicts.js +238 -34
- 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 +305 -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 +215 -14
- 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 +11 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +17 -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 +152 -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 +309 -0
- package/dist/commands/queen.js.map +1 -0
- package/dist/commands/ready-check.d.ts +1 -0
- package/dist/commands/ready-check.d.ts.map +1 -1
- package/dist/commands/ready-check.js +43 -28
- package/dist/commands/ready-check.js.map +1 -1
- 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 +2 -0
- package/dist/commands/register.d.ts.map +1 -1
- package/dist/commands/register.js +66 -10
- 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 +69 -12
- package/dist/commands/rescue.js.map +1 -1
- package/dist/commands/stale.d.ts +16 -0
- package/dist/commands/stale.d.ts.map +1 -1
- package/dist/commands/stale.js +55 -21
- 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 +45 -22
- package/dist/commands/torrent.js.map +1 -1
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +198 -7
- 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 +3 -1
- 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 +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +7 -3
- 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 +185 -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/repo-scanner.d.ts +36 -0
- package/dist/lib/repo-scanner.d.ts.map +1 -0
- package/dist/lib/repo-scanner.js +159 -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 +15 -8
- package/dist/lib/security.d.ts.map +1 -1
- package/dist/lib/security.js +36 -1
- 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/git-messages.d.ts.map +1 -1
- package/dist/storage/git-messages.js +57 -53
- package/dist/storage/git-messages.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/mycmail-adapter.d.ts.map +1 -1
- package/dist/storage/mycmail-adapter.js +11 -6
- package/dist/storage/mycmail-adapter.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 +9 -6
- 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/commands/pulse.js
CHANGED
|
@@ -1,232 +1,182 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* spidersan pulse
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Quick health-check: sync from Colony, then run local conflict detection.
|
|
5
|
+
* Calls syncFromColony() first so that active work_claim signals from other
|
|
6
|
+
* agents are reflected in the registry before conflicts are computed.
|
|
7
|
+
*
|
|
8
|
+
* Offline mode: if Colony is unreachable, prints a warning and continues
|
|
9
|
+
* with existing local registry data — never crashes.
|
|
6
10
|
*/
|
|
7
11
|
import { Command } from 'commander';
|
|
8
|
-
import {
|
|
9
|
-
import { existsSync, statSync } from 'fs';
|
|
10
|
-
import { homedir } from 'os';
|
|
11
|
-
import { join } from 'path';
|
|
12
|
+
import { execFileSync } from 'child_process';
|
|
12
13
|
import { getStorage } from '../storage/index.js';
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
import { syncFromColony } from '../lib/colony-subscriber.js';
|
|
15
|
+
import { loadConfig } from '../lib/config.js';
|
|
16
|
+
// Critical files — TIER 3 block
|
|
17
|
+
const TIER_3_PATTERNS = [
|
|
18
|
+
/\.env$/,
|
|
19
|
+
/secrets?\./i,
|
|
20
|
+
/credentials/i,
|
|
21
|
+
/password/i,
|
|
22
|
+
/api[_-]?key/i,
|
|
23
|
+
/private[_-]?key/i,
|
|
24
|
+
/\.pem$/,
|
|
25
|
+
/auth\.(ts|js)$/,
|
|
26
|
+
/security\.(ts|js)$/,
|
|
27
|
+
];
|
|
28
|
+
// Important files — TIER 2 pause
|
|
29
|
+
const TIER_2_PATTERNS = [
|
|
30
|
+
/package\.json$/,
|
|
31
|
+
/package-lock\.json$/,
|
|
32
|
+
/tsconfig\.json$/,
|
|
33
|
+
/CLAUDE\.md$/,
|
|
34
|
+
/\.gitignore$/,
|
|
35
|
+
/server\.(ts|js)$/,
|
|
36
|
+
/index\.(ts|js)$/,
|
|
37
|
+
/config\.(ts|js)$/,
|
|
38
|
+
];
|
|
39
|
+
function classifyTier(file) {
|
|
40
|
+
for (const p of TIER_3_PATTERNS) {
|
|
41
|
+
if (p.test(file))
|
|
42
|
+
return 3;
|
|
43
|
+
}
|
|
44
|
+
for (const p of TIER_2_PATTERNS) {
|
|
45
|
+
if (p.test(file))
|
|
46
|
+
return 2;
|
|
47
|
+
}
|
|
48
|
+
return 1;
|
|
21
49
|
}
|
|
22
|
-
function
|
|
23
|
-
if (process.env.SUPABASE_URL && process.env.SUPABASE_KEY) {
|
|
24
|
-
return 'supabase';
|
|
25
|
-
}
|
|
26
|
-
const localPath = join(process.cwd(), '.spidersan', 'registry.json');
|
|
27
|
-
const globalPath = join(homedir(), '.spidersan', 'registry.json');
|
|
28
|
-
if (existsSync(localPath) || existsSync(globalPath)) {
|
|
29
|
-
return 'local';
|
|
30
|
-
}
|
|
31
|
-
return 'unknown';
|
|
32
|
-
}
|
|
33
|
-
function getStorageSize() {
|
|
50
|
+
function getCurrentBranch() {
|
|
34
51
|
try {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (existsSync(path)) {
|
|
39
|
-
return statSync(path).size;
|
|
40
|
-
}
|
|
52
|
+
return execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
53
|
+
encoding: 'utf-8',
|
|
54
|
+
}).trim();
|
|
41
55
|
}
|
|
42
56
|
catch {
|
|
43
|
-
|
|
57
|
+
return 'unknown';
|
|
44
58
|
}
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
function daysBetween(date1, date2) {
|
|
48
|
-
const diffMs = Math.abs(date2.getTime() - date1.getTime());
|
|
49
|
-
return Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
50
|
-
}
|
|
51
|
-
function determineHealth(pulse) {
|
|
52
|
-
// Dormant: not initialized or no activity
|
|
53
|
-
if (!pulse.registry.initialized)
|
|
54
|
-
return 'dormant';
|
|
55
|
-
if (pulse.registry.activeBranches === 0)
|
|
56
|
-
return 'dormant';
|
|
57
|
-
// Weak: high stale count or low completeness
|
|
58
|
-
if (pulse.registry.staleBranches > pulse.registry.activeBranches)
|
|
59
|
-
return 'weak';
|
|
60
|
-
if (pulse.completeness.score < 50)
|
|
61
|
-
return 'weak';
|
|
62
|
-
// Steady: some issues but functional
|
|
63
|
-
if (pulse.completeness.score < 80)
|
|
64
|
-
return 'steady';
|
|
65
|
-
if (pulse.registry.staleBranches > 0)
|
|
66
|
-
return 'steady';
|
|
67
|
-
// Strong: healthy web
|
|
68
|
-
return 'strong';
|
|
69
59
|
}
|
|
70
60
|
export const pulseCommand = new Command('pulse')
|
|
71
|
-
.description(
|
|
61
|
+
.description('Sync from Colony then show active conflicts (quick health-check)')
|
|
72
62
|
.option('--json', 'Output as JSON')
|
|
73
|
-
.option('-
|
|
63
|
+
.option('--no-sync', 'Skip Colony sync, use local registry only')
|
|
74
64
|
.action(async (options) => {
|
|
75
65
|
const storage = await getStorage();
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
},
|
|
102
|
-
};
|
|
103
|
-
// Check if initialized
|
|
104
|
-
pulse.registry.initialized = await storage.isInitialized();
|
|
105
|
-
if (pulse.registry.initialized) {
|
|
106
|
-
const branches = await storage.list();
|
|
107
|
-
const gitBranches = new Set(getGitBranches());
|
|
108
|
-
// Count by status
|
|
109
|
-
const active = branches.filter(b => b.status === 'active');
|
|
110
|
-
const stale = active.filter(b => daysBetween(new Date(b.registeredAt), now) > STALE_DAYS);
|
|
111
|
-
const abandoned = branches.filter(b => b.status === 'abandoned');
|
|
112
|
-
pulse.registry.totalBranches = branches.length;
|
|
113
|
-
pulse.registry.activeBranches = active.length;
|
|
114
|
-
pulse.registry.staleBranches = stale.length;
|
|
115
|
-
pulse.registry.abandonedBranches = abandoned.length;
|
|
116
|
-
// Unique agents
|
|
117
|
-
const agents = new Set(branches.map(b => b.agent).filter((a) => !!a));
|
|
118
|
-
pulse.registry.agents = Array.from(agents);
|
|
119
|
-
// Date ranges
|
|
120
|
-
if (active.length > 0) {
|
|
121
|
-
const dates = active.map(b => new Date(b.registeredAt).getTime());
|
|
122
|
-
pulse.registry.oldestActive = new Date(Math.min(...dates));
|
|
123
|
-
pulse.registry.newestActive = new Date(Math.max(...dates));
|
|
124
|
-
pulse.lastActivity.lastSync = pulse.registry.newestActive;
|
|
125
|
-
pulse.lastActivity.daysSinceActivity = daysBetween(pulse.registry.newestActive, now);
|
|
126
|
-
}
|
|
127
|
-
// Completeness: find git branches not in registry
|
|
128
|
-
const registeredNames = new Set(branches.map(b => b.name));
|
|
129
|
-
const unregistered = Array.from(gitBranches).filter(b => !registeredNames.has(b) && b !== 'main' && b !== 'master');
|
|
130
|
-
pulse.completeness.unregisteredBranches = unregistered;
|
|
131
|
-
// Calculate completeness score
|
|
132
|
-
const relevantBranches = Array.from(gitBranches).filter(b => b !== 'main' && b !== 'master');
|
|
133
|
-
if (relevantBranches.length === 0) {
|
|
134
|
-
pulse.completeness.score = 100; // No branches to track
|
|
66
|
+
if (!await storage.isInitialized()) {
|
|
67
|
+
console.error('❌ Spidersan not initialized. Run: spidersan init');
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
const config = await loadConfig();
|
|
71
|
+
const highSeverity = (config.conflicts?.highSeverityPatterns || []).map((p) => new RegExp(p));
|
|
72
|
+
const mediumSeverity = (config.conflicts?.mediumSeverityPatterns || []).map((p) => new RegExp(p));
|
|
73
|
+
// ── Colony sync ───────────────────────────────────────────────────────
|
|
74
|
+
let colonySynced = 0;
|
|
75
|
+
let colonyOffline = true;
|
|
76
|
+
if (options.sync !== false) {
|
|
77
|
+
const result = await syncFromColony();
|
|
78
|
+
colonySynced = result.synced;
|
|
79
|
+
colonyOffline = result.offline;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
console.log('ℹ Colony sync skipped (--no-sync)');
|
|
83
|
+
}
|
|
84
|
+
// ── Local conflict detection ──────────────────────────────────────────
|
|
85
|
+
const currentBranch = getCurrentBranch();
|
|
86
|
+
const allBranches = await storage.list();
|
|
87
|
+
const target = allBranches.find(b => b.name === currentBranch);
|
|
88
|
+
if (!target) {
|
|
89
|
+
if (options.json) {
|
|
90
|
+
console.log(JSON.stringify({ branch: currentBranch, registered: false, conflicts: [], colonySynced, colonyOffline }));
|
|
135
91
|
}
|
|
136
92
|
else {
|
|
137
|
-
|
|
138
|
-
|
|
93
|
+
console.log(`🕷️ Branch "${currentBranch}" is not registered.`);
|
|
94
|
+
console.log(' Run: spidersan register --files "..."');
|
|
95
|
+
if (!colonyOffline) {
|
|
96
|
+
console.log(` Colony: synced ${colonySynced} claim(s)`);
|
|
97
|
+
}
|
|
139
98
|
}
|
|
140
|
-
}
|
|
141
|
-
// Determine overall health
|
|
142
|
-
pulse.health = determineHealth(pulse);
|
|
143
|
-
// JSON output
|
|
144
|
-
if (options.json) {
|
|
145
|
-
console.log(JSON.stringify(pulse, null, 2));
|
|
146
99
|
return;
|
|
147
100
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
101
|
+
const targetFilesSet = new Set(target.files);
|
|
102
|
+
const conflicts = [];
|
|
103
|
+
for (const branch of allBranches) {
|
|
104
|
+
if (branch.name === currentBranch || branch.status !== 'active')
|
|
105
|
+
continue;
|
|
106
|
+
const overlapping = branch.files.filter(f => targetFilesSet.has(f));
|
|
107
|
+
if (overlapping.length === 0)
|
|
108
|
+
continue;
|
|
109
|
+
// Determine max tier for this conflict group
|
|
110
|
+
let maxTier = 1;
|
|
111
|
+
for (const file of overlapping) {
|
|
112
|
+
let tier = classifyTier(file);
|
|
113
|
+
// Also apply config-level patterns
|
|
114
|
+
for (const p of highSeverity) {
|
|
115
|
+
if (p.test(file)) {
|
|
116
|
+
tier = 3;
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (tier < 3) {
|
|
121
|
+
for (const p of mediumSeverity) {
|
|
122
|
+
if (p.test(file)) {
|
|
123
|
+
tier = Math.max(tier, 2);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (tier > maxTier)
|
|
129
|
+
maxTier = tier;
|
|
130
|
+
}
|
|
131
|
+
conflicts.push({
|
|
132
|
+
branch: branch.name,
|
|
133
|
+
files: overlapping,
|
|
134
|
+
tier: maxTier,
|
|
135
|
+
agent: branch.agent,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
conflicts.sort((a, b) => b.tier - a.tier);
|
|
139
|
+
if (options.json) {
|
|
140
|
+
console.log(JSON.stringify({
|
|
141
|
+
branch: currentBranch,
|
|
142
|
+
registered: true,
|
|
143
|
+
conflicts,
|
|
144
|
+
colonySynced,
|
|
145
|
+
colonyOffline,
|
|
146
|
+
}, null, 2));
|
|
152
147
|
return;
|
|
153
148
|
}
|
|
154
|
-
//
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
console.log(
|
|
149
|
+
// ── Human-readable output ─────────────────────────────────────────────
|
|
150
|
+
const colonyStatus = colonyOffline
|
|
151
|
+
? '⚠ offline'
|
|
152
|
+
: `✅ synced ${colonySynced} claim(s)`;
|
|
153
|
+
console.log(`
|
|
154
|
+
🕷️ SPIDERSAN PULSE — "${currentBranch}"
|
|
155
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
156
|
+
Colony: ${colonyStatus}
|
|
157
|
+
Branches: ${allBranches.filter(b => b.status === 'active').length} active
|
|
158
|
+
`.trim());
|
|
159
159
|
console.log('');
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
steady: ['💛', 'STEADY', 'The web is functional.'],
|
|
164
|
-
weak: ['🧡', 'WEAK', 'The web needs attention.'],
|
|
165
|
-
dormant: ['💤', 'DORMANT', 'The spider sleeps...'],
|
|
166
|
-
};
|
|
167
|
-
const [emoji, label, tagline] = healthDisplay[pulse.health];
|
|
168
|
-
console.log(' ╭─────────────────────────────────────╮');
|
|
169
|
-
console.log(` │ ${emoji} Web Health: ${label.padEnd(23)} │`);
|
|
170
|
-
console.log(' ╰─────────────────────────────────────╯');
|
|
171
|
-
console.log(` "${tagline}"`);
|
|
172
|
-
console.log('');
|
|
173
|
-
// Registry overview
|
|
174
|
-
console.log(' 📊 Registry:');
|
|
175
|
-
console.log(` • ${pulse.registry.activeBranches} active thread${pulse.registry.activeBranches !== 1 ? 's' : ''}`);
|
|
176
|
-
if (pulse.registry.staleBranches > 0) {
|
|
177
|
-
console.log(` • ${pulse.registry.staleBranches} stale (older than ${STALE_DAYS} days)`);
|
|
178
|
-
}
|
|
179
|
-
if (pulse.registry.abandonedBranches > 0) {
|
|
180
|
-
console.log(` • ${pulse.registry.abandonedBranches} abandoned`);
|
|
181
|
-
}
|
|
182
|
-
if (pulse.registry.agents.length > 0) {
|
|
183
|
-
console.log(` • Agents: ${pulse.registry.agents.join(', ')}`);
|
|
160
|
+
if (conflicts.length === 0) {
|
|
161
|
+
console.log('✅ No conflicts detected. You\'re good to go!');
|
|
162
|
+
return;
|
|
184
163
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
console.log(` └─ ${branch}`);
|
|
195
|
-
}
|
|
196
|
-
if (pulse.completeness.unregisteredBranches.length > 3) {
|
|
197
|
-
console.log(` └─ +${pulse.completeness.unregisteredBranches.length - 3} more`);
|
|
164
|
+
const tierIcons = { 1: '🟡', 2: '🟠', 3: '🔴' };
|
|
165
|
+
const tierLabels = { 1: 'WARN', 2: 'PAUSE', 3: 'BLOCK' };
|
|
166
|
+
for (const c of conflicts) {
|
|
167
|
+
const icon = tierIcons[c.tier] ?? '🟡';
|
|
168
|
+
const label = tierLabels[c.tier] ?? 'WARN';
|
|
169
|
+
const agentTag = c.agent ? ` [@${c.agent}]` : '';
|
|
170
|
+
console.log(`${icon} TIER ${c.tier} ${label}: ${c.branch}${agentTag}`);
|
|
171
|
+
for (const f of c.files) {
|
|
172
|
+
console.log(` • ${f}`);
|
|
198
173
|
}
|
|
199
|
-
}
|
|
200
|
-
else if (pulse.completeness.score === 100) {
|
|
201
|
-
console.log(' ✅ All branches tracked');
|
|
202
|
-
}
|
|
203
|
-
// Activity
|
|
204
|
-
if (pulse.lastActivity.daysSinceActivity !== null) {
|
|
205
174
|
console.log('');
|
|
206
|
-
console.log(' ⏱️ Activity:');
|
|
207
|
-
if (pulse.lastActivity.daysSinceActivity === 0) {
|
|
208
|
-
console.log(' • Last activity: today');
|
|
209
|
-
}
|
|
210
|
-
else if (pulse.lastActivity.daysSinceActivity === 1) {
|
|
211
|
-
console.log(' • Last activity: yesterday');
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
console.log(` • Last activity: ${pulse.lastActivity.daysSinceActivity} days ago`);
|
|
215
|
-
}
|
|
216
175
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
console.log(
|
|
221
|
-
|
|
222
|
-
const kb = (pulse.storage.sizeBytes / 1024).toFixed(1);
|
|
223
|
-
console.log(` • Size: ${kb} KB`);
|
|
224
|
-
}
|
|
225
|
-
// Wyatt's question
|
|
226
|
-
console.log('');
|
|
227
|
-
console.log(' ╭─────────────────────────────────────╮');
|
|
228
|
-
console.log(' │ "Do I guide them? Or they me?" │');
|
|
229
|
-
console.log(' ╰─────────────────────────────────────╯');
|
|
230
|
-
console.log('');
|
|
176
|
+
const t3 = conflicts.filter(c => c.tier === 3).length;
|
|
177
|
+
const t2 = conflicts.filter(c => c.tier === 2).length;
|
|
178
|
+
const t1 = conflicts.filter(c => c.tier === 1).length;
|
|
179
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
180
|
+
console.log(`📊 Summary: 🔴 ${t3} BLOCK | 🟠 ${t2} PAUSE | 🟡 ${t1} WARN`);
|
|
231
181
|
});
|
|
232
182
|
//# sourceMappingURL=pulse.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pulse.js","sourceRoot":"","sources":["../../src/commands/pulse.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"pulse.js","sourceRoot":"","sources":["../../src/commands/pulse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spidersan queen
|
|
3
|
+
*
|
|
4
|
+
* Mode 3: Queen Spider — sub-spidersan dispatch for parallel ground jobs.
|
|
5
|
+
*
|
|
6
|
+
* The queen never does ground work. It spawns scoped, ephemeral sub-spidersans,
|
|
7
|
+
* watches them via the colony gradient, and integrates results. Each sub fires,
|
|
8
|
+
* completes its single job, and dissolves back into the colony.
|
|
9
|
+
*
|
|
10
|
+
* Subcommands:
|
|
11
|
+
* spawn — define a ground job, emit colony assignment, print launch script
|
|
12
|
+
* status — show active sub-spidersans spawned by this queen signal
|
|
13
|
+
* dissolve — manually close a stuck sub-spidersan
|
|
14
|
+
*
|
|
15
|
+
* Colony shape:
|
|
16
|
+
* Queen emits a signal (status=in-progress, type=work_claim, task="queen dispatch")
|
|
17
|
+
* Each sub emits a signal with payload.spawned_by = queen_signal_id
|
|
18
|
+
* Sub closes via colony_close on completion (fire-complete-dissolve)
|
|
19
|
+
*
|
|
20
|
+
* Note: Actual claude spawning (via nanoclaw/INFRA-A) is stubbed until Phase 0
|
|
21
|
+
* is proven. spawn prints the launch script — execution is manual or via birdsan.
|
|
22
|
+
*/
|
|
23
|
+
import { Command } from 'commander';
|
|
24
|
+
export declare const queenCommand: Command;
|
|
25
|
+
//# sourceMappingURL=queen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queen.d.ts","sourceRoot":"","sources":["../../src/commands/queen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkXpC,eAAO,MAAM,YAAY,SAIY,CAAC"}
|