spidersan 0.2.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.
Files changed (245) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/LICENSE +21 -0
  3. package/LICENSE.md +85 -0
  4. package/README.md +217 -0
  5. package/dist/bin/spidersan.d.ts +9 -0
  6. package/dist/bin/spidersan.d.ts.map +1 -0
  7. package/dist/bin/spidersan.js +152 -0
  8. package/dist/bin/spidersan.js.map +1 -0
  9. package/dist/commands/abandon.d.ts +8 -0
  10. package/dist/commands/abandon.d.ts.map +1 -0
  11. package/dist/commands/abandon.js +49 -0
  12. package/dist/commands/abandon.js.map +1 -0
  13. package/dist/commands/activate.d.ts +9 -0
  14. package/dist/commands/activate.d.ts.map +1 -0
  15. package/dist/commands/activate.js +45 -0
  16. package/dist/commands/activate.js.map +1 -0
  17. package/dist/commands/active-windows.d.ts +16 -0
  18. package/dist/commands/active-windows.d.ts.map +1 -0
  19. package/dist/commands/active-windows.js +373 -0
  20. package/dist/commands/active-windows.js.map +1 -0
  21. package/dist/commands/audit-mark.d.ts +12 -0
  22. package/dist/commands/audit-mark.d.ts.map +1 -0
  23. package/dist/commands/audit-mark.js +204 -0
  24. package/dist/commands/audit-mark.js.map +1 -0
  25. package/dist/commands/cleanup.d.ts +8 -0
  26. package/dist/commands/cleanup.d.ts.map +1 -0
  27. package/dist/commands/cleanup.js +41 -0
  28. package/dist/commands/cleanup.js.map +1 -0
  29. package/dist/commands/close.d.ts +9 -0
  30. package/dist/commands/close.d.ts.map +1 -0
  31. package/dist/commands/close.js +129 -0
  32. package/dist/commands/close.js.map +1 -0
  33. package/dist/commands/collab-sync.d.ts +14 -0
  34. package/dist/commands/collab-sync.d.ts.map +1 -0
  35. package/dist/commands/collab-sync.js +240 -0
  36. package/dist/commands/collab-sync.js.map +1 -0
  37. package/dist/commands/collab.d.ts +6 -0
  38. package/dist/commands/collab.d.ts.map +1 -0
  39. package/dist/commands/collab.js +103 -0
  40. package/dist/commands/collab.js.map +1 -0
  41. package/dist/commands/completions.d.ts +8 -0
  42. package/dist/commands/completions.d.ts.map +1 -0
  43. package/dist/commands/completions.js +83 -0
  44. package/dist/commands/completions.js.map +1 -0
  45. package/dist/commands/conflicts.d.ts +12 -0
  46. package/dist/commands/conflicts.d.ts.map +1 -0
  47. package/dist/commands/conflicts.js +426 -0
  48. package/dist/commands/conflicts.js.map +1 -0
  49. package/dist/commands/demo.d.ts +3 -0
  50. package/dist/commands/demo.d.ts.map +1 -0
  51. package/dist/commands/demo.js +113 -0
  52. package/dist/commands/demo.js.map +1 -0
  53. package/dist/commands/depends.d.ts +8 -0
  54. package/dist/commands/depends.d.ts.map +1 -0
  55. package/dist/commands/depends.js +44 -0
  56. package/dist/commands/depends.js.map +1 -0
  57. package/dist/commands/doctor.d.ts +8 -0
  58. package/dist/commands/doctor.d.ts.map +1 -0
  59. package/dist/commands/doctor.js +249 -0
  60. package/dist/commands/doctor.js.map +1 -0
  61. package/dist/commands/inbox.d.ts +3 -0
  62. package/dist/commands/inbox.d.ts.map +1 -0
  63. package/dist/commands/inbox.js +66 -0
  64. package/dist/commands/inbox.js.map +1 -0
  65. package/dist/commands/index.d.ts +43 -0
  66. package/dist/commands/index.d.ts.map +1 -0
  67. package/dist/commands/index.js +61 -0
  68. package/dist/commands/index.js.map +1 -0
  69. package/dist/commands/init.d.ts +8 -0
  70. package/dist/commands/init.d.ts.map +1 -0
  71. package/dist/commands/init.js +23 -0
  72. package/dist/commands/init.js.map +1 -0
  73. package/dist/commands/intent-scan.d.ts +17 -0
  74. package/dist/commands/intent-scan.d.ts.map +1 -0
  75. package/dist/commands/intent-scan.js +336 -0
  76. package/dist/commands/intent-scan.js.map +1 -0
  77. package/dist/commands/key-import.d.ts +3 -0
  78. package/dist/commands/key-import.d.ts.map +1 -0
  79. package/dist/commands/key-import.js +54 -0
  80. package/dist/commands/key-import.js.map +1 -0
  81. package/dist/commands/keygen.d.ts +3 -0
  82. package/dist/commands/keygen.d.ts.map +1 -0
  83. package/dist/commands/keygen.js +53 -0
  84. package/dist/commands/keygen.js.map +1 -0
  85. package/dist/commands/keys.d.ts +3 -0
  86. package/dist/commands/keys.d.ts.map +1 -0
  87. package/dist/commands/keys.js +56 -0
  88. package/dist/commands/keys.js.map +1 -0
  89. package/dist/commands/list.d.ts +3 -0
  90. package/dist/commands/list.d.ts.map +1 -0
  91. package/dist/commands/list.js +45 -0
  92. package/dist/commands/list.js.map +1 -0
  93. package/dist/commands/lock.d.ts +11 -0
  94. package/dist/commands/lock.d.ts.map +1 -0
  95. package/dist/commands/lock.js +220 -0
  96. package/dist/commands/lock.js.map +1 -0
  97. package/dist/commands/log.d.ts +8 -0
  98. package/dist/commands/log.d.ts.map +1 -0
  99. package/dist/commands/log.js +95 -0
  100. package/dist/commands/log.js.map +1 -0
  101. package/dist/commands/mcp-health.d.ts +3 -0
  102. package/dist/commands/mcp-health.d.ts.map +1 -0
  103. package/dist/commands/mcp-health.js +305 -0
  104. package/dist/commands/mcp-health.js.map +1 -0
  105. package/dist/commands/mcp-restart.d.ts +3 -0
  106. package/dist/commands/mcp-restart.d.ts.map +1 -0
  107. package/dist/commands/mcp-restart.js +176 -0
  108. package/dist/commands/mcp-restart.js.map +1 -0
  109. package/dist/commands/merge-order.d.ts +9 -0
  110. package/dist/commands/merge-order.d.ts.map +1 -0
  111. package/dist/commands/merge-order.js +138 -0
  112. package/dist/commands/merge-order.js.map +1 -0
  113. package/dist/commands/merged.d.ts +8 -0
  114. package/dist/commands/merged.d.ts.map +1 -0
  115. package/dist/commands/merged.js +39 -0
  116. package/dist/commands/merged.js.map +1 -0
  117. package/dist/commands/msg-read.d.ts +3 -0
  118. package/dist/commands/msg-read.d.ts.map +1 -0
  119. package/dist/commands/msg-read.js +70 -0
  120. package/dist/commands/msg-read.js.map +1 -0
  121. package/dist/commands/pulse.d.ts +9 -0
  122. package/dist/commands/pulse.d.ts.map +1 -0
  123. package/dist/commands/pulse.js +232 -0
  124. package/dist/commands/pulse.js.map +1 -0
  125. package/dist/commands/radar.d.ts +3 -0
  126. package/dist/commands/radar.d.ts.map +1 -0
  127. package/dist/commands/radar.js +147 -0
  128. package/dist/commands/radar.js.map +1 -0
  129. package/dist/commands/ready-check.d.ts +9 -0
  130. package/dist/commands/ready-check.d.ts.map +1 -0
  131. package/dist/commands/ready-check.js +156 -0
  132. package/dist/commands/ready-check.js.map +1 -0
  133. package/dist/commands/register.d.ts +3 -0
  134. package/dist/commands/register.d.ts.map +1 -0
  135. package/dist/commands/register.js +124 -0
  136. package/dist/commands/register.js.map +1 -0
  137. package/dist/commands/send.d.ts +3 -0
  138. package/dist/commands/send.d.ts.map +1 -0
  139. package/dist/commands/send.js +134 -0
  140. package/dist/commands/send.js.map +1 -0
  141. package/dist/commands/stale.d.ts +8 -0
  142. package/dist/commands/stale.d.ts.map +1 -0
  143. package/dist/commands/stale.js +38 -0
  144. package/dist/commands/stale.js.map +1 -0
  145. package/dist/commands/status.d.ts +9 -0
  146. package/dist/commands/status.d.ts.map +1 -0
  147. package/dist/commands/status.js +41 -0
  148. package/dist/commands/status.js.map +1 -0
  149. package/dist/commands/sync-all.d.ts +9 -0
  150. package/dist/commands/sync-all.d.ts.map +1 -0
  151. package/dist/commands/sync-all.js +180 -0
  152. package/dist/commands/sync-all.js.map +1 -0
  153. package/dist/commands/sync.d.ts +8 -0
  154. package/dist/commands/sync.d.ts.map +1 -0
  155. package/dist/commands/sync.js +49 -0
  156. package/dist/commands/sync.js.map +1 -0
  157. package/dist/commands/tension.d.ts +12 -0
  158. package/dist/commands/tension.d.ts.map +1 -0
  159. package/dist/commands/tension.js +242 -0
  160. package/dist/commands/tension.js.map +1 -0
  161. package/dist/commands/torrent.d.ts +9 -0
  162. package/dist/commands/torrent.d.ts.map +1 -0
  163. package/dist/commands/torrent.js +431 -0
  164. package/dist/commands/torrent.js.map +1 -0
  165. package/dist/commands/tui.d.ts +8 -0
  166. package/dist/commands/tui.d.ts.map +1 -0
  167. package/dist/commands/tui.js +15 -0
  168. package/dist/commands/tui.js.map +1 -0
  169. package/dist/commands/wake.d.ts +9 -0
  170. package/dist/commands/wake.d.ts.map +1 -0
  171. package/dist/commands/wake.js +188 -0
  172. package/dist/commands/wake.js.map +1 -0
  173. package/dist/commands/watch.d.ts +3 -0
  174. package/dist/commands/watch.d.ts.map +1 -0
  175. package/dist/commands/watch.js +245 -0
  176. package/dist/commands/watch.js.map +1 -0
  177. package/dist/commands/who-touched.d.ts +9 -0
  178. package/dist/commands/who-touched.d.ts.map +1 -0
  179. package/dist/commands/who-touched.js +186 -0
  180. package/dist/commands/who-touched.js.map +1 -0
  181. package/dist/index.d.ts +6 -0
  182. package/dist/index.d.ts.map +1 -0
  183. package/dist/index.js +6 -0
  184. package/dist/index.js.map +1 -0
  185. package/dist/lib/agent-errors.d.ts +41 -0
  186. package/dist/lib/agent-errors.d.ts.map +1 -0
  187. package/dist/lib/agent-errors.js +143 -0
  188. package/dist/lib/agent-errors.js.map +1 -0
  189. package/dist/lib/ast.d.ts +56 -0
  190. package/dist/lib/ast.d.ts.map +1 -0
  191. package/dist/lib/ast.js +134 -0
  192. package/dist/lib/ast.js.map +1 -0
  193. package/dist/lib/config.d.ts +33 -0
  194. package/dist/lib/config.d.ts.map +1 -0
  195. package/dist/lib/config.js +127 -0
  196. package/dist/lib/config.js.map +1 -0
  197. package/dist/lib/crdt.d.ts +83 -0
  198. package/dist/lib/crdt.d.ts.map +1 -0
  199. package/dist/lib/crdt.js +160 -0
  200. package/dist/lib/crdt.js.map +1 -0
  201. package/dist/lib/crypto.d.ts +71 -0
  202. package/dist/lib/crypto.d.ts.map +1 -0
  203. package/dist/lib/crypto.js +172 -0
  204. package/dist/lib/crypto.js.map +1 -0
  205. package/dist/lib/errors.d.ts +35 -0
  206. package/dist/lib/errors.d.ts.map +1 -0
  207. package/dist/lib/errors.js +71 -0
  208. package/dist/lib/errors.js.map +1 -0
  209. package/dist/lib/license.d.ts +61 -0
  210. package/dist/lib/license.d.ts.map +1 -0
  211. package/dist/lib/license.js +171 -0
  212. package/dist/lib/license.js.map +1 -0
  213. package/dist/lib/security.d.ts +53 -0
  214. package/dist/lib/security.d.ts.map +1 -0
  215. package/dist/lib/security.js +122 -0
  216. package/dist/lib/security.js.map +1 -0
  217. package/dist/lib/update-check.d.ts +11 -0
  218. package/dist/lib/update-check.d.ts.map +1 -0
  219. package/dist/lib/update-check.js +113 -0
  220. package/dist/lib/update-check.js.map +1 -0
  221. package/dist/storage/adapter.d.ts +58 -0
  222. package/dist/storage/adapter.d.ts.map +1 -0
  223. package/dist/storage/adapter.js +8 -0
  224. package/dist/storage/adapter.js.map +1 -0
  225. package/dist/storage/factory.d.ts +6 -0
  226. package/dist/storage/factory.d.ts.map +1 -0
  227. package/dist/storage/factory.js +22 -0
  228. package/dist/storage/factory.js.map +1 -0
  229. package/dist/storage/index.d.ts +5 -0
  230. package/dist/storage/index.d.ts.map +1 -0
  231. package/dist/storage/index.js +5 -0
  232. package/dist/storage/index.js.map +1 -0
  233. package/dist/storage/local.d.ts +24 -0
  234. package/dist/storage/local.d.ts.map +1 -0
  235. package/dist/storage/local.js +101 -0
  236. package/dist/storage/local.js.map +1 -0
  237. package/dist/storage/supabase.d.ts +52 -0
  238. package/dist/storage/supabase.d.ts.map +1 -0
  239. package/dist/storage/supabase.js +221 -0
  240. package/dist/storage/supabase.js.map +1 -0
  241. package/dist/tui/screen.d.ts +14 -0
  242. package/dist/tui/screen.d.ts.map +1 -0
  243. package/dist/tui/screen.js +136 -0
  244. package/dist/tui/screen.js.map +1 -0
  245. package/package.json +89 -0
