@oscharko-dev/keiko-server 0.2.7 → 0.2.9

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 (302) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/chat-handlers.d.ts +18 -2
  3. package/dist/chat-handlers.d.ts.map +1 -1
  4. package/dist/chat-handlers.js +185 -3
  5. package/dist/command-runner-errors.d.ts +17 -0
  6. package/dist/command-runner-errors.d.ts.map +1 -0
  7. package/dist/command-runner-errors.js +37 -0
  8. package/dist/command-runner-evidence.d.ts +23 -0
  9. package/dist/command-runner-evidence.d.ts.map +1 -0
  10. package/dist/command-runner-evidence.js +69 -0
  11. package/dist/command-runner-routes.d.ts +7 -0
  12. package/dist/command-runner-routes.d.ts.map +1 -0
  13. package/dist/command-runner-routes.js +175 -0
  14. package/dist/command-runner.d.ts +29 -0
  15. package/dist/command-runner.d.ts.map +1 -0
  16. package/dist/command-runner.js +348 -0
  17. package/dist/conversation-prompt.d.ts +2 -2
  18. package/dist/conversation-prompt.d.ts.map +1 -1
  19. package/dist/conversation-prompt.js +17 -1
  20. package/dist/csp.d.ts.map +1 -1
  21. package/dist/csp.js +3 -0
  22. package/dist/deps.d.ts +28 -1
  23. package/dist/deps.d.ts.map +1 -1
  24. package/dist/deps.js +288 -13
  25. package/dist/discussion-prompt.d.ts +4 -0
  26. package/dist/discussion-prompt.d.ts.map +1 -0
  27. package/dist/discussion-prompt.js +19 -0
  28. package/dist/editor/agentActionAudit.d.ts +18 -0
  29. package/dist/editor/agentActionAudit.d.ts.map +1 -0
  30. package/dist/editor/agentActionAudit.js +80 -0
  31. package/dist/editor/agentRoutes.d.ts +1 -0
  32. package/dist/editor/agentRoutes.d.ts.map +1 -1
  33. package/dist/editor/agentRoutes.js +292 -55
  34. package/dist/editor/agentSessionRegistry.d.ts +35 -0
  35. package/dist/editor/agentSessionRegistry.d.ts.map +1 -0
  36. package/dist/editor/agentSessionRegistry.js +243 -0
  37. package/dist/editor/completionRoutes.d.ts.map +1 -1
  38. package/dist/editor/completionRoutes.js +5 -10
  39. package/dist/editor/languageRoutes.d.ts +12 -1
  40. package/dist/editor/languageRoutes.d.ts.map +1 -1
  41. package/dist/editor/languageRoutes.js +71 -8
  42. package/dist/editor/languageService.d.ts +3 -2
  43. package/dist/editor/languageService.d.ts.map +1 -1
  44. package/dist/editor/languageService.js +41 -3
  45. package/dist/editor/languageServiceHost.d.ts.map +1 -1
  46. package/dist/editor/languageServiceHost.js +2 -2
  47. package/dist/editor/lsp/hostLanguageOperation.d.ts +17 -0
  48. package/dist/editor/lsp/hostLanguageOperation.d.ts.map +1 -0
  49. package/dist/editor/lsp/hostLanguageOperation.js +436 -0
  50. package/dist/editor/lsp/hostLanguageProviders.d.ts +26 -0
  51. package/dist/editor/lsp/hostLanguageProviders.d.ts.map +1 -0
  52. package/dist/editor/lsp/hostLanguageProviders.js +161 -0
  53. package/dist/editor/lsp/lspFrameCodec.d.ts +13 -0
  54. package/dist/editor/lsp/lspFrameCodec.d.ts.map +1 -0
  55. package/dist/editor/lsp/lspFrameCodec.js +164 -0
  56. package/dist/editor/lsp/lspJsonRpcClient.d.ts +34 -0
  57. package/dist/editor/lsp/lspJsonRpcClient.d.ts.map +1 -0
  58. package/dist/editor/lsp/lspJsonRpcClient.js +173 -0
  59. package/dist/editor/lsp/lspLanguageProvider.d.ts +7 -0
  60. package/dist/editor/lsp/lspLanguageProvider.d.ts.map +1 -0
  61. package/dist/editor/lsp/lspLanguageProvider.js +29 -0
  62. package/dist/editor/lsp/lspLifecycleLedger.d.ts +5 -0
  63. package/dist/editor/lsp/lspLifecycleLedger.d.ts.map +1 -0
  64. package/dist/editor/lsp/lspLifecycleLedger.js +37 -0
  65. package/dist/editor/lsp/lspNodeAdapter.d.ts +31 -0
  66. package/dist/editor/lsp/lspNodeAdapter.d.ts.map +1 -0
  67. package/dist/editor/lsp/lspNodeAdapter.js +230 -0
  68. package/dist/editor/lsp/lspProcessManager.d.ts +24 -0
  69. package/dist/editor/lsp/lspProcessManager.d.ts.map +1 -0
  70. package/dist/editor/lsp/lspProcessManager.js +255 -0
  71. package/dist/editor/lsp/lspRestartThrottle.d.ts +6 -0
  72. package/dist/editor/lsp/lspRestartThrottle.d.ts.map +1 -0
  73. package/dist/editor/lsp/lspRestartThrottle.js +24 -0
  74. package/dist/editor/lsp/lspStatusRoute.d.ts +8 -0
  75. package/dist/editor/lsp/lspStatusRoute.d.ts.map +1 -0
  76. package/dist/editor/lsp/lspStatusRoute.js +22 -0
  77. package/dist/editor/lsp/lspTransport.d.ts +19 -0
  78. package/dist/editor/lsp/lspTransport.d.ts.map +1 -0
  79. package/dist/editor/lsp/lspTransport.js +55 -0
  80. package/dist/editor/lsp/testing/fakeLspProcess.d.ts +23 -0
  81. package/dist/editor/lsp/testing/fakeLspProcess.d.ts.map +1 -0
  82. package/dist/editor/lsp/testing/fakeLspProcess.js +132 -0
  83. package/dist/files.d.ts +63 -0
  84. package/dist/files.d.ts.map +1 -1
  85. package/dist/files.js +799 -1
  86. package/dist/gateway-readiness.d.ts +6 -0
  87. package/dist/gateway-readiness.d.ts.map +1 -0
  88. package/dist/gateway-readiness.js +624 -0
  89. package/dist/gateway-setup.d.ts +2 -0
  90. package/dist/gateway-setup.d.ts.map +1 -1
  91. package/dist/gateway-setup.js +275 -11
  92. package/dist/gitDelivery/actionSheetProjection.d.ts +30 -0
  93. package/dist/gitDelivery/actionSheetProjection.d.ts.map +1 -0
  94. package/dist/gitDelivery/actionSheetProjection.js +206 -0
  95. package/dist/gitDelivery/actionSheetRoutes.d.ts +29 -0
  96. package/dist/gitDelivery/actionSheetRoutes.d.ts.map +1 -0
  97. package/dist/gitDelivery/actionSheetRoutes.js +293 -0
  98. package/dist/gitDelivery/agentOperationsRoutes.d.ts +33 -0
  99. package/dist/gitDelivery/agentOperationsRoutes.d.ts.map +1 -0
  100. package/dist/gitDelivery/agentOperationsRoutes.js +405 -0
  101. package/dist/gitDelivery/commitRoutes.d.ts +23 -0
  102. package/dist/gitDelivery/commitRoutes.d.ts.map +1 -0
  103. package/dist/gitDelivery/commitRoutes.js +204 -0
  104. package/dist/gitDelivery/evidenceRoutes.d.ts +9 -0
  105. package/dist/gitDelivery/evidenceRoutes.d.ts.map +1 -0
  106. package/dist/gitDelivery/evidenceRoutes.js +101 -0
  107. package/dist/gitDelivery/execution.d.ts +38 -0
  108. package/dist/gitDelivery/execution.d.ts.map +1 -0
  109. package/dist/gitDelivery/execution.js +117 -0
  110. package/dist/gitDelivery/localMutationRoutes.d.ts +30 -0
  111. package/dist/gitDelivery/localMutationRoutes.d.ts.map +1 -0
  112. package/dist/gitDelivery/localMutationRoutes.js +165 -0
  113. package/dist/gitDelivery/mergeExecution.d.ts +63 -0
  114. package/dist/gitDelivery/mergeExecution.d.ts.map +1 -0
  115. package/dist/gitDelivery/mergeExecution.js +168 -0
  116. package/dist/gitDelivery/mergeRoutes.d.ts +12 -0
  117. package/dist/gitDelivery/mergeRoutes.d.ts.map +1 -0
  118. package/dist/gitDelivery/mergeRoutes.js +218 -0
  119. package/dist/gitDelivery/mutationEvidenceLedger.d.ts +23 -0
  120. package/dist/gitDelivery/mutationEvidenceLedger.d.ts.map +1 -0
  121. package/dist/gitDelivery/mutationEvidenceLedger.js +87 -0
  122. package/dist/gitDelivery/prExecution.d.ts +54 -0
  123. package/dist/gitDelivery/prExecution.d.ts.map +1 -0
  124. package/dist/gitDelivery/prExecution.js +192 -0
  125. package/dist/gitDelivery/prRoutes.d.ts +12 -0
  126. package/dist/gitDelivery/prRoutes.d.ts.map +1 -0
  127. package/dist/gitDelivery/prRoutes.js +256 -0
  128. package/dist/gitDelivery/pushExecution.d.ts +43 -0
  129. package/dist/gitDelivery/pushExecution.d.ts.map +1 -0
  130. package/dist/gitDelivery/pushExecution.js +124 -0
  131. package/dist/gitDelivery/pushRoutes.d.ts +12 -0
  132. package/dist/gitDelivery/pushRoutes.d.ts.map +1 -0
  133. package/dist/gitDelivery/pushRoutes.js +200 -0
  134. package/dist/gitDelivery/requestGuards.d.ts +15 -0
  135. package/dist/gitDelivery/requestGuards.d.ts.map +1 -0
  136. package/dist/gitDelivery/requestGuards.js +97 -0
  137. package/dist/gitDelivery/syncEvidence.d.ts +37 -0
  138. package/dist/gitDelivery/syncEvidence.d.ts.map +1 -0
  139. package/dist/gitDelivery/syncEvidence.js +85 -0
  140. package/dist/gitDelivery/syncExecution.d.ts +30 -0
  141. package/dist/gitDelivery/syncExecution.d.ts.map +1 -0
  142. package/dist/gitDelivery/syncExecution.js +266 -0
  143. package/dist/gitDelivery/syncRoutes.d.ts +13 -0
  144. package/dist/gitDelivery/syncRoutes.d.ts.map +1 -0
  145. package/dist/gitDelivery/syncRoutes.js +200 -0
  146. package/dist/gitPorcelainStatus.d.ts +15 -0
  147. package/dist/gitPorcelainStatus.d.ts.map +1 -0
  148. package/dist/gitPorcelainStatus.js +104 -0
  149. package/dist/gitRepositoryReads.d.ts +10 -0
  150. package/dist/gitRepositoryReads.d.ts.map +1 -0
  151. package/dist/gitRepositoryReads.js +314 -0
  152. package/dist/gitRepositoryRoutes.d.ts +7 -0
  153. package/dist/gitRepositoryRoutes.d.ts.map +1 -0
  154. package/dist/gitRepositoryRoutes.js +221 -0
  155. package/dist/gitRoutes.d.ts +66 -0
  156. package/dist/gitRoutes.d.ts.map +1 -0
  157. package/dist/gitRoutes.js +543 -0
  158. package/dist/governed-workflow.d.ts +2 -0
  159. package/dist/governed-workflow.d.ts.map +1 -1
  160. package/dist/governed-workflow.js +4 -0
  161. package/dist/grounded-qa-hybrid.d.ts.map +1 -1
  162. package/dist/grounded-qa-hybrid.js +2 -0
  163. package/dist/grounded-qa-multi-source.d.ts.map +1 -1
  164. package/dist/grounded-qa-multi-source.js +1 -0
  165. package/dist/grounded-qa.d.ts +11 -0
  166. package/dist/grounded-qa.d.ts.map +1 -1
  167. package/dist/grounded-qa.js +14 -4
  168. package/dist/headers.d.ts +4 -1
  169. package/dist/headers.d.ts.map +1 -1
  170. package/dist/headers.js +11 -4
  171. package/dist/index.d.ts +8 -1
  172. package/dist/index.d.ts.map +1 -1
  173. package/dist/index.js +9 -1
  174. package/dist/local-knowledge-grounded-qa.d.ts.map +1 -1
  175. package/dist/local-knowledge-grounded-qa.js +11 -2
  176. package/dist/qualityIntelligence/figmaSnapshotRoutes.d.ts +1 -1
  177. package/dist/qualityIntelligence/figmaSnapshotRoutes.d.ts.map +1 -1
  178. package/dist/qualityIntelligence/figmaSnapshotRoutes.js +1 -1
  179. package/dist/read-handlers.d.ts +5 -0
  180. package/dist/read-handlers.d.ts.map +1 -1
  181. package/dist/read-handlers.js +57 -1
  182. package/dist/routes.d.ts.map +1 -1
  183. package/dist/routes.js +260 -12
  184. package/dist/run-engine.d.ts.map +1 -1
  185. package/dist/run-engine.js +3 -0
  186. package/dist/run-handlers.d.ts +0 -1
  187. package/dist/run-handlers.d.ts.map +1 -1
  188. package/dist/run-handlers.js +64 -211
  189. package/dist/run-request.d.ts +11 -0
  190. package/dist/run-request.d.ts.map +1 -1
  191. package/dist/run-request.js +158 -10
  192. package/dist/runtime/capabilityDetector.d.ts +38 -0
  193. package/dist/runtime/capabilityDetector.d.ts.map +1 -0
  194. package/dist/runtime/capabilityDetector.js +443 -0
  195. package/dist/runtime/capabilityRoutes.d.ts +9 -0
  196. package/dist/runtime/capabilityRoutes.d.ts.map +1 -0
  197. package/dist/runtime/capabilityRoutes.js +45 -0
  198. package/dist/runtime/containerEngineDetector.d.ts +17 -0
  199. package/dist/runtime/containerEngineDetector.d.ts.map +1 -0
  200. package/dist/runtime/containerEngineDetector.js +222 -0
  201. package/dist/runtime/containerRoutes.d.ts +8 -0
  202. package/dist/runtime/containerRoutes.d.ts.map +1 -0
  203. package/dist/runtime/containerRoutes.js +207 -0
  204. package/dist/runtime/containerRunner-errors.d.ts +18 -0
  205. package/dist/runtime/containerRunner-errors.d.ts.map +1 -0
  206. package/dist/runtime/containerRunner-errors.js +42 -0
  207. package/dist/runtime/containerRunner-evidence.d.ts +24 -0
  208. package/dist/runtime/containerRunner-evidence.d.ts.map +1 -0
  209. package/dist/runtime/containerRunner-evidence.js +74 -0
  210. package/dist/runtime/containerRunner.d.ts +37 -0
  211. package/dist/runtime/containerRunner.d.ts.map +1 -0
  212. package/dist/runtime/containerRunner.js +443 -0
  213. package/dist/server.d.ts.map +1 -1
  214. package/dist/server.js +24 -4
  215. package/dist/store/db.d.ts.map +1 -1
  216. package/dist/store/db.js +2 -1
  217. package/dist/store/index.d.ts +1 -1
  218. package/dist/store/index.d.ts.map +1 -1
  219. package/dist/store/messages.d.ts +2 -1
  220. package/dist/store/messages.d.ts.map +1 -1
  221. package/dist/store/messages.js +46 -4
  222. package/dist/store/schema.d.ts +1 -1
  223. package/dist/store/schema.d.ts.map +1 -1
  224. package/dist/store/schema.js +68 -1
  225. package/dist/store/types.d.ts +3 -2
  226. package/dist/store/types.d.ts.map +1 -1
  227. package/dist/task-workspace/active-store.d.ts +21 -0
  228. package/dist/task-workspace/active-store.d.ts.map +1 -0
  229. package/dist/task-workspace/active-store.js +55 -0
  230. package/dist/task-workspace/authorization.d.ts +7 -0
  231. package/dist/task-workspace/authorization.d.ts.map +1 -0
  232. package/dist/task-workspace/authorization.js +54 -0
  233. package/dist/task-workspace/binding.d.ts +3 -0
  234. package/dist/task-workspace/binding.d.ts.map +1 -0
  235. package/dist/task-workspace/binding.js +22 -0
  236. package/dist/task-workspace/cleanup.d.ts +4 -0
  237. package/dist/task-workspace/cleanup.d.ts.map +1 -0
  238. package/dist/task-workspace/cleanup.js +428 -0
  239. package/dist/task-workspace/errors.d.ts +14 -0
  240. package/dist/task-workspace/errors.d.ts.map +1 -0
  241. package/dist/task-workspace/errors.js +81 -0
  242. package/dist/task-workspace/evidence.d.ts +32 -0
  243. package/dist/task-workspace/evidence.d.ts.map +1 -0
  244. package/dist/task-workspace/evidence.js +52 -0
  245. package/dist/task-workspace/field-safety.d.ts +3 -0
  246. package/dist/task-workspace/field-safety.d.ts.map +1 -0
  247. package/dist/task-workspace/field-safety.js +42 -0
  248. package/dist/task-workspace/health.d.ts +4 -0
  249. package/dist/task-workspace/health.d.ts.map +1 -0
  250. package/dist/task-workspace/health.js +163 -0
  251. package/dist/task-workspace/lifecycle.d.ts +3 -0
  252. package/dist/task-workspace/lifecycle.d.ts.map +1 -0
  253. package/dist/task-workspace/lifecycle.js +248 -0
  254. package/dist/task-workspace/locks.d.ts +13 -0
  255. package/dist/task-workspace/locks.d.ts.map +1 -0
  256. package/dist/task-workspace/locks.js +44 -0
  257. package/dist/task-workspace/managed-root.d.ts +7 -0
  258. package/dist/task-workspace/managed-root.d.ts.map +1 -0
  259. package/dist/task-workspace/managed-root.js +98 -0
  260. package/dist/task-workspace/mutex.d.ts +8 -0
  261. package/dist/task-workspace/mutex.d.ts.map +1 -0
  262. package/dist/task-workspace/mutex.js +82 -0
  263. package/dist/task-workspace/naming.d.ts +15 -0
  264. package/dist/task-workspace/naming.d.ts.map +1 -0
  265. package/dist/task-workspace/naming.js +0 -0
  266. package/dist/task-workspace/provisioning.d.ts +3 -0
  267. package/dist/task-workspace/provisioning.d.ts.map +1 -0
  268. package/dist/task-workspace/provisioning.js +528 -0
  269. package/dist/task-workspace/reconciliation.d.ts +15 -0
  270. package/dist/task-workspace/reconciliation.d.ts.map +1 -0
  271. package/dist/task-workspace/reconciliation.js +274 -0
  272. package/dist/task-workspace/repair.d.ts +3 -0
  273. package/dist/task-workspace/repair.d.ts.map +1 -0
  274. package/dist/task-workspace/repair.js +286 -0
  275. package/dist/task-workspace/routes.d.ts +19 -0
  276. package/dist/task-workspace/routes.d.ts.map +1 -0
  277. package/dist/task-workspace/routes.js +481 -0
  278. package/dist/task-workspace/store.d.ts +12 -0
  279. package/dist/task-workspace/store.d.ts.map +1 -0
  280. package/dist/task-workspace/store.js +128 -0
  281. package/dist/task-workspace/types.d.ts +170 -0
  282. package/dist/task-workspace/types.d.ts.map +1 -0
  283. package/dist/task-workspace/types.js +5 -0
  284. package/dist/voice-action-governance.d.ts +23 -0
  285. package/dist/voice-action-governance.d.ts.map +1 -0
  286. package/dist/voice-action-governance.js +126 -0
  287. package/dist/voice-handlers.d.ts +6 -0
  288. package/dist/voice-handlers.d.ts.map +1 -0
  289. package/dist/voice-handlers.js +570 -0
  290. package/dist/voice-realtime-grounded-tool.d.ts +31 -0
  291. package/dist/voice-realtime-grounded-tool.d.ts.map +1 -0
  292. package/dist/voice-realtime-grounded-tool.js +322 -0
  293. package/dist/voice-realtime.d.ts +69 -0
  294. package/dist/voice-realtime.d.ts.map +1 -0
  295. package/dist/voice-realtime.js +787 -0
  296. package/dist/workspace-state-handlers.d.ts +5 -0
  297. package/dist/workspace-state-handlers.d.ts.map +1 -0
  298. package/dist/workspace-state-handlers.js +106 -0
  299. package/package.json +20 -19
  300. package/dist/grounded-handoff.d.ts +0 -4
  301. package/dist/grounded-handoff.d.ts.map +0 -1
  302. package/dist/grounded-handoff.js +0 -445
