@kodycodes/cli 1.26.1 → 1.26.3

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 (271) hide show
  1. package/dist/auth-4FW6GCLG.js +26 -0
  2. package/dist/auth-4FW6GCLG.js.map +6 -0
  3. package/dist/bin.js +27 -3
  4. package/dist/bin.js.map +6 -1
  5. package/dist/chunk-46IJPEID.js +30 -0
  6. package/dist/chunk-46IJPEID.js.map +6 -0
  7. package/dist/chunk-4D6ORNXY.js +24404 -0
  8. package/dist/chunk-4D6ORNXY.js.map +6 -0
  9. package/dist/chunk-64IM6G4Z.js +341 -0
  10. package/dist/chunk-64IM6G4Z.js.map +6 -0
  11. package/dist/{package-local-runtime-source.js → chunk-64XN367G.js} +373 -52
  12. package/dist/chunk-64XN367G.js.map +6 -0
  13. package/dist/chunk-6XQP5SWX.js +26 -0
  14. package/dist/chunk-6XQP5SWX.js.map +6 -0
  15. package/dist/chunk-75RZUXQL.js +62 -0
  16. package/dist/chunk-75RZUXQL.js.map +6 -0
  17. package/dist/chunk-BISUL7CE.js +106 -0
  18. package/dist/chunk-BISUL7CE.js.map +6 -0
  19. package/dist/chunk-BPGY4IE7.js +57 -0
  20. package/dist/chunk-BPGY4IE7.js.map +6 -0
  21. package/dist/chunk-CASGRYOF.js +21 -0
  22. package/dist/chunk-CASGRYOF.js.map +6 -0
  23. package/dist/chunk-CWWHR4FH.js +19 -0
  24. package/dist/chunk-CWWHR4FH.js.map +6 -0
  25. package/dist/chunk-D55XPY3T.js +1382 -0
  26. package/dist/chunk-D55XPY3T.js.map +6 -0
  27. package/dist/chunk-EOCV74B2.js +948 -0
  28. package/dist/chunk-EOCV74B2.js.map +6 -0
  29. package/dist/chunk-FBVNFWR6.js +437 -0
  30. package/dist/chunk-FBVNFWR6.js.map +6 -0
  31. package/dist/chunk-G4YN6XP5.js +14 -0
  32. package/dist/chunk-G4YN6XP5.js.map +6 -0
  33. package/dist/chunk-G6LJWROP.js +18 -0
  34. package/dist/chunk-G6LJWROP.js.map +6 -0
  35. package/dist/chunk-IHP6PV6X.js +49 -0
  36. package/dist/chunk-IHP6PV6X.js.map +6 -0
  37. package/dist/chunk-JWEFKKAD.js +24 -0
  38. package/dist/chunk-JWEFKKAD.js.map +6 -0
  39. package/dist/chunk-LWNB26KO.js +147 -0
  40. package/dist/chunk-LWNB26KO.js.map +6 -0
  41. package/dist/chunk-OVGXPRSY.js +20 -0
  42. package/dist/chunk-OVGXPRSY.js.map +6 -0
  43. package/dist/chunk-PDWCKWQF.js +453 -0
  44. package/dist/chunk-PDWCKWQF.js.map +6 -0
  45. package/dist/chunk-QHBCP4OB.js +44 -0
  46. package/dist/chunk-QHBCP4OB.js.map +6 -0
  47. package/dist/chunk-R4IUV5P5.js +664 -0
  48. package/dist/chunk-R4IUV5P5.js.map +6 -0
  49. package/dist/chunk-RM34N3KI.js +525 -0
  50. package/dist/chunk-RM34N3KI.js.map +6 -0
  51. package/dist/chunk-RTWUNV76.js +309 -0
  52. package/dist/chunk-RTWUNV76.js.map +6 -0
  53. package/dist/chunk-SMURF26I.js +23 -0
  54. package/dist/chunk-SMURF26I.js.map +6 -0
  55. package/dist/chunk-SXHULGL4.js +426 -0
  56. package/dist/chunk-SXHULGL4.js.map +6 -0
  57. package/dist/chunk-TIL35OWA.js +1959 -0
  58. package/dist/chunk-TIL35OWA.js.map +6 -0
  59. package/dist/chunk-VQS5YSCI.js +54 -0
  60. package/dist/chunk-VQS5YSCI.js.map +6 -0
  61. package/dist/chunk-XDCOWU5R.js +696 -0
  62. package/dist/chunk-XDCOWU5R.js.map +6 -0
  63. package/dist/chunk-XOPPGRUP.js +605 -0
  64. package/dist/chunk-XOPPGRUP.js.map +6 -0
  65. package/dist/cli.js +74 -1500
  66. package/dist/cli.js.map +6 -1
  67. package/dist/dev/dev-watcher.d.ts +5 -1
  68. package/dist/dev-command-3LX234N6.js +4900 -0
  69. package/dist/dev-command-3LX234N6.js.map +6 -0
  70. package/dist/git-credential-FUE3JE3T.js +163 -0
  71. package/dist/git-credential-FUE3JE3T.js.map +6 -0
  72. package/dist/install-ZML2TCDG.js +10694 -0
  73. package/dist/install-ZML2TCDG.js.map +6 -0
  74. package/dist/local-execute-SZV6XN4T.js +368 -0
  75. package/dist/local-execute-SZV6XN4T.js.map +6 -0
  76. package/dist/local-package-run-2TMCAZZ2.js +23 -0
  77. package/dist/local-package-run-2TMCAZZ2.js.map +6 -0
  78. package/dist/mcp-G2AWTIXR.js +21 -0
  79. package/dist/mcp-G2AWTIXR.js.map +6 -0
  80. package/dist/mock-dep-resolve-TVABDNR7.js +52 -0
  81. package/dist/mock-dep-resolve-TVABDNR7.js.map +6 -0
  82. package/dist/mock-fetch-gateway-B5TFGGQS.js +34 -0
  83. package/dist/mock-fetch-gateway-B5TFGGQS.js.map +6 -0
  84. package/dist/mock-local-deps-5SZT3PWT.js +197 -0
  85. package/dist/mock-local-deps-5SZT3PWT.js.map +6 -0
  86. package/dist/mock-server-SV2IKC4I.js +21 -0
  87. package/dist/mock-server-SV2IKC4I.js.map +6 -0
  88. package/dist/open-api-client-DVVMLY7P.js +42 -0
  89. package/dist/open-api-client-DVVMLY7P.js.map +6 -0
  90. package/dist/org-X7B5BI4R.js +132 -0
  91. package/dist/org-X7B5BI4R.js.map +6 -0
  92. package/dist/package-manifest-QH2RU64C.js +14 -0
  93. package/dist/package-manifest-QH2RU64C.js.map +6 -0
  94. package/dist/remote-execute-QMQDVHOY.js +110 -0
  95. package/dist/remote-execute-QMQDVHOY.js.map +6 -0
  96. package/dist/setup-git-5KCUBYPB.js +88 -0
  97. package/dist/setup-git-5KCUBYPB.js.map +6 -0
  98. package/dist/skill-ENPATRIW.js +43 -0
  99. package/dist/skill-ENPATRIW.js.map +6 -0
  100. package/dist/store-WTMRH527.js +48 -0
  101. package/dist/store-WTMRH527.js.map +6 -0
  102. package/dist/structured-error-C65GQ53Z.js +13 -0
  103. package/dist/structured-error-C65GQ53Z.js.map +6 -0
  104. package/dist/target-3QHY7JT4.js +45 -0
  105. package/dist/target-3QHY7JT4.js.map +6 -0
  106. package/dist/webapi-NTVP4BO3.js +2482 -0
  107. package/dist/webapi-NTVP4BO3.js.map +6 -0
  108. package/package.json +8 -8
  109. package/dist/add-mcp-install.js +0 -59
  110. package/dist/add-mcp-install.js.map +0 -1
  111. package/dist/api-token-store.js +0 -120
  112. package/dist/api-token-store.js.map +0 -1
  113. package/dist/api-token.js +0 -238
  114. package/dist/api-token.js.map +0 -1
  115. package/dist/auth-bootstrap.js +0 -373
  116. package/dist/auth-bootstrap.js.map +0 -1
  117. package/dist/auth.js +0 -386
  118. package/dist/auth.js.map +0 -1
  119. package/dist/capability-proxy.js +0 -527
  120. package/dist/capability-proxy.js.map +0 -1
  121. package/dist/credential-call-map.js +0 -155
  122. package/dist/credential-call-map.js.map +0 -1
  123. package/dist/credential-client-runtime-source.js +0 -9
  124. package/dist/credential-client-runtime-source.js.map +0 -1
  125. package/dist/credentialed-fetch-scan.js +0 -98
  126. package/dist/credentialed-fetch-scan.js.map +0 -1
  127. package/dist/defaults.js +0 -34
  128. package/dist/defaults.js.map +0 -1
  129. package/dist/detect-running-hosts.js +0 -13
  130. package/dist/detect-running-hosts.js.map +0 -1
  131. package/dist/dev/dev-assets.js +0 -202
  132. package/dist/dev/dev-assets.js.map +0 -1
  133. package/dist/dev/dev-bundler.js +0 -65
  134. package/dist/dev/dev-bundler.js.map +0 -1
  135. package/dist/dev/dev-events.js +0 -94
  136. package/dist/dev/dev-events.js.map +0 -1
  137. package/dist/dev/dev-port.js +0 -80
  138. package/dist/dev/dev-port.js.map +0 -1
  139. package/dist/dev/dev-protocol.js +0 -14
  140. package/dist/dev/dev-protocol.js.map +0 -1
  141. package/dist/dev/dev-registry.js +0 -95
  142. package/dist/dev/dev-registry.js.map +0 -1
  143. package/dist/dev/dev-watcher.js +0 -156
  144. package/dist/dev/dev-watcher.js.map +0 -1
  145. package/dist/dev/error-page.js +0 -64
  146. package/dist/dev/error-page.js.map +0 -1
  147. package/dist/dev/live-reload.js +0 -148
  148. package/dist/dev/live-reload.js.map +0 -1
  149. package/dist/dev/prebuild.js +0 -102
  150. package/dist/dev/prebuild.js.map +0 -1
  151. package/dist/dev/process-reaper.js +0 -151
  152. package/dist/dev/process-reaper.js.map +0 -1
  153. package/dist/dev/stack-trace.js +0 -56
  154. package/dist/dev/stack-trace.js.map +0 -1
  155. package/dist/dev/workerd-process.js +0 -118
  156. package/dist/dev/workerd-process.js.map +0 -1
  157. package/dist/dev-command.js +0 -672
  158. package/dist/dev-command.js.map +0 -1
  159. package/dist/discover-login-identity.js +0 -77
  160. package/dist/discover-login-identity.js.map +0 -1
  161. package/dist/discover-org.js +0 -62
  162. package/dist/discover-org.js.map +0 -1
  163. package/dist/git-credential.js +0 -147
  164. package/dist/git-credential.js.map +0 -1
  165. package/dist/help.js +0 -333
  166. package/dist/help.js.map +0 -1
  167. package/dist/host-catalog.js +0 -427
  168. package/dist/host-catalog.js.map +0 -1
  169. package/dist/host-config.js +0 -80
  170. package/dist/host-config.js.map +0 -1
  171. package/dist/http-error-body.js +0 -35
  172. package/dist/http-error-body.js.map +0 -1
  173. package/dist/install-hosts.js +0 -328
  174. package/dist/install-hosts.js.map +0 -1
  175. package/dist/install.js +0 -120
  176. package/dist/install.js.map +0 -1
  177. package/dist/invoke-passthrough.js +0 -60
  178. package/dist/invoke-passthrough.js.map +0 -1
  179. package/dist/local-bundle.js +0 -200
  180. package/dist/local-bundle.js.map +0 -1
  181. package/dist/local-execute-auth.js +0 -53
  182. package/dist/local-execute-auth.js.map +0 -1
  183. package/dist/local-execute.js +0 -338
  184. package/dist/local-execute.js.map +0 -1
  185. package/dist/local-gateway-fetch-forward.js +0 -135
  186. package/dist/local-gateway-fetch-forward.js.map +0 -1
  187. package/dist/local-host-runtime-surface.js +0 -75
  188. package/dist/local-host-runtime-surface.js.map +0 -1
  189. package/dist/local-package-graph.js +0 -405
  190. package/dist/local-package-graph.js.map +0 -1
  191. package/dist/local-package-run.js +0 -307
  192. package/dist/local-package-run.js.map +0 -1
  193. package/dist/local-runtime-bridge.js +0 -132
  194. package/dist/local-runtime-bridge.js.map +0 -1
  195. package/dist/local-runtime-source.js +0 -541
  196. package/dist/local-runtime-source.js.map +0 -1
  197. package/dist/login-callback-assets.js +0 -10
  198. package/dist/login-callback-assets.js.map +0 -1
  199. package/dist/login-callback-page.js +0 -362
  200. package/dist/login-callback-page.js.map +0 -1
  201. package/dist/mcp.js +0 -134
  202. package/dist/mcp.js.map +0 -1
  203. package/dist/mock/ensure-msw.js +0 -215
  204. package/dist/mock/ensure-msw.js.map +0 -1
  205. package/dist/mock/install-mock-fetch-shim.js +0 -36
  206. package/dist/mock/install-mock-fetch-shim.js.map +0 -1
  207. package/dist/mock/load-package-mocks.js +0 -136
  208. package/dist/mock/load-package-mocks.js.map +0 -1
  209. package/dist/mock/mock-fetch-gateway.js +0 -343
  210. package/dist/mock/mock-fetch-gateway.js.map +0 -1
  211. package/dist/mock/mock-gateway-fetch-shim.js +0 -104
  212. package/dist/mock/mock-gateway-fetch-shim.js.map +0 -1
  213. package/dist/mock/mock-server.js +0 -499
  214. package/dist/mock/mock-server.js.map +0 -1
  215. package/dist/mock/mock-storage.js +0 -186
  216. package/dist/mock/mock-storage.js.map +0 -1
  217. package/dist/mock/mock-supported.js +0 -63
  218. package/dist/mock/mock-supported.js.map +0 -1
  219. package/dist/mock-dep-resolve.js +0 -47
  220. package/dist/mock-dep-resolve.js.map +0 -1
  221. package/dist/mock-local-deps.js +0 -207
  222. package/dist/mock-local-deps.js.map +0 -1
  223. package/dist/network-error.js +0 -11
  224. package/dist/network-error.js.map +0 -1
  225. package/dist/node-engine.js +0 -21
  226. package/dist/node-engine.js.map +0 -1
  227. package/dist/oauth-provider.js +0 -107
  228. package/dist/oauth-provider.js.map +0 -1
  229. package/dist/onboarding-prompt.js +0 -15
  230. package/dist/onboarding-prompt.js.map +0 -1
  231. package/dist/open-api-client.js +0 -432
  232. package/dist/open-api-client.js.map +0 -1
  233. package/dist/open-url.js +0 -21
  234. package/dist/open-url.js.map +0 -1
  235. package/dist/org-resolve.js +0 -16
  236. package/dist/org-resolve.js.map +0 -1
  237. package/dist/org-slug.js +0 -11
  238. package/dist/org-slug.js.map +0 -1
  239. package/dist/org.js +0 -100
  240. package/dist/org.js.map +0 -1
  241. package/dist/package-app-dev.js +0 -905
  242. package/dist/package-app-dev.js.map +0 -1
  243. package/dist/package-collaborators.js +0 -179
  244. package/dist/package-collaborators.js.map +0 -1
  245. package/dist/package-info.js +0 -19
  246. package/dist/package-info.js.map +0 -1
  247. package/dist/package-local-runtime-source.js.map +0 -1
  248. package/dist/package-manifest.js +0 -364
  249. package/dist/package-manifest.js.map +0 -1
  250. package/dist/process-info.js +0 -14
  251. package/dist/process-info.js.map +0 -1
  252. package/dist/redact.js +0 -16
  253. package/dist/redact.js.map +0 -1
  254. package/dist/remote-execute.js +0 -108
  255. package/dist/remote-execute.js.map +0 -1
  256. package/dist/setup-git.js +0 -676
  257. package/dist/setup-git.js.map +0 -1
  258. package/dist/skill.js +0 -35
  259. package/dist/skill.js.map +0 -1
  260. package/dist/store.js +0 -597
  261. package/dist/store.js.map +0 -1
  262. package/dist/structured-error.js +0 -57
  263. package/dist/structured-error.js.map +0 -1
  264. package/dist/target.js +0 -52
  265. package/dist/target.js.map +0 -1
  266. package/dist/tool-result.js +0 -19
  267. package/dist/tool-result.js.map +0 -1
  268. package/dist/which.js +0 -22
  269. package/dist/which.js.map +0 -1
  270. package/dist/workerd-binary.js +0 -98
  271. package/dist/workerd-binary.js.map +0 -1
