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,92 @@
1
+ const DEFAULT_HUB_URL = process.env.HUB_URL || 'https://hub.treebird.uk';
2
+ function warnHubError(action, error) {
3
+ const message = error instanceof Error ? error.message : String(error);
4
+ console.warn(`⚠️ Hub ${action} failed: ${message}`);
5
+ }
6
+ class FetchHubAdapter {
7
+ url;
8
+ constructor(url) {
9
+ this.url = url;
10
+ }
11
+ async postToChat(payload) {
12
+ try {
13
+ const response = await fetch(`${this.url}/api/chat`, {
14
+ method: 'POST',
15
+ headers: { 'Content-Type': 'application/json' },
16
+ body: JSON.stringify(payload),
17
+ });
18
+ if (!response.ok) {
19
+ console.warn(`⚠️ Hub chat post failed: ${response.status}`);
20
+ }
21
+ }
22
+ catch (error) {
23
+ warnHubError('chat post', error);
24
+ }
25
+ }
26
+ async wakeAgent(agentId, payload) {
27
+ try {
28
+ const response = await fetch(`${this.url}/api/wake/${encodeURIComponent(agentId)}`, {
29
+ method: 'POST',
30
+ headers: { 'Content-Type': 'application/json' },
31
+ body: JSON.stringify(payload),
32
+ });
33
+ if (!response.ok) {
34
+ console.warn(`⚠️ Hub wake failed for ${agentId}: ${response.status}`);
35
+ }
36
+ return response.ok;
37
+ }
38
+ catch (error) {
39
+ warnHubError(`wake for ${agentId}`, error);
40
+ return false;
41
+ }
42
+ }
43
+ }
44
+ export class HubClient {
45
+ adapter;
46
+ url;
47
+ constructor(adapter, url = DEFAULT_HUB_URL) {
48
+ this.adapter = adapter;
49
+ this.url = url;
50
+ }
51
+ async postToChat(payload) {
52
+ try {
53
+ await this.adapter.postToChat(payload);
54
+ }
55
+ catch (error) {
56
+ warnHubError('chat post', error);
57
+ }
58
+ }
59
+ async notifyConflict(branch, conflicts) {
60
+ const actionableConflicts = conflicts.filter((conflict) => conflict.tier >= 2);
61
+ if (actionableConflicts.length === 0)
62
+ return;
63
+ const severity = actionableConflicts.some((conflict) => conflict.tier === 3)
64
+ ? '🔴 TIER 3 BLOCK'
65
+ : '🟠 TIER 2 PAUSE';
66
+ const message = `🕷️⚠️ **Conflict Alert** on \`${branch}\`\n\n${severity}\n\nConflicting files require coordination.`;
67
+ await this.postToChat({
68
+ agent: 'spidersan',
69
+ name: 'Spidersan',
70
+ message,
71
+ glyph: '🕷️',
72
+ });
73
+ }
74
+ async wakeAgent(agentId, reason) {
75
+ try {
76
+ return await this.adapter.wakeAgent(agentId, {
77
+ sender: 'spidersan',
78
+ reason,
79
+ });
80
+ }
81
+ catch (error) {
82
+ warnHubError(`wake for ${agentId}`, error);
83
+ return false;
84
+ }
85
+ }
86
+ }
87
+ export function createHubClient(options = {}) {
88
+ const url = options.url || DEFAULT_HUB_URL;
89
+ const adapter = options.adapter || new FetchHubAdapter(url);
90
+ return new HubClient(adapter, url);
91
+ }
92
+ //# sourceMappingURL=hub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/lib/hub.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { DriftResult, DriftSkipped } from './remote-drift.js';
2
+ export interface PulseRenderOptions {
3
+ branch: string;
4
+ registered: boolean;
5
+ colonySynced?: number;
6
+ colonyOffline?: boolean;
7
+ activeBranches?: number;
8
+ conflicts: Array<{
9
+ tier: number;
10
+ branch: string;
11
+ files: string[];
12
+ agent?: string;
13
+ }>;
14
+ drift?: DriftResult | DriftSkipped | null;
15
+ verbose?: boolean;
16
+ }
17
+ /** Pure. Returns terminal string for spidersan pulse human output. */
18
+ export declare function renderPulseReport(opts: PulseRenderOptions): string;
19
+ //# sourceMappingURL=pulse-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pulse-renderer.d.ts","sourceRoot":"","sources":["../../src/lib/pulse-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEnE,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpF,KAAK,CAAC,EAAE,WAAW,GAAG,YAAY,GAAG,IAAI,CAAC;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAqDlE"}
@@ -0,0 +1,108 @@
1
+ /** Pure. Returns terminal string for spidersan pulse human output. */
2
+ export function renderPulseReport(opts) {
3
+ const lines = [];
4
+ if (!opts.registered) {
5
+ lines.push(`🕷️ Branch "${opts.branch}" is not registered.`);
6
+ lines.push(' Run: spidersan register --files "..."');
7
+ if (opts.colonyOffline === false) {
8
+ lines.push(` Colony: synced ${opts.colonySynced ?? 0} claim(s)`);
9
+ }
10
+ appendDrift(lines, opts.drift);
11
+ return lines.join('\n').trimEnd();
12
+ }
13
+ const colonyStatus = opts.colonyOffline
14
+ ? '⚠ offline'
15
+ : `✅ synced ${opts.colonySynced ?? 0} claim(s)`;
16
+ lines.push(`🕷️ SPIDERSAN PULSE — "${opts.branch}"`);
17
+ lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
18
+ lines.push(`Colony: ${colonyStatus}`);
19
+ lines.push(`Branches: ${opts.activeBranches ?? 1} active`);
20
+ lines.push('');
21
+ if (opts.conflicts.length === 0) {
22
+ lines.push('✅ No conflicts detected. You\'re good to go!');
23
+ }
24
+ else {
25
+ const tierIcons = { 1: '🟡', 2: '🟠', 3: '🔴' };
26
+ const tierLabels = { 1: 'WARN', 2: 'PAUSE', 3: 'BLOCK' };
27
+ for (const conflict of opts.conflicts) {
28
+ const icon = tierIcons[conflict.tier] ?? '🟡';
29
+ const label = tierLabels[conflict.tier] ?? 'WARN';
30
+ const agentTag = conflict.agent ? ` [@${conflict.agent}]` : '';
31
+ lines.push(`${icon} TIER ${conflict.tier} ${label}: ${conflict.branch}${agentTag}`);
32
+ for (const file of conflict.files) {
33
+ lines.push(` • ${file}`);
34
+ }
35
+ lines.push('');
36
+ }
37
+ const tier3 = opts.conflicts.filter((conflict) => conflict.tier === 3).length;
38
+ const tier2 = opts.conflicts.filter((conflict) => conflict.tier === 2).length;
39
+ const tier1 = opts.conflicts.filter((conflict) => conflict.tier === 1).length;
40
+ lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
41
+ lines.push(`📊 Summary: 🔴 ${tier3} BLOCK | 🟠 ${tier2} PAUSE | 🟡 ${tier1} WARN`);
42
+ }
43
+ appendDrift(lines, opts.drift);
44
+ return lines.join('\n').trimEnd();
45
+ }
46
+ function appendDrift(lines, drift) {
47
+ if (!drift) {
48
+ return;
49
+ }
50
+ lines.push('');
51
+ if ('skipped' in drift) {
52
+ lines.push(`⚠ Remote drift check skipped: ${drift.reason}`);
53
+ return;
54
+ }
55
+ lines.push(...renderDriftReportLines(drift));
56
+ }
57
+ function tierIcon(tier) {
58
+ if (tier === 3)
59
+ return '🔴';
60
+ if (tier === 2)
61
+ return '🟠';
62
+ if (tier === 1)
63
+ return '🟡';
64
+ return '⚪';
65
+ }
66
+ function renderDriftReportLines(drift) {
67
+ if (drift.state === 'synced' || drift.remoteAhead === 0) {
68
+ return ['✅ Remote drift: 0 commits ahead. Safe to push.'];
69
+ }
70
+ const tierLabels = { 1: 'TIER 1', 2: 'TIER 2', 3: 'TIER 3' };
71
+ const lines = [
72
+ `🕷️ REMOTE DRIFT — "${drift.branch}"`,
73
+ '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
74
+ `Remote is ${drift.remoteAhead} commit(s) ahead of local.`,
75
+ '',
76
+ 'Drift zone (files touched by remote commits):',
77
+ ];
78
+ for (const entry of drift.driftZone.map((file) => {
79
+ const found = [...drift.registeredInDrift, ...drift.unstagedInDrift].find((item) => item.file === file);
80
+ return found ?? { file, registered: false, tier: null, unstaged: false };
81
+ })) {
82
+ const parts = [];
83
+ if (entry.registered && entry.tier !== null) {
84
+ parts.push(`registered — ${tierIcon(entry.tier)} ${tierLabels[entry.tier]}`);
85
+ }
86
+ if (entry.unstaged) {
87
+ parts.push('unstaged modification ⚠');
88
+ }
89
+ const label = parts.length > 0 ? ` [${parts.join('] [')}]` : ' [not registered, not modified]';
90
+ lines.push(` ${entry.file}${label}`);
91
+ }
92
+ lines.push('');
93
+ if (drift.registeredInDrift.length > 0) {
94
+ lines.push(`⚠ ${drift.registeredInDrift.length} registered file(s) in drift zone. Rebase will conflict.`);
95
+ }
96
+ if (drift.rebaseContinueRisk) {
97
+ lines.push('⚠ File(s) with unstaged modifications — git rebase --continue may block even');
98
+ lines.push(' after resolving conflict markers. Fix: git checkout HEAD -- <file>');
99
+ for (const entry of drift.unstagedInDrift) {
100
+ lines.push(` ${entry.file}`);
101
+ }
102
+ }
103
+ lines.push('');
104
+ lines.push(' git fetch origin');
105
+ lines.push(` git log --oneline ${drift.remote} -3`);
106
+ return lines;
107
+ }
108
+ //# sourceMappingURL=pulse-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pulse-renderer.js","sourceRoot":"","sources":["../../src/lib/pulse-renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface RegisterRenderOptions {
2
+ branchName: string;
3
+ files: string[];
4
+ isUpdate: boolean;
5
+ autoDetected?: boolean;
6
+ autoDetectedFiles?: string[];
7
+ }
8
+ /** Pure. Returns terminal string for spidersan register success output. */
9
+ export declare function renderRegisterResult(opts: RegisterRenderOptions): string;
10
+ //# sourceMappingURL=register-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-renderer.d.ts","sourceRoot":"","sources":["../../src/lib/register-renderer.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM,CAmBxE"}
@@ -0,0 +1,19 @@
1
+ /** Pure. Returns terminal string for spidersan register success output. */
2
+ export function renderRegisterResult(opts) {
3
+ const lines = [];
4
+ const detectedFiles = opts.autoDetectedFiles ?? opts.files;
5
+ if (opts.autoDetected && detectedFiles.length > 0) {
6
+ lines.push(`🕷️ Auto-detected ${detectedFiles.length} changed file(s)`);
7
+ }
8
+ if (opts.isUpdate) {
9
+ lines.push(`🕷️ Updated branch: ${opts.branchName}`);
10
+ }
11
+ else {
12
+ lines.push(`🕷️ Registered branch: ${opts.branchName}`);
13
+ }
14
+ if (opts.files.length > 0) {
15
+ lines.push(` Files: ${opts.files.join(', ')}`);
16
+ }
17
+ return lines.join('\n').trimEnd();
18
+ }
19
+ //# sourceMappingURL=register-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-renderer.js","sourceRoot":"","sources":["../../src/lib/register-renderer.ts"],"names":[],"mappings":"AAQA,2EAA2E;AAC3E,MAAM,UAAU,oBAAoB,CAAC,IAA2B;IAC5D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,KAAK,CAAC;IAE3D,IAAI,IAAI,CAAC,YAAY,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,qBAAqB,aAAa,CAAC,MAAM,kBAAkB,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,uBAAuB,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACJ,KAAK,CAAC,IAAI,CAAC,0BAA0B,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;AACtC,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * remote-drift.ts
3
+ *
4
+ * Detects whether origin/main has advanced past local HEAD and cross-references
5
+ * the drift zone against (a) the registered file list and (b) unstaged tracked
6
+ * files in the working tree.
7
+ *
8
+ * Core primitives (getDriftZone, getUnstagedTrackedFiles, classifyDriftZone)
9
+ * are exported so that watch --fetch-poll can reuse them without importing
10
+ * from the command layer.
11
+ */
12
+ export interface DriftEntry {
13
+ file: string;
14
+ registered: boolean;
15
+ tier: 1 | 2 | 3 | null;
16
+ unstaged: boolean;
17
+ }
18
+ export interface DriftResult {
19
+ branch: string;
20
+ remote: string;
21
+ localAhead: number;
22
+ remoteAhead: number;
23
+ state: 'synced' | 'local_ahead' | 'remote_ahead' | 'diverged';
24
+ driftZone: string[];
25
+ registeredInDrift: DriftEntry[];
26
+ unstagedInDrift: DriftEntry[];
27
+ safeToPush: boolean;
28
+ rebaseContinueRisk: boolean;
29
+ recommendation: 'synced' | 'push_clean' | 'pull_rebase' | 'rebase_clean' | 'rebase_with_conflict_prep';
30
+ }
31
+ export interface DriftSkipped {
32
+ skipped: true;
33
+ reason: string;
34
+ }
35
+ export declare function isOfflineError(error: unknown): boolean;
36
+ /**
37
+ * Returns the union of files touched by commits that origin/<branch> has but
38
+ * local HEAD does not. Requires a prior `git fetch origin`.
39
+ */
40
+ export declare function getDriftZone(remote: string, branch: string): string[];
41
+ /**
42
+ * Returns tracked files that have unstaged modifications (working tree vs index).
43
+ */
44
+ export declare function getUnstagedTrackedFiles(): string[];
45
+ /**
46
+ * Cross-references driftFiles against registeredFiles + unstagedFiles.
47
+ * Returns a DriftEntry for each file in the drift zone.
48
+ */
49
+ export declare function classifyDriftZone(driftFiles: string[], registeredFiles: string[], unstagedFiles: string[], tierOptions?: {
50
+ extraTier3?: RegExp[];
51
+ extraTier2?: RegExp[];
52
+ }): DriftEntry[];
53
+ /**
54
+ * Main entry point. Fetches origin, computes drift, classifies against registry
55
+ * and working tree. Returns DriftSkipped for graceful-degradation cases.
56
+ */
57
+ export declare function computeDriftResult(registeredFiles: string[], options?: {
58
+ remote?: string;
59
+ branch?: string;
60
+ }): Promise<DriftResult | DriftSkipped>;
61
+ //# sourceMappingURL=remote-drift.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-drift.d.ts","sourceRoot":"","sources":["../../src/lib/remote-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,QAAQ,GAAG,aAAa,GAAG,cAAc,GAAG,UAAU,CAAC;IAC9D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,iBAAiB,EAAE,UAAU,EAAE,CAAC;IAChC,eAAe,EAAE,UAAU,EAAE,CAAC;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,QAAQ,GAAG,YAAY,GAAG,aAAa,GAAG,cAAc,GAAG,2BAA2B,CAAC;CAC1G;AAED,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB;AAYD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGtD;AAcD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAgCrE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CAOlD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC7B,UAAU,EAAE,MAAM,EAAE,EACpB,eAAe,EAAE,MAAM,EAAE,EACzB,aAAa,EAAE,MAAM,EAAE,EACvB,WAAW,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAC/D,UAAU,EAAE,CAgBd;AAuBD;;;GAGG;AACH,wBAAsB,kBAAkB,CACpC,eAAe,EAAE,MAAM,EAAE,EACzB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,OAAO,CAAC,WAAW,GAAG,YAAY,CAAC,CAuGrC"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * remote-drift.ts
3
+ *
4
+ * Detects whether origin/main has advanced past local HEAD and cross-references
5
+ * the drift zone against (a) the registered file list and (b) unstaged tracked
6
+ * files in the working tree.
7
+ *
8
+ * Core primitives (getDriftZone, getUnstagedTrackedFiles, classifyDriftZone)
9
+ * are exported so that watch --fetch-poll can reuse them without importing
10
+ * from the command layer.
11
+ */
12
+ import { execFileSync } from 'child_process';
13
+ import * as fs from 'fs';
14
+ import * as path from 'path';
15
+ import { getCurrentBranch, getAheadBehind } from './git.js';
16
+ import { classifyTier } from './conflict-tier.js';
17
+ import { validateBranchName } from './security.js';
18
+ const GIT_TIMEOUT_MS = 15_000;
19
+ function execGit(args) {
20
+ return execFileSync('git', args, {
21
+ encoding: 'utf-8',
22
+ env: { ...process.env },
23
+ timeout: GIT_TIMEOUT_MS,
24
+ });
25
+ }
26
+ export function isOfflineError(error) {
27
+ const msg = String(error instanceof Error ? error.message : error);
28
+ return /ENOTFOUND|ETIMEDOUT|ECONNREFUSED|network|Could not resolve host|unable to connect|cannot access/i.test(msg);
29
+ }
30
+ function isInRebase() {
31
+ try {
32
+ const gitDir = execGit(['rev-parse', '--git-dir']).trim();
33
+ return (fs.existsSync(path.join(gitDir, 'rebase-merge')) ||
34
+ fs.existsSync(path.join(gitDir, 'rebase-apply')));
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ }
40
+ /**
41
+ * Returns the union of files touched by commits that origin/<branch> has but
42
+ * local HEAD does not. Requires a prior `git fetch origin`.
43
+ */
44
+ export function getDriftZone(remote, branch) {
45
+ const safeBranch = validateBranchName(branch);
46
+ const upstreamRef = `${remote}/${safeBranch}`;
47
+ let commitList;
48
+ try {
49
+ commitList = execGit(['rev-list', `HEAD..${upstreamRef}`]).trim();
50
+ }
51
+ catch {
52
+ return [];
53
+ }
54
+ if (!commitList)
55
+ return [];
56
+ const shas = commitList.split('\n').filter(Boolean);
57
+ const files = new Set();
58
+ for (const sha of shas) {
59
+ try {
60
+ const stat = execGit(['show', '--stat', '--format=', sha]);
61
+ for (const line of stat.split('\n')) {
62
+ // Lines like: " src/lib/git.ts | 10 ++--"
63
+ const match = /^\s+(.+?)\s+\|/.exec(line);
64
+ if (match && match[1]) {
65
+ files.add(match[1].trim());
66
+ }
67
+ }
68
+ }
69
+ catch {
70
+ // skip unparseable commit
71
+ }
72
+ }
73
+ return [...files];
74
+ }
75
+ /**
76
+ * Returns tracked files that have unstaged modifications (working tree vs index).
77
+ */
78
+ export function getUnstagedTrackedFiles() {
79
+ try {
80
+ const output = execGit(['diff', '--name-only']).trim();
81
+ return output ? output.split('\n').filter(Boolean) : [];
82
+ }
83
+ catch {
84
+ return [];
85
+ }
86
+ }
87
+ /**
88
+ * Cross-references driftFiles against registeredFiles + unstagedFiles.
89
+ * Returns a DriftEntry for each file in the drift zone.
90
+ */
91
+ export function classifyDriftZone(driftFiles, registeredFiles, unstagedFiles, tierOptions) {
92
+ const registeredSet = new Set(registeredFiles);
93
+ const unstagedSet = new Set(unstagedFiles);
94
+ return driftFiles.map((file) => {
95
+ const registered = registeredSet.has(file);
96
+ const unstaged = unstagedSet.has(file);
97
+ const tier = registered
98
+ ? classifyTier(file, {
99
+ extraTier3: tierOptions?.extraTier3 ?? [],
100
+ extraTier2: tierOptions?.extraTier2 ?? [],
101
+ })
102
+ : null;
103
+ return { file, registered, tier, unstaged };
104
+ });
105
+ }
106
+ function deriveState(localAhead, remoteAhead) {
107
+ if (localAhead === 0 && remoteAhead === 0)
108
+ return 'synced';
109
+ if (localAhead > 0 && remoteAhead === 0)
110
+ return 'local_ahead';
111
+ if (localAhead === 0 && remoteAhead > 0)
112
+ return 'remote_ahead';
113
+ return 'diverged';
114
+ }
115
+ function deriveRecommendation(state, registeredInDrift, unstagedInDrift) {
116
+ if (state === 'synced')
117
+ return 'synced';
118
+ if (state === 'local_ahead')
119
+ return 'push_clean';
120
+ // remote_ahead or diverged
121
+ if (registeredInDrift.length > 0 || unstagedInDrift.length > 0) {
122
+ return 'rebase_with_conflict_prep';
123
+ }
124
+ return state === 'diverged' ? 'rebase_clean' : 'pull_rebase';
125
+ }
126
+ /**
127
+ * Main entry point. Fetches origin, computes drift, classifies against registry
128
+ * and working tree. Returns DriftSkipped for graceful-degradation cases.
129
+ */
130
+ export async function computeDriftResult(registeredFiles, options) {
131
+ const remote = options?.remote ?? 'origin';
132
+ // Detect mid-rebase
133
+ if (isInRebase()) {
134
+ return { skipped: true, reason: 'Rebase in progress — run after completing or aborting rebase' };
135
+ }
136
+ // Determine branch
137
+ let branch;
138
+ try {
139
+ branch = options?.branch ?? getCurrentBranch();
140
+ }
141
+ catch {
142
+ return { skipped: true, reason: 'Not in a git repository' };
143
+ }
144
+ if (branch === 'HEAD') {
145
+ return { skipped: true, reason: 'Detached HEAD — cannot determine branch' };
146
+ }
147
+ // Fetch
148
+ try {
149
+ execGit(['fetch', remote]);
150
+ }
151
+ catch (error) {
152
+ if (isOfflineError(error)) {
153
+ return { skipped: true, reason: '⚠ Remote unreachable — drift check skipped' };
154
+ }
155
+ const msg = error instanceof Error ? error.message : String(error);
156
+ if (/No such remote|remote .* not found/i.test(msg)) {
157
+ return { skipped: true, reason: `No remote '${remote}' found` };
158
+ }
159
+ // Unknown fetch error — still skip gracefully
160
+ return { skipped: true, reason: `Fetch failed: ${msg}` };
161
+ }
162
+ // Check if remote branch exists
163
+ const safeBranch = validateBranchName(branch);
164
+ const upstreamRef = `${remote}/${safeBranch}`;
165
+ try {
166
+ execGit(['rev-parse', '--verify', upstreamRef]);
167
+ }
168
+ catch {
169
+ // Remote branch doesn't exist yet (first push)
170
+ return {
171
+ branch,
172
+ remote: upstreamRef,
173
+ localAhead: 0,
174
+ remoteAhead: 0,
175
+ state: 'synced',
176
+ driftZone: [],
177
+ registeredInDrift: [],
178
+ unstagedInDrift: [],
179
+ safeToPush: true,
180
+ rebaseContinueRisk: false,
181
+ recommendation: 'push_clean',
182
+ };
183
+ }
184
+ // Ahead/behind
185
+ let localAhead;
186
+ let remoteAhead;
187
+ try {
188
+ const ab = getAheadBehind(remote, branch);
189
+ localAhead = ab.ahead;
190
+ remoteAhead = ab.behind; // getAheadBehind returns { ahead: local, behind: remote }
191
+ }
192
+ catch (error) {
193
+ const msg = error instanceof Error ? error.message : String(error);
194
+ if (/not a git repository/i.test(msg)) {
195
+ return { skipped: true, reason: 'Not in a git repository' };
196
+ }
197
+ return { skipped: true, reason: `Could not compute ahead/behind: ${msg}` };
198
+ }
199
+ const state = deriveState(localAhead, remoteAhead);
200
+ // Only compute drift zone when remote has new commits
201
+ let driftZone = [];
202
+ let entries = [];
203
+ if (remoteAhead > 0) {
204
+ driftZone = getDriftZone(remote, branch);
205
+ const unstagedFiles = getUnstagedTrackedFiles();
206
+ entries = classifyDriftZone(driftZone, registeredFiles, unstagedFiles);
207
+ }
208
+ const registeredInDrift = entries.filter(e => e.registered);
209
+ const unstagedInDrift = entries.filter(e => e.unstaged);
210
+ const rebaseContinueRisk = unstagedInDrift.length > 0;
211
+ const safeToPush = remoteAhead === 0;
212
+ const recommendation = deriveRecommendation(state, registeredInDrift, unstagedInDrift);
213
+ return {
214
+ branch,
215
+ remote: upstreamRef,
216
+ localAhead,
217
+ remoteAhead,
218
+ state,
219
+ driftZone,
220
+ registeredInDrift,
221
+ unstagedInDrift,
222
+ safeToPush,
223
+ rebaseContinueRisk,
224
+ recommendation,
225
+ };
226
+ }
227
+ //# sourceMappingURL=remote-drift.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-drift.js","sourceRoot":"","sources":["../../src/lib/remote-drift.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"salvage-analyzer.d.ts","sourceRoot":"","sources":["../../src/lib/salvage-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,SAAS,GACf,OAAO,CAAC,aAAa,CAAC,CAyFxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAmBjE"}
1
+ {"version":3,"file":"salvage-analyzer.d.ts","sourceRoot":"","sources":["../../src/lib/salvage-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,SAAS,GACf,OAAO,CAAC,aAAa,CAAC,CAwFxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAmBjE"}
@@ -5,7 +5,7 @@
5
5
  * not present in main (salvageable code). Wired into `rescue --symbols`.
6
6
  */
7
7
  import { execFileSync } from 'child_process';
8
- import { mkdirSync, writeFileSync, rmSync } from 'fs';
8
+ import { mkdtempSync, writeFileSync, rmSync } from 'fs';
9
9
  import { join } from 'path';
10
10
  import { tmpdir } from 'os';
11
11
  import { extractSymbols } from './symbol-extractor.js';
@@ -38,8 +38,7 @@ export async function analyzeSalvage(branch, mainRef = 'main') {
38
38
  catch {
39
39
  return report;
40
40
  }
41
- const tmpDir = join(tmpdir(), `ssan-salvage-${Date.now()}`);
42
- mkdirSync(tmpDir, { recursive: true });
41
+ const tmpDir = mkdtempSync(join(tmpdir(), 'ssan-salvage-'));
43
42
  try {
44
43
  for (const file of branchFiles) {
45
44
  // Get file content from the abandoned branch
@@ -1 +1 @@
1
- {"version":3,"file":"salvage-analyzer.js","sourceRoot":"","sources":["../../src/lib/salvage-analyzer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"salvage-analyzer.js","sourceRoot":"","sources":["../../src/lib/salvage-analyzer.ts"],"names":[],"mappings":"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"}