@@ -0,0 +1,314 @@
1
+ // Read-only Git repository summary / history / remotes BFF (Issue #1573, Epic #1572). Git execution
2
+ // stays server-side with fixed args/env, selected-root containment, unsafe-owner surfacing, and
3
+ // bounded output. Reuses the hardened runner + containment from gitRoutes.ts and the shared
4
+ // porcelain-v2 parser; every response body is content-free (counts, typed codes, branch/remote
5
+ // names, ISO dates) and passes through `deps.redactor`.
6
+ import { stat } from "node:fs/promises";
7
+ import { isAbsolute, resolve } from "node:path";
8
+ import { GIT_HISTORY_SCHEMA_VERSION, GIT_REPOSITORY_SUMMARY_SCHEMA_VERSION, } from "@oscharko-dev/keiko-contracts";
9
+ import { classifyFailure, isContained, optionsWithDefaults, resolveRepository, } from "./gitRoutes.js";
10
+ import { parsePorcelainV2Branch } from "./gitPorcelainStatus.js";
11
+ import { FilesError, runFilesHandler } from "./files.js";
12
+ const HISTORY_RECORD_SEP = "\x1e";
13
+ const HISTORY_FIELD_SEP = "\x1f";
14
+ const HISTORY_PRETTY_FORMAT = `format:${HISTORY_RECORD_SEP}%H${HISTORY_FIELD_SEP}%h${HISTORY_FIELD_SEP}%P${HISTORY_FIELD_SEP}%an${HISTORY_FIELD_SEP}%aI${HISTORY_FIELD_SEP}%D${HISTORY_FIELD_SEP}%s`;
15
+ const HISTORY_LIMIT_DEFAULT = 50;
16
+ const HISTORY_LIMIT_MAX = 200;
17
+ const HISTORY_SKIP_MAX = 100_000;
18
+ function redacted(deps, value) {
19
+ return deps.redactor(value);
20
+ }
21
+ function unavailableState(reason) {
22
+ return reason === "unsafe-repository" ? "unsafe" : "unavailable";
23
+ }
24
+ function isUnavailable(repo) {
25
+ return "available" in repo;
26
+ }
27
+ // --- remotes ----------------------------------------------------------------
28
+ // `git remote -v` emits `name\turl (fetch|push)` lines; fetch/push URLs are deduplicated by name.
29
+ export function parseRemotes(stdout) {
30
+ const byName = new Map();
31
+ const order = [];
32
+ for (const line of stdout.split(/\r?\n/u)) {
33
+ const match = /^(\S+)\t(.+?)\s+\((fetch|push)\)$/u.exec(line.trim());
34
+ if (match === null)
35
+ continue;
36
+ const [, name, url, kind] = match;
37
+ if (name === undefined || url === undefined)
38
+ continue;
39
+ if (!byName.has(name)) {
40
+ byName.set(name, { name });
41
+ order.push(name);
42
+ }
43
+ const entry = byName.get(name);
44
+ if (entry === undefined)
45
+ continue;
46
+ if (kind === "fetch")
47
+ entry.fetchUrl = url;
48
+ else
49
+ entry.pushUrl = url;
50
+ }
51
+ return order.map((name) => {
52
+ const entry = byName.get(name) ?? { name };
53
+ return { name: entry.name, fetchUrl: entry.fetchUrl, pushUrl: entry.pushUrl };
54
+ });
55
+ }
56
+ function runGit(repo, options, args) {
57
+ return options.runner(["--no-pager", "--no-optional-locks", "-C", repo.repositoryRoot, ...args], {
58
+ cwd: repo.repositoryRoot,
59
+ maxBytes: options.maxStatusBytes,
60
+ timeoutMs: options.timeoutMs,
61
+ });
62
+ }
63
+ // --- last sync (FETCH_HEAD mtime) -------------------------------------------
64
+ async function readLastSync(repo, options) {
65
+ try {
66
+ const result = await runGit(repo, options, ["rev-parse", "--git-path", "FETCH_HEAD"]);
67
+ if (result.exitCode !== 0)
68
+ return undefined;
69
+ const rawPath = result.stdout.split(/\r?\n/u)[0]?.trim();
70
+ if (rawPath === undefined || rawPath.length === 0)
71
+ return undefined;
72
+ // Defence-in-depth: `--git-path` resolves relative to the repository root, but verify the
73
+ // resolved path is contained under it before stat-ing so a manipulated rev-parse result can
74
+ // never stat an out-of-tree file. Containment failure ⇒ omit lastSync (metadata stays optional).
75
+ const path = isAbsolute(rawPath) ? rawPath : resolve(repo.repositoryRoot, rawPath);
76
+ if (!isContained(repo.repositoryRoot, path))
77
+ return undefined;
78
+ const info = await stat(path);
79
+ return { lastFetchAtMs: Math.round(info.mtimeMs) };
80
+ }
81
+ catch {
82
+ return undefined;
83
+ }
84
+ }
85
+ // --- summary ----------------------------------------------------------------
86
+ // `GitRemotesResponse` IS the shared unavailable envelope head; the summary spreads it and adds the
87
+ // zeroed status fields, so both responses stay byte-identical for the common fields.
88
+ function unavailableRemotes(root, repositoryRoot, reason) {
89
+ return {
90
+ schemaVersion: GIT_REPOSITORY_SUMMARY_SCHEMA_VERSION,
91
+ root,
92
+ repositoryRoot,
93
+ state: reason === undefined ? "unavailable" : unavailableState(reason),
94
+ available: false,
95
+ reason,
96
+ remotes: [],
97
+ truncated: false,
98
+ };
99
+ }
100
+ function unavailableSummary(root, repositoryRoot, reason) {
101
+ return {
102
+ ...unavailableRemotes(root, repositoryRoot, reason),
103
+ detached: false,
104
+ ahead: 0,
105
+ behind: 0,
106
+ stagedCount: 0,
107
+ unstagedCount: 0,
108
+ untrackedCount: 0,
109
+ conflictedCount: 0,
110
+ clean: true,
111
+ };
112
+ }
113
+ function buildSummary(repo, status, remotes, lastSync) {
114
+ const parsed = parsePorcelainV2Branch(status.stdout);
115
+ const remoteAliases = remotes.map((remote) => ({ name: remote.name }));
116
+ return {
117
+ schemaVersion: GIT_REPOSITORY_SUMMARY_SCHEMA_VERSION,
118
+ root: repo.root,
119
+ repositoryRoot: repo.repositoryRoot,
120
+ state: "available",
121
+ available: true,
122
+ branch: parsed.branch,
123
+ detached: parsed.detached,
124
+ upstream: parsed.upstream,
125
+ ahead: parsed.ahead,
126
+ behind: parsed.behind,
127
+ stagedCount: parsed.stagedCount,
128
+ unstagedCount: parsed.unstagedCount,
129
+ untrackedCount: parsed.untrackedCount,
130
+ conflictedCount: parsed.conflictedCount,
131
+ clean: !parsed.dirty,
132
+ remotes: remoteAliases,
133
+ lastSync,
134
+ truncated: status.truncated,
135
+ };
136
+ }
137
+ export async function handleGitSummary(ctx, deps, rawOptions) {
138
+ return runFilesHandler(async () => {
139
+ const options = optionsWithDefaults(rawOptions ?? deps.gitRouteOptions);
140
+ const repo = await resolveRepository(ctx, deps, options);
141
+ if (isUnavailable(repo)) {
142
+ const body = unavailableSummary(repo.root, repo.repositoryRoot, repo.reason);
143
+ return { status: 200, body: redacted(deps, body) };
144
+ }
145
+ const status = await runGit(repo, options, [
146
+ "status",
147
+ "--porcelain=v2",
148
+ "--branch",
149
+ "-z",
150
+ "--untracked-files=all",
151
+ ]);
152
+ if (status.exitCode !== 0) {
153
+ const reason = classifyFailure(status);
154
+ return {
155
+ status: 200,
156
+ body: redacted(deps, unavailableSummary(repo.root, repo.repositoryRoot, reason)),
157
+ };
158
+ }
159
+ const remotesResult = await runGit(repo, options, ["remote", "-v"]);
160
+ const remotes = remotesResult.exitCode === 0 ? parseRemotes(remotesResult.stdout) : [];
161
+ const lastSync = await readLastSync(repo, options);
162
+ return { status: 200, body: redacted(deps, buildSummary(repo, status, remotes, lastSync)) };
163
+ });
164
+ }
165
+ // --- remotes route ----------------------------------------------------------
166
+ export async function handleGitRemotes(ctx, deps, rawOptions) {
167
+ return runFilesHandler(async () => {
168
+ const options = optionsWithDefaults(rawOptions ?? deps.gitRouteOptions);
169
+ const repo = await resolveRepository(ctx, deps, options);
170
+ if (isUnavailable(repo)) {
171
+ const body = unavailableRemotes(repo.root, repo.repositoryRoot, repo.reason);
172
+ return { status: 200, body: redacted(deps, body) };
173
+ }
174
+ const result = await runGit(repo, options, ["remote", "-v"]);
175
+ if (result.exitCode !== 0) {
176
+ const reason = classifyFailure(result);
177
+ const body = unavailableRemotes(repo.root, repo.repositoryRoot, reason);
178
+ return { status: 200, body: redacted(deps, { ...body, truncated: result.truncated }) };
179
+ }
180
+ return {
181
+ status: 200,
182
+ body: redacted(deps, {
183
+ schemaVersion: GIT_REPOSITORY_SUMMARY_SCHEMA_VERSION,
184
+ root: repo.root,
185
+ repositoryRoot: repo.repositoryRoot,
186
+ state: "available",
187
+ available: true,
188
+ remotes: parseRemotes(result.stdout),
189
+ truncated: result.truncated,
190
+ }),
191
+ };
192
+ });
193
+ }
194
+ // --- history ----------------------------------------------------------------
195
+ function parseInteger(raw, fallback, min, max) {
196
+ if (raw === null || raw.trim().length === 0)
197
+ return fallback;
198
+ if (!/^-?\d+$/u.test(raw.trim())) {
199
+ throw new FilesError(400, "BAD_REQUEST", "The limit and skip parameters must be integers.");
200
+ }
201
+ const value = Number.parseInt(raw.trim(), 10);
202
+ if (value < min)
203
+ return min;
204
+ if (value > max)
205
+ return max;
206
+ return value;
207
+ }
208
+ // The `--shortstat` summary line carries "N files changed"; merge/empty commits omit it (⇒ 0).
209
+ function parseChangedFileCount(remainder) {
210
+ const match = /(\d+)\s+files?\s+changed/u.exec(remainder);
211
+ return match?.[1] === undefined ? 0 : Number.parseInt(match[1], 10);
212
+ }
213
+ function parseHistoryEntry(record) {
214
+ const newline = record.indexOf("\n");
215
+ const head = newline === -1 ? record : record.slice(0, newline);
216
+ const remainder = newline === -1 ? "" : record.slice(newline + 1);
217
+ const fields = head.split(HISTORY_FIELD_SEP);
218
+ const [sha, shortSha, parents, author, date, refs] = fields;
219
+ if (sha === undefined || shortSha === undefined || sha.length === 0)
220
+ return undefined;
221
+ const subject = fields.slice(6).join(HISTORY_FIELD_SEP);
222
+ return {
223
+ sha,
224
+ shortSha,
225
+ subject,
226
+ author: author ?? "",
227
+ date: date ?? "",
228
+ refs: (refs ?? "")
229
+ .split(", ")
230
+ .map((ref) => ref.trim())
231
+ .filter((ref) => ref.length > 0),
232
+ parentCount: (parents ?? "").split(/\s+/u).filter((entry) => entry.length > 0).length,
233
+ changedFileCount: parseChangedFileCount(remainder),
234
+ };
235
+ }
236
+ export function parseHistory(stdout) {
237
+ return stdout
238
+ .split(HISTORY_RECORD_SEP)
239
+ .filter((record) => record.length > 0)
240
+ .map(parseHistoryEntry)
241
+ .filter((entry) => entry !== undefined);
242
+ }
243
+ // An empty repository (no commits yet) makes `git log` exit non-zero; treat that as empty history.
244
+ function isEmptyRepository(result) {
245
+ const text = `${result.stdout}\n${result.stderr}`.toLowerCase();
246
+ return (text.includes("does not have any commits yet") ||
247
+ text.includes("bad default revision 'head'") ||
248
+ text.includes("bad revision 'head'"));
249
+ }
250
+ function unavailableHistory(root, repositoryRoot, reason, limit, skip) {
251
+ return {
252
+ schemaVersion: GIT_HISTORY_SCHEMA_VERSION,
253
+ root,
254
+ repositoryRoot,
255
+ state: reason === undefined ? "unavailable" : unavailableState(reason),
256
+ available: false,
257
+ reason,
258
+ entries: [],
259
+ limit,
260
+ skip,
261
+ truncated: false,
262
+ };
263
+ }
264
+ function availableHistory(repo, entries, limit, skip, truncated) {
265
+ return {
266
+ schemaVersion: GIT_HISTORY_SCHEMA_VERSION,
267
+ root: repo.root,
268
+ repositoryRoot: repo.repositoryRoot,
269
+ state: "available",
270
+ available: true,
271
+ entries,
272
+ limit,
273
+ skip,
274
+ truncated,
275
+ };
276
+ }
277
+ function historyArgs(limit, skip) {
278
+ return [
279
+ "log",
280
+ "--no-color",
281
+ `--max-count=${String(limit)}`,
282
+ `--skip=${String(skip)}`,
283
+ `--pretty=${HISTORY_PRETTY_FORMAT}`,
284
+ "--shortstat",
285
+ ];
286
+ }
287
+ export async function handleGitHistory(ctx, deps, rawOptions) {
288
+ return runFilesHandler(async () => {
289
+ const options = optionsWithDefaults(rawOptions ?? deps.gitRouteOptions);
290
+ const limit = parseInteger(ctx.url.searchParams.get("limit"), HISTORY_LIMIT_DEFAULT, 1, HISTORY_LIMIT_MAX);
291
+ const skip = parseInteger(ctx.url.searchParams.get("skip"), 0, 0, HISTORY_SKIP_MAX);
292
+ const repo = await resolveRepository(ctx, deps, options);
293
+ if (isUnavailable(repo)) {
294
+ const body = unavailableHistory(repo.root, repo.repositoryRoot, repo.reason, limit, skip);
295
+ return { status: 200, body: redacted(deps, body) };
296
+ }
297
+ const result = await runGit(repo, options, historyArgs(limit, skip));
298
+ if (result.exitCode !== 0) {
299
+ if (isEmptyRepository(result)) {
300
+ return {
301
+ status: 200,
302
+ body: redacted(deps, availableHistory(repo, [], limit, skip, false)),
303
+ };
304
+ }
305
+ const reason = classifyFailure(result);
306
+ const body = unavailableHistory(repo.root, repo.repositoryRoot, reason, limit, skip);
307
+ return { status: 200, body: redacted(deps, body) };
308
+ }
309
+ const entries = parseHistory(result.stdout);
310
+ const truncated = result.truncated || entries.length === limit;
311
+ const body = availableHistory(repo, entries, limit, skip, truncated);
312
+ return { status: 200, body: redacted(deps, body) };
313
+ });
314
+ }
@@ -0,0 +1,7 @@
1
+ import type { RouteContext, RouteResult } from "./routes.js";
2
+ import type { UiHandlerDeps } from "./deps.js";
3
+ type CloneRepositoryRunner = (repositoryUrl: string, destinationPath: string) => Promise<RouteResult | null>;
4
+ export declare function createCloneRepositoryHandler(cloneRunner?: CloneRepositoryRunner): (ctx: RouteContext, deps: UiHandlerDeps) => Promise<RouteResult>;
5
+ export declare const handleCloneRepository: (ctx: RouteContext, deps: UiHandlerDeps) => Promise<RouteResult>;
6
+ export {};
7
+ //# sourceMappingURL=gitRepositoryRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitRepositoryRoutes.d.ts","sourceRoot":"","sources":["../src/gitRepositoryRoutes.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAuI/C,KAAK,qBAAqB,GAAG,CAC3B,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,KACpB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;AAuEjC,wBAAgB,4BAA4B,CAC1C,WAAW,GAAE,qBAAuC,GACnD,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,WAAW,CAAC,CA2BlE;AAED,eAAO,MAAM,qBAAqB,QA7BzB,YAAY,QAAQ,aAAa,KAAK,OAAO,CAAC,WAAW,CA6BC,CAAC"}
@@ -0,0 +1,221 @@
1
+ import { spawn } from "node:child_process";
2
+ import { Buffer } from "node:buffer";
3
+ import { statSync } from "node:fs";
4
+ import { dirname, isAbsolute, normalize } from "node:path";
5
+ import { errorBody } from "./routes.js";
6
+ import { pathIsDenied } from "./files-deny.js";
7
+ import { assertUiDbOutsideProject, isProjectAvailable, validateProjectPath, } from "./store/index.js";
8
+ const MAX_BODY_BYTES = 32 * 1024;
9
+ const MAX_OUTPUT_BYTES = 64 * 1024;
10
+ const CLONE_TIMEOUT_MS = 120_000;
11
+ class BodyTooLargeError extends Error {
12
+ constructor() {
13
+ super("body too large");
14
+ this.name = "BodyTooLargeError";
15
+ }
16
+ }
17
+ function readBody(req) {
18
+ return new Promise((resolve, reject) => {
19
+ const chunks = [];
20
+ let total = 0;
21
+ let capped = false;
22
+ req.on("data", (chunk) => {
23
+ total += chunk.length;
24
+ if (total > MAX_BODY_BYTES) {
25
+ if (!capped) {
26
+ capped = true;
27
+ chunks.length = 0;
28
+ reject(new BodyTooLargeError());
29
+ req.resume();
30
+ }
31
+ return;
32
+ }
33
+ chunks.push(chunk);
34
+ });
35
+ req.on("end", () => {
36
+ if (!capped)
37
+ resolve(Buffer.concat(chunks).toString("utf8"));
38
+ });
39
+ req.on("error", reject);
40
+ });
41
+ }
42
+ async function readJsonObject(req) {
43
+ const raw = await readBody(req);
44
+ const parsed = JSON.parse(raw);
45
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
46
+ throw new Error("Expected JSON object");
47
+ }
48
+ return parsed;
49
+ }
50
+ function optionalString(body, key) {
51
+ const value = body[key];
52
+ if (value === undefined || value === null)
53
+ return undefined;
54
+ if (typeof value !== "string")
55
+ throw new Error(`${key} must be a string`);
56
+ const trimmed = value.trim();
57
+ return trimmed.length === 0 ? undefined : trimmed;
58
+ }
59
+ function requireString(body, key) {
60
+ const value = optionalString(body, key);
61
+ if (value === undefined)
62
+ throw new Error(`${key} is required`);
63
+ return value;
64
+ }
65
+ function projectWithAvailability(project) {
66
+ return { ...project, available: isProjectAvailable(project) };
67
+ }
68
+ function invalid(message) {
69
+ return { status: 400, body: errorBody("BAD_REQUEST", message) };
70
+ }
71
+ function forbidden(message) {
72
+ return { status: 403, body: errorBody("DENIED", message) };
73
+ }
74
+ function repositoryUrlAllowed(input) {
75
+ if (containsControlCharacter(input))
76
+ return false;
77
+ if (/^git@[^:\s]+:[^\s]+$/u.test(input))
78
+ return true;
79
+ try {
80
+ const url = new URL(input);
81
+ if (url.username !== "" || url.password !== "")
82
+ return false;
83
+ return url.protocol === "https:" || url.protocol === "ssh:";
84
+ }
85
+ catch {
86
+ return false;
87
+ }
88
+ }
89
+ function containsControlCharacter(input) {
90
+ for (const char of input) {
91
+ const code = char.charCodeAt(0);
92
+ if (code < 32 || code === 127)
93
+ return true;
94
+ }
95
+ return false;
96
+ }
97
+ function assertDestination(candidate) {
98
+ if (!isAbsolute(candidate))
99
+ return invalid("Destination path must be absolute.");
100
+ const normalized = normalize(candidate);
101
+ if (pathIsDenied(normalized)) {
102
+ return forbidden("The destination path is excluded from Keiko's safe repository surface.");
103
+ }
104
+ try {
105
+ statSync(normalized);
106
+ return invalid("Destination path already exists.");
107
+ }
108
+ catch {
109
+ // Expected: git clone creates the final directory.
110
+ }
111
+ const parent = dirname(normalized);
112
+ if (pathIsDenied(parent)) {
113
+ return forbidden("The destination parent is excluded from Keiko's safe repository surface.");
114
+ }
115
+ try {
116
+ const info = statSync(parent);
117
+ if (!info.isDirectory())
118
+ return invalid("Destination parent must be a directory.");
119
+ }
120
+ catch {
121
+ return invalid("Destination parent must exist.");
122
+ }
123
+ return normalized;
124
+ }
125
+ function gitEnv() {
126
+ return {
127
+ PATH: process.env.PATH ?? "",
128
+ GIT_TERMINAL_PROMPT: "0",
129
+ GIT_PAGER: "cat",
130
+ PAGER: "cat",
131
+ };
132
+ }
133
+ const cloneRepository = function cloneRepository(repositoryUrl, destinationPath) {
134
+ return new Promise((resolveResult) => {
135
+ const child = spawn("git", ["clone", "--", repositoryUrl, destinationPath], {
136
+ cwd: dirname(destinationPath),
137
+ env: gitEnv(),
138
+ shell: false,
139
+ windowsHide: true,
140
+ stdio: ["ignore", "pipe", "pipe"],
141
+ });
142
+ monitorCloneProcess(child, resolveResult);
143
+ });
144
+ };
145
+ function cloneFailure(truncated) {
146
+ return {
147
+ status: truncated ? 504 : 409,
148
+ body: errorBody(truncated ? "GIT_CLONE_TIMEOUT" : "GIT_CLONE_FAILED", truncated
149
+ ? "Repository clone did not finish within the bounded execution window."
150
+ : "Repository clone failed. Check the URL, credentials, and destination path."),
151
+ };
152
+ }
153
+ function monitorCloneProcess(child, resolveResult) {
154
+ let outputBytes = 0;
155
+ let truncated = false;
156
+ let settled = false;
157
+ const timer = setTimeout(() => {
158
+ truncated = true;
159
+ child.kill("SIGTERM");
160
+ }, CLONE_TIMEOUT_MS);
161
+ const capture = (chunk) => {
162
+ outputBytes += chunk.byteLength;
163
+ if (outputBytes > MAX_OUTPUT_BYTES) {
164
+ truncated = true;
165
+ child.kill("SIGTERM");
166
+ }
167
+ };
168
+ child.stdout?.on("data", capture);
169
+ child.stderr?.on("data", capture);
170
+ child.on("error", () => {
171
+ if (settled)
172
+ return;
173
+ settled = true;
174
+ clearTimeout(timer);
175
+ resolveResult({
176
+ status: 503,
177
+ body: errorBody("GIT_UNAVAILABLE", "Git is not available on this host."),
178
+ });
179
+ });
180
+ child.on("close", (code) => {
181
+ if (settled)
182
+ return;
183
+ settled = true;
184
+ clearTimeout(timer);
185
+ if (code === 0) {
186
+ resolveResult(null);
187
+ return;
188
+ }
189
+ resolveResult(cloneFailure(truncated));
190
+ });
191
+ }
192
+ export function createCloneRepositoryHandler(cloneRunner = cloneRepository) {
193
+ return async (ctx, deps) => {
194
+ try {
195
+ const body = await readJsonObject(ctx.req);
196
+ const repositoryUrl = requireString(body, "repositoryUrl");
197
+ const destinationInput = requireString(body, "destinationPath");
198
+ const name = optionalString(body, "name");
199
+ if (!repositoryUrlAllowed(repositoryUrl)) {
200
+ return invalid("Repository URL must be HTTPS, SSH, or git@host:path without embedded secrets.");
201
+ }
202
+ const destination = assertDestination(destinationInput);
203
+ if (typeof destination !== "string")
204
+ return destination;
205
+ assertUiDbOutsideProject(deps.uiDbPath, destination);
206
+ const cloneResult = await cloneRunner(repositoryUrl, destination);
207
+ if (cloneResult !== null)
208
+ return cloneResult;
209
+ const normalizedPath = validateProjectPath(destination, { mustExist: true });
210
+ const project = deps.store.createProject(normalizedPath, name);
211
+ return { status: 201, body: { project: projectWithAvailability(project) } };
212
+ }
213
+ catch (error) {
214
+ if (error instanceof BodyTooLargeError) {
215
+ return { status: 413, body: errorBody("PAYLOAD_TOO_LARGE", "Request body is too large.") };
216
+ }
217
+ return invalid("The clone request is invalid.");
218
+ }
219
+ };
220
+ }
221
+ export const handleCloneRepository = createCloneRepositoryHandler();
@@ -0,0 +1,66 @@
1
+ import type { GitRepositoryStatusResponse } from "@oscharko-dev/keiko-contracts";
2
+ import { GIT_REPOSITORY_SCHEMA_VERSION } from "@oscharko-dev/keiko-contracts";
3
+ import { type RouteContext, type RouteResult } from "./routes.js";
4
+ import type { UiHandlerDeps } from "./deps.js";
5
+ export interface GitProcessResult {
6
+ readonly exitCode: number | null;
7
+ readonly signal: NodeJS.Signals | null;
8
+ readonly stdout: string;
9
+ readonly stderr: string;
10
+ readonly truncated: boolean;
11
+ }
12
+ export interface GitProcessOptions {
13
+ readonly cwd: string;
14
+ readonly maxBytes: number;
15
+ readonly timeoutMs: number;
16
+ }
17
+ export type GitProcessRunner = (args: readonly string[], options: GitProcessOptions) => Promise<GitProcessResult>;
18
+ export interface GitRouteOptions {
19
+ readonly runner?: GitProcessRunner | undefined;
20
+ readonly maxStatusBytes?: number | undefined;
21
+ readonly maxDiffBytes?: number | undefined;
22
+ readonly maxChanges?: number | undefined;
23
+ readonly timeoutMs?: number | undefined;
24
+ }
25
+ export interface NormalizedGitRouteOptions {
26
+ readonly runner: GitProcessRunner;
27
+ readonly maxStatusBytes: number;
28
+ readonly maxDiffBytes: number;
29
+ readonly maxChanges: number;
30
+ readonly timeoutMs: number;
31
+ }
32
+ export interface RepositoryContext {
33
+ readonly root: string;
34
+ readonly realRoot: string;
35
+ readonly repositoryRoot: string;
36
+ readonly selectedRootPrefix: string;
37
+ }
38
+ export interface GitBranchListEntry {
39
+ readonly name: string;
40
+ readonly headRefHash: string;
41
+ readonly current: boolean;
42
+ }
43
+ export interface GitBranchListResponse {
44
+ readonly schemaVersion: typeof GIT_REPOSITORY_SCHEMA_VERSION;
45
+ readonly root: string;
46
+ readonly repositoryRoot?: string | undefined;
47
+ readonly available: boolean;
48
+ readonly state: "available" | "unavailable" | "unsafe";
49
+ readonly reason?: GitRepositoryStatusResponse["reason"] | undefined;
50
+ readonly message?: string | undefined;
51
+ readonly branches: readonly GitBranchListEntry[];
52
+ readonly truncated: boolean;
53
+ }
54
+ export declare function gitEnv(): NodeJS.ProcessEnv;
55
+ export declare function networkGitEnv(): NodeJS.ProcessEnv;
56
+ export declare function createGitProcessRunner(buildEnv: () => NodeJS.ProcessEnv): GitProcessRunner;
57
+ export declare const defaultGitProcessRunner: GitProcessRunner;
58
+ export declare const defaultGitNetworkProcessRunner: GitProcessRunner;
59
+ export declare function isContained(root: string, target: string): boolean;
60
+ export declare function classifyFailure(result: GitProcessResult): GitRepositoryStatusResponse["reason"];
61
+ export declare function optionsWithDefaults(options: GitRouteOptions | undefined): NormalizedGitRouteOptions;
62
+ export declare function resolveRepository(ctx: RouteContext, deps: UiHandlerDeps, options: NormalizedGitRouteOptions): Promise<RepositoryContext | GitRepositoryStatusResponse>;
63
+ export declare function handleGitBranches(ctx: RouteContext, deps: UiHandlerDeps, rawOptions?: GitRouteOptions): Promise<RouteResult>;
64
+ export declare function handleGitStatus(ctx: RouteContext, deps: UiHandlerDeps, rawOptions?: GitRouteOptions): Promise<RouteResult>;
65
+ export declare function handleGitDiff(ctx: RouteContext, deps: UiHandlerDeps, rawOptions?: GitRouteOptions): Promise<RouteResult>;
66
+ //# sourceMappingURL=gitRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitRoutes.d.ts","sourceRoot":"","sources":["../src/gitRoutes.ts"],"names":[],"mappings":"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"}