spidersan 0.6.0 → 0.10.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.
Files changed (227) hide show
  1. package/CHANGELOG.md +65 -51
  2. package/README.md +238 -3
  3. package/dist/bin/spidersan.d.ts.map +1 -1
  4. package/dist/bin/spidersan.js +13 -1
  5. package/dist/bin/spidersan.js.map +1 -1
  6. package/dist/commands/abandon.d.ts.map +1 -1
  7. package/dist/commands/abandon.js +1 -9
  8. package/dist/commands/abandon.js.map +1 -1
  9. package/dist/commands/ai.d.ts +15 -0
  10. package/dist/commands/ai.d.ts.map +1 -0
  11. package/dist/commands/ai.js +498 -0
  12. package/dist/commands/ai.js.map +1 -0
  13. package/dist/commands/auto.d.ts.map +1 -1
  14. package/dist/commands/auto.js +2 -1
  15. package/dist/commands/auto.js.map +1 -1
  16. package/dist/commands/bot.d.ts +16 -0
  17. package/dist/commands/bot.d.ts.map +1 -0
  18. package/dist/commands/bot.js +416 -0
  19. package/dist/commands/bot.js.map +1 -0
  20. package/dist/commands/conflicts.d.ts.map +1 -1
  21. package/dist/commands/conflicts.js +49 -77
  22. package/dist/commands/conflicts.js.map +1 -1
  23. package/dist/commands/context.d.ts +8 -0
  24. package/dist/commands/context.d.ts.map +1 -0
  25. package/dist/commands/context.js +104 -0
  26. package/dist/commands/context.js.map +1 -0
  27. package/dist/commands/cross-conflicts.d.ts.map +1 -1
  28. package/dist/commands/cross-conflicts.js +10 -44
  29. package/dist/commands/cross-conflicts.js.map +1 -1
  30. package/dist/commands/depends.d.ts.map +1 -1
  31. package/dist/commands/depends.js +1 -9
  32. package/dist/commands/depends.js.map +1 -1
  33. package/dist/commands/fleet-status.d.ts +14 -0
  34. package/dist/commands/fleet-status.d.ts.map +1 -0
  35. package/dist/commands/fleet-status.js +127 -0
  36. package/dist/commands/fleet-status.js.map +1 -0
  37. package/dist/commands/git-watch.d.ts +24 -0
  38. package/dist/commands/git-watch.d.ts.map +1 -0
  39. package/dist/commands/git-watch.js +84 -0
  40. package/dist/commands/git-watch.js.map +1 -0
  41. package/dist/commands/index.d.ts +5 -0
  42. package/dist/commands/index.d.ts.map +1 -1
  43. package/dist/commands/index.js +7 -0
  44. package/dist/commands/index.js.map +1 -1
  45. package/dist/commands/merge-order.d.ts.map +1 -1
  46. package/dist/commands/merge-order.js +18 -67
  47. package/dist/commands/merge-order.js.map +1 -1
  48. package/dist/commands/merged.d.ts.map +1 -1
  49. package/dist/commands/merged.js +1 -9
  50. package/dist/commands/merged.js.map +1 -1
  51. package/dist/commands/pulse.d.ts.map +1 -1
  52. package/dist/commands/pulse.js +82 -82
  53. package/dist/commands/pulse.js.map +1 -1
  54. package/dist/commands/queen.d.ts.map +1 -1
  55. package/dist/commands/queen.js +11 -7
  56. package/dist/commands/queen.js.map +1 -1
  57. package/dist/commands/ready-check.d.ts +2 -1
  58. package/dist/commands/ready-check.d.ts.map +1 -1
  59. package/dist/commands/ready-check.js +6 -30
  60. package/dist/commands/ready-check.js.map +1 -1
  61. package/dist/commands/register.d.ts.map +1 -1
  62. package/dist/commands/register.js +22 -37
  63. package/dist/commands/register.js.map +1 -1
  64. package/dist/commands/torrent.d.ts.map +1 -1
  65. package/dist/commands/torrent.js +29 -18
  66. package/dist/commands/torrent.js.map +1 -1
  67. package/dist/commands/watch.d.ts +6 -0
  68. package/dist/commands/watch.d.ts.map +1 -1
  69. package/dist/commands/watch.js +117 -30
  70. package/dist/commands/watch.js.map +1 -1
  71. package/dist/lib/ai/context-builder.d.ts +16 -0
  72. package/dist/lib/ai/context-builder.d.ts.map +1 -0
  73. package/dist/lib/ai/context-builder.js +216 -0
  74. package/dist/lib/ai/context-builder.js.map +1 -0
  75. package/dist/lib/ai/event-handler.d.ts +21 -0
  76. package/dist/lib/ai/event-handler.d.ts.map +1 -0
  77. package/dist/lib/ai/event-handler.js +98 -0
  78. package/dist/lib/ai/event-handler.js.map +1 -0
  79. package/dist/lib/ai/index.d.ts +13 -0
  80. package/dist/lib/ai/index.d.ts.map +1 -0
  81. package/dist/lib/ai/index.js +11 -0
  82. package/dist/lib/ai/index.js.map +1 -0
  83. package/dist/lib/ai/llm-client.d.ts +37 -0
  84. package/dist/lib/ai/llm-client.d.ts.map +1 -0
  85. package/dist/lib/ai/llm-client.js +225 -0
  86. package/dist/lib/ai/llm-client.js.map +1 -0
  87. package/dist/lib/ai/reasoner.d.ts +11 -0
  88. package/dist/lib/ai/reasoner.d.ts.map +1 -0
  89. package/dist/lib/ai/reasoner.js +246 -0
  90. package/dist/lib/ai/reasoner.js.map +1 -0
  91. package/dist/lib/ai/setup.d.ts +40 -0
  92. package/dist/lib/ai/setup.d.ts.map +1 -0
  93. package/dist/lib/ai/setup.js +154 -0
  94. package/dist/lib/ai/setup.js.map +1 -0
  95. package/dist/lib/ai/types.d.ts +135 -0
  96. package/dist/lib/ai/types.d.ts.map +1 -0
  97. package/dist/lib/ai/types.js +39 -0
  98. package/dist/lib/ai/types.js.map +1 -0
  99. package/dist/lib/colony-subscriber.d.ts +15 -12
  100. package/dist/lib/colony-subscriber.d.ts.map +1 -1
  101. package/dist/lib/colony-subscriber.js +146 -65
  102. package/dist/lib/colony-subscriber.js.map +1 -1
  103. package/dist/lib/config.d.ts.map +1 -1
  104. package/dist/lib/config.js +18 -4
  105. package/dist/lib/config.js.map +1 -1
  106. package/dist/lib/conflict-analyzer.d.ts +33 -0
  107. package/dist/lib/conflict-analyzer.d.ts.map +1 -0
  108. package/dist/lib/conflict-analyzer.js +114 -0
  109. package/dist/lib/conflict-analyzer.js.map +1 -0
  110. package/dist/lib/conflict-renderer.d.ts +7 -0
  111. package/dist/lib/conflict-renderer.d.ts.map +1 -0
  112. package/dist/lib/conflict-renderer.js +162 -0
  113. package/dist/lib/conflict-renderer.js.map +1 -0
  114. package/dist/lib/conflict-tier.d.ts +20 -0
  115. package/dist/lib/conflict-tier.d.ts.map +1 -0
  116. package/dist/lib/conflict-tier.js +49 -0
  117. package/dist/lib/conflict-tier.js.map +1 -0
  118. package/dist/lib/crypto.js +1 -1
  119. package/dist/lib/crypto.js.map +1 -1
  120. package/dist/lib/git-events-subscriber.d.ts +59 -0
  121. package/dist/lib/git-events-subscriber.d.ts.map +1 -0
  122. package/dist/lib/git-events-subscriber.js +779 -0
  123. package/dist/lib/git-events-subscriber.js.map +1 -0
  124. package/dist/lib/git.d.ts +15 -0
  125. package/dist/lib/git.d.ts.map +1 -0
  126. package/dist/lib/git.js +180 -0
  127. package/dist/lib/git.js.map +1 -0
  128. package/dist/lib/github.d.ts.map +1 -1
  129. package/dist/lib/github.js +14 -9
  130. package/dist/lib/github.js.map +1 -1
  131. package/dist/lib/graph.d.ts +23 -0
  132. package/dist/lib/graph.d.ts.map +1 -0
  133. package/dist/lib/graph.js +134 -0
  134. package/dist/lib/graph.js.map +1 -0
  135. package/dist/lib/hub.d.ts +31 -0
  136. package/dist/lib/hub.d.ts.map +1 -0
  137. package/dist/lib/hub.js +92 -0
  138. package/dist/lib/hub.js.map +1 -0
  139. package/dist/lib/pulse-renderer.d.ts +19 -0
  140. package/dist/lib/pulse-renderer.d.ts.map +1 -0
  141. package/dist/lib/pulse-renderer.js +108 -0
  142. package/dist/lib/pulse-renderer.js.map +1 -0
  143. package/dist/lib/register-renderer.d.ts +10 -0
  144. package/dist/lib/register-renderer.d.ts.map +1 -0
  145. package/dist/lib/register-renderer.js +19 -0
  146. package/dist/lib/register-renderer.js.map +1 -0
  147. package/dist/lib/remote-drift.d.ts +61 -0
  148. package/dist/lib/remote-drift.d.ts.map +1 -0
  149. package/dist/lib/remote-drift.js +227 -0
  150. package/dist/lib/remote-drift.js.map +1 -0
  151. package/dist/lib/salvage-analyzer.d.ts.map +1 -1
  152. package/dist/lib/salvage-analyzer.js +2 -3
  153. package/dist/lib/salvage-analyzer.js.map +1 -1
  154. package/dist/lib/security.d.ts +11 -0
  155. package/dist/lib/security.d.ts.map +1 -1
  156. package/dist/lib/security.js +24 -1
  157. package/dist/lib/security.js.map +1 -1
  158. package/dist/lib/session-logger.d.ts +54 -0
  159. package/dist/lib/session-logger.d.ts.map +1 -0
  160. package/dist/lib/session-logger.js +136 -0
  161. package/dist/lib/session-logger.js.map +1 -0
  162. package/dist/lib/watch-renderer.d.ts +13 -0
  163. package/dist/lib/watch-renderer.d.ts.map +1 -0
  164. package/dist/lib/watch-renderer.js +35 -0
  165. package/dist/lib/watch-renderer.js.map +1 -0
  166. package/dist/storage/adapter.d.ts +4 -0
  167. package/dist/storage/adapter.d.ts.map +1 -1
  168. package/dist/storage/branch-registry-store.d.ts +13 -0
  169. package/dist/storage/branch-registry-store.d.ts.map +1 -0
  170. package/dist/storage/branch-registry-store.js +2 -0
  171. package/dist/storage/branch-registry-store.js.map +1 -0
  172. package/dist/storage/factory.d.ts +4 -0
  173. package/dist/storage/factory.d.ts.map +1 -1
  174. package/dist/storage/factory.js +25 -9
  175. package/dist/storage/factory.js.map +1 -1
  176. package/dist/storage/git-messages.d.ts +53 -0
  177. package/dist/storage/git-messages.d.ts.map +1 -0
  178. package/dist/storage/git-messages.js +376 -0
  179. package/dist/storage/git-messages.js.map +1 -0
  180. package/dist/storage/index.d.ts +5 -0
  181. package/dist/storage/index.d.ts.map +1 -1
  182. package/dist/storage/index.js +5 -0
  183. package/dist/storage/index.js.map +1 -1
  184. package/dist/storage/json-branch-registry-store.d.ts +19 -0
  185. package/dist/storage/json-branch-registry-store.d.ts.map +1 -0
  186. package/dist/storage/json-branch-registry-store.js +112 -0
  187. package/dist/storage/json-branch-registry-store.js.map +1 -0
  188. package/dist/storage/local-messages.d.ts +37 -0
  189. package/dist/storage/local-messages.d.ts.map +1 -0
  190. package/dist/storage/local-messages.js +151 -0
  191. package/dist/storage/local-messages.js.map +1 -0
  192. package/dist/storage/local.d.ts +2 -6
  193. package/dist/storage/local.d.ts.map +1 -1
  194. package/dist/storage/local.js +13 -76
  195. package/dist/storage/local.js.map +1 -1
  196. package/dist/storage/memory-branch-registry-store.d.ts +16 -0
  197. package/dist/storage/memory-branch-registry-store.d.ts.map +1 -0
  198. package/dist/storage/memory-branch-registry-store.js +65 -0
  199. package/dist/storage/memory-branch-registry-store.js.map +1 -0
  200. package/dist/storage/message-adapter.d.ts +86 -0
  201. package/dist/storage/message-adapter.d.ts.map +1 -0
  202. package/dist/storage/message-adapter.js +28 -0
  203. package/dist/storage/message-adapter.js.map +1 -0
  204. package/dist/storage/message-factory.d.ts +36 -0
  205. package/dist/storage/message-factory.d.ts.map +1 -0
  206. package/dist/storage/message-factory.js +99 -0
  207. package/dist/storage/message-factory.js.map +1 -0
  208. package/dist/storage/mycmail-adapter.d.ts +38 -0
  209. package/dist/storage/mycmail-adapter.d.ts.map +1 -0
  210. package/dist/storage/mycmail-adapter.js +300 -0
  211. package/dist/storage/mycmail-adapter.js.map +1 -0
  212. package/dist/storage/supabase-registry-sync-client-impl.d.ts +46 -0
  213. package/dist/storage/supabase-registry-sync-client-impl.d.ts.map +1 -0
  214. package/dist/storage/supabase-registry-sync-client-impl.js +322 -0
  215. package/dist/storage/supabase-registry-sync-client-impl.js.map +1 -0
  216. package/dist/storage/supabase-registry-sync-client.d.ts +9 -0
  217. package/dist/storage/supabase-registry-sync-client.d.ts.map +1 -0
  218. package/dist/storage/supabase-registry-sync-client.js +2 -0
  219. package/dist/storage/supabase-registry-sync-client.js.map +1 -0
  220. package/dist/storage/supabase.d.ts +8 -46
  221. package/dist/storage/supabase.d.ts.map +1 -1
  222. package/dist/storage/supabase.js +30 -342
  223. package/dist/storage/supabase.js.map +1 -1
  224. package/dist/tui/screen.d.ts.map +1 -1
  225. package/dist/tui/screen.js +5 -3
  226. package/dist/tui/screen.js.map +1 -1
  227. package/package.json +1 -1
@@ -0,0 +1,416 @@
1
+ /**
2
+ * spidersan bot — Message-driven git operations daemon via smalltoak.
3
+ *
4
+ * Polls smalltoak for /commands, executes git actions, replies with results.
5
+ * Requires envoak vault injection (GIT_BOT_ENABLED=true).
6
+ *
7
+ * Usage:
8
+ * envoak vault inject --key ... -- spidersan bot
9
+ * spidersan bot --once
10
+ * spidersan bot add <name> --path <path> --branch <branch> --push <files>
11
+ * spidersan bot remove <name>
12
+ * spidersan bot repos
13
+ */
14
+ import { Command } from 'commander';
15
+ import { execFileSync } from 'child_process';
16
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
17
+ import { join } from 'path';
18
+ import { homedir } from 'os';
19
+ // ── Config ──────────────────────────────────────────────────────────────────
20
+ const CONFIG_DIR = join(homedir(), '.spidersan');
21
+ const CONFIG_FILE = join(CONFIG_DIR, 'bot.json');
22
+ const HWM_FILE = join(CONFIG_DIR, 'bot_hwm');
23
+ const AGENT_NAME = 'spidersan';
24
+ const SMALLTOAK_URL = (process.env.SMALLTOAK_SERVER_URL || '').replace(/\/+$/, '');
25
+ const SMALLTOAK_TOKEN = process.env.SMALLTOAK_TOKEN || '';
26
+ const POLL_INTERVAL = 15_000;
27
+ const SYNC_INTERVAL = 90_000;
28
+ const RATE_LIMIT = 10_000; // ms per repo
29
+ const VALID_COMMANDS = new Set(['sync', 'pull', 'push', 'status', 'conflicts', 'log']);
30
+ const BRANCH_RE = /^[\w/.-]{1,200}$/;
31
+ // Minimal env for git subprocesses — excludes bot secrets (SMALLTOAK_TOKEN etc.)
32
+ function gitEnv() {
33
+ const env = { GIT_TERMINAL_PROMPT: '0' };
34
+ for (const k of ['HOME', 'PATH', 'GIT_SSH_COMMAND', 'SSH_AUTH_SOCK',
35
+ 'GIT_AUTHOR_NAME', 'GIT_AUTHOR_EMAIL',
36
+ 'GIT_COMMITTER_NAME', 'GIT_COMMITTER_EMAIL']) {
37
+ if (process.env[k] !== undefined)
38
+ env[k] = process.env[k];
39
+ }
40
+ return env;
41
+ }
42
+ // Env for spidersan subprocesses — full env minus bot-specific secrets
43
+ function spidersanEnv() {
44
+ const { SMALLTOAK_TOKEN: _t, SMALLTOAK_SERVER_URL: _u, GIT_BOT_ENABLED: _e, ...rest } = process.env;
45
+ return rest;
46
+ }
47
+ // ── Tiers ───────────────────────────────────────────────────────────────────
48
+ const TIERS = {
49
+ coordinator: {
50
+ agents: ['birdsan', 'bsan', 'treebird', 'trbr'],
51
+ commands: ['sync', 'pull', 'push', 'status', 'conflicts', 'log'],
52
+ },
53
+ specialist: {
54
+ agents: ['spidersan', 'ssan', 'sherlock', 'srlk', 'watsan', 'wsan',
55
+ 'treesan', 'tsan', 'mycsan', 'mycs'],
56
+ commands: ['sync', 'pull', 'push', 'status', 'conflicts', 'log'],
57
+ },
58
+ worker: {
59
+ agents: ['nemosan', 'nemo', 'codex', 'codx', 'goose', 'goos'],
60
+ commands: ['status', 'log'],
61
+ },
62
+ };
63
+ function getTier(sender) {
64
+ for (const [tier, cfg] of Object.entries(TIERS)) {
65
+ if (cfg.agents.includes(sender))
66
+ return tier;
67
+ }
68
+ return null;
69
+ }
70
+ function isAuthorized(sender, command) {
71
+ const tier = getTier(sender);
72
+ if (!tier)
73
+ return false;
74
+ return TIERS[tier].commands.includes(command);
75
+ }
76
+ function loadBotConfig() {
77
+ if (existsSync(CONFIG_FILE)) {
78
+ try {
79
+ return JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));
80
+ }
81
+ catch { /* fall through */ }
82
+ }
83
+ return { repos: {}, pollInterval: 15, syncInterval: 90, rateLimit: 10 };
84
+ }
85
+ function saveBotConfig(cfg) {
86
+ if (!existsSync(CONFIG_DIR))
87
+ mkdirSync(CONFIG_DIR, { recursive: true });
88
+ writeFileSync(CONFIG_FILE, JSON.stringify(cfg, null, 2), 'utf-8');
89
+ }
90
+ // ── Command parser ──────────────────────────────────────────────────────────
91
+ function parseCommand(text, repos) {
92
+ if (!text || !text.startsWith('/'))
93
+ return null;
94
+ const parts = text.trim().split(/\s+/);
95
+ if (parts.length < 2)
96
+ return null;
97
+ const cmd = parts[0].slice(1);
98
+ const repo = parts[1];
99
+ const args = parts.slice(2);
100
+ if (!VALID_COMMANDS.has(cmd))
101
+ return null;
102
+ if (!(repo in repos))
103
+ return null;
104
+ for (const arg of args) {
105
+ if (arg.includes(".."))
106
+ return null;
107
+ if (!BRANCH_RE.test(arg))
108
+ return null;
109
+ }
110
+ return { cmd, repo, args };
111
+ }
112
+ // ── Smalltoak transport ─────────────────────────────────────────────────────
113
+ async function stRead(to, last) {
114
+ if (!SMALLTOAK_URL)
115
+ return [];
116
+ const params = new URLSearchParams();
117
+ if (to)
118
+ params.set('to', to);
119
+ if (last)
120
+ params.set('last', String(last));
121
+ const qs = params.toString() ? `?${params}` : '';
122
+ const headers = {};
123
+ if (SMALLTOAK_TOKEN)
124
+ headers['Authorization'] = `Bearer ${SMALLTOAK_TOKEN}`;
125
+ try {
126
+ const resp = await fetch(`${SMALLTOAK_URL}/messages${qs}`, { headers });
127
+ if (!resp.ok)
128
+ return [];
129
+ return await resp.json();
130
+ }
131
+ catch {
132
+ return [];
133
+ }
134
+ }
135
+ async function stPost(text, to, replyTo) {
136
+ if (!SMALLTOAK_URL)
137
+ return;
138
+ const headers = { 'Content-Type': 'application/json' };
139
+ if (SMALLTOAK_TOKEN)
140
+ headers['Authorization'] = `Bearer ${SMALLTOAK_TOKEN}`;
141
+ try {
142
+ await fetch(`${SMALLTOAK_URL}/messages`, {
143
+ method: 'POST',
144
+ headers,
145
+ body: JSON.stringify({
146
+ text, from: AGENT_NAME, to,
147
+ reply_to: replyTo,
148
+ }),
149
+ });
150
+ }
151
+ catch (e) {
152
+ console.warn('[bot] stPost failed:', e);
153
+ }
154
+ }
155
+ // ── High-water mark ─────────────────────────────────────────────────────────
156
+ function loadHwm() {
157
+ try {
158
+ return parseInt(readFileSync(HWM_FILE, 'utf-8').trim(), 10) || 0;
159
+ }
160
+ catch {
161
+ return 0;
162
+ }
163
+ }
164
+ function saveHwm(id) {
165
+ if (!existsSync(CONFIG_DIR))
166
+ mkdirSync(CONFIG_DIR, { recursive: true });
167
+ writeFileSync(HWM_FILE, String(id), 'utf-8');
168
+ }
169
+ // ── Git executors ───────────────────────────────────────────────────────────
170
+ function executePull(cfg, branch) {
171
+ try {
172
+ const b = branch || cfg.branch;
173
+ const r = execFileSync('git', ['pull', '--ff-only', 'origin', b], { cwd: cfg.path, encoding: 'utf-8', timeout: 60_000, env: gitEnv() });
174
+ return r.trim().substring(0, 500);
175
+ }
176
+ catch (err) {
177
+ return err.message;
178
+ }
179
+ }
180
+ function executePush(cfg) {
181
+ registerFiles(cfg);
182
+ const conflict = checkConflictsBefore(cfg);
183
+ if (conflict)
184
+ return conflict;
185
+ try {
186
+ for (const filePattern of cfg.autoPush) {
187
+ execFileSync('git', ['add', filePattern], { cwd: cfg.path, encoding: 'utf-8', env: gitEnv() });
188
+ }
189
+ try {
190
+ execFileSync('git', ['diff', '--cached', '--quiet'], { cwd: cfg.path, encoding: 'utf-8', env: gitEnv() });
191
+ return 'No changes to push';
192
+ }
193
+ catch { /* has staged changes */ }
194
+ execFileSync('git', ['commit', '-m', 'spidersan bot auto-push'], { cwd: cfg.path, encoding: 'utf-8', env: gitEnv() });
195
+ const r = execFileSync('git', ['push'], { cwd: cfg.path, encoding: 'utf-8', timeout: 60_000, env: gitEnv() });
196
+ return r.trim().substring(0, 500) || 'Pushed';
197
+ }
198
+ catch (err) {
199
+ return err.message;
200
+ }
201
+ }
202
+ function registerFiles(cfg) {
203
+ try {
204
+ execFileSync('spidersan', ['register',
205
+ '--agent', 'spidersan-bot',
206
+ '--files', cfg.autoPush.join(','),
207
+ ], { cwd: cfg.path, encoding: 'utf-8', timeout: 10_000, env: spidersanEnv() });
208
+ }
209
+ catch { /* best effort */ }
210
+ }
211
+ function checkConflictsBefore(cfg) {
212
+ try {
213
+ const result = execFileSync('spidersan', ['conflicts', '--json'], { cwd: cfg.path, encoding: 'utf-8', timeout: 10_000, env: spidersanEnv() });
214
+ const data = JSON.parse(result);
215
+ const blocking = (data.conflicts || []).filter((c) => c.tier >= 2 || c.tier === 'BLOCK' || c.tier === 'PAUSE');
216
+ if (blocking.length > 0) {
217
+ const labels = blocking.map((c) => `${c.tierInfo?.label || 'T' + c.tier}: ${(c.files || [c.branch]).join(', ')}`);
218
+ return `BLOCKED: ${blocking.length} conflict(s) (tier 2+) — ${labels.join('; ')}`;
219
+ }
220
+ }
221
+ catch { /* spidersan not available or no conflicts */ }
222
+ return null;
223
+ }
224
+ function executeSync(cfg) {
225
+ registerFiles(cfg);
226
+ const conflict = checkConflictsBefore(cfg);
227
+ if (conflict)
228
+ return conflict;
229
+ const pull = executePull(cfg);
230
+ const push = executePush(cfg);
231
+ return `Pull: ${pull}\nPush: ${push}`;
232
+ }
233
+ function executeStatus(cfg) {
234
+ try {
235
+ const status = execFileSync('git', ['status', '--porcelain'], { cwd: cfg.path, encoding: 'utf-8', env: gitEnv() });
236
+ const branch = execFileSync('git', ['branch', '--show-current'], { cwd: cfg.path, encoding: 'utf-8', env: gitEnv() });
237
+ return `${status.trim()}\nBranch: ${branch.trim()}`.substring(0, 500);
238
+ }
239
+ catch (err) {
240
+ return err.message;
241
+ }
242
+ }
243
+ function executeLog(cfg, n = 10) {
244
+ try {
245
+ const limitedN = Math.min(n, 50);
246
+ const r = execFileSync('git', ['log', '--oneline', `-${limitedN}`], { cwd: cfg.path, encoding: 'utf-8', env: gitEnv() });
247
+ return r.trim().substring(0, 500);
248
+ }
249
+ catch (err) {
250
+ return err.message;
251
+ }
252
+ }
253
+ function executeConflicts(cfg) {
254
+ try {
255
+ const r = execFileSync('spidersan', ['conflicts'], { cwd: cfg.path, encoding: 'utf-8', timeout: 60_000, env: spidersanEnv() });
256
+ return r.trim().substring(0, 500);
257
+ }
258
+ catch (err) {
259
+ if (err.code === 'ENOENT')
260
+ return 'spidersan command not found';
261
+ return err.message;
262
+ }
263
+ }
264
+ // ── Rate limiter ────────────────────────────────────────────────────────────
265
+ const lastAction = {};
266
+ function rateCheck(repo) {
267
+ const now = Date.now();
268
+ const last = lastAction[repo] || 0;
269
+ if (now - last < RATE_LIMIT)
270
+ return false;
271
+ lastAction[repo] = now;
272
+ return true;
273
+ }
274
+ // ── Command ─────────────────────────────────────────────────────────────────
275
+ export const botCommand = new Command('bot')
276
+ .description('Message-driven git operations daemon via smalltoak')
277
+ .option('--once', 'Single poll+sync cycle then exit')
278
+ .action(async (opts) => {
279
+ if (process.env.GIT_BOT_ENABLED !== 'true') {
280
+ console.error('Error: GIT_BOT_ENABLED not set. Run via: envoak vault inject --key ... -- spidersan bot');
281
+ process.exit(1);
282
+ }
283
+ const config = loadBotConfig();
284
+ if (Object.keys(config.repos).length === 0) {
285
+ console.error('No repos configured. Use: spidersan bot add <name> --path <path> --branch <branch> --push <files>');
286
+ process.exit(1);
287
+ }
288
+ console.log(`[bot] started — ${Object.keys(config.repos).length} repos, poll=${POLL_INTERVAL / 1000}s, sync=${SYNC_INTERVAL / 1000}s`);
289
+ // Register all configured repos/branches with spidersan for conflict detection
290
+ for (const [name, cfg] of Object.entries(config.repos)) {
291
+ try {
292
+ execFileSync('spidersan', ['register',
293
+ '--agent', 'spidersan-bot',
294
+ '--files', cfg.autoPush.join(','),
295
+ '--description', `git-bot auto-sync: ${name} (${cfg.branch})`
296
+ ], { cwd: cfg.path, encoding: 'utf-8', timeout: 10_000, env: spidersanEnv() });
297
+ console.log(`[bot] registered ${name} (${cfg.branch}) — files: ${cfg.autoPush.join(', ')}`);
298
+ }
299
+ catch (err) {
300
+ console.log(`[bot] register ${name} skipped: ${err.message.split('\n')[0]}`);
301
+ }
302
+ }
303
+ const executors = {
304
+ sync: (cfg) => executeSync(cfg),
305
+ pull: (cfg, args) => executePull(cfg, args[0]),
306
+ push: (cfg) => executePush(cfg),
307
+ status: (cfg) => executeStatus(cfg),
308
+ log: (cfg, args) => executeLog(cfg, args[0] ? parseInt(args[0]) : 10),
309
+ conflicts: (cfg) => executeConflicts(cfg),
310
+ };
311
+ async function processMessage(msg) {
312
+ const sender = msg.from || 'unknown';
313
+ const parsed = parseCommand(msg.text || '', config.repos);
314
+ if (!parsed)
315
+ return;
316
+ const { cmd, repo, args } = parsed;
317
+ if (!isAuthorized(sender, cmd)) {
318
+ const tier = getTier(sender) || 'unknown';
319
+ await stPost(`DENIED: /${cmd} requires specialist or coordinator tier. Your tier: ${tier}.`, sender, msg.id);
320
+ return;
321
+ }
322
+ if (!rateCheck(repo)) {
323
+ await stPost(`RATE LIMITED: wait ${RATE_LIMIT / 1000}s between actions on ${repo}.`, sender, msg.id);
324
+ return;
325
+ }
326
+ const ts = new Date().toLocaleTimeString('en-US', { hour12: false });
327
+ console.log(`[${ts}] ${sender} → /${cmd} ${repo} ${args.join(' ')}`.trim());
328
+ try {
329
+ const result = executors[cmd](config.repos[repo], args);
330
+ await stPost(`/${cmd} ${repo}: ${result.substring(0, 500)}`, sender, msg.id);
331
+ }
332
+ catch (err) {
333
+ await stPost(`/${cmd} ${repo}: Error: ${err.message}`, sender, msg.id);
334
+ }
335
+ }
336
+ let hwm = loadHwm();
337
+ let lastSync = 0;
338
+ const cycle = async () => {
339
+ const now = Date.now();
340
+ // Periodic auto-sync
341
+ if (now - lastSync >= SYNC_INTERVAL) {
342
+ for (const [name, cfg] of Object.entries(config.repos)) {
343
+ try {
344
+ const result = executeSync(cfg);
345
+ const ts = new Date().toLocaleTimeString('en-US', { hour12: false });
346
+ console.log(`[${ts}] auto-sync ${name}: ${result.substring(0, 100)}`);
347
+ }
348
+ catch (err) {
349
+ console.log(`[auto-sync] ${name} failed: ${err.message}`);
350
+ }
351
+ }
352
+ lastSync = now;
353
+ }
354
+ // Poll for commands
355
+ try {
356
+ const msgs = await stRead(AGENT_NAME, 50);
357
+ const newMsgs = msgs.filter((m) => (m.id || 0) > hwm).sort((a, b) => a.id - b.id);
358
+ for (const msg of newMsgs) {
359
+ await processMessage(msg);
360
+ hwm = msg.id;
361
+ saveHwm(hwm);
362
+ }
363
+ }
364
+ catch (err) {
365
+ console.log(`[poll] error: ${err.message}`);
366
+ }
367
+ };
368
+ // Run once or loop
369
+ await cycle();
370
+ if (opts.once)
371
+ return;
372
+ setInterval(cycle, POLL_INTERVAL);
373
+ // Keep process alive
374
+ await new Promise(() => { });
375
+ });
376
+ // Sub-commands: add, remove, repos
377
+ botCommand
378
+ .command('add <name>')
379
+ .description('Add a repo to the bot watchlist')
380
+ .requiredOption('--path <path>', 'Absolute path to repo')
381
+ .requiredOption('--branch <branch>', 'Branch to track')
382
+ .option('--push <files>', 'Comma-separated auto-push file patterns')
383
+ .action((name, opts) => {
384
+ const config = loadBotConfig();
385
+ config.repos[name] = {
386
+ path: opts.path,
387
+ branch: opts.branch,
388
+ autoPush: opts.push ? opts.push.split(',') : [],
389
+ };
390
+ saveBotConfig(config);
391
+ console.log(`Added repo: ${name}`);
392
+ });
393
+ botCommand
394
+ .command('remove <name>')
395
+ .description('Remove a repo from the bot watchlist')
396
+ .action((name) => {
397
+ const config = loadBotConfig();
398
+ delete config.repos[name];
399
+ saveBotConfig(config);
400
+ console.log(`Removed repo: ${name}`);
401
+ });
402
+ botCommand
403
+ .command('repos')
404
+ .description('List configured repos')
405
+ .action(() => {
406
+ const config = loadBotConfig();
407
+ const repos = Object.entries(config.repos);
408
+ if (repos.length === 0) {
409
+ console.log('No repos configured.');
410
+ return;
411
+ }
412
+ for (const [name, cfg] of repos) {
413
+ console.log(` ${name}: ${cfg.path} (${cfg.branch}) push=[${cfg.autoPush.join(', ')}]`);
414
+ }
415
+ });
416
+ //# sourceMappingURL=bot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bot.js","sourceRoot":"","sources":["../../src/commands/bot.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"conflicts.d.ts","sourceRoot":"","sources":["../../src/commands/conflicts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqWpC,eAAO,MAAM,gBAAgB,SAgUvB,CAAC"}
1
+ {"version":3,"file":"conflicts.d.ts","sourceRoot":"","sources":["../../src/commands/conflicts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiSpC,eAAO,MAAM,gBAAgB,SAuVvB,CAAC"}
@@ -19,67 +19,9 @@ import { isExcludedPath } from './register.js';
19
19
  import { loadConfig } from '../lib/config.js';
20
20
  import { logActivity } from '../lib/activity.js';
21
21
  import { isGhAvailable, getPRDetails } from '../lib/github.js';
22
+ import { classifyWithLabel } from '../lib/conflict-tier.js';
22
23
  // Config
23
24
  const HUB_URL = process.env.HUB_URL || 'https://hub.treebird.uk';
24
- // Critical files that trigger TIER 3 blocking
25
- const TIER_3_PATTERNS = [
26
- /\.env$/,
27
- /secrets?\./i,
28
- /credentials/i,
29
- /password/i,
30
- /api[_-]?key/i,
31
- /private[_-]?key/i,
32
- /\.pem$/,
33
- /auth\.(ts|js)$/,
34
- /security\.(ts|js)$/,
35
- ];
36
- // Important files that trigger TIER 2 pause
37
- const TIER_2_PATTERNS = [
38
- /package\.json$/,
39
- /package-lock\.json$/,
40
- /tsconfig\.json$/,
41
- /CLAUDE\.md$/,
42
- /\.gitignore$/,
43
- /server\.(ts|js)$/,
44
- /index\.(ts|js)$/,
45
- /config\.(ts|js)$/,
46
- ];
47
- // Optimization: Pre-compile static patterns
48
- const COMPILED_TIER_3 = compilePatterns(TIER_3_PATTERNS);
49
- const COMPILED_TIER_2 = compilePatterns(TIER_2_PATTERNS);
50
- function getConflictTier(file, compiledHigh = [], compiledMedium = []) {
51
- // Check TIER 3 first (most critical)
52
- const tier3 = [...COMPILED_TIER_3, ...compiledHigh];
53
- for (const pattern of tier3) {
54
- if (pattern.test(file)) {
55
- return {
56
- tier: 3,
57
- label: 'BLOCK',
58
- icon: 'šŸ”“',
59
- action: 'Merge blocked. Resolve conflict first.'
60
- };
61
- }
62
- }
63
- // Check TIER 2
64
- const tier2 = [...COMPILED_TIER_2, ...compiledMedium];
65
- for (const pattern of tier2) {
66
- if (pattern.test(file)) {
67
- return {
68
- tier: 2,
69
- label: 'PAUSE',
70
- icon: '🟠',
71
- action: 'Coordinate with other agent before proceeding.'
72
- };
73
- }
74
- }
75
- // Default: TIER 1
76
- return {
77
- tier: 1,
78
- label: 'WARN',
79
- icon: '🟔',
80
- action: 'Consider coordinating, but safe to proceed.'
81
- };
82
- }
83
25
  function getCurrentBranch() {
84
26
  try {
85
27
  return execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { encoding: 'utf-8' }).trim();
@@ -89,11 +31,19 @@ function getCurrentBranch() {
89
31
  }
90
32
  }
91
33
  async function notifyHub(branch, conflicts) {
92
- const tier3 = conflicts.filter(c => c.tier === 3);
93
- const tier2 = conflicts.filter(c => c.tier === 2);
94
- if (tier3.length === 0 && tier2.length === 0)
34
+ let hasTier3 = false;
35
+ let hasTier2 = false;
36
+ for (const c of conflicts) {
37
+ if (c.tier === 3)
38
+ hasTier3 = true;
39
+ else if (c.tier === 2)
40
+ hasTier2 = true;
41
+ if (hasTier3 && hasTier2)
42
+ break;
43
+ }
44
+ if (!hasTier3 && !hasTier2)
95
45
  return;
96
- const severity = tier3.length > 0 ? 'šŸ”“ TIER 3 BLOCK' : '🟠 TIER 2 PAUSE';
46
+ const severity = hasTier3 ? 'šŸ”“ TIER 3 BLOCK' : '🟠 TIER 2 PAUSE';
97
47
  const message = `šŸ•·ļøāš ļø **Conflict Alert** on \`${branch}\`\n\n${severity}\n\nConflicting files require coordination.`;
98
48
  try {
99
49
  await fetch(`${HUB_URL}/api/chat`, {
@@ -114,9 +64,7 @@ async function notifyHub(branch, conflicts) {
114
64
  /**
115
65
  * Wake a conflicting agent and send them a message about what to fix
116
66
  */
117
- async function wakeConflictingAgent(agentId, myBranch, theirBranch, conflictingFiles) {
118
- const fileList = conflictingFiles.slice(0, 5).join(', ');
119
- const more = conflictingFiles.length > 5 ? ` (+${conflictingFiles.length - 5} more)` : '';
67
+ async function wakeConflictingAgent(agentId, myBranch, theirBranch, _conflictingFiles) {
120
68
  // 1. Wake the agent via Hub
121
69
  try {
122
70
  const wakeResponse = await fetch(`${HUB_URL}/api/wake/${agentId}`, {
@@ -389,12 +337,23 @@ export const conflictsCommand = new Command('conflicts')
389
337
  for (const branch of allBranches) {
390
338
  if (branch.name === targetBranch || branch.status !== 'active')
391
339
  continue;
392
- const overlappingFiles = branch.files.filter(f => !isExcludedPath(f) && targetFilesSet.has(f));
340
+ // Performance Optimization: Replace .filter() with a standard loop to avoid array allocation.
341
+ // Short-circuit using O(1) Set lookup (targetFilesSet.has) before calling the expensive isExcludedPath.
342
+ const overlappingFiles = [];
343
+ for (let i = 0; i < branch.files.length; i++) {
344
+ const f = branch.files[i];
345
+ if (targetFilesSet.has(f) && !isExcludedPath(f)) {
346
+ overlappingFiles.push(f);
347
+ }
348
+ }
393
349
  if (overlappingFiles.length > 0) {
394
350
  // Get highest tier for this conflict
395
351
  let maxTier = { tier: 1, label: 'WARN', icon: '🟔', action: '' };
396
352
  for (const file of overlappingFiles) {
397
- const fileTier = getConflictTier(file, compiledHigh, compiledMedium);
353
+ const fileTier = classifyWithLabel(file, {
354
+ extraTier3: compiledHigh,
355
+ extraTier2: compiledMedium,
356
+ });
398
357
  if (fileTier.tier > maxTier.tier) {
399
358
  maxTier = fileTier;
400
359
  }
@@ -435,22 +394,31 @@ export const conflictsCommand = new Command('conflicts')
435
394
  }
436
395
  // Sort by tier (highest first)
437
396
  conflicts.sort((a, b) => b.tier - a.tier);
397
+ let tier3Count = 0;
398
+ let tier2Count = 0;
399
+ let tier1Count = 0;
400
+ for (const c of conflicts) {
401
+ if (c.tier === 3)
402
+ tier3Count++;
403
+ else if (c.tier === 2)
404
+ tier2Count++;
405
+ else if (c.tier === 1)
406
+ tier1Count++;
407
+ }
438
408
  // Log conflict detection to activity log
439
409
  if (conflicts.length > 0) {
440
410
  logActivity({
441
411
  event: 'conflict_detected',
442
412
  branch: targetBranch,
443
413
  details: {
444
- tier3: conflicts.filter(c => c.tier === 3).length,
445
- tier2: conflicts.filter(c => c.tier === 2).length,
446
- tier1: conflicts.filter(c => c.tier === 1).length,
414
+ tier3: tier3Count,
415
+ tier2: tier2Count,
416
+ tier1: tier1Count,
447
417
  conflicting_branches: conflicts.map(c => c.branch),
448
418
  }
449
419
  });
450
420
  }
451
421
  // Check for blocking conditions
452
- const tier3Count = conflicts.filter(c => c.tier === 3).length;
453
- const tier2Count = conflicts.filter(c => c.tier === 2).length;
454
422
  const shouldBlock = options.strict && (tier3Count > 0 || tier2Count > 0);
455
423
  // Notify Hub if requested
456
424
  if (options.notify && (tier3Count > 0 || tier2Count > 0)) {
@@ -463,7 +431,7 @@ export const conflictsCommand = new Command('conflicts')
463
431
  summary: {
464
432
  tier3: tier3Count,
465
433
  tier2: tier2Count,
466
- tier1: conflicts.filter(c => c.tier === 1).length,
434
+ tier1: tier1Count,
467
435
  blocked: shouldBlock
468
436
  }
469
437
  }, null, 2));
@@ -483,14 +451,17 @@ export const conflictsCommand = new Command('conflicts')
483
451
  for (const conflict of conflicts) {
484
452
  console.log(`${conflict.tierInfo.icon} TIER ${conflict.tier} (${conflict.tierInfo.label}): ${conflict.branch}`);
485
453
  for (const file of conflict.files) {
486
- const fileTier = getConflictTier(file, compiledHigh, compiledMedium);
454
+ const fileTier = classifyWithLabel(file, {
455
+ extraTier3: compiledHigh,
456
+ extraTier2: compiledMedium,
457
+ });
487
458
  console.log(` ${fileTier.icon} ${file}`);
488
459
  }
489
460
  console.log(` → ${conflict.tierInfo.action}`);
490
461
  console.log('');
491
462
  }
492
463
  console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
493
- console.log(`šŸ“Š Summary: šŸ”“ ${tier3Count} BLOCK | 🟠 ${tier2Count} PAUSE | 🟔 ${conflicts.filter(c => c.tier === 1).length} WARN`);
464
+ console.log(`šŸ“Š Summary: šŸ”“ ${tier3Count} BLOCK | 🟠 ${tier2Count} PAUSE | 🟔 ${tier1Count} WARN`);
494
465
  // Offer add/add resolution suggestions for likely add/add files
495
466
  suggestAddAddResolution(conflicts);
496
467
  // Show semantic analysis results
@@ -567,10 +538,11 @@ export const conflictsCommand = new Command('conflicts')
567
538
  console.log('\nšŸ”„ RE-CHECKING CONFLICTS...\n');
568
539
  const { execFileSync } = await import('child_process');
569
540
  try {
541
+ const { getCLIPath } = await import('../lib/security.js');
570
542
  // Security: Use execFileSync with argument array
571
543
  const safeBranch = validateBranchName(targetBranch);
572
544
  const tierArg = String(parseInt(options.tier, 10) || 1);
573
- execFileSync('node', [process.argv[1], 'conflicts', '--branch', safeBranch, '--tier', tierArg], {
545
+ execFileSync(process.execPath, [getCLIPath(), 'conflicts', '--branch', safeBranch, '--tier', tierArg], {
574
546
  encoding: 'utf-8',
575
547
  stdio: 'inherit'
576
548
  });