@kosuke-ai/kosuke 1.0.0 → 1.0.1

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 (352) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +198 -1
  3. package/dist/agent/http.js +18 -0
  4. package/dist/agent/summary.js +419 -0
  5. package/dist/commands/agent.js +22 -0
  6. package/dist/commands/auth.js +117 -0
  7. package/dist/commands/integrations.js +310 -0
  8. package/dist/commands/skill-runs.js +230 -0
  9. package/dist/commands/watch.js +167 -0
  10. package/dist/generated/commands/activity/list.js +73 -0
  11. package/dist/generated/commands/crons/artifacts-list.js +57 -0
  12. package/dist/generated/commands/crons/create.js +65 -0
  13. package/dist/generated/commands/crons/delete.js +18 -0
  14. package/dist/generated/commands/crons/get.js +19 -0
  15. package/dist/generated/commands/crons/list.js +54 -0
  16. package/dist/generated/commands/crons/projects-resume.js +21 -0
  17. package/dist/generated/commands/crons/run.js +37 -0
  18. package/dist/generated/commands/crons/runs-artifacts-get.js +23 -0
  19. package/dist/generated/commands/crons/runs-artifacts-list.js +22 -0
  20. package/dist/generated/commands/crons/runs-cancel.js +21 -0
  21. package/dist/generated/commands/crons/runs-diagnostics.js +20 -0
  22. package/dist/generated/commands/crons/runs-get.js +21 -0
  23. package/dist/generated/commands/crons/runs-list.js +58 -0
  24. package/dist/generated/commands/crons/runs-messages.js +21 -0
  25. package/dist/generated/commands/crons/update.js +73 -0
  26. package/dist/generated/commands/deploy/cancel.js +18 -0
  27. package/dist/generated/commands/deploy/list.js +33 -0
  28. package/dist/generated/commands/deploy/message.js +32 -0
  29. package/dist/generated/commands/deploy/messages.js +18 -0
  30. package/dist/generated/commands/deploy/queue-delete.js +19 -0
  31. package/dist/generated/commands/deploy/queue-list.js +19 -0
  32. package/dist/generated/commands/deploy/queue-move.js +31 -0
  33. package/dist/generated/commands/deploy/queue-resume.js +19 -0
  34. package/dist/generated/commands/deploy/queue-send.js +20 -0
  35. package/dist/generated/commands/deploy/queue-steer.js +20 -0
  36. package/dist/generated/commands/deploy/queue-update.js +56 -0
  37. package/dist/generated/commands/deploy/run.js +65 -0
  38. package/dist/generated/commands/deploy/set-model.js +28 -0
  39. package/dist/generated/commands/devices/list.js +18 -0
  40. package/dist/generated/commands/devices/request.js +31 -0
  41. package/dist/generated/commands/files/delete.js +18 -0
  42. package/dist/generated/commands/files/get.js +19 -0
  43. package/dist/generated/commands/files/list.js +25 -0
  44. package/dist/generated/commands/files/mkdir.js +28 -0
  45. package/dist/generated/commands/files/move.js +35 -0
  46. package/dist/generated/commands/files/put.js +92 -0
  47. package/dist/generated/commands/github/repositories.js +16 -0
  48. package/dist/generated/commands/github/status.js +16 -0
  49. package/dist/generated/commands/index.js +650 -0
  50. package/dist/generated/commands/integrations/execute.js +49 -0
  51. package/dist/generated/commands/integrations/tools.js +70 -0
  52. package/dist/generated/commands/mac/apps.js +30 -0
  53. package/dist/generated/commands/mac/ax-tree.js +65 -0
  54. package/dist/generated/commands/mac/browser-connection-check.js +69 -0
  55. package/dist/generated/commands/mac/browser-connections.js +30 -0
  56. package/dist/generated/commands/mac/browser-profiles.js +36 -0
  57. package/dist/generated/commands/mac/browser-sign-in.js +79 -0
  58. package/dist/generated/commands/mac/browser.js +44 -0
  59. package/dist/generated/commands/mac/click.js +72 -0
  60. package/dist/generated/commands/mac/file-delete.js +37 -0
  61. package/dist/generated/commands/mac/file-list.js +37 -0
  62. package/dist/generated/commands/mac/file-move.js +44 -0
  63. package/dist/generated/commands/mac/file-read.js +37 -0
  64. package/dist/generated/commands/mac/file-write.js +50 -0
  65. package/dist/generated/commands/mac/key.js +58 -0
  66. package/dist/generated/commands/mac/open.js +43 -0
  67. package/dist/generated/commands/mac/screenshot.js +51 -0
  68. package/dist/generated/commands/mac/scroll.js +70 -0
  69. package/dist/generated/commands/mac/shell.js +51 -0
  70. package/dist/generated/commands/mac/tools.js +18 -0
  71. package/dist/generated/commands/mac/type.js +64 -0
  72. package/dist/generated/commands/mac/windows.js +30 -0
  73. package/dist/generated/commands/members/list.js +24 -0
  74. package/dist/generated/commands/models/list.js +16 -0
  75. package/dist/generated/commands/personal-tasks/create.js +72 -0
  76. package/dist/generated/commands/personal-tasks/delete.js +17 -0
  77. package/dist/generated/commands/personal-tasks/get.js +20 -0
  78. package/dist/generated/commands/personal-tasks/list.js +71 -0
  79. package/dist/generated/commands/personal-tasks/move.js +31 -0
  80. package/dist/generated/commands/personal-tasks/start.js +69 -0
  81. package/dist/generated/commands/personal-tasks/update.js +81 -0
  82. package/dist/generated/commands/preview/get.js +26 -0
  83. package/dist/generated/commands/preview/health.js +26 -0
  84. package/dist/generated/commands/preview/reset.js +28 -0
  85. package/dist/generated/commands/preview/share-create.js +37 -0
  86. package/dist/generated/commands/preview/share-delete.js +26 -0
  87. package/dist/generated/commands/preview/share-get.js +27 -0
  88. package/dist/generated/commands/preview/shared-artifact.js +19 -0
  89. package/dist/generated/commands/preview/shared.js +17 -0
  90. package/dist/generated/commands/projects/backlog-items-create.js +35 -0
  91. package/dist/generated/commands/projects/backlog-items-delete.js +19 -0
  92. package/dist/generated/commands/projects/backlog-items-list.js +19 -0
  93. package/dist/generated/commands/projects/backlog-items-send.js +20 -0
  94. package/dist/generated/commands/projects/backlog-items-update.js +42 -0
  95. package/dist/generated/commands/projects/batch-merging-eject.js +37 -0
  96. package/dist/generated/commands/projects/batch-merging-finish.js +30 -0
  97. package/dist/generated/commands/projects/batch-merging-get.js +19 -0
  98. package/dist/generated/commands/projects/batch-merging-set.js +32 -0
  99. package/dist/generated/commands/projects/branches.js +31 -0
  100. package/dist/generated/commands/projects/create.js +72 -0
  101. package/dist/generated/commands/projects/delete.js +17 -0
  102. package/dist/generated/commands/projects/env-vars-add.js +22 -0
  103. package/dist/generated/commands/projects/env-vars-remove.js +21 -0
  104. package/dist/generated/commands/projects/get.js +18 -0
  105. package/dist/generated/commands/projects/labels-color.js +37 -0
  106. package/dist/generated/commands/projects/labels-delete.js +50 -0
  107. package/dist/generated/commands/projects/labels-usage.js +27 -0
  108. package/dist/generated/commands/projects/labels.js +18 -0
  109. package/dist/generated/commands/projects/list.js +16 -0
  110. package/dist/generated/commands/projects/live-logs.js +34 -0
  111. package/dist/generated/commands/projects/live-query.js +30 -0
  112. package/dist/generated/commands/projects/live-traffic.js +27 -0
  113. package/dist/generated/commands/projects/live-write-status.js +20 -0
  114. package/dist/generated/commands/projects/live-write.js +37 -0
  115. package/dist/generated/commands/projects/qa-guide-get.js +19 -0
  116. package/dist/generated/commands/projects/qa-guide-set.js +40 -0
  117. package/dist/generated/commands/projects/releases.js +18 -0
  118. package/dist/generated/commands/projects/services-add.js +88 -0
  119. package/dist/generated/commands/projects/services-list.js +19 -0
  120. package/dist/generated/commands/projects/services-remove.js +19 -0
  121. package/dist/generated/commands/projects/services-update.js +82 -0
  122. package/dist/generated/commands/projects/settings-get.js +19 -0
  123. package/dist/generated/commands/projects/settings-import.js +99 -0
  124. package/dist/generated/commands/projects/settings-update.js +85 -0
  125. package/dist/generated/commands/projects/skills.js +39 -0
  126. package/dist/generated/commands/projects/switch-workflow.js +34 -0
  127. package/dist/generated/commands/projects/update.js +28 -0
  128. package/dist/generated/commands/projects/versions.js +18 -0
  129. package/dist/generated/commands/sensei/cards-close.js +43 -0
  130. package/dist/generated/commands/sensei/cards-mark-read.js +30 -0
  131. package/dist/generated/commands/sensei/cards-put.js +152 -0
  132. package/dist/generated/commands/sensei/cards-send-reply.js +30 -0
  133. package/dist/generated/commands/sensei/cards.js +38 -0
  134. package/dist/generated/commands/sensei/chat.js +23 -0
  135. package/dist/generated/commands/sensei/connect.js +57 -0
  136. package/dist/generated/commands/sensei/delegates-get.js +21 -0
  137. package/dist/generated/commands/sensei/delegates-note.js +46 -0
  138. package/dist/generated/commands/sensei/delegates-start.js +51 -0
  139. package/dist/generated/commands/sensei/delegates-stop.js +21 -0
  140. package/dist/generated/commands/sensei/describe.js +36 -0
  141. package/dist/generated/commands/sensei/device-requests-decide.js +48 -0
  142. package/dist/generated/commands/sensei/device-requests-list.js +27 -0
  143. package/dist/generated/commands/sensei/memory-get.js +19 -0
  144. package/dist/generated/commands/sensei/memory-put.js +55 -0
  145. package/dist/generated/commands/sensei/merge-rule.js +36 -0
  146. package/dist/generated/commands/sensei/merge.js +36 -0
  147. package/dist/generated/commands/sensei/messages-reply.js +44 -0
  148. package/dist/generated/commands/sensei/messages-reroute.js +37 -0
  149. package/dist/generated/commands/sensei/messages-send.js +98 -0
  150. package/dist/generated/commands/sensei/notifications-open.js +19 -0
  151. package/dist/generated/commands/sensei/reels-activity.js +16 -0
  152. package/dist/generated/commands/sensei/reels-proposals.js +24 -0
  153. package/dist/generated/commands/sensei/reels-ranks.js +16 -0
  154. package/dist/generated/commands/sensei/reels-skips.js +32 -0
  155. package/dist/generated/commands/sensei/repository.js +36 -0
  156. package/dist/generated/commands/sensei/review-approve.js +37 -0
  157. package/dist/generated/commands/sensei/review-ask.js +44 -0
  158. package/dist/generated/commands/sensei/review-context.js +32 -0
  159. package/dist/generated/commands/sensei/sessions-assess.js +71 -0
  160. package/dist/generated/commands/sensei/sessions-facts.js +26 -0
  161. package/dist/generated/commands/sensei/suggest.js +36 -0
  162. package/dist/generated/commands/sensei/thread-done.js +21 -0
  163. package/dist/generated/commands/sensei/thread-move.js +30 -0
  164. package/dist/generated/commands/sensei/thread-read.js +41 -0
  165. package/dist/generated/commands/sensei/thread-split.js +30 -0
  166. package/dist/generated/commands/sensei/threads.js +47 -0
  167. package/dist/generated/commands/sensei/tickets-merge.js +51 -0
  168. package/dist/generated/commands/sensei/widgets.js +15 -0
  169. package/dist/generated/commands/sessions/activate.js +33 -0
  170. package/dist/generated/commands/sessions/all.js +142 -0
  171. package/dist/generated/commands/sessions/app-stack-start.js +20 -0
  172. package/dist/generated/commands/sessions/artifacts-attach.js +31 -0
  173. package/dist/generated/commands/sessions/artifacts-get.js +21 -0
  174. package/dist/generated/commands/sessions/artifacts-list.js +20 -0
  175. package/dist/generated/commands/sessions/create.js +234 -0
  176. package/dist/generated/commands/sessions/delete.js +21 -0
  177. package/dist/generated/commands/sessions/desktop-control.js +35 -0
  178. package/dist/generated/commands/sessions/desktop-start.js +19 -0
  179. package/dist/generated/commands/sessions/desktop.js +19 -0
  180. package/dist/generated/commands/sessions/diff-comments-add.js +65 -0
  181. package/dist/generated/commands/sessions/diff-comments-delete.js +21 -0
  182. package/dist/generated/commands/sessions/diff-comments-list.js +21 -0
  183. package/dist/generated/commands/sessions/diff-comments-update.js +25 -0
  184. package/dist/generated/commands/sessions/diff-commits.js +20 -0
  185. package/dist/generated/commands/sessions/diff-files.js +20 -0
  186. package/dist/generated/commands/sessions/diff-patch.js +87 -0
  187. package/dist/generated/commands/sessions/edit-prompt.js +81 -0
  188. package/dist/generated/commands/sessions/files-get.js +28 -0
  189. package/dist/generated/commands/sessions/files-list.js +20 -0
  190. package/dist/generated/commands/sessions/files-write.js +42 -0
  191. package/dist/generated/commands/sessions/get.js +19 -0
  192. package/dist/generated/commands/sessions/git-commit-message.js +20 -0
  193. package/dist/generated/commands/sessions/git-commit.js +30 -0
  194. package/dist/generated/commands/sessions/git-push.js +20 -0
  195. package/dist/generated/commands/sessions/git-state.js +20 -0
  196. package/dist/generated/commands/sessions/jobs-cancel.js +21 -0
  197. package/dist/generated/commands/sessions/jobs-get.js +21 -0
  198. package/dist/generated/commands/sessions/jobs-list.js +35 -0
  199. package/dist/generated/commands/sessions/labels-edit.js +45 -0
  200. package/dist/generated/commands/sessions/labels-set.js +45 -0
  201. package/dist/generated/commands/sessions/list.js +130 -0
  202. package/dist/generated/commands/sessions/mark-read.js +19 -0
  203. package/dist/generated/commands/sessions/message.js +33 -0
  204. package/dist/generated/commands/sessions/messages.js +41 -0
  205. package/dist/generated/commands/sessions/needs-you.js +16 -0
  206. package/dist/generated/commands/sessions/qa-clear.js +22 -0
  207. package/dist/generated/commands/sessions/qa-set.js +33 -0
  208. package/dist/generated/commands/sessions/queue-delete.js +23 -0
  209. package/dist/generated/commands/sessions/queue-list.js +20 -0
  210. package/dist/generated/commands/sessions/queue-move.js +32 -0
  211. package/dist/generated/commands/sessions/queue-resume.js +20 -0
  212. package/dist/generated/commands/sessions/queue-send.js +21 -0
  213. package/dist/generated/commands/sessions/queue-steer.js +21 -0
  214. package/dist/generated/commands/sessions/queue-update.js +57 -0
  215. package/dist/generated/commands/sessions/runtime-command.js +39 -0
  216. package/dist/generated/commands/sessions/search.js +24 -0
  217. package/dist/generated/commands/sessions/send.js +138 -0
  218. package/dist/generated/commands/sessions/steer.js +36 -0
  219. package/dist/generated/commands/sessions/sync.js +37 -0
  220. package/dist/generated/commands/sessions/title-generate.js +29 -0
  221. package/dist/generated/commands/sessions/update.js +118 -0
  222. package/dist/generated/commands/tasks/all.js +112 -0
  223. package/dist/generated/commands/tasks/create.js +230 -0
  224. package/dist/generated/commands/tasks/delete.js +18 -0
  225. package/dist/generated/commands/tasks/get.js +19 -0
  226. package/dist/generated/commands/tasks/labels.js +18 -0
  227. package/dist/generated/commands/tasks/list.js +114 -0
  228. package/dist/generated/commands/tasks/start.js +68 -0
  229. package/dist/generated/commands/tasks/update.js +136 -0
  230. package/dist/generated/commands/user/auth-token-revoke.js +16 -0
  231. package/dist/generated/commands/user/crons-artifacts-list.js +59 -0
  232. package/dist/generated/commands/user/crons-create.js +65 -0
  233. package/dist/generated/commands/user/crons-get.js +21 -0
  234. package/dist/generated/commands/user/crons-list.js +41 -0
  235. package/dist/generated/commands/user/crons-run.js +21 -0
  236. package/dist/generated/commands/user/crons-runs-artifacts-get.js +25 -0
  237. package/dist/generated/commands/user/crons-runs-artifacts-list.js +24 -0
  238. package/dist/generated/commands/user/crons-runs-get.js +23 -0
  239. package/dist/generated/commands/user/crons-runs-list.js +52 -0
  240. package/dist/generated/commands/user/crons-update.js +73 -0
  241. package/dist/generated/commands/user/files-delete.js +18 -0
  242. package/dist/generated/commands/user/files-get.js +19 -0
  243. package/dist/generated/commands/user/files-list.js +24 -0
  244. package/dist/generated/commands/user/files-mkdir.js +27 -0
  245. package/dist/generated/commands/user/files-move.js +35 -0
  246. package/dist/generated/commands/user/files-put.js +91 -0
  247. package/dist/generated/commands/user/integrations-linkedin-connect.js +35 -0
  248. package/dist/generated/commands/user/integrations-linkedin-list.js +17 -0
  249. package/dist/generated/commands/user/integrations-linkedin-reconnect.js +19 -0
  250. package/dist/generated/commands/user/integrations-list.js +16 -0
  251. package/dist/generated/commands/user/integrations-remove.js +19 -0
  252. package/dist/generated/commands/user/integrations-x-connect.js +35 -0
  253. package/dist/generated/commands/user/integrations-x-list.js +17 -0
  254. package/dist/generated/commands/user/integrations-x-reconnect.js +19 -0
  255. package/dist/generated/commands/user/memory-list.js +16 -0
  256. package/dist/generated/commands/user/memory-put.js +36 -0
  257. package/dist/generated/commands/user/plugins-list.js +28 -0
  258. package/dist/generated/commands/user/plugins-update.js +29 -0
  259. package/dist/generated/commands/user/profile.js +16 -0
  260. package/dist/generated/commands/user/push-devices-register.js +76 -0
  261. package/dist/generated/commands/user/push-devices-remove.js +26 -0
  262. package/dist/generated/commands/user/skills-create.js +33 -0
  263. package/dist/generated/commands/user/skills-delete.js +18 -0
  264. package/dist/generated/commands/user/skills-get.js +19 -0
  265. package/dist/generated/commands/user/skills-list.js +17 -0
  266. package/dist/generated/commands/user/skills-update.js +35 -0
  267. package/dist/generated/commands/user/subscriptions-delete.js +18 -0
  268. package/dist/generated/commands/user/subscriptions-get.js +17 -0
  269. package/dist/generated/commands/user/subscriptions-grok-change.js +20 -0
  270. package/dist/generated/commands/user/subscriptions-grok-get.js +18 -0
  271. package/dist/generated/commands/user/subscriptions-login-antigravity-cancel.js +34 -0
  272. package/dist/generated/commands/user/subscriptions-login-antigravity-complete.js +40 -0
  273. package/dist/generated/commands/user/subscriptions-login-antigravity-start.js +28 -0
  274. package/dist/generated/commands/user/subscriptions-login-claude-complete.js +34 -0
  275. package/dist/generated/commands/user/subscriptions-login-claude-start.js +29 -0
  276. package/dist/generated/commands/user/subscriptions-login-codex-complete.js +28 -0
  277. package/dist/generated/commands/user/subscriptions-login-codex-start.js +29 -0
  278. package/dist/generated/commands/user/subscriptions-login-muse-complete.js +28 -0
  279. package/dist/generated/commands/user/subscriptions-login-muse-start.js +29 -0
  280. package/dist/generated/commands/user/subscriptions-logins-delete.js +20 -0
  281. package/dist/generated/commands/user/subscriptions-logins-recheck.js +19 -0
  282. package/dist/generated/commands/user/subscriptions-set-default-model.js +33 -0
  283. package/dist/generated/commands/user/subscriptions-set-key.js +35 -0
  284. package/dist/generated/commands/user/subscriptions-token-usage.js +17 -0
  285. package/dist/generated/commands/user/subscriptions-usage.js +52 -0
  286. package/dist/generated/commands/workspaces/access-status.js +30 -0
  287. package/dist/generated/commands/workspaces/ai-provider-get.js +19 -0
  288. package/dist/generated/commands/workspaces/ai-provider-google-delete-method.js +33 -0
  289. package/dist/generated/commands/workspaces/ai-provider-google-get.js +20 -0
  290. package/dist/generated/commands/workspaces/ai-provider-google-remove.js +19 -0
  291. package/dist/generated/commands/workspaces/ai-provider-google-save.js +38 -0
  292. package/dist/generated/commands/workspaces/ai-provider-google-select-method.js +39 -0
  293. package/dist/generated/commands/workspaces/ai-provider-google-usage.js +39 -0
  294. package/dist/generated/commands/workspaces/ai-provider-login-antigravity-cancel.js +36 -0
  295. package/dist/generated/commands/workspaces/ai-provider-login-antigravity-complete.js +42 -0
  296. package/dist/generated/commands/workspaces/ai-provider-login-antigravity-start.js +30 -0
  297. package/dist/generated/commands/workspaces/ai-provider-logins-recheck.js +41 -0
  298. package/dist/generated/commands/workspaces/ai-provider-remove.js +57 -0
  299. package/dist/generated/commands/workspaces/ai-provider-set.js +21 -0
  300. package/dist/generated/commands/workspaces/ai-provider-token-usage.js +19 -0
  301. package/dist/generated/commands/workspaces/ai-provider-usage-claude.js +39 -0
  302. package/dist/generated/commands/workspaces/ai-provider-usage-codex.js +39 -0
  303. package/dist/generated/commands/workspaces/ai-provider-usage-coding-plan.js +32 -0
  304. package/dist/generated/commands/workspaces/ai-provider-usage-deepseek.js +32 -0
  305. package/dist/generated/commands/workspaces/ai-provider-usage-grok.js +39 -0
  306. package/dist/generated/commands/workspaces/ai-provider-usage-kimi-code.js +32 -0
  307. package/dist/generated/commands/workspaces/ai-provider-usage-muse.js +39 -0
  308. package/dist/generated/commands/workspaces/artifacts.js +26 -0
  309. package/dist/generated/commands/workspaces/credits.js +18 -0
  310. package/dist/generated/commands/workspaces/get.js +18 -0
  311. package/dist/generated/commands/workspaces/grok-change.js +21 -0
  312. package/dist/generated/commands/workspaces/grok-get.js +19 -0
  313. package/dist/generated/commands/workspaces/integrations-get.js +20 -0
  314. package/dist/generated/commands/workspaces/integrations-list.js +37 -0
  315. package/dist/generated/commands/workspaces/integrations-remove.js +19 -0
  316. package/dist/generated/commands/workspaces/list.js +16 -0
  317. package/dist/generated/commands/workspaces/members.js +26 -0
  318. package/dist/generated/commands/workspaces/plugins-list.js +30 -0
  319. package/dist/generated/commands/workspaces/plugins-update.js +30 -0
  320. package/dist/generated/commands/workspaces/provider-login-claude-complete.js +35 -0
  321. package/dist/generated/commands/workspaces/provider-login-claude-start.js +30 -0
  322. package/dist/generated/commands/workspaces/provider-login-codex-complete.js +29 -0
  323. package/dist/generated/commands/workspaces/provider-login-codex-start.js +30 -0
  324. package/dist/generated/commands/workspaces/provider-login-muse-complete.js +29 -0
  325. package/dist/generated/commands/workspaces/provider-login-muse-start.js +30 -0
  326. package/dist/generated/commands/workspaces/sandbox-limit.js +18 -0
  327. package/dist/generated/commands/workspaces/skills-create.js +35 -0
  328. package/dist/generated/commands/workspaces/skills-delete.js +19 -0
  329. package/dist/generated/commands/workspaces/skills-get.js +20 -0
  330. package/dist/generated/commands/workspaces/skills-list.js +19 -0
  331. package/dist/generated/commands/workspaces/skills-update.js +36 -0
  332. package/dist/generated/commands/workspaces/stop-sandboxes.js +28 -0
  333. package/dist/generated/commands/workspaces/timezone-set.js +29 -0
  334. package/dist/generated/commands/workspaces/usage.js +33 -0
  335. package/dist/generated/providers.js +31 -0
  336. package/dist/index.js +7 -0
  337. package/dist/integrations/api.js +136 -0
  338. package/dist/integrations/render.js +59 -0
  339. package/dist/program.js +73 -0
  340. package/dist/runtime/agent-tokens.js +39 -0
  341. package/dist/runtime/attach.js +199 -0
  342. package/dist/runtime/attachments.js +63 -0
  343. package/dist/runtime/client.js +188 -0
  344. package/dist/runtime/config.js +49 -0
  345. package/dist/runtime/credentials.js +32 -0
  346. package/dist/runtime/descriptor.js +7 -0
  347. package/dist/runtime/invoke.js +152 -0
  348. package/dist/runtime/job-watch.js +374 -0
  349. package/dist/runtime/runtime.js +46 -0
  350. package/dist/runtime/version.js +5 -0
  351. package/openapi.json +26091 -0
  352. package/package.json +103 -4
