spidersan 0.20.1 → 0.20.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 (310) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/bin/command-registry.d.ts +25 -0
  3. package/dist/bin/command-registry.d.ts.map +1 -0
  4. package/dist/bin/command-registry.js +29 -0
  5. package/dist/bin/command-registry.js.map +1 -0
  6. package/dist/bin/spidersan.d.ts +16 -0
  7. package/dist/bin/spidersan.d.ts.map +1 -0
  8. package/dist/bin/spidersan.js +98 -0
  9. package/dist/bin/spidersan.js.map +1 -0
  10. package/dist/commands/abandon.d.ts +8 -0
  11. package/dist/commands/abandon.d.ts.map +1 -0
  12. package/dist/commands/abandon.js +43 -0
  13. package/dist/commands/abandon.js.map +1 -0
  14. package/dist/commands/cleanup.d.ts +8 -0
  15. package/dist/commands/cleanup.d.ts.map +1 -0
  16. package/dist/commands/cleanup.js +50 -0
  17. package/dist/commands/cleanup.js.map +1 -0
  18. package/dist/commands/config.d.ts +15 -0
  19. package/dist/commands/config.d.ts.map +1 -0
  20. package/dist/commands/config.js +309 -0
  21. package/dist/commands/config.js.map +1 -0
  22. package/dist/commands/conflicts.d.ts +34 -0
  23. package/dist/commands/conflicts.d.ts.map +1 -0
  24. package/dist/commands/conflicts.js +773 -0
  25. package/dist/commands/conflicts.js.map +1 -0
  26. package/dist/commands/context.d.ts +8 -0
  27. package/dist/commands/context.d.ts.map +1 -0
  28. package/dist/commands/context.js +104 -0
  29. package/dist/commands/context.js.map +1 -0
  30. package/dist/commands/cross-conflicts.d.ts +17 -0
  31. package/dist/commands/cross-conflicts.d.ts.map +1 -0
  32. package/dist/commands/cross-conflicts.js +273 -0
  33. package/dist/commands/cross-conflicts.js.map +1 -0
  34. package/dist/commands/depends.d.ts +11 -0
  35. package/dist/commands/depends.d.ts.map +1 -0
  36. package/dist/commands/depends.js +63 -0
  37. package/dist/commands/depends.js.map +1 -0
  38. package/dist/commands/doctor.d.ts +30 -0
  39. package/dist/commands/doctor.d.ts.map +1 -0
  40. package/dist/commands/doctor.js +558 -0
  41. package/dist/commands/doctor.js.map +1 -0
  42. package/dist/commands/git-watch.d.ts +24 -0
  43. package/dist/commands/git-watch.d.ts.map +1 -0
  44. package/dist/commands/git-watch.js +84 -0
  45. package/dist/commands/git-watch.js.map +1 -0
  46. package/dist/commands/github-sync.d.ts +42 -0
  47. package/dist/commands/github-sync.d.ts.map +1 -0
  48. package/dist/commands/github-sync.js +191 -0
  49. package/dist/commands/github-sync.js.map +1 -0
  50. package/dist/commands/index.d.ts +25 -0
  51. package/dist/commands/index.d.ts.map +1 -0
  52. package/dist/commands/index.js +29 -0
  53. package/dist/commands/index.js.map +1 -0
  54. package/dist/commands/init.d.ts +8 -0
  55. package/dist/commands/init.d.ts.map +1 -0
  56. package/dist/commands/init.js +23 -0
  57. package/dist/commands/init.js.map +1 -0
  58. package/dist/commands/list.d.ts +3 -0
  59. package/dist/commands/list.d.ts.map +1 -0
  60. package/dist/commands/list.js +45 -0
  61. package/dist/commands/list.js.map +1 -0
  62. package/dist/commands/log.d.ts +7 -0
  63. package/dist/commands/log.d.ts.map +1 -0
  64. package/dist/commands/log.js +110 -0
  65. package/dist/commands/log.js.map +1 -0
  66. package/dist/commands/merge-order.d.ts +9 -0
  67. package/dist/commands/merge-order.d.ts.map +1 -0
  68. package/dist/commands/merge-order.js +100 -0
  69. package/dist/commands/merge-order.js.map +1 -0
  70. package/dist/commands/merged.d.ts +8 -0
  71. package/dist/commands/merged.d.ts.map +1 -0
  72. package/dist/commands/merged.js +37 -0
  73. package/dist/commands/merged.js.map +1 -0
  74. package/dist/commands/pr-check.d.ts +24 -0
  75. package/dist/commands/pr-check.d.ts.map +1 -0
  76. package/dist/commands/pr-check.js +85 -0
  77. package/dist/commands/pr-check.js.map +1 -0
  78. package/dist/commands/ready-check.d.ts +11 -0
  79. package/dist/commands/ready-check.d.ts.map +1 -0
  80. package/dist/commands/ready-check.js +150 -0
  81. package/dist/commands/ready-check.js.map +1 -0
  82. package/dist/commands/rebase-helper.d.ts +3 -0
  83. package/dist/commands/rebase-helper.d.ts.map +1 -0
  84. package/dist/commands/rebase-helper.js +52 -0
  85. package/dist/commands/rebase-helper.js.map +1 -0
  86. package/dist/commands/register.d.ts +10 -0
  87. package/dist/commands/register.d.ts.map +1 -0
  88. package/dist/commands/register.js +176 -0
  89. package/dist/commands/register.js.map +1 -0
  90. package/dist/commands/registry-sync.d.ts +9 -0
  91. package/dist/commands/registry-sync.d.ts.map +1 -0
  92. package/dist/commands/registry-sync.js +129 -0
  93. package/dist/commands/registry-sync.js.map +1 -0
  94. package/dist/commands/stale.d.ts +17 -0
  95. package/dist/commands/stale.d.ts.map +1 -0
  96. package/dist/commands/stale.js +136 -0
  97. package/dist/commands/stale.js.map +1 -0
  98. package/dist/commands/sync.d.ts +21 -0
  99. package/dist/commands/sync.d.ts.map +1 -0
  100. package/dist/commands/sync.js +78 -0
  101. package/dist/commands/sync.js.map +1 -0
  102. package/dist/commands/verify-trunk.d.ts +18 -0
  103. package/dist/commands/verify-trunk.d.ts.map +1 -0
  104. package/dist/commands/verify-trunk.js +77 -0
  105. package/dist/commands/verify-trunk.js.map +1 -0
  106. package/dist/commands/watch.d.ts +8 -0
  107. package/dist/commands/watch.d.ts.map +1 -0
  108. package/dist/commands/watch.js +509 -0
  109. package/dist/commands/watch.js.map +1 -0
  110. package/dist/index.d.ts +8 -0
  111. package/dist/index.d.ts.map +1 -0
  112. package/dist/index.js +8 -0
  113. package/dist/index.js.map +1 -0
  114. package/dist/lib/activity.d.ts +53 -0
  115. package/dist/lib/activity.d.ts.map +1 -0
  116. package/dist/lib/activity.js +271 -0
  117. package/dist/lib/activity.js.map +1 -0
  118. package/dist/lib/agent-errors.d.ts +41 -0
  119. package/dist/lib/agent-errors.d.ts.map +1 -0
  120. package/dist/lib/agent-errors.js +145 -0
  121. package/dist/lib/agent-errors.js.map +1 -0
  122. package/dist/lib/ai/context-builder.d.ts +16 -0
  123. package/dist/lib/ai/context-builder.d.ts.map +1 -0
  124. package/dist/lib/ai/context-builder.js +229 -0
  125. package/dist/lib/ai/context-builder.js.map +1 -0
  126. package/dist/lib/ai/event-handler.d.ts +21 -0
  127. package/dist/lib/ai/event-handler.d.ts.map +1 -0
  128. package/dist/lib/ai/event-handler.js +111 -0
  129. package/dist/lib/ai/event-handler.js.map +1 -0
  130. package/dist/lib/ai/index.d.ts +13 -0
  131. package/dist/lib/ai/index.d.ts.map +1 -0
  132. package/dist/lib/ai/index.js +11 -0
  133. package/dist/lib/ai/index.js.map +1 -0
  134. package/dist/lib/ai/llm-client.d.ts +37 -0
  135. package/dist/lib/ai/llm-client.d.ts.map +1 -0
  136. package/dist/lib/ai/llm-client.js +225 -0
  137. package/dist/lib/ai/llm-client.js.map +1 -0
  138. package/dist/lib/ai/reasoner.d.ts +11 -0
  139. package/dist/lib/ai/reasoner.d.ts.map +1 -0
  140. package/dist/lib/ai/reasoner.js +227 -0
  141. package/dist/lib/ai/reasoner.js.map +1 -0
  142. package/dist/lib/ai/setup.d.ts +40 -0
  143. package/dist/lib/ai/setup.d.ts.map +1 -0
  144. package/dist/lib/ai/setup.js +154 -0
  145. package/dist/lib/ai/setup.js.map +1 -0
  146. package/dist/lib/ai/types.d.ts +135 -0
  147. package/dist/lib/ai/types.d.ts.map +1 -0
  148. package/dist/lib/ai/types.js +42 -0
  149. package/dist/lib/ai/types.js.map +1 -0
  150. package/dist/lib/ast.d.ts +44 -0
  151. package/dist/lib/ast.d.ts.map +1 -0
  152. package/dist/lib/ast.js +160 -0
  153. package/dist/lib/ast.js.map +1 -0
  154. package/dist/lib/carries.d.ts +22 -0
  155. package/dist/lib/carries.d.ts.map +1 -0
  156. package/dist/lib/carries.js +56 -0
  157. package/dist/lib/carries.js.map +1 -0
  158. package/dist/lib/colony-subscriber.d.ts +56 -0
  159. package/dist/lib/colony-subscriber.d.ts.map +1 -0
  160. package/dist/lib/colony-subscriber.js +265 -0
  161. package/dist/lib/colony-subscriber.js.map +1 -0
  162. package/dist/lib/config.d.ts +62 -0
  163. package/dist/lib/config.d.ts.map +1 -0
  164. package/dist/lib/config.js +235 -0
  165. package/dist/lib/config.js.map +1 -0
  166. package/dist/lib/conflict-analyzer.d.ts +33 -0
  167. package/dist/lib/conflict-analyzer.d.ts.map +1 -0
  168. package/dist/lib/conflict-analyzer.js +114 -0
  169. package/dist/lib/conflict-analyzer.js.map +1 -0
  170. package/dist/lib/conflict-renderer.d.ts +7 -0
  171. package/dist/lib/conflict-renderer.d.ts.map +1 -0
  172. package/dist/lib/conflict-renderer.js +145 -0
  173. package/dist/lib/conflict-renderer.js.map +1 -0
  174. package/dist/lib/conflict-tier.d.ts +20 -0
  175. package/dist/lib/conflict-tier.d.ts.map +1 -0
  176. package/dist/lib/conflict-tier.js +49 -0
  177. package/dist/lib/conflict-tier.js.map +1 -0
  178. package/dist/lib/crypto.d.ts +71 -0
  179. package/dist/lib/crypto.d.ts.map +1 -0
  180. package/dist/lib/crypto.js +176 -0
  181. package/dist/lib/crypto.js.map +1 -0
  182. package/dist/lib/ecosystem-env.d.ts +33 -0
  183. package/dist/lib/ecosystem-env.d.ts.map +1 -0
  184. package/dist/lib/ecosystem-env.js +62 -0
  185. package/dist/lib/ecosystem-env.js.map +1 -0
  186. package/dist/lib/errors.d.ts +35 -0
  187. package/dist/lib/errors.d.ts.map +1 -0
  188. package/dist/lib/errors.js +71 -0
  189. package/dist/lib/errors.js.map +1 -0
  190. package/dist/lib/git-events-subscriber.d.ts +86 -0
  191. package/dist/lib/git-events-subscriber.d.ts.map +1 -0
  192. package/dist/lib/git-events-subscriber.js +870 -0
  193. package/dist/lib/git-events-subscriber.js.map +1 -0
  194. package/dist/lib/git-merge-analyzer.d.ts +38 -0
  195. package/dist/lib/git-merge-analyzer.d.ts.map +1 -0
  196. package/dist/lib/git-merge-analyzer.js +23 -0
  197. package/dist/lib/git-merge-analyzer.js.map +1 -0
  198. package/dist/lib/git.d.ts +103 -0
  199. package/dist/lib/git.d.ts.map +1 -0
  200. package/dist/lib/git.js +670 -0
  201. package/dist/lib/git.js.map +1 -0
  202. package/dist/lib/github.d.ts +151 -0
  203. package/dist/lib/github.d.ts.map +1 -0
  204. package/dist/lib/github.js +425 -0
  205. package/dist/lib/github.js.map +1 -0
  206. package/dist/lib/graph.d.ts +38 -0
  207. package/dist/lib/graph.d.ts.map +1 -0
  208. package/dist/lib/graph.js +165 -0
  209. package/dist/lib/graph.js.map +1 -0
  210. package/dist/lib/machine.d.ts +14 -0
  211. package/dist/lib/machine.d.ts.map +1 -0
  212. package/dist/lib/machine.js +38 -0
  213. package/dist/lib/machine.js.map +1 -0
  214. package/dist/lib/notify.d.ts +68 -0
  215. package/dist/lib/notify.d.ts.map +1 -0
  216. package/dist/lib/notify.js +111 -0
  217. package/dist/lib/notify.js.map +1 -0
  218. package/dist/lib/outline.d.ts +6 -0
  219. package/dist/lib/outline.d.ts.map +1 -0
  220. package/dist/lib/outline.js +60 -0
  221. package/dist/lib/outline.js.map +1 -0
  222. package/dist/lib/push-registry.d.ts +22 -0
  223. package/dist/lib/push-registry.d.ts.map +1 -0
  224. package/dist/lib/push-registry.js +21 -0
  225. package/dist/lib/push-registry.js.map +1 -0
  226. package/dist/lib/reconcile.d.ts +100 -0
  227. package/dist/lib/reconcile.d.ts.map +1 -0
  228. package/dist/lib/reconcile.js +121 -0
  229. package/dist/lib/reconcile.js.map +1 -0
  230. package/dist/lib/regex-utils.d.ts +6 -0
  231. package/dist/lib/regex-utils.d.ts.map +1 -0
  232. package/dist/lib/regex-utils.js +24 -0
  233. package/dist/lib/regex-utils.js.map +1 -0
  234. package/dist/lib/register-renderer.d.ts +10 -0
  235. package/dist/lib/register-renderer.d.ts.map +1 -0
  236. package/dist/lib/register-renderer.js +19 -0
  237. package/dist/lib/register-renderer.js.map +1 -0
  238. package/dist/lib/remote-drift.d.ts +61 -0
  239. package/dist/lib/remote-drift.d.ts.map +1 -0
  240. package/dist/lib/remote-drift.js +227 -0
  241. package/dist/lib/remote-drift.js.map +1 -0
  242. package/dist/lib/security.d.ts +72 -0
  243. package/dist/lib/security.d.ts.map +1 -0
  244. package/dist/lib/security.js +180 -0
  245. package/dist/lib/security.js.map +1 -0
  246. package/dist/lib/semantic-analysis.d.ts +31 -0
  247. package/dist/lib/semantic-analysis.d.ts.map +1 -0
  248. package/dist/lib/semantic-analysis.js +120 -0
  249. package/dist/lib/semantic-analysis.js.map +1 -0
  250. package/dist/lib/supabase-credentials.d.ts +36 -0
  251. package/dist/lib/supabase-credentials.d.ts.map +1 -0
  252. package/dist/lib/supabase-credentials.js +43 -0
  253. package/dist/lib/supabase-credentials.js.map +1 -0
  254. package/dist/lib/trunk.d.ts +39 -0
  255. package/dist/lib/trunk.d.ts.map +1 -0
  256. package/dist/lib/trunk.js +116 -0
  257. package/dist/lib/trunk.js.map +1 -0
  258. package/dist/lib/update-check.d.ts +11 -0
  259. package/dist/lib/update-check.d.ts.map +1 -0
  260. package/dist/lib/update-check.js +113 -0
  261. package/dist/lib/update-check.js.map +1 -0
  262. package/dist/lib/watch-renderer.d.ts +13 -0
  263. package/dist/lib/watch-renderer.d.ts.map +1 -0
  264. package/dist/lib/watch-renderer.js +35 -0
  265. package/dist/lib/watch-renderer.js.map +1 -0
  266. package/dist/storage/adapter.d.ts +81 -0
  267. package/dist/storage/adapter.d.ts.map +1 -0
  268. package/dist/storage/adapter.js +8 -0
  269. package/dist/storage/adapter.js.map +1 -0
  270. package/dist/storage/branch-registry-store.d.ts +13 -0
  271. package/dist/storage/branch-registry-store.d.ts.map +1 -0
  272. package/dist/storage/branch-registry-store.js +2 -0
  273. package/dist/storage/branch-registry-store.js.map +1 -0
  274. package/dist/storage/factory.d.ts +6 -0
  275. package/dist/storage/factory.d.ts.map +1 -0
  276. package/dist/storage/factory.js +14 -0
  277. package/dist/storage/factory.js.map +1 -0
  278. package/dist/storage/index.d.ts +10 -0
  279. package/dist/storage/index.d.ts.map +1 -0
  280. package/dist/storage/index.js +11 -0
  281. package/dist/storage/index.js.map +1 -0
  282. package/dist/storage/json-branch-registry-store.d.ts +19 -0
  283. package/dist/storage/json-branch-registry-store.d.ts.map +1 -0
  284. package/dist/storage/json-branch-registry-store.js +138 -0
  285. package/dist/storage/json-branch-registry-store.js.map +1 -0
  286. package/dist/storage/local.d.ts +20 -0
  287. package/dist/storage/local.d.ts.map +1 -0
  288. package/dist/storage/local.js +40 -0
  289. package/dist/storage/local.js.map +1 -0
  290. package/dist/storage/memory-branch-registry-store.d.ts +16 -0
  291. package/dist/storage/memory-branch-registry-store.d.ts.map +1 -0
  292. package/dist/storage/memory-branch-registry-store.js +68 -0
  293. package/dist/storage/memory-branch-registry-store.js.map +1 -0
  294. package/dist/storage/supabase-registry-sync-client-impl.d.ts +40 -0
  295. package/dist/storage/supabase-registry-sync-client-impl.d.ts.map +1 -0
  296. package/dist/storage/supabase-registry-sync-client-impl.js +278 -0
  297. package/dist/storage/supabase-registry-sync-client-impl.js.map +1 -0
  298. package/dist/storage/supabase-registry-sync-client.d.ts +9 -0
  299. package/dist/storage/supabase-registry-sync-client.d.ts.map +1 -0
  300. package/dist/storage/supabase-registry-sync-client.js +2 -0
  301. package/dist/storage/supabase-registry-sync-client.js.map +1 -0
  302. package/dist/storage/supabase.d.ts +28 -0
  303. package/dist/storage/supabase.d.ts.map +1 -0
  304. package/dist/storage/supabase.js +56 -0
  305. package/dist/storage/supabase.js.map +1 -0
  306. package/dist/types/cloud.d.ts +102 -0
  307. package/dist/types/cloud.d.ts.map +1 -0
  308. package/dist/types/cloud.js +13 -0
  309. package/dist/types/cloud.js.map +1 -0
  310. package/package.json +1 -1
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Validate agent ID (e.g., "sherlock", "watsan-1", "agent_01")
3
+ * @throws Error if invalid
4
+ */
5
+ export declare function validateAgentId(agentId: string): string;
6
+ /**
7
+ * Validate git branch name
8
+ * @throws Error if invalid
9
+ */
10
+ export declare function validateBranchName(branch: string): string;
11
+ /**
12
+ * Validate PR number
13
+ * @throws Error if invalid
14
+ */
15
+ export declare function validatePRNumber(prNumber: number | string): number;
16
+ /**
17
+ * Validate task ID (for torrent/task commands)
18
+ * @throws Error if invalid
19
+ */
20
+ export declare function validateTaskId(taskId: string): string;
21
+ /**
22
+ * Validate file path (basic safety check)
23
+ * @throws Error if invalid
24
+ */
25
+ export declare function validateFilePath(filePath: string): string;
26
+ /**
27
+ * Sanitize free-form text by removing shell metacharacters
28
+ * Use for message bodies, subjects, etc.
29
+ */
30
+ export declare function sanitizeText(text: string): string;
31
+ /**
32
+ * Sanitize an array of file paths
33
+ */
34
+ export declare function sanitizeFilePaths(files: string[]): string[];
35
+ /**
36
+ * Escape a string for safe use in git commands (minimal escaping)
37
+ */
38
+ export declare function escapeGitArg(arg: string): string;
39
+ /**
40
+ * Escapes a string so it can be safely used in a shell script.
41
+ * Replaces single quotes with '\'' and wraps the result in single quotes.
42
+ * Prevents command injection when generating bash scripts.
43
+ */
44
+ export declare function escapeShellString(str: string): string;
45
+ export declare const patterns: {
46
+ VALID_AGENT_ID: RegExp;
47
+ VALID_BRANCH_NAME: RegExp;
48
+ VALID_TASK_ID: RegExp;
49
+ VALID_FILE_PATH: RegExp;
50
+ SHELL_METACHARACTERS: RegExp;
51
+ };
52
+ export declare const sanitizeAgentId: typeof validateAgentId;
53
+ export declare const sanitizeBranchName: typeof validateBranchName;
54
+ export declare const sanitizeFilePath: typeof validateFilePath;
55
+ export declare const sanitizePRNumber: typeof validatePRNumber;
56
+ export declare function isValidMessageId(messageId: string): boolean;
57
+ /**
58
+ * Validate that a file path resolves to a location inside the current repository.
59
+ * Prevents arbitrary file read/write vulnerabilities via path traversal or absolute paths.
60
+ *
61
+ * @param filePath The path to validate
62
+ * @param rootDir The root directory (defaults to CWD)
63
+ * @returns The resolved absolute path if valid
64
+ * @throws Error if path is outside rootDir
65
+ */
66
+ export declare function validateRepoPath(filePath: string, rootDir?: string): string;
67
+ /**
68
+ * Safely resolves the CLI entry point path.
69
+ * Replaces insecure usage of process.argv[1] which can be manipulated.
70
+ */
71
+ export declare function getCLIPath(): string;
72
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/lib/security.ts"],"names":[],"mappings":"AAsBA;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQvD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQzD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAMlE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQrD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYzD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAU3D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGrD;AAGD,eAAO,MAAM,QAAQ;;;;;;CAMpB,CAAA;AAGD,eAAO,MAAM,eAAe,wBAAkB,CAAC;AAC/C,eAAO,MAAM,kBAAkB,2BAAqB,CAAC;AACrD,eAAO,MAAM,gBAAgB,yBAAmB,CAAC;AACjD,eAAO,MAAM,gBAAgB,yBAAmB,CAAC;AAIjD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,MAAsB,GAAG,MAAM,CAgB1F;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAKnC"}
@@ -0,0 +1,180 @@
1
+ import { resolve, relative, isAbsolute, dirname } from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ /**
4
+ * Spidersan Security Utilities
5
+ *
6
+ * Input validation and sanitization for shell command safety.
7
+ * Prevents command injection attacks via agent IDs, branch names, etc.
8
+ *
9
+ * @module security
10
+ */
11
+ // Validation patterns
12
+ const VALID_AGENT_ID = /^[a-z0-9][a-z0-9_-]{0,30}$/i;
13
+ const VALID_BRANCH_NAME = /^[a-zA-Z0-9][a-zA-Z0-9/_.-]{0,99}$/;
14
+ const VALID_TASK_ID = /^[a-z0-9][a-z0-9_-]{0,50}$/i;
15
+ // Allow spaces in file paths
16
+ const VALID_FILE_PATH = /^[./a-zA-Z0-9][a-zA-Z0-9/_.@\- ]{0,200}$/;
17
+ // Shell metacharacters to remove from text
18
+ const SHELL_METACHARACTERS = /[`$(){}[\]|;&<>\\]/g;
19
+ /**
20
+ * Validate agent ID (e.g., "sherlock", "watsan-1", "agent_01")
21
+ * @throws Error if invalid
22
+ */
23
+ export function validateAgentId(agentId) {
24
+ if (!agentId || typeof agentId !== 'string') {
25
+ throw new Error('Agent ID is required');
26
+ }
27
+ if (!VALID_AGENT_ID.test(agentId)) {
28
+ throw new Error(`Invalid agent ID: "${agentId.slice(0, 20)}..." (must be alphanumeric with - or _)`);
29
+ }
30
+ return agentId;
31
+ }
32
+ /**
33
+ * Validate git branch name
34
+ * @throws Error if invalid
35
+ */
36
+ export function validateBranchName(branch) {
37
+ if (!branch || typeof branch !== 'string') {
38
+ throw new Error('Branch name is required');
39
+ }
40
+ if (!VALID_BRANCH_NAME.test(branch)) {
41
+ throw new Error(`Invalid branch name: "${branch.slice(0, 20)}..."`);
42
+ }
43
+ return branch;
44
+ }
45
+ /**
46
+ * Validate PR number
47
+ * @throws Error if invalid
48
+ */
49
+ export function validatePRNumber(prNumber) {
50
+ const num = typeof prNumber === 'string' ? parseInt(prNumber, 10) : prNumber;
51
+ if (!Number.isInteger(num) || num <= 0) {
52
+ throw new Error(`Invalid PR number: ${prNumber}`);
53
+ }
54
+ return num;
55
+ }
56
+ /**
57
+ * Validate task ID (for torrent/task commands)
58
+ * @throws Error if invalid
59
+ */
60
+ export function validateTaskId(taskId) {
61
+ if (!taskId || typeof taskId !== 'string') {
62
+ throw new Error('Task ID is required');
63
+ }
64
+ if (!VALID_TASK_ID.test(taskId)) {
65
+ throw new Error(`Invalid task ID: "${taskId.slice(0, 20)}..." (must be alphanumeric with - or _)`);
66
+ }
67
+ return taskId;
68
+ }
69
+ /**
70
+ * Validate file path (basic safety check)
71
+ * @throws Error if invalid
72
+ */
73
+ export function validateFilePath(filePath) {
74
+ if (!filePath || typeof filePath !== 'string') {
75
+ throw new Error('File path is required');
76
+ }
77
+ // Block path traversal
78
+ if (filePath.includes('..')) {
79
+ throw new Error('Path traversal not allowed');
80
+ }
81
+ if (!VALID_FILE_PATH.test(filePath)) {
82
+ throw new Error(`Invalid file path: "${filePath.slice(0, 20)}..."`);
83
+ }
84
+ return filePath;
85
+ }
86
+ /**
87
+ * Sanitize free-form text by removing shell metacharacters
88
+ * Use for message bodies, subjects, etc.
89
+ */
90
+ export function sanitizeText(text) {
91
+ if (!text || typeof text !== 'string') {
92
+ return '';
93
+ }
94
+ return text.replace(SHELL_METACHARACTERS, '');
95
+ }
96
+ /**
97
+ * Sanitize an array of file paths
98
+ */
99
+ export function sanitizeFilePaths(files) {
100
+ return files.filter(f => {
101
+ try {
102
+ validateFilePath(f);
103
+ return true;
104
+ }
105
+ catch {
106
+ console.warn(`⚠️ Skipping invalid file path: ${f.slice(0, 30)}...`);
107
+ return false;
108
+ }
109
+ });
110
+ }
111
+ /**
112
+ * Escape a string for safe use in git commands (minimal escaping)
113
+ */
114
+ export function escapeGitArg(arg) {
115
+ // For use with execFileSync where no shell is invoked
116
+ // Just basic validation, no escaping needed
117
+ return arg;
118
+ }
119
+ /**
120
+ * Escapes a string so it can be safely used in a shell script.
121
+ * Replaces single quotes with '\'' and wraps the result in single quotes.
122
+ * Prevents command injection when generating bash scripts.
123
+ */
124
+ export function escapeShellString(str) {
125
+ if (str === null || str === undefined)
126
+ return "''";
127
+ return `'${String(str).replace(/'/g, "'\\''")}'`;
128
+ }
129
+ // Export validation patterns for testing
130
+ export const patterns = {
131
+ VALID_AGENT_ID,
132
+ VALID_BRANCH_NAME,
133
+ VALID_TASK_ID,
134
+ VALID_FILE_PATH,
135
+ SHELL_METACHARACTERS,
136
+ };
137
+ // Test-compatible aliases for vitest security tests
138
+ export const sanitizeAgentId = validateAgentId;
139
+ export const sanitizeBranchName = validateBranchName;
140
+ export const sanitizeFilePath = validateFilePath;
141
+ export const sanitizePRNumber = validatePRNumber;
142
+ // Message ID validation (for mycmail commands)
143
+ const VALID_MESSAGE_ID = /^[a-z0-9][a-z0-9_-]{0,64}$/i;
144
+ export function isValidMessageId(messageId) {
145
+ return typeof messageId === 'string' && VALID_MESSAGE_ID.test(messageId);
146
+ }
147
+ /**
148
+ * Validate that a file path resolves to a location inside the current repository.
149
+ * Prevents arbitrary file read/write vulnerabilities via path traversal or absolute paths.
150
+ *
151
+ * @param filePath The path to validate
152
+ * @param rootDir The root directory (defaults to CWD)
153
+ * @returns The resolved absolute path if valid
154
+ * @throws Error if path is outside rootDir
155
+ */
156
+ export function validateRepoPath(filePath, rootDir = process.cwd()) {
157
+ if (!filePath || typeof filePath !== 'string') {
158
+ throw new Error('File path is required');
159
+ }
160
+ const resolved = resolve(rootDir, filePath);
161
+ const rel = relative(rootDir, resolved);
162
+ // Check if path is outside root (starts with ..) or is absolute (on different drive on Windows)
163
+ // Note: on Linux/Mac relative() returns relative path, on Windows it might be absolute if different drive.
164
+ // Checking isAbsolute(rel) handles the different drive case.
165
+ if (rel.startsWith('..') || isAbsolute(rel)) {
166
+ throw new Error(`Security Error: Path "${filePath}" resolves outside the repository.`);
167
+ }
168
+ return resolved;
169
+ }
170
+ /**
171
+ * Safely resolves the CLI entry point path.
172
+ * Replaces insecure usage of process.argv[1] which can be manipulated.
173
+ */
174
+ export function getCLIPath() {
175
+ const __filename = fileURLToPath(import.meta.url);
176
+ const __dirname = dirname(__filename);
177
+ const ext = __filename.endsWith('.ts') ? '.ts' : '.js';
178
+ return resolve(__dirname, '..', 'bin', `spidersan${ext}`);
179
+ }
180
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/lib/security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { type SymbolConflict } from './ast.js';
2
+ export interface SemanticTarget {
3
+ label: string;
4
+ files: string[];
5
+ /** Resolvable git ref for this target's head, or null when it isn't available locally. */
6
+ ref: string | null;
7
+ }
8
+ export interface SemanticResult {
9
+ conflicts: SymbolConflict[];
10
+ /** One human-readable line per file/target that could not be analyzed. */
11
+ skipped: string[];
12
+ /**
13
+ * Overlapping files of a type semantic analysis doesn't cover (.sql, .yaml, .md …). "No symbol
14
+ * conflicts" says nothing about them, so callers must not turn it into "safe to merge".
15
+ */
16
+ unsupported: string[];
17
+ }
18
+ /**
19
+ * A branch's tip for analysis: the LOCAL branch first (unpushed commits are the point), then
20
+ * origin's. resolveBranchRef alone prefers the remote and would read a stale tip.
21
+ */
22
+ export declare function resolveBranchTip(name: string): string | null;
23
+ /**
24
+ * A cross-machine label "<machine>/<branch>" names ANOTHER machine's branch, so it resolves only
25
+ * against origin — a same-named local branch would be the wrong tip. The caller must know the
26
+ * label is cross-machine (from where the entry came from); guessing from the label's shape is
27
+ * ambiguous for local branches like "feat/x".
28
+ */
29
+ export declare function resolveCrossMachineRef(label: string): string | null;
30
+ export declare function analyzeSemantic(currentLabel: string, currentRef: string | null, targets: SemanticTarget[], cwd?: string): SemanticResult;
31
+ //# sourceMappingURL=semantic-analysis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-analysis.d.ts","sourceRoot":"","sources":["../../src/lib/semantic-analysis.ts"],"names":[],"mappings":"AAQA,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAI1D,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,0FAA0F;IAC1F,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,0EAA0E;IAC1E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;OAGG;IACH,WAAW,EAAE,MAAM,EAAE,CAAC;CACzB;AAqBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE5D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGnE;AAED,wBAAgB,eAAe,CAC3B,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,OAAO,EAAE,cAAc,EAAE,EACzB,GAAG,CAAC,EAAE,MAAM,GACb,cAAc,CAyEhB"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * semantic-analysis.ts — the `conflicts --semantic` engine.
3
+ *
4
+ * Takes targets that carry a REAL git ref (never a display label like
5
+ * "PR #303 (branch)") and returns symbol conflicts plus every file it could not
6
+ * analyze. Callers must not print "safe to merge" while `skipped` is non-empty.
7
+ */
8
+ import { execFileSync } from 'child_process';
9
+ import { ASTParser } from './ast.js';
10
+ import { findOutlineConflicts } from './outline.js';
11
+ import { resolveBranchRef, resolveLocalBranchRef } from './git.js';
12
+ const TS_FILE = /\.(ts|js|tsx|jsx)$/;
13
+ const PY_FILE = /\.py$/;
14
+ const git = (args, cwd) => execFileSync('git', args, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], cwd, timeout: 30_000 }); // a hung object store must not hang the command
15
+ /**
16
+ * File content at ref; null ONLY when the path genuinely doesn't exist there (a legitimate
17
+ * non-conflict). Any other git failure throws, so the caller records it as skipped instead of
18
+ * reading it as "absent".
19
+ *
20
+ * `ls-tree`, not `cat-file -e`: cat-file exits 128 for a missing path AND for a bad ref/repo, so it
21
+ * can't tell them apart. ls-tree exits 0 with empty output for an absent path and non-zero otherwise.
22
+ */
23
+ function show(ref, file, cwd) {
24
+ if (!git(['ls-tree', '--name-only', ref, '--', file], cwd).trim())
25
+ return null;
26
+ return git(['show', `${ref}:${file}`], cwd);
27
+ }
28
+ /**
29
+ * A branch's tip for analysis: the LOCAL branch first (unpushed commits are the point), then
30
+ * origin's. resolveBranchRef alone prefers the remote and would read a stale tip.
31
+ */
32
+ export function resolveBranchTip(name) {
33
+ return resolveLocalBranchRef(name) ?? resolveBranchRef(name);
34
+ }
35
+ /**
36
+ * A cross-machine label "<machine>/<branch>" names ANOTHER machine's branch, so it resolves only
37
+ * against origin — a same-named local branch would be the wrong tip. The caller must know the
38
+ * label is cross-machine (from where the entry came from); guessing from the label's shape is
39
+ * ambiguous for local branches like "feat/x".
40
+ */
41
+ export function resolveCrossMachineRef(label) {
42
+ const remote = resolveBranchRef(label.slice(label.indexOf('/') + 1));
43
+ return remote?.startsWith('refs/remotes/') ? remote : null;
44
+ }
45
+ export function analyzeSemantic(currentLabel, currentRef, targets, cwd) {
46
+ const parser = new ASTParser();
47
+ const result = { conflicts: [], skipped: [], unsupported: [] };
48
+ for (const target of targets) {
49
+ for (const file of target.files) {
50
+ const isPython = PY_FILE.test(file);
51
+ if (!isPython && !TS_FILE.test(file)) {
52
+ if (!result.unsupported.includes(file))
53
+ result.unsupported.push(file);
54
+ continue;
55
+ }
56
+ // An unresolvable ref is UNKNOWN, not "no conflict" — never swallow it.
57
+ if (!currentRef) {
58
+ result.skipped.push(`${file}: no local ref for ${currentLabel}`);
59
+ continue;
60
+ }
61
+ if (!target.ref) {
62
+ result.skipped.push(`${file}: no local ref for ${target.label} (not fetched?)`);
63
+ continue;
64
+ }
65
+ let current;
66
+ let other;
67
+ try {
68
+ current = show(currentRef, file, cwd);
69
+ other = show(target.ref, file, cwd);
70
+ }
71
+ catch {
72
+ result.skipped.push(`${file}: could not read from ${target.label}`);
73
+ continue;
74
+ }
75
+ // Absent on one side = added/deleted there. A delete/modify overlap is a real git conflict, and
76
+ // symbol comparison can't judge it, so it is unanalyzed (incomplete), never "nothing to conflict".
77
+ if (current === null || other === null) {
78
+ result.skipped.push(`${file}: absent on ${current === null ? currentLabel : target.label} (added or deleted) — not analyzed`);
79
+ continue;
80
+ }
81
+ // Three-way against the merge-base. Two-way ONLY when the histories are genuinely unrelated
82
+ // (merge-base exit 1); any other failure is unknown, not a reason to change comparison mode.
83
+ let base;
84
+ try {
85
+ let mb = null;
86
+ try {
87
+ mb = git(['merge-base', currentRef, target.ref], cwd).trim();
88
+ }
89
+ catch (err) {
90
+ if (err.status !== 1)
91
+ throw err; // 1 = no common ancestor
92
+ }
93
+ base = mb ? show(mb, file, cwd) ?? undefined : undefined;
94
+ }
95
+ catch {
96
+ result.skipped.push(`${file}: could not compute merge-base with ${target.label}`);
97
+ continue;
98
+ }
99
+ let found;
100
+ try {
101
+ found = isPython
102
+ ? findOutlineConflicts('.py', current, `${currentLabel}:${file}`, other, `${target.label}:${file}`, base)
103
+ : parser.findSymbolConflicts(current, `${currentLabel}:${file}`, other, `${target.label}:${file}`, base);
104
+ }
105
+ catch {
106
+ // A parser failure is unknown, not "no conflicts". No caught message: it can carry
107
+ // internals and this line is printed.
108
+ result.skipped.push(`${file}: parse failed`);
109
+ continue;
110
+ }
111
+ if (!found) {
112
+ result.skipped.push(`${file}: semantic analysis unavailable (install ast-grep)`);
113
+ continue;
114
+ }
115
+ result.conflicts.push(...found);
116
+ }
117
+ }
118
+ return result;
119
+ }
120
+ //# sourceMappingURL=semantic-analysis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-analysis.js","sourceRoot":"","sources":["../../src/lib/semantic-analysis.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Single source of truth for resolving spidersan's Supabase credentials.
3
+ *
4
+ * Precedence: SPIDERSAN_SUPABASE_* → SUPABASE_* → config.storage.*
5
+ *
6
+ * SPIDERSAN_SUPABASE_* MUST come first. envoak's vault-inject guard drops any
7
+ * secret whose name carries a bare SUPABASE_ prefix, so vault-injected creds
8
+ * only ever arrive under the scoped names. Resolvers checking just the bare
9
+ * names silently no-op under `envoak vault inject` — the production hook path —
10
+ * and report "Supabase not configured" while a valid grant is present (fc8cf22,
11
+ * 29aa575, tb-efmm; tb-ly0b found 7 more copies with the same defect).
12
+ *
13
+ * This module exists so that stays fixed in ONE place. Do not re-derive these
14
+ * env names inline; call resolveSupabaseCredentials()/resolveSupabaseEnv().
15
+ *
16
+ * COLONY_SUPABASE_* is deliberately absent from the chain: colony points at a
17
+ * different Supabase project, so falling back to it would silently write
18
+ * spider_registries into the wrong database (tb-ly0b).
19
+ */
20
+ export interface SupabaseCredentials {
21
+ url: string;
22
+ key: string;
23
+ }
24
+ /**
25
+ * Env-only resolution. For callers with no config file in scope (subscribers,
26
+ * activity logging) that need a synchronous answer.
27
+ */
28
+ export declare function resolveSupabaseEnv(): {
29
+ url?: string;
30
+ key?: string;
31
+ };
32
+ /**
33
+ * Env → config.storage. The default for commands; null when unconfigured.
34
+ */
35
+ export declare function resolveSupabaseCredentials(basePath?: string): Promise<SupabaseCredentials | null>;
36
+ //# sourceMappingURL=supabase-credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-credentials.d.ts","sourceRoot":"","sources":["../../src/lib/supabase-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,MAAM,WAAW,mBAAmB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAKnE;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC5C,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAQrC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Single source of truth for resolving spidersan's Supabase credentials.
3
+ *
4
+ * Precedence: SPIDERSAN_SUPABASE_* → SUPABASE_* → config.storage.*
5
+ *
6
+ * SPIDERSAN_SUPABASE_* MUST come first. envoak's vault-inject guard drops any
7
+ * secret whose name carries a bare SUPABASE_ prefix, so vault-injected creds
8
+ * only ever arrive under the scoped names. Resolvers checking just the bare
9
+ * names silently no-op under `envoak vault inject` — the production hook path —
10
+ * and report "Supabase not configured" while a valid grant is present (fc8cf22,
11
+ * 29aa575, tb-efmm; tb-ly0b found 7 more copies with the same defect).
12
+ *
13
+ * This module exists so that stays fixed in ONE place. Do not re-derive these
14
+ * env names inline; call resolveSupabaseCredentials()/resolveSupabaseEnv().
15
+ *
16
+ * COLONY_SUPABASE_* is deliberately absent from the chain: colony points at a
17
+ * different Supabase project, so falling back to it would silently write
18
+ * spider_registries into the wrong database (tb-ly0b).
19
+ */
20
+ import { loadConfig } from './config.js';
21
+ /**
22
+ * Env-only resolution. For callers with no config file in scope (subscribers,
23
+ * activity logging) that need a synchronous answer.
24
+ */
25
+ export function resolveSupabaseEnv() {
26
+ return {
27
+ url: process.env.SPIDERSAN_SUPABASE_URL || process.env.SUPABASE_URL,
28
+ key: process.env.SPIDERSAN_SUPABASE_KEY || process.env.SUPABASE_KEY,
29
+ };
30
+ }
31
+ /**
32
+ * Env → config.storage. The default for commands; null when unconfigured.
33
+ */
34
+ export async function resolveSupabaseCredentials(basePath) {
35
+ const env = resolveSupabaseEnv();
36
+ const config = await loadConfig(basePath);
37
+ const url = env.url || config.storage.supabaseUrl;
38
+ const key = env.key || config.storage.supabaseKey;
39
+ if (!url || !key)
40
+ return null;
41
+ return { url, key };
42
+ }
43
+ //# sourceMappingURL=supabase-credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-credentials.js","sourceRoot":"","sources":["../../src/lib/supabase-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAOzC;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAC9B,OAAO;QACH,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QACnE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;KACtE,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC5C,QAAiB;IAEjB,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;IAClD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;IAElD,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAC9B,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Trunk branch detection.
3
+ *
4
+ * Centralizes the "which branch is trunk?" question that was previously
5
+ * hardcoded as `main`/`master` in several places.
6
+ *
7
+ * Resolution order (first hit wins):
8
+ * 1. `git symbolic-ref refs/remotes/origin/HEAD` (strip the `origin/` prefix)
9
+ * 2. `.spidersanrc` `trunk` key
10
+ * 3. `main` — if that branch exists
11
+ * 4. `master` — if that branch exists
12
+ * 5. `'main'` — default fallback
13
+ *
14
+ * Pure + cached per `cwd` within a process. Tolerates a missing
15
+ * `origin/HEAD` (fresh clones throw — we catch and fall through).
16
+ */
17
+ /**
18
+ * Resolve the repo's trunk branch name.
19
+ *
20
+ * @param opts.cwd - Repo directory (defaults to `process.cwd()`).
21
+ * @returns The trunk branch name (e.g. `'main'`, `'master'`, `'develop'`).
22
+ */
23
+ export declare function getTrunkBranch(opts?: {
24
+ cwd?: string;
25
+ }): string;
26
+ /**
27
+ * True if `branch` is the repo's trunk.
28
+ *
29
+ * @param branch - Branch name to test.
30
+ * @param opts.cwd - Repo directory (defaults to `process.cwd()`).
31
+ */
32
+ export declare function isTrunk(branch: string, opts?: {
33
+ cwd?: string;
34
+ }): boolean;
35
+ /**
36
+ * Clear the per-cwd trunk cache. Intended for tests; harmless in production.
37
+ */
38
+ export declare function _clearTrunkCache(): void;
39
+ //# sourceMappingURL=trunk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trunk.d.ts","sourceRoot":"","sources":["../../src/lib/trunk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA0EH;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAQ9D;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAExE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}