spidersan 0.2.5 β 0.3.3
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 +21 -0
- package/README.md +14 -33
- package/dist/bin/spidersan.d.ts.map +1 -1
- package/dist/bin/spidersan.js +12 -4
- package/dist/bin/spidersan.js.map +1 -1
- package/dist/commands/collab-sync.d.ts.map +1 -1
- package/dist/commands/collab-sync.js +44 -20
- package/dist/commands/collab-sync.js.map +1 -1
- package/dist/commands/conflicts.js.map +1 -1
- package/dist/commands/demo.d.ts.map +1 -1
- package/dist/commands/demo.js +24 -19
- package/dist/commands/demo.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +40 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/inbox.d.ts.map +1 -1
- package/dist/commands/inbox.js +81 -27
- package/dist/commands/inbox.js.map +1 -1
- package/dist/commands/index.d.ts +5 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +7 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/lock.d.ts.map +1 -1
- package/dist/commands/lock.js +47 -10
- package/dist/commands/lock.js.map +1 -1
- package/dist/commands/monitor.d.ts +3 -0
- package/dist/commands/monitor.d.ts.map +1 -0
- package/dist/commands/monitor.js +153 -0
- package/dist/commands/monitor.js.map +1 -0
- package/dist/commands/msg-read.d.ts.map +1 -1
- package/dist/commands/msg-read.js +59 -34
- package/dist/commands/msg-read.js.map +1 -1
- package/dist/commands/rescue.d.ts +11 -0
- package/dist/commands/rescue.d.ts.map +1 -0
- package/dist/commands/rescue.js +90 -0
- package/dist/commands/rescue.js.map +1 -0
- package/dist/commands/semantic.d.ts +3 -0
- package/dist/commands/semantic.d.ts.map +1 -0
- package/dist/commands/semantic.js +62 -0
- package/dist/commands/semantic.js.map +1 -0
- package/dist/commands/send.d.ts.map +1 -1
- package/dist/commands/send.js +53 -66
- package/dist/commands/send.js.map +1 -1
- package/dist/commands/stale.d.ts +1 -0
- package/dist/commands/stale.d.ts.map +1 -1
- package/dist/commands/stale.js +101 -1
- package/dist/commands/stale.js.map +1 -1
- package/dist/commands/tension.d.ts.map +1 -1
- package/dist/commands/tension.js +27 -7
- package/dist/commands/tension.js.map +1 -1
- package/dist/commands/torrent.d.ts.map +1 -1
- package/dist/commands/torrent.js +23 -18
- package/dist/commands/torrent.js.map +1 -1
- package/dist/commands/welcome.d.ts +3 -0
- package/dist/commands/welcome.d.ts.map +1 -0
- package/dist/commands/welcome.js +92 -0
- package/dist/commands/welcome.js.map +1 -0
- package/dist/commands/who-owns.d.ts +3 -0
- package/dist/commands/who-owns.d.ts.map +1 -0
- package/dist/commands/who-owns.js +68 -0
- package/dist/commands/who-owns.js.map +1 -0
- package/dist/commands/who-touched.d.ts.map +1 -1
- package/dist/commands/who-touched.js +22 -10
- package/dist/commands/who-touched.js.map +1 -1
- package/dist/lib/ast.d.ts +20 -40
- package/dist/lib/ast.d.ts.map +1 -1
- package/dist/lib/ast.js +55 -101
- package/dist/lib/ast.js.map +1 -1
- package/dist/lib/license.d.ts +0 -1
- package/dist/lib/license.d.ts.map +1 -1
- package/dist/lib/license.js +2 -5
- package/dist/lib/license.js.map +1 -1
- package/dist/storage/git-messages.d.ts +53 -0
- package/dist/storage/git-messages.d.ts.map +1 -0
- package/dist/storage/git-messages.js +372 -0
- package/dist/storage/git-messages.js.map +1 -0
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +7 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/local-messages.d.ts +37 -0
- package/dist/storage/local-messages.d.ts.map +1 -0
- package/dist/storage/local-messages.js +151 -0
- package/dist/storage/local-messages.js.map +1 -0
- package/dist/storage/message-adapter.d.ts +86 -0
- package/dist/storage/message-adapter.d.ts.map +1 -0
- package/dist/storage/message-adapter.js +28 -0
- package/dist/storage/message-adapter.js.map +1 -0
- package/dist/storage/message-factory.d.ts +36 -0
- package/dist/storage/message-factory.d.ts.map +1 -0
- package/dist/storage/message-factory.js +99 -0
- package/dist/storage/message-factory.js.map +1 -0
- package/dist/storage/mycmail-adapter.d.ts +38 -0
- package/dist/storage/mycmail-adapter.d.ts.map +1 -0
- package/dist/storage/mycmail-adapter.js +297 -0
- package/dist/storage/mycmail-adapter.js.map +1 -0
- package/dist/tui/dashboard.d.ts +35 -0
- package/dist/tui/dashboard.d.ts.map +1 -0
- package/dist/tui/dashboard.js +190 -0
- package/dist/tui/dashboard.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { io } from 'socket.io-client';
|
|
3
|
+
import { readFileSync, existsSync } from 'fs';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import chokidar from 'chokidar';
|
|
6
|
+
import { SpidersanDashboard } from '../tui/dashboard.js';
|
|
7
|
+
import { getStorage } from '../storage/index.js';
|
|
8
|
+
import { createSwarmState } from '../lib/crdt.js';
|
|
9
|
+
// Config
|
|
10
|
+
const HUB_URL = process.env.HUB_URL || 'https://hub.treebird.uk';
|
|
11
|
+
const AGENT_ID = process.env.SPIDERSAN_AGENT || 'monitor-daemon';
|
|
12
|
+
export const monitorCommand = new Command('monitor')
|
|
13
|
+
.description('π·οΈ Real-time Hub Monitor Dashboard')
|
|
14
|
+
.option('--hub <url>', 'Hub URL to connect to', HUB_URL)
|
|
15
|
+
.action(async (options) => {
|
|
16
|
+
const dashboard = new SpidersanDashboard();
|
|
17
|
+
dashboard.render(); // Initial render
|
|
18
|
+
// CRDT State
|
|
19
|
+
const swarmState = createSwarmState(AGENT_ID);
|
|
20
|
+
// Local Persistence
|
|
21
|
+
const SPIDERSAN_DIR = join(process.cwd(), '.spidersan');
|
|
22
|
+
const STATE_FILE = join(SPIDERSAN_DIR, 'crdt.state');
|
|
23
|
+
// Load initial state
|
|
24
|
+
if (existsSync(STATE_FILE)) {
|
|
25
|
+
try {
|
|
26
|
+
const data = readFileSync(STATE_FILE);
|
|
27
|
+
swarmState.applyUpdate(new Uint8Array(data));
|
|
28
|
+
dashboard.addLog('π Loaded local state');
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
dashboard.addLog(`β οΈ Failed to load state: ${e}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Watch for local changes (from other CLI commands)
|
|
35
|
+
// using chokidar for better cross-platform support
|
|
36
|
+
const watcher = chokidar.watch(STATE_FILE, { persistent: true });
|
|
37
|
+
watcher.on('change', () => {
|
|
38
|
+
try {
|
|
39
|
+
const data = readFileSync(STATE_FILE);
|
|
40
|
+
swarmState.applyUpdate(new Uint8Array(data));
|
|
41
|
+
// dashboard.addLog('π Local state updated'); // verbose
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
// ignore read errors (race conditions)
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
// Refresh dashboard when CRDT state changes
|
|
48
|
+
swarmState.doc.on('update', () => {
|
|
49
|
+
const locks = swarmState.getAllLocks().map(l => ({
|
|
50
|
+
symbol: l.symbolId,
|
|
51
|
+
agent: l.agentId,
|
|
52
|
+
time: l.timestamp
|
|
53
|
+
}));
|
|
54
|
+
dashboard.updateState({ activeLocks: locks });
|
|
55
|
+
});
|
|
56
|
+
try {
|
|
57
|
+
// 1. Connect to Hub
|
|
58
|
+
dashboard.addLog(`Connecting to Hub: ${options.hub}...`);
|
|
59
|
+
const socket = io(options.hub, {
|
|
60
|
+
reconnection: true,
|
|
61
|
+
timeout: 5000
|
|
62
|
+
});
|
|
63
|
+
const connectedAgents = new Set();
|
|
64
|
+
socket.on('connect', () => {
|
|
65
|
+
dashboard.addLog('β
Connected to Hub');
|
|
66
|
+
dashboard.updateState({ connectedAgents: Array.from(connectedAgents) });
|
|
67
|
+
socket.emit('subscribe', {
|
|
68
|
+
events: ['file:changed', 'task:updated', 'agent:heartbeat', 'crdt:update', 'crdt:state']
|
|
69
|
+
});
|
|
70
|
+
// Request initial CRDT state
|
|
71
|
+
socket.emit('crdt:request-state');
|
|
72
|
+
});
|
|
73
|
+
socket.on('disconnect', () => {
|
|
74
|
+
dashboard.addLog('β Disconnected from Hub');
|
|
75
|
+
connectedAgents.clear();
|
|
76
|
+
dashboard.updateState({ connectedAgents: [] });
|
|
77
|
+
});
|
|
78
|
+
socket.on('connect_error', (err) => {
|
|
79
|
+
dashboard.addLog(`β οΈ Connection error: ${err.message}`);
|
|
80
|
+
});
|
|
81
|
+
// 2. Listen for Events
|
|
82
|
+
// CRDT Sync
|
|
83
|
+
socket.on('crdt:update', (data) => {
|
|
84
|
+
const update = new Uint8Array(Buffer.from(data.update, 'base64'));
|
|
85
|
+
swarmState.applyUpdate(update);
|
|
86
|
+
});
|
|
87
|
+
socket.on('crdt:state', (data) => {
|
|
88
|
+
dashboard.addLog(`π¦ Received State (${data.updates.length} chunks)`);
|
|
89
|
+
for (const chunk of data.updates) {
|
|
90
|
+
const update = new Uint8Array(Buffer.from(chunk, 'base64'));
|
|
91
|
+
swarmState.applyUpdate(update);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
// Heartbeats
|
|
95
|
+
socket.on('agent:heartbeat', (data) => {
|
|
96
|
+
if (!connectedAgents.has(data.agent)) {
|
|
97
|
+
connectedAgents.add(data.agent);
|
|
98
|
+
dashboard.addLog(`π Agent joined: ${data.agent}`);
|
|
99
|
+
dashboard.updateState({ connectedAgents: Array.from(connectedAgents) });
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
// File Changes (Conflict Radar)
|
|
103
|
+
const activeFiles = new Map();
|
|
104
|
+
socket.on('file:changed', (data) => {
|
|
105
|
+
if (data.action === 'editing') {
|
|
106
|
+
const agents = activeFiles.get(data.file) || [];
|
|
107
|
+
if (!agents.includes(data.agent)) {
|
|
108
|
+
agents.push(data.agent);
|
|
109
|
+
activeFiles.set(data.file, agents);
|
|
110
|
+
dashboard.addLog(`βοΈ ${data.agent} editing ${data.file}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else if (data.action === 'closed' || data.action === 'saved') {
|
|
114
|
+
const agents = activeFiles.get(data.file) || [];
|
|
115
|
+
const newAgents = agents.filter(a => a !== data.agent);
|
|
116
|
+
if (newAgents.length === 0) {
|
|
117
|
+
activeFiles.delete(data.file);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
activeFiles.set(data.file, newAgents);
|
|
121
|
+
}
|
|
122
|
+
dashboard.addLog(`πΎ ${data.agent} ${data.action} ${data.file}`);
|
|
123
|
+
}
|
|
124
|
+
dashboard.updateState({ activeFiles });
|
|
125
|
+
});
|
|
126
|
+
// Task Updates (Formation)
|
|
127
|
+
socket.on('task:updated', (task) => {
|
|
128
|
+
// In a real app we'd merge this into a map, for now just log
|
|
129
|
+
dashboard.addLog(`π Task Update: ${task.title} -> ${task.status}`);
|
|
130
|
+
});
|
|
131
|
+
// 3. Local Polling (Backup if Hub is quiet)
|
|
132
|
+
// Just to show some activity in the demo if no other agents are online
|
|
133
|
+
setInterval(() => {
|
|
134
|
+
dashboard.render(); // Keep clock updating
|
|
135
|
+
}, 1000);
|
|
136
|
+
// Access local storage to show local branches as a baseline
|
|
137
|
+
try {
|
|
138
|
+
const storage = await getStorage();
|
|
139
|
+
const branches = await storage.list();
|
|
140
|
+
if (branches.length > 0) {
|
|
141
|
+
dashboard.addLog(`π Loaded ${branches.length} local branches`);
|
|
142
|
+
// We could visualize these, but Monitor is mainly for Hub state
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (e) {
|
|
146
|
+
// ignore
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
dashboard.addLog(`β Fatal error: ${error}`);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=monitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../src/commands/monitor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"msg-read.d.ts","sourceRoot":"","sources":["../../src/commands/msg-read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"msg-read.d.ts","sourceRoot":"","sources":["../../src/commands/msg-read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBpC,eAAO,MAAM,cAAc,SAoFrB,CAAC"}
|
|
@@ -1,68 +1,93 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import {
|
|
2
|
+
import { getMessageStorage, parseTierOption } from '../storage/message-factory.js';
|
|
3
3
|
// Security: Input validation
|
|
4
|
-
const VALID_AGENT_ID = /^[a-z0-9][a-z0-9_-]{0,30}$/i;
|
|
5
4
|
const VALID_MESSAGE_ID = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,64}$/;
|
|
6
|
-
function validateAgentId(agentId) {
|
|
7
|
-
if (!VALID_AGENT_ID.test(agentId)) {
|
|
8
|
-
throw new Error(`Invalid agent ID: "${agentId.slice(0, 20)}..."`);
|
|
9
|
-
}
|
|
10
|
-
return agentId;
|
|
11
|
-
}
|
|
12
5
|
function validateMessageId(id) {
|
|
13
6
|
if (!VALID_MESSAGE_ID.test(id)) {
|
|
14
7
|
throw new Error(`Invalid message ID: "${id.slice(0, 20)}..."`);
|
|
15
8
|
}
|
|
16
9
|
return id;
|
|
17
10
|
}
|
|
11
|
+
function formatTimestamp(date) {
|
|
12
|
+
return date.toLocaleString('en-US', {
|
|
13
|
+
weekday: 'short',
|
|
14
|
+
month: 'short',
|
|
15
|
+
day: 'numeric',
|
|
16
|
+
hour: '2-digit',
|
|
17
|
+
minute: '2-digit',
|
|
18
|
+
});
|
|
19
|
+
}
|
|
18
20
|
export const msgReadCommand = new Command('read')
|
|
19
|
-
.description('Read a specific message (
|
|
21
|
+
.description('Read a specific message (tiered fallback)')
|
|
20
22
|
.argument('<id>', 'Message ID (full or partial)')
|
|
21
|
-
.option('--no-mark-read', 'Don\'t mark the message as read
|
|
23
|
+
.option('--no-mark-read', 'Don\'t mark the message as read')
|
|
24
|
+
.option('--tier <n>', 'Force specific tier (1, 2, or 3)')
|
|
25
|
+
.option('-v, --verbose', 'Show which tier is being used')
|
|
22
26
|
.option('--json', 'Output as JSON')
|
|
23
27
|
.action(async (id, options) => {
|
|
24
|
-
const
|
|
25
|
-
// Security: Validate
|
|
26
|
-
let agentId;
|
|
28
|
+
const agentId = process.env.SPIDERSAN_AGENT || 'cli-agent';
|
|
29
|
+
// Security: Validate message ID
|
|
27
30
|
let messageId;
|
|
28
31
|
try {
|
|
29
|
-
agentId = validateAgentId(rawAgentId);
|
|
30
32
|
messageId = validateMessageId(id);
|
|
31
33
|
}
|
|
32
34
|
catch (error) {
|
|
33
35
|
console.error(`β ${error.message}`);
|
|
34
36
|
process.exit(1);
|
|
35
37
|
}
|
|
38
|
+
// Get message storage adapter
|
|
39
|
+
const forceTier = parseTierOption(options.tier);
|
|
36
40
|
try {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
console.error(' Please install it: npm install -g myceliumail');
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
44
|
-
// Security: Use spawnSync with argument array instead of string interpolation
|
|
45
|
-
try {
|
|
46
|
-
const result = spawnSync('mycmail', ['read', messageId], {
|
|
47
|
-
encoding: 'utf-8',
|
|
48
|
-
env: { ...process.env, MYCELIUMAIL_AGENT_ID: agentId }
|
|
41
|
+
const storage = await getMessageStorage({
|
|
42
|
+
forceTier,
|
|
43
|
+
agentId,
|
|
44
|
+
verbose: options.verbose,
|
|
49
45
|
});
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
// Read message
|
|
47
|
+
const message = await storage.read(messageId);
|
|
48
|
+
if (!message) {
|
|
49
|
+
console.error(`β Message not found: ${messageId}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
// Mark as read if requested
|
|
53
|
+
if (options.markRead !== false) {
|
|
54
|
+
await storage.markRead(messageId);
|
|
52
55
|
}
|
|
53
|
-
const output = result.stdout || '';
|
|
54
56
|
if (options.json) {
|
|
55
57
|
console.log(JSON.stringify({
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
tier: storage.getTier(),
|
|
59
|
+
tierName: storage.getTierName(),
|
|
60
|
+
message: {
|
|
61
|
+
...message,
|
|
62
|
+
timestamp: message.timestamp.toISOString(),
|
|
63
|
+
},
|
|
58
64
|
}, null, 2));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Display message
|
|
68
|
+
const tierInfo = options.verbose ? ` (via ${storage.getTierName()})` : '';
|
|
69
|
+
const encryptIcon = message.encrypted ? ' π' : '';
|
|
70
|
+
const typeLabel = message.type !== 'info' ? ` [${message.type.toUpperCase()}]` : '';
|
|
71
|
+
console.log(`\nπ§ Message${tierInfo}\n`);
|
|
72
|
+
console.log('β'.repeat(60));
|
|
73
|
+
console.log(`Subject: ${message.subject}${typeLabel}${encryptIcon}`);
|
|
74
|
+
console.log(`From: ${message.from}`);
|
|
75
|
+
console.log(`To: ${message.to}`);
|
|
76
|
+
console.log(`Date: ${formatTimestamp(message.timestamp)}`);
|
|
77
|
+
console.log(`ID: ${message.id}`);
|
|
78
|
+
if (message.branch) {
|
|
79
|
+
console.log(`Branch: ${message.branch}`);
|
|
59
80
|
}
|
|
60
|
-
|
|
61
|
-
console.log(
|
|
81
|
+
if (message.files && message.files.length > 0) {
|
|
82
|
+
console.log(`Files: ${message.files.join(', ')}`);
|
|
62
83
|
}
|
|
84
|
+
console.log('β'.repeat(60));
|
|
85
|
+
console.log('');
|
|
86
|
+
console.log(message.body);
|
|
87
|
+
console.log('');
|
|
63
88
|
}
|
|
64
89
|
catch (error) {
|
|
65
|
-
console.error('β Failed to read message
|
|
90
|
+
console.error('β Failed to read message');
|
|
66
91
|
console.error(error.message || error);
|
|
67
92
|
process.exit(1);
|
|
68
93
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"msg-read.js","sourceRoot":"","sources":["../../src/commands/msg-read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"msg-read.js","sourceRoot":"","sources":["../../src/commands/msg-read.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spidersan rescue
|
|
3
|
+
*
|
|
4
|
+
* Rescue Mission:
|
|
5
|
+
* 1. Scan for untracked files (aliens)
|
|
6
|
+
* 2. Scan for unregistered branches (ghosts)
|
|
7
|
+
* 3. Triage & Salvage
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
export declare const rescueCommand: Command;
|
|
11
|
+
//# sourceMappingURL=rescue.d.ts.map
|
|
@@ -0,0 +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;AAMpC,eAAO,MAAM,aAAa,SAsFpB,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spidersan rescue
|
|
3
|
+
*
|
|
4
|
+
* Rescue Mission:
|
|
5
|
+
* 1. Scan for untracked files (aliens)
|
|
6
|
+
* 2. Scan for unregistered branches (ghosts)
|
|
7
|
+
* 3. Triage & Salvage
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
import { execSync } from 'child_process';
|
|
11
|
+
import { getStorage } from '../storage/index.js';
|
|
12
|
+
import { existsSync, mkdirSync, copyFileSync } from 'fs';
|
|
13
|
+
import { join, basename } from 'path';
|
|
14
|
+
export const rescueCommand = new Command('rescue')
|
|
15
|
+
.description('π Rescue Mode - Scan for and salvage rogue work')
|
|
16
|
+
.option('--scan', 'Scan for problems')
|
|
17
|
+
.option('--salvage <file>', 'Salvage a specific file to ./salvage/')
|
|
18
|
+
.option('--abandon <file>', 'Delete a rogue file')
|
|
19
|
+
.action(async (options) => {
|
|
20
|
+
const storage = await getStorage();
|
|
21
|
+
console.log('\nπ SPIDERSAN RESCUE MISSION\nββββββββββββββββββββββββββ');
|
|
22
|
+
// 1. Scan for Untracked Files
|
|
23
|
+
let untracked = [];
|
|
24
|
+
try {
|
|
25
|
+
const output = execSync('git status --porcelain', { encoding: 'utf-8' });
|
|
26
|
+
untracked = output.split('\n')
|
|
27
|
+
.filter(line => line.startsWith('?? '))
|
|
28
|
+
.map(line => line.substring(3));
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
console.error('β Failed to scan git status');
|
|
32
|
+
}
|
|
33
|
+
// 2. Scan for Unregistered Branches
|
|
34
|
+
let ghosts = [];
|
|
35
|
+
try {
|
|
36
|
+
const localBranches = execSync('git branch --format="%(refname:short)"', { encoding: 'utf-8' })
|
|
37
|
+
.split('\n').filter(Boolean);
|
|
38
|
+
const registered = await storage.list();
|
|
39
|
+
const registeredNames = new Set(registered.map(b => b.name));
|
|
40
|
+
ghosts = localBranches.filter(b => !registeredNames.has(b) && b !== 'main' && b !== 'master');
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
console.error('β Failed to scan branches');
|
|
44
|
+
}
|
|
45
|
+
if (options.scan) {
|
|
46
|
+
console.log(`\nπ SCAN RESULTS:`);
|
|
47
|
+
if (untracked.length === 0 && ghosts.length === 0) {
|
|
48
|
+
console.log(' β
Sector clear. No anomalies detected.');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (untracked.length > 0) {
|
|
52
|
+
console.log(`\nπ½ Untracked Files (${untracked.length}):`);
|
|
53
|
+
untracked.forEach(f => console.log(` - ${f}`));
|
|
54
|
+
}
|
|
55
|
+
if (ghosts.length > 0) {
|
|
56
|
+
console.log(`\nπ» Ghost Branches (${ghosts.length}):`);
|
|
57
|
+
ghosts.forEach(b => console.log(` - ${b}`));
|
|
58
|
+
}
|
|
59
|
+
console.log('\nπ‘ Actions:');
|
|
60
|
+
console.log(' spidersan rescue --salvage <file>');
|
|
61
|
+
console.log(' spidersan rescue --abandon <file>');
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// Salvage Operation
|
|
65
|
+
if (options.salvage) {
|
|
66
|
+
const target = options.salvage;
|
|
67
|
+
if (!untracked.includes(target) && existsSync(target)) {
|
|
68
|
+
console.log(`β οΈ File '${target}' is tracked by git. Use git commands instead.`);
|
|
69
|
+
}
|
|
70
|
+
const salvageDir = 'salvage';
|
|
71
|
+
if (!existsSync(salvageDir))
|
|
72
|
+
mkdirSync(salvageDir);
|
|
73
|
+
const dest = join(salvageDir, basename(target));
|
|
74
|
+
copyFileSync(target, dest);
|
|
75
|
+
console.log(`β
Salvaged '${target}' to '${dest}'`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Abandon Operation
|
|
79
|
+
if (options.abandon) {
|
|
80
|
+
const target = options.abandon;
|
|
81
|
+
// In a real CLI we'd ask for confirmation, for now just warn
|
|
82
|
+
console.log(`β οΈ Deleting '${target}'... (Simulated)`);
|
|
83
|
+
// rmSync(target); // Safety first for this demo
|
|
84
|
+
console.log(`ποΈ Abandoned '${target}'`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// Default: Run scan
|
|
88
|
+
console.log('Use --scan to see anomalies.');
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=rescue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rescue.js","sourceRoot":"","sources":["../../src/commands/rescue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../src/commands/semantic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,eAAe,SAwDtB,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
export const semanticCommand = new Command('semantic')
|
|
5
|
+
.description('π·οΈ Semantic conflict detection via RLS Knowledge Graph')
|
|
6
|
+
.option('-c, --check <file>', 'Check a specific file for semantic conflicts')
|
|
7
|
+
.option('-q, --query <text>', 'Query the knowledge graph manually')
|
|
8
|
+
.action(async (options) => {
|
|
9
|
+
let AgentKnowledgeBase;
|
|
10
|
+
try {
|
|
11
|
+
const mappersan = await import('mappersan');
|
|
12
|
+
AgentKnowledgeBase = mappersan.AgentKnowledgeBase;
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
console.error(chalk.red('\nβ The "semantic" command requires the @treebird/mappersan package.'));
|
|
16
|
+
console.log(chalk.gray(' This package is currently part of the internal Treebird ecosystem.'));
|
|
17
|
+
console.log(chalk.gray(' If you are an internal user, run: npm install ../mappersan\n'));
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
const kb = new AgentKnowledgeBase({
|
|
21
|
+
agentId: 'spidersan',
|
|
22
|
+
supabaseUrl: process.env.SUPABASE_URL || '',
|
|
23
|
+
supabaseKey: process.env.SUPABASE_SERVICE_KEY || '', // Needs service key for internal
|
|
24
|
+
openaiKey: process.env.OPENAI_API_KEY
|
|
25
|
+
});
|
|
26
|
+
if (options.query) {
|
|
27
|
+
console.log(chalk.gray(`Querying: "${options.query}"`));
|
|
28
|
+
try {
|
|
29
|
+
const result = await kb.query(options.query);
|
|
30
|
+
console.log(chalk.bold('\nπ Context Found:'));
|
|
31
|
+
console.log(result.context);
|
|
32
|
+
if (result.graph.length > 0) {
|
|
33
|
+
console.log(chalk.bold('\nπΈοΈ Graph Connections:'));
|
|
34
|
+
result.graph.forEach((node) => {
|
|
35
|
+
console.log(` ${node.connected_to} --${node.relation_type}--> ${node.node_name} (${node.node_type})`);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
console.error(chalk.red('Query failed:'), err.message);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else if (options.check) {
|
|
44
|
+
console.log(chalk.yellow(`Checking file: ${options.check}`));
|
|
45
|
+
// MVP: Just query specifically for the file name in the graph
|
|
46
|
+
// In future: read file content, extract entities, check graph intersection
|
|
47
|
+
const fileName = path.basename(options.check);
|
|
48
|
+
const result = await kb.query(`conflicts related to ${fileName} or file:${fileName}`);
|
|
49
|
+
console.log(chalk.bold('\nβ οΈ Potential Semantic Overlaps:'));
|
|
50
|
+
// Heuristic display
|
|
51
|
+
if (result.context.length > 50) {
|
|
52
|
+
console.log(result.context);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
console.log(chalk.green('No knowledge graph entries found for this file.'));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
console.log('Please provide --query or --check');
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=semantic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic.js","sourceRoot":"","sources":["../../src/commands/semantic.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCpC,eAAO,MAAM,WAAW,SAiGlB,CAAC"}
|