convex 1.47.0 → 1.48.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.
- package/CHANGELOG.md +28 -4
- package/README.md +1 -1
- package/dist/browser.bundle.js +1 -1
- package/dist/browser.bundle.js.map +1 -1
- package/dist/cjs/cli/aiFiles.js +26 -4
- package/dist/cjs/cli/aiFiles.js.map +2 -2
- package/dist/cjs/cli/env.js +6 -3
- package/dist/cjs/cli/env.js.map +2 -2
- package/dist/cjs/cli/envDefault.js +5 -2
- package/dist/cjs/cli/envDefault.js.map +2 -2
- package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js +2 -1
- package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js.map +2 -2
- package/dist/cjs/cli/lib/aiFiles/index.js +13 -2
- package/dist/cjs/cli/lib/aiFiles/index.js.map +2 -2
- package/dist/cjs/cli/lib/aiFiles/skills.js +6 -5
- package/dist/cjs/cli/lib/aiFiles/skills.js.map +2 -2
- package/dist/cjs/cli/lib/aiFiles/state.js +1 -1
- package/dist/cjs/cli/lib/aiFiles/state.js.map +1 -1
- package/dist/cjs/cli/lib/components.js +12 -2
- package/dist/cjs/cli/lib/components.js.map +2 -2
- package/dist/cjs/cli/lib/deployApi/startPush.js +42 -1
- package/dist/cjs/cli/lib/deployApi/startPush.js.map +2 -2
- package/dist/cjs/cli/lib/env.js +9 -1
- package/dist/cjs/cli/lib/env.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/dashboard.js +11 -1
- package/dist/cjs/cli/lib/localDeployment/dashboard.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/download.js +16 -1
- package/dist/cjs/cli/lib/localDeployment/download.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/utils.js +4 -0
- package/dist/cjs/cli/lib/localDeployment/utils.js.map +2 -2
- package/dist/cjs/cli/lib/utils/aiAgent.js +32 -0
- package/dist/cjs/cli/lib/utils/aiAgent.js.map +7 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server/authentication.js.map +1 -1
- package/dist/cjs/server/components/index.js.map +2 -2
- package/dist/cjs/server/impl/authentication_impl.js +15 -1
- package/dist/cjs/server/impl/authentication_impl.js.map +2 -2
- package/dist/cjs/server/impl/registration_impl.js +1 -1
- package/dist/cjs/server/impl/registration_impl.js.map +2 -2
- package/dist/cjs/server/index.js.map +2 -2
- package/dist/cjs/server/meta.js.map +1 -1
- package/dist/cjs/server/registration.js.map +1 -1
- package/dist/cjs/server/schema.js +0 -2
- package/dist/cjs/server/schema.js.map +2 -2
- package/dist/cjs/server/storage.js.map +1 -1
- package/dist/cjs-types/cli/aiFiles.d.ts.map +1 -1
- package/dist/cjs-types/cli/env.d.ts.map +1 -1
- package/dist/cjs-types/cli/envDefault.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts +3 -1
- package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/aiFiles/index.d.ts +11 -1
- package/dist/cjs-types/cli/lib/aiFiles/index.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts +4 -1
- package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/components.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +13 -0
- package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/env.d.ts +1 -0
- package/dist/cjs-types/cli/lib/env.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/dashboard.d.ts +6 -0
- package/dist/cjs-types/cli/lib/localDeployment/dashboard.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/download.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts +1 -0
- package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/utils/aiAgent.d.ts +8 -0
- package/dist/cjs-types/cli/lib/utils/aiAgent.d.ts.map +1 -0
- package/dist/cjs-types/index.d.ts +1 -1
- package/dist/cjs-types/server/authentication.d.ts +65 -0
- package/dist/cjs-types/server/authentication.d.ts.map +1 -1
- package/dist/cjs-types/server/components/index.d.ts +6 -0
- package/dist/cjs-types/server/components/index.d.ts.map +1 -1
- package/dist/cjs-types/server/impl/authentication_impl.d.ts +2 -1
- package/dist/cjs-types/server/impl/authentication_impl.d.ts.map +1 -1
- package/dist/cjs-types/server/index.d.ts +2 -2
- package/dist/cjs-types/server/index.d.ts.map +1 -1
- package/dist/cjs-types/server/meta.d.ts +8 -0
- package/dist/cjs-types/server/meta.d.ts.map +1 -1
- package/dist/cjs-types/server/registration.d.ts +5 -3
- package/dist/cjs-types/server/registration.d.ts.map +1 -1
- package/dist/cjs-types/server/schema.d.ts +0 -2
- package/dist/cjs-types/server/schema.d.ts.map +1 -1
- package/dist/cjs-types/server/storage.d.ts +28 -25
- package/dist/cjs-types/server/storage.d.ts.map +1 -1
- package/dist/cli.bundle.cjs +284 -25
- package/dist/cli.bundle.cjs.map +4 -4
- package/dist/esm/cli/aiFiles.js +26 -4
- package/dist/esm/cli/aiFiles.js.map +2 -2
- package/dist/esm/cli/env.js +6 -3
- package/dist/esm/cli/env.js.map +2 -2
- package/dist/esm/cli/envDefault.js +5 -2
- package/dist/esm/cli/envDefault.js.map +2 -2
- package/dist/esm/cli/lib/aiFiles/guidelinesmd.js +2 -1
- package/dist/esm/cli/lib/aiFiles/guidelinesmd.js.map +2 -2
- package/dist/esm/cli/lib/aiFiles/index.js +13 -2
- package/dist/esm/cli/lib/aiFiles/index.js.map +2 -2
- package/dist/esm/cli/lib/aiFiles/skills.js +6 -5
- package/dist/esm/cli/lib/aiFiles/skills.js.map +2 -2
- package/dist/esm/cli/lib/aiFiles/state.js +1 -1
- package/dist/esm/cli/lib/aiFiles/state.js.map +1 -1
- package/dist/esm/cli/lib/components.js +15 -2
- package/dist/esm/cli/lib/components.js.map +2 -2
- package/dist/esm/cli/lib/deployApi/startPush.js +39 -0
- package/dist/esm/cli/lib/deployApi/startPush.js.map +2 -2
- package/dist/esm/cli/lib/env.js +9 -1
- package/dist/esm/cli/lib/env.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/dashboard.js +9 -0
- package/dist/esm/cli/lib/localDeployment/dashboard.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/download.js +16 -1
- package/dist/esm/cli/lib/localDeployment/download.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/utils.js +3 -0
- package/dist/esm/cli/lib/localDeployment/utils.js.map +2 -2
- package/dist/esm/cli/lib/utils/aiAgent.js +10 -0
- package/dist/esm/cli/lib/utils/aiAgent.js.map +7 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/server/components/index.js.map +2 -2
- package/dist/esm/server/impl/authentication_impl.js +13 -0
- package/dist/esm/server/impl/authentication_impl.js.map +2 -2
- package/dist/esm/server/impl/registration_impl.js +2 -2
- package/dist/esm/server/impl/registration_impl.js.map +2 -2
- package/dist/esm/server/index.js.map +2 -2
- package/dist/esm/server/schema.js +0 -2
- package/dist/esm/server/schema.js.map +2 -2
- package/dist/esm-types/cli/aiFiles.d.ts.map +1 -1
- package/dist/esm-types/cli/env.d.ts.map +1 -1
- package/dist/esm-types/cli/envDefault.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts +3 -1
- package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/aiFiles/index.d.ts +11 -1
- package/dist/esm-types/cli/lib/aiFiles/index.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/aiFiles/skills.d.ts +4 -1
- package/dist/esm-types/cli/lib/aiFiles/skills.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/components.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +13 -0
- package/dist/esm-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/env.d.ts +1 -0
- package/dist/esm-types/cli/lib/env.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/dashboard.d.ts +6 -0
- package/dist/esm-types/cli/lib/localDeployment/dashboard.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/download.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/localDeployment/utils.d.ts +1 -0
- package/dist/esm-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/utils/aiAgent.d.ts +8 -0
- package/dist/esm-types/cli/lib/utils/aiAgent.d.ts.map +1 -0
- package/dist/esm-types/index.d.ts +1 -1
- package/dist/esm-types/server/authentication.d.ts +65 -0
- package/dist/esm-types/server/authentication.d.ts.map +1 -1
- package/dist/esm-types/server/components/index.d.ts +6 -0
- package/dist/esm-types/server/components/index.d.ts.map +1 -1
- package/dist/esm-types/server/impl/authentication_impl.d.ts +2 -1
- package/dist/esm-types/server/impl/authentication_impl.d.ts.map +1 -1
- package/dist/esm-types/server/index.d.ts +2 -2
- package/dist/esm-types/server/index.d.ts.map +1 -1
- package/dist/esm-types/server/meta.d.ts +8 -0
- package/dist/esm-types/server/meta.d.ts.map +1 -1
- package/dist/esm-types/server/registration.d.ts +5 -3
- package/dist/esm-types/server/registration.d.ts.map +1 -1
- package/dist/esm-types/server/schema.d.ts +0 -2
- package/dist/esm-types/server/schema.d.ts.map +1 -1
- package/dist/esm-types/server/storage.d.ts +28 -25
- package/dist/esm-types/server/storage.d.ts.map +1 -1
- package/dist/react.bundle.js +1 -1
- package/dist/react.bundle.js.map +1 -1
- package/package.json +3 -2
- package/schemas/convex.schema.json +1 -2
- package/src/cli/aiFiles.ts +30 -4
- package/src/cli/env.ts +4 -1
- package/src/cli/envDefault.ts +4 -1
- package/src/cli/lib/aiFiles/guidelinesmd.ts +7 -2
- package/src/cli/lib/aiFiles/index.ts +23 -3
- package/src/cli/lib/aiFiles/skills.ts +11 -7
- package/src/cli/lib/aiFiles/state.ts +1 -1
- package/src/cli/lib/components.ts +18 -3
- package/src/cli/lib/deployApi/startPush.ts +64 -0
- package/src/cli/lib/env.ts +13 -2
- package/src/cli/lib/localDeployment/dashboard.ts +19 -0
- package/src/cli/lib/localDeployment/download.ts +17 -1
- package/src/cli/lib/localDeployment/utils.ts +4 -0
- package/src/cli/lib/utils/aiAgent.ts +15 -0
- package/src/index.ts +1 -1
- package/src/server/authentication.ts +79 -0
- package/src/server/components/index.ts +11 -0
- package/src/server/impl/authentication_impl.ts +15 -1
- package/src/server/impl/registration_impl.ts +2 -2
- package/src/server/index.ts +6 -0
- package/src/server/meta.ts +0 -8
- package/src/server/registration.ts +5 -2
- package/src/server/schema.ts +0 -2
- package/src/server/storage.ts +29 -42
package/dist/esm/cli/aiFiles.js
CHANGED
|
@@ -25,8 +25,19 @@ async function resolveProjectPaths() {
|
|
|
25
25
|
const aiInstall = new Command("install").summary("Install or refresh Convex AI files").description(
|
|
26
26
|
"Installs the following (or refreshes them if already present):\n - convex/_generated/ai/guidelines.md\n - AGENTS.md (Convex section only)\n - CLAUDE.md (Convex section only)\n - Agent skills (installed to each coding agent's native path, configured via convex.json)"
|
|
27
27
|
).allowExcessArguments(false).action(async () => {
|
|
28
|
-
const { projectDir, convexDir, aiFilesConfig } = await resolveProjectPaths();
|
|
29
|
-
await installAiFiles({
|
|
28
|
+
const { ctx, projectDir, convexDir, aiFilesConfig } = await resolveProjectPaths();
|
|
29
|
+
const result = await installAiFiles({
|
|
30
|
+
projectDir,
|
|
31
|
+
convexDir,
|
|
32
|
+
aiFilesConfig
|
|
33
|
+
});
|
|
34
|
+
if (result.kind === "error") {
|
|
35
|
+
return await ctx.crash({
|
|
36
|
+
exitCode: 1,
|
|
37
|
+
errorType: "fatal",
|
|
38
|
+
printedMessage: result.message
|
|
39
|
+
});
|
|
40
|
+
}
|
|
30
41
|
logMessage(`${chalkStderr.green("\u2714")} Convex AI files installed.`);
|
|
31
42
|
});
|
|
32
43
|
const aiEnable = new Command("enable").summary("Enable Convex AI files").description(
|
|
@@ -43,8 +54,19 @@ const aiEnable = new Command("enable").summary("Enable Convex AI files").descrip
|
|
|
43
54
|
const aiUpdate = new Command("update").summary("Update Convex AI files to the latest version").description(
|
|
44
55
|
"Updates the following to their latest versions:\n - convex/_generated/ai/guidelines.md\n - AGENTS.md (Convex section only)\n - CLAUDE.md (Convex section only)\n - Agent skills (installed to each coding agent's native path, configured via convex.json)"
|
|
45
56
|
).allowExcessArguments(false).action(async () => {
|
|
46
|
-
const { projectDir, convexDir, aiFilesConfig } = await resolveProjectPaths();
|
|
47
|
-
await installAiFiles({
|
|
57
|
+
const { ctx, projectDir, convexDir, aiFilesConfig } = await resolveProjectPaths();
|
|
58
|
+
const result = await installAiFiles({
|
|
59
|
+
projectDir,
|
|
60
|
+
convexDir,
|
|
61
|
+
aiFilesConfig
|
|
62
|
+
});
|
|
63
|
+
if (result.kind === "error") {
|
|
64
|
+
return await ctx.crash({
|
|
65
|
+
exitCode: 1,
|
|
66
|
+
errorType: "fatal",
|
|
67
|
+
printedMessage: result.message
|
|
68
|
+
});
|
|
69
|
+
}
|
|
48
70
|
logMessage(`${chalkStderr.green("\u2714")} Convex AI files updated.`);
|
|
49
71
|
});
|
|
50
72
|
const aiDisable = new Command("disable").summary("Disable Convex AI files without removing them").description(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/cli/aiFiles.ts"],
|
|
4
|
-
"sourcesContent": ["import path from \"path\";\nimport { Command } from \"@commander-js/extra-typings\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../bundler/log.js\";\nimport { oneoffContext } from \"../bundler/context.js\";\nimport { readProjectConfig } from \"./lib/config.js\";\nimport { functionsDir } from \"./lib/utils/utils.js\";\nimport {\n installAiFiles,\n enableAiFiles,\n disableAiFiles,\n removeAiFiles,\n} from \"./lib/aiFiles/index.js\";\nimport { statusAiFiles } from \"./lib/aiFiles/status.js\";\nimport { writeAiFilesConfig } from \"./lib/config.js\";\n\nasync function resolveProjectPaths() {\n const ctx = await oneoffContext({});\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n const convexDir = path.resolve(functionsDir(configPath, projectConfig));\n const projectDir = path.resolve(path.dirname(configPath));\n const aiFilesConfig = projectConfig.aiFiles;\n return { ctx, projectDir, convexDir, aiFilesConfig, projectConfig };\n}\n\nconst aiInstall = new Command(\"install\")\n .summary(\"Install or refresh Convex AI files\")\n .description(\n \"Installs the following (or refreshes them if already present):\\n\" +\n \" - convex/_generated/ai/guidelines.md\\n\" +\n \" - AGENTS.md (Convex section only)\\n\" +\n \" - CLAUDE.md (Convex section only)\\n\" +\n \" - Agent skills (installed to each coding agent's native path, configured via convex.json)\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n await installAiFiles({
|
|
5
|
-
"mappings": ";AAAA,OAAO,UAAU;AACjB,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,qBAAqB;AAC9B,SAAS,0BAA0B;AAEnC,eAAe,sBAAsB;AACnC,QAAM,MAAM,MAAM,cAAc,CAAC,CAAC;AAClC,QAAM,EAAE,YAAY,cAAc,IAAI,MAAM,kBAAkB,GAAG;AACjE,QAAM,YAAY,KAAK,QAAQ,aAAa,YAAY,aAAa,CAAC;AACtE,QAAM,aAAa,KAAK,QAAQ,KAAK,QAAQ,UAAU,CAAC;AACxD,QAAM,gBAAgB,cAAc;AACpC,SAAO,EAAE,KAAK,YAAY,WAAW,eAAe,cAAc;AACpE;AAEA,MAAM,YAAY,IAAI,QAAQ,SAAS,EACpC,QAAQ,oCAAoC,EAC5C;AAAA,EACC;AAKF,EACC,qBAAqB,KAAK,EAC1B,OAAO,YAAY;AAClB,QAAM,EAAE,YAAY,WAAW,cAAc,
|
|
4
|
+
"sourcesContent": ["import path from \"path\";\nimport { Command } from \"@commander-js/extra-typings\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../bundler/log.js\";\nimport { oneoffContext } from \"../bundler/context.js\";\nimport { readProjectConfig } from \"./lib/config.js\";\nimport { functionsDir } from \"./lib/utils/utils.js\";\nimport {\n installAiFiles,\n enableAiFiles,\n disableAiFiles,\n removeAiFiles,\n} from \"./lib/aiFiles/index.js\";\nimport { statusAiFiles } from \"./lib/aiFiles/status.js\";\nimport { writeAiFilesConfig } from \"./lib/config.js\";\n\nasync function resolveProjectPaths() {\n const ctx = await oneoffContext({});\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n const convexDir = path.resolve(functionsDir(configPath, projectConfig));\n const projectDir = path.resolve(path.dirname(configPath));\n const aiFilesConfig = projectConfig.aiFiles;\n return { ctx, projectDir, convexDir, aiFilesConfig, projectConfig };\n}\n\nconst aiInstall = new Command(\"install\")\n .summary(\"Install or refresh Convex AI files\")\n .description(\n \"Installs the following (or refreshes them if already present):\\n\" +\n \" - convex/_generated/ai/guidelines.md\\n\" +\n \" - AGENTS.md (Convex section only)\\n\" +\n \" - CLAUDE.md (Convex section only)\\n\" +\n \" - Agent skills (installed to each coding agent's native path, configured via convex.json)\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { ctx, projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n\n const result = await installAiFiles({\n projectDir,\n convexDir,\n aiFilesConfig,\n });\n\n if (result.kind === \"error\") {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: result.message,\n });\n }\n\n logMessage(`${chalkStderr.green(\"\u2714\")} Convex AI files installed.`);\n });\n\nconst aiEnable = new Command(\"enable\")\n .summary(\"Enable Convex AI files\")\n .description(\n \"Re-enables Convex AI files by writing `aiFiles.enabled: true` to\\n\" +\n \"`convex.json`, then installs or refreshes the managed AI files.\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n\n const newAiFilesConfig = await enableAiFiles({\n projectDir,\n convexDir,\n aiFilesConfig,\n });\n\n await writeAiFilesConfig({ projectDir, aiFiles: newAiFilesConfig });\n });\n\nconst aiUpdate = new Command(\"update\")\n .summary(\"Update Convex AI files to the latest version\")\n .description(\n \"Updates the following to their latest versions:\\n\" +\n \" - convex/_generated/ai/guidelines.md\\n\" +\n \" - AGENTS.md (Convex section only)\\n\" +\n \" - CLAUDE.md (Convex section only)\\n\" +\n \" - Agent skills (installed to each coding agent's native path, configured via convex.json)\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { ctx, projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n\n const result = await installAiFiles({\n projectDir,\n convexDir,\n aiFilesConfig,\n });\n\n if (result.kind === \"error\") {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: result.message,\n });\n }\n\n logMessage(`${chalkStderr.green(\"\u2714\")} Convex AI files updated.`);\n });\n\nconst aiDisable = new Command(\"disable\")\n .summary(\"Disable Convex AI files without removing them\")\n .description(\n \"Writes `aiFiles.enabled: false` to `convex.json` so `npx convex dev`\\n\" +\n \"stops prompting to install AI files and suppresses staleness messages.\\n\\n\" +\n \"Files already installed are left untouched - use `npx convex ai-files remove`\\n\" +\n \"if you also want to delete them.\\n\\n\" +\n \"Run `npx convex ai-files enable` to re-enable at any time.\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { projectDir, aiFilesConfig } = await resolveProjectPaths();\n\n const newAiFilesConfig = disableAiFiles(aiFilesConfig);\n\n await writeAiFilesConfig({\n projectDir,\n aiFiles: newAiFilesConfig,\n });\n\n logMessage(\n `${chalkStderr.green(`\u2714`)} Convex AI files disabled. Run ${chalkStderr.bold(`npx convex ai-files enable`)} to re-enable.`,\n );\n });\n\nconst aiStatus = new Command(\"status\")\n .summary(\"Show the current status of Convex AI files\")\n .description(\n \"Prints whether Convex AI files are enabled, and for each component:\\n\" +\n \" - convex/_generated/ai/guidelines.md\\n\" +\n \" - AGENTS.md (Convex section)\\n\" +\n \" - CLAUDE.md (if installed by Convex)\\n\" +\n \" - Agent skills\\n\\n\" +\n \"Fetches the latest hashes from version.convex.dev to report whether\\n\" +\n \"each file is up to date. If the network is unavailable the staleness\\n\" +\n \"check is skipped silently.\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n\n await statusAiFiles({ projectDir, convexDir, aiFilesConfig });\n });\n\nconst aiRemove = new Command(\"remove\")\n .summary(\"Remove all Convex AI files from the project\")\n .description(\n \"Removes the following:\\n\" +\n \" - convex/_generated/ai/ directory (guidelines.md, ai-files.state.json)\\n\" +\n \" - Convex sections from AGENTS.md and CLAUDE.md\\n\" +\n \" - Agent skills installed by `npx convex ai-files install`\\n\\n\" +\n \"If removing the managed section leaves AGENTS.md or CLAUDE.md empty, the\\n\" +\n \"empty file is deleted. Otherwise the rest of the file is kept.\\n\\n\" +\n \"Skills installed from other sources are not affected.\\n\\n\" +\n \"Note: after `remove`, `npx convex dev` will suggest reinstalling AI files.\\n\" +\n \"Use `npx convex ai-files disable` to opt out entirely without deleting files.\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { ctx, projectDir, convexDir } = await resolveProjectPaths();\n const result = await removeAiFiles({ projectDir, convexDir });\n if (result.kind === \"error\") {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: result.message,\n });\n }\n });\n\nexport const aiFiles = new Command(\"ai-files\")\n .summary(\"Manage Convex AI files\")\n .description(\n \"Convex AI files help AI coding assistants (Cursor, Claude Code, etc.) understand\\n\" +\n \"Convex patterns and APIs. They are set up during your first `npx convex dev`\\n\" +\n \"and can be managed at any time with the commands below.\",\n )\n .addCommand(aiStatus)\n .addCommand(aiInstall)\n .addCommand(aiEnable)\n .addCommand(aiUpdate)\n .addCommand(aiDisable)\n .addCommand(aiRemove)\n .addHelpCommand(false);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/esm/cli/env.js
CHANGED
|
@@ -119,7 +119,9 @@ const envListCmd = new Command("list").summary("List all environment variables a
|
|
|
119
119
|
"\u2022 List only variable names (no values): `npx convex env list --names-only`",
|
|
120
120
|
"\u2022 List all variables and their values: `npx convex env list --include-values`",
|
|
121
121
|
"\u2022 Save all variables to a file: `npx convex env list --include-values > .env.convex`",
|
|
122
|
-
"\u2022 Append to a file: `npx convex env list --include-values >> .env.convex`"
|
|
122
|
+
"\u2022 Append to a file: `npx convex env list --include-values >> .env.convex`",
|
|
123
|
+
"",
|
|
124
|
+
"When an AI agent runs this command (detected from environment variables like AI_AGENT or CLAUDECODE), only names are listed unless --include-values is passed."
|
|
123
125
|
].join("\n")
|
|
124
126
|
).option(
|
|
125
127
|
"--names-only",
|
|
@@ -127,7 +129,7 @@ const envListCmd = new Command("list").summary("List all environment variables a
|
|
|
127
129
|
).addOption(
|
|
128
130
|
new Option(
|
|
129
131
|
"--include-values",
|
|
130
|
-
"Print each variable's value alongside its name, in .env format
|
|
132
|
+
"Print each variable's value alongside its name, in .env format. This is the default unless an AI agent is detected, so pass it explicitly in scripts that rely on the values."
|
|
131
133
|
).conflicts("namesOnly")
|
|
132
134
|
).configureHelp({ showGlobalOptions: true }).allowExcessArguments(false).action(async (cmdOptions, cmd) => {
|
|
133
135
|
const options = cmd.optsWithGlobals();
|
|
@@ -139,7 +141,8 @@ const envListCmd = new Command("list").summary("List all environment variables a
|
|
|
139
141
|
action: async () => {
|
|
140
142
|
const backend = deploymentEnvBackend(ctx, deployment);
|
|
141
143
|
await envList(ctx, backend, {
|
|
142
|
-
namesOnly: cmdOptions.namesOnly ?? false
|
|
144
|
+
namesOnly: cmdOptions.namesOnly ?? false,
|
|
145
|
+
includeValues: cmdOptions.includeValues ?? false
|
|
143
146
|
});
|
|
144
147
|
}
|
|
145
148
|
});
|
package/dist/esm/cli/env.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/cli/env.ts"],
|
|
4
|
-
"sourcesContent": ["import { Command, Option } from \"@commander-js/extra-typings\";\nimport { chalkStderr } from \"chalk\";\nimport { Context, oneoffContext } from \"../bundler/context.js\";\nimport {\n DeploymentSelectionOptions,\n DetailedDeploymentCredentials,\n loadSelectedDeploymentCredentials,\n} from \"./lib/api.js\";\nimport { actionDescription } from \"./lib/command.js\";\nimport { ensureHasConvexDependency } from \"./lib/utils/utils.js\";\nimport {\n deploymentEnvBackend,\n envGet,\n envList,\n envRemove,\n envSet,\n} from \"./lib/env.js\";\nimport { getDeploymentSelection } from \"./lib/deploymentSelection.js\";\nimport { withRunningBackend } from \"./lib/localDeployment/run.js\";\nimport { envDefault } from \"./envDefault.js\";\n\nconst envSetCmd = new Command(\"set\")\n // Pretend value is required\n .usage(\"[options] <name> <value>\")\n .argument(\"[name]\", \"The name of the environment variable to set.\")\n .argument(\n \"[value]\",\n \"The value to set the variable to. Omit to set it interactively.\",\n )\n .summary(\"Set a variable\")\n .description(\n [\n \"Set environment variables on your deployment.\",\n \"\",\n \"\u2022 `npx convex env set NAME 'value'`\",\n \"\u2022 `npx convex env set NAME # omit a value to set one interactively`\",\n \"\u2022 `npx convex env set NAME --from-file value.txt`\",\n \"\u2022 `npx convex env set --from-file .env.defaults`\",\n \"\",\n \"When setting multiple values, it will refuse all changes if any variables are already set to different values by default. Pass --force to overwrite the provided values.\",\n \"\",\n \"To keep secrets out of your shell history, omit the value to pipe it in via stdin, for instance:\",\n \"\u2022 `pbpaste | npx convex env set API_KEY` (macOS)\",\n \"\u2022 `Get-Clipboard | npx convex env set API_KEY` (Windows PowerShell)\",\n \"\",\n \"To update many variables at once, save them with `npx convex env list --include-values > .env.convex`, edit the file, then reapply the changes with `npx convex env set --force < .env.convex`.\",\n ].join(\"\\n\"),\n )\n .option(\n \"--from-file <file>\",\n \"Read environment variables from a .env file. Without --force, fails if any existing variable has a different value.\",\n )\n .option(\n \"--force\",\n \"When setting multiple variables, overwrite existing environment variable values instead of failing on mismatch.\",\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false)\n .action(async (name, value, cmdOptions, cmd) => {\n // Note: We use `as` here because optsWithGlobals() type inference doesn't\n // include global options from the parent command (added via addDeploymentSelectionOptions)\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions;\n const { ctx, deployment } = await selectEnvDeployment(options);\n await ensureHasConvexDependency(ctx, \"env set\");\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n const backend = deploymentEnvBackend(ctx, deployment);\n const didAnything = await envSet(ctx, backend, name, value, cmdOptions);\n if (didAnything === false) {\n cmd.outputHelp({ error: true });\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"error: No environment variables specified to be set.\",\n });\n }\n },\n });\n });\n\nexport async function selectEnvDeployment(\n options: DeploymentSelectionOptions,\n): Promise<{\n ctx: Context;\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice: string;\n deploymentFields: DetailedDeploymentCredentials[\"deploymentFields\"];\n };\n}> {\n const ctx = await oneoffContext(options);\n const deploymentSelection = await getDeploymentSelection(ctx, options);\n const {\n adminKey,\n url: deploymentUrl,\n deploymentFields,\n } = await loadSelectedDeploymentCredentials(ctx, deploymentSelection, {\n ensureLocalRunning: false,\n });\n\n const deploymentNotice =\n deploymentFields !== null\n ? ` (on ${chalkStderr.bold(deploymentFields.deploymentType)} deployment ${chalkStderr.bold(deploymentFields.deploymentName)})`\n : \"\";\n const result = {\n ctx,\n deployment: {\n deploymentUrl,\n adminKey,\n deploymentNotice,\n deploymentFields,\n },\n };\n return result;\n}\n\nconst envGetCmd = new Command(\"get\")\n .argument(\"<name>\", \"The name of the environment variable to print.\")\n .summary(\"Print a variable's value\")\n .description(\"Print a variable's value: `npx convex env get NAME`\")\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false)\n .action(async (envVarName, _options, cmd) => {\n const options = cmd.optsWithGlobals();\n const { ctx, deployment } = await selectEnvDeployment(options);\n await ensureHasConvexDependency(ctx, \"env get\");\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n const backend = deploymentEnvBackend(ctx, deployment);\n await envGet(ctx, backend, envVarName);\n },\n });\n });\n\nconst envRemoveCmd = new Command(\"remove\")\n .alias(\"rm\")\n .alias(\"unset\")\n .argument(\"<name>\", \"The name of the environment variable to unset.\")\n .summary(\"Unset a variable\")\n .description(\n \"Unset a variable: `npx convex env remove NAME`\\n\" +\n \"If the variable doesn't exist, the command doesn't do anything and succeeds.\",\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false)\n .action(async (name, _options, cmd) => {\n const options = cmd.optsWithGlobals();\n const { ctx, deployment } = await selectEnvDeployment(options);\n await ensureHasConvexDependency(ctx, \"env remove\");\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n const backend = deploymentEnvBackend(ctx, deployment);\n await envRemove(ctx, backend, name);\n },\n });\n });\n\nconst envListCmd = new Command(\"list\")\n .summary(\"List all environment variables and their values\")\n .description(\n [\n \"\u2022 List only variable names (no values): `npx convex env list --names-only`\",\n \"\u2022 List all variables and their values: `npx convex env list --include-values`\",\n \"\u2022 Save all variables to a file: `npx convex env list --include-values > .env.convex`\",\n \"\u2022 Append to a file: `npx convex env list --include-values >> .env.convex`\",\n ].join(\"\\n\"),\n )\n .option(\n \"--names-only\",\n \"List only the names of environment variables, without their values\",\n )\n .addOption(\n new Option(\n \"--include-values\",\n \"Print each variable's value alongside its name, in .env format
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { Command, Option } from \"@commander-js/extra-typings\";\nimport { chalkStderr } from \"chalk\";\nimport { Context, oneoffContext } from \"../bundler/context.js\";\nimport {\n DeploymentSelectionOptions,\n DetailedDeploymentCredentials,\n loadSelectedDeploymentCredentials,\n} from \"./lib/api.js\";\nimport { actionDescription } from \"./lib/command.js\";\nimport { ensureHasConvexDependency } from \"./lib/utils/utils.js\";\nimport {\n deploymentEnvBackend,\n envGet,\n envList,\n envRemove,\n envSet,\n} from \"./lib/env.js\";\nimport { getDeploymentSelection } from \"./lib/deploymentSelection.js\";\nimport { withRunningBackend } from \"./lib/localDeployment/run.js\";\nimport { envDefault } from \"./envDefault.js\";\n\nconst envSetCmd = new Command(\"set\")\n // Pretend value is required\n .usage(\"[options] <name> <value>\")\n .argument(\"[name]\", \"The name of the environment variable to set.\")\n .argument(\n \"[value]\",\n \"The value to set the variable to. Omit to set it interactively.\",\n )\n .summary(\"Set a variable\")\n .description(\n [\n \"Set environment variables on your deployment.\",\n \"\",\n \"\u2022 `npx convex env set NAME 'value'`\",\n \"\u2022 `npx convex env set NAME # omit a value to set one interactively`\",\n \"\u2022 `npx convex env set NAME --from-file value.txt`\",\n \"\u2022 `npx convex env set --from-file .env.defaults`\",\n \"\",\n \"When setting multiple values, it will refuse all changes if any variables are already set to different values by default. Pass --force to overwrite the provided values.\",\n \"\",\n \"To keep secrets out of your shell history, omit the value to pipe it in via stdin, for instance:\",\n \"\u2022 `pbpaste | npx convex env set API_KEY` (macOS)\",\n \"\u2022 `Get-Clipboard | npx convex env set API_KEY` (Windows PowerShell)\",\n \"\",\n \"To update many variables at once, save them with `npx convex env list --include-values > .env.convex`, edit the file, then reapply the changes with `npx convex env set --force < .env.convex`.\",\n ].join(\"\\n\"),\n )\n .option(\n \"--from-file <file>\",\n \"Read environment variables from a .env file. Without --force, fails if any existing variable has a different value.\",\n )\n .option(\n \"--force\",\n \"When setting multiple variables, overwrite existing environment variable values instead of failing on mismatch.\",\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false)\n .action(async (name, value, cmdOptions, cmd) => {\n // Note: We use `as` here because optsWithGlobals() type inference doesn't\n // include global options from the parent command (added via addDeploymentSelectionOptions)\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions;\n const { ctx, deployment } = await selectEnvDeployment(options);\n await ensureHasConvexDependency(ctx, \"env set\");\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n const backend = deploymentEnvBackend(ctx, deployment);\n const didAnything = await envSet(ctx, backend, name, value, cmdOptions);\n if (didAnything === false) {\n cmd.outputHelp({ error: true });\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"error: No environment variables specified to be set.\",\n });\n }\n },\n });\n });\n\nexport async function selectEnvDeployment(\n options: DeploymentSelectionOptions,\n): Promise<{\n ctx: Context;\n deployment: {\n deploymentUrl: string;\n adminKey: string;\n deploymentNotice: string;\n deploymentFields: DetailedDeploymentCredentials[\"deploymentFields\"];\n };\n}> {\n const ctx = await oneoffContext(options);\n const deploymentSelection = await getDeploymentSelection(ctx, options);\n const {\n adminKey,\n url: deploymentUrl,\n deploymentFields,\n } = await loadSelectedDeploymentCredentials(ctx, deploymentSelection, {\n ensureLocalRunning: false,\n });\n\n const deploymentNotice =\n deploymentFields !== null\n ? ` (on ${chalkStderr.bold(deploymentFields.deploymentType)} deployment ${chalkStderr.bold(deploymentFields.deploymentName)})`\n : \"\";\n const result = {\n ctx,\n deployment: {\n deploymentUrl,\n adminKey,\n deploymentNotice,\n deploymentFields,\n },\n };\n return result;\n}\n\nconst envGetCmd = new Command(\"get\")\n .argument(\"<name>\", \"The name of the environment variable to print.\")\n .summary(\"Print a variable's value\")\n .description(\"Print a variable's value: `npx convex env get NAME`\")\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false)\n .action(async (envVarName, _options, cmd) => {\n const options = cmd.optsWithGlobals();\n const { ctx, deployment } = await selectEnvDeployment(options);\n await ensureHasConvexDependency(ctx, \"env get\");\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n const backend = deploymentEnvBackend(ctx, deployment);\n await envGet(ctx, backend, envVarName);\n },\n });\n });\n\nconst envRemoveCmd = new Command(\"remove\")\n .alias(\"rm\")\n .alias(\"unset\")\n .argument(\"<name>\", \"The name of the environment variable to unset.\")\n .summary(\"Unset a variable\")\n .description(\n \"Unset a variable: `npx convex env remove NAME`\\n\" +\n \"If the variable doesn't exist, the command doesn't do anything and succeeds.\",\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false)\n .action(async (name, _options, cmd) => {\n const options = cmd.optsWithGlobals();\n const { ctx, deployment } = await selectEnvDeployment(options);\n await ensureHasConvexDependency(ctx, \"env remove\");\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n const backend = deploymentEnvBackend(ctx, deployment);\n await envRemove(ctx, backend, name);\n },\n });\n });\n\nconst envListCmd = new Command(\"list\")\n .summary(\"List all environment variables and their values\")\n .description(\n [\n \"\u2022 List only variable names (no values): `npx convex env list --names-only`\",\n \"\u2022 List all variables and their values: `npx convex env list --include-values`\",\n \"\u2022 Save all variables to a file: `npx convex env list --include-values > .env.convex`\",\n \"\u2022 Append to a file: `npx convex env list --include-values >> .env.convex`\",\n \"\",\n \"When an AI agent runs this command (detected from environment variables like AI_AGENT or CLAUDECODE), only names are listed unless --include-values is passed.\",\n ].join(\"\\n\"),\n )\n .option(\n \"--names-only\",\n \"List only the names of environment variables, without their values\",\n )\n .addOption(\n new Option(\n \"--include-values\",\n \"Print each variable's value alongside its name, in .env format. This is the default unless an AI agent is detected, so pass it explicitly in scripts that rely on the values.\",\n ).conflicts(\"namesOnly\"),\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false)\n .action(async (cmdOptions, cmd) => {\n // Note: We use `as` here because optsWithGlobals() type inference doesn't\n // include global options from the parent command (added via addDeploymentSelectionOptions)\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions;\n const { ctx, deployment } = await selectEnvDeployment(options);\n await ensureHasConvexDependency(ctx, \"env list\");\n await withRunningBackend({\n ctx,\n deployment,\n action: async () => {\n const backend = deploymentEnvBackend(ctx, deployment);\n await envList(ctx, backend, {\n namesOnly: cmdOptions.namesOnly ?? false,\n includeValues: cmdOptions.includeValues ?? false,\n });\n },\n });\n });\n\nexport const env = new Command(\"env\")\n .summary(\"Set and view environment variables\")\n .description(\n [\n \"Set and view environment variables on your deployment\",\n \"\",\n \"\u2022 Set a variable: `npx convex env set NAME 'value'`\",\n \"\u2022 Set interactively: `npx convex env set NAME`\",\n \"\u2022 Set multiple from file: `npx convex env set --from-file .env`\",\n \"\u2022 Unset a variable: `npx convex env remove NAME`\",\n \"\u2022 List only variable names (no values): `npx convex env list --names-only`\",\n \"\u2022 List all variables and their values: `npx convex env list --include-values`\",\n \"\u2022 Print a variable's value: `npx convex env get NAME`\",\n \"\",\n \"By default, this sets and views variables on your dev deployment.\",\n \"\",\n \"See the environment variables guide (https://docs.convex.dev/production/environment-variables) to learn more.\",\n ].join(\"\\n\"),\n )\n .addCommand(envSetCmd)\n .addCommand(envGetCmd)\n .addCommand(envRemoveCmd)\n .addCommand(envListCmd)\n .addCommand(envDefault)\n .helpCommand(false)\n .addDeploymentSelectionOptions(\n actionDescription(\"Set and view environment variables on\"),\n );\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -105,6 +105,8 @@ const envDefaultList = addEnvDefaultOptions(
|
|
|
105
105
|
"\u2022 List only default variable names (no values): `npx convex env default list --names-only`",
|
|
106
106
|
"\u2022 List all default variables and their values: `npx convex env default list --include-values`",
|
|
107
107
|
"",
|
|
108
|
+
"When an AI agent runs this command (detected from environment variables like AI_AGENT or CLAUDECODE), only names are listed unless --include-values is passed.",
|
|
109
|
+
"",
|
|
108
110
|
"The deployment type is determined by the current deployment (local maps to dev), or by --type if provided."
|
|
109
111
|
].join("\n")
|
|
110
112
|
).option(
|
|
@@ -113,7 +115,7 @@ const envDefaultList = addEnvDefaultOptions(
|
|
|
113
115
|
).addOption(
|
|
114
116
|
new Option(
|
|
115
117
|
"--include-values",
|
|
116
|
-
"Print each variable's value alongside its name, in .env format
|
|
118
|
+
"Print each variable's value alongside its name, in .env format. This is the default unless an AI agent is detected, so pass it explicitly in scripts that rely on the values."
|
|
117
119
|
).conflicts("namesOnly")
|
|
118
120
|
).configureHelp({ showGlobalOptions: true }).allowExcessArguments(false)
|
|
119
121
|
).action(async (cmdOptions, cmd) => {
|
|
@@ -121,7 +123,8 @@ const envDefaultList = addEnvDefaultOptions(
|
|
|
121
123
|
const { ctx, backend } = await resolveEnvDefaultBackend(options);
|
|
122
124
|
await ensureHasConvexDependency(ctx, "env default list");
|
|
123
125
|
await envList(ctx, backend, {
|
|
124
|
-
namesOnly: cmdOptions.namesOnly ?? false
|
|
126
|
+
namesOnly: cmdOptions.namesOnly ?? false,
|
|
127
|
+
includeValues: cmdOptions.includeValues ?? false
|
|
125
128
|
});
|
|
126
129
|
});
|
|
127
130
|
export const envDefault = new Command("default").summary("Manage project-level default environment variables").description(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/cli/envDefault.ts"],
|
|
4
|
-
"sourcesContent": ["import { Command, Option } from \"@commander-js/extra-typings\";\nimport {\n envGet,\n envList,\n envRemove,\n envSet,\n EnvVarBackend,\n} from \"./lib/env.js\";\nimport { ensureHasConvexDependency } from \"./lib/utils/utils.js\";\nimport { defaultEnvBackend } from \"./lib/defaultEnv.js\";\nimport {\n CloudDeploymentType,\n DeploymentSelectionOptions,\n DeploymentType,\n fetchTeamAndProject,\n} from \"./lib/api.js\";\nimport { Context, oneoffContext } from \"../bundler/context.js\";\nimport { selectEnvDeployment } from \"./env.js\";\nimport { getProjectDetails } from \"./lib/deploymentSelection.js\";\n\ntype EnvDefaultExtraOptions = {\n type?: string;\n project?: string;\n};\n\nfunction addEnvDefaultOptions<T extends Command<any, any>>(cmd: T): T {\n return cmd\n .addOption(\n new Option(\n \"--type <type>\",\n \"Manage default env vars for the given deployment type (dev, preview, prod) instead of inferring from the current deployment.\",\n ),\n )\n .addOption(\n new Option(\n \"--project <project>\",\n \"Select a project manually. Accepts `team-slug:project-slug` or just `project-slug` (team inferred from your current project). Requires --type.\",\n ),\n ) as T;\n}\n\nconst envDefaultSet = addEnvDefaultOptions(\n new Command(\"set\")\n .usage(\"[options] <name> <value>\")\n .argument(\"[name]\", \"The name of the default environment variable to set.\")\n .argument(\n \"[value]\",\n \"The value to set the variable to. Omit to set it interactively.\",\n )\n .summary(\"Set a default variable\")\n .description(\n [\n \"Set default environment variables for your project's deployment type.\",\n \"\",\n \"\u2022 `npx convex env default set NAME 'value'`\",\n \"\u2022 `npx convex env default set NAME # omit a value to set one interactively`\",\n \"\u2022 `npx convex env default set NAME --from-file value.txt`\",\n \"\u2022 `npx convex env default set --from-file .env.defaults`\",\n \"\",\n \"When setting multiple values, it will refuse all changes if any variables are already set to different values by default. Pass --force to overwrite the provided values.\",\n \"\",\n \"The deployment type is determined by the current deployment (local maps to dev), or by --type if provided.\",\n ].join(\"\\n\"),\n )\n .option(\n \"--from-file <file>\",\n \"Read environment variables from a .env file. Without --force, fails if any existing variable has a different value.\",\n )\n .option(\n \"--force\",\n \"When setting multiple variables, overwrite existing environment variable values instead of failing on mismatch.\",\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false),\n).action(async (name, value, cmdOptions, cmd) => {\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions &\n EnvDefaultExtraOptions;\n const { ctx, backend } = await resolveEnvDefaultBackend(options);\n await ensureHasConvexDependency(ctx, \"env default set\");\n const didAnything = await envSet(ctx, backend, name, value, cmdOptions);\n if (didAnything === false) {\n cmd.outputHelp({ error: true });\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"error: No environment variables specified to be set.\",\n });\n }\n});\n\nconst envDefaultGet = addEnvDefaultOptions(\n new Command(\"get\")\n .argument(\n \"<name>\",\n \"The name of the default environment variable to print.\",\n )\n .summary(\"Print a default variable's value\")\n .description(\n \"Print a default variable's value: `npx convex env default get NAME`\\n\" +\n \"The deployment type is determined by the current deployment (local maps to dev), or by --type if provided.\",\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false),\n).action(async (envVarName, _options, cmd) => {\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions &\n EnvDefaultExtraOptions;\n const { ctx, backend } = await resolveEnvDefaultBackend(options);\n await ensureHasConvexDependency(ctx, \"env default get\");\n await envGet(ctx, backend, envVarName);\n});\n\nconst envDefaultRemove = addEnvDefaultOptions(\n new Command(\"remove\")\n .alias(\"rm\")\n .alias(\"unset\")\n .argument(\n \"<name>\",\n \"The name of the default environment variable to unset.\",\n )\n .summary(\"Unset a default variable\")\n .description(\n [\n \"Unset a default variable.\",\n \"\",\n \"\u2022 `npx convex env default remove NAME`\",\n \"\",\n \"If the variable doesn't exist, the command doesn't do anything and succeeds.\",\n \"\",\n \"The deployment type is determined by the current deployment (local maps to dev), or by --type if provided.\",\n ].join(\"\\n\"),\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false),\n).action(async (name, _options, cmd) => {\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions &\n EnvDefaultExtraOptions;\n const { ctx, backend } = await resolveEnvDefaultBackend(options);\n await ensureHasConvexDependency(ctx, \"env default remove\");\n await envRemove(ctx, backend, name);\n});\n\nconst envDefaultList = addEnvDefaultOptions(\n new Command(\"list\")\n .summary(\"List all default environment variables and their values\")\n .description(\n [\n \"\u2022 List only default variable names (no values): `npx convex env default list --names-only`\",\n \"\u2022 List all default variables and their values: `npx convex env default list --include-values`\",\n \"\",\n \"The deployment type is determined by the current deployment (local maps to dev), or by --type if provided.\",\n ].join(\"\\n\"),\n )\n .option(\n \"--names-only\",\n \"List only the names of environment variables, without their values\",\n )\n .addOption(\n new Option(\n \"--include-values\",\n \"Print each variable's value alongside its name, in .env format (the default). Pass it explicitly in scripts that rely on the values.\",\n ).conflicts(\"namesOnly\"),\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false),\n).action(async (cmdOptions, cmd) => {\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions &\n EnvDefaultExtraOptions;\n const { ctx, backend } = await resolveEnvDefaultBackend(options);\n await ensureHasConvexDependency(ctx, \"env default list\");\n await envList(ctx, backend, {\n namesOnly: cmdOptions.namesOnly ?? false,\n });\n});\n\nexport const envDefault = new Command(\"default\")\n .summary(\"Manage project-level default environment variables\")\n .description(\n [\n \"Manage default environment variables for your project.\",\n \"\",\n \"The default environment variables read and written to by this command are the ones for the deployment type of the current deployment (i.e. dev in most cases), unless --type is provided.\",\n \"\",\n \"\u2022 Set a default variable: `npx convex env default set NAME 'value'`\",\n \"\u2022 Unset a default variable: `npx convex env default remove NAME`\",\n \"\u2022 List only default variable names (no values): `npx convex env default list --names-only`\",\n \"\u2022 List all default variables and their values: `npx convex env default list --include-values`\",\n \"\u2022 Print a default variable's value: `npx convex env default get NAME`\",\n ].join(\"\\n\"),\n )\n .addCommand(envDefaultSet)\n .addCommand(envDefaultGet)\n .addCommand(envDefaultRemove)\n .addCommand(envDefaultList)\n .helpCommand(false);\n\ntype ParsedProjectOption =\n | { kind: \"teamAndProject\"; teamSlug: string; projectSlug: string }\n | { kind: \"projectOnly\"; projectSlug: string };\n\nasync function resolveEnvDefaultBackend(\n options: DeploymentSelectionOptions & EnvDefaultExtraOptions,\n): Promise<{ ctx: Context; backend: EnvVarBackend }> {\n const dtypeOverride = normalizeTypeOption(options.type);\n\n if (options.project !== undefined) {\n const parsedProject = parseProjectOption(options.project);\n if (parsedProject === null) {\n const ctx = await oneoffContext(options);\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"error: --project must be `team-slug:project-slug` or `project-slug`.\",\n });\n }\n if (dtypeOverride === undefined) {\n const ctx = await oneoffContext(options);\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"error: --project requires --type to also be set.\",\n });\n }\n\n let ctx: Context;\n let resolved: { teamSlug: string; projectSlug: string };\n if (parsedProject.kind === \"teamAndProject\") {\n ctx = await oneoffContext(options);\n resolved = {\n teamSlug: parsedProject.teamSlug,\n projectSlug: parsedProject.projectSlug,\n };\n } else {\n const selected = await selectEnvDeployment(options);\n ctx = selected.ctx;\n if (selected.deployment.deploymentFields === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"error: --project <project-slug> requires a current cloud deployment to infer the team from. Use `team-slug:project-slug` to specify the team explicitly.\",\n });\n }\n const { team } = await fetchTeamAndProject(\n ctx,\n selected.deployment.deploymentFields.deploymentName,\n );\n resolved = { teamSlug: team, projectSlug: parsedProject.projectSlug };\n }\n\n const details = await getProjectDetails(ctx, {\n kind: \"teamAndProjectSlugs\",\n teamSlug: resolved.teamSlug,\n projectSlug: resolved.projectSlug,\n });\n return {\n ctx,\n backend: defaultEnvBackend(ctx, details.id, dtypeOverride),\n };\n }\n\n const { ctx, deployment } = await selectEnvDeployment(options);\n const backend = await resolveDefaultEnvBackend(\n ctx,\n deployment.deploymentFields,\n dtypeOverride,\n );\n return { ctx, backend };\n}\n\nfunction normalizeTypeOption(\n type: string | undefined,\n): CloudDeploymentType | undefined {\n if (type === undefined) return undefined;\n if (type === \"development\") return \"dev\";\n if (type === \"production\") return \"prod\";\n return type as CloudDeploymentType;\n}\n\nfunction parseProjectOption(value: string): ParsedProjectOption | null {\n const parts = value.split(\":\");\n if (parts.length === 1 && parts[0].length > 0) {\n return { kind: \"projectOnly\", projectSlug: parts[0] };\n }\n if (parts.length === 2 && parts[0].length > 0 && parts[1].length > 0) {\n return {\n kind: \"teamAndProject\",\n teamSlug: parts[0],\n projectSlug: parts[1],\n };\n }\n return null;\n}\n\nexport async function resolveDefaultEnvBackend(\n ctx: Context,\n deploymentFields: {\n deploymentName: string;\n deploymentType: DeploymentType;\n } | null,\n dtypeOverride?: CloudDeploymentType,\n): Promise<EnvVarBackend> {\n if (deploymentFields === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Default environment variables are only available for cloud projects.\",\n });\n }\n if (deploymentFields.deploymentType === \"anonymous\") {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Default environment variables are not available for anonymous deployments.\",\n });\n }\n const dtype =\n dtypeOverride ?? resolveDefaultEnvDtype(deploymentFields.deploymentType);\n const { projectId } = await fetchTeamAndProject(\n ctx,\n deploymentFields.deploymentName,\n );\n return defaultEnvBackend(ctx, projectId, dtype);\n}\n\nfunction resolveDefaultEnvDtype(\n deploymentType: Exclude<DeploymentType, \"anonymous\">,\n): CloudDeploymentType {\n if (deploymentType === \"local\") return \"dev\";\n return deploymentType;\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { Command, Option } from \"@commander-js/extra-typings\";\nimport {\n envGet,\n envList,\n envRemove,\n envSet,\n EnvVarBackend,\n} from \"./lib/env.js\";\nimport { ensureHasConvexDependency } from \"./lib/utils/utils.js\";\nimport { defaultEnvBackend } from \"./lib/defaultEnv.js\";\nimport {\n CloudDeploymentType,\n DeploymentSelectionOptions,\n DeploymentType,\n fetchTeamAndProject,\n} from \"./lib/api.js\";\nimport { Context, oneoffContext } from \"../bundler/context.js\";\nimport { selectEnvDeployment } from \"./env.js\";\nimport { getProjectDetails } from \"./lib/deploymentSelection.js\";\n\ntype EnvDefaultExtraOptions = {\n type?: string;\n project?: string;\n};\n\nfunction addEnvDefaultOptions<T extends Command<any, any>>(cmd: T): T {\n return cmd\n .addOption(\n new Option(\n \"--type <type>\",\n \"Manage default env vars for the given deployment type (dev, preview, prod) instead of inferring from the current deployment.\",\n ),\n )\n .addOption(\n new Option(\n \"--project <project>\",\n \"Select a project manually. Accepts `team-slug:project-slug` or just `project-slug` (team inferred from your current project). Requires --type.\",\n ),\n ) as T;\n}\n\nconst envDefaultSet = addEnvDefaultOptions(\n new Command(\"set\")\n .usage(\"[options] <name> <value>\")\n .argument(\"[name]\", \"The name of the default environment variable to set.\")\n .argument(\n \"[value]\",\n \"The value to set the variable to. Omit to set it interactively.\",\n )\n .summary(\"Set a default variable\")\n .description(\n [\n \"Set default environment variables for your project's deployment type.\",\n \"\",\n \"\u2022 `npx convex env default set NAME 'value'`\",\n \"\u2022 `npx convex env default set NAME # omit a value to set one interactively`\",\n \"\u2022 `npx convex env default set NAME --from-file value.txt`\",\n \"\u2022 `npx convex env default set --from-file .env.defaults`\",\n \"\",\n \"When setting multiple values, it will refuse all changes if any variables are already set to different values by default. Pass --force to overwrite the provided values.\",\n \"\",\n \"The deployment type is determined by the current deployment (local maps to dev), or by --type if provided.\",\n ].join(\"\\n\"),\n )\n .option(\n \"--from-file <file>\",\n \"Read environment variables from a .env file. Without --force, fails if any existing variable has a different value.\",\n )\n .option(\n \"--force\",\n \"When setting multiple variables, overwrite existing environment variable values instead of failing on mismatch.\",\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false),\n).action(async (name, value, cmdOptions, cmd) => {\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions &\n EnvDefaultExtraOptions;\n const { ctx, backend } = await resolveEnvDefaultBackend(options);\n await ensureHasConvexDependency(ctx, \"env default set\");\n const didAnything = await envSet(ctx, backend, name, value, cmdOptions);\n if (didAnything === false) {\n cmd.outputHelp({ error: true });\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"error: No environment variables specified to be set.\",\n });\n }\n});\n\nconst envDefaultGet = addEnvDefaultOptions(\n new Command(\"get\")\n .argument(\n \"<name>\",\n \"The name of the default environment variable to print.\",\n )\n .summary(\"Print a default variable's value\")\n .description(\n \"Print a default variable's value: `npx convex env default get NAME`\\n\" +\n \"The deployment type is determined by the current deployment (local maps to dev), or by --type if provided.\",\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false),\n).action(async (envVarName, _options, cmd) => {\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions &\n EnvDefaultExtraOptions;\n const { ctx, backend } = await resolveEnvDefaultBackend(options);\n await ensureHasConvexDependency(ctx, \"env default get\");\n await envGet(ctx, backend, envVarName);\n});\n\nconst envDefaultRemove = addEnvDefaultOptions(\n new Command(\"remove\")\n .alias(\"rm\")\n .alias(\"unset\")\n .argument(\n \"<name>\",\n \"The name of the default environment variable to unset.\",\n )\n .summary(\"Unset a default variable\")\n .description(\n [\n \"Unset a default variable.\",\n \"\",\n \"\u2022 `npx convex env default remove NAME`\",\n \"\",\n \"If the variable doesn't exist, the command doesn't do anything and succeeds.\",\n \"\",\n \"The deployment type is determined by the current deployment (local maps to dev), or by --type if provided.\",\n ].join(\"\\n\"),\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false),\n).action(async (name, _options, cmd) => {\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions &\n EnvDefaultExtraOptions;\n const { ctx, backend } = await resolveEnvDefaultBackend(options);\n await ensureHasConvexDependency(ctx, \"env default remove\");\n await envRemove(ctx, backend, name);\n});\n\nconst envDefaultList = addEnvDefaultOptions(\n new Command(\"list\")\n .summary(\"List all default environment variables and their values\")\n .description(\n [\n \"\u2022 List only default variable names (no values): `npx convex env default list --names-only`\",\n \"\u2022 List all default variables and their values: `npx convex env default list --include-values`\",\n \"\",\n \"When an AI agent runs this command (detected from environment variables like AI_AGENT or CLAUDECODE), only names are listed unless --include-values is passed.\",\n \"\",\n \"The deployment type is determined by the current deployment (local maps to dev), or by --type if provided.\",\n ].join(\"\\n\"),\n )\n .option(\n \"--names-only\",\n \"List only the names of environment variables, without their values\",\n )\n .addOption(\n new Option(\n \"--include-values\",\n \"Print each variable's value alongside its name, in .env format. This is the default unless an AI agent is detected, so pass it explicitly in scripts that rely on the values.\",\n ).conflicts(\"namesOnly\"),\n )\n .configureHelp({ showGlobalOptions: true })\n .allowExcessArguments(false),\n).action(async (cmdOptions, cmd) => {\n const options = cmd.optsWithGlobals() as DeploymentSelectionOptions &\n EnvDefaultExtraOptions;\n const { ctx, backend } = await resolveEnvDefaultBackend(options);\n await ensureHasConvexDependency(ctx, \"env default list\");\n await envList(ctx, backend, {\n namesOnly: cmdOptions.namesOnly ?? false,\n includeValues: cmdOptions.includeValues ?? false,\n });\n});\n\nexport const envDefault = new Command(\"default\")\n .summary(\"Manage project-level default environment variables\")\n .description(\n [\n \"Manage default environment variables for your project.\",\n \"\",\n \"The default environment variables read and written to by this command are the ones for the deployment type of the current deployment (i.e. dev in most cases), unless --type is provided.\",\n \"\",\n \"\u2022 Set a default variable: `npx convex env default set NAME 'value'`\",\n \"\u2022 Unset a default variable: `npx convex env default remove NAME`\",\n \"\u2022 List only default variable names (no values): `npx convex env default list --names-only`\",\n \"\u2022 List all default variables and their values: `npx convex env default list --include-values`\",\n \"\u2022 Print a default variable's value: `npx convex env default get NAME`\",\n ].join(\"\\n\"),\n )\n .addCommand(envDefaultSet)\n .addCommand(envDefaultGet)\n .addCommand(envDefaultRemove)\n .addCommand(envDefaultList)\n .helpCommand(false);\n\ntype ParsedProjectOption =\n | { kind: \"teamAndProject\"; teamSlug: string; projectSlug: string }\n | { kind: \"projectOnly\"; projectSlug: string };\n\nasync function resolveEnvDefaultBackend(\n options: DeploymentSelectionOptions & EnvDefaultExtraOptions,\n): Promise<{ ctx: Context; backend: EnvVarBackend }> {\n const dtypeOverride = normalizeTypeOption(options.type);\n\n if (options.project !== undefined) {\n const parsedProject = parseProjectOption(options.project);\n if (parsedProject === null) {\n const ctx = await oneoffContext(options);\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"error: --project must be `team-slug:project-slug` or `project-slug`.\",\n });\n }\n if (dtypeOverride === undefined) {\n const ctx = await oneoffContext(options);\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"error: --project requires --type to also be set.\",\n });\n }\n\n let ctx: Context;\n let resolved: { teamSlug: string; projectSlug: string };\n if (parsedProject.kind === \"teamAndProject\") {\n ctx = await oneoffContext(options);\n resolved = {\n teamSlug: parsedProject.teamSlug,\n projectSlug: parsedProject.projectSlug,\n };\n } else {\n const selected = await selectEnvDeployment(options);\n ctx = selected.ctx;\n if (selected.deployment.deploymentFields === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"error: --project <project-slug> requires a current cloud deployment to infer the team from. Use `team-slug:project-slug` to specify the team explicitly.\",\n });\n }\n const { team } = await fetchTeamAndProject(\n ctx,\n selected.deployment.deploymentFields.deploymentName,\n );\n resolved = { teamSlug: team, projectSlug: parsedProject.projectSlug };\n }\n\n const details = await getProjectDetails(ctx, {\n kind: \"teamAndProjectSlugs\",\n teamSlug: resolved.teamSlug,\n projectSlug: resolved.projectSlug,\n });\n return {\n ctx,\n backend: defaultEnvBackend(ctx, details.id, dtypeOverride),\n };\n }\n\n const { ctx, deployment } = await selectEnvDeployment(options);\n const backend = await resolveDefaultEnvBackend(\n ctx,\n deployment.deploymentFields,\n dtypeOverride,\n );\n return { ctx, backend };\n}\n\nfunction normalizeTypeOption(\n type: string | undefined,\n): CloudDeploymentType | undefined {\n if (type === undefined) return undefined;\n if (type === \"development\") return \"dev\";\n if (type === \"production\") return \"prod\";\n return type as CloudDeploymentType;\n}\n\nfunction parseProjectOption(value: string): ParsedProjectOption | null {\n const parts = value.split(\":\");\n if (parts.length === 1 && parts[0].length > 0) {\n return { kind: \"projectOnly\", projectSlug: parts[0] };\n }\n if (parts.length === 2 && parts[0].length > 0 && parts[1].length > 0) {\n return {\n kind: \"teamAndProject\",\n teamSlug: parts[0],\n projectSlug: parts[1],\n };\n }\n return null;\n}\n\nexport async function resolveDefaultEnvBackend(\n ctx: Context,\n deploymentFields: {\n deploymentName: string;\n deploymentType: DeploymentType;\n } | null,\n dtypeOverride?: CloudDeploymentType,\n): Promise<EnvVarBackend> {\n if (deploymentFields === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Default environment variables are only available for cloud projects.\",\n });\n }\n if (deploymentFields.deploymentType === \"anonymous\") {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Default environment variables are not available for anonymous deployments.\",\n });\n }\n const dtype =\n dtypeOverride ?? resolveDefaultEnvDtype(deploymentFields.deploymentType);\n const { projectId } = await fetchTeamAndProject(\n ctx,\n deploymentFields.deploymentName,\n );\n return defaultEnvBackend(ctx, projectId, dtype);\n}\n\nfunction resolveDefaultEnvDtype(\n deploymentType: Exclude<DeploymentType, \"anonymous\">,\n): CloudDeploymentType {\n if (deploymentType === \"local\") return \"dev\";\n return deploymentType;\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAS,SAAS,cAAc;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,iCAAiC;AAC1C,SAAS,yBAAyB;AAClC;AAAA,EAIE;AAAA,OACK;AACP,SAAkB,qBAAqB;AACvC,SAAS,2BAA2B;AACpC,SAAS,yBAAyB;AAOlC,SAAS,qBAAkD,KAAW;AACpE,SAAO,IACJ;AAAA,IACC,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF,EACC;AAAA,IACC,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACJ;AAEA,MAAM,gBAAgB;AAAA,EACpB,IAAI,QAAQ,KAAK,EACd,MAAM,0BAA0B,EAChC,SAAS,UAAU,sDAAsD,EACzE;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,QAAQ,wBAAwB,EAChC;AAAA,IACC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,cAAc,EAAE,mBAAmB,KAAK,CAAC,EACzC,qBAAqB,KAAK;AAC/B,EAAE,OAAO,OAAO,MAAM,OAAO,YAAY,QAAQ;AAC/C,QAAM,UAAU,IAAI,gBAAgB;AAEpC,QAAM,EAAE,KAAK,QAAQ,IAAI,MAAM,yBAAyB,OAAO;AAC/D,QAAM,0BAA0B,KAAK,iBAAiB;AACtD,QAAM,cAAc,MAAM,OAAO,KAAK,SAAS,MAAM,OAAO,UAAU;AACtE,MAAI,gBAAgB,OAAO;AACzB,QAAI,WAAW,EAAE,OAAO,KAAK,CAAC;AAC9B,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH;AACF,CAAC;AAED,MAAM,gBAAgB;AAAA,EACpB,IAAI,QAAQ,KAAK,EACd;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,QAAQ,kCAAkC,EAC1C;AAAA,IACC;AAAA,EAEF,EACC,cAAc,EAAE,mBAAmB,KAAK,CAAC,EACzC,qBAAqB,KAAK;AAC/B,EAAE,OAAO,OAAO,YAAY,UAAU,QAAQ;AAC5C,QAAM,UAAU,IAAI,gBAAgB;AAEpC,QAAM,EAAE,KAAK,QAAQ,IAAI,MAAM,yBAAyB,OAAO;AAC/D,QAAM,0BAA0B,KAAK,iBAAiB;AACtD,QAAM,OAAO,KAAK,SAAS,UAAU;AACvC,CAAC;AAED,MAAM,mBAAmB;AAAA,EACvB,IAAI,QAAQ,QAAQ,EACjB,MAAM,IAAI,EACV,MAAM,OAAO,EACb;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,QAAQ,0BAA0B,EAClC;AAAA,IACC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,EACC,cAAc,EAAE,mBAAmB,KAAK,CAAC,EACzC,qBAAqB,KAAK;AAC/B,EAAE,OAAO,OAAO,MAAM,UAAU,QAAQ;AACtC,QAAM,UAAU,IAAI,gBAAgB;AAEpC,QAAM,EAAE,KAAK,QAAQ,IAAI,MAAM,yBAAyB,OAAO;AAC/D,QAAM,0BAA0B,KAAK,oBAAoB;AACzD,QAAM,UAAU,KAAK,SAAS,IAAI;AACpC,CAAC;AAED,MAAM,iBAAiB;AAAA,EACrB,IAAI,QAAQ,MAAM,EACf,QAAQ,yDAAyD,EACjE;AAAA,IACC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF,EAAE,UAAU,WAAW;AAAA,EACzB,EACC,cAAc,EAAE,mBAAmB,KAAK,CAAC,EACzC,qBAAqB,KAAK;AAC/B,EAAE,OAAO,OAAO,YAAY,QAAQ;AAClC,QAAM,UAAU,IAAI,gBAAgB;AAEpC,QAAM,EAAE,KAAK,QAAQ,IAAI,MAAM,yBAAyB,OAAO;AAC/D,QAAM,0BAA0B,KAAK,kBAAkB;AACvD,QAAM,QAAQ,KAAK,SAAS;AAAA,IAC1B,WAAW,WAAW,aAAa;AAAA,IACnC,eAAe,WAAW,iBAAiB;AAAA,EAC7C,CAAC;AACH,CAAC;AAEM,aAAM,aAAa,IAAI,QAAQ,SAAS,EAC5C,QAAQ,oDAAoD,EAC5D;AAAA,EACC;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb,EACC,WAAW,aAAa,EACxB,WAAW,aAAa,EACxB,WAAW,gBAAgB,EAC3B,WAAW,cAAc,EACzB,YAAY,KAAK;AAMpB,eAAe,yBACb,SACmD;AACnD,QAAM,gBAAgB,oBAAoB,QAAQ,IAAI;AAEtD,MAAI,QAAQ,YAAY,QAAW;AACjC,UAAM,gBAAgB,mBAAmB,QAAQ,OAAO;AACxD,QAAI,kBAAkB,MAAM;AAC1B,YAAMA,OAAM,MAAM,cAAc,OAAO;AACvC,aAAO,MAAMA,KAAI,MAAM;AAAA,QACrB,UAAU;AAAA,QACV,WAAW;AAAA,QACX,gBACE;AAAA,MACJ,CAAC;AAAA,IACH;AACA,QAAI,kBAAkB,QAAW;AAC/B,YAAMA,OAAM,MAAM,cAAc,OAAO;AACvC,aAAO,MAAMA,KAAI,MAAM;AAAA,QACrB,UAAU;AAAA,QACV,WAAW;AAAA,QACX,gBAAgB;AAAA,MAClB,CAAC;AAAA,IACH;AAEA,QAAIA;AACJ,QAAI;AACJ,QAAI,cAAc,SAAS,kBAAkB;AAC3C,MAAAA,OAAM,MAAM,cAAc,OAAO;AACjC,iBAAW;AAAA,QACT,UAAU,cAAc;AAAA,QACxB,aAAa,cAAc;AAAA,MAC7B;AAAA,IACF,OAAO;AACL,YAAM,WAAW,MAAM,oBAAoB,OAAO;AAClD,MAAAA,OAAM,SAAS;AACf,UAAI,SAAS,WAAW,qBAAqB,MAAM;AACjD,eAAO,MAAMA,KAAI,MAAM;AAAA,UACrB,UAAU;AAAA,UACV,WAAW;AAAA,UACX,gBACE;AAAA,QACJ,CAAC;AAAA,MACH;AACA,YAAM,EAAE,KAAK,IAAI,MAAM;AAAA,QACrBA;AAAA,QACA,SAAS,WAAW,iBAAiB;AAAA,MACvC;AACA,iBAAW,EAAE,UAAU,MAAM,aAAa,cAAc,YAAY;AAAA,IACtE;AAEA,UAAM,UAAU,MAAM,kBAAkBA,MAAK;AAAA,MAC3C,MAAM;AAAA,MACN,UAAU,SAAS;AAAA,MACnB,aAAa,SAAS;AAAA,IACxB,CAAC;AACD,WAAO;AAAA,MACL,KAAAA;AAAA,MACA,SAAS,kBAAkBA,MAAK,QAAQ,IAAI,aAAa;AAAA,IAC3D;AAAA,EACF;AAEA,QAAM,EAAE,KAAK,WAAW,IAAI,MAAM,oBAAoB,OAAO;AAC7D,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA,WAAW;AAAA,IACX;AAAA,EACF;AACA,SAAO,EAAE,KAAK,QAAQ;AACxB;AAEA,SAAS,oBACP,MACiC;AACjC,MAAI,SAAS,OAAW,QAAO;AAC/B,MAAI,SAAS,cAAe,QAAO;AACnC,MAAI,SAAS,aAAc,QAAO;AAClC,SAAO;AACT;AAEA,SAAS,mBAAmB,OAA2C;AACrE,QAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,MAAI,MAAM,WAAW,KAAK,MAAM,CAAC,EAAE,SAAS,GAAG;AAC7C,WAAO,EAAE,MAAM,eAAe,aAAa,MAAM,CAAC,EAAE;AAAA,EACtD;AACA,MAAI,MAAM,WAAW,KAAK,MAAM,CAAC,EAAE,SAAS,KAAK,MAAM,CAAC,EAAE,SAAS,GAAG;AACpE,WAAO;AAAA,MACL,MAAM;AAAA,MACN,UAAU,MAAM,CAAC;AAAA,MACjB,aAAa,MAAM,CAAC;AAAA,IACtB;AAAA,EACF;AACA,SAAO;AACT;AAEA,sBAAsB,yBACpB,KACA,kBAIA,eACwB;AACxB,MAAI,qBAAqB,MAAM;AAC7B,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBACE;AAAA,IACJ,CAAC;AAAA,EACH;AACA,MAAI,iBAAiB,mBAAmB,aAAa;AACnD,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBACE;AAAA,IACJ,CAAC;AAAA,EACH;AACA,QAAM,QACJ,iBAAiB,uBAAuB,iBAAiB,cAAc;AACzE,QAAM,EAAE,UAAU,IAAI,MAAM;AAAA,IAC1B;AAAA,IACA,iBAAiB;AAAA,EACnB;AACA,SAAO,kBAAkB,KAAK,WAAW,KAAK;AAChD;AAEA,SAAS,uBACP,gBACqB;AACrB,MAAI,mBAAmB,QAAS,QAAO;AACvC,SAAO;AACT;",
|
|
6
6
|
"names": ["ctx"]
|
|
7
7
|
}
|
|
@@ -23,7 +23,7 @@ export async function installGuidelinesFile({
|
|
|
23
23
|
"Could not download Convex AI guidelines right now. You can retry with: npx convex ai-files install"
|
|
24
24
|
)
|
|
25
25
|
);
|
|
26
|
-
return;
|
|
26
|
+
return false;
|
|
27
27
|
}
|
|
28
28
|
await fs.mkdir(aiDirForConvexDir(convexDir), { recursive: true });
|
|
29
29
|
await fs.writeFile(guidelinesPathForConvexDir(convexDir), guidelines, "utf8");
|
|
@@ -31,5 +31,6 @@ export async function installGuidelinesFile({
|
|
|
31
31
|
logMessage(
|
|
32
32
|
`${chalkStderr.green("\u2714")} ${guidelinesPathForConvexDir(convexDir)} written`
|
|
33
33
|
);
|
|
34
|
+
return true;
|
|
34
35
|
}
|
|
35
36
|
//# sourceMappingURL=guidelinesmd.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/lib/aiFiles/guidelinesmd.ts"],
|
|
4
|
-
"sourcesContent": ["// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { downloadGuidelines } from \"../versionApi.js\";\nimport { hashSha256 } from \"../utils/hash.js\";\nimport { aiDirForConvexDir, guidelinesPathForConvexDir } from \"./paths.js\";\nimport { attemptReadFile, exhaustiveCheck } from \"./utils.js\";\nimport { type AiFilesState } from \"./state.js\";\n\nexport async function hasGuidelinesInstalled(\n convexDir: string,\n): Promise<boolean> {\n const result = await attemptReadFile(guidelinesPathForConvexDir(convexDir));\n if (result.kind === \"content\") return true;\n if (result.kind === \"empty\" || result.kind === \"not-found\") return false;\n return exhaustiveCheck(result);\n}\n\n/**\n * Download and write the guidelines file.\n * Guidelines live in `_generated/` so local edits are not expected and are\n * not preserved.\n */\nexport async function installGuidelinesFile({\n convexDir,\n state,\n}: {\n convexDir: string;\n state: AiFilesState;\n}): Promise<
|
|
5
|
-
"mappings": ";AACA,SAAS,YAAY,UAAU;AAC/B,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB,kCAAkC;AAC9D,SAAS,iBAAiB,uBAAuB;AAGjD,sBAAsB,uBACpB,WACkB;AAClB,QAAM,SAAS,MAAM,gBAAgB,2BAA2B,SAAS,CAAC;AAC1E,MAAI,OAAO,SAAS,UAAW,QAAO;AACtC,MAAI,OAAO,SAAS,WAAW,OAAO,SAAS,YAAa,QAAO;AACnE,SAAO,gBAAgB,MAAM;AAC/B;
|
|
4
|
+
"sourcesContent": ["// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { downloadGuidelines } from \"../versionApi.js\";\nimport { hashSha256 } from \"../utils/hash.js\";\nimport { aiDirForConvexDir, guidelinesPathForConvexDir } from \"./paths.js\";\nimport { attemptReadFile, exhaustiveCheck } from \"./utils.js\";\nimport { type AiFilesState } from \"./state.js\";\n\nexport async function hasGuidelinesInstalled(\n convexDir: string,\n): Promise<boolean> {\n const result = await attemptReadFile(guidelinesPathForConvexDir(convexDir));\n if (result.kind === \"content\") return true;\n if (result.kind === \"empty\" || result.kind === \"not-found\") return false;\n return exhaustiveCheck(result);\n}\n\n/**\n * Download and write the guidelines file.\n * Guidelines live in `_generated/` so local edits are not expected and are\n * not preserved.\n *\n * Returns false if the guidelines could not be downloaded.\n */\nexport async function installGuidelinesFile({\n convexDir,\n state,\n}: {\n convexDir: string;\n state: AiFilesState;\n}): Promise<boolean> {\n const guidelines = await downloadGuidelines();\n\n if (guidelines === null) {\n logMessage(\n chalkStderr.yellow(\n \"Could not download Convex AI guidelines right now. You can retry with: npx convex ai-files install\",\n ),\n );\n return false;\n }\n\n await fs.mkdir(aiDirForConvexDir(convexDir), { recursive: true });\n await fs.writeFile(guidelinesPathForConvexDir(convexDir), guidelines, \"utf8\");\n state.guidelinesHash = hashSha256(guidelines);\n\n logMessage(\n `${chalkStderr.green(\"\u2714\")} ${guidelinesPathForConvexDir(convexDir)} written`,\n );\n\n return true;\n}\n"],
|
|
5
|
+
"mappings": ";AACA,SAAS,YAAY,UAAU;AAC/B,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB,kCAAkC;AAC9D,SAAS,iBAAiB,uBAAuB;AAGjD,sBAAsB,uBACpB,WACkB;AAClB,QAAM,SAAS,MAAM,gBAAgB,2BAA2B,SAAS,CAAC;AAC1E,MAAI,OAAO,SAAS,UAAW,QAAO;AACtC,MAAI,OAAO,SAAS,WAAW,OAAO,SAAS,YAAa,QAAO;AACnE,SAAO,gBAAgB,MAAM;AAC/B;AASA,sBAAsB,sBAAsB;AAAA,EAC1C;AAAA,EACA;AACF,GAGqB;AACnB,QAAM,aAAa,MAAM,mBAAmB;AAE5C,MAAI,eAAe,MAAM;AACvB;AAAA,MACE,YAAY;AAAA,QACV;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,GAAG,MAAM,kBAAkB,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAChE,QAAM,GAAG,UAAU,2BAA2B,SAAS,GAAG,YAAY,MAAM;AAC5E,QAAM,iBAAiB,WAAW,UAAU;AAE5C;AAAA,IACE,GAAG,YAAY,MAAM,QAAG,CAAC,IAAI,2BAA2B,SAAS,CAAC;AAAA,EACpE;AAEA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -43,12 +43,23 @@ export async function installAiFiles({
|
|
|
43
43
|
}) {
|
|
44
44
|
const convexDirName = path.relative(projectDir, convexDir);
|
|
45
45
|
const state = await readAiStateOrDefault(convexDir);
|
|
46
|
-
await installGuidelinesFile({ convexDir, state });
|
|
46
|
+
const guidelinesInstalled = await installGuidelinesFile({ convexDir, state });
|
|
47
47
|
await applyAgentsMdSection({ projectDir, state, convexDirName });
|
|
48
48
|
await applyClaudeMdSection({ projectDir, state, convexDirName });
|
|
49
|
-
await installSkills({
|
|
49
|
+
const skillsInstalled = await installSkills({
|
|
50
|
+
projectDir,
|
|
51
|
+
state,
|
|
52
|
+
aiFilesConfig
|
|
53
|
+
});
|
|
50
54
|
await removeLegacyCursorRules(projectDir);
|
|
51
55
|
await writeAiState({ state, convexDir });
|
|
56
|
+
if (!guidelinesInstalled || !skillsInstalled) {
|
|
57
|
+
return {
|
|
58
|
+
kind: "error",
|
|
59
|
+
message: "Some Convex AI files could not be installed. See the messages above."
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return { kind: "success" };
|
|
52
63
|
}
|
|
53
64
|
async function attemptToInstallAiFiles(opts) {
|
|
54
65
|
try {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/lib/aiFiles/index.ts"],
|
|
4
|
-
"sourcesContent": ["import * as Sentry from \"@sentry/node\";\nimport path from \"path\";\nimport { Context } from \"../../../bundler/context.js\";\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { promptYesNo } from \"../utils/prompts.js\";\nimport { fetchAgentSkillsCatalog } from \"../versionApi.js\";\nimport { type AiFilesPaths, aiDirForConvexDir } from \"./paths.js\";\nimport {\n installGuidelinesFile,\n hasGuidelinesInstalled,\n} from \"./guidelinesmd.js\";\nimport {\n attemptReadAiState,\n readAiStateOrDefault,\n writeAiState,\n hasAiState,\n} from \"./state.js\";\nimport { type AiFilesProjectConfig } from \"../config.js\";\nimport { exhaustiveCheck, isInInteractiveTerminal } from \"./utils.js\";\nimport {\n hasAgentsMdInstalled,\n applyAgentsMdSection,\n attemptToRemoveAgentsMdSection,\n} from \"./agentsmd.js\";\nimport {\n hasClaudeMdInstalled,\n applyClaudeMdSection,\n attemptToRemoveClaudeMdSection,\n} from \"./claudemd.js\";\nimport { installSkills, removeInstalledSkills } from \"./skills.js\";\nimport { removeLegacyCursorRulesFile as removeLegacyCursorRules } from \"./cursorrules.js\";\n\nasync function hasExistingAiFilesArtifacts({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<boolean> {\n return (\n (await hasGuidelinesInstalled(convexDir)) ||\n (await hasAgentsMdInstalled(projectDir)) ||\n (await hasClaudeMdInstalled(projectDir))\n );\n}\n\n/**\n * Install or refresh all Convex AI files.\n *\n * Reads the existing state if present, or starts from a blank one for a\n * fresh install.\n */\nexport async function installAiFiles({\n projectDir,\n convexDir,\n aiFilesConfig,\n}: AiFilesPaths & {\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n}): Promise<
|
|
5
|
-
"mappings": ";AAAA,YAAY,YAAY;AACxB,OAAO,UAAU;AAGjB,SAAS,YAAY,UAAU;AAC/B,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,+BAA+B;AACxC,SAA4B,yBAAyB;AACrD;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,iBAAiB,+BAA+B;AACzD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,eAAe,6BAA6B;AACrD,SAAS,+BAA+B,+BAA+B;AAEvE,eAAe,4BAA4B;AAAA,EACzC;AAAA,EACA;AACF,GAAmC;AACjC,SACG,MAAM,uBAAuB,SAAS,KACtC,MAAM,qBAAqB,UAAU,KACrC,MAAM,qBAAqB,UAAU;AAE1C;
|
|
4
|
+
"sourcesContent": ["import * as Sentry from \"@sentry/node\";\nimport path from \"path\";\nimport { Context } from \"../../../bundler/context.js\";\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { promptYesNo } from \"../utils/prompts.js\";\nimport { fetchAgentSkillsCatalog } from \"../versionApi.js\";\nimport { type AiFilesPaths, aiDirForConvexDir } from \"./paths.js\";\nimport {\n installGuidelinesFile,\n hasGuidelinesInstalled,\n} from \"./guidelinesmd.js\";\nimport {\n attemptReadAiState,\n readAiStateOrDefault,\n writeAiState,\n hasAiState,\n} from \"./state.js\";\nimport { type AiFilesProjectConfig } from \"../config.js\";\nimport { exhaustiveCheck, isInInteractiveTerminal } from \"./utils.js\";\nimport {\n hasAgentsMdInstalled,\n applyAgentsMdSection,\n attemptToRemoveAgentsMdSection,\n} from \"./agentsmd.js\";\nimport {\n hasClaudeMdInstalled,\n applyClaudeMdSection,\n attemptToRemoveClaudeMdSection,\n} from \"./claudemd.js\";\nimport { installSkills, removeInstalledSkills } from \"./skills.js\";\nimport { removeLegacyCursorRulesFile as removeLegacyCursorRules } from \"./cursorrules.js\";\n\nasync function hasExistingAiFilesArtifacts({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<boolean> {\n return (\n (await hasGuidelinesInstalled(convexDir)) ||\n (await hasAgentsMdInstalled(projectDir)) ||\n (await hasClaudeMdInstalled(projectDir))\n );\n}\n\ntype InstallAiFilesResult =\n | { kind: \"success\" }\n | { kind: \"error\"; message: string };\n\n/**\n * Install or refresh all Convex AI files.\n *\n * Reads the existing state if present, or starts from a blank one for a\n * fresh install.\n *\n * Writes everything it can even when the guidelines download or the skills\n * install fails, and returns an error if either of them failed.\n */\nexport async function installAiFiles({\n projectDir,\n convexDir,\n aiFilesConfig,\n}: AiFilesPaths & {\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n}): Promise<InstallAiFilesResult> {\n const convexDirName = path.relative(projectDir, convexDir);\n const state = await readAiStateOrDefault(convexDir);\n\n const guidelinesInstalled = await installGuidelinesFile({ convexDir, state });\n await applyAgentsMdSection({ projectDir, state, convexDirName });\n await applyClaudeMdSection({ projectDir, state, convexDirName });\n const skillsInstalled = await installSkills({\n projectDir,\n state,\n aiFilesConfig,\n });\n await removeLegacyCursorRules(projectDir);\n await writeAiState({ state, convexDir });\n\n if (!guidelinesInstalled || !skillsInstalled) {\n return {\n kind: \"error\",\n message:\n \"Some Convex AI files could not be installed. See the messages above.\",\n };\n }\n return { kind: \"success\" };\n}\n\nasync function attemptToInstallAiFiles(\n opts: Parameters<typeof installAiFiles>[0],\n): Promise<void> {\n try {\n await installAiFiles(opts);\n } catch (error) {\n Sentry.captureException(error);\n }\n}\n\ntype AiFilesStalenessStatus = \"not-installed\" | \"stale\" | \"silent\";\n\nexport function isAiFilesDisabled(\n aiFilesConfig: AiFilesProjectConfig | undefined,\n): boolean {\n if (aiFilesConfig?.enabled !== undefined)\n return aiFilesConfig.enabled === false;\n return aiFilesConfig?.disableStalenessMessage === true;\n}\n\nasync function determineAiFilesStaleness({\n canonicalGuidelinesHash,\n canonicalAgentSkillsSha,\n aiFilesConfig,\n projectDir,\n convexDir,\n}: {\n canonicalGuidelinesHash: string | null;\n canonicalAgentSkillsSha: string | null;\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n} & AiFilesPaths): Promise<AiFilesStalenessStatus> {\n if (isAiFilesDisabled(aiFilesConfig)) return \"silent\";\n\n const result = await attemptReadAiState(convexDir);\n\n if (result.kind === \"no-file\" || result.kind === \"parse-error\") {\n const hasArtifacts = await hasExistingAiFilesArtifacts({\n projectDir,\n convexDir,\n });\n return hasArtifacts ? \"silent\" : \"not-installed\";\n }\n\n if (result.kind === \"ok\") {\n const { state } = result;\n\n if (canonicalGuidelinesHash === null && canonicalAgentSkillsSha === null)\n return \"silent\";\n\n const guidelinesStale =\n canonicalGuidelinesHash !== null &&\n state.guidelinesHash !== null &&\n state.guidelinesHash !== canonicalGuidelinesHash;\n\n const skillsStale =\n canonicalAgentSkillsSha !== null &&\n state.agentSkillsSha !== null &&\n state.agentSkillsSha !== canonicalAgentSkillsSha;\n\n return guidelinesStale || skillsStale ? \"stale\" : \"silent\";\n }\n\n return exhaustiveCheck(result);\n}\n\n/**\n * Check whether the Convex AI files are out of date and log a nag message\n * if so.\n */\nexport async function checkAiFilesStalenessAndLog(\n opts: {\n canonicalGuidelinesHash: string | null;\n canonicalAgentSkillsSha: string | null;\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n } & AiFilesPaths,\n): Promise<void> {\n const status = await determineAiFilesStaleness(opts);\n\n if (status === \"not-installed\") {\n logMessage(\n chalkStderr.yellow(\n `Convex AI files are not installed. Run ${chalkStderr.bold(`npx convex ai-files install`)} to get started or ${chalkStderr.bold(`npx convex ai-files disable`)} to hide this message.`,\n ),\n );\n return;\n }\n\n if (status === \"stale\") {\n logMessage(\n chalkStderr.yellow(\n `Your Convex AI files are out of date. Run ${chalkStderr.bold(`npx convex ai-files update`)} to get the latest.`,\n ),\n );\n return;\n }\n\n if (status === \"silent\") return;\n\n exhaustiveCheck(status);\n}\n\n/**\n * Installs AI files and returns the aiFiles config to write.\n */\nexport async function enableAiFiles({\n projectDir,\n convexDir,\n aiFilesConfig,\n}: AiFilesPaths & {\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n}): Promise<AiFilesProjectConfig> {\n await installAiFiles({ projectDir, convexDir, aiFilesConfig });\n // Deleting the deprecated disableStalenessMessage key\n const { disableStalenessMessage: _, ...rest } = aiFilesConfig ?? {};\n return { ...rest, enabled: true };\n}\n\n/**\n * Returns the aiFiles config to write when disabling AI files.\n */\nexport function disableAiFiles(\n aiFilesConfig?: AiFilesProjectConfig | undefined,\n): AiFilesProjectConfig {\n // Deleting the deprecated disableStalenessMessage key\n const { disableStalenessMessage: _, ...rest } = aiFilesConfig ?? {};\n return { ...rest, enabled: false };\n}\n\nexport type RemoveAiFilesResult =\n | { kind: \"success\" }\n | { kind: \"error\"; message: string };\n\n/**\n * Remove all Convex AI files from the project.\n * Called by `npx convex ai-files remove`.\n */\nexport async function removeAiFiles({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<RemoveAiFilesResult> {\n const agentSkillsCatalog = await fetchAgentSkillsCatalog();\n if (agentSkillsCatalog.kind === \"error\") {\n return {\n kind: \"error\",\n message:\n \"Could not fetch canonical agent skills from version.convex.dev. Aborting `convex ai-files remove`.\",\n };\n }\n\n const removals = [\n await attemptToRemoveAgentsMdSection(projectDir),\n await attemptToRemoveClaudeMdSection(projectDir),\n (await removeInstalledSkills({\n projectDir,\n skillNames: agentSkillsCatalog.data.skills.map(\n ({ skillName }) => skillName,\n ),\n })) === \"removed\",\n await removeLegacyCursorRules(projectDir),\n await attemptToDeleteAiDir({ projectDir, convexDir }),\n ];\n\n if (removals.some(Boolean)) logMessage(\"Convex AI files removed.\");\n else logMessage(\"No Convex AI files found \u2014 nothing to remove.\");\n return { kind: \"success\" };\n}\n\nasync function attemptToDeleteAiDir({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<boolean> {\n const aiDir = aiDirForConvexDir(convexDir);\n const relPath = path.relative(projectDir, aiDir);\n try {\n await fs.rm(aiDir, { recursive: true });\n logMessage(`${chalkStderr.green(\"\u2714\")} Deleted ${relPath}/`);\n return true;\n } catch (error) {\n if ((error as { code?: string }).code === \"ENOENT\") return false;\n Sentry.captureException(error);\n logMessage(\n chalkStderr.yellow(`Could not delete ${relPath}/. Remove it manually.`),\n );\n return false;\n }\n}\n\nasync function hasAiFilesBeenInstalledBefore({\n projectDir,\n convexDir,\n aiFilesConfig,\n}: AiFilesPaths & {\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n}): Promise<boolean> {\n if (isAiFilesDisabled(aiFilesConfig)) return false;\n return (\n (await hasAiState(convexDir)) ||\n (await hasExistingAiFilesArtifacts({ projectDir, convexDir }))\n );\n}\n\nexport async function attemptSetupAiFiles({\n ctx,\n convexDir,\n projectDir,\n aiFilesConfig,\n}: {\n ctx: Context;\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n} & AiFilesPaths): Promise<void> {\n if (!isInInteractiveTerminal()) return;\n if (isAiFilesDisabled(aiFilesConfig)) return;\n\n if (\n await hasAiFilesBeenInstalledBefore({\n projectDir,\n convexDir,\n aiFilesConfig,\n })\n ) {\n await attemptToInstallAiFiles({ projectDir, convexDir, aiFilesConfig });\n return;\n }\n\n const shouldInstall = await promptYesNo(ctx, {\n message: \"Set up Convex AI files? (guidelines, AGENTS.md, agent skills)\",\n default: true,\n });\n\n if (shouldInstall)\n await attemptToInstallAiFiles({ projectDir, convexDir, aiFilesConfig });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -11,7 +11,7 @@ function configuredSkillAgents(aiFilesConfig) {
|
|
|
11
11
|
return aiFilesConfig?.skills?.agents ?? defaultAgents;
|
|
12
12
|
}
|
|
13
13
|
function runSkillsAdd(cwd, agents) {
|
|
14
|
-
const args = ["add", "
|
|
14
|
+
const args = ["add", "convex/agent-skills", "--yes", "--copy"];
|
|
15
15
|
for (const agent of agents) {
|
|
16
16
|
args.push("--agent", agent);
|
|
17
17
|
}
|
|
@@ -67,21 +67,22 @@ export async function installSkills({
|
|
|
67
67
|
aiFilesConfig
|
|
68
68
|
}) {
|
|
69
69
|
const agents = configuredSkillAgents(aiFilesConfig);
|
|
70
|
-
if (agents.length === 0) return;
|
|
71
|
-
if (!await shouldRunSkillsCli()) return;
|
|
70
|
+
if (agents.length === 0) return true;
|
|
71
|
+
if (!await shouldRunSkillsCli()) return true;
|
|
72
72
|
logMessage("Installing Convex agent skills...");
|
|
73
73
|
const skillsOk = await runSkillsAdd(projectDir, agents);
|
|
74
74
|
if (!skillsOk) {
|
|
75
75
|
logMessage(
|
|
76
76
|
chalkStderr.yellow(
|
|
77
|
-
"Could not install agent skills. You can retry manually with: npx skills add
|
|
77
|
+
"Could not install agent skills. You can retry manually with: npx skills add convex/agent-skills --copy"
|
|
78
78
|
)
|
|
79
79
|
);
|
|
80
|
-
return;
|
|
80
|
+
return false;
|
|
81
81
|
}
|
|
82
82
|
const sha = await fetchAgentSkillsSha();
|
|
83
83
|
if (sha) state.agentSkillsSha = sha;
|
|
84
84
|
logMessage(`${chalkStderr.green("\u2714")} Skills installed`);
|
|
85
|
+
return true;
|
|
85
86
|
}
|
|
86
87
|
export async function removeInstalledSkills({
|
|
87
88
|
projectDir,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/lib/aiFiles/skills.ts"],
|
|
4
|
-
"sourcesContent": ["import child_process from \"child_process\";\nimport path from \"path\";\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { getVersion, fetchAgentSkillsSha } from \"../versionApi.js\";\nimport { type AiFilesState } from \"./state.js\";\nimport { exhaustiveCheck } from \"./utils.js\";\n\nimport { type AiFilesProjectConfig } from \"../config.js\";\n\n/**\n * Resolve the configured agent list, falling back to defaults.\n */\nfunction configuredSkillAgents(\n aiFilesConfig?: AiFilesProjectConfig | undefined,\n): string[] {\n // We default to the two most popular agents for now, \"codex\" installs to `.agents` which also\n // covers cursor and many other tools. See: https://github.com/vercel-labs/skills?tab=readme-ov-file#supported-agents\n const defaultAgents = [\"claude-code\", \"codex\"];\n return aiFilesConfig?.skills?.agents ?? defaultAgents;\n}\n\n/**\n * Runs `npx skills add
|
|
5
|
-
"mappings": ";AAAA,OAAO,mBAAmB;AAC1B,OAAO,UAAU;AAEjB,SAAS,YAAY,UAAU;AAC/B,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,YAAY,2BAA2B;AAEhD,SAAS,uBAAuB;AAOhC,SAAS,sBACP,eACU;AAGV,QAAM,gBAAgB,CAAC,eAAe,OAAO;AAC7C,SAAO,eAAe,QAAQ,UAAU;AAC1C;AAMA,SAAS,aAAa,KAAa,QAAoC;AACrE,QAAM,OAAO,CAAC,OAAO,
|
|
4
|
+
"sourcesContent": ["import child_process from \"child_process\";\nimport path from \"path\";\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { getVersion, fetchAgentSkillsSha } from \"../versionApi.js\";\nimport { type AiFilesState } from \"./state.js\";\nimport { exhaustiveCheck } from \"./utils.js\";\n\nimport { type AiFilesProjectConfig } from \"../config.js\";\n\n/**\n * Resolve the configured agent list, falling back to defaults.\n */\nfunction configuredSkillAgents(\n aiFilesConfig?: AiFilesProjectConfig | undefined,\n): string[] {\n // We default to the two most popular agents for now, \"codex\" installs to `.agents` which also\n // covers cursor and many other tools. See: https://github.com/vercel-labs/skills?tab=readme-ov-file#supported-agents\n const defaultAgents = [\"claude-code\", \"codex\"];\n return aiFilesConfig?.skills?.agents ?? defaultAgents;\n}\n\n/**\n * Runs `npx skills add convex/agent-skills --yes --copy` in the given directory.\n * Returns true on success, false if the process fails or cannot be started.\n */\nfunction runSkillsAdd(cwd: string, agents: string[]): Promise<boolean> {\n const args = [\"add\", \"convex/agent-skills\", \"--yes\", \"--copy\"];\n for (const agent of agents) {\n args.push(\"--agent\", agent);\n }\n return runSkillsCommand(cwd, args).then(({ ok }) => ok);\n}\n\n/**\n * Runs `npx skills remove <name...> --yes` to surgically remove only the\n * Convex-managed skills, leaving any skills from other sources intact.\n */\nfunction runSkillsRemove({\n cwd,\n skillNames,\n}: {\n cwd: string;\n skillNames: string[];\n}): Promise<boolean> {\n return runSkillsCommand(cwd, [\"remove\", ...skillNames, \"--yes\"]).then(\n ({ ok }) => ok,\n );\n}\n\n/**\n * This function exists so we have a way to disable skills installs without pushing a new\n * version of the convex CLI\n */\nasync function shouldRunSkillsCli(): Promise<boolean> {\n const versionData = await getVersion();\n\n if (versionData.kind === \"error\") return true;\n\n if (versionData.kind === \"ok\") {\n if (versionData.data.disableSkillsCli) {\n const message =\n versionData.data.disableSkillsCliMessage ??\n \"Agent skills are temporarily disabled.\";\n logMessage(chalkStderr.yellow(message));\n return false;\n }\n return true;\n }\n\n return exhaustiveCheck(versionData);\n}\n\n/**\n * Remove the skills-lock.json file if it only contains skills that we\n * are removing. The `npx skills remove` command leaves the lockfile behind\n * even when it's logically empty.\n */\nasync function removeSkillsLockIfEmpty({\n projectDir,\n removedSkillNames,\n}: {\n projectDir: string;\n removedSkillNames: string[];\n}): Promise<boolean> {\n const lockPath = path.join(projectDir, \"skills-lock.json\");\n try {\n const content = await fs.readFile(lockPath, \"utf8\");\n const lock = JSON.parse(content);\n\n if (\n !lock ||\n typeof lock !== \"object\" ||\n !lock.skills ||\n typeof lock.skills !== \"object\"\n ) {\n return false;\n }\n\n const remainingSkills = Object.keys(lock.skills).filter(\n (name) => !removedSkillNames.includes(name),\n );\n\n if (remainingSkills.length === 0) {\n await fs.unlink(lockPath);\n return true;\n }\n return false;\n } catch {\n return false;\n }\n}\n\n/**\n * Install Convex agent skills and record the SHA into the state.\n * Handles the kill-switch check and all logging internally.\n *\n * Returns false if the skills CLI failed. Skipping skills because no agents\n * are configured or the kill switch is on counts as success.\n */\nexport async function installSkills({\n projectDir,\n state,\n aiFilesConfig,\n}: {\n projectDir: string;\n state: AiFilesState;\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n}): Promise<boolean> {\n const agents = configuredSkillAgents(aiFilesConfig);\n if (agents.length === 0) return true;\n if (!(await shouldRunSkillsCli())) return true;\n\n logMessage(\"Installing Convex agent skills...\");\n const skillsOk = await runSkillsAdd(projectDir, agents);\n if (!skillsOk) {\n logMessage(\n chalkStderr.yellow(\n \"Could not install agent skills. You can retry manually with: npx skills add convex/agent-skills --copy\",\n ),\n );\n return false;\n }\n\n const sha = await fetchAgentSkillsSha();\n if (sha) state.agentSkillsSha = sha;\n\n logMessage(`${chalkStderr.green(\"\u2714\")} Skills installed`);\n return true;\n}\n\nexport type RemoveInstalledSkillsStatus = \"unchanged\" | \"removed\" | \"failed\";\n\n/**\n * Remove Convex-managed agent skills and clean up the lock file if empty.\n * Returns whether removal was skipped, succeeded, or failed.\n */\nexport async function removeInstalledSkills({\n projectDir,\n skillNames,\n}: {\n projectDir: string;\n skillNames: string[];\n}): Promise<RemoveInstalledSkillsStatus> {\n if (skillNames.length === 0) return \"unchanged\";\n if (!(await shouldRunSkillsCli())) return \"unchanged\";\n\n logMessage(`Removing Convex agent skills: ${skillNames.join(\", \")}`);\n const skillsOk = await runSkillsRemove({ cwd: projectDir, skillNames });\n if (!skillsOk) {\n logMessage(\n chalkStderr.yellow(\n \"Could not remove agent skills automatically. Remove them manually with: npx skills remove\",\n ),\n );\n return \"failed\";\n }\n\n const lockRemoved = await removeSkillsLockIfEmpty({\n projectDir,\n removedSkillNames: skillNames,\n });\n\n if (lockRemoved)\n logMessage(`${chalkStderr.green(\"\u2714\")} Deleted skills-lock.json.`);\n\n return \"removed\";\n}\n\nfunction runSkillsCommand(\n cwd: string,\n args: string[],\n): Promise<{ ok: boolean; output: string }> {\n return new Promise((resolve) => {\n const proc = child_process.spawn(\n \"npx\",\n [\"--yes\", \"skills@latest\", ...args],\n {\n cwd,\n stdio: \"pipe\",\n // .cmd files on Windows require shell execution.\n shell: process.platform === \"win32\",\n },\n );\n let capturedOutput = \"\";\n proc.stdout?.on(\"data\", (chunk) => {\n capturedOutput += chunk.toString();\n });\n proc.stderr?.on(\"data\", (chunk) => {\n capturedOutput += chunk.toString();\n });\n proc.on(\"close\", (code) => {\n if (code !== 0 && capturedOutput.trim().length > 0) {\n const lines = capturedOutput.trim().split(/\\r?\\n/);\n const tail = lines.slice(-10).join(\"\\n\");\n logMessage(chalkStderr.gray(`skills output (tail):\\n${tail}`));\n }\n resolve({ ok: code === 0, output: capturedOutput });\n });\n proc.on(\"error\", () => resolve({ ok: false, output: capturedOutput }));\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -8,7 +8,7 @@ export const aiFilesStateSchema = z.object({
|
|
|
8
8
|
guidelinesHash: z.string().nullable(),
|
|
9
9
|
agentsMdSectionHash: z.string().nullable(),
|
|
10
10
|
claudeMdHash: z.string().nullable(),
|
|
11
|
-
// Commit SHA from
|
|
11
|
+
// Commit SHA from convex/agent-skills that was current when skills were
|
|
12
12
|
// last installed. Used to detect when newer skills are available.
|
|
13
13
|
agentSkillsSha: z.string().nullable()
|
|
14
14
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/cli/lib/aiFiles/state.ts"],
|
|
4
|
-
"sourcesContent": ["import * as Sentry from \"@sentry/node\";\n// Use raw fs (not ctx.fs) so these operations run asynchronously and don't\n// interfere with the file-watcher used by `convex dev`.\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { z } from \"zod\";\nimport { aiDirForConvexDir, aiFilesStatePathForConvexDir } from \"./paths.js\";\nimport { attemptReadFile, exhaustiveCheck } from \"./utils.js\";\n\nexport const aiFilesStateSchema = z.object({\n guidelinesHash: z.string().nullable(),\n agentsMdSectionHash: z.string().nullable(),\n claudeMdHash: z.string().nullable(),\n // Commit SHA from
|
|
4
|
+
"sourcesContent": ["import * as Sentry from \"@sentry/node\";\n// Use raw fs (not ctx.fs) so these operations run asynchronously and don't\n// interfere with the file-watcher used by `convex dev`.\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { z } from \"zod\";\nimport { aiDirForConvexDir, aiFilesStatePathForConvexDir } from \"./paths.js\";\nimport { attemptReadFile, exhaustiveCheck } from \"./utils.js\";\n\nexport const aiFilesStateSchema = z.object({\n guidelinesHash: z.string().nullable(),\n agentsMdSectionHash: z.string().nullable(),\n claudeMdHash: z.string().nullable(),\n // Commit SHA from convex/agent-skills that was current when skills were\n // last installed. Used to detect when newer skills are available.\n agentSkillsSha: z.string().nullable(),\n});\n\nexport type AiFilesState = z.infer<typeof aiFilesStateSchema>;\n\nconst DEFAULT_AI_STATE: AiFilesState = {\n guidelinesHash: null,\n agentsMdSectionHash: null,\n claudeMdHash: null,\n agentSkillsSha: null,\n};\n\nexport type AttemptReadAiStateResult =\n | { kind: \"no-file\" }\n | { kind: \"ok\"; state: AiFilesState }\n | { kind: \"parse-error\"; error: unknown };\n\nexport async function attemptReadAiState(\n convexDir: string,\n): Promise<AttemptReadAiStateResult> {\n const result = await attemptReadFile(aiFilesStatePathForConvexDir(convexDir));\n if (result.kind === \"not-found\" || result.kind === \"empty\")\n return { kind: \"no-file\" };\n\n try {\n const state = aiFilesStateSchema.parse(JSON.parse(result.content));\n return { kind: \"ok\", state };\n } catch (error) {\n Sentry.captureException(error);\n return { kind: \"parse-error\", error };\n }\n}\n\nexport async function readAiStateOrDefault(\n convexDir: string,\n): Promise<AiFilesState> {\n const result = await attemptReadAiState(convexDir);\n if (result.kind === \"ok\") return result.state;\n if (result.kind === \"no-file\") return { ...DEFAULT_AI_STATE };\n if (result.kind === \"parse-error\") return { ...DEFAULT_AI_STATE };\n return exhaustiveCheck(result);\n}\n\nexport async function hasAiState(convexDir: string): Promise<boolean> {\n const result = await attemptReadAiState(convexDir);\n return result.kind === \"ok\";\n}\n\nexport async function writeAiState({\n state,\n convexDir,\n}: {\n state: AiFilesState;\n convexDir: string;\n}): Promise<void> {\n const validated = aiFilesStateSchema.parse(state);\n await fs.mkdir(aiDirForConvexDir(convexDir), { recursive: true });\n await fs.writeFile(\n aiFilesStatePathForConvexDir(convexDir),\n JSON.stringify(validated, null, 2) + \"\\n\",\n \"utf8\",\n );\n}\n"],
|
|
5
5
|
"mappings": ";AAAA,YAAY,YAAY;AAIxB,SAAS,YAAY,UAAU;AAC/B,SAAS,SAAS;AAClB,SAAS,mBAAmB,oCAAoC;AAChE,SAAS,iBAAiB,uBAAuB;AAE1C,aAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,gBAAgB,EAAE,OAAO,EAAE,SAAS;AAAA,EACpC,qBAAqB,EAAE,OAAO,EAAE,SAAS;AAAA,EACzC,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA;AAAA;AAAA,EAGlC,gBAAgB,EAAE,OAAO,EAAE,SAAS;AACtC,CAAC;AAID,MAAM,mBAAiC;AAAA,EACrC,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,cAAc;AAAA,EACd,gBAAgB;AAClB;AAOA,sBAAsB,mBACpB,WACmC;AACnC,QAAM,SAAS,MAAM,gBAAgB,6BAA6B,SAAS,CAAC;AAC5E,MAAI,OAAO,SAAS,eAAe,OAAO,SAAS;AACjD,WAAO,EAAE,MAAM,UAAU;AAE3B,MAAI;AACF,UAAM,QAAQ,mBAAmB,MAAM,KAAK,MAAM,OAAO,OAAO,CAAC;AACjE,WAAO,EAAE,MAAM,MAAM,MAAM;AAAA,EAC7B,SAAS,OAAO;AACd,WAAO,iBAAiB,KAAK;AAC7B,WAAO,EAAE,MAAM,eAAe,MAAM;AAAA,EACtC;AACF;AAEA,sBAAsB,qBACpB,WACuB;AACvB,QAAM,SAAS,MAAM,mBAAmB,SAAS;AACjD,MAAI,OAAO,SAAS,KAAM,QAAO,OAAO;AACxC,MAAI,OAAO,SAAS,UAAW,QAAO,EAAE,GAAG,iBAAiB;AAC5D,MAAI,OAAO,SAAS,cAAe,QAAO,EAAE,GAAG,iBAAiB;AAChE,SAAO,gBAAgB,MAAM;AAC/B;AAEA,sBAAsB,WAAW,WAAqC;AACpE,QAAM,SAAS,MAAM,mBAAmB,SAAS;AACjD,SAAO,OAAO,SAAS;AACzB;AAEA,sBAAsB,aAAa;AAAA,EACjC;AAAA,EACA;AACF,GAGkB;AAChB,QAAM,YAAY,mBAAmB,MAAM,KAAK;AAChD,QAAM,GAAG,MAAM,kBAAkB,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAChE,QAAM,GAAG;AAAA,IACP,6BAA6B,SAAS;AAAA,IACtC,KAAK,UAAU,WAAW,MAAM,CAAC,IAAI;AAAA,IACrC;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|