@@ -0,0 +1,199 @@
1
+ import { Argument, Command, InvalidArgumentError, Option } from 'commander';
2
+ import { buildRequest, execute, readWholeBody, UsageError } from './invoke.js';
3
+ /**
4
+ * One commander command per operation descriptor: positionals for path
5
+ * params, a flag per top-level field, `--body`/`--body-file` for a whole
6
+ * body and `--attach` where the operation takes files. The command's help is
7
+ * the contract's summary, verbatim.
8
+ */
9
+ export function attachOperation(root, operation, runtime) {
10
+ const leaf = attachLeaf(root, operation.command, operation, runtime, { hidden: false });
11
+ const name = operation.command.join(' ');
12
+ for (const [alias, target] of COMMAND_ALIASES) {
13
+ if (target === name) {
14
+ attachLeaf(root, alias.split(' '), operation, runtime, {
15
+ hidden: true,
16
+ workspaceArgument: true,
17
+ });
18
+ }
19
+ }
20
+ return leaf;
21
+ }
22
+ // Alias: Sensei's commands from when it was a workspace's, `kosuke workspaces sensei-* <id>`,
23
+ // and the Lead's names for them, which an older sandbox's Sensei prompt still runs; remove the
24
+ // Lead's one release after the Sensei rename, Sensei's one release after Sensei moved to the
25
+ // person. The workspace they take goes to `--workspace` where the command reads one.
26
+ const COMMAND_ALIASES = new Map([
27
+ ['cards', 'sensei cards'],
28
+ ['merge', 'sensei merge'],
29
+ ['notifications open', 'sensei notifications open'],
30
+ ].flatMap(([old, target]) => [
31
+ [`workspaces sensei-${old}`, target],
32
+ [`workspaces lead-${old}`, target],
33
+ ]));
34
+ function attachLeaf(root, path, operation, runtime, { hidden, workspaceArgument = false }) {
35
+ const parent = groupFor(root, path.slice(0, -1), { hidden });
36
+ const leaf = parent.command(path[path.length - 1], { hidden });
37
+ leaf.description(operation.summary);
38
+ if (workspaceArgument)
39
+ leaf.addArgument(new Argument('<workspaceId>', 'Workspace id'));
40
+ for (const name of operation.pathParams) {
41
+ leaf.addArgument(new Argument(`<${name}>`, humanize(name)));
42
+ }
43
+ const fields = dedupe([
44
+ ...operation.query,
45
+ ...(operation.body?.fields ?? []),
46
+ ...(operation.multipart ?? []),
47
+ ]);
48
+ for (const field of fields) {
49
+ leaf.addOption(optionFor(field));
50
+ // Both spellings, so a field whose meaningful value is false (members
51
+ // --no-include-invitations) can be said; neither given leaves it unsent.
52
+ if (field.kind === 'boolean') {
53
+ leaf.addOption(new Option(`--no-${field.flag}`, `Send ${field.name} as false.`));
54
+ }
55
+ }
56
+ const takesBody = operation.body !== null || operation.multipart !== null;
57
+ if (takesBody) {
58
+ leaf.option('--body <json>', 'The whole request body as JSON; overrides field flags.');
59
+ leaf.option('--body-file <path>', 'Read the whole request body from a file, or - for stdin.');
60
+ }
61
+ if (operation.attachments) {
62
+ leaf.option('--attach <path>', 'Attach a file; repeat for several. Sends the request as multipart.', collect, []);
63
+ }
64
+ leaf.action(async (...args) => {
65
+ const options = args[args.length - 2];
66
+ const offset = workspaceArgument ? 1 : 0;
67
+ const positionals = args.slice(offset, offset + operation.pathParams.length);
68
+ const workspace = workspaceArgument ? args[0] : undefined;
69
+ const input = {
70
+ pathParams: Object.fromEntries(operation.pathParams.map((name, i) => [name, positionals[i]])),
71
+ fields: Object.fromEntries(fields.map((field) => {
72
+ const given = options[optionKey(field.flag)];
73
+ // The old command's workspace filters a read that takes one; a write names its own.
74
+ const value = given ?? (field.name === 'workspace' ? workspace : undefined);
75
+ return [field.name, value];
76
+ })),
77
+ wholeBody: readWholeBody({
78
+ body: options.body,
79
+ bodyFile: options.bodyFile,
80
+ }),
81
+ attachments: options.attach ?? [],
82
+ };
83
+ let request;
84
+ try {
85
+ request = buildRequest(operation, input);
86
+ }
87
+ catch (error) {
88
+ if (error instanceof UsageError)
89
+ leaf.error(error.message);
90
+ throw error;
91
+ }
92
+ const client = runtime.client({
93
+ anonymous: operation.anonymous,
94
+ answerTimeoutMs: operation.answerTimeoutMs,
95
+ });
96
+ const outcome = await execute(client, request);
97
+ runtime.output(outcome);
98
+ });
99
+ return leaf;
100
+ }
101
+ /** A group created here is hidden when asked; one that already exists keeps what it is. */
102
+ export function groupFor(root, path, { hidden = false } = {}) {
103
+ let current = root;
104
+ for (const segment of path) {
105
+ const existing = current.commands.find((command) => command.name() === segment);
106
+ current =
107
+ existing ?? current.command(segment, { hidden }).description(`${humanize(segment)} commands`);
108
+ }
109
+ return current;
110
+ }
111
+ function optionFor(field) {
112
+ const description = field.description ?? '';
113
+ if (field.repeated)
114
+ return repeatedOption(field, description);
115
+ if (field.kind === 'boolean')
116
+ return new Option(`--${field.flag}`, description);
117
+ const option = new Option(`--${field.flag} <value>`, description);
118
+ if (field.choices)
119
+ option.choices([...field.choices]);
120
+ if (field.kind === 'number' || field.kind === 'integer')
121
+ option.argParser(numberParser(field));
122
+ if (field.kind === 'json')
123
+ option.argParser(jsonParser);
124
+ return option;
125
+ }
126
+ /**
127
+ * One value per flag, collected into the array the wire takes. `choices` is
128
+ * set for the help text and then overridden, because its own parser keeps
129
+ * only the last value of a flag that is not variadic.
130
+ */
131
+ function repeatedOption(field, description) {
132
+ const option = new Option(`--${field.flag} <value>`, `${description} Repeat for several.`.trim());
133
+ if (field.choices)
134
+ option.choices([...field.choices]);
135
+ const parse = field.kind === 'number' || field.kind === 'integer'
136
+ ? numberParser(field)
137
+ : (raw) => raw;
138
+ return option.argParser((raw, previous) => {
139
+ if (field.choices && !field.choices.includes(raw)) {
140
+ throw new InvalidArgumentError(`Allowed choices are ${field.choices.join(', ')}.`);
141
+ }
142
+ return [...(previous ?? []), field.kind === 'boolean' ? raw === 'true' : parse(raw)];
143
+ });
144
+ }
145
+ /**
146
+ * Decimal digits only. `Number()` reads '' as 0, '0x10' as 16 and '1e999' as
147
+ * Infinity (which JSON writes as null), none of which a customer meant.
148
+ */
149
+ const DECIMAL = /^-?\d+(\.\d+)?$/;
150
+ const INTEGER = /^-?\d+$/;
151
+ function numberParser(field) {
152
+ return (raw) => {
153
+ const pattern = field.kind === 'integer' ? INTEGER : DECIMAL;
154
+ if (!pattern.test(raw)) {
155
+ throw new InvalidArgumentError(field.kind === 'integer' ? 'Expected an integer.' : 'Expected a number.');
156
+ }
157
+ const value = Number(raw);
158
+ if (!Number.isFinite(value))
159
+ throw new InvalidArgumentError('Expected a finite number.');
160
+ return value;
161
+ };
162
+ }
163
+ function jsonParser(raw) {
164
+ try {
165
+ return JSON.parse(raw);
166
+ }
167
+ catch {
168
+ throw new InvalidArgumentError('Expected JSON.');
169
+ }
170
+ }
171
+ function collect(value, previous) {
172
+ return [...previous, value];
173
+ }
174
+ /**
175
+ * One option per flag. The generator gives the same wire name on the JSON and
176
+ * the form branch one flag, and two wire names never one flag; this keys on
177
+ * the flag because that is what commander refuses to register twice.
178
+ */
179
+ function dedupe(fields) {
180
+ const seen = new Set();
181
+ return fields.filter((field) => {
182
+ if (seen.has(field.flag))
183
+ return false;
184
+ seen.add(field.flag);
185
+ return true;
186
+ });
187
+ }
188
+ /** commander stores `--exclude-archived` as `excludeArchived`. */
189
+ export function optionKey(flag) {
190
+ return flag.replace(/-([a-z0-9])/g, (_, letter) => letter.toUpperCase());
191
+ }
192
+ /** `projectId` reads as `Project id`; `env-vars` as `Env vars`. */
193
+ export function humanize(name) {
194
+ const words = name
195
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
196
+ .replace(/-/g, ' ')
197
+ .toLowerCase();
198
+ return words.charAt(0).toUpperCase() + words.slice(1);
199
+ }
@@ -0,0 +1,63 @@
1
+ import { readFileSync, statSync } from 'node:fs';
2
+ import { basename, extname } from 'node:path';
3
+ /**
4
+ * Files on a multipart request, the way the platform reads them.
5
+ *
6
+ * Hand-written on purpose. The API takes `attachmentCount` and one file per
7
+ * `attachment_<i>` field, and a field whose name carries an index is not
8
+ * something an OpenAPI document can describe: the spec marks the operation
9
+ * with `x-kosuke-attachments` and its limits and stops there, so the convention
10
+ * lives here, outside the generated tree, in the one place that has to know it.
11
+ *
12
+ * The limits are the operation's own, generated from the server's policy, so a
13
+ * bad batch fails before any byte is uploaded and a valid one is never refused.
14
+ */
15
+ /**
16
+ * The server trusts an explicit media type and only infers one, from the
17
+ * extension, for documents sent as octet-stream. Images are never inferred,
18
+ * so a screenshot has to arrive typed or it is refused.
19
+ */
20
+ const MEDIA_TYPES = {
21
+ '.jpg': 'image/jpeg',
22
+ '.jpeg': 'image/jpeg',
23
+ '.png': 'image/png',
24
+ '.gif': 'image/gif',
25
+ '.webp': 'image/webp',
26
+ '.pdf': 'application/pdf',
27
+ '.txt': 'text/plain',
28
+ '.md': 'text/markdown',
29
+ '.html': 'text/html',
30
+ '.htm': 'text/html',
31
+ '.csv': 'text/csv',
32
+ '.tsv': 'text/tab-separated-values',
33
+ '.json': 'application/json',
34
+ '.xml': 'application/xml',
35
+ '.svg': 'image/svg+xml',
36
+ '.yaml': 'application/x-yaml',
37
+ '.yml': 'application/x-yaml',
38
+ '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
39
+ '.xls': 'application/vnd.ms-excel',
40
+ '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
41
+ };
42
+ function mediaTypeFor(path) {
43
+ return MEDIA_TYPES[extname(path).toLowerCase()] ?? 'application/octet-stream';
44
+ }
45
+ function formatBytes(bytes) {
46
+ const mib = bytes / (1024 * 1024);
47
+ return Number.isInteger(mib) ? `${mib} MiB` : `${bytes}-byte`;
48
+ }
49
+ export function appendAttachments(form, paths, { maxFiles, maxBytes }) {
50
+ if (paths.length > maxFiles) {
51
+ throw new Error(`At most ${maxFiles} attachments per request; ${paths.length} given.`);
52
+ }
53
+ // Size from the inode before the read: a file past the cap must fail with
54
+ // this message, not with the runtime's own error once it has been loaded.
55
+ for (const path of paths) {
56
+ if (statSync(path).size > maxBytes) {
57
+ throw new Error(`${path} is larger than the ${formatBytes(maxBytes)} attachment limit.`);
58
+ }
59
+ }
60
+ const files = paths.map((path) => new File([readFileSync(path)], basename(path), { type: mediaTypeFor(path) }));
61
+ form.set('attachmentCount', String(files.length));
62
+ files.forEach((file, index) => form.set(`attachment_${index}`, file));
63
+ }
@@ -0,0 +1,188 @@
1
+ import createClient, {} from 'openapi-fetch';
2
+ import { version } from './version.js';
3
+ const MAX_ATTEMPTS = 3;
4
+ // A few hundred ms, growing: this sits in front of a human or agent waiting
5
+ // on a command, so a real failure must not cost seconds.
6
+ const RETRY_DELAYS_MS = [200, 400];
7
+ function sleep(ms) {
8
+ return new Promise((resolve) => setTimeout(resolve, ms));
9
+ }
10
+ /**
11
+ * Codes that can only be raised before any request bytes reach the server: a
12
+ * name that would not resolve, or a connection that was never accepted. Safe to
13
+ * retry whatever the method, because the server cannot have acted.
14
+ */
15
+ const PRE_FLIGHT_CODES = ['EAI_AGAIN', 'ENOTFOUND', 'ECONNREFUSED'];
16
+ /**
17
+ * Codes that can be raised at any point, including after the server has read
18
+ * the request and committed to it — a reset mid-response, an idle timeout on a
19
+ * pooled socket, an instance drained by a rolling deploy after its transaction
20
+ * landed. Indistinguishable from a pre-flight failure at this layer, so they
21
+ * are retried only where a repeat is harmless.
22
+ */
23
+ const AMBIGUOUS_CODES = ['ECONNRESET', 'ETIMEDOUT'];
24
+ /** No request body was ever sent twice for these, so a repeat cannot create anything. */
25
+ const IDEMPOTENT_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']);
26
+ function methodOf(args) {
27
+ const [input, init] = args;
28
+ const method = init?.method ?? (input instanceof Request ? input.method : 'GET');
29
+ return method.toUpperCase();
30
+ }
31
+ /**
32
+ * Whether a repeat is harmless even if the first attempt reached the server.
33
+ * `markSeen` makes a GET a claim: the server moves the Seen Mark past the
34
+ * events it returns, so a repeat after a lost response claims the next ones
35
+ * and the lost events stay marked seen, never shown.
36
+ */
37
+ function isRepeatable(args) {
38
+ if (!IDEMPOTENT_METHODS.has(methodOf(args)))
39
+ return false;
40
+ try {
41
+ const [input] = args;
42
+ const href = input instanceof Request ? input.url : String(input);
43
+ return new URL(href, 'http://localhost').searchParams.get('markSeen') !== 'true';
44
+ }
45
+ catch {
46
+ return false;
47
+ }
48
+ }
49
+ function signalOf(args) {
50
+ const [input, init] = args;
51
+ return init?.signal ?? (input instanceof Request ? input.signal : undefined);
52
+ }
53
+ /**
54
+ * A sandbox VM resumed from pause can have a cold DNS resolver, which surfaces
55
+ * as a transport-level rejection rather than an HTTP error. An HTTP response is
56
+ * never retried — even a 500 is a definite answer, and `fetch` resolves rather
57
+ * than rejects for one, so that distinction falls out of catching here.
58
+ *
59
+ * What does NOT fall out of it is whether the server acted. `ECONNRESET` after
60
+ * a commit looks exactly like one before the connect, and `sessions create` is
61
+ * not idempotent: retrying it can leave a workspace paying for two sandboxes on
62
+ * one mention while the thread links only the second. So the ambiguous codes
63
+ * are retried on repeatable requests only, and anything else gets a retry only
64
+ * when the failure provably precedes the request.
65
+ */
66
+ function isRetryable(error, repeatable) {
67
+ // An abort or a timeout says the client stopped waiting, never that the
68
+ // server stopped working — the write may already have landed.
69
+ const name = error instanceof Error ? error.name : undefined;
70
+ if (name === 'AbortError' || name === 'TimeoutError')
71
+ return repeatable;
72
+ const cause = error instanceof Error ? error.cause : undefined;
73
+ const code = cause instanceof Error ? cause.code : undefined;
74
+ if (!code)
75
+ return false;
76
+ if (PRE_FLIGHT_CODES.includes(code))
77
+ return true;
78
+ return repeatable && AMBIGUOUS_CODES.includes(code);
79
+ }
80
+ function withTransportRetry(fetchImpl) {
81
+ return async (...args) => {
82
+ let attempt = 0;
83
+ for (;;) {
84
+ attempt++;
85
+ try {
86
+ return await fetchImpl(...args);
87
+ }
88
+ catch (error) {
89
+ if (attempt >= MAX_ATTEMPTS)
90
+ throw error;
91
+ // The caller's own signal fired: it stopped waiting, and a repeat would only fail again.
92
+ if (signalOf(args)?.aborted)
93
+ throw error;
94
+ if (!isRetryable(error, isRepeatable(args)))
95
+ throw error;
96
+ // Safe: the guard above ensures attempt is within [1, MAX_ATTEMPTS - 1] here.
97
+ await sleep(RETRY_DELAYS_MS[attempt - 1]);
98
+ }
99
+ }
100
+ };
101
+ }
102
+ /** Where Node's fetch, and the `undici` package beside it, keep the dispatcher every request uses. */
103
+ const GLOBAL_DISPATCHER = Symbol.for('undici.globalDispatcher.1');
104
+ function globalDispatcher() {
105
+ return globalThis[GLOBAL_DISPATCHER];
106
+ }
107
+ /**
108
+ * Node's fetch gives up on an answer after 300 s, undici's `headersTimeout` and `bodyTimeout`,
109
+ * whatever signal the caller set. Each request here sets both for itself and goes on through the
110
+ * dispatcher Node already uses, rather than a new one, so a proxy that `NODE_USE_ENV_PROXY` set
111
+ * up, as in Sensei, still carries it.
112
+ */
113
+ function withAnswerTimeout(fetchImpl, timeoutMs) {
114
+ const dispatcher = {
115
+ dispatch(options, handler) {
116
+ return globalDispatcher().dispatch({ ...options, headersTimeout: timeoutMs, bodyTimeout: timeoutMs }, handler);
117
+ },
118
+ };
119
+ return (input, init) => {
120
+ // Another runtime has no such dispatcher, and keeps its own limits.
121
+ if (!globalDispatcher())
122
+ return fetchImpl(input, init);
123
+ // Node's own `Dispatcher` type is undici's whole class; fetch calls only `dispatch`.
124
+ return fetchImpl(input, { ...init, dispatcher });
125
+ };
126
+ }
127
+ /** The most of one integration answer the CLI reads; its listings are bounded well below it. */
128
+ const MAX_INTEGRATION_RESPONSE_BYTES = 512 * 1024;
129
+ const INTEGRATIONS_PREFIX = '/api/agent-integrations/';
130
+ /** An integration answer past the cap; a call that got one may still have run. */
131
+ export class ResponseTooLarge extends Error {
132
+ constructor() {
133
+ super('Integration response was too large');
134
+ this.name = 'ResponseTooLarge';
135
+ }
136
+ }
137
+ /**
138
+ * Caps what an integration route can make the CLI buffer, error bodies included. The body is
139
+ * counted as it streams, so nothing past the cap is held or parsed. Other routes are untouched.
140
+ */
141
+ function withIntegrationCap(fetchImpl) {
142
+ return async (...args) => {
143
+ const response = await fetchImpl(...args);
144
+ const [input] = args;
145
+ try {
146
+ const href = input instanceof Request ? input.url : String(input);
147
+ if (!new URL(href, 'http://localhost').pathname.startsWith(INTEGRATIONS_PREFIX)) {
148
+ return response;
149
+ }
150
+ }
151
+ catch {
152
+ return response;
153
+ }
154
+ if (!response.body)
155
+ return response;
156
+ const declared = Number(response.headers.get('content-length'));
157
+ if (Number.isFinite(declared) && declared > MAX_INTEGRATION_RESPONSE_BYTES) {
158
+ await response.body.cancel().catch(() => undefined);
159
+ throw new ResponseTooLarge();
160
+ }
161
+ let total = 0;
162
+ const counted = response.body.pipeThrough(new TransformStream({
163
+ transform(chunk, controller) {
164
+ total += chunk.byteLength;
165
+ if (total > MAX_INTEGRATION_RESPONSE_BYTES)
166
+ controller.error(new ResponseTooLarge());
167
+ else
168
+ controller.enqueue(chunk);
169
+ },
170
+ }));
171
+ return new Response(counted, {
172
+ status: response.status,
173
+ statusText: response.statusText,
174
+ headers: response.headers,
175
+ });
176
+ };
177
+ }
178
+ export function createApiClient({ apiUrl, apiKey, fetch, answerTimeoutMs, }) {
179
+ const base = fetch ?? globalThis.fetch;
180
+ return createClient({
181
+ baseUrl: apiUrl,
182
+ headers: {
183
+ ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),
184
+ 'User-Agent': `@kosuke-ai/kosuke/${version}`,
185
+ },
186
+ fetch: withIntegrationCap(withTransportRetry(answerTimeoutMs === undefined ? base : withAnswerTimeout(base, answerTimeoutMs))),
187
+ });
188
+ }
@@ -0,0 +1,49 @@
1
+ import { chmodSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ export const DEFAULT_API_URL = 'https://app.kosuke.ai';
5
+ function configDir(env = process.env) {
6
+ if (env.KOSUKE_CONFIG_DIR)
7
+ return env.KOSUKE_CONFIG_DIR;
8
+ if (env.XDG_CONFIG_HOME)
9
+ return join(env.XDG_CONFIG_HOME, 'kosuke');
10
+ if (process.platform === 'win32' && env.APPDATA)
11
+ return join(env.APPDATA, 'kosuke');
12
+ return join(homedir(), '.config', 'kosuke');
13
+ }
14
+ export function credentialsPath(env = process.env) {
15
+ return join(configDir(env), 'credentials.json');
16
+ }
17
+ export function readCredentials(env = process.env) {
18
+ try {
19
+ const parsed = JSON.parse(readFileSync(credentialsPath(env), 'utf8'));
20
+ if (parsed && typeof parsed === 'object' && 'apiKey' in parsed) {
21
+ const { apiKey, apiUrl } = parsed;
22
+ if (typeof apiKey === 'string' && apiKey.length > 0) {
23
+ return { apiKey, ...(typeof apiUrl === 'string' ? { apiUrl } : {}) };
24
+ }
25
+ }
26
+ return null;
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ }
32
+ export function writeCredentials(credentials, env = process.env) {
33
+ const path = credentialsPath(env);
34
+ mkdirSync(configDir(env), { recursive: true, mode: 0o700 });
35
+ writeFileSync(path, JSON.stringify(credentials, null, 2) + '\n', { mode: 0o600 });
36
+ // `mode` on write only applies to a file being created; an existing one keeps
37
+ // whatever it had, and a token file must not.
38
+ chmodSync(path, 0o600);
39
+ return path;
40
+ }
41
+ export function deleteCredentials(env = process.env) {
42
+ try {
43
+ rmSync(credentialsPath(env));
44
+ return true;
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ }
@@ -0,0 +1,32 @@
1
+ import { agentTokenOf } from './agent-tokens.js';
2
+ import { DEFAULT_API_URL, readCredentials } from './config.js';
3
+ /**
4
+ * A credential that needs no `--workspace`: a sandbox or cron token decides its
5
+ * workspace, and a Sensei token reaches its member's own connections without one.
6
+ */
7
+ export function isTurnToken(token) {
8
+ return agentTokenOf(token) !== null;
9
+ }
10
+ export function resolveCredentials(flags, env = process.env) {
11
+ const stored = readCredentials(env);
12
+ const apiKey = flags.apiKey
13
+ ? { value: flags.apiKey, source: 'flag' }
14
+ : env.KOSUKE_API_KEY
15
+ ? { value: env.KOSUKE_API_KEY, source: 'env' }
16
+ : stored
17
+ ? { value: stored.apiKey, source: 'file' }
18
+ : null;
19
+ const apiUrl = flags.apiUrl
20
+ ? { value: flags.apiUrl, source: 'flag' }
21
+ : env.KOSUKE_API_URL
22
+ ? { value: env.KOSUKE_API_URL, source: 'env' }
23
+ : stored?.apiUrl
24
+ ? { value: stored.apiUrl, source: 'file' }
25
+ : { value: DEFAULT_API_URL, source: 'default' };
26
+ return {
27
+ apiKey: apiKey?.value ?? null,
28
+ apiKeySource: apiKey?.source ?? null,
29
+ apiUrl: apiUrl.value.replace(/\/+$/, ''),
30
+ apiUrlSource: apiUrl.source,
31
+ };
32
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * What the generator writes per operation, and what the runtime builds a
3
+ * command from. Data only: the generated tree holds no logic, so it stays
4
+ * small, byte-stable and reviewable, and every behaviour lives in one
5
+ * hand-written place.
6
+ */
7
+ export {};