@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,1959 @@
1
+ import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
+ import {
3
+ assertLocalExecuteNodeEngine
4
+ } from "./chunk-SMURF26I.js";
5
+ import {
6
+ isPublishedPackageInvokeSpecifier,
7
+ resolveExecuteInvokeCode
8
+ } from "./chunk-75RZUXQL.js";
9
+ import {
10
+ formatToolResult
11
+ } from "./chunk-46IJPEID.js";
12
+ import {
13
+ hostIds
14
+ } from "./chunk-PDWCKWQF.js";
15
+ import {
16
+ resolveOrgSlug
17
+ } from "./chunk-OVGXPRSY.js";
18
+ import {
19
+ resolveLocalExecuteBearer
20
+ } from "./chunk-VQS5YSCI.js";
21
+ import {
22
+ authBootstrap,
23
+ authBootstrapWithScopes,
24
+ bootstrapMintLifetimeFields,
25
+ cliCredentialBootstrapOperationId,
26
+ parseCliLifetimeSecondsFlag,
27
+ parseCliScopesFlag,
28
+ refreshGitCredentialHelperPinIfNeeded,
29
+ resolveCliTokenLifetime
30
+ } from "./chunk-EOCV74B2.js";
31
+ import {
32
+ parseCredentialFlags
33
+ } from "./chunk-R4IUV5P5.js";
34
+ import {
35
+ redactError
36
+ } from "./chunk-CASGRYOF.js";
37
+ import {
38
+ orgEnvVar,
39
+ orgSlugFromFlag
40
+ } from "./chunk-CWWHR4FH.js";
41
+ import {
42
+ readPackageVersion
43
+ } from "./chunk-G6LJWROP.js";
44
+ import {
45
+ cliBootstrapMintCall,
46
+ deleteStoredApiToken,
47
+ hasExplicitTokenFlag,
48
+ loadStoredApiToken,
49
+ requireApiToken,
50
+ resolveScopedApiToken
51
+ } from "./chunk-RTWUNV76.js";
52
+ import {
53
+ deleteCredentials,
54
+ listStoredOrgs,
55
+ loadCredentials
56
+ } from "./chunk-RM34N3KI.js";
57
+ import {
58
+ apiTokenEnvVar,
59
+ defaultApiUrl,
60
+ defaultMcpUrl,
61
+ modernMcpProtocolVersion,
62
+ onboardingUrl
63
+ } from "./chunk-IHP6PV6X.js";
64
+
65
+ // src/cli.ts
66
+ import { parseArgs } from "node:util";
67
+ import { readFile } from "node:fs/promises";
68
+
69
+ // src/help.ts
70
+ function formatOrgsHelpBlock(orgs, indent = " ") {
71
+ if (orgs.length === 0) {
72
+ return `${indent}Not logged in. Run \`kody login\`.
73
+ `;
74
+ }
75
+ const lines = [`${indent}Logged-in orgs:`];
76
+ for (const org of orgs) {
77
+ const mark = org.active ? "*" : " ";
78
+ const pending = org.pending ? " (slug pending \u2014 run any authenticated command)" : "";
79
+ lines.push(
80
+ `${indent} ${mark} ${org.slug}${org.active ? " (active)" : ""}${pending}`
81
+ );
82
+ }
83
+ return `${lines.join("\n")}
84
+ `;
85
+ }
86
+ function buildUsage(input = {}) {
87
+ const mcpUrl = input.mcpUrl ?? defaultMcpUrl;
88
+ let orgs = input.orgs;
89
+ if (!orgs) {
90
+ try {
91
+ orgs = listStoredOrgs(mcpUrl, input.backend, input.resolution);
92
+ } catch {
93
+ orgs = [];
94
+ }
95
+ }
96
+ const orgBlock = formatOrgsHelpBlock(orgs);
97
+ return `Kody CLI ${readPackageVersion()}
98
+
99
+ Install Kody as a remote MCP server in local agents, or use this CLI as a local client.
100
+
101
+ Usage:
102
+ kody login [--mcp-url <url>] [--org <slug>] [--no-browser]
103
+ kody logout [--org <slug>] [--mcp-url <url>] [--api-url <url>]
104
+ kody org list [--json] [--mcp-url <url>]
105
+ kody org use [<slug>] [--mcp-url <url>]
106
+ kody status [--mcp-url <url>] [--api-url <url>]
107
+ kody auth bootstrap (--code <kody_bc_\u2026> | --scopes <list>) (--lifetime short|long | --idle-ttl-seconds <n> --max-lifetime-seconds <n>)
108
+ [--token <token>] [--mcp-url <url>] [--api-url <url>]
109
+ kody auth setup-git [--lifetime long|short] [--scopes <list>] [--token <token>] [--mcp-url <url>] [--api-url <url>]
110
+ kody auth remove-git [--mcp-url <url>] [--api-url <url>]
111
+ kody git-credential <get|store|erase>
112
+ kody whoami [--org <slug>] [--target prod|mock] [--mcp-url <url>] [--token <token>] [--api-url <url>] [--json]
113
+ kody search [query] [--org <slug>] [--entity <ref>] [--domain <id>] [--limit <n>] [--target prod|mock] [--token <token>] [--api-url <url>] [--json]
114
+ kody api <operationId> [--org <slug>] [--params <json>] [--token <token>] [--api-url <url>] [--json]
115
+ kody package publish [<@owner/leaf|package_id>] [--org <slug>] [--params <json>] [--token <token>] [--api-url <url>]
116
+ kody package collaborators <package> [--org <slug>] [--json] [--token <token>] [--api-url <url>]
117
+ kody package grant <package> (--team <slug> | --user <username>) [--preset use|contribute|manage] [--org <slug>] [--json]
118
+ kody package revoke <package> (--team <slug> | --user <username> | --grant <grant_id>) [--org <slug>] [--json]
119
+ kody execute [--org <slug>] [--invoke <ref> | --code <esm> | --file <path>] [--params <json>] [--conversation-id <id>] [--json]
120
+ [--credential <key=name>]\u2026 [--target prod|mock] [--token <token>] [--api-url <url>] [--local] [--allow-private-network]
121
+ kody dev [serve] [--org <slug>] [--target prod|mock] [--reset-storage] [--port <n>] [--app-base-path <path>] [--allow-private-network] [--no-live-reload] [--json] [--ready-file <path>]
122
+ kody dev fetch <path> [--method <verb>] [--body <file>] [--target prod|mock] [--json] [--no-attach]
123
+ kody dev job <name> [--target prod|mock] [--dry-run] [--json]
124
+ kody dev webhook <name> --body <file.json> [--target prod|mock] [--dry-run] [--json]
125
+ kody dev emit <event> --body <event.json> [--target prod|mock] [--dry-run] [--json]
126
+ kody dev check [--target prod|mock] [--json]
127
+ kody install [--mcp-url <url>] [--clients <ids>] [--yes] [--project] [--json]
128
+ kody skill install [--project]
129
+
130
+ kody install configures running local MCP clients (Cursor, Claude Desktop,
131
+ VS Code, Goose, and others). For web-based clients (ChatGPT, Claude.ai, Grok),
132
+ see ${onboardingUrl(defaultMcpUrl)}
133
+
134
+ Orgs (local store, offline):
135
+ ${orgBlock}
136
+ --org <slug>
137
+ For \`kody login\` / \`kody logout\`: only the flag counts
138
+ (${orgEnvVar} is ignored). Login binds the browser grant to
139
+ this organization (adds/replaces that org's stored login;
140
+ other orgs stay). Example: \`kody login --org acme\`
141
+ Omit and the server picker binds one org.
142
+ For org-scoped commands (whoami, search, api, execute, \u2026):
143
+ run as this org for one call. Precedence: flag, then
144
+ ${orgEnvVar}, then the active org (\`kody org use\`).
145
+
146
+ kody org list
147
+ Show logged-in orgs and mark the active one. \`--json\` for agents.
148
+
149
+ kody org use [<slug>]
150
+ Switch the active org. With a slug (agents), switches directly.
151
+ With no slug on a TTY (humans), opens an interactive chooser.
152
+ Without a TTY, pass a slug.
153
+
154
+ kody logout
155
+ Without \`--org\`, removes the active org login only (or the
156
+ pending legacy session). With \`--org <slug>\`, removes just
157
+ that org. Other org logins stay. Also clears a stored
158
+ bootstrap/API token when present.
159
+
160
+ --clients Comma-separated ids: ${hostIds.join(", ")}
161
+
162
+ auth bootstrap
163
+ Redeem a one-shot \`kody_bc_\u2026\` from MCP \`cliCredentialBootstrap\`
164
+ (POST /v1/tokens/bootstrap/redeem, no Authorization header).
165
+ Lifetime is required: \`--lifetime short|long\` (\`short\` = 1h
166
+ idle / 24h max; \`long\` = 14d idle / 3mo max), or both
167
+ \`--idle-ttl-seconds\` and \`--max-lifetime-seconds\`.
168
+ Single-task agents should use \`--lifetime short\`.
169
+ Stores the resulting \`kody_at_\u2026\` for \`execute --local\`,
170
+ search, whoami, api, and token-auth cloud execute without
171
+ printing the token. Prefer this over tokenCreate for agents
172
+ already on MCP. Interactive humans can use \`kody login\`
173
+ instead. Do not call \`kody api cliCredentialBootstrapRedeem\`
174
+ \u2014 that would print the token.
175
+
176
+ --scopes <list>
177
+ Opt in to scopes beyond the cliCredentialBootstrap defaults
178
+ (comma- or space-separated, e.g.
179
+ \`--scopes org:execute,org:read,package:read,package:write\`).
180
+ The list replaces the defaults, so include every scope you
181
+ need. Instead of \`--code\`, the CLI mints the code itself by
182
+ passing \`scopes\` to cliCredentialBootstrap, then redeems and
183
+ stores it. It mints with \`--token\` if given, else the
184
+ \`kody login\` session (any scope your org role grants), else
185
+ ${apiTokenEnvVar} / a stored token (only scopes that token
186
+ already holds). A bootstrap code's scopes are fixed when it is
187
+ minted, so \`--code\` with \`--scopes\` is an error. Defaults
188
+ stay least-privilege; \`insufficient_scope\` errors print the
189
+ exact \`--scopes\` command to run.
190
+
191
+ auth setup-git
192
+ Install a Git credential helper for HTTPS clones/fetches/pushes
193
+ at \`https://kody.codes/@owner/name.git\` (see guide:auth_setup_git).
194
+ Uses a \`kody login\` session (or \`--token\` / ${apiTokenEnvVar} /
195
+ stored bootstrap token) to mint a user-owned \`kody_at_\u2026\` with
196
+ at least \`package:read\` and \`package:write\` (default
197
+ \`--lifetime long\`; reuses a suitable stored token). That token
198
+ authorizes every repo you can access across all orgs \u2014 login
199
+ \`--org\` only scopes the MCP mint session, not git. User-wide:
200
+ one setup covers every org. Requires a server that advertises
201
+ \`org_binding\`. Configures a stable
202
+ \`credential.https://<host>.helper\` (global \`kody\` only when
203
+ its version supports \`git-credential\`, else
204
+ \`npx -y @kodycodes/cli@<exact>\` \u2014 never a major-only range or
205
+ ephemeral npx cache path) + \`useHttpPath\`. Re-run (or any
206
+ newer CLI command) rewrites stale helper pins. Undo with
207
+ \`kody auth remove-git\`. Does not change \`kody login\` /
208
+ existing auth flows.
209
+
210
+ auth remove-git
211
+ Inverse of \`auth setup-git\`: removes every
212
+ \`credential.https://<host>.*\` helper entry setup-git may have
213
+ written (global and local; including stale \`~/.npm/_npx\` and
214
+ major-only \`@1\` pins), revokes the stored API token on the
215
+ server (\`token:delete\` / DELETE /v1/tokens/current), and
216
+ deletes it from the OS keychain. Idempotent when nothing is
217
+ set up; prints what it removed. Leaves \`kody login\` sessions
218
+ alone.
219
+
220
+ git-credential
221
+ Git credential helper invoked by git after \`auth setup-git\`
222
+ (\`get\` returns username=x / password=kody_at_\u2026 for the Kody
223
+ host with no network while the stored token is still valid;
224
+ silently remints via \`kody login\` only when expired or near
225
+ expiry; \`store\`/\`erase\` are no-ops). Not meant for interactive
226
+ use.
227
+
228
+ api Call one Open API operation by operationId + flat --params
229
+ JSON (same shape as the MCP \`api\` tool). Uses scoped API
230
+ auth only (\`--token\` / ${apiTokenEnvVar} / stored bootstrap).
231
+ Prints JSON. Example: \`kody api usageGet --params '{}'\`.
232
+ Unknown operationIds error clearly; see
233
+ ${defaultApiUrl}/openapi.json. tokenCreate / tokenRotate
234
+ responses include a one-time token value \u2014 prefer env storage
235
+ over pasting into chat.
236
+
237
+ package publish
238
+ Thin wrapper for Open API \`packagePublishExternalPush\` (same
239
+ auth as \`kody api\`). Optional positional is a \`package_id\`, or a
240
+ name (\`@owner/leaf\` or bare leaf) resolved to its package_id
241
+ via \`packageList\` in the current org. Extra fields
242
+ via \`--params\` JSON (e.g. \`allow_force\`). Prints JSON.
243
+
244
+ package collaborators | grant | revoke
245
+ Who can use one package, and add or remove teams and members of
246
+ the org (\`--org\`). \`<package>\` is \`@owner/leaf\`, the kody id,
247
+ or the package id. \`grant\` adds a team or org member or changes
248
+ their preset (default \`use\`) via \`packageCollaboratorSet\`;
249
+ people outside the org are refused. \`revoke\` removes one by
250
+ team, user, or grant id via \`packageCollaboratorRemove\`. Needs
251
+ Manage on the package and a token with
252
+ \`package:manage_access\` (\`auth bootstrap --scopes \u2026\`); same
253
+ auth as \`kody api\`. Prints a short summary, or the API JSON
254
+ with \`--json\`.
255
+
256
+ --token / ${apiTokenEnvVar}
257
+ Scoped API token (preferred via env). With no \`kody login\`
258
+ session, search / whoami / api / execute use the Open API and
259
+ CapabilityProxy \u2014 including cloud execute without --local.
260
+ Auth priority matches \`execute --local\`: \`--token\` /
261
+ ${apiTokenEnvVar}; stored bootstrap/API token from
262
+ \`auth bootstrap\`; then \`kody login\` where applicable.
263
+ Prefer \`cliCredentialBootstrap\` then \`auth bootstrap\`
264
+ (\`--lifetime short|long\`). CI/headless: \`tokenCreate\` with
265
+ \`org:execute\` plus the capability scopes you need.
266
+ For \`execute --local\`, a valid \`kody login\` session can also
267
+ supply Bearer when no scoped token is available (no tokenCreate
268
+ exchange). User-owned tokens (\`org_binding: user\`) honor
269
+ \`--org\` / ${orgEnvVar} as \`?org=\` on API calls.
270
+
271
+ --local Run the execute module on this machine (workerd, Linux/macOS).
272
+ Requires Node.js 22 or newer. \`--file\` entries are bundled
273
+ (relative imports and npm packages; \`kody:*\` stays external)
274
+ before workerd loads them \u2014 same shape as hosted execute /
275
+ publish. Unresolvable imports fail with a clear bundle error.
276
+ \`--invoke kody:@scope/pkg/export\` (or \`@scope/pkg#export\`)
277
+ works with \`--local\` / \`--target mock\` \u2014 mints the same thin
278
+ passthrough as a \`--code\` import wrapper. From a package
279
+ directory, \`--invoke ./export\` runs a local package.json#exports
280
+ key. Auth: \`--token\` /
281
+ ${apiTokenEnvVar}, else stored \`auth bootstrap\` token, else
282
+ paired \`kody login\` credentials. Static kody:@\u2026 imports are fetched via POST
283
+ /v1/local-execute/package-graph and embedded in local workerd
284
+ (CapabilityProxy only for per-call kody:runtime hops \u2014 never a
285
+ whole-module cloud kody.execute defer). Fails clearly when that
286
+ package-graph API is unavailable. Cloud token execute (no
287
+ --local) uses CapabilityProxy \u2192 kody.execute for every module.
288
+
289
+ --credential <key=name>
290
+ ADR 0068 call map: pick which credential each \`credential(key)\`
291
+ / \`credentials(key)\` call gets. Repeatable.
292
+ \`--credential github=work\`, \`--credential x=org:work\`
293
+ (or \`personal:name\`), \`--credential github=\` for none on
294
+ purpose. With \`--local\`, sent as CapabilityProxy top-level
295
+ \`credentials\` (code never sets the map) after a
296
+ \`credentialClientCheck\` preflight. With a \`kody login\` MCP
297
+ session (no token), passed as MCP execute \`credentials\`.
298
+ Token-auth cloud execute (CapabilityProxy \u2192 kody.execute)
299
+ rejects the flag \u2014 use \`--local\` or MCP.
300
+
301
+ --allow-private-network
302
+ Allow execute --local / \`kody dev\` code to fetch private and
303
+ local network addresses. Default is public-only.
304
+
305
+ --target prod|mock
306
+ Where server-side calls go (storage, credentials, kody:*,
307
+ execute, invoke, search). Same meaning on \`dev\`, \`execute\`,
308
+ and \`search\`. Defaults: \`mock\` for \`kody dev\`; \`prod\` for
309
+ execute/search (unchanged). \`--target mock\` starts the
310
+ built-in CLI mock (no kody-celld); scratch storage; fake or
311
+ local credentials so unpublished packages never touch real
312
+ secrets. Unimplemented mock routes refuse with
313
+ \`not_implemented_in_mock\`.
314
+
315
+ --reset-storage
316
+ With \`--target mock\`, wipe the mock session's scratch storage
317
+ before the command.
318
+
319
+ --dry-run With \`kody dev job|webhook|emit\`, print the module path and
320
+ params that would run without invoking (safe against prod side
321
+ effects). Does not apply to serve/fetch/check.
322
+
323
+ --passthrough <host,\u2026>
324
+ With \`--target mock\` and a package \`.kody/mocks.ts\`, allow
325
+ listed hosts to use the real network (credentials stay fake \u2014
326
+ never carries real secrets). Unmatched hosts fail with
327
+ \`unmocked_request\` plus a paste-ready MSW handler stub.
328
+ Ignored on \`--target prod\`. On mock, outbound fetch always
329
+ goes through the Node gateway: with \`.kody/mocks.ts\`, unmatched
330
+ hosts (and all \`createAuthenticatedFetch\` / credentialed hops
331
+ without a handler) fail closed; without the file, public hosts
332
+ passthrough and private hosts need \`--allow-private-network\`.
333
+
334
+ kody dev Local testing for unpublished packages. Serves \`kody.app.entry\`
335
+ on localhost via workerd with hot reload (mount-stripped path;
336
+ packageContext.hostedUrl / appBasePath point at localhost).
337
+ Rebuilds swap to a new workerd only once it listens (requests
338
+ wait; no 503 or stale bundle). Build errors (file:line:col +
339
+ code frame) and uncaught handler errors (stack mapped to your
340
+ .ts sources) are served as dev-only 500 pages until fixed. App
341
+ console.* streams to the terminal tagged by request. HTML pages
342
+ live-reload after each rebuild and show an error overlay
343
+ (SSE at /__kody/dev/events; \`--no-live-reload\` disables).
344
+ Stable default port per package (4100-4999, next free port
345
+ if taken); \`--port <n>\` is exact (\`--port 0\` = any).
346
+ Serves \`kody.app.client\` at /_assets/client.<hash>.js
347
+ (packageContext.clientModuleUrl), \`kody.app.assets\` under
348
+ /_assets/, and /_assets/__version.json. \`kody.dev.prebuild\`
349
+ (shell command, run before every build) regenerates assets;
350
+ \`kody.dev.ignore\` lists watcher path prefixes to skip.
351
+ Agents: \`--json\` streams NDJSON events (ready, rebuild_start,
352
+ rebuild_ok, build_error, runtime_error, log); GET
353
+ /__kody/dev/status returns build id + last error;
354
+ \`--ready-file <path>\` writes { url, port, basePath, pid } once
355
+ ready. \`kody dev fetch\` attaches to a running \`kody dev\` for
356
+ the same package and target (\`--no-attach\` boots a one-shot
357
+ server).
358
+ Bundles with the same esbuild path as publish (\`local-bundle\`).
359
+ Four surfaces: exports (\`execute --invoke ./export\` or
360
+ \`--file\` against the local package), webhooks
361
+ (\`kody dev webhook\`), schedules (\`kody dev job\` \u2014 runs once,
362
+ never schedules locally), subscriptions
363
+ (\`kody dev emit <event> --body event.json\`). \`kody dev check\`
364
+ bundles + light publish validations without running; when the
365
+ package uses credentialed fetch and \`.kody/mocks.ts\` is
366
+ missing, check soft-suggests adding that file. On
367
+ \`--target mock\`, \`kody:@\` deps resolve from this package's
368
+ exports, \`.kody/deps.json\` / \`package.json#kody.localDeps\`
369
+ path maps, then published package-graph when a login/API token
370
+ is available (storage/credentials stay on the mock; local-only
371
+ deps need no login). Optional \`.kody/mocks.ts\` exports MSW
372
+ \`handlers\` for outbound fetch mocking (Node gateway; not
373
+ published with the package) \u2014 \`createAuthenticatedFetch\`,
374
+ \`credential().fetch\`, \`gatewayFetch\`, and
375
+ \`gatewayFetchStream\` all match against them. Unmocked
376
+ requests fail closed with a ready-to-paste MSW handler stub
377
+ pointing at \`.kody/mocks.ts\`. Share previews are out of scope.
378
+
379
+ Environment:
380
+ KODY_MCP_URL Override the default MCP URL (${defaultMcpUrl})
381
+ ${orgEnvVar} Default org slug for org-scoped commands (overridden by --org)
382
+ ${apiTokenEnvVar} Scoped API token for token-auth search / whoami / api / execute
383
+ KODY_API_URL Override the Kody API URL (${defaultApiUrl})
384
+ KODY_TARGET Default \`prod\`|\`mock\` (overridden by --target)
385
+ KODY_MOCK_SESSION_ID Scratch storage key for --target mock (default: default)
386
+ KODY_CACHE_DIR Where execute --local caches workerd (default: user cache dir)
387
+ KODY_WORKERD_PATH Use this workerd binary instead of the pinned download
388
+ `;
389
+ }
390
+
391
+ // src/package-collaborators.ts
392
+ var packageCollaboratorPresets = ["use", "contribute", "manage"];
393
+ var packageCollaboratorActions = [
394
+ "collaborators",
395
+ "grant",
396
+ "revoke"
397
+ ];
398
+ function isPackageCollaboratorAction(value) {
399
+ return packageCollaboratorActions.includes(value);
400
+ }
401
+ var packageCollaboratorUsage = [
402
+ "Usage: kody package collaborators <@owner/leaf|kody_id|package_id> [--org <slug>] [--json]",
403
+ " kody package grant <package> (--team <slug> | --user <username>) [--preset use|contribute|manage] [--org <slug>] [--json]",
404
+ " kody package revoke <package> (--team <slug> | --user <username> | --grant <grant_id>) [--org <slug>] [--json]"
405
+ ].join("\n");
406
+ function readFlag(value, name) {
407
+ if (value === void 0) return void 0;
408
+ if (typeof value !== "string" || value.trim() === "") {
409
+ throw new Error(`--${name} needs a value.
410
+ ${packageCollaboratorUsage}`);
411
+ }
412
+ return value.trim();
413
+ }
414
+ function readSubject(values, allowGrant) {
415
+ const team = readFlag(values.team, "team");
416
+ const user = readFlag(values.user, "user");
417
+ const grant = allowGrant ? readFlag(values.grant, "grant") : void 0;
418
+ const given = [team, user, grant].filter((value) => value !== void 0);
419
+ if (given.length !== 1) {
420
+ throw new Error(
421
+ `Pass exactly one of ${allowGrant ? "--team, --user, or --grant" : "--team or --user"}.
422
+ ${packageCollaboratorUsage}`
423
+ );
424
+ }
425
+ if (team) return { kind: "team", slug: team.replace(/^@/, "") };
426
+ if (user) return { kind: "user", username: user.replace(/^@/, "") };
427
+ return { kind: "grant", grantId: grant };
428
+ }
429
+ function readPreset(value) {
430
+ const preset = readFlag(value, "preset") ?? "use";
431
+ if (!packageCollaboratorPresets.includes(preset)) {
432
+ throw new Error(`--preset must be one of ${packageCollaboratorPresets.join(", ")}.`);
433
+ }
434
+ return preset;
435
+ }
436
+ function parsePackageCollaboratorCommand(input) {
437
+ const packageId = input.positionals[0]?.trim();
438
+ if (!packageId || input.positionals.length > 1) {
439
+ throw new Error(packageCollaboratorUsage);
440
+ }
441
+ switch (input.action) {
442
+ case "collaborators":
443
+ return { action: "collaborators", packageId };
444
+ case "grant": {
445
+ const subject = readSubject(input.values, false);
446
+ if (subject.kind === "grant") throw new Error(packageCollaboratorUsage);
447
+ return {
448
+ action: "grant",
449
+ packageId,
450
+ subject,
451
+ preset: readPreset(input.values.preset)
452
+ };
453
+ }
454
+ case "revoke":
455
+ if (input.values.preset !== void 0) {
456
+ throw new Error(`--preset is only for grant.
457
+ ${packageCollaboratorUsage}`);
458
+ }
459
+ return { action: "revoke", packageId, target: readSubject(input.values, true) };
460
+ default: {
461
+ const exhaustive = input.action;
462
+ throw new Error(`Unhandled package action: ${String(exhaustive)}`);
463
+ }
464
+ }
465
+ }
466
+ function describeSubject(subject) {
467
+ return subject.kind === "team" ? `team ${subject.slug}` : `@${subject.username}`;
468
+ }
469
+ function collaboratorLabel(collaborator) {
470
+ if (collaborator.subject_type === "team") {
471
+ return collaborator.team_slug ? `${collaborator.team_slug}${collaborator.team_name ? ` (${collaborator.team_name})` : ""}` : collaborator.subject_id;
472
+ }
473
+ if (!collaborator.username) return collaborator.display_name ?? collaborator.subject_id;
474
+ return collaborator.display_name ? `@${collaborator.username} (${collaborator.display_name})` : `@${collaborator.username}`;
475
+ }
476
+ function presetLabel(collaborator) {
477
+ return collaborator.preset ?? `custom (${collaborator.permissions.length} permissions)`;
478
+ }
479
+ function formatCollaboratorList(list) {
480
+ const header = `${list.package.name} (${list.package.id})`;
481
+ if (list.collaborators.length === 0) {
482
+ return `${header}
483
+ No collaborators. Org owners always have full access.
484
+ `;
485
+ }
486
+ const rows = list.collaborators.map((collaborator) => [
487
+ collaborator.kind,
488
+ collaboratorLabel(collaborator),
489
+ presetLabel(collaborator),
490
+ collaborator.grant_id
491
+ ]);
492
+ const widths = [0, 1, 2].map(
493
+ (column) => Math.max(...rows.map((row) => row[column].length))
494
+ );
495
+ const lines = rows.map(
496
+ (row) => row.map((cell, column) => column < 3 ? cell.padEnd(widths[column]) : cell).join(" ")
497
+ );
498
+ return `${header}
499
+ ${lines.join("\n")}
500
+ `;
501
+ }
502
+ function findCollaborator(list, subject) {
503
+ const match = list.collaborators.find(
504
+ (collaborator) => subject.kind === "team" ? collaborator.subject_type === "team" && collaborator.team_slug === subject.slug : collaborator.subject_type === "user" && collaborator.username?.toLowerCase() === subject.username.toLowerCase()
505
+ );
506
+ if (!match) {
507
+ throw new Error(`${describeSubject(subject)} is not a collaborator on ${list.package.name}.`);
508
+ }
509
+ return match;
510
+ }
511
+ async function runPackageCollaboratorPlan(input) {
512
+ const { plan, call, json } = input;
513
+ const print = (value, text) => json ? `${JSON.stringify(value, null, 2)}
514
+ ` : text;
515
+ switch (plan.action) {
516
+ case "collaborators": {
517
+ const list = await call("packageCollaboratorList", {
518
+ package_id: plan.packageId
519
+ });
520
+ return print(list, formatCollaboratorList(list));
521
+ }
522
+ case "grant": {
523
+ const result = await call("packageCollaboratorSet", {
524
+ package_id: plan.packageId,
525
+ ...plan.subject.kind === "team" ? { team_slug: plan.subject.slug } : { username: plan.subject.username },
526
+ preset: plan.preset
527
+ });
528
+ return print(
529
+ result,
530
+ `${collaboratorLabel(result.collaborator)} now has ${presetLabel(result.collaborator)} on ${result.package.name} (grant ${result.collaborator.grant_id}).
531
+ `
532
+ );
533
+ }
534
+ case "revoke": {
535
+ const target = plan.target;
536
+ let grantId;
537
+ let label;
538
+ let packageName = plan.packageId;
539
+ if (target.kind === "grant") {
540
+ grantId = target.grantId;
541
+ label = `grant ${grantId}`;
542
+ } else {
543
+ const list = await call("packageCollaboratorList", {
544
+ package_id: plan.packageId
545
+ });
546
+ const collaborator = findCollaborator(list, target);
547
+ grantId = collaborator.grant_id;
548
+ label = collaboratorLabel(collaborator);
549
+ packageName = list.package.name;
550
+ }
551
+ const result = await call("packageCollaboratorRemove", {
552
+ package_id: plan.packageId,
553
+ grant_id: grantId
554
+ });
555
+ return print(result, `Removed ${label} from ${packageName}.
556
+ `);
557
+ }
558
+ default: {
559
+ const exhaustive = plan;
560
+ throw new Error(`Unhandled package plan: ${JSON.stringify(exhaustive)}`);
561
+ }
562
+ }
563
+ }
564
+
565
+ // src/cli.ts
566
+ var orgScopedCommands = /* @__PURE__ */ new Set([
567
+ "login",
568
+ "logout",
569
+ "whoami",
570
+ "search",
571
+ "api",
572
+ "package",
573
+ "execute",
574
+ "dev",
575
+ "auth"
576
+ ]);
577
+ function mcpUrlFrom(values) {
578
+ return values.mcpUrl || process.env.KODY_MCP_URL || defaultMcpUrl;
579
+ }
580
+ function apiUrlFrom(values, env = process.env) {
581
+ return values.apiUrl || env.KODY_API_URL || defaultApiUrl;
582
+ }
583
+ function parseKnown(args) {
584
+ return parseArgs({
585
+ args,
586
+ allowPositionals: true,
587
+ strict: false,
588
+ options: {
589
+ help: { type: "boolean", short: "h" },
590
+ version: { type: "boolean", short: "v" },
591
+ json: { type: "boolean" },
592
+ "mcp-url": { type: "string" },
593
+ entity: { type: "string" },
594
+ domain: { type: "string" },
595
+ limit: { type: "string" },
596
+ code: { type: "string" },
597
+ file: { type: "string" },
598
+ invoke: { type: "string" },
599
+ params: { type: "string" },
600
+ "conversation-id": { type: "string" },
601
+ local: { type: "boolean" },
602
+ "allow-private-network": { type: "boolean" },
603
+ credential: { type: "string", multiple: true },
604
+ token: { type: "string" },
605
+ "api-url": { type: "string" },
606
+ lifetime: { type: "string" },
607
+ "idle-ttl-seconds": { type: "string" },
608
+ "max-lifetime-seconds": { type: "string" },
609
+ scopes: { type: "string" },
610
+ project: { type: "boolean" },
611
+ "no-browser": { type: "boolean" },
612
+ org: { type: "string" },
613
+ target: { type: "string" },
614
+ "reset-storage": { type: "boolean" },
615
+ "dry-run": { type: "boolean" },
616
+ passthrough: { type: "string" },
617
+ port: { type: "string" },
618
+ "app-base-path": { type: "string" },
619
+ "no-live-reload": { type: "boolean" },
620
+ "ready-file": { type: "string" },
621
+ "no-attach": { type: "boolean" },
622
+ method: { type: "string" },
623
+ body: { type: "string" },
624
+ clients: { type: "string" },
625
+ yes: { type: "boolean", short: "y" },
626
+ team: { type: "string" },
627
+ user: { type: "string" },
628
+ preset: { type: "string" },
629
+ grant: { type: "string" }
630
+ }
631
+ });
632
+ }
633
+ function resolveCommand(argv) {
634
+ const { positionals, values } = parseKnown(argv);
635
+ if (values.help && positionals.length === 0) {
636
+ return { command: "help", positionals, values };
637
+ }
638
+ if (values.version && positionals.length === 0) {
639
+ return { command: "version", positionals, values };
640
+ }
641
+ const raw = positionals[0];
642
+ if (!raw) return { command: "help", positionals, values };
643
+ switch (raw) {
644
+ case "login":
645
+ case "logout":
646
+ case "org":
647
+ case "status":
648
+ case "auth":
649
+ case "git-credential":
650
+ case "whoami":
651
+ case "search":
652
+ case "api":
653
+ case "package":
654
+ case "execute":
655
+ case "dev":
656
+ case "install":
657
+ case "skill":
658
+ case "help":
659
+ case "version":
660
+ return { command: raw, positionals: positionals.slice(1), values };
661
+ default:
662
+ throw new Error(
663
+ `Unknown command "${raw}". Run \`kody --help\` for usage.`
664
+ );
665
+ }
666
+ }
667
+ async function runCli(argv = process.argv.slice(2), io = {}) {
668
+ const write = io.stdout ?? ((text) => process.stdout.write(text));
669
+ const writeErr = io.stderr ?? ((text) => process.stderr.write(text));
670
+ const head = argv[0];
671
+ const skipHelperRefresh = process.env.NODE_TEST === "1" || process.env.KODY_SKIP_GIT_HELPER_REFRESH === "1" || head === "git-credential" || head === "version" || head === "--version" || head === "-v" || head === "help" || head === "--help" || head === "-h" || head === void 0;
672
+ if (!skipHelperRefresh) {
673
+ try {
674
+ refreshGitCredentialHelperPinIfNeeded({
675
+ mcpUrl: process.env.KODY_MCP_URL || void 0
676
+ });
677
+ } catch {
678
+ }
679
+ }
680
+ try {
681
+ const parsed = resolveCommand(argv);
682
+ const helpMcpUrl = mcpUrlFrom({
683
+ mcpUrl: typeof parsed.values["mcp-url"] === "string" ? parsed.values["mcp-url"] : void 0
684
+ });
685
+ if (parsed.values.help && parsed.command !== "help") {
686
+ write(buildUsage({ mcpUrl: helpMcpUrl }));
687
+ return 0;
688
+ }
689
+ return await dispatch(parsed, write, writeErr);
690
+ } catch (error) {
691
+ writeErr(`${redactError(error).message}
692
+ `);
693
+ return 1;
694
+ }
695
+ }
696
+ async function dispatch(parsed, write, writeErr) {
697
+ const mcpUrl = mcpUrlFrom({
698
+ mcpUrl: typeof parsed.values["mcp-url"] === "string" ? parsed.values["mcp-url"] : void 0
699
+ });
700
+ const json = parsed.values.json === true;
701
+ if (parsed.values["allow-private-network"] === true) {
702
+ const executeAllowsPrivateNetwork = parsed.command === "execute" && (parsed.values.local === true || (await import("./target-3QHY7JT4.js")).resolveTarget({
703
+ command: "execute",
704
+ flag: typeof parsed.values.target === "string" ? parsed.values.target : void 0
705
+ }) === "mock");
706
+ if (parsed.command !== "dev" && !executeAllowsPrivateNetwork) {
707
+ throw new Error(
708
+ "--allow-private-network can only be used with execute --local, execute --target mock, or kody dev."
709
+ );
710
+ }
711
+ }
712
+ if (parsed.values["reset-storage"] === true && parsed.command !== "dev" && parsed.command !== "execute" && parsed.command !== "search") {
713
+ throw new Error("`--reset-storage` is only used with --target mock on execute, search, or dev.");
714
+ }
715
+ if (parsed.values["dry-run"] === true && parsed.command !== "dev") {
716
+ throw new Error(
717
+ "`--dry-run` is only used with `kody dev job|webhook|emit` (shows the plan without invoking)."
718
+ );
719
+ }
720
+ if (typeof parsed.values.passthrough === "string" && parsed.command !== "dev" && parsed.command !== "execute") {
721
+ throw new Error(
722
+ "`--passthrough` is only used with `execute --target mock` or `kody dev` when `.kody/mocks.ts` is active."
723
+ );
724
+ }
725
+ const orgFlag = typeof parsed.values.org === "string" ? parsed.values.org : void 0;
726
+ if (orgFlag !== void 0 && !orgScopedCommands.has(parsed.command)) {
727
+ throw new Error(
728
+ `\`--org\` is not used with \`kody ${parsed.command}\`. Use it with login, logout, whoami, search, api, package, execute, or auth.`
729
+ );
730
+ }
731
+ const orgFlagOnly = orgFlag !== void 0 ? orgSlugFromFlag(orgFlag) : void 0;
732
+ const org = resolveOrgSlug({ flag: orgFlag });
733
+ switch (parsed.command) {
734
+ case "help":
735
+ write(buildUsage({ mcpUrl }));
736
+ return 0;
737
+ case "version":
738
+ write(`${readPackageVersion()}
739
+ `);
740
+ return 0;
741
+ case "login": {
742
+ const { login } = await import("./auth-4FW6GCLG.js");
743
+ write("Opening the Kody login page in your browser\u2026\n");
744
+ const result = await login({
745
+ mcpUrl,
746
+ ...orgFlagOnly ? { org: orgFlagOnly } : {},
747
+ openBrowser: parsed.values["no-browser"] !== true,
748
+ onAuthorizationUrl: (url) => {
749
+ write(`If the browser does not open, visit:
750
+ ${url.href}
751
+ `);
752
+ }
753
+ });
754
+ const orgLabel = result.org ? ` as org ${result.org}` : result.credentials.org ? ` as org ${result.credentials.org}` : "";
755
+ const accountLabel = result.account?.email ? ` (${result.account.email})` : result.account?.displayName ? ` (${result.account.displayName})` : "";
756
+ write(`Logged in to ${result.credentials.mcpUrl}${orgLabel}${accountLabel}.
757
+ `);
758
+ if (result.backendKind === "file" && result.backendPath) {
759
+ write(
760
+ `OS keychain was unavailable; credentials saved at ${result.backendPath} (mode 0600).
761
+ `
762
+ );
763
+ } else {
764
+ write("Credentials stored in the OS keychain.\n");
765
+ }
766
+ return 0;
767
+ }
768
+ case "logout": {
769
+ const apiUrl = apiUrlFrom({
770
+ apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
771
+ });
772
+ const oauth = deleteCredentials(
773
+ mcpUrl,
774
+ void 0,
775
+ void 0,
776
+ orgFlagOnly ? { org: orgFlagOnly } : void 0
777
+ );
778
+ const clearApiToken = !orgFlagOnly || oauth.remaining === 0;
779
+ const apiToken = clearApiToken ? deleteStoredApiToken(apiUrl) : { deleted: false };
780
+ if (!oauth.deleted && !apiToken.deleted) {
781
+ write(
782
+ orgFlagOnly ? `No stored login for org "${orgFlagOnly}".
783
+ ` : "No stored credentials.\n"
784
+ );
785
+ return 0;
786
+ }
787
+ const parts = [];
788
+ if (oauth.deleted) {
789
+ parts.push(
790
+ orgFlagOnly ? `Logged out of org ${orgFlagOnly}.` : "Logged out of the active org (kody login)."
791
+ );
792
+ }
793
+ if (apiToken.deleted) parts.push("Cleared stored bootstrap/API token.");
794
+ write(`${parts.join(" ")}
795
+ `);
796
+ return 0;
797
+ }
798
+ case "org": {
799
+ const {
800
+ chooseOrgInteractively,
801
+ formatOrgListHuman,
802
+ formatOrgListJson,
803
+ useOrg
804
+ } = await import("./org-X7B5BI4R.js");
805
+ const { listStoredOrgs: listStoredOrgs2 } = await import("./store-WTMRH527.js");
806
+ const action = parsed.positionals[0];
807
+ if (action === "list") {
808
+ const orgs = listStoredOrgs2(mcpUrl);
809
+ write(json ? formatOrgListJson(orgs) : formatOrgListHuman(orgs));
810
+ return orgs.length === 0 ? 1 : 0;
811
+ }
812
+ if (action === "use") {
813
+ const slugArg = parsed.positionals[1];
814
+ if (slugArg) {
815
+ const next2 = useOrg(slugArg, mcpUrl);
816
+ write(`Active org is now ${next2.activeOrg}.
817
+ `);
818
+ return 0;
819
+ }
820
+ const orgs = listStoredOrgs2(mcpUrl);
821
+ const chosen = await chooseOrgInteractively({ orgs });
822
+ const next = useOrg(chosen, mcpUrl);
823
+ write(`Active org is now ${next.activeOrg}.
824
+ `);
825
+ return 0;
826
+ }
827
+ throw new Error("Usage: kody org list [--json] | kody org use [<slug>]");
828
+ }
829
+ case "status": {
830
+ const apiUrl = apiUrlFrom({
831
+ apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
832
+ });
833
+ const credentials = loadCredentials(mcpUrl);
834
+ const orgs = listStoredOrgs(mcpUrl);
835
+ const storedApi = loadStoredApiToken(apiUrl);
836
+ if (!credentials && orgs.length === 0 && !storedApi) {
837
+ write("Not logged in.\n");
838
+ return 1;
839
+ }
840
+ const lines = [];
841
+ if (credentials || orgs.length > 0) {
842
+ const expires = credentials?.expiresAt ? new Date(credentials.expiresAt).toISOString() : "unknown";
843
+ lines.push(
844
+ `mcp: ${credentials?.mcpUrl ?? mcpUrl}`,
845
+ `logged in: yes`,
846
+ `active org: ${credentials?.org ?? orgs.find((row) => row.active)?.slug ?? "(pending)"}`,
847
+ `orgs: ${orgs.map((row) => row.active ? `${row.slug}*` : row.slug).join(", ") || "(pending)"}`,
848
+ `access token expires: ${expires}`,
849
+ `refresh token: ${credentials?.refreshToken ? "yes" : "no"}`,
850
+ `scope: ${credentials?.scope ?? "unknown"}`
851
+ );
852
+ } else {
853
+ lines.push(`mcp: ${mcpUrl}`, `logged in: no`);
854
+ }
855
+ if (storedApi) {
856
+ const scopes = storedApi.scopes?.join(", ") || "(unknown)";
857
+ lines.push(
858
+ `api: ${storedApi.apiUrl}`,
859
+ `stored API token: yes (${storedApi.tokenId})`,
860
+ `API token scopes: ${scopes}`,
861
+ `API token expires: ${storedApi.expiresAt ?? "unknown"}`,
862
+ `API token via: ${storedApi.createdVia ?? "unknown"}`
863
+ );
864
+ } else {
865
+ lines.push(`api: ${apiUrl}`, `stored API token: no`);
866
+ }
867
+ lines.push("");
868
+ write(lines.join("\n"));
869
+ return 0;
870
+ }
871
+ case "auth": {
872
+ const action = parsed.positionals[0];
873
+ if (action === "setup-git") {
874
+ return runAuthSetupGit({
875
+ values: parsed.values,
876
+ mcpUrl,
877
+ write,
878
+ ...org ? { org } : {}
879
+ });
880
+ }
881
+ if (action === "remove-git") {
882
+ return runAuthRemoveGit({
883
+ values: parsed.values,
884
+ mcpUrl,
885
+ write
886
+ });
887
+ }
888
+ if (action !== "bootstrap") {
889
+ throw new Error(
890
+ "Usage: kody auth bootstrap (\u2026) | kody auth setup-git [\u2026] | kody auth remove-git [--api-url <url>] [--mcp-url <url>]"
891
+ );
892
+ }
893
+ const code = typeof parsed.values.code === "string" ? parsed.values.code.trim() : "";
894
+ const scopes = parseCliScopesFlag(
895
+ typeof parsed.values.scopes === "string" ? parsed.values.scopes : void 0
896
+ );
897
+ if (!code && !scopes) {
898
+ throw new Error(
899
+ "Provide --code <kody_bc_\u2026> from cliCredentialBootstrap (MCP api / kody.cliCredentialBootstrap), or --scopes <list> to mint one with the current kody login session or API token."
900
+ );
901
+ }
902
+ const lifetime = resolveCliTokenLifetime({
903
+ lifetime: typeof parsed.values.lifetime === "string" ? parsed.values.lifetime : void 0,
904
+ idleTtlSeconds: parseCliLifetimeSecondsFlag(
905
+ typeof parsed.values["idle-ttl-seconds"] === "string" ? parsed.values["idle-ttl-seconds"] : void 0,
906
+ "--idle-ttl-seconds"
907
+ ),
908
+ maxLifetimeSeconds: parseCliLifetimeSecondsFlag(
909
+ typeof parsed.values["max-lifetime-seconds"] === "string" ? parsed.values["max-lifetime-seconds"] : void 0,
910
+ "--max-lifetime-seconds"
911
+ )
912
+ });
913
+ const apiUrl = apiUrlFrom({
914
+ apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
915
+ });
916
+ if (code && scopes) {
917
+ throw new Error(
918
+ `--scopes cannot change a bootstrap code: its scopes are fixed when it is minted. From Kody MCP, call \`${cliBootstrapMintCall(scopes, bootstrapMintLifetimeFields(lifetime))}\` and redeem the new code, or drop --code to mint with the current kody login session or API token.`
919
+ );
920
+ }
921
+ const result = scopes ? await authBootstrapWithScopes({
922
+ scopes,
923
+ lifetime,
924
+ apiUrl,
925
+ mint: bootstrapMinter({
926
+ scopes,
927
+ lifetime,
928
+ mcpUrl,
929
+ apiUrl,
930
+ tokenValues: tokenFlagValues(parsed.values),
931
+ ...org ? { org } : {}
932
+ })
933
+ }) : await authBootstrap({
934
+ code,
935
+ apiUrl,
936
+ ...lifetime.kind === "alias" ? { lifetime: lifetime.lifetime } : {
937
+ idleTtlSeconds: lifetime.idleTtlSeconds,
938
+ maxLifetimeSeconds: lifetime.maxLifetimeSeconds
939
+ }
940
+ });
941
+ const storedScopes = result.stored.scopes?.join(", ") || "(none)";
942
+ write(
943
+ [
944
+ `Bootstrap API token stored for execute --local, search, whoami, api, and token-auth cloud execute.`,
945
+ `api: ${result.stored.apiUrl}`,
946
+ `token id: ${result.stored.tokenId}`,
947
+ `scopes: ${storedScopes}`,
948
+ `expires: ${result.stored.expiresAt ?? "unknown"}`,
949
+ result.backendKind === "file" && result.backendPath ? `OS keychain was unavailable; token saved at ${result.backendPath} (mode 0600).` : "Token stored in the OS keychain.",
950
+ ""
951
+ ].join("\n")
952
+ );
953
+ return 0;
954
+ }
955
+ case "git-credential": {
956
+ const {
957
+ handleGitCredential,
958
+ parseGitCredentialAction,
959
+ parseGitCredentialInput,
960
+ readGitCredentialStdin
961
+ } = await import("./git-credential-FUE3JE3T.js");
962
+ const action = parseGitCredentialAction(parsed.positionals);
963
+ const raw = await readGitCredentialStdin(process.stdin);
964
+ const output = await handleGitCredential({
965
+ action,
966
+ request: parseGitCredentialInput(raw),
967
+ apiUrl: apiUrlFrom({
968
+ apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
969
+ }),
970
+ mcpUrl
971
+ });
972
+ if (output) process.stdout.write(output);
973
+ return 0;
974
+ }
975
+ case "whoami": {
976
+ const { resolveTarget } = await import("./target-3QHY7JT4.js");
977
+ const target = resolveTarget({
978
+ command: "whoami",
979
+ flag: typeof parsed.values.target === "string" ? parsed.values.target : void 0
980
+ });
981
+ const tokenValues = tokenFlagValues(parsed.values);
982
+ let apiUrl = apiUrlFrom({
983
+ apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
984
+ });
985
+ if (target === "mock") {
986
+ const { ensureMockTarget } = await import("./mock-server-SV2IKC4I.js");
987
+ const mock = await ensureMockTarget({
988
+ resetStorage: parsed.values["reset-storage"] === true,
989
+ ...org ? { orgSlug: org } : {}
990
+ });
991
+ try {
992
+ const me = await fetch(`${mock.apiUrl}/v1/me${org ? `?org=${encodeURIComponent(org)}` : ""}`, {
993
+ headers: { authorization: `Bearer ${mock.token}` }
994
+ });
995
+ const body = await me.json();
996
+ if (json) {
997
+ write(`${JSON.stringify({ target: "mock", ...body }, null, 2)}
998
+ `);
999
+ } else {
1000
+ const userId = typeof body.user_id === "string" ? body.user_id : "user_mock";
1001
+ const username = typeof body.username === "string" ? body.username : "mock-user";
1002
+ const orgBody = body.org && typeof body.org === "object" ? body.org : {};
1003
+ write(
1004
+ [
1005
+ `target: mock`,
1006
+ `api: ${mock.apiUrl}`,
1007
+ `user: ${username} (${userId})`,
1008
+ `org: ${orgBody.slug ?? org ?? "mock-org"}`,
1009
+ ""
1010
+ ].join("\n")
1011
+ );
1012
+ }
1013
+ return me.ok ? 0 : 1;
1014
+ } finally {
1015
+ if (mock.started) await mock.server.close();
1016
+ }
1017
+ }
1018
+ if (shouldUseApiToken({
1019
+ tokenValues,
1020
+ mcpUrl,
1021
+ apiUrl,
1022
+ allowEnvWithoutLogin: true,
1023
+ ...org ? { org } : {}
1024
+ })) {
1025
+ const { whoamiWithApiToken } = await import("./open-api-client-DVVMLY7P.js");
1026
+ const identity = await whoamiWithApiToken({
1027
+ token: requireApiToken(tokenValues, process.env, "whoami", { apiUrl }),
1028
+ apiUrl,
1029
+ ...org ? { org } : {}
1030
+ });
1031
+ if (json) {
1032
+ write(`${JSON.stringify(identity, null, 2)}
1033
+ `);
1034
+ return 0;
1035
+ }
1036
+ const scopeLine = identity.token.scopes.join(", ") || "(none)";
1037
+ const userLine = identity.user ? `${identity.user.displayName} <${identity.user.email}>` : "(account:read not on this token)";
1038
+ write(
1039
+ [
1040
+ `api: ${identity.apiUrl}`,
1041
+ `auth: API token (${identity.token.id})`,
1042
+ `user: ${userLine}`,
1043
+ `scopes: ${scopeLine}`,
1044
+ `expires: ${identity.token.expiresAt ?? "unknown"}`,
1045
+ ""
1046
+ ].join("\n")
1047
+ );
1048
+ return 0;
1049
+ }
1050
+ const [{ ensureFreshCredentials }, { listKodyTools }] = await Promise.all([
1051
+ import("./auth-4FW6GCLG.js"),
1052
+ import("./mcp-G2AWTIXR.js")
1053
+ ]);
1054
+ const credentials = await ensureFreshCredentials({ mcpUrl, org });
1055
+ const tools = await listKodyTools({ mcpUrl, org });
1056
+ if (json) {
1057
+ write(
1058
+ `${JSON.stringify(
1059
+ {
1060
+ mcpUrl: credentials.mcpUrl,
1061
+ org: credentials.org ?? null,
1062
+ protocol: modernMcpProtocolVersion,
1063
+ scope: credentials.scope ?? null,
1064
+ tools: tools.map((tool) => tool.name)
1065
+ },
1066
+ null,
1067
+ 2
1068
+ )}
1069
+ `
1070
+ );
1071
+ return 0;
1072
+ }
1073
+ const orgLine = credentials.org ? `
1074
+ org: ${credentials.org}` : "";
1075
+ write(
1076
+ `Connected to ${credentials.mcpUrl} (${modernMcpProtocolVersion})${orgLine}
1077
+ Tools: ${tools.map((tool) => tool.name).join(", ") || "(none)"}
1078
+ `
1079
+ );
1080
+ return 0;
1081
+ }
1082
+ case "search": {
1083
+ const { resolveTarget } = await import("./target-3QHY7JT4.js");
1084
+ const target = resolveTarget({
1085
+ command: "search",
1086
+ flag: typeof parsed.values.target === "string" ? parsed.values.target : void 0
1087
+ });
1088
+ const query = parsed.positionals.join(" ").trim();
1089
+ const tokenValues = tokenFlagValues(parsed.values);
1090
+ let apiUrl = apiUrlFrom({
1091
+ apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
1092
+ });
1093
+ let closeMock;
1094
+ try {
1095
+ if (target === "mock") {
1096
+ const { ensureMockTarget } = await import("./mock-server-SV2IKC4I.js");
1097
+ const mock = await ensureMockTarget({
1098
+ resetStorage: parsed.values["reset-storage"] === true
1099
+ });
1100
+ apiUrl = mock.apiUrl;
1101
+ closeMock = mock.started ? () => mock.server.close() : void 0;
1102
+ const { searchWithApiToken } = await import("./open-api-client-DVVMLY7P.js");
1103
+ const result2 = await searchWithApiToken({
1104
+ token: mock.token,
1105
+ apiUrl,
1106
+ query: query || void 0,
1107
+ entity: typeof parsed.values.entity === "string" ? parsed.values.entity : void 0,
1108
+ domain: typeof parsed.values.domain === "string" ? parsed.values.domain : void 0,
1109
+ limit: typeof parsed.values.limit === "string" ? Number(parsed.values.limit) : void 0
1110
+ });
1111
+ write(formatToolResult(result2, json));
1112
+ return result2.isError ? 1 : 0;
1113
+ }
1114
+ if (shouldUseApiToken({
1115
+ tokenValues,
1116
+ mcpUrl,
1117
+ apiUrl,
1118
+ allowEnvWithoutLogin: true,
1119
+ ...org ? { org } : {}
1120
+ })) {
1121
+ const { searchWithApiToken } = await import("./open-api-client-DVVMLY7P.js");
1122
+ const result2 = await searchWithApiToken({
1123
+ token: requireApiToken(tokenValues, process.env, "search", { apiUrl }),
1124
+ apiUrl,
1125
+ ...org ? { org } : {},
1126
+ query: query || void 0,
1127
+ entity: typeof parsed.values.entity === "string" ? parsed.values.entity : void 0,
1128
+ domain: typeof parsed.values.domain === "string" ? parsed.values.domain : void 0,
1129
+ limit: typeof parsed.values.limit === "string" ? Number(parsed.values.limit) : void 0
1130
+ });
1131
+ write(formatToolResult(result2, json));
1132
+ return result2.isError ? 1 : 0;
1133
+ }
1134
+ const args = {};
1135
+ if (query) args.query = query;
1136
+ if (typeof parsed.values.entity === "string") args.entity = parsed.values.entity;
1137
+ if (typeof parsed.values.domain === "string") args.domain = parsed.values.domain;
1138
+ if (typeof parsed.values.limit === "string") args.limit = Number(parsed.values.limit);
1139
+ const { callKodyTool } = await import("./mcp-G2AWTIXR.js");
1140
+ const result = await callKodyTool({
1141
+ name: "search",
1142
+ args,
1143
+ mcpUrl,
1144
+ ...org ? { org } : {}
1145
+ });
1146
+ write(formatToolResult(result, json));
1147
+ return result.isError ? 1 : 0;
1148
+ } finally {
1149
+ await closeMock?.();
1150
+ }
1151
+ }
1152
+ case "execute": {
1153
+ const { resolveTarget } = await import("./target-3QHY7JT4.js");
1154
+ const target = resolveTarget({
1155
+ command: "execute",
1156
+ flag: typeof parsed.values.target === "string" ? parsed.values.target : void 0
1157
+ });
1158
+ const invoke = typeof parsed.values.invoke === "string" ? parsed.values.invoke : void 0;
1159
+ const hasCodeFlag = typeof parsed.values.code === "string";
1160
+ const hasFileFlag = typeof parsed.values.file === "string";
1161
+ const positionalModule = parsed.positionals.join("\n").trim();
1162
+ const local = parsed.values.local === true || target === "mock";
1163
+ const tokenValues = tokenFlagValues(parsed.values);
1164
+ const localPackageInvoke = invoke !== void 0 ? await tryResolveLocalPackageInvoke(invoke) : null;
1165
+ let publishedInvokeCode;
1166
+ if (local && invoke !== void 0 && !localPackageInvoke) {
1167
+ try {
1168
+ publishedInvokeCode = resolveExecuteInvokeCode(invoke);
1169
+ } catch {
1170
+ throw new Error(
1171
+ `--invoke ${JSON.stringify(invoke)} is neither a local package export nor a published package specifier. From a package directory, pass an export key from package.json#exports (e.g. \`--invoke ./greet\`). To call a published export locally, use \`--invoke kody:@scope/pkg/export\` (or \`@scope/pkg#export\`) \u2014 no \`--code "import \u2026"\` wrapper needed. Or pass --code / --file / a module string.`
1172
+ );
1173
+ }
1174
+ }
1175
+ if (executeSourcesConflict({ invoke, hasCodeFlag, hasFileFlag, positionalModule })) {
1176
+ throw new Error(
1177
+ "--invoke cannot be combined with --code, --file, or a module string."
1178
+ );
1179
+ }
1180
+ if (local) assertLocalExecuteNodeEngine();
1181
+ const fileArg = hasFileFlag ? parsed.values.file : void 0;
1182
+ const modulePath = localPackageInvoke?.modulePath ?? (!hasCodeFlag && fileArg !== void 0 && fileArg !== "-" ? fileArg : void 0);
1183
+ const code = publishedInvokeCode !== void 0 ? publishedInvokeCode : invoke !== void 0 && !localPackageInvoke ? void 0 : hasCodeFlag ? parsed.values.code : modulePath !== void 0 && !localPackageInvoke ? await readFile(modulePath, "utf8") : localPackageInvoke ? await readFile(localPackageInvoke.modulePath, "utf8") : fileArg === "-" ? await readStdin() : positionalModule || void 0;
1184
+ const credentials = parseCredentialFlags(
1185
+ Array.isArray(parsed.values.credential) ? parsed.values.credential.filter(
1186
+ (value) => typeof value === "string"
1187
+ ) : typeof parsed.values.credential === "string" ? [parsed.values.credential] : void 0
1188
+ );
1189
+ const args = buildExecuteToolArgs({
1190
+ // Local published invoke is already minted into `code`.
1191
+ invoke: localPackageInvoke || publishedInvokeCode !== void 0 ? void 0 : invoke,
1192
+ code: typeof code === "string" ? code : void 0,
1193
+ paramsJson: typeof parsed.values.params === "string" ? parsed.values.params : void 0,
1194
+ conversationId: typeof parsed.values["conversation-id"] === "string" ? parsed.values["conversation-id"] : void 0,
1195
+ credentials
1196
+ });
1197
+ const prodApiUrl = apiUrlFrom({
1198
+ apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
1199
+ });
1200
+ let apiUrl = prodApiUrl;
1201
+ const { parsePassthroughHosts } = await import("./mock-fetch-gateway-B5TFGGQS.js");
1202
+ const passthroughHosts = parsePassthroughHosts(
1203
+ typeof parsed.values.passthrough === "string" ? parsed.values.passthrough : void 0
1204
+ );
1205
+ if (passthroughHosts.length > 0 && target !== "mock") {
1206
+ writeErr(
1207
+ "note: `--passthrough` is ignored on `--target prod` (outbound fetch mocking is mock-only).\n"
1208
+ );
1209
+ }
1210
+ let closeMock;
1211
+ let mockToken;
1212
+ let mockDepResolve;
1213
+ let localPackageRun = localPackageInvoke;
1214
+ if (!localPackageRun && local && modulePath !== void 0) {
1215
+ try {
1216
+ const { loadPackageManifest } = await import("./package-manifest-QH2RU64C.js");
1217
+ const manifest = await loadPackageManifest(process.cwd());
1218
+ localPackageRun = {
1219
+ modulePath,
1220
+ kodyId: manifest.kodyId,
1221
+ packageRoot: manifest.root
1222
+ };
1223
+ } catch {
1224
+ localPackageRun = null;
1225
+ }
1226
+ }
1227
+ try {
1228
+ if (target === "mock") {
1229
+ const { ensureMockTarget } = await import("./mock-server-SV2IKC4I.js");
1230
+ const mock = await ensureMockTarget({
1231
+ resetStorage: parsed.values["reset-storage"] === true,
1232
+ packageId: localPackageRun ? `local:${localPackageRun.kodyId}` : void 0,
1233
+ ...org ? { orgSlug: org } : {}
1234
+ });
1235
+ apiUrl = mock.apiUrl;
1236
+ mockToken = mock.token;
1237
+ closeMock = mock.started ? () => mock.server.close() : void 0;
1238
+ const { tryResolveMockDepResolve } = await import("./mock-dep-resolve-TVABDNR7.js");
1239
+ mockDepResolve = await tryResolveMockDepResolve({
1240
+ tokenValues,
1241
+ apiUrl: prodApiUrl,
1242
+ mcpUrl,
1243
+ ...org ? { org } : {}
1244
+ });
1245
+ }
1246
+ if (localPackageRun) {
1247
+ const { buildLocalPackageContext, runLocalPackageModule } = await import("./local-package-run-2TMCAZZ2.js");
1248
+ const result2 = await runLocalPackageModule({
1249
+ modulePath: localPackageRun.modulePath,
1250
+ params: args.params,
1251
+ token: mockToken ?? await resolveLocalExecuteBearer({
1252
+ tokenValues,
1253
+ mcpUrl,
1254
+ apiUrl,
1255
+ purpose: "execute local package export",
1256
+ ...org ? { org } : {}
1257
+ }),
1258
+ apiUrl,
1259
+ target,
1260
+ packageContext: buildLocalPackageContext({
1261
+ kodyId: localPackageRun.kodyId,
1262
+ hostedUrl: "http://127.0.0.1:0"
1263
+ }),
1264
+ packageRoot: localPackageRun.packageRoot,
1265
+ ...org ? { org } : {},
1266
+ ...mockDepResolve ? { depResolve: mockDepResolve } : {},
1267
+ ...passthroughHosts.length > 0 && target === "mock" ? { passthroughHosts } : {},
1268
+ allowPrivateNetwork: parsed.values["allow-private-network"] === true,
1269
+ onStatus: (message) => writeErr(`${message}
1270
+ `)
1271
+ });
1272
+ write(formatToolResult(result2, json));
1273
+ return result2.isError ? 1 : 0;
1274
+ }
1275
+ const useToken = local || shouldUseApiToken({
1276
+ tokenValues,
1277
+ mcpUrl,
1278
+ apiUrl,
1279
+ allowEnvWithoutLogin: true,
1280
+ ...org ? { org } : {}
1281
+ });
1282
+ let packageRootForMocks;
1283
+ if (target === "mock") {
1284
+ try {
1285
+ const { loadPackageManifest } = await import("./package-manifest-QH2RU64C.js");
1286
+ packageRootForMocks = (await loadPackageManifest(process.cwd())).root;
1287
+ } catch {
1288
+ packageRootForMocks = void 0;
1289
+ }
1290
+ }
1291
+ const result = local ? await (await import("./local-execute-SZV6XN4T.js")).runLocalExecute({
1292
+ code: args.code,
1293
+ ...modulePath !== void 0 ? { modulePath } : {},
1294
+ params: args.params,
1295
+ conversationId: args.conversationId,
1296
+ ...credentials !== void 0 ? { credentials } : {},
1297
+ token: mockToken ?? await resolveLocalExecuteBearer({
1298
+ tokenValues,
1299
+ mcpUrl,
1300
+ apiUrl,
1301
+ purpose: "execute --local",
1302
+ ...org ? { org } : {}
1303
+ }),
1304
+ apiUrl,
1305
+ target,
1306
+ ...org ? { org } : {},
1307
+ ...mockDepResolve ? { depResolve: mockDepResolve } : {},
1308
+ ...packageRootForMocks ? { packageRoot: packageRootForMocks } : {},
1309
+ ...passthroughHosts.length > 0 ? { passthroughHosts } : {},
1310
+ allowPrivateNetwork: parsed.values["allow-private-network"] === true,
1311
+ onStatus: (message) => writeErr(`${message}
1312
+ `)
1313
+ }) : useToken ? await (await import("./remote-execute-QMQDVHOY.js")).runRemoteExecuteWithToken({
1314
+ code: typeof args.code === "string" ? args.code : void 0,
1315
+ invoke,
1316
+ params: args.params,
1317
+ conversationId: args.conversationId,
1318
+ ...credentials !== void 0 ? { credentials } : {},
1319
+ token: requireApiToken(
1320
+ tokenValues,
1321
+ process.env,
1322
+ "execute with an API token",
1323
+ { apiUrl }
1324
+ ),
1325
+ apiUrl,
1326
+ ...org ? { org } : {}
1327
+ }) : await (await import("./mcp-G2AWTIXR.js")).callKodyTool({
1328
+ name: "execute",
1329
+ args,
1330
+ mcpUrl,
1331
+ ...org ? { org } : {}
1332
+ });
1333
+ write(formatToolResult(result, json));
1334
+ return result.isError ? 1 : 0;
1335
+ } finally {
1336
+ await closeMock?.();
1337
+ }
1338
+ }
1339
+ case "dev": {
1340
+ const { resolveTarget } = await import("./target-3QHY7JT4.js");
1341
+ const {
1342
+ parseDevPort,
1343
+ parseDevSubcommand,
1344
+ resolveDevAuth,
1345
+ runDevCheck,
1346
+ runDevEmit,
1347
+ runDevFetch,
1348
+ runDevJob,
1349
+ runDevServe,
1350
+ runDevWebhook,
1351
+ tryAttachedDevFetch
1352
+ } = await import("./dev-command-3LX234N6.js");
1353
+ const target = resolveTarget({
1354
+ command: "dev",
1355
+ flag: typeof parsed.values.target === "string" ? parsed.values.target : void 0
1356
+ });
1357
+ const { subcommand, rest } = parseDevSubcommand(parsed.positionals);
1358
+ const tokenValues = tokenFlagValues(parsed.values);
1359
+ const prodApiUrl = apiUrlFrom({
1360
+ apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
1361
+ });
1362
+ const io = { stdout: write, stderr: writeErr };
1363
+ const bodyPath = typeof parsed.values.body === "string" ? parsed.values.body : void 0;
1364
+ if (subcommand === "check") {
1365
+ return await runDevCheck({ target, json, io });
1366
+ }
1367
+ const dryRun = parsed.values["dry-run"] === true;
1368
+ if (dryRun && subcommand !== "job" && subcommand !== "webhook" && subcommand !== "emit") {
1369
+ throw new Error(
1370
+ "`--dry-run` applies to `kody dev job|webhook|emit` only (shows the plan without invoking)."
1371
+ );
1372
+ }
1373
+ if (dryRun) {
1374
+ const dryAuth = { token: "dry-run", apiUrl: prodApiUrl };
1375
+ switch (subcommand) {
1376
+ case "job": {
1377
+ const jobName = rest[0];
1378
+ if (!jobName) throw new Error("Usage: kody dev job <name>");
1379
+ return await runDevJob({
1380
+ target,
1381
+ auth: dryAuth,
1382
+ jobName,
1383
+ json,
1384
+ dryRun: true,
1385
+ io
1386
+ });
1387
+ }
1388
+ case "webhook": {
1389
+ const webhookName = rest[0];
1390
+ if (!webhookName || !bodyPath) {
1391
+ throw new Error(
1392
+ "Usage: kody dev webhook <name> --body file.json"
1393
+ );
1394
+ }
1395
+ return await runDevWebhook({
1396
+ target,
1397
+ auth: dryAuth,
1398
+ webhookName,
1399
+ bodyPath,
1400
+ json,
1401
+ dryRun: true,
1402
+ io
1403
+ });
1404
+ }
1405
+ case "emit": {
1406
+ const event = rest[0];
1407
+ if (!event || !bodyPath) {
1408
+ throw new Error(
1409
+ "Usage: kody dev emit <event> --body event.json"
1410
+ );
1411
+ }
1412
+ return await runDevEmit({
1413
+ target,
1414
+ auth: dryAuth,
1415
+ event,
1416
+ bodyPath,
1417
+ json,
1418
+ dryRun: true,
1419
+ io
1420
+ });
1421
+ }
1422
+ default: {
1423
+ throw new Error(
1424
+ "`--dry-run` applies to `kody dev job|webhook|emit` only (shows the plan without invoking)."
1425
+ );
1426
+ }
1427
+ }
1428
+ }
1429
+ if (subcommand === "fetch" && parsed.values["no-attach"] !== true && rest[0]) {
1430
+ const attached = await tryAttachedDevFetch({
1431
+ target,
1432
+ path: rest[0],
1433
+ method: typeof parsed.values.method === "string" ? parsed.values.method : void 0,
1434
+ body: bodyPath ? await readFile(bodyPath, "utf8") : void 0,
1435
+ json,
1436
+ io
1437
+ });
1438
+ if (attached !== null) return attached;
1439
+ }
1440
+ const token = target === "prod" ? await resolveLocalExecuteBearer({
1441
+ tokenValues,
1442
+ mcpUrl,
1443
+ apiUrl: prodApiUrl,
1444
+ purpose: "kody dev",
1445
+ ...org ? { org } : {}
1446
+ }) : "mock";
1447
+ const mockDepResolve = target === "mock" ? await (await import("./mock-dep-resolve-TVABDNR7.js")).tryResolveMockDepResolve({
1448
+ tokenValues,
1449
+ apiUrl: prodApiUrl,
1450
+ mcpUrl,
1451
+ ...org ? { org } : {}
1452
+ }) : void 0;
1453
+ const { parsePassthroughHosts } = await import("./mock-fetch-gateway-B5TFGGQS.js");
1454
+ const passthroughHosts = parsePassthroughHosts(
1455
+ typeof parsed.values.passthrough === "string" ? parsed.values.passthrough : void 0
1456
+ );
1457
+ if (passthroughHosts.length > 0 && target !== "mock") {
1458
+ writeErr(
1459
+ "note: `--passthrough` is ignored on `--target prod` (outbound fetch mocking is mock-only).\n"
1460
+ );
1461
+ }
1462
+ const allowPrivateNetwork = parsed.values["allow-private-network"] === true;
1463
+ let packageId;
1464
+ try {
1465
+ const { loadPackageManifest } = await import("./package-manifest-QH2RU64C.js");
1466
+ const manifest = await loadPackageManifest(process.cwd());
1467
+ packageId = `local:${manifest.kodyId}`;
1468
+ } catch {
1469
+ packageId = void 0;
1470
+ }
1471
+ const auth = await resolveDevAuth({
1472
+ target,
1473
+ token,
1474
+ apiUrl: prodApiUrl,
1475
+ ...org ? { org } : {},
1476
+ ...mockDepResolve ? { depResolve: mockDepResolve } : {},
1477
+ ...passthroughHosts.length > 0 && target === "mock" ? { passthroughHosts } : {},
1478
+ resetStorage: parsed.values["reset-storage"] === true,
1479
+ ...packageId ? { packageId } : {},
1480
+ ...org && target === "mock" ? { orgSlug: org } : {}
1481
+ });
1482
+ const port = typeof parsed.values.port === "string" ? parseDevPort(parsed.values.port) : void 0;
1483
+ const appBasePath = typeof parsed.values["app-base-path"] === "string" ? parsed.values["app-base-path"] : void 0;
1484
+ try {
1485
+ switch (subcommand) {
1486
+ case "serve":
1487
+ return await runDevServe({
1488
+ target,
1489
+ auth,
1490
+ port,
1491
+ appBasePath,
1492
+ allowPrivateNetwork,
1493
+ liveReload: parsed.values["no-live-reload"] !== true,
1494
+ json,
1495
+ ...typeof parsed.values["ready-file"] === "string" ? { readyFile: parsed.values["ready-file"] } : {},
1496
+ io
1497
+ });
1498
+ case "fetch": {
1499
+ const path = rest[0];
1500
+ if (!path) {
1501
+ throw new Error(
1502
+ "Usage: kody dev fetch <path> [--method GET] [--body file.json]"
1503
+ );
1504
+ }
1505
+ let body;
1506
+ if (bodyPath) body = await readFile(bodyPath, "utf8");
1507
+ return await runDevFetch({
1508
+ target,
1509
+ auth,
1510
+ path,
1511
+ method: typeof parsed.values.method === "string" ? parsed.values.method : void 0,
1512
+ body,
1513
+ port,
1514
+ appBasePath,
1515
+ allowPrivateNetwork,
1516
+ json,
1517
+ io
1518
+ });
1519
+ }
1520
+ case "job": {
1521
+ const jobName = rest[0];
1522
+ if (!jobName) throw new Error("Usage: kody dev job <name>");
1523
+ return await runDevJob({
1524
+ target,
1525
+ auth,
1526
+ jobName,
1527
+ json,
1528
+ allowPrivateNetwork,
1529
+ io
1530
+ });
1531
+ }
1532
+ case "webhook": {
1533
+ const webhookName = rest[0];
1534
+ if (!webhookName || !bodyPath) {
1535
+ throw new Error(
1536
+ "Usage: kody dev webhook <name> --body file.json"
1537
+ );
1538
+ }
1539
+ return await runDevWebhook({
1540
+ target,
1541
+ auth,
1542
+ webhookName,
1543
+ bodyPath,
1544
+ json,
1545
+ allowPrivateNetwork,
1546
+ io
1547
+ });
1548
+ }
1549
+ case "emit": {
1550
+ const event = rest[0];
1551
+ if (!event || !bodyPath) {
1552
+ throw new Error(
1553
+ "Usage: kody dev emit <event> --body event.json"
1554
+ );
1555
+ }
1556
+ return await runDevEmit({
1557
+ target,
1558
+ auth,
1559
+ event,
1560
+ bodyPath,
1561
+ json,
1562
+ allowPrivateNetwork,
1563
+ io
1564
+ });
1565
+ }
1566
+ default: {
1567
+ const exhaustive = subcommand;
1568
+ throw new Error(
1569
+ `Unhandled kody dev subcommand: ${String(exhaustive)}`
1570
+ );
1571
+ }
1572
+ }
1573
+ } catch (error) {
1574
+ await auth.closeMock?.();
1575
+ throw error;
1576
+ }
1577
+ }
1578
+ case "api": {
1579
+ const operationId = parsed.positionals[0]?.trim() ?? "";
1580
+ if (!operationId || parsed.positionals.length > 1) {
1581
+ throw new Error(
1582
+ "Usage: kody api <operationId> [--params <json>] [--token <token>] [--api-url <url>] [--json]"
1583
+ );
1584
+ }
1585
+ const apiUrl = apiUrlFrom({
1586
+ apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
1587
+ });
1588
+ const tokenValues = tokenFlagValues(parsed.values);
1589
+ const params = parseApiParamsJson(
1590
+ typeof parsed.values.params === "string" ? parsed.values.params : void 0
1591
+ );
1592
+ const { callOpenApiOperation } = await import("./open-api-client-DVVMLY7P.js");
1593
+ const result = await callOpenApiOperation({
1594
+ operationId,
1595
+ params,
1596
+ token: requireApiToken(tokenValues, process.env, "api", { apiUrl }),
1597
+ apiUrl,
1598
+ ...org ? { org } : {}
1599
+ });
1600
+ write(`${JSON.stringify(result, null, 2)}
1601
+ `);
1602
+ return 0;
1603
+ }
1604
+ case "package": {
1605
+ const action = parsed.positionals[0];
1606
+ const apiUrl = apiUrlFrom({
1607
+ apiUrl: typeof parsed.values["api-url"] === "string" ? parsed.values["api-url"] : void 0
1608
+ });
1609
+ const tokenValues = tokenFlagValues(parsed.values);
1610
+ if (isPackageCollaboratorAction(action)) {
1611
+ const plan = parsePackageCollaboratorCommand({
1612
+ action,
1613
+ positionals: parsed.positionals.slice(1),
1614
+ values: parsed.values
1615
+ });
1616
+ const token = requireApiToken(tokenValues, process.env, `package ${action}`, {
1617
+ apiUrl
1618
+ });
1619
+ const { callOpenApiOperation: callOpenApiOperation2 } = await import("./open-api-client-DVVMLY7P.js");
1620
+ write(
1621
+ await runPackageCollaboratorPlan({
1622
+ plan,
1623
+ json,
1624
+ call: (operationId, params2) => callOpenApiOperation2({
1625
+ operationId,
1626
+ params: params2,
1627
+ token,
1628
+ apiUrl,
1629
+ ...org ? { org } : {}
1630
+ })
1631
+ })
1632
+ );
1633
+ return 0;
1634
+ }
1635
+ if (action !== "publish") {
1636
+ throw new Error(
1637
+ `Usage: kody package publish [<@owner/leaf|package_id>] [--params <json>] [--token <token>] [--api-url <url>] [--org <slug>]
1638
+ ${packageCollaboratorUsage}`
1639
+ );
1640
+ }
1641
+ const params = packagePublishParams({
1642
+ positional: parsed.positionals[1],
1643
+ paramsJson: typeof parsed.values.params === "string" ? parsed.values.params : void 0
1644
+ });
1645
+ const { callOpenApiOperation } = await import("./open-api-client-DVVMLY7P.js");
1646
+ const publishToken = requireApiToken(tokenValues, process.env, "package publish", {
1647
+ apiUrl
1648
+ });
1649
+ const call = (operationId, operationParams) => callOpenApiOperation({
1650
+ operationId,
1651
+ params: operationParams,
1652
+ token: publishToken,
1653
+ apiUrl,
1654
+ ...org ? { org } : {}
1655
+ });
1656
+ const result = await call(
1657
+ "packagePublishExternalPush",
1658
+ await resolvePackagePublishTarget(params, call)
1659
+ );
1660
+ write(`${JSON.stringify(result, null, 2)}
1661
+ `);
1662
+ return 0;
1663
+ }
1664
+ case "install": {
1665
+ const { runInstall } = await import("./install-ZML2TCDG.js");
1666
+ const result = await runInstall(
1667
+ {
1668
+ mcpUrl,
1669
+ clients: typeof parsed.values.clients === "string" ? parsed.values.clients : void 0,
1670
+ yes: parsed.values.yes === true,
1671
+ project: parsed.values.project === true,
1672
+ json
1673
+ },
1674
+ { stdout: write }
1675
+ );
1676
+ return result.code;
1677
+ }
1678
+ case "skill": {
1679
+ const action = parsed.positionals[0] ?? "install";
1680
+ if (action !== "install") {
1681
+ throw new Error("Usage: kody skill install [--project]");
1682
+ }
1683
+ const { installSkill } = await import("./skill-ENPATRIW.js");
1684
+ const targets = await installSkill({ project: parsed.values.project === true });
1685
+ write(
1686
+ `Installed the Kody skill to:
1687
+ ${targets.map((target) => `- ${target.host}: ${target.path}`).join("\n")}
1688
+ `
1689
+ );
1690
+ return 0;
1691
+ }
1692
+ default: {
1693
+ const exhaustive = parsed.command;
1694
+ throw new Error(`Unhandled command: ${String(exhaustive)}`);
1695
+ }
1696
+ }
1697
+ }
1698
+ async function readStdin() {
1699
+ const chunks = [];
1700
+ for await (const chunk of process.stdin) {
1701
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
1702
+ }
1703
+ return Buffer.concat(chunks).toString("utf8");
1704
+ }
1705
+ async function tryResolveLocalPackageInvoke(invoke) {
1706
+ const trimmed = invoke.trim();
1707
+ if (!trimmed) return null;
1708
+ if (isPublishedPackageInvokeSpecifier(trimmed)) return null;
1709
+ const { loadPackageManifest, resolveExportModulePath } = await import("./package-manifest-QH2RU64C.js");
1710
+ const { StructuredCliError } = await import("./structured-error-C65GQ53Z.js");
1711
+ let manifest;
1712
+ try {
1713
+ manifest = await loadPackageManifest(process.cwd());
1714
+ } catch {
1715
+ return null;
1716
+ }
1717
+ try {
1718
+ const modulePath = resolveExportModulePath(manifest, trimmed, {
1719
+ exportsOnly: true
1720
+ });
1721
+ const { access } = await import("node:fs/promises");
1722
+ try {
1723
+ await access(modulePath);
1724
+ } catch {
1725
+ throw new StructuredCliError({
1726
+ code: "dev_surface_missing",
1727
+ message: `No package export ${JSON.stringify(trimmed)} (path missing: ${modulePath}).`,
1728
+ where: manifest.packageJsonPath,
1729
+ fix: `Known exports: ${Object.keys(manifest.exports).join(", ") || "(none)"}.`
1730
+ });
1731
+ }
1732
+ return { modulePath, kodyId: manifest.kodyId, packageRoot: manifest.root };
1733
+ } catch (error) {
1734
+ if (error instanceof StructuredCliError) throw error;
1735
+ return null;
1736
+ }
1737
+ }
1738
+ function executeSourcesConflict(input) {
1739
+ return input.invoke !== void 0 && (input.hasCodeFlag || input.hasFileFlag || input.positionalModule.length > 0);
1740
+ }
1741
+ function buildExecuteToolArgs(input) {
1742
+ const invoke = input.invoke;
1743
+ const code = input.code;
1744
+ if (invoke !== void 0 && code !== void 0 && code.length > 0) {
1745
+ throw new Error("--invoke cannot be combined with --code, --file, or a module string.");
1746
+ }
1747
+ if (invoke !== void 0) {
1748
+ if (!invoke) {
1749
+ throw new Error("Provide a non-empty --invoke value.");
1750
+ }
1751
+ return attachExecuteCommonArgs({ invoke }, input);
1752
+ }
1753
+ if (code) {
1754
+ return attachExecuteCommonArgs({ code }, input);
1755
+ }
1756
+ throw new Error("Provide --invoke, --code, --file, or a module string.");
1757
+ }
1758
+ function attachExecuteCommonArgs(args, input) {
1759
+ if (input.paramsJson !== void 0) {
1760
+ args.params = JSON.parse(input.paramsJson);
1761
+ }
1762
+ if (input.conversationId !== void 0) {
1763
+ args.conversationId = input.conversationId;
1764
+ }
1765
+ if (input.credentials !== void 0) {
1766
+ args.credentials = input.credentials;
1767
+ }
1768
+ return args;
1769
+ }
1770
+ async function runAuthSetupGit(input) {
1771
+ const { authSetupGit, setupGitDefaultScopes } = await import("./setup-git-5KCUBYPB.js");
1772
+ const apiUrl = apiUrlFrom({
1773
+ apiUrl: typeof input.values["api-url"] === "string" ? input.values["api-url"] : void 0
1774
+ });
1775
+ const scopes = parseCliScopesFlag(
1776
+ typeof input.values.scopes === "string" ? input.values.scopes : void 0
1777
+ );
1778
+ const lifetime = resolveCliTokenLifetime({
1779
+ lifetime: typeof input.values.lifetime === "string" ? input.values.lifetime : "long",
1780
+ idleTtlSeconds: parseCliLifetimeSecondsFlag(
1781
+ typeof input.values["idle-ttl-seconds"] === "string" ? input.values["idle-ttl-seconds"] : void 0,
1782
+ "--idle-ttl-seconds"
1783
+ ),
1784
+ maxLifetimeSeconds: parseCliLifetimeSecondsFlag(
1785
+ typeof input.values["max-lifetime-seconds"] === "string" ? input.values["max-lifetime-seconds"] : void 0,
1786
+ "--max-lifetime-seconds"
1787
+ )
1788
+ });
1789
+ const tokenValues = tokenFlagValues(input.values);
1790
+ const mintScopes = scopes ?? setupGitDefaultScopes;
1791
+ const hasLoginSession = loadCredentials(input.mcpUrl, void 0, void 0, {
1792
+ org: input.org
1793
+ }) != null;
1794
+ const result = await authSetupGit({
1795
+ apiUrl,
1796
+ mcpUrl: input.mcpUrl,
1797
+ token: tokenValues.token,
1798
+ hasLoginSession,
1799
+ ...scopes ? { scopesOverride: scopes } : {},
1800
+ lifetime,
1801
+ mint: bootstrapMinter({
1802
+ scopes: mintScopes,
1803
+ lifetime,
1804
+ mcpUrl: input.mcpUrl,
1805
+ apiUrl,
1806
+ tokenValues,
1807
+ ...input.org ? { org: input.org } : {}
1808
+ })
1809
+ });
1810
+ input.write(
1811
+ [
1812
+ `Git HTTPS credential helper installed for https://${result.host}/`,
1813
+ `helper: ${result.helperCommand}`,
1814
+ `token: ${result.minted ? "minted" : "reused"} ${result.tokenId} (org_binding=user)`,
1815
+ `scopes: ${result.scopes.join(", ") || "(none)"}`,
1816
+ `expires: ${result.expiresAt ?? "unknown"}`,
1817
+ result.backendKind === "file" && result.backendPath ? `OS keychain was unavailable; token saved at ${result.backendPath} (mode 0600).` : result.minted ? "Token stored in the OS keychain (or existing store)." : "Using the existing stored API token.",
1818
+ "",
1819
+ "This user-owned token authorizes every @owner/name.git you can access (all orgs).",
1820
+ "Try: git clone https://kody.codes/@owner/name.git",
1821
+ "Undo later: kody auth remove-git",
1822
+ ""
1823
+ ].join("\n")
1824
+ );
1825
+ return 0;
1826
+ }
1827
+ async function runAuthRemoveGit(input) {
1828
+ const { authRemoveGit, formatAuthRemoveGitReport } = await import("./setup-git-5KCUBYPB.js");
1829
+ const apiUrl = apiUrlFrom({
1830
+ apiUrl: typeof input.values["api-url"] === "string" ? input.values["api-url"] : void 0
1831
+ });
1832
+ const result = await authRemoveGit({
1833
+ apiUrl,
1834
+ mcpUrl: input.mcpUrl
1835
+ });
1836
+ input.write(formatAuthRemoveGitReport(result));
1837
+ return 0;
1838
+ }
1839
+ function bootstrapMinter(input) {
1840
+ return async (params) => {
1841
+ if (shouldUseApiToken({
1842
+ tokenValues: input.tokenValues,
1843
+ mcpUrl: input.mcpUrl,
1844
+ apiUrl: input.apiUrl,
1845
+ allowEnvWithoutLogin: true,
1846
+ ...input.org ? { org: input.org } : {}
1847
+ })) {
1848
+ const token = requireApiToken(input.tokenValues, process.env, "auth bootstrap --scopes", {
1849
+ apiUrl: input.apiUrl
1850
+ });
1851
+ const { callOpenApiOperation } = await import("./open-api-client-DVVMLY7P.js");
1852
+ try {
1853
+ return await callOpenApiOperation({
1854
+ token,
1855
+ apiUrl: input.apiUrl,
1856
+ operationId: cliCredentialBootstrapOperationId,
1857
+ params,
1858
+ ...input.org ? { org: input.org } : {}
1859
+ });
1860
+ } catch (error) {
1861
+ if (error instanceof Error && /cannot grant scopes it does not hold/i.test(error.message)) {
1862
+ throw new Error(
1863
+ `${error.message} A token can only mint scopes it already holds. Run \`kody login\` and retry without --token (a login session can mint any scope your org role grants), or from Kody MCP call \`${cliBootstrapMintCall(input.scopes, bootstrapMintLifetimeFields(input.lifetime))}\` and run the returned cli_command.`
1864
+ );
1865
+ }
1866
+ throw error;
1867
+ }
1868
+ }
1869
+ if (loadCredentials(input.mcpUrl, void 0, void 0, {
1870
+ org: input.org
1871
+ })) {
1872
+ return (await import("./mcp-G2AWTIXR.js")).callKodyApiOperation({
1873
+ operationId: cliCredentialBootstrapOperationId,
1874
+ params,
1875
+ mcpUrl: input.mcpUrl,
1876
+ ...input.org ? { org: input.org } : {}
1877
+ });
1878
+ }
1879
+ throw new Error(
1880
+ `auth bootstrap --scopes mints with your current Kody credential, and none was found. Run \`kody login\` and retry, or from Kody MCP call \`${cliBootstrapMintCall(input.scopes, bootstrapMintLifetimeFields(input.lifetime))}\` and run the returned cli_command.`
1881
+ );
1882
+ };
1883
+ }
1884
+ function tokenFlagValues(values) {
1885
+ return {
1886
+ token: typeof values.token === "string" ? values.token : void 0
1887
+ };
1888
+ }
1889
+ function parseApiParamsJson(paramsJson) {
1890
+ if (paramsJson === void 0) return {};
1891
+ let parsed;
1892
+ try {
1893
+ parsed = JSON.parse(paramsJson);
1894
+ } catch {
1895
+ throw new Error("--params must be valid JSON (a flat object).");
1896
+ }
1897
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
1898
+ throw new Error(`--params must be a JSON object (e.g. '{"query":"email"}').`);
1899
+ }
1900
+ return parsed;
1901
+ }
1902
+ var packageIdUuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1903
+ function packagePublishParams(input) {
1904
+ const params = parseApiParamsJson(input.paramsJson);
1905
+ const ref = input.positional?.trim();
1906
+ if (!ref) return params;
1907
+ if (packageIdUuidPattern.test(ref)) {
1908
+ if (params.package_id === void 0) params.package_id = ref;
1909
+ } else if (params.kody_id === void 0) {
1910
+ params.kody_id = ref;
1911
+ }
1912
+ return params;
1913
+ }
1914
+ async function resolvePackagePublishTarget(params, call) {
1915
+ if (params.package_id !== void 0 || typeof params.kody_id !== "string") return params;
1916
+ const ref = params.kody_id.trim();
1917
+ const listed = await call("packageList", {});
1918
+ const packages = listed.packages ?? [];
1919
+ const leaf = ref.includes("/") ? ref.slice(ref.lastIndexOf("/") + 1) : ref;
1920
+ const byName = packages.filter((pkg) => pkg.name === ref);
1921
+ const matches = byName.length > 0 ? byName : ref.startsWith("@") ? [] : packages.filter((pkg) => pkg.kody_id === leaf);
1922
+ if (matches.length !== 1) {
1923
+ const known = packages.map((pkg) => pkg.name).slice(0, 20).join(", ");
1924
+ throw new Error(
1925
+ matches.length === 0 ? `No saved package named "${ref}" in this org.${known ? ` Saved packages: ${known}.` : ""} Pass the scoped name (@owner/leaf), the package_id, or --org <slug> for another org.` : `"${ref}" matches several saved packages (${matches.map((pkg) => `${pkg.name} = ${pkg.package_id}`).join(", ")}). Pass the scoped name or the package_id.`
1926
+ );
1927
+ }
1928
+ const { kody_id: _name, ...rest } = params;
1929
+ return { ...rest, package_id: matches[0].package_id };
1930
+ }
1931
+ function shouldUseApiToken(input) {
1932
+ if (hasExplicitTokenFlag(input.tokenValues)) return true;
1933
+ if (!input.allowEnvWithoutLogin) return false;
1934
+ if (!resolveScopedApiToken({
1935
+ tokenValues: input.tokenValues,
1936
+ env: input.env,
1937
+ apiUrl: input.apiUrl,
1938
+ loadApiToken: input.loadApiToken
1939
+ })) {
1940
+ return false;
1941
+ }
1942
+ const loggedIn = input.hasSession ?? loadCredentials(input.mcpUrl, void 0, void 0, {
1943
+ org: input.org
1944
+ }) != null;
1945
+ return !loggedIn;
1946
+ }
1947
+
1948
+ export {
1949
+ apiUrlFrom,
1950
+ resolveCommand,
1951
+ runCli,
1952
+ executeSourcesConflict,
1953
+ buildExecuteToolArgs,
1954
+ parseApiParamsJson,
1955
+ packagePublishParams,
1956
+ resolvePackagePublishTarget,
1957
+ shouldUseApiToken
1958
+ };
1959
+ //# sourceMappingURL=chunk-TIL35OWA.js.map