convex 1.48.0 → 1.49.0-alpha.0

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 (248) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/browser.bundle.js +1 -1
  3. package/dist/browser.bundle.js.map +1 -1
  4. package/dist/cjs/bundler/context.js +7 -5
  5. package/dist/cjs/bundler/context.js.map +2 -2
  6. package/dist/cjs/bundler/fs.js +47 -6
  7. package/dist/cjs/bundler/fs.js.map +2 -2
  8. package/dist/cjs/cli/account.js +237 -0
  9. package/dist/cjs/cli/account.js.map +7 -0
  10. package/dist/cjs/cli/configure.js +15 -2
  11. package/dist/cjs/cli/configure.js.map +2 -2
  12. package/dist/cjs/cli/lib/accountManagement.js +196 -0
  13. package/dist/cjs/cli/lib/accountManagement.js.map +7 -0
  14. package/dist/cjs/cli/lib/accounts.js +334 -0
  15. package/dist/cjs/cli/lib/accounts.js.map +7 -0
  16. package/dist/cjs/cli/lib/deployKeyWarning.js +43 -0
  17. package/dist/cjs/cli/lib/deployKeyWarning.js.map +7 -0
  18. package/dist/cjs/cli/lib/deployment.js +2 -0
  19. package/dist/cjs/cli/lib/deployment.js.map +2 -2
  20. package/dist/cjs/cli/lib/deploymentSelection.js +27 -18
  21. package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
  22. package/dist/cjs/cli/lib/envvars.js +32 -0
  23. package/dist/cjs/cli/lib/envvars.js.map +2 -2
  24. package/dist/cjs/cli/lib/fsUtils.js +1 -1
  25. package/dist/cjs/cli/lib/fsUtils.js.map +2 -2
  26. package/dist/cjs/cli/lib/generateDocs.js +1 -1
  27. package/dist/cjs/cli/lib/generateDocs.js.map +1 -1
  28. package/dist/cjs/cli/lib/login.js +42 -4
  29. package/dist/cjs/cli/lib/login.js.map +3 -3
  30. package/dist/cjs/cli/lib/mcp/requestContext.js +5 -1
  31. package/dist/cjs/cli/lib/mcp/requestContext.js.map +2 -2
  32. package/dist/cjs/cli/lib/plugins/claudeCode.js +188 -0
  33. package/dist/cjs/cli/lib/plugins/claudeCode.js.map +7 -0
  34. package/dist/cjs/cli/lib/plugins/codex.js +167 -0
  35. package/dist/cjs/cli/lib/plugins/codex.js.map +7 -0
  36. package/dist/cjs/cli/lib/plugins/harness.js +50 -0
  37. package/dist/cjs/cli/lib/plugins/harness.js.map +7 -0
  38. package/dist/cjs/cli/lib/plugins/marketplaces.js +76 -0
  39. package/dist/cjs/cli/lib/plugins/marketplaces.js.map +7 -0
  40. package/dist/cjs/cli/lib/plugins/skills.js +98 -0
  41. package/dist/cjs/cli/lib/plugins/skills.js.map +7 -0
  42. package/dist/cjs/cli/lib/plugins/utils.js +125 -0
  43. package/dist/cjs/cli/lib/plugins/utils.js.map +7 -0
  44. package/dist/cjs/cli/lib/utils/utils.js +18 -9
  45. package/dist/cjs/cli/lib/utils/utils.js.map +2 -2
  46. package/dist/cjs/cli/login.js +213 -114
  47. package/dist/cjs/cli/login.js.map +3 -3
  48. package/dist/cjs/cli/logout.js +113 -12
  49. package/dist/cjs/cli/logout.js.map +3 -3
  50. package/dist/cjs/cli/mcp.js +43 -10
  51. package/dist/cjs/cli/mcp.js.map +3 -3
  52. package/dist/cjs/cli/plugins.js +114 -0
  53. package/dist/cjs/cli/plugins.js.map +7 -0
  54. package/dist/cjs/cli/program.js +3 -1
  55. package/dist/cjs/cli/program.js.map +2 -2
  56. package/dist/cjs/index.js +1 -1
  57. package/dist/cjs/index.js.map +1 -1
  58. package/dist/cjs/server/impl/actions_impl.js.map +2 -2
  59. package/dist/cjs-types/bundler/context.d.ts +5 -0
  60. package/dist/cjs-types/bundler/context.d.ts.map +1 -1
  61. package/dist/cjs-types/bundler/fs.d.ts +7 -2
  62. package/dist/cjs-types/bundler/fs.d.ts.map +1 -1
  63. package/dist/cjs-types/cli/account.d.ts +6 -0
  64. package/dist/cjs-types/cli/account.d.ts.map +1 -0
  65. package/dist/cjs-types/cli/configure.d.ts.map +1 -1
  66. package/dist/cjs-types/cli/lib/accountManagement.d.ts +10 -0
  67. package/dist/cjs-types/cli/lib/accountManagement.d.ts.map +1 -0
  68. package/dist/cjs-types/cli/lib/accounts.d.ts +59 -0
  69. package/dist/cjs-types/cli/lib/accounts.d.ts.map +1 -0
  70. package/dist/cjs-types/cli/lib/deployKeyWarning.d.ts +3 -0
  71. package/dist/cjs-types/cli/lib/deployKeyWarning.d.ts.map +1 -0
  72. package/dist/cjs-types/cli/lib/deployment.d.ts +2 -0
  73. package/dist/cjs-types/cli/lib/deployment.d.ts.map +1 -1
  74. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts +2 -1
  75. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  76. package/dist/cjs-types/cli/lib/envvars.d.ts +6 -0
  77. package/dist/cjs-types/cli/lib/envvars.d.ts.map +1 -1
  78. package/dist/cjs-types/cli/lib/fsUtils.d.ts +1 -0
  79. package/dist/cjs-types/cli/lib/fsUtils.d.ts.map +1 -1
  80. package/dist/cjs-types/cli/lib/login.d.ts +3 -1
  81. package/dist/cjs-types/cli/lib/login.d.ts.map +1 -1
  82. package/dist/cjs-types/cli/lib/mcp/requestContext.d.ts.map +1 -1
  83. package/dist/cjs-types/cli/lib/mcp/tools/insights.d.ts +2 -2
  84. package/dist/cjs-types/cli/lib/plugins/claudeCode.d.ts +25 -0
  85. package/dist/cjs-types/cli/lib/plugins/claudeCode.d.ts.map +1 -0
  86. package/dist/cjs-types/cli/lib/plugins/codex.d.ts +25 -0
  87. package/dist/cjs-types/cli/lib/plugins/codex.d.ts.map +1 -0
  88. package/dist/cjs-types/cli/lib/plugins/harness.d.ts +33 -0
  89. package/dist/cjs-types/cli/lib/plugins/harness.d.ts.map +1 -0
  90. package/dist/cjs-types/cli/lib/plugins/marketplaces.d.ts +40 -0
  91. package/dist/cjs-types/cli/lib/plugins/marketplaces.d.ts.map +1 -0
  92. package/dist/cjs-types/cli/lib/plugins/skills.d.ts +18 -0
  93. package/dist/cjs-types/cli/lib/plugins/skills.d.ts.map +1 -0
  94. package/dist/cjs-types/cli/lib/plugins/utils.d.ts +21 -0
  95. package/dist/cjs-types/cli/lib/plugins/utils.d.ts.map +1 -0
  96. package/dist/cjs-types/cli/lib/utils/utils.d.ts +5 -0
  97. package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
  98. package/dist/cjs-types/cli/login.d.ts +21 -0
  99. package/dist/cjs-types/cli/login.d.ts.map +1 -1
  100. package/dist/cjs-types/cli/logout.d.ts +8 -1
  101. package/dist/cjs-types/cli/logout.d.ts.map +1 -1
  102. package/dist/cjs-types/cli/mcp.d.ts.map +1 -1
  103. package/dist/cjs-types/cli/plugins.d.ts +3 -0
  104. package/dist/cjs-types/cli/plugins.d.ts.map +1 -0
  105. package/dist/cjs-types/cli/program.d.ts.map +1 -1
  106. package/dist/cjs-types/index.d.ts +1 -1
  107. package/dist/cjs-types/index.d.ts.map +1 -1
  108. package/dist/cjs-types/server/impl/actions_impl.d.ts +3 -2
  109. package/dist/cjs-types/server/impl/actions_impl.d.ts.map +1 -1
  110. package/dist/cli.bundle.cjs +10059 -7094
  111. package/dist/cli.bundle.cjs.map +4 -4
  112. package/dist/esm/bundler/context.js +7 -5
  113. package/dist/esm/bundler/context.js.map +2 -2
  114. package/dist/esm/bundler/fs.js +47 -6
  115. package/dist/esm/bundler/fs.js.map +2 -2
  116. package/dist/esm/cli/account.js +221 -0
  117. package/dist/esm/cli/account.js.map +7 -0
  118. package/dist/esm/cli/configure.js +15 -2
  119. package/dist/esm/cli/configure.js.map +2 -2
  120. package/dist/esm/cli/lib/accountManagement.js +179 -0
  121. package/dist/esm/cli/lib/accountManagement.js.map +7 -0
  122. package/dist/esm/cli/lib/accounts.js +289 -0
  123. package/dist/esm/cli/lib/accounts.js.map +7 -0
  124. package/dist/esm/cli/lib/deployKeyWarning.js +27 -0
  125. package/dist/esm/cli/lib/deployKeyWarning.js.map +7 -0
  126. package/dist/esm/cli/lib/deployment.js +2 -2
  127. package/dist/esm/cli/lib/deployment.js.map +2 -2
  128. package/dist/esm/cli/lib/deploymentSelection.js +35 -20
  129. package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
  130. package/dist/esm/cli/lib/envvars.js +35 -1
  131. package/dist/esm/cli/lib/envvars.js.map +2 -2
  132. package/dist/esm/cli/lib/fsUtils.js +1 -1
  133. package/dist/esm/cli/lib/fsUtils.js.map +2 -2
  134. package/dist/esm/cli/lib/generateDocs.js +1 -1
  135. package/dist/esm/cli/lib/generateDocs.js.map +1 -1
  136. package/dist/esm/cli/lib/login.js +52 -4
  137. package/dist/esm/cli/lib/login.js.map +3 -3
  138. package/dist/esm/cli/lib/mcp/requestContext.js +5 -1
  139. package/dist/esm/cli/lib/mcp/requestContext.js.map +2 -2
  140. package/dist/esm/cli/lib/plugins/claudeCode.js +160 -0
  141. package/dist/esm/cli/lib/plugins/claudeCode.js.map +7 -0
  142. package/dist/esm/cli/lib/plugins/codex.js +140 -0
  143. package/dist/esm/cli/lib/plugins/codex.js.map +7 -0
  144. package/dist/esm/cli/lib/plugins/harness.js +17 -0
  145. package/dist/esm/cli/lib/plugins/harness.js.map +7 -0
  146. package/dist/esm/cli/lib/plugins/marketplaces.js +53 -0
  147. package/dist/esm/cli/lib/plugins/marketplaces.js.map +7 -0
  148. package/dist/esm/cli/lib/plugins/skills.js +65 -0
  149. package/dist/esm/cli/lib/plugins/skills.js.map +7 -0
  150. package/dist/esm/cli/lib/plugins/utils.js +86 -0
  151. package/dist/esm/cli/lib/plugins/utils.js.map +7 -0
  152. package/dist/esm/cli/lib/utils/utils.js +16 -9
  153. package/dist/esm/cli/lib/utils/utils.js.map +2 -2
  154. package/dist/esm/cli/login.js +225 -112
  155. package/dist/esm/cli/login.js.map +3 -3
  156. package/dist/esm/cli/logout.js +110 -13
  157. package/dist/esm/cli/logout.js.map +2 -2
  158. package/dist/esm/cli/mcp.js +34 -10
  159. package/dist/esm/cli/mcp.js.map +2 -2
  160. package/dist/esm/cli/plugins.js +99 -0
  161. package/dist/esm/cli/plugins.js.map +7 -0
  162. package/dist/esm/cli/program.js +3 -1
  163. package/dist/esm/cli/program.js.map +2 -2
  164. package/dist/esm/index.js +1 -1
  165. package/dist/esm/index.js.map +1 -1
  166. package/dist/esm/server/impl/actions_impl.js.map +2 -2
  167. package/dist/esm-types/bundler/context.d.ts +5 -0
  168. package/dist/esm-types/bundler/context.d.ts.map +1 -1
  169. package/dist/esm-types/bundler/fs.d.ts +7 -2
  170. package/dist/esm-types/bundler/fs.d.ts.map +1 -1
  171. package/dist/esm-types/cli/account.d.ts +6 -0
  172. package/dist/esm-types/cli/account.d.ts.map +1 -0
  173. package/dist/esm-types/cli/configure.d.ts.map +1 -1
  174. package/dist/esm-types/cli/lib/accountManagement.d.ts +10 -0
  175. package/dist/esm-types/cli/lib/accountManagement.d.ts.map +1 -0
  176. package/dist/esm-types/cli/lib/accounts.d.ts +59 -0
  177. package/dist/esm-types/cli/lib/accounts.d.ts.map +1 -0
  178. package/dist/esm-types/cli/lib/deployKeyWarning.d.ts +3 -0
  179. package/dist/esm-types/cli/lib/deployKeyWarning.d.ts.map +1 -0
  180. package/dist/esm-types/cli/lib/deployment.d.ts +2 -0
  181. package/dist/esm-types/cli/lib/deployment.d.ts.map +1 -1
  182. package/dist/esm-types/cli/lib/deploymentSelection.d.ts +2 -1
  183. package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  184. package/dist/esm-types/cli/lib/envvars.d.ts +6 -0
  185. package/dist/esm-types/cli/lib/envvars.d.ts.map +1 -1
  186. package/dist/esm-types/cli/lib/fsUtils.d.ts +1 -0
  187. package/dist/esm-types/cli/lib/fsUtils.d.ts.map +1 -1
  188. package/dist/esm-types/cli/lib/login.d.ts +3 -1
  189. package/dist/esm-types/cli/lib/login.d.ts.map +1 -1
  190. package/dist/esm-types/cli/lib/mcp/requestContext.d.ts.map +1 -1
  191. package/dist/esm-types/cli/lib/mcp/tools/insights.d.ts +2 -2
  192. package/dist/esm-types/cli/lib/plugins/claudeCode.d.ts +25 -0
  193. package/dist/esm-types/cli/lib/plugins/claudeCode.d.ts.map +1 -0
  194. package/dist/esm-types/cli/lib/plugins/codex.d.ts +25 -0
  195. package/dist/esm-types/cli/lib/plugins/codex.d.ts.map +1 -0
  196. package/dist/esm-types/cli/lib/plugins/harness.d.ts +33 -0
  197. package/dist/esm-types/cli/lib/plugins/harness.d.ts.map +1 -0
  198. package/dist/esm-types/cli/lib/plugins/marketplaces.d.ts +40 -0
  199. package/dist/esm-types/cli/lib/plugins/marketplaces.d.ts.map +1 -0
  200. package/dist/esm-types/cli/lib/plugins/skills.d.ts +18 -0
  201. package/dist/esm-types/cli/lib/plugins/skills.d.ts.map +1 -0
  202. package/dist/esm-types/cli/lib/plugins/utils.d.ts +21 -0
  203. package/dist/esm-types/cli/lib/plugins/utils.d.ts.map +1 -0
  204. package/dist/esm-types/cli/lib/utils/utils.d.ts +5 -0
  205. package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
  206. package/dist/esm-types/cli/login.d.ts +21 -0
  207. package/dist/esm-types/cli/login.d.ts.map +1 -1
  208. package/dist/esm-types/cli/logout.d.ts +8 -1
  209. package/dist/esm-types/cli/logout.d.ts.map +1 -1
  210. package/dist/esm-types/cli/mcp.d.ts.map +1 -1
  211. package/dist/esm-types/cli/plugins.d.ts +3 -0
  212. package/dist/esm-types/cli/plugins.d.ts.map +1 -0
  213. package/dist/esm-types/cli/program.d.ts.map +1 -1
  214. package/dist/esm-types/index.d.ts +1 -1
  215. package/dist/esm-types/index.d.ts.map +1 -1
  216. package/dist/esm-types/server/impl/actions_impl.d.ts +3 -2
  217. package/dist/esm-types/server/impl/actions_impl.d.ts.map +1 -1
  218. package/dist/react.bundle.js +1 -1
  219. package/dist/react.bundle.js.map +1 -1
  220. package/package.json +2 -2
  221. package/src/bundler/context.ts +9 -5
  222. package/src/bundler/fs.ts +54 -5
  223. package/src/cli/account.ts +320 -0
  224. package/src/cli/configure.ts +18 -2
  225. package/src/cli/lib/accountManagement.ts +262 -0
  226. package/src/cli/lib/accounts.ts +400 -0
  227. package/src/cli/lib/deployKeyWarning.ts +43 -0
  228. package/src/cli/lib/deployment.ts +2 -2
  229. package/src/cli/lib/deploymentSelection.ts +37 -18
  230. package/src/cli/lib/envvars.ts +43 -1
  231. package/src/cli/lib/fsUtils.ts +5 -2
  232. package/src/cli/lib/generateDocs.ts +1 -1
  233. package/src/cli/lib/login.ts +64 -3
  234. package/src/cli/lib/mcp/requestContext.ts +7 -1
  235. package/src/cli/lib/plugins/claudeCode.ts +201 -0
  236. package/src/cli/lib/plugins/codex.ts +177 -0
  237. package/src/cli/lib/plugins/harness.ts +49 -0
  238. package/src/cli/lib/plugins/marketplaces.ts +94 -0
  239. package/src/cli/lib/plugins/skills.ts +101 -0
  240. package/src/cli/lib/plugins/utils.ts +121 -0
  241. package/src/cli/lib/utils/utils.ts +19 -15
  242. package/src/cli/login.ts +293 -168
  243. package/src/cli/logout.ts +142 -17
  244. package/src/cli/mcp.ts +48 -11
  245. package/src/cli/plugins.ts +154 -0
  246. package/src/cli/program.ts +4 -0
  247. package/src/index.ts +1 -1
  248. package/src/server/impl/actions_impl.ts +3 -2
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var codex_exports = {};
30
+ __export(codex_exports, {
31
+ codex: () => codex,
32
+ codexMarketplaces: () => codexMarketplaces,
33
+ createGetCodexLocations: () => createGetCodexLocations,
34
+ getCodexLocations: () => getCodexLocations
35
+ });
36
+ module.exports = __toCommonJS(codex_exports);
37
+ var import_os = __toESM(require("os"), 1);
38
+ var import_path = __toESM(require("path"), 1);
39
+ var import_zod = require("zod");
40
+ var import_fs = require("../../../bundler/fs.js");
41
+ var import_marketplaces = require("./marketplaces.js");
42
+ var import_utils = require("./utils.js");
43
+ const createGetCodexLocations = (places) => async () => {
44
+ const desktop = import_path.default.join(
45
+ places.applications,
46
+ "ChatGPT.app",
47
+ "Contents",
48
+ "Resources",
49
+ "codex-cli",
50
+ "CodexCLI.app",
51
+ "Contents",
52
+ "MacOS",
53
+ "codex"
54
+ );
55
+ const found = [
56
+ ...(0, import_utils.onPath)("codex", places.path).map((p) => ({
57
+ source: "terminal",
58
+ path: p
59
+ })),
60
+ ...import_fs.nodeFs.exists(desktop) ? [{ source: "desktop", path: desktop }] : [],
61
+ // The extension keeps its binary in a folder named for the platform, like
62
+ // `bin/macos-aarch64`.
63
+ ...(0, import_utils.subfolders)(import_path.default.join(places.home, ".vscode", "extensions")).filter((dir) => import_path.default.basename(dir).startsWith("openai.chatgpt-")).flatMap((dir) => (0, import_utils.subfolders)(import_path.default.join(dir, "bin"))).map((dir) => ({
64
+ source: "vscode",
65
+ path: import_path.default.join(dir, "codex")
66
+ }))
67
+ ];
68
+ return Promise.all(
69
+ found.map(async (cli) => ({
70
+ ...cli,
71
+ version: await (0, import_utils.versionOf)(cli.path)
72
+ }))
73
+ );
74
+ };
75
+ const getCodexLocations = createGetCodexLocations({
76
+ home: import_os.default.homedir(),
77
+ path: process.env.PATH ?? "",
78
+ applications: "/Applications"
79
+ });
80
+ async function codexLatest() {
81
+ const plugin = await (0, import_utils.fetchGitHubJson)(
82
+ "convex/convex-codex-plugin/main/plugins/convex/.codex-plugin/plugin.json"
83
+ );
84
+ return plugin === null ? {} : { convex: plugin.version };
85
+ }
86
+ const codexMarketplaceList = import_zod.z.object({
87
+ marketplaces: import_zod.z.array(
88
+ import_zod.z.object({
89
+ name: import_zod.z.string(),
90
+ root: import_zod.z.string(),
91
+ marketplaceSource: import_zod.z.object({ sourceType: import_zod.z.string(), source: import_zod.z.string() }).optional()
92
+ })
93
+ )
94
+ });
95
+ const codexPluginList = import_zod.z.object({
96
+ installed: import_zod.z.array(
97
+ import_zod.z.object({
98
+ name: import_zod.z.string(),
99
+ marketplaceName: import_zod.z.string(),
100
+ version: import_zod.z.string(),
101
+ enabled: import_zod.z.boolean()
102
+ })
103
+ )
104
+ });
105
+ function codexPlugins(pluginList) {
106
+ const plugins = (0, import_utils.parseList)(
107
+ codexPluginList,
108
+ pluginList,
109
+ "codex plugin list --json"
110
+ );
111
+ if (plugins === null) return null;
112
+ return plugins.installed.map((p) => ({
113
+ name: p.name,
114
+ marketplace: p.marketplaceName,
115
+ version: p.version,
116
+ enabled: p.enabled
117
+ }));
118
+ }
119
+ function codexMarketplaces(marketplaceList, pluginList) {
120
+ const marketplaces = (0, import_utils.parseList)(
121
+ codexMarketplaceList,
122
+ marketplaceList,
123
+ "codex plugin marketplace list --json"
124
+ );
125
+ const plugins = codexPlugins(pluginList);
126
+ if (marketplaces === null || plugins === null) return null;
127
+ return (0, import_marketplaces.convexMarketplaces)(
128
+ marketplaces.marketplaces.map((m) => ({
129
+ name: m.name,
130
+ // Anything that isn't a git marketplace is shown by its folder.
131
+ source: m.marketplaceSource?.sourceType === "git" ? { kind: "git", url: m.marketplaceSource.source } : { kind: "folder", path: m.root }
132
+ })),
133
+ plugins
134
+ );
135
+ }
136
+ const pluginId = "convex@convex-codex-plugin";
137
+ const upgradeStep = ["plugin", "marketplace", "upgrade", "convex-codex-plugin"];
138
+ const codex = {
139
+ id: "codex",
140
+ name: "Codex",
141
+ plugin: pluginId,
142
+ upgradeStep,
143
+ installSteps: [
144
+ // Notes:
145
+ //
146
+ // 1. The marketplace is added from the `get-convex` org, the org's name
147
+ // before the rename to `convex`. Codex refuses to re-add a marketplace
148
+ // from a different source, so switching would make install fail for
149
+ // anyone who installed before. Switch once install handles an existing
150
+ // marketplace.
151
+ //
152
+ // 2. Codex installs plugins from its own local copy of each marketplace, so
153
+ // it doesn't see the new plugin versions we publish until that copy is
154
+ // updated.
155
+ // Add the marketplace
156
+ ["plugin", "marketplace", "add", "get-convex/convex-codex-plugin"],
157
+ // Update the local copy from GitHub, so the latest plugin version is
158
+ // available to install - this is important
159
+ upgradeStep,
160
+ // Install the latest plugin from the updated marketplace
161
+ ["plugin", "add", pluginId]
162
+ ],
163
+ plugins: codexPlugins,
164
+ marketplaces: codexMarketplaces,
165
+ latest: codexLatest
166
+ };
167
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/cli/lib/plugins/codex.ts"],
4
+ "sourcesContent": ["import os from \"os\";\nimport path from \"path\";\nimport { z } from \"zod\";\nimport { nodeFs } from \"../../../bundler/fs.js\";\nimport type { Cli, Places } from \"./harness.js\";\nimport {\n convexMarketplaces,\n type Marketplace,\n type Plugin,\n} from \"./marketplaces.js\";\nimport {\n fetchGitHubJson,\n onPath,\n parseList,\n subfolders,\n versionOf,\n} from \"./utils.js\";\n\n/** Builds `getCodexLocations` for the given places, so tests can point it at fixtures. */\nexport const createGetCodexLocations =\n (places: Places) => async (): Promise<Cli[]> => {\n // The ChatGPT app also has `codex-cli/bin/codex`, a script that runs this\n // binary. Running that script from another app sets off macOS's App\n // Management prompt, and running the binary doesn't.\n const desktop = path.join(\n places.applications,\n \"ChatGPT.app\",\n \"Contents\",\n \"Resources\",\n \"codex-cli\",\n \"CodexCLI.app\",\n \"Contents\",\n \"MacOS\",\n \"codex\",\n );\n const found: Omit<Cli, \"version\">[] = [\n ...onPath(\"codex\", places.path).map((p) => ({\n source: \"terminal\" as const,\n path: p,\n })),\n ...(nodeFs.exists(desktop)\n ? [{ source: \"desktop\" as const, path: desktop }]\n : []),\n // The extension keeps its binary in a folder named for the platform, like\n // `bin/macos-aarch64`.\n ...subfolders(path.join(places.home, \".vscode\", \"extensions\"))\n .filter((dir) => path.basename(dir).startsWith(\"openai.chatgpt-\"))\n .flatMap((dir) => subfolders(path.join(dir, \"bin\")))\n .map((dir) => ({\n source: \"vscode\" as const,\n path: path.join(dir, \"codex\"),\n })),\n ];\n return Promise.all(\n found.map(async (cli) => ({\n ...cli,\n version: await versionOf(cli.path),\n })),\n );\n };\n\n/** Every copy of Codex on this machine: the terminal CLI, the ChatGPT app's copy and the VS Code extension's copies. */\nexport const getCodexLocations = createGetCodexLocations({\n home: os.homedir(),\n path: process.env.PATH ?? \"\",\n applications: \"/Applications\",\n});\n\n/** The newest Convex plugin a Codex user can install, which is main of our repo. */\nasync function codexLatest(): Promise<Record<string, string>> {\n const plugin = await fetchGitHubJson<{ version: string }>(\n \"convex/convex-codex-plugin/main/plugins/convex/.codex-plugin/plugin.json\",\n );\n return plugin === null ? {} : { convex: plugin.version };\n}\n\n/** `codex plugin marketplace list --json` */\nconst codexMarketplaceList = z.object({\n marketplaces: z.array(\n z.object({\n name: z.string(),\n root: z.string(),\n marketplaceSource: z\n .object({ sourceType: z.string(), source: z.string() })\n .optional(),\n }),\n ),\n});\n\n/** `codex plugin list --json` */\nconst codexPluginList = z.object({\n installed: z.array(\n z.object({\n name: z.string(),\n marketplaceName: z.string(),\n version: z.string(),\n enabled: z.boolean(),\n }),\n ),\n});\n\n/** Reads the plugins in `codex plugin list --json`, or returns null when it doesn't match. */\nfunction codexPlugins(pluginList: string): Plugin[] | null {\n const plugins = parseList(\n codexPluginList,\n pluginList,\n \"codex plugin list --json\",\n );\n if (plugins === null) return null;\n return plugins.installed.map((p) => ({\n name: p.name,\n marketplace: p.marketplaceName,\n version: p.version,\n enabled: p.enabled,\n }));\n}\n\n/** Reads Codex's Convex marketplaces from `codex plugin marketplace list --json` and `codex plugin list --json`, or returns null when either doesn't match. */\nexport function codexMarketplaces(\n marketplaceList: string,\n pluginList: string,\n): Marketplace[] | null {\n const marketplaces = parseList(\n codexMarketplaceList,\n marketplaceList,\n \"codex plugin marketplace list --json\",\n );\n const plugins = codexPlugins(pluginList);\n if (marketplaces === null || plugins === null) return null;\n return convexMarketplaces(\n marketplaces.marketplaces.map((m) => ({\n name: m.name,\n // Anything that isn't a git marketplace is shown by its folder.\n source:\n m.marketplaceSource?.sourceType === \"git\"\n ? { kind: \"git\", url: m.marketplaceSource.source }\n : { kind: \"folder\", path: m.root },\n })),\n plugins,\n );\n}\n\nconst pluginId = \"convex@convex-codex-plugin\";\n/** The install step that brings an installed plugin to the latest version. When it fails, the user keeps an old version. */\nconst upgradeStep = [\"plugin\", \"marketplace\", \"upgrade\", \"convex-codex-plugin\"];\n\n/** Codex as `npx convex plugins` installs and reads it. */\nexport const codex = {\n id: \"codex\" as const,\n name: \"Codex\",\n plugin: pluginId,\n upgradeStep,\n installSteps: [\n // Notes:\n //\n // 1. The marketplace is added from the `get-convex` org, the org's name\n // before the rename to `convex`. Codex refuses to re-add a marketplace\n // from a different source, so switching would make install fail for\n // anyone who installed before. Switch once install handles an existing\n // marketplace.\n //\n // 2. Codex installs plugins from its own local copy of each marketplace, so\n // it doesn't see the new plugin versions we publish until that copy is\n // updated.\n\n // Add the marketplace\n [\"plugin\", \"marketplace\", \"add\", \"get-convex/convex-codex-plugin\"],\n // Update the local copy from GitHub, so the latest plugin version is\n // available to install - this is important\n upgradeStep,\n // Install the latest plugin from the updated marketplace\n [\"plugin\", \"add\", pluginId],\n ],\n plugins: codexPlugins,\n marketplaces: codexMarketplaces,\n latest: codexLatest,\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAe;AACf,kBAAiB;AACjB,iBAAkB;AAClB,gBAAuB;AAEvB,0BAIO;AACP,mBAMO;AAGA,MAAM,0BACX,CAAC,WAAmB,YAA4B;AAI9C,QAAM,UAAU,YAAAA,QAAK;AAAA,IACnB,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,QAAgC;AAAA,IACpC,OAAG,qBAAO,SAAS,OAAO,IAAI,EAAE,IAAI,CAAC,OAAO;AAAA,MAC1C,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,EAAE;AAAA,IACF,GAAI,iBAAO,OAAO,OAAO,IACrB,CAAC,EAAE,QAAQ,WAAoB,MAAM,QAAQ,CAAC,IAC9C,CAAC;AAAA;AAAA;AAAA,IAGL,OAAG,yBAAW,YAAAA,QAAK,KAAK,OAAO,MAAM,WAAW,YAAY,CAAC,EAC1D,OAAO,CAAC,QAAQ,YAAAA,QAAK,SAAS,GAAG,EAAE,WAAW,iBAAiB,CAAC,EAChE,QAAQ,CAAC,YAAQ,yBAAW,YAAAA,QAAK,KAAK,KAAK,KAAK,CAAC,CAAC,EAClD,IAAI,CAAC,SAAS;AAAA,MACb,QAAQ;AAAA,MACR,MAAM,YAAAA,QAAK,KAAK,KAAK,OAAO;AAAA,IAC9B,EAAE;AAAA,EACN;AACA,SAAO,QAAQ;AAAA,IACb,MAAM,IAAI,OAAO,SAAS;AAAA,MACxB,GAAG;AAAA,MACH,SAAS,UAAM,wBAAU,IAAI,IAAI;AAAA,IACnC,EAAE;AAAA,EACJ;AACF;AAGK,MAAM,oBAAoB,wBAAwB;AAAA,EACvD,MAAM,UAAAC,QAAG,QAAQ;AAAA,EACjB,MAAM,QAAQ,IAAI,QAAQ;AAAA,EAC1B,cAAc;AAChB,CAAC;AAGD,eAAe,cAA+C;AAC5D,QAAM,SAAS,UAAM;AAAA,IACnB;AAAA,EACF;AACA,SAAO,WAAW,OAAO,CAAC,IAAI,EAAE,QAAQ,OAAO,QAAQ;AACzD;AAGA,MAAM,uBAAuB,aAAE,OAAO;AAAA,EACpC,cAAc,aAAE;AAAA,IACd,aAAE,OAAO;AAAA,MACP,MAAM,aAAE,OAAO;AAAA,MACf,MAAM,aAAE,OAAO;AAAA,MACf,mBAAmB,aAChB,OAAO,EAAE,YAAY,aAAE,OAAO,GAAG,QAAQ,aAAE,OAAO,EAAE,CAAC,EACrD,SAAS;AAAA,IACd,CAAC;AAAA,EACH;AACF,CAAC;AAGD,MAAM,kBAAkB,aAAE,OAAO;AAAA,EAC/B,WAAW,aAAE;AAAA,IACX,aAAE,OAAO;AAAA,MACP,MAAM,aAAE,OAAO;AAAA,MACf,iBAAiB,aAAE,OAAO;AAAA,MAC1B,SAAS,aAAE,OAAO;AAAA,MAClB,SAAS,aAAE,QAAQ;AAAA,IACrB,CAAC;AAAA,EACH;AACF,CAAC;AAGD,SAAS,aAAa,YAAqC;AACzD,QAAM,cAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,YAAY,KAAM,QAAO;AAC7B,SAAO,QAAQ,UAAU,IAAI,CAAC,OAAO;AAAA,IACnC,MAAM,EAAE;AAAA,IACR,aAAa,EAAE;AAAA,IACf,SAAS,EAAE;AAAA,IACX,SAAS,EAAE;AAAA,EACb,EAAE;AACJ;AAGO,SAAS,kBACd,iBACA,YACsB;AACtB,QAAM,mBAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,UAAU,aAAa,UAAU;AACvC,MAAI,iBAAiB,QAAQ,YAAY,KAAM,QAAO;AACtD,aAAO;AAAA,IACL,aAAa,aAAa,IAAI,CAAC,OAAO;AAAA,MACpC,MAAM,EAAE;AAAA;AAAA,MAER,QACE,EAAE,mBAAmB,eAAe,QAChC,EAAE,MAAM,OAAO,KAAK,EAAE,kBAAkB,OAAO,IAC/C,EAAE,MAAM,UAAU,MAAM,EAAE,KAAK;AAAA,IACvC,EAAE;AAAA,IACF;AAAA,EACF;AACF;AAEA,MAAM,WAAW;AAEjB,MAAM,cAAc,CAAC,UAAU,eAAe,WAAW,qBAAqB;AAGvE,MAAM,QAAQ;AAAA,EACnB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,QAAQ;AAAA,EACR;AAAA,EACA,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcZ,CAAC,UAAU,eAAe,OAAO,gCAAgC;AAAA;AAAA;AAAA,IAGjE;AAAA;AAAA,IAEA,CAAC,UAAU,OAAO,QAAQ;AAAA,EAC5B;AAAA,EACA,SAAS;AAAA,EACT,cAAc;AAAA,EACd,QAAQ;AACV;",
6
+ "names": ["path", "os"]
7
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var harness_exports = {};
30
+ __export(harness_exports, {
31
+ createGetNewestHarnessLocations: () => createGetNewestHarnessLocations,
32
+ getNewestHarnessLocations: () => getNewestHarnessLocations
33
+ });
34
+ module.exports = __toCommonJS(harness_exports);
35
+ var semver = __toESM(require("semver"), 1);
36
+ var import_claudeCode = require("./claudeCode.js");
37
+ var import_codex = require("./codex.js");
38
+ function newest(clis) {
39
+ const version = (cli) => semver.coerce(cli.version, { includePrerelease: true });
40
+ return [...clis].sort((a, b) => semver.rcompare(version(a), version(b)))[0];
41
+ }
42
+ const createGetNewestHarnessLocations = (getters) => async () => ({
43
+ codex: newest(await getters.getCodexLocations()),
44
+ claudeCode: newest(await getters.getClaudeCodeLocations())
45
+ });
46
+ const getNewestHarnessLocations = createGetNewestHarnessLocations({
47
+ getCodexLocations: import_codex.getCodexLocations,
48
+ getClaudeCodeLocations: import_claudeCode.getClaudeCodeLocations
49
+ });
50
+ //# sourceMappingURL=harness.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/cli/lib/plugins/harness.ts"],
4
+ "sourcesContent": ["/**\n * The Claude Code and Codex CLIs found on the user's machine. Users of the\n * desktop apps or the VS Code extensions often have no CLI on PATH, but each\n * app ships its own copy, which takes the same commands and shares the same\n * plugin state as the terminal CLI.\n */\nimport * as semver from \"semver\";\nimport { getClaudeCodeLocations } from \"./claudeCode.js\";\nimport { getCodexLocations } from \"./codex.js\";\n\n/** Where a copy of a harness CLI was found. */\ntype CliSource = \"terminal\" | \"desktop\" | \"vscode\";\n\n/** A copy of a harness CLI and the first line it prints for `--version`. */\nexport type Cli = { source: CliSource; path: string; version: string };\n\n/** Where to look for harness CLIs. */\nexport type Places = {\n home: string;\n /** Directories separated like `$PATH`. */\n path: string;\n /** Where macOS apps are installed, `/Applications`. */\n applications: string;\n};\n\n/** The copy with the highest version. Versions compare as semver, where a release beats its prereleases. */\nfunction newest(clis: Cli[]): Cli | undefined {\n // Every copy printed its version when the finder ran it.\n const version = (cli: Cli) =>\n semver.coerce(cli.version, { includePrerelease: true })!;\n return [...clis].sort((a, b) => semver.rcompare(version(a), version(b)))[0];\n}\n\n/** Builds `getNewestHarnessLocations` from the given location getters, so tests can pass fixed locations. */\nexport const createGetNewestHarnessLocations =\n (getters: {\n getCodexLocations: () => Promise<Cli[]>;\n getClaudeCodeLocations: () => Promise<Cli[]>;\n }) =>\n async () => ({\n codex: newest(await getters.getCodexLocations()),\n claudeCode: newest(await getters.getClaudeCodeLocations()),\n });\n\n/** The newest copy of each harness's CLI on this machine, or `undefined` for a harness that isn't installed. */\nexport const getNewestHarnessLocations = createGetNewestHarnessLocations({\n getCodexLocations,\n getClaudeCodeLocations,\n});\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,aAAwB;AACxB,wBAAuC;AACvC,mBAAkC;AAkBlC,SAAS,OAAO,MAA8B;AAE5C,QAAM,UAAU,CAAC,QACf,OAAO,OAAO,IAAI,SAAS,EAAE,mBAAmB,KAAK,CAAC;AACxD,SAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,SAAS,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5E;AAGO,MAAM,kCACX,CAAC,YAID,aAAa;AAAA,EACX,OAAO,OAAO,MAAM,QAAQ,kBAAkB,CAAC;AAAA,EAC/C,YAAY,OAAO,MAAM,QAAQ,uBAAuB,CAAC;AAC3D;AAGK,MAAM,4BAA4B,gCAAgC;AAAA,EACvE;AAAA,EACA;AACF,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var marketplaces_exports = {};
20
+ __export(marketplaces_exports, {
21
+ convexMarketplaces: () => convexMarketplaces,
22
+ logMarketplaces: () => logMarketplaces
23
+ });
24
+ module.exports = __toCommonJS(marketplaces_exports);
25
+ var import_log = require("../../../bundler/log.js");
26
+ var import_utils = require("./utils.js");
27
+ const pluginNames = ["convex", "convex-beta"];
28
+ function convexMarketplaces(marketplaces, plugins) {
29
+ const convex = plugins.filter((p) => pluginNames.includes(p.name));
30
+ return marketplaces.map((m) => ({
31
+ ...m,
32
+ plugins: convex.filter((p) => p.marketplace === m.name)
33
+ })).filter((m) => m.name.startsWith("convex") || m.plugins.length > 0);
34
+ }
35
+ function sourceText(source) {
36
+ switch (source.kind) {
37
+ case "github":
38
+ return `github.com/${source.repo}`;
39
+ case "git":
40
+ return source.url.replace(/^https?:\/\//, "").replace(/\.git$/, "");
41
+ case "folder":
42
+ return source.path;
43
+ case "other":
44
+ return source.type;
45
+ }
46
+ }
47
+ function logMarketplaces(title, marketplaces, latest) {
48
+ (0, import_log.logOutput)(title);
49
+ if (marketplaces.length === 0) {
50
+ (0, import_log.logOutput)(" No Convex plugin installed");
51
+ return;
52
+ }
53
+ const marketplaceLines = (0, import_utils.formatRows)(
54
+ marketplaces.map((m) => [m.name, sourceText(m.source)])
55
+ );
56
+ const pluginLines = (0, import_utils.formatRows)(
57
+ marketplaces.flatMap((m) => m.plugins).map((p) => [
58
+ p.name,
59
+ p.version,
60
+ latest[p.name] === void 0 ? "" : `latest ${latest[p.name]}`,
61
+ p.scope ?? "-",
62
+ p.enabled ? "enabled" : "disabled",
63
+ p.cachedVersion === void 0 ? "" : `cached copy ${p.cachedVersion}`
64
+ ]),
65
+ " "
66
+ );
67
+ let next = 0;
68
+ marketplaces.forEach((m, i) => {
69
+ (0, import_log.logOutput)(marketplaceLines[i]);
70
+ for (const line of pluginLines.slice(next, next + m.plugins.length)) {
71
+ (0, import_log.logOutput)(line);
72
+ }
73
+ next += m.plugins.length;
74
+ });
75
+ }
76
+ //# sourceMappingURL=marketplaces.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/cli/lib/plugins/marketplaces.ts"],
4
+ "sourcesContent": ["import { logOutput } from \"../../../bundler/log.js\";\nimport { formatRows } from \"./utils.js\";\n\n/** Names of the Convex plugins, including the old internal beta. */\nconst pluginNames = [\"convex\", \"convex-beta\"];\n\n/** A Convex plugin as its harness reports it. */\nexport type Plugin = {\n name: string;\n marketplace: string;\n /** The version that runs. */\n version: string;\n /** Claude Code only. */\n scope?: string;\n enabled: boolean;\n /** Claude Code folder installs only. The copy cached at install time, when it differs from the folder. */\n cachedVersion?: string | undefined;\n};\n\n/** Where a marketplace comes from. `other` is a source type we haven't seen, by its type name. */\nexport type Source =\n | { kind: \"github\"; repo: string }\n | { kind: \"git\"; url: string }\n | { kind: \"folder\"; path: string }\n | { kind: \"other\"; type: string };\n\n/** A marketplace named after Convex or holding a Convex plugin, with the Convex plugins installed from it. */\nexport type Marketplace = { name: string; source: Source; plugins: Plugin[] };\n\n/** Keeps the marketplaces named after Convex or holding a Convex plugin, each with its Convex plugins. */\nexport function convexMarketplaces(\n marketplaces: { name: string; source: Source }[],\n plugins: Plugin[],\n): Marketplace[] {\n const convex = plugins.filter((p) => pluginNames.includes(p.name));\n return marketplaces\n .map((m) => ({\n ...m,\n plugins: convex.filter((p) => p.marketplace === m.name),\n }))\n .filter((m) => m.name.startsWith(\"convex\") || m.plugins.length > 0);\n}\n\n/** Describes a marketplace's source for people. */\nfunction sourceText(source: Source): string {\n switch (source.kind) {\n case \"github\":\n return `github.com/${source.repo}`;\n case \"git\":\n return source.url.replace(/^https?:\\/\\//, \"\").replace(/\\.git$/, \"\");\n case \"folder\":\n return source.path;\n case \"other\":\n return source.type;\n }\n}\n\n/** Prints each Convex marketplace with its Convex plugins indented under it. */\nexport function logMarketplaces(\n title: string,\n marketplaces: Marketplace[],\n latest: Record<string, string>,\n) {\n logOutput(title);\n if (marketplaces.length === 0) {\n logOutput(\" No Convex plugin installed\");\n return;\n }\n const marketplaceLines = formatRows(\n marketplaces.map((m) => [m.name, sourceText(m.source)]),\n );\n // Plugin rows are formatted together so their columns line up across marketplaces.\n const pluginLines = formatRows(\n marketplaces\n .flatMap((m) => m.plugins)\n .map((p) => [\n p.name,\n p.version,\n latest[p.name] === undefined ? \"\" : `latest ${latest[p.name]}`,\n p.scope ?? \"-\",\n p.enabled ? \"enabled\" : \"disabled\",\n p.cachedVersion === undefined ? \"\" : `cached copy ${p.cachedVersion}`,\n ]),\n \" \",\n );\n let next = 0;\n marketplaces.forEach((m, i) => {\n logOutput(marketplaceLines[i]);\n for (const line of pluginLines.slice(next, next + m.plugins.length)) {\n logOutput(line);\n }\n next += m.plugins.length;\n });\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA0B;AAC1B,mBAA2B;AAG3B,MAAM,cAAc,CAAC,UAAU,aAAa;AA0BrC,SAAS,mBACd,cACA,SACe;AACf,QAAM,SAAS,QAAQ,OAAO,CAAC,MAAM,YAAY,SAAS,EAAE,IAAI,CAAC;AACjE,SAAO,aACJ,IAAI,CAAC,OAAO;AAAA,IACX,GAAG;AAAA,IACH,SAAS,OAAO,OAAO,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI;AAAA,EACxD,EAAE,EACD,OAAO,CAAC,MAAM,EAAE,KAAK,WAAW,QAAQ,KAAK,EAAE,QAAQ,SAAS,CAAC;AACtE;AAGA,SAAS,WAAW,QAAwB;AAC1C,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,cAAc,OAAO,IAAI;AAAA,IAClC,KAAK;AACH,aAAO,OAAO,IAAI,QAAQ,gBAAgB,EAAE,EAAE,QAAQ,UAAU,EAAE;AAAA,IACpE,KAAK;AACH,aAAO,OAAO;AAAA,IAChB,KAAK;AACH,aAAO,OAAO;AAAA,EAClB;AACF;AAGO,SAAS,gBACd,OACA,cACA,QACA;AACA,4BAAU,KAAK;AACf,MAAI,aAAa,WAAW,GAAG;AAC7B,8BAAU,8BAA8B;AACxC;AAAA,EACF;AACA,QAAM,uBAAmB;AAAA,IACvB,aAAa,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,WAAW,EAAE,MAAM,CAAC,CAAC;AAAA,EACxD;AAEA,QAAM,kBAAc;AAAA,IAClB,aACG,QAAQ,CAAC,MAAM,EAAE,OAAO,EACxB,IAAI,CAAC,MAAM;AAAA,MACV,EAAE;AAAA,MACF,EAAE;AAAA,MACF,OAAO,EAAE,IAAI,MAAM,SAAY,KAAK,UAAU,OAAO,EAAE,IAAI,CAAC;AAAA,MAC5D,EAAE,SAAS;AAAA,MACX,EAAE,UAAU,YAAY;AAAA,MACxB,EAAE,kBAAkB,SAAY,KAAK,eAAe,EAAE,aAAa;AAAA,IACrE,CAAC;AAAA,IACH;AAAA,EACF;AACA,MAAI,OAAO;AACX,eAAa,QAAQ,CAAC,GAAG,MAAM;AAC7B,8BAAU,iBAAiB,CAAC,CAAC;AAC7B,eAAW,QAAQ,YAAY,MAAM,MAAM,OAAO,EAAE,QAAQ,MAAM,GAAG;AACnE,gCAAU,IAAI;AAAA,IAChB;AACA,YAAQ,EAAE,QAAQ;AAAA,EACpB,CAAC;AACH;",
6
+ "names": []
7
+ }
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var skills_exports = {};
30
+ __export(skills_exports, {
31
+ convexSkillsFolders: () => convexSkillsFolders,
32
+ logConvexSkills: () => logConvexSkills
33
+ });
34
+ module.exports = __toCommonJS(skills_exports);
35
+ var import_os = __toESM(require("os"), 1);
36
+ var import_path = __toESM(require("path"), 1);
37
+ var import_fs = require("../../../bundler/fs.js");
38
+ var import_log = require("../../../bundler/log.js");
39
+ var import_versionApi = require("../versionApi.js");
40
+ function skillsFolders(dir, depth) {
41
+ let entries;
42
+ try {
43
+ entries = import_fs.nodeFs.listDir(dir);
44
+ } catch {
45
+ return [];
46
+ }
47
+ return entries.filter((entry) => entry.isDirectory()).flatMap((entry) => {
48
+ const child = import_path.default.join(dir, entry.name);
49
+ if (entry.name === "skills") return [child];
50
+ return depth > 1 ? skillsFolders(child, depth - 1) : [];
51
+ });
52
+ }
53
+ function convexSkillsFolders(root, names) {
54
+ return import_fs.nodeFs.listDir(root).filter((entry) => entry.isDirectory() && entry.name.startsWith(".")).flatMap((entry) => skillsFolders(import_path.default.join(root, entry.name), 2)).map((folder) => {
55
+ const entries = import_fs.nodeFs.listDir(folder).map((entry) => entry.name);
56
+ const current = entries.filter((name) => names.current.has(name));
57
+ const deleted = entries.filter((name) => names.deleted.has(name));
58
+ const brokenLinks = [...current, ...deleted].filter(
59
+ (name) => !import_fs.nodeFs.exists(import_path.default.join(folder, name))
60
+ ).length;
61
+ return {
62
+ path: folder,
63
+ current: current.length,
64
+ deleted: deleted.length,
65
+ brokenLinks
66
+ };
67
+ }).filter((folder) => folder.current + folder.deleted > 0);
68
+ }
69
+ function logSkills(title, root, label, names) {
70
+ const folders = convexSkillsFolders(root, names);
71
+ (0, import_log.logOutput)(title);
72
+ if (folders.length === 0) {
73
+ (0, import_log.logOutput)(" No Convex skills found");
74
+ return;
75
+ }
76
+ for (const folder of folders) {
77
+ (0, import_log.logOutput)(
78
+ ` ${folder.path.replace(root, label)} ${folder.current} Convex skills, ${folder.deleted} deleted, ${folder.brokenLinks} broken links`
79
+ );
80
+ }
81
+ }
82
+ async function logConvexSkills() {
83
+ const catalog = await (0, import_versionApi.fetchAgentSkillsCatalog)();
84
+ if (catalog.kind === "error") {
85
+ (0, import_log.logOutput)("Skills: couldn't fetch the list of Convex skills");
86
+ } else {
87
+ const names = (kind) => new Set(
88
+ catalog.data.skills.filter((skill) => skill.status.kind === kind).map((skill) => skill.skillName)
89
+ );
90
+ const skillNames = {
91
+ current: names("active"),
92
+ deleted: names("deleted")
93
+ };
94
+ logSkills("Global skills", import_os.default.homedir(), "~", skillNames);
95
+ logSkills("Project skills", process.cwd(), ".", skillNames);
96
+ }
97
+ }
98
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/cli/lib/plugins/skills.ts"],
4
+ "sourcesContent": ["import os from \"os\";\nimport path from \"path\";\nimport { nodeFs } from \"../../../bundler/fs.js\";\nimport { logOutput } from \"../../../bundler/log.js\";\nimport { fetchAgentSkillsCatalog } from \"../versionApi.js\";\n\n/** Finds folders named `skills` in a folder's children and grandchildren, without following links. */\nfunction skillsFolders(dir: string, depth: number): string[] {\n let entries;\n try {\n entries = nodeFs.listDir(dir);\n } catch {\n return [];\n }\n return entries\n .filter((entry) => entry.isDirectory())\n .flatMap((entry) => {\n const child = path.join(dir, entry.name);\n if (entry.name === \"skills\") return [child];\n return depth > 1 ? skillsFolders(child, depth - 1) : [];\n });\n}\n\n/** Convex skill names from the catalog on version.convex.dev, split into current and deleted ones. */\ntype SkillNames = { current: Set<string>; deleted: Set<string> };\n\n/** A skills folder holding Convex skills. */\ntype SkillsFolder = {\n path: string;\n current: number;\n deleted: number;\n brokenLinks: number;\n};\n\n/** Finds the skills folders in a root's hidden folders that hold Convex skills, counting deleted skills and broken links. */\nexport function convexSkillsFolders(\n root: string,\n names: SkillNames,\n): SkillsFolder[] {\n return nodeFs\n .listDir(root)\n .filter((entry) => entry.isDirectory() && entry.name.startsWith(\".\"))\n .flatMap((entry) => skillsFolders(path.join(root, entry.name), 2))\n .map((folder) => {\n const entries = nodeFs.listDir(folder).map((entry) => entry.name);\n const current = entries.filter((name) => names.current.has(name));\n const deleted = entries.filter((name) => names.deleted.has(name));\n // exists follows links, so it's false for a link whose target is gone.\n const brokenLinks = [...current, ...deleted].filter(\n (name) => !nodeFs.exists(path.join(folder, name)),\n ).length;\n return {\n path: folder,\n current: current.length,\n deleted: deleted.length,\n brokenLinks,\n };\n })\n .filter((folder) => folder.current + folder.deleted > 0);\n}\n\n/** Prints each skills folder in a root's hidden folders that holds Convex skills, counting deleted skills and broken links. */\nfunction logSkills(\n title: string,\n root: string,\n label: string,\n names: SkillNames,\n) {\n const folders = convexSkillsFolders(root, names);\n logOutput(title);\n if (folders.length === 0) {\n logOutput(\" No Convex skills found\");\n return;\n }\n for (const folder of folders) {\n logOutput(\n ` ${folder.path.replace(root, label)} ${folder.current} Convex skills, ${folder.deleted} deleted, ${folder.brokenLinks} broken links`,\n );\n }\n}\n\n/** Prints the Convex skills in the hidden folders of the home folder and the current folder. */\nexport async function logConvexSkills() {\n const catalog = await fetchAgentSkillsCatalog();\n if (catalog.kind === \"error\") {\n logOutput(\"Skills: couldn't fetch the list of Convex skills\");\n } else {\n const names = (kind: \"active\" | \"deleted\") =>\n new Set(\n catalog.data.skills\n .filter((skill) => skill.status.kind === kind)\n .map((skill) => skill.skillName),\n );\n const skillNames = {\n current: names(\"active\"),\n deleted: names(\"deleted\"),\n };\n logSkills(\"Global skills\", os.homedir(), \"~\", skillNames);\n logSkills(\"Project skills\", process.cwd(), \".\", skillNames);\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAe;AACf,kBAAiB;AACjB,gBAAuB;AACvB,iBAA0B;AAC1B,wBAAwC;AAGxC,SAAS,cAAc,KAAa,OAAyB;AAC3D,MAAI;AACJ,MAAI;AACF,cAAU,iBAAO,QAAQ,GAAG;AAAA,EAC9B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,SAAO,QACJ,OAAO,CAAC,UAAU,MAAM,YAAY,CAAC,EACrC,QAAQ,CAAC,UAAU;AAClB,UAAM,QAAQ,YAAAA,QAAK,KAAK,KAAK,MAAM,IAAI;AACvC,QAAI,MAAM,SAAS,SAAU,QAAO,CAAC,KAAK;AAC1C,WAAO,QAAQ,IAAI,cAAc,OAAO,QAAQ,CAAC,IAAI,CAAC;AAAA,EACxD,CAAC;AACL;AAcO,SAAS,oBACd,MACA,OACgB;AAChB,SAAO,iBACJ,QAAQ,IAAI,EACZ,OAAO,CAAC,UAAU,MAAM,YAAY,KAAK,MAAM,KAAK,WAAW,GAAG,CAAC,EACnE,QAAQ,CAAC,UAAU,cAAc,YAAAA,QAAK,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,EAChE,IAAI,CAAC,WAAW;AACf,UAAM,UAAU,iBAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,UAAU,MAAM,IAAI;AAChE,UAAM,UAAU,QAAQ,OAAO,CAAC,SAAS,MAAM,QAAQ,IAAI,IAAI,CAAC;AAChE,UAAM,UAAU,QAAQ,OAAO,CAAC,SAAS,MAAM,QAAQ,IAAI,IAAI,CAAC;AAEhE,UAAM,cAAc,CAAC,GAAG,SAAS,GAAG,OAAO,EAAE;AAAA,MAC3C,CAAC,SAAS,CAAC,iBAAO,OAAO,YAAAA,QAAK,KAAK,QAAQ,IAAI,CAAC;AAAA,IAClD,EAAE;AACF,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,QAAQ;AAAA,MACjB,SAAS,QAAQ;AAAA,MACjB;AAAA,IACF;AAAA,EACF,CAAC,EACA,OAAO,CAAC,WAAW,OAAO,UAAU,OAAO,UAAU,CAAC;AAC3D;AAGA,SAAS,UACP,OACA,MACA,OACA,OACA;AACA,QAAM,UAAU,oBAAoB,MAAM,KAAK;AAC/C,4BAAU,KAAK;AACf,MAAI,QAAQ,WAAW,GAAG;AACxB,8BAAU,0BAA0B;AACpC;AAAA,EACF;AACA,aAAW,UAAU,SAAS;AAC5B;AAAA,MACE,KAAK,OAAO,KAAK,QAAQ,MAAM,KAAK,CAAC,KAAK,OAAO,OAAO,mBAAmB,OAAO,OAAO,aAAa,OAAO,WAAW;AAAA,IAC1H;AAAA,EACF;AACF;AAGA,eAAsB,kBAAkB;AACtC,QAAM,UAAU,UAAM,2CAAwB;AAC9C,MAAI,QAAQ,SAAS,SAAS;AAC5B,8BAAU,kDAAkD;AAAA,EAC9D,OAAO;AACL,UAAM,QAAQ,CAAC,SACb,IAAI;AAAA,MACF,QAAQ,KAAK,OACV,OAAO,CAAC,UAAU,MAAM,OAAO,SAAS,IAAI,EAC5C,IAAI,CAAC,UAAU,MAAM,SAAS;AAAA,IACnC;AACF,UAAM,aAAa;AAAA,MACjB,SAAS,MAAM,QAAQ;AAAA,MACvB,SAAS,MAAM,SAAS;AAAA,IAC1B;AACA,cAAU,iBAAiB,UAAAC,QAAG,QAAQ,GAAG,KAAK,UAAU;AACxD,cAAU,kBAAkB,QAAQ,IAAI,GAAG,KAAK,UAAU;AAAA,EAC5D;AACF;",
6
+ "names": ["path", "os"]
7
+ }
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var utils_exports = {};
30
+ __export(utils_exports, {
31
+ capture: () => capture,
32
+ fetchGitHubJson: () => fetchGitHubJson,
33
+ formatRows: () => formatRows,
34
+ onPath: () => onPath,
35
+ parseList: () => parseList,
36
+ run: () => run,
37
+ subfolders: () => subfolders,
38
+ versionOf: () => versionOf
39
+ });
40
+ module.exports = __toCommonJS(utils_exports);
41
+ var import_child_process = __toESM(require("child_process"), 1);
42
+ var import_path = __toESM(require("path"), 1);
43
+ var import_util = require("util");
44
+ var Sentry = __toESM(require("@sentry/node"), 1);
45
+ var import_fs = require("../../../bundler/fs.js");
46
+ function onPath(name, pathDirs) {
47
+ const dir = pathDirs.split(import_path.default.delimiter).find((d) => import_fs.nodeFs.exists(import_path.default.join(d, name)));
48
+ return dir === void 0 ? [] : [import_path.default.join(dir, name)];
49
+ }
50
+ function subfolders(dir) {
51
+ let entries;
52
+ try {
53
+ entries = import_fs.nodeFs.listDir(dir);
54
+ } catch {
55
+ return [];
56
+ }
57
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => import_path.default.join(dir, entry.name)).sort();
58
+ }
59
+ async function versionOf(cli) {
60
+ const { stdout } = await (0, import_util.promisify)(import_child_process.default.execFile)(cli, [
61
+ "--version"
62
+ ]);
63
+ return stdout.split("\n")[0];
64
+ }
65
+ function run(command, args) {
66
+ return new Promise((resolve) => {
67
+ let output = "";
68
+ const proc = import_child_process.default.spawn(command, args, {
69
+ stdio: ["ignore", "pipe", "pipe"]
70
+ });
71
+ proc.stdout.on("data", (chunk) => output += chunk);
72
+ proc.stderr.on("data", (chunk) => output += chunk);
73
+ proc.on("error", () => resolve({ ok: false, output }));
74
+ proc.on("close", (code) => resolve({ ok: code === 0, output }));
75
+ });
76
+ }
77
+ function capture(command, args) {
78
+ return new Promise((resolve) => {
79
+ let stdout = "";
80
+ const proc = import_child_process.default.spawn(command, args, {
81
+ stdio: ["ignore", "pipe", "inherit"]
82
+ });
83
+ proc.stdout.on("data", (chunk) => stdout += chunk);
84
+ proc.on("error", () => resolve(null));
85
+ proc.on("close", () => resolve(stdout));
86
+ });
87
+ }
88
+ async function fetchGitHubJson(path2) {
89
+ try {
90
+ const response = await fetch(`https://raw.githubusercontent.com/${path2}`);
91
+ if (!response.ok) {
92
+ Sentry.captureException(
93
+ new Error(`Failed to fetch ${path2}: status = ${response.status}`)
94
+ );
95
+ return null;
96
+ }
97
+ return await response.json();
98
+ } catch (error) {
99
+ Sentry.captureException(error);
100
+ return null;
101
+ }
102
+ }
103
+ function parseList(schema, list, command) {
104
+ let result;
105
+ try {
106
+ result = schema.safeParse(JSON.parse(list));
107
+ } catch {
108
+ result = void 0;
109
+ }
110
+ if (!result?.success) {
111
+ Sentry.captureMessage(`Unexpected output from \`${command}\``, "error");
112
+ return null;
113
+ }
114
+ return result.data;
115
+ }
116
+ function formatRows(rows, indent = " ") {
117
+ if (rows.length === 0) return [];
118
+ const widths = rows[0].map(
119
+ (_, i) => Math.max(...rows.map((row) => row[i].length))
120
+ );
121
+ return rows.map(
122
+ (row) => `${indent}${row.map((cell, i) => cell.padEnd(widths[i])).join(" ")}`.trimEnd()
123
+ );
124
+ }
125
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/cli/lib/plugins/utils.ts"],
4
+ "sourcesContent": ["import child_process from \"child_process\";\nimport path from \"path\";\nimport { promisify } from \"util\";\nimport * as Sentry from \"@sentry/node\";\nimport { z } from \"zod\";\nimport { nodeFs } from \"../../../bundler/fs.js\";\n\n/** The file the shell runs for `name`, like `which`. */\nexport function onPath(name: string, pathDirs: string): string[] {\n const dir = pathDirs\n .split(path.delimiter)\n .find((d) => nodeFs.exists(path.join(d, name)));\n return dir === undefined ? [] : [path.join(dir, name)];\n}\n\n/** The folders directly inside `dir`, sorted by name, or none when `dir` doesn't exist. */\nexport function subfolders(dir: string): string[] {\n let entries;\n try {\n entries = nodeFs.listDir(dir);\n } catch {\n return [];\n }\n return entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => path.join(dir, entry.name))\n .sort();\n}\n\n/** The first line a CLI prints for `--version`. */\nexport async function versionOf(cli: string): Promise<string> {\n const { stdout } = await promisify(child_process.execFile)(cli, [\n \"--version\",\n ]);\n return stdout.split(\"\\n\")[0];\n}\n\n/** Runs a command and resolves to whether it succeeded and everything it printed. */\nexport function run(\n command: string,\n args: string[],\n): Promise<{ ok: boolean; output: string }> {\n return new Promise((resolve) => {\n let output = \"\";\n\n const proc = child_process.spawn(command, args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n proc.stdout.on(\"data\", (chunk) => (output += chunk));\n proc.stderr.on(\"data\", (chunk) => (output += chunk));\n proc.on(\"error\", () => resolve({ ok: false, output }));\n proc.on(\"close\", (code) => resolve({ ok: code === 0, output }));\n });\n}\n\n/** Runs a command and resolves to its stdout, or null when it can't be started. */\nexport function capture(\n command: string,\n args: string[],\n): Promise<string | null> {\n return new Promise((resolve) => {\n let stdout = \"\";\n\n const proc = child_process.spawn(command, args, {\n stdio: [\"ignore\", \"pipe\", \"inherit\"],\n });\n\n proc.stdout.on(\"data\", (chunk) => (stdout += chunk));\n proc.on(\"error\", () => resolve(null));\n proc.on(\"close\", () => resolve(stdout));\n });\n}\n\n/** Fetches a JSON file from GitHub, or resolves to null when it can't, reporting why to Sentry. */\nexport async function fetchGitHubJson<T>(path: string): Promise<T | null> {\n try {\n const response = await fetch(`https://raw.githubusercontent.com/${path}`);\n if (!response.ok) {\n Sentry.captureException(\n new Error(`Failed to fetch ${path}: status = ${response.status}`),\n );\n return null;\n }\n return (await response.json()) as T;\n } catch (error) {\n Sentry.captureException(error);\n return null;\n }\n}\n\n/** Parses a JSON list from a harness CLI, or returns null and reports to Sentry when it isn't JSON or doesn't match. */\nexport function parseList<T>(\n schema: z.ZodType<T, z.ZodTypeDef, unknown>,\n list: string,\n command: string,\n): T | null {\n let result;\n try {\n result = schema.safeParse(JSON.parse(list));\n } catch {\n // A failing CLI can print nothing, which isn't JSON.\n result = undefined;\n }\n if (!result?.success) {\n Sentry.captureMessage(`Unexpected output from \\`${command}\\``, \"error\");\n return null;\n }\n return result.data;\n}\n\n/** Pads each column to its widest cell and indents every row. */\nexport function formatRows(rows: string[][], indent = \" \"): string[] {\n if (rows.length === 0) return [];\n const widths = rows[0].map((_, i) =>\n Math.max(...rows.map((row) => row[i].length)),\n );\n return rows.map((row) =>\n `${indent}${row.map((cell, i) => cell.padEnd(widths[i])).join(\" \")}`.trimEnd(),\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["path", "child_process"]
7
+ }