@@ -0,0 +1,948 @@
1
+ import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
+ import {
3
+ which
4
+ } from "./chunk-6XQP5SWX.js";
5
+ import {
6
+ OpenApiError,
7
+ openApiGet,
8
+ openApiRequest
9
+ } from "./chunk-FBVNFWR6.js";
10
+ import {
11
+ assertTokenSafeApiUrl,
12
+ capabilityProxyUrl
13
+ } from "./chunk-R4IUV5P5.js";
14
+ import {
15
+ describeNetworkError
16
+ } from "./chunk-G4YN6XP5.js";
17
+ import {
18
+ readPackageVersion
19
+ } from "./chunk-G6LJWROP.js";
20
+ import {
21
+ deleteStoredApiToken,
22
+ loadStoredApiToken,
23
+ saveStoredApiToken
24
+ } from "./chunk-RTWUNV76.js";
25
+ import {
26
+ apiTokenEnvVar,
27
+ cliName,
28
+ defaultApiUrl,
29
+ defaultMcpUrl
30
+ } from "./chunk-IHP6PV6X.js";
31
+
32
+ // src/setup-git.ts
33
+ import { spawnSync } from "node:child_process";
34
+ import { createRequire } from "node:module";
35
+
36
+ // src/http-error-body.ts
37
+ var nonJsonErrorBodyMaxChars = 200;
38
+ function summarizeNonJsonErrorBody(text) {
39
+ const trimmed = text.trim();
40
+ const looksLikeHtml = /^<(?:!doctype|html|head|body)\b/i.test(trimmed);
41
+ const title = looksLikeHtml ? trimmed.match(/<title[^>]*>([\s\S]*?)<\/title>/i)?.[1] : void 0;
42
+ const excerpt = collapseWhitespace(
43
+ looksLikeHtml ? stripHtml(title?.trim() ? title : trimmed) : trimmed
44
+ );
45
+ const kind = looksLikeHtml ? "HTML" : "non-JSON";
46
+ const bytes = Buffer.byteLength(text);
47
+ if (excerpt.length <= nonJsonErrorBodyMaxChars && !looksLikeHtml) return excerpt;
48
+ const shortened = excerpt.length > nonJsonErrorBodyMaxChars ? `${excerpt.slice(0, nonJsonErrorBodyMaxChars).trimEnd()}\u2026` : excerpt;
49
+ return `${shortened ? `${shortened} ` : ""}(${kind} response, ${bytes} bytes; check --api-url / KODY_API_URL points at the Kody API host)`;
50
+ }
51
+ function stripHtml(html) {
52
+ return html.replace(/<(script|style)\b[\s\S]*?<\/\1>/gi, " ").replace(/<[^>]+>/g, " ").replace(/&nbsp;/g, " ").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&amp;/g, "&");
53
+ }
54
+ function collapseWhitespace(text) {
55
+ return text.replace(/\s+/g, " ").trim();
56
+ }
57
+
58
+ // src/auth-bootstrap.ts
59
+ var cliBootstrapCodePrefix = "kody_bc_";
60
+ var bootstrapCodePattern = /^kody_bc_([a-z0-9]{16})_([A-Za-z0-9_-]{32})$/;
61
+ var bootstrapRedeemPath = "v1/tokens/bootstrap/redeem";
62
+ var cliTokenLifetimePolicy = {
63
+ minIdleTtlSeconds: 60,
64
+ /** Idle timeout at most 14 days. */
65
+ maxIdleTtlSeconds: 14 * 24 * 60 * 60,
66
+ /** Absolute lifetime at most 3 months. */
67
+ maxMaxLifetimeSeconds: 90 * 24 * 60 * 60
68
+ };
69
+ var cliTokenLifetimeAliases = {
70
+ short: {
71
+ idleTtlSeconds: 60 * 60,
72
+ maxLifetimeSeconds: 24 * 60 * 60
73
+ },
74
+ long: {
75
+ idleTtlSeconds: cliTokenLifetimePolicy.maxIdleTtlSeconds,
76
+ maxLifetimeSeconds: cliTokenLifetimePolicy.maxMaxLifetimeSeconds
77
+ }
78
+ };
79
+ function parseCliBootstrapCode(value) {
80
+ const match = bootstrapCodePattern.exec(value.trim());
81
+ if (!match) return null;
82
+ const [, codeId, secret] = match;
83
+ if (!codeId || !secret) return null;
84
+ return { codeId, secret };
85
+ }
86
+ function assertCliBootstrapCode(code) {
87
+ const trimmed = code.trim();
88
+ if (!parseCliBootstrapCode(trimmed)) {
89
+ throw new Error(
90
+ `Invalid bootstrap code. Expected a one-shot ${cliBootstrapCodePrefix}\u2026 from cliCredentialBootstrap (MCP api / kody.cliCredentialBootstrap).`
91
+ );
92
+ }
93
+ return trimmed;
94
+ }
95
+ function cliTokenLifetimeMissingError() {
96
+ return `Token lifetime is required. Pass --lifetime short|long, or both --idle-ttl-seconds <n> and --max-lifetime-seconds <n> (idle ${cliTokenLifetimePolicy.minIdleTtlSeconds}-${cliTokenLifetimePolicy.maxIdleTtlSeconds}s, max age up to ${cliTokenLifetimePolicy.maxMaxLifetimeSeconds}s). Single-task agents should use --lifetime short.`;
97
+ }
98
+ function resolveCliTokenLifetime(input) {
99
+ const aliasRaw = typeof input.lifetime === "string" ? input.lifetime.trim() : "";
100
+ const hasAlias = aliasRaw.length > 0;
101
+ const hasIdle = input.idleTtlSeconds !== void 0;
102
+ const hasMax = input.maxLifetimeSeconds !== void 0;
103
+ if (!hasAlias && !hasIdle && !hasMax) {
104
+ throw new Error(cliTokenLifetimeMissingError());
105
+ }
106
+ if (hasAlias && (hasIdle || hasMax)) {
107
+ throw new Error(
108
+ "Pass --lifetime short|long, or both --idle-ttl-seconds and --max-lifetime-seconds, not both forms."
109
+ );
110
+ }
111
+ if (hasAlias) {
112
+ if (!(aliasRaw in cliTokenLifetimeAliases)) {
113
+ throw new Error(
114
+ `--lifetime must be short or long (got ${JSON.stringify(aliasRaw)}).`
115
+ );
116
+ }
117
+ const lifetime = aliasRaw;
118
+ const resolved = cliTokenLifetimeAliases[lifetime];
119
+ return {
120
+ kind: "alias",
121
+ lifetime,
122
+ idleTtlSeconds: resolved.idleTtlSeconds,
123
+ maxLifetimeSeconds: resolved.maxLifetimeSeconds
124
+ };
125
+ }
126
+ if (!hasIdle || !hasMax) {
127
+ throw new Error(
128
+ "When not using --lifetime short|long, both --idle-ttl-seconds and --max-lifetime-seconds are required."
129
+ );
130
+ }
131
+ const idleTtlSeconds = readRequiredInteger({
132
+ value: input.idleTtlSeconds,
133
+ min: cliTokenLifetimePolicy.minIdleTtlSeconds,
134
+ max: cliTokenLifetimePolicy.maxIdleTtlSeconds,
135
+ field: "--idle-ttl-seconds"
136
+ });
137
+ const maxLifetimeSeconds = readRequiredInteger({
138
+ value: input.maxLifetimeSeconds,
139
+ min: idleTtlSeconds,
140
+ max: cliTokenLifetimePolicy.maxMaxLifetimeSeconds,
141
+ field: "--max-lifetime-seconds"
142
+ });
143
+ return {
144
+ kind: "explicit",
145
+ idleTtlSeconds,
146
+ maxLifetimeSeconds
147
+ };
148
+ }
149
+ function bootstrapRedeemRequestBody(code, lifetime) {
150
+ if (lifetime.kind === "alias") {
151
+ return { code, lifetime: lifetime.lifetime };
152
+ }
153
+ return {
154
+ code,
155
+ idle_ttl_seconds: lifetime.idleTtlSeconds,
156
+ max_lifetime_seconds: lifetime.maxLifetimeSeconds
157
+ };
158
+ }
159
+ function parseCliLifetimeSecondsFlag(raw, flag) {
160
+ if (raw === void 0) return void 0;
161
+ const trimmed = raw.trim();
162
+ if (!/^-?\d+$/.test(trimmed)) {
163
+ throw new Error(`${flag} must be an integer.`);
164
+ }
165
+ return Number(trimmed);
166
+ }
167
+ function resolveMintedRedeemLifetime(minted) {
168
+ const maxLifetimeSeconds = minted.max_lifetime_seconds;
169
+ const idleTtlSeconds = Math.min(minted.idle_ttl_seconds, maxLifetimeSeconds);
170
+ return {
171
+ kind: "explicit",
172
+ idleTtlSeconds,
173
+ maxLifetimeSeconds
174
+ };
175
+ }
176
+ async function redeemBootstrapCode(input) {
177
+ const code = assertCliBootstrapCode(input.code);
178
+ const lifetime = input.trustedMintLifetime ? resolveMintedRedeemLifetime(input.trustedMintLifetime) : resolveCliTokenLifetime({
179
+ lifetime: input.lifetime,
180
+ idleTtlSeconds: input.idleTtlSeconds,
181
+ maxLifetimeSeconds: input.maxLifetimeSeconds
182
+ });
183
+ const apiUrl = input.apiUrl || defaultApiUrl;
184
+ assertTokenSafeApiUrl(apiUrl);
185
+ const url = capabilityProxyUrl(apiUrl, bootstrapRedeemPath);
186
+ const fetchFn = input.fetchFn ?? fetch;
187
+ let response;
188
+ try {
189
+ response = await fetchFn(url, {
190
+ method: "POST",
191
+ headers: {
192
+ accept: "application/json",
193
+ "content-type": "application/json",
194
+ "user-agent": `${cliName}/${readPackageVersion()}`
195
+ },
196
+ body: JSON.stringify(bootstrapRedeemRequestBody(code, lifetime))
197
+ });
198
+ } catch (error) {
199
+ const reason = describeNetworkError(error);
200
+ throw new Error(
201
+ `Could not reach the Kody API at ${url.origin} (${reason}). Check --api-url / KODY_API_URL and your network.`
202
+ );
203
+ }
204
+ const body = await readJson(response);
205
+ if (!response.ok) {
206
+ throw describeRedeemFailure(response.status, body, url);
207
+ }
208
+ return parseRedeemResponse(body);
209
+ }
210
+ function storedApiTokenFromRedeem(input) {
211
+ const token = input.redeemed.token.trim();
212
+ if (!token.startsWith("kody_at_")) {
213
+ throw new Error("Bootstrap redeem did not return a scoped kody_at_\u2026 API token.");
214
+ }
215
+ return {
216
+ version: 1,
217
+ apiUrl: input.apiUrl,
218
+ token,
219
+ tokenId: input.redeemed.id,
220
+ ...input.redeemed.name ? { name: input.redeemed.name } : {},
221
+ ...Array.isArray(input.redeemed.scopes) ? { scopes: input.redeemed.scopes } : {},
222
+ expiresAt: input.redeemed.expires_at ?? null,
223
+ maxExpiresAt: input.redeemed.max_expires_at ?? null,
224
+ createdVia: input.redeemed.created_via ?? "cli-bootstrap"
225
+ };
226
+ }
227
+ async function authBootstrap(input) {
228
+ const apiUrl = input.apiUrl || defaultApiUrl;
229
+ const redeemed = await redeemBootstrapCode({
230
+ code: input.code,
231
+ lifetime: input.lifetime,
232
+ idleTtlSeconds: input.idleTtlSeconds,
233
+ maxLifetimeSeconds: input.maxLifetimeSeconds,
234
+ apiUrl,
235
+ fetchFn: input.fetchFn
236
+ });
237
+ const stored = storedApiTokenFromRedeem({ apiUrl, redeemed });
238
+ const saved = saveStoredApiToken(stored, input.backend, input.resolution);
239
+ return {
240
+ stored,
241
+ backendKind: saved.backend.kind,
242
+ ...saved.backend.path ? { backendPath: saved.backend.path } : {}
243
+ };
244
+ }
245
+ var cliCredentialBootstrapOperationId = "cliCredentialBootstrap";
246
+ function parseCliScopesFlag(raw) {
247
+ if (raw === void 0) return void 0;
248
+ const scopes = [
249
+ ...new Set(
250
+ raw.split(/[\s,]+/).map((scope) => scope.trim()).filter(Boolean)
251
+ )
252
+ ];
253
+ if (scopes.length === 0) {
254
+ throw new Error("--scopes needs at least one scope (e.g. --scopes org:execute,package:write).");
255
+ }
256
+ return scopes;
257
+ }
258
+ function bootstrapMintParams(scopes, lifetime) {
259
+ return {
260
+ scopes: [...scopes],
261
+ ...bootstrapMintLifetimeFields(lifetime)
262
+ };
263
+ }
264
+ function bootstrapMintLifetimeFields(lifetime) {
265
+ return lifetime.kind === "alias" ? { lifetime: lifetime.lifetime } : {
266
+ idle_ttl_seconds: lifetime.idleTtlSeconds,
267
+ max_lifetime_seconds: lifetime.maxLifetimeSeconds
268
+ };
269
+ }
270
+ function parseBootstrapMintResponse(body) {
271
+ if (!isRecord(body) || typeof body.bootstrap_code !== "string" || typeof body.idle_ttl_seconds !== "number" || typeof body.max_lifetime_seconds !== "number") {
272
+ throw new Error("cliCredentialBootstrap returned an unexpected response.");
273
+ }
274
+ return {
275
+ bootstrap_code: body.bootstrap_code,
276
+ scopes: Array.isArray(body.scopes) ? body.scopes.filter((scope) => typeof scope === "string") : [],
277
+ idle_ttl_seconds: body.idle_ttl_seconds,
278
+ max_lifetime_seconds: body.max_lifetime_seconds
279
+ };
280
+ }
281
+ async function authBootstrapWithScopes(input) {
282
+ const minted = parseBootstrapMintResponse(
283
+ await input.mint(bootstrapMintParams(input.scopes, input.lifetime))
284
+ );
285
+ const apiUrl = input.apiUrl || defaultApiUrl;
286
+ const redeemed = await redeemBootstrapCode({
287
+ code: minted.bootstrap_code,
288
+ trustedMintLifetime: {
289
+ idle_ttl_seconds: minted.idle_ttl_seconds,
290
+ max_lifetime_seconds: minted.max_lifetime_seconds
291
+ },
292
+ apiUrl,
293
+ fetchFn: input.fetchFn
294
+ });
295
+ const stored = storedApiTokenFromRedeem({ apiUrl, redeemed });
296
+ const saved = saveStoredApiToken(stored, input.backend, input.resolution);
297
+ return {
298
+ stored,
299
+ backendKind: saved.backend.kind,
300
+ ...saved.backend.path ? { backendPath: saved.backend.path } : {}
301
+ };
302
+ }
303
+ function readRequiredInteger(input) {
304
+ if (!Number.isInteger(input.value) || input.value < input.min || input.value > input.max) {
305
+ throw new Error(
306
+ `${input.field} must be an integer between ${input.min} and ${input.max}.`
307
+ );
308
+ }
309
+ return input.value;
310
+ }
311
+ function parseRedeemResponse(body) {
312
+ if (!isRecord(body) || typeof body.token !== "string" || typeof body.id !== "string") {
313
+ throw new Error("Bootstrap redeem returned an unexpected response.");
314
+ }
315
+ return {
316
+ token: body.token,
317
+ token_type: typeof body.token_type === "string" ? body.token_type : void 0,
318
+ id: body.id,
319
+ name: typeof body.name === "string" ? body.name : null,
320
+ scopes: Array.isArray(body.scopes) ? body.scopes.filter((scope) => typeof scope === "string") : void 0,
321
+ status: typeof body.status === "string" ? body.status : void 0,
322
+ idle_ttl_seconds: typeof body.idle_ttl_seconds === "number" ? body.idle_ttl_seconds : void 0,
323
+ expires_at: typeof body.expires_at === "string" ? body.expires_at : null,
324
+ max_expires_at: typeof body.max_expires_at === "string" ? body.max_expires_at : null,
325
+ created_via: typeof body.created_via === "string" ? body.created_via : void 0
326
+ };
327
+ }
328
+ function describeRedeemFailure(status, body, url) {
329
+ const failure = readErrorBody(body);
330
+ const detail = failure?.message ? ` Server said: ${failure.message}` : "";
331
+ if (status === 400 || status === 401 || status === 403 || status === 404) {
332
+ return new Error(
333
+ `Bootstrap redeem failed (HTTP ${status}). The code may be invalid, expired, or already used. Call cliCredentialBootstrap again for a fresh code.${detail}`
334
+ );
335
+ }
336
+ return new Error(
337
+ failure?.message ?? `Bootstrap redeem failed with HTTP ${status} (${url.pathname}).${detail}`
338
+ );
339
+ }
340
+ async function readJson(response) {
341
+ const text = await response.text();
342
+ if (!text) return null;
343
+ try {
344
+ return JSON.parse(text);
345
+ } catch {
346
+ return text;
347
+ }
348
+ }
349
+ function readErrorBody(body) {
350
+ if (!isRecord(body) || body.error == null) {
351
+ if (typeof body === "string" && body.trim()) {
352
+ return { code: null, message: summarizeNonJsonErrorBody(body) };
353
+ }
354
+ if (isRecord(body) && typeof body.message === "string") {
355
+ return { code: null, message: body.message };
356
+ }
357
+ return null;
358
+ }
359
+ const { error } = body;
360
+ if (typeof error === "string") return { code: null, message: error };
361
+ if (isRecord(error)) {
362
+ const code = typeof error.code === "string" ? error.code : null;
363
+ const message = typeof error.message === "string" ? error.message : code ?? JSON.stringify(error);
364
+ return { code, message };
365
+ }
366
+ return { code: null, message: String(error) };
367
+ }
368
+ function isRecord(value) {
369
+ return value !== null && typeof value === "object" && !Array.isArray(value);
370
+ }
371
+
372
+ // src/setup-git.ts
373
+ var setupGitRequiredScopes = ["package:read", "package:write"];
374
+ var setupGitDefaultScopes = [
375
+ "app:execute",
376
+ "app:read",
377
+ "email:read",
378
+ "email:send",
379
+ "integration:read",
380
+ "integration:use",
381
+ "job:execute",
382
+ "job:read",
383
+ "memory:read",
384
+ "org:execute",
385
+ "org:read",
386
+ "package:execute",
387
+ "package:read",
388
+ "package:write",
389
+ "secret:use",
390
+ "token:delete"
391
+ ];
392
+ function gitCredentialHostFromMcpUrl(mcpUrl = defaultMcpUrl) {
393
+ return new URL(mcpUrl).host;
394
+ }
395
+ function scopesIncludeRequired(scopes, required = setupGitRequiredScopes) {
396
+ if (!scopes) return false;
397
+ const held = new Set(scopes);
398
+ return required.every((scope) => held.has(scope));
399
+ }
400
+ function ensureSetupGitScopes(base = setupGitDefaultScopes) {
401
+ const out = [...base];
402
+ for (const required of setupGitRequiredScopes) {
403
+ if (!out.includes(required)) out.push(required);
404
+ }
405
+ return out;
406
+ }
407
+ async function fetchTokenCurrentMetadata(input) {
408
+ const apiUrl = input.apiUrl || defaultApiUrl;
409
+ const current = await openApiGet({
410
+ token: input.token,
411
+ apiUrl,
412
+ path: "v1/tokens/current",
413
+ fetchFn: input.fetchFn
414
+ });
415
+ const orgBindingRaw = current.org_binding;
416
+ const orgBinding = orgBindingRaw === "user" || orgBindingRaw === "org" ? orgBindingRaw : null;
417
+ return {
418
+ id: String(current.id ?? ""),
419
+ orgBinding,
420
+ scopes: Array.isArray(current.scopes) ? current.scopes.filter((scope) => typeof scope === "string") : [],
421
+ expiresAt: typeof current.expires_at === "string" ? current.expires_at : null
422
+ };
423
+ }
424
+ function assertUserOwnedTokensLive(metadata) {
425
+ if (metadata.orgBinding === null) {
426
+ throw new Error(
427
+ "This Kody origin does not advertise user-owned API tokens (`org_binding` missing on GET /v1/tokens/current). Upgrade the server (kody auth setup-git / persistent git HTTPS) before installing the credential helper."
428
+ );
429
+ }
430
+ }
431
+ function decideSetupGitToken(input) {
432
+ const lifetime = input.lifetime ?? resolveCliTokenLifetime({ lifetime: "long" });
433
+ if (input.stored && input.metadata && input.metadata.orgBinding === "user" && scopesIncludeRequired(input.metadata.scopes) && !input.scopesOverride) {
434
+ return { action: "reuse", stored: input.stored, metadata: input.metadata };
435
+ }
436
+ const scopes = ensureSetupGitScopes(
437
+ input.scopesOverride ?? input.metadata?.scopes ?? input.stored?.scopes ?? setupGitDefaultScopes
438
+ );
439
+ const reason = !input.stored ? "No stored API token yet." : input.metadata?.orgBinding !== "user" ? "Stored token is not user-owned (`org_binding` must be `user`)." : !scopesIncludeRequired(input.metadata?.scopes) ? "Stored token is missing package:read and/or package:write." : "Minting with the requested --scopes list.";
440
+ return { action: "mint", scopes, lifetime, reason };
441
+ }
442
+ function defaultGitConfigRunner(args) {
443
+ const result = spawnSync("git", [...args], {
444
+ encoding: "utf8",
445
+ env: process.env
446
+ });
447
+ if (result.error) {
448
+ return { status: 1, stderr: result.error.message };
449
+ }
450
+ return {
451
+ status: result.status ?? 1,
452
+ stderr: (result.stderr || "").trim()
453
+ };
454
+ }
455
+ function installGitCredentialConfig(input) {
456
+ const runGit = input.runGit ?? defaultGitConfigRunner;
457
+ const scope = input.global === false ? "--local" : "--global";
458
+ const helperKey = `credential.https://${input.host}.helper`;
459
+ const pathKey = `credential.https://${input.host}.useHttpPath`;
460
+ for (const [key, value] of [
461
+ [helperKey, input.helperCommand],
462
+ [pathKey, "true"]
463
+ ]) {
464
+ const result = runGit(["config", scope, key, value]);
465
+ if (result.status !== 0) {
466
+ throw new Error(
467
+ `git config ${scope} ${key} failed${result.stderr ? `: ${result.stderr}` : ""}. Is git installed?`
468
+ );
469
+ }
470
+ }
471
+ return { host: input.host, helperCommand: input.helperCommand, scope };
472
+ }
473
+ var gitApiTokenRefreshSkewMs = 60 * 60 * 1e3;
474
+ var gitCredentialMinCliVersion = "1.16.0";
475
+ var gitCredentialHelperPinFallbackVersion = "1.18.0";
476
+ var requireFromSetupGit = createRequire(import.meta.url);
477
+ function readCliPackageVersion() {
478
+ try {
479
+ const pkg = requireFromSetupGit("../package.json");
480
+ return typeof pkg.version === "string" ? pkg.version : gitCredentialHelperPinFallbackVersion;
481
+ } catch {
482
+ return gitCredentialHelperPinFallbackVersion;
483
+ }
484
+ }
485
+ function isEphemeralNpxEntryPath(entryPath) {
486
+ const normalized = entryPath.replace(/\\/g, "/");
487
+ return normalized.includes("/.npm/_npx/") || normalized.includes("/npm/_npx/") || /\/_npx\//.test(normalized);
488
+ }
489
+ function parseCliSemver(version) {
490
+ const match = /^(\d+)\.(\d+)\.(\d+)/.exec(version.trim());
491
+ if (!match) return null;
492
+ return {
493
+ major: Number(match[1]),
494
+ minor: Number(match[2]),
495
+ patch: Number(match[3])
496
+ };
497
+ }
498
+ function compareCliSemver(a, b) {
499
+ if (a.major !== b.major) return a.major < b.major ? -1 : 1;
500
+ if (a.minor !== b.minor) return a.minor < b.minor ? -1 : 1;
501
+ if (a.patch !== b.patch) return a.patch < b.patch ? -1 : 1;
502
+ return 0;
503
+ }
504
+ function cliVersionGte(version, minimum) {
505
+ const left = parseCliSemver(version);
506
+ const right = parseCliSemver(minimum);
507
+ if (!left || !right) return false;
508
+ return compareCliSemver(left, right) >= 0;
509
+ }
510
+ function cliVersionGt(version, other) {
511
+ const left = parseCliSemver(version);
512
+ const right = parseCliSemver(other);
513
+ if (!left || !right) return false;
514
+ return compareCliSemver(left, right) > 0;
515
+ }
516
+ function cliVersionSupportsGitCredential(version) {
517
+ return cliVersionGte(version, gitCredentialMinCliVersion);
518
+ }
519
+ function cliExactVersionForNpx(packageVersion) {
520
+ const parsed = parseCliSemver(packageVersion);
521
+ if (parsed && parsed.major >= 1) {
522
+ return `${parsed.major}.${parsed.minor}.${parsed.patch}`;
523
+ }
524
+ return gitCredentialHelperPinFallbackVersion;
525
+ }
526
+ function cliMajorVersionForNpx(packageVersion) {
527
+ return cliExactVersionForNpx(packageVersion);
528
+ }
529
+ function apiTokenNeedsRefresh(stored, nowMs = Date.now(), skewMs = gitApiTokenRefreshSkewMs) {
530
+ if (!stored) return true;
531
+ if (stored.expiresAt == null || stored.expiresAt === "") return false;
532
+ const expiresMs = Date.parse(stored.expiresAt);
533
+ if (!Number.isFinite(expiresMs)) return true;
534
+ return expiresMs - nowMs <= skewMs;
535
+ }
536
+ function readVersionFromKodyBinary(binPath, args = ["--version"]) {
537
+ const result = spawnSync(binPath, [...args], {
538
+ encoding: "utf8",
539
+ env: {
540
+ ...process.env,
541
+ KODY_SKIP_GIT_HELPER_REFRESH: "1"
542
+ },
543
+ timeout: 8e3
544
+ });
545
+ if (result.error || (result.status ?? 1) !== 0) return null;
546
+ const text = `${result.stdout || ""}
547
+ ${result.stderr || ""}`;
548
+ const match = /(\d+\.\d+\.\d+)/.exec(text);
549
+ return match?.[1] ?? null;
550
+ }
551
+ function defaultReadGlobalKodyVersion(binPath) {
552
+ return readVersionFromKodyBinary(binPath);
553
+ }
554
+ function gitCredentialHelperCommand(input) {
555
+ const env = input?.env ?? process.env;
556
+ const whichFn = input?.which ?? which;
557
+ const entryPath = input?.entryPath ?? process.argv[1];
558
+ const readVersion = input?.readKodyVersion ?? defaultReadGlobalKodyVersion;
559
+ const globalKody = whichFn("kody", env);
560
+ if (globalKody && !isEphemeralNpxEntryPath(globalKody)) {
561
+ const globalVersion = readVersion(globalKody);
562
+ if (globalVersion && cliVersionSupportsGitCredential(globalVersion)) {
563
+ return `!${shellQuote(globalKody)} git-credential`;
564
+ }
565
+ }
566
+ if (entryPath && entryPath.length > 0 && !isEphemeralNpxEntryPath(entryPath)) {
567
+ const execPath = input?.execPath ?? process.execPath;
568
+ return `!${shellQuote(execPath)} ${shellQuote(entryPath)} git-credential`;
569
+ }
570
+ const exact = cliExactVersionForNpx(
571
+ input?.packageVersion ?? readCliPackageVersion()
572
+ );
573
+ return `!npx -y ${cliName}@${exact} git-credential`;
574
+ }
575
+ function shellQuote(value) {
576
+ if (/^[A-Za-z0-9_./:@+=,-]+$/.test(value)) return value;
577
+ return `'${value.replace(/'/g, `'\\''`)}'`;
578
+ }
579
+ function isMajorOnlyNpxHelper(helper) {
580
+ return /@kodycodes\/cli@\d+(?![\.\d])/.test(helper);
581
+ }
582
+ function exactNpxHelperVersion(helper) {
583
+ const match = /@kodycodes\/cli@(\d+\.\d+\.\d+)/.exec(helper);
584
+ return match?.[1] ?? null;
585
+ }
586
+ function gitCredentialHelperNeedsRepair(input) {
587
+ const helper = input.helper?.trim();
588
+ if (!helper) return false;
589
+ if (isEphemeralNpxEntryPath(helper)) return true;
590
+ if (isMajorOnlyNpxHelper(helper)) return true;
591
+ const pinned = exactNpxHelperVersion(helper);
592
+ if (pinned) {
593
+ if (!cliVersionSupportsGitCredential(pinned)) return true;
594
+ const current = cliExactVersionForNpx(
595
+ input.packageVersion ?? readCliPackageVersion()
596
+ );
597
+ return cliVersionGt(current, pinned);
598
+ }
599
+ if (input.probeBinaryVersion !== true) {
600
+ return false;
601
+ }
602
+ const readVersion = input.readKodyVersion ?? defaultReadGlobalKodyVersion;
603
+ const bang = helper.startsWith("!") ? helper.slice(1).trim() : helper.trim();
604
+ const parts = bang.split(/\s+/).filter(Boolean);
605
+ if (parts.length >= 2 && parts[parts.length - 1] === "git-credential") {
606
+ const invocation = parts.slice(0, -1);
607
+ if (invocation.length === 1) {
608
+ const version = readVersion(invocation[0]);
609
+ if (version && !cliVersionSupportsGitCredential(version)) return true;
610
+ } else if (invocation.length >= 2) {
611
+ const version = readVersionFromKodyBinary(invocation[0], [
612
+ ...invocation.slice(1),
613
+ "--version"
614
+ ]);
615
+ if (version && !cliVersionSupportsGitCredential(version)) return true;
616
+ }
617
+ }
618
+ return false;
619
+ }
620
+ function defaultGitConfigGetRunner(args) {
621
+ const result = spawnSync("git", [...args], {
622
+ encoding: "utf8",
623
+ env: process.env
624
+ });
625
+ if (result.error) {
626
+ return { status: 1, stdout: "", stderr: result.error.message };
627
+ }
628
+ return {
629
+ status: result.status ?? 1,
630
+ stdout: (result.stdout || "").trim(),
631
+ stderr: (result.stderr || "").trim()
632
+ };
633
+ }
634
+ function refreshGitCredentialHelperPinIfNeeded(input) {
635
+ const mcpUrl = input?.mcpUrl || defaultMcpUrl;
636
+ const host = gitCredentialHostFromMcpUrl(mcpUrl);
637
+ const scope = input?.global === false ? "--local" : "--global";
638
+ const runGet = input?.runGitGet ?? defaultGitConfigGetRunner;
639
+ const helperKey = `credential.https://${host}.helper`;
640
+ const got = runGet(["config", scope, "--get", helperKey]);
641
+ if (got.status !== 0 || !got.stdout) return false;
642
+ const packageVersion = input?.packageVersion ?? readCliPackageVersion();
643
+ if (!gitCredentialHelperNeedsRepair({
644
+ helper: got.stdout,
645
+ packageVersion,
646
+ readKodyVersion: input?.readKodyVersion,
647
+ probeBinaryVersion: input?.probeBinaryVersion === true
648
+ })) {
649
+ return false;
650
+ }
651
+ const helperCommand = input?.helperCommand ?? gitCredentialHelperCommand({
652
+ packageVersion,
653
+ which: input?.which,
654
+ execPath: input?.execPath,
655
+ entryPath: input?.entryPath,
656
+ env: input?.env,
657
+ readKodyVersion: input?.readKodyVersion
658
+ });
659
+ if (helperCommand === got.stdout) return false;
660
+ installGitCredentialConfig({
661
+ host,
662
+ helperCommand,
663
+ global: input?.global,
664
+ runGit: input?.runGit
665
+ });
666
+ return true;
667
+ }
668
+ async function authSetupGit(input) {
669
+ const apiUrl = input.apiUrl || defaultApiUrl;
670
+ const mcpUrl = input.mcpUrl || defaultMcpUrl;
671
+ const host = gitCredentialHostFromMcpUrl(mcpUrl);
672
+ const storedExisting = loadStoredApiToken(apiUrl, input.backend, input.resolution);
673
+ const probeToken = input.token || storedExisting?.token;
674
+ const hasLoginSession = input.hasLoginSession === true;
675
+ if (!probeToken && !hasLoginSession) {
676
+ throw new Error(
677
+ `setup-git needs a Kody credential to detect server support and mint a token. Run \`kody login\`, or set ${apiTokenEnvVar}, or pass --token.`
678
+ );
679
+ }
680
+ let probeMetadata = null;
681
+ if (probeToken) {
682
+ try {
683
+ probeMetadata = await fetchTokenCurrentMetadata({
684
+ token: probeToken,
685
+ apiUrl,
686
+ fetchFn: input.fetchFn
687
+ });
688
+ } catch (error) {
689
+ if (error instanceof OpenApiError && error.status === 401) {
690
+ throw new Error(
691
+ `Could not read token metadata from ${apiUrl} (unauthorized). Run \`kody login\` or pass a valid --token / ${apiTokenEnvVar}.`
692
+ );
693
+ }
694
+ throw error;
695
+ }
696
+ assertUserOwnedTokensLive(probeMetadata);
697
+ }
698
+ let storedMetadata = null;
699
+ if (storedExisting) {
700
+ if (probeMetadata && storedExisting.token === probeToken) {
701
+ storedMetadata = probeMetadata;
702
+ } else {
703
+ try {
704
+ storedMetadata = await fetchTokenCurrentMetadata({
705
+ token: storedExisting.token,
706
+ apiUrl,
707
+ fetchFn: input.fetchFn
708
+ });
709
+ } catch {
710
+ storedMetadata = null;
711
+ }
712
+ }
713
+ }
714
+ const decision = decideSetupGitToken({
715
+ stored: storedExisting,
716
+ metadata: storedMetadata,
717
+ scopesOverride: input.scopesOverride,
718
+ lifetime: input.lifetime
719
+ });
720
+ let stored;
721
+ let minted = false;
722
+ let backendKind;
723
+ let backendPath;
724
+ let finalMetadata;
725
+ if (decision.action === "reuse") {
726
+ stored = decision.stored;
727
+ backendKind = "existing";
728
+ finalMetadata = decision.metadata;
729
+ } else {
730
+ const result = await authBootstrapWithScopes({
731
+ scopes: decision.scopes,
732
+ lifetime: decision.lifetime,
733
+ mint: input.mint,
734
+ apiUrl,
735
+ fetchFn: input.fetchFn,
736
+ backend: input.backend,
737
+ resolution: input.resolution
738
+ });
739
+ stored = result.stored;
740
+ minted = true;
741
+ backendKind = result.backendKind;
742
+ backendPath = result.backendPath;
743
+ const after = await fetchTokenCurrentMetadata({
744
+ token: stored.token,
745
+ apiUrl,
746
+ fetchFn: input.fetchFn
747
+ });
748
+ assertUserOwnedTokensLive(after);
749
+ if (after.orgBinding !== "user") {
750
+ throw new Error(
751
+ `Minted token ${stored.tokenId} has org_binding=${JSON.stringify(after.orgBinding)}; expected "user". Refusing to install the git helper.`
752
+ );
753
+ }
754
+ if (!scopesIncludeRequired(after.scopes)) {
755
+ throw new Error(
756
+ `Minted token ${stored.tokenId} is missing package:read and/or package:write. Pass --scopes that include both.`
757
+ );
758
+ }
759
+ finalMetadata = after;
760
+ }
761
+ const helperCommand = input.helperCommand ?? gitCredentialHelperCommand();
762
+ installGitCredentialConfig({
763
+ host,
764
+ helperCommand,
765
+ global: input.global,
766
+ runGit: input.runGit
767
+ });
768
+ return {
769
+ host,
770
+ helperCommand,
771
+ tokenId: stored.tokenId,
772
+ scopes: finalMetadata.scopes,
773
+ orgBinding: "user",
774
+ minted,
775
+ backendKind,
776
+ ...backendPath ? { backendPath } : {},
777
+ expiresAt: finalMetadata.expiresAt
778
+ };
779
+ }
780
+ var setupGitConfigScopes = ["--global", "--local"];
781
+ function isKodyGitCredentialHelperValue(value) {
782
+ const v = value.trim();
783
+ if (!v) return false;
784
+ if (v.includes("@kodycodes/cli")) return true;
785
+ if (isEphemeralNpxEntryPath(v)) return true;
786
+ if (/\bgit-credential\b/.test(v) && /(^|[\/\s!])kody(\s|$)/.test(v)) return true;
787
+ if (/\bgit-credential\b/.test(v) && /kody/i.test(v)) return true;
788
+ return false;
789
+ }
790
+ async function authRemoveGit(input) {
791
+ const apiUrl = input.apiUrl || defaultApiUrl;
792
+ const mcpUrl = input.mcpUrl || defaultMcpUrl;
793
+ const host = gitCredentialHostFromMcpUrl(mcpUrl);
794
+ const runGet = input.runGitGet ?? defaultGitConfigGetRunner;
795
+ const runGit = input.runGit ?? defaultGitConfigRunner;
796
+ const helperKey = `credential.https://${host}.helper`;
797
+ const pathKey = `credential.https://${host}.useHttpPath`;
798
+ const removedHelpers = [];
799
+ const removedPathKeys = [];
800
+ for (const scope of setupGitConfigScopes) {
801
+ const helpers = runGet(["config", scope, "--get-all", helperKey]);
802
+ if (helpers.status === 0 && helpers.stdout.trim()) {
803
+ const values = helpers.stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
804
+ const unset = runGit(["config", scope, "--unset-all", helperKey]);
805
+ if (unset.status === 0) {
806
+ for (const value of values) {
807
+ removedHelpers.push({ scope, key: helperKey, value });
808
+ }
809
+ }
810
+ }
811
+ const pathGot = runGet(["config", scope, "--get-all", pathKey]);
812
+ if (pathGot.status === 0 && pathGot.stdout.trim()) {
813
+ const unset = runGit(["config", scope, "--unset-all", pathKey]);
814
+ if (unset.status === 0) {
815
+ removedPathKeys.push({
816
+ scope,
817
+ key: pathKey,
818
+ value: pathGot.stdout.trim().split(/\r?\n/)[0]
819
+ });
820
+ }
821
+ }
822
+ }
823
+ const stored = loadStoredApiToken(apiUrl, input.backend, input.resolution);
824
+ let tokenRevoked = "skipped";
825
+ let tokenRevokeError;
826
+ let tokenId = stored?.tokenId ?? null;
827
+ if (stored?.token) {
828
+ try {
829
+ await openApiRequest({
830
+ token: stored.token,
831
+ apiUrl,
832
+ method: "DELETE",
833
+ path: "v1/tokens/current",
834
+ fetchFn: input.fetchFn
835
+ });
836
+ tokenRevoked = "yes";
837
+ } catch (error) {
838
+ if (error instanceof OpenApiError && (error.status === 401 || error.status === 404)) {
839
+ tokenRevoked = "already";
840
+ } else {
841
+ tokenRevoked = "failed";
842
+ tokenRevokeError = error instanceof Error ? error.message : String(error);
843
+ }
844
+ }
845
+ }
846
+ const deleted = deleteStoredApiToken(apiUrl, input.backend, input.resolution);
847
+ return {
848
+ host,
849
+ removedHelpers,
850
+ removedPathKeys,
851
+ tokenId,
852
+ tokenRevoked,
853
+ ...tokenRevokeError ? { tokenRevokeError } : {},
854
+ tokenDeletedLocally: deleted.deleted
855
+ };
856
+ }
857
+ function formatAuthRemoveGitReport(result) {
858
+ const lines = [];
859
+ const removedAnything = result.removedHelpers.length > 0 || result.removedPathKeys.length > 0 || result.tokenDeletedLocally || result.tokenRevoked === "yes" || result.tokenRevoked === "already";
860
+ if (!removedAnything) {
861
+ return [
862
+ `No Kody Git HTTPS credential helper or stored API token found for https://${result.host}/.`,
863
+ "Nothing to remove. (kody login sessions were not touched.)",
864
+ ""
865
+ ].join("\n");
866
+ }
867
+ lines.push(`Removed Kody Git HTTPS setup for https://${result.host}/`);
868
+ for (const entry of result.removedHelpers) {
869
+ lines.push(` ${entry.scope} ${entry.key}: ${entry.value}`);
870
+ }
871
+ for (const entry of result.removedPathKeys) {
872
+ lines.push(` ${entry.scope} ${entry.key}${entry.value ? `: ${entry.value}` : ""}`);
873
+ }
874
+ if (result.tokenRevoked === "yes") {
875
+ lines.push(
876
+ `Revoked API token${result.tokenId ? ` ${result.tokenId}` : ""} on the server (token:delete).`
877
+ );
878
+ } else if (result.tokenRevoked === "already") {
879
+ lines.push(
880
+ `API token${result.tokenId ? ` ${result.tokenId}` : ""} already revoked or expired on the server.`
881
+ );
882
+ } else if (result.tokenRevoked === "failed") {
883
+ lines.push(
884
+ `Could not revoke API token on the server${result.tokenRevokeError ? `: ${result.tokenRevokeError}` : "."}`
885
+ );
886
+ } else if (result.tokenRevoked === "skipped") {
887
+ lines.push("No stored API token to revoke.");
888
+ }
889
+ if (result.tokenDeletedLocally) {
890
+ lines.push("Deleted stored API token from the OS keychain (and file fallback).");
891
+ } else if (result.tokenRevoked !== "skipped") {
892
+ lines.push("Stored API token was already absent from the local store.");
893
+ }
894
+ lines.push("Left kody login sessions alone.");
895
+ lines.push("");
896
+ return lines.join("\n");
897
+ }
898
+
899
+ export {
900
+ cliTokenLifetimePolicy,
901
+ cliTokenLifetimeAliases,
902
+ cliTokenLifetimeMissingError,
903
+ resolveCliTokenLifetime,
904
+ bootstrapRedeemRequestBody,
905
+ parseCliLifetimeSecondsFlag,
906
+ redeemBootstrapCode,
907
+ authBootstrap,
908
+ cliCredentialBootstrapOperationId,
909
+ parseCliScopesFlag,
910
+ bootstrapMintLifetimeFields,
911
+ authBootstrapWithScopes,
912
+ setupGitRequiredScopes,
913
+ setupGitDefaultScopes,
914
+ gitCredentialHostFromMcpUrl,
915
+ scopesIncludeRequired,
916
+ ensureSetupGitScopes,
917
+ fetchTokenCurrentMetadata,
918
+ assertUserOwnedTokensLive,
919
+ decideSetupGitToken,
920
+ defaultGitConfigRunner,
921
+ installGitCredentialConfig,
922
+ gitApiTokenRefreshSkewMs,
923
+ gitCredentialMinCliVersion,
924
+ gitCredentialHelperPinFallbackVersion,
925
+ readCliPackageVersion,
926
+ isEphemeralNpxEntryPath,
927
+ parseCliSemver,
928
+ compareCliSemver,
929
+ cliVersionGte,
930
+ cliVersionGt,
931
+ cliVersionSupportsGitCredential,
932
+ cliExactVersionForNpx,
933
+ cliMajorVersionForNpx,
934
+ apiTokenNeedsRefresh,
935
+ readVersionFromKodyBinary,
936
+ gitCredentialHelperCommand,
937
+ isMajorOnlyNpxHelper,
938
+ exactNpxHelperVersion,
939
+ gitCredentialHelperNeedsRepair,
940
+ defaultGitConfigGetRunner,
941
+ refreshGitCredentialHelperPinIfNeeded,
942
+ authSetupGit,
943
+ setupGitConfigScopes,
944
+ isKodyGitCredentialHelperValue,
945
+ authRemoveGit,
946
+ formatAuthRemoveGitReport
947
+ };
948
+ //# sourceMappingURL=chunk-EOCV74B2.js.map