@@ -0,0 +1,336 @@
1
+ /**
2
+ * spidersan intent-scan
3
+ *
4
+ * Layer 3: Intent Conflict Detection
5
+ *
6
+ * Parses collab entries to detect overlapping work intentions
7
+ * BEFORE agents start coding. Prevents duplicate work like
8
+ * the formation incident.
9
+ *
10
+ * Usage:
11
+ * spidersan intent-scan # Scan today's collab
12
+ * spidersan intent-scan --days 3 # Scan last 3 days
13
+ * spidersan intent-scan --watch # Watch for new intents
14
+ */
15
+ import { Command } from 'commander';
16
+ import { readFileSync, readdirSync, existsSync } from 'fs';
17
+ import { join } from 'path';
18
+ import chalk from 'chalk';
19
+ // Keywords that indicate work intent
20
+ const INTENT_VERBS = [
21
+ 'building', 'implementing', 'creating', 'adding', 'developing',
22
+ 'starting', 'working on', 'claiming', 'taking', 'picking up',
23
+ 'coding', 'writing', 'designing', 'planning', 'shipping'
24
+ ];
25
+ // Keywords that indicate completion
26
+ const COMPLETION_VERBS = [
27
+ 'shipped', 'completed', 'finished', 'done', 'merged', 'pushed'
28
+ ];
29
+ // High-value keywords to track
30
+ const PROJECT_KEYWORDS = [
31
+ 'formation', 'invoak', 'swarmsan', 'treesan', 'spidersan',
32
+ 'flockview', 'treesync', 'mycmail', 'myceliumail', 'watsan',
33
+ 'sancho', 'birdsan', 'sherlocksan', 'envoak', 'mappersan',
34
+ 'mvp', 'cli', 'mcp', 'worker', 'pool', 'task', 'sync',
35
+ 'hybrid', 'search', 'rag', 'kg', 'digest', 'status'
36
+ ];
37
+ // Agent emoji patterns
38
+ const AGENT_PATTERNS = {
39
+ '🐦': 'Birdsan',
40
+ '🕷️': 'Spidersan',
41
+ '🔍': 'Sherlocksan',
42
+ '🌵': 'Sancho',
43
+ '📣': 'Marksan',
44
+ '🗺️': 'Mappersan',
45
+ '🍄': 'Myceliumail',
46
+ '📚': 'Watsan',
47
+ '🧪': 'Yosef',
48
+ '🎨': 'Artisan',
49
+ '🌑': 'Sasusan',
50
+ '🌲': 'Treesan'
51
+ };
52
+ function parseAgentEntry(line) {
53
+ // Pattern: ## 🐦 Birdsan — 21:10 (optional context)
54
+ const match = line.match(/^##\s+([\p{Emoji}]+)\s+(\w+)\s*[—-]\s*(\d{1,2}:\d{2})/u);
55
+ if (match) {
56
+ return { agent: match[2], time: match[3] };
57
+ }
58
+ return null;
59
+ }
60
+ function extractStatus(text) {
61
+ const lower = text.toLowerCase();
62
+ if (COMPLETION_VERBS.some(v => lower.includes(v)))
63
+ return 'complete';
64
+ if (lower.includes('starting') || lower.includes('claiming'))
65
+ return 'starting';
66
+ if (lower.includes('implementing') || lower.includes('building'))
67
+ return 'implementing';
68
+ if (lower.includes('planning') || lower.includes('proposing'))
69
+ return 'planning';
70
+ return 'unknown';
71
+ }
72
+ function extractKeywords(text) {
73
+ const lower = text.toLowerCase();
74
+ return PROJECT_KEYWORDS.filter(kw => lower.includes(kw));
75
+ }
76
+ function extractIntent(text) {
77
+ const lower = text.toLowerCase();
78
+ // Look for intent patterns
79
+ for (const verb of INTENT_VERBS) {
80
+ const idx = lower.indexOf(verb);
81
+ if (idx !== -1) {
82
+ // Extract up to 50 chars after verb
83
+ const start = idx;
84
+ const end = Math.min(idx + 60, text.length);
85
+ const snippet = text.substring(start, end).split('\n')[0];
86
+ return snippet.trim();
87
+ }
88
+ }
89
+ // Fallback: first line with keywords
90
+ const lines = text.split('\n');
91
+ for (const line of lines) {
92
+ if (extractKeywords(line).length > 0) {
93
+ return line.trim().substring(0, 80);
94
+ }
95
+ }
96
+ return '';
97
+ }
98
+ function parseCollabFile(filePath) {
99
+ const content = readFileSync(filePath, 'utf-8');
100
+ const lines = content.split('\n');
101
+ const intents = [];
102
+ let currentAgent = null;
103
+ let currentTime = null;
104
+ let entryStart = 0;
105
+ let entryLines = [];
106
+ for (let i = 0; i < lines.length; i++) {
107
+ const line = lines[i];
108
+ const agentMatch = parseAgentEntry(line);
109
+ if (agentMatch) {
110
+ // Save previous entry if exists
111
+ if (currentAgent && entryLines.length > 0) {
112
+ const entryText = entryLines.join('\n');
113
+ const intent = extractIntent(entryText);
114
+ const keywords = extractKeywords(entryText);
115
+ const status = extractStatus(entryText);
116
+ // Only record if intent detected
117
+ if (intent || keywords.length > 0) {
118
+ intents.push({
119
+ agent: currentAgent,
120
+ timestamp: currentTime,
121
+ rawEntry: entryText.substring(0, 500),
122
+ intent,
123
+ keywords,
124
+ status,
125
+ file: filePath,
126
+ lineNumber: entryStart
127
+ });
128
+ }
129
+ }
130
+ // Start new entry
131
+ currentAgent = agentMatch.agent;
132
+ currentTime = agentMatch.time;
133
+ entryStart = i + 1;
134
+ entryLines = [];
135
+ }
136
+ else if (currentAgent) {
137
+ entryLines.push(line);
138
+ }
139
+ }
140
+ // Don't forget last entry
141
+ if (currentAgent && entryLines.length > 0) {
142
+ const entryText = entryLines.join('\n');
143
+ const intent = extractIntent(entryText);
144
+ const keywords = extractKeywords(entryText);
145
+ const status = extractStatus(entryText);
146
+ if (intent || keywords.length > 0) {
147
+ intents.push({
148
+ agent: currentAgent,
149
+ timestamp: currentTime,
150
+ rawEntry: entryText.substring(0, 500),
151
+ intent,
152
+ keywords,
153
+ status,
154
+ file: filePath,
155
+ lineNumber: entryStart
156
+ });
157
+ }
158
+ }
159
+ return intents;
160
+ }
161
+ function calculateOverlap(a, b) {
162
+ // Same agent can't conflict with themselves
163
+ if (a.agent === b.agent)
164
+ return null;
165
+ // Completed work doesn't conflict
166
+ if (a.status === 'complete' || b.status === 'complete')
167
+ return null;
168
+ // Find shared keywords
169
+ const sharedKeywords = a.keywords.filter(k => b.keywords.includes(k));
170
+ if (sharedKeywords.length === 0)
171
+ return null;
172
+ // Calculate overlap score
173
+ const totalKeywords = new Set([...a.keywords, ...b.keywords]).size;
174
+ const overlapScore = Math.round((sharedKeywords.length / totalKeywords) * 100);
175
+ // Determine severity
176
+ let severity = 'info';
177
+ if (overlapScore >= 70)
178
+ severity = 'conflict';
179
+ else if (overlapScore >= 40)
180
+ severity = 'warn';
181
+ return {
182
+ intent1: a,
183
+ intent2: b,
184
+ overlapScore,
185
+ sharedKeywords,
186
+ severity
187
+ };
188
+ }
189
+ function findOverlaps(intents) {
190
+ const overlaps = [];
191
+ // Only look at recent intents (last 24 hours worth)
192
+ const recentIntents = intents.filter(i => i.status !== 'complete' &&
193
+ (i.status === 'starting' || i.status === 'implementing' || i.status === 'planning'));
194
+ // Compare all pairs
195
+ for (let i = 0; i < recentIntents.length; i++) {
196
+ for (let j = i + 1; j < recentIntents.length; j++) {
197
+ const overlap = calculateOverlap(recentIntents[i], recentIntents[j]);
198
+ if (overlap) {
199
+ overlaps.push(overlap);
200
+ }
201
+ }
202
+ }
203
+ // Sort by severity and score
204
+ return overlaps.sort((a, b) => {
205
+ if (a.severity === 'conflict' && b.severity !== 'conflict')
206
+ return -1;
207
+ if (b.severity === 'conflict' && a.severity !== 'conflict')
208
+ return 1;
209
+ return b.overlapScore - a.overlapScore;
210
+ });
211
+ }
212
+ function formatOverlap(overlap) {
213
+ const icon = overlap.severity === 'conflict' ? '🔴' :
214
+ overlap.severity === 'warn' ? '🟠' : '🟡';
215
+ const label = overlap.severity === 'conflict' ? 'CONFLICT' :
216
+ overlap.severity === 'warn' ? 'WARNING' : 'INFO';
217
+ return `
218
+ ${icon} ${chalk.bold(label)}: Overlapping intent detected (${overlap.overlapScore}% match)
219
+
220
+ ${chalk.cyan(overlap.intent1.agent)} (${overlap.intent1.timestamp}):
221
+ "${overlap.intent1.intent || overlap.intent1.keywords.join(', ')}"
222
+ Status: ${overlap.intent1.status}
223
+
224
+ ${chalk.cyan(overlap.intent2.agent)} (${overlap.intent2.timestamp}):
225
+ "${overlap.intent2.intent || overlap.intent2.keywords.join(', ')}"
226
+ Status: ${overlap.intent2.status}
227
+
228
+ Shared keywords: ${chalk.yellow(overlap.sharedKeywords.join(', '))}
229
+
230
+ ${chalk.gray('Recommendation: Coordinate before continuing')}
231
+ `;
232
+ }
233
+ export const intentScanCommand = new Command('intent-scan')
234
+ .description('Detect overlapping work intentions in collab entries (Layer 3)')
235
+ .option('--days <n>', 'Number of days to scan', '1')
236
+ .option('--json', 'Output as JSON')
237
+ .option('--verbose', 'Show all detected intents')
238
+ .option('--collab-dir <path>', 'Path to collab directory', process.env.TREEBIRD_INTERNAL
239
+ ? join(process.env.TREEBIRD_INTERNAL, 'collab')
240
+ : join(process.env.HOME || '', 'Dev', 'treebird-internal', 'collab'))
241
+ .addHelpText('after', `
242
+ Examples:
243
+ spidersan intent-scan # Scan today's collab for overlaps
244
+ spidersan intent-scan --days 3 # Scan last 3 days
245
+ spidersan intent-scan --verbose # Show all detected intents
246
+ spidersan intent-scan --json # Output as JSON for tooling
247
+
248
+ Layer 3 of Spidersan's 7-layer conflict detection:
249
+ L1: File-level (git conflicts)
250
+ L2: Semantic (code dependencies)
251
+ L3: Intent (collab entries) ← THIS
252
+ L4: Temporal (active windows)
253
+ L5: Cross-repo (breaking changes)
254
+ L6: Predictive (pattern analysis)
255
+ L7: Resolution (auto-merge)
256
+ `)
257
+ .action((options) => {
258
+ const days = parseInt(options.days) || 1;
259
+ const collabDir = options.collabDir;
260
+ const isJson = options.json;
261
+ if (!existsSync(collabDir)) {
262
+ console.error(chalk.red(`Collab directory not found: ${collabDir}`));
263
+ process.exit(1);
264
+ }
265
+ // Find collab files for the date range
266
+ const files = readdirSync(collabDir)
267
+ .filter(f => f.match(/^\d{4}-\d{2}-\d{2}-daily\.md$/))
268
+ .sort()
269
+ .slice(-days);
270
+ if (files.length === 0) {
271
+ console.log(chalk.yellow('No collab files found'));
272
+ return;
273
+ }
274
+ if (!isJson) {
275
+ console.log(chalk.bold('\n🕷️ INTENT SCAN — Layer 3 Conflict Detection\n'));
276
+ console.log(chalk.gray(`Scanning ${files.length} collab file(s)...\n`));
277
+ }
278
+ // Parse all files
279
+ const allIntents = [];
280
+ for (const file of files) {
281
+ const filePath = join(collabDir, file);
282
+ const intents = parseCollabFile(filePath);
283
+ allIntents.push(...intents);
284
+ }
285
+ // Find overlaps
286
+ const overlaps = findOverlaps(allIntents);
287
+ if (isJson) {
288
+ console.log(JSON.stringify({
289
+ scanned: files,
290
+ intentsFound: allIntents.length,
291
+ overlaps: overlaps,
292
+ summary: {
293
+ conflicts: overlaps.filter(o => o.severity === 'conflict').length,
294
+ warnings: overlaps.filter(o => o.severity === 'warn').length,
295
+ info: overlaps.filter(o => o.severity === 'info').length
296
+ }
297
+ }, null, 2));
298
+ return;
299
+ }
300
+ // Verbose: show all intents
301
+ if (options.verbose) {
302
+ console.log(chalk.bold('📋 Detected Intents:\n'));
303
+ for (const intent of allIntents) {
304
+ const statusIcon = intent.status === 'complete' ? '✅' :
305
+ intent.status === 'implementing' ? '🔨' :
306
+ intent.status === 'starting' ? '🚀' :
307
+ intent.status === 'planning' ? '📝' : '❓';
308
+ console.log(` ${statusIcon} ${chalk.cyan(intent.agent)} (${intent.timestamp})`);
309
+ console.log(` ${intent.intent || intent.keywords.join(', ')}`);
310
+ console.log(` Keywords: ${chalk.gray(intent.keywords.join(', '))}\n`);
311
+ }
312
+ }
313
+ // Show overlaps
314
+ if (overlaps.length === 0) {
315
+ console.log(chalk.green('✅ No overlapping intents detected\n'));
316
+ console.log(chalk.gray(`Scanned ${allIntents.length} intents from ${files.length} file(s)`));
317
+ }
318
+ else {
319
+ const conflicts = overlaps.filter(o => o.severity === 'conflict');
320
+ const warnings = overlaps.filter(o => o.severity === 'warn');
321
+ console.log(chalk.bold(`Found ${overlaps.length} overlap(s):\n`));
322
+ for (const overlap of overlaps) {
323
+ console.log(formatOverlap(overlap));
324
+ }
325
+ // Summary
326
+ console.log(chalk.bold('Summary:'));
327
+ if (conflicts.length > 0) {
328
+ console.log(chalk.red(` 🔴 ${conflicts.length} conflict(s) — coordinate immediately`));
329
+ }
330
+ if (warnings.length > 0) {
331
+ console.log(chalk.yellow(` 🟠 ${warnings.length} warning(s) — check with agents`));
332
+ }
333
+ console.log(chalk.gray(` 📊 ${allIntents.length} intents scanned from ${files.length} file(s)\n`));
334
+ }
335
+ });
336
+ //# sourceMappingURL=intent-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent-scan.js","sourceRoot":"","sources":["../../src/commands/intent-scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const keyImportCommand: Command;
3
+ //# sourceMappingURL=key-import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-import.d.ts","sourceRoot":"","sources":["../../src/commands/key-import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,eAAO,MAAM,gBAAgB,SAmCvB,CAAC"}
@@ -0,0 +1,54 @@
1
+ import { Command } from 'commander';
2
+ import { execSync, spawnSync } from 'child_process';
3
+ // Security: Input validation
4
+ const VALID_AGENT_ID = /^[a-z0-9][a-z0-9_-]{0,30}$/i;
5
+ const VALID_BASE64_KEY = /^[A-Za-z0-9+/=]{20,500}$/;
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
+ function validatePublicKey(key) {
13
+ if (!VALID_BASE64_KEY.test(key)) {
14
+ throw new Error(`Invalid public key format (expected base64)`);
15
+ }
16
+ return key;
17
+ }
18
+ export const keyImportCommand = new Command('key-import')
19
+ .description('Import another agent\'s public key (via Myceliumail)')
20
+ .argument('<agentId>', 'Agent ID to associate with the key')
21
+ .argument('<publicKey>', 'Base64-encoded public key')
22
+ .action(async (agentId, publicKey) => {
23
+ // Security: Validate inputs
24
+ let safeAgentId;
25
+ let safeKey;
26
+ let myAgent;
27
+ try {
28
+ safeAgentId = validateAgentId(agentId);
29
+ safeKey = validatePublicKey(publicKey);
30
+ myAgent = validateAgentId(process.env.SPIDERSAN_AGENT || 'cli-agent');
31
+ }
32
+ catch (error) {
33
+ console.error(`❌ ${error.message}`);
34
+ process.exit(1);
35
+ }
36
+ try {
37
+ execSync('which mycmail', { stdio: 'ignore' });
38
+ }
39
+ catch {
40
+ console.error('❌ Myceliumail not found');
41
+ process.exit(1);
42
+ }
43
+ // Security: Use spawnSync with argument array
44
+ try {
45
+ spawnSync('mycmail', ['key-import', safeAgentId, safeKey], {
46
+ stdio: 'inherit',
47
+ env: { ...process.env, MYCELIUMAIL_AGENT_ID: myAgent }
48
+ });
49
+ }
50
+ catch (error) {
51
+ process.exit(1);
52
+ }
53
+ });
54
+ //# sourceMappingURL=key-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-import.js","sourceRoot":"","sources":["../../src/commands/key-import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEpD,6BAA6B;AAC7B,MAAM,cAAc,GAAG,6BAA6B,CAAC;AACrD,MAAM,gBAAgB,GAAG,0BAA0B,CAAC;AAEpD,SAAS,eAAe,CAAC,OAAe;IACpC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,sBAAsB,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IAClC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC;KACpD,WAAW,CAAC,sDAAsD,CAAC;KACnE,QAAQ,CAAC,WAAW,EAAE,oCAAoC,CAAC;KAC3D,QAAQ,CAAC,aAAa,EAAE,2BAA2B,CAAC;KACpD,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,SAAiB,EAAE,EAAE;IACjD,4BAA4B;IAC5B,IAAI,WAAmB,CAAC;IACxB,IAAI,OAAe,CAAC;IACpB,IAAI,OAAe,CAAC;IAEpB,IAAI,CAAC;QACD,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACvC,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,WAAW,CAAC,CAAC;IAC1E,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,IAAI,CAAC;QACD,QAAQ,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,8CAA8C;IAC9C,IAAI,CAAC;QACD,SAAS,CAAC,SAAS,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE;YACvD,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,oBAAoB,EAAE,OAAO,EAAE;SACzD,CAAC,CAAC;IACP,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const keygenCommand: Command;
3
+ //# sourceMappingURL=keygen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keygen.d.ts","sourceRoot":"","sources":["../../src/commands/keygen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,eAAO,MAAM,aAAa,SA4CpB,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { Command } from 'commander';
2
+ import { execSync, spawnSync } from 'child_process';
3
+ // Security: Input validation
4
+ const VALID_AGENT_ID = /^[a-z0-9][a-z0-9_-]{0,30}$/i;
5
+ function validateAgentId(agentId) {
6
+ if (!VALID_AGENT_ID.test(agentId)) {
7
+ throw new Error(`Invalid agent ID: "${agentId.slice(0, 20)}..."`);
8
+ }
9
+ return agentId;
10
+ }
11
+ export const keygenCommand = new Command('keygen')
12
+ .description('Generate a new keypair for encrypted messaging (via Myceliumail)')
13
+ .option('--agent <id>', 'Agent ID (default: from SPIDERSAN_AGENT env)')
14
+ .option('--force', 'Overwrite existing keypair (if supported by mycmail)')
15
+ .action(async (options) => {
16
+ const rawAgentId = options.agent || process.env.SPIDERSAN_AGENT;
17
+ if (!rawAgentId) {
18
+ console.error('❌ Agent ID required. Set SPIDERSAN_AGENT env or use --agent');
19
+ process.exit(1);
20
+ }
21
+ // Security: Validate agent ID
22
+ let agentId;
23
+ try {
24
+ agentId = validateAgentId(rawAgentId);
25
+ }
26
+ catch (error) {
27
+ console.error(`❌ ${error.message}`);
28
+ process.exit(1);
29
+ }
30
+ try {
31
+ execSync('which mycmail', { stdio: 'ignore' });
32
+ }
33
+ catch {
34
+ console.error('❌ Myceliumail (mycmail) not found.');
35
+ process.exit(1);
36
+ }
37
+ console.log(`🔑 Delegating to Myceliumail for agent: ${agentId}`);
38
+ // Security: Use spawnSync with argument array
39
+ const args = ['keygen'];
40
+ if (options.force) {
41
+ args.push('--force');
42
+ }
43
+ try {
44
+ spawnSync('mycmail', args, {
45
+ stdio: 'inherit',
46
+ env: { ...process.env, MYCELIUMAIL_AGENT_ID: agentId }
47
+ });
48
+ }
49
+ catch (error) {
50
+ process.exit(1);
51
+ }
52
+ });
53
+ //# sourceMappingURL=keygen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keygen.js","sourceRoot":"","sources":["../../src/commands/keygen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEpD,6BAA6B;AAC7B,MAAM,cAAc,GAAG,6BAA6B,CAAC;AAErD,SAAS,eAAe,CAAC,OAAe;IACpC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,sBAAsB,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC7C,WAAW,CAAC,kEAAkE,CAAC;KAC/E,MAAM,CAAC,cAAc,EAAE,8CAA8C,CAAC;KACtE,MAAM,CAAC,SAAS,EAAE,sDAAsD,CAAC;KACzE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAEhE,IAAI,CAAC,UAAU,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;QAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,8BAA8B;IAC9B,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACD,OAAO,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,IAAI,CAAC;QACD,QAAQ,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,2CAA2C,OAAO,EAAE,CAAC,CAAC;IAElE,8CAA8C;IAC9C,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzB,CAAC;IAED,IAAI,CAAC;QACD,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE;YACvB,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,oBAAoB,EAAE,OAAO,EAAE;SACzD,CAAC,CAAC;IACP,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const keysCommand: Command;
3
+ //# sourceMappingURL=keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,eAAO,MAAM,WAAW,SA6ClB,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { Command } from 'commander';
2
+ import { execSync, spawnSync } from 'child_process';
3
+ // Security: Input validation
4
+ const VALID_AGENT_ID = /^[a-z0-9][a-z0-9_-]{0,30}$/i;
5
+ function validateAgentId(agentId) {
6
+ if (!VALID_AGENT_ID.test(agentId)) {
7
+ throw new Error(`Invalid agent ID: "${agentId.slice(0, 20)}..."`);
8
+ }
9
+ return agentId;
10
+ }
11
+ export const keysCommand = new Command('keys')
12
+ .description('List known public keys (via Myceliumail)')
13
+ .option('--json', 'Output as JSON')
14
+ .action(async (options) => {
15
+ const rawAgentId = process.env.SPIDERSAN_AGENT || 'cli-agent';
16
+ // Security: Validate agent ID
17
+ let agentId;
18
+ try {
19
+ agentId = validateAgentId(rawAgentId);
20
+ }
21
+ catch (error) {
22
+ console.error(`❌ ${error.message}`);
23
+ process.exit(1);
24
+ }
25
+ try {
26
+ execSync('which mycmail', { stdio: 'ignore' });
27
+ }
28
+ catch {
29
+ console.error('❌ Myceliumail not found');
30
+ process.exit(1);
31
+ }
32
+ // Security: Use spawnSync with argument array
33
+ try {
34
+ const result = spawnSync('mycmail', ['keys'], {
35
+ encoding: 'utf-8',
36
+ env: { ...process.env, MYCELIUMAIL_AGENT_ID: agentId }
37
+ });
38
+ if (result.error) {
39
+ throw result.error;
40
+ }
41
+ const output = result.stdout || '';
42
+ if (options.json) {
43
+ console.log(JSON.stringify({
44
+ command: 'keys',
45
+ output: output.trim()
46
+ }, null, 2));
47
+ }
48
+ else {
49
+ console.log(output);
50
+ }
51
+ }
52
+ catch (error) {
53
+ process.exit(1);
54
+ }
55
+ });
56
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEpD,6BAA6B;AAC7B,MAAM,cAAc,GAAG,6BAA6B,CAAC;AAErD,SAAS,eAAe,CAAC,OAAe;IACpC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,sBAAsB,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KACzC,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,WAAW,CAAC;IAE9D,8BAA8B;IAC9B,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACD,OAAO,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,IAAI,CAAC;QACD,QAAQ,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,8CAA8C;IAC9C,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE;YAC1C,QAAQ,EAAE,OAAO;YACjB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,oBAAoB,EAAE,OAAO,EAAE;SACzD,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,MAAM,CAAC,KAAK,CAAC;QACvB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;QACnC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;gBACvB,OAAO,EAAE,MAAM;gBACf,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;aACxB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;IACL,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const listCommand: Command;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,WAAW,SAuClB,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { Command } from 'commander';
2
+ import { getStorage } from '../storage/index.js';
3
+ export const listCommand = new Command('list')
4
+ .description('List all registered branches')
5
+ .option('--json', 'Output as JSON')
6
+ .action(async (options) => {
7
+ const storage = await getStorage();
8
+ if (!await storage.isInitialized()) {
9
+ console.error('❌ Spidersan not initialized. Run: spidersan init');
10
+ process.exit(1);
11
+ }
12
+ const branches = await storage.list();
13
+ if (branches.length === 0) {
14
+ console.log('🕷️ No branches registered yet.');
15
+ console.log(' Run: spidersan register --files "src/foo.ts"');
16
+ return;
17
+ }
18
+ if (options.json) {
19
+ console.log(JSON.stringify(branches, null, 2));
20
+ return;
21
+ }
22
+ console.log('🕷️ Registered Branches:\n');
23
+ for (const branch of branches) {
24
+ const status = branch.status === 'active' ? '🔄' :
25
+ branch.status === 'completed' ? '✅' : '❌';
26
+ const ago = getTimeAgo(new Date(branch.registeredAt));
27
+ console.log(` ${status} ${branch.name}`);
28
+ console.log(` └─ ${ago}${branch.agent ? ` | ${branch.agent}` : ''}`);
29
+ if (branch.files.length > 0) {
30
+ console.log(` └─ Files: ${branch.files.slice(0, 3).join(', ')}${branch.files.length > 3 ? ` (+${branch.files.length - 3} more)` : ''}`);
31
+ }
32
+ console.log('');
33
+ }
34
+ });
35
+ function getTimeAgo(date) {
36
+ const seconds = Math.floor((new Date().getTime() - date.getTime()) / 1000);
37
+ if (seconds < 60)
38
+ return 'Just now';
39
+ if (seconds < 3600)
40
+ return `${Math.floor(seconds / 60)} min ago`;
41
+ if (seconds < 86400)
42
+ return `${Math.floor(seconds / 3600)} hours ago`;
43
+ return `${Math.floor(seconds / 86400)} days ago`;
44
+ }
45
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * spidersan lock
3
+ *
4
+ * Claim or release locks on symbols (functions, classes, etc.)
5
+ * Uses CRDT for decentralized coordination, syncs via Hub.
6
+ *
7
+ * Part of Codex 5.2 implementation.
8
+ */
9
+ import { Command } from 'commander';
10
+ export declare const lockCommand: Command;
11
+ //# sourceMappingURL=lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/commands/lock.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+EpC,eAAO,MAAM,WAAW,SA4JlB,CAAC"}