convex 1.34.0 → 1.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/browser.bundle.js +6 -9
- package/dist/browser.bundle.js.map +2 -2
- package/dist/cjs/browser/sync/authentication_manager.js +4 -1
- package/dist/cjs/browser/sync/authentication_manager.js.map +2 -2
- package/dist/cjs/browser/sync/web_socket_manager.js +1 -7
- package/dist/cjs/browser/sync/web_socket_manager.js.map +2 -2
- package/dist/cjs/cli/aiFiles.js +15 -14
- package/dist/cjs/cli/aiFiles.js.map +2 -2
- package/dist/cjs/cli/configure.js +15 -10
- package/dist/cjs/cli/configure.js.map +2 -2
- package/dist/cjs/cli/lib/aiFiles/agentsmd.js +69 -0
- package/dist/cjs/cli/lib/aiFiles/agentsmd.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/claudemd.js +69 -0
- package/dist/cjs/cli/lib/aiFiles/claudemd.js.map +7 -0
- package/dist/cjs/cli/lib/{ai → aiFiles}/config.js +73 -46
- package/dist/cjs/cli/lib/aiFiles/config.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/cursorrules.js +48 -0
- package/dist/cjs/cli/lib/aiFiles/cursorrules.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js +51 -0
- package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/index.js +231 -0
- package/dist/cjs/cli/lib/aiFiles/index.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/paths.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/skills.js +180 -0
- package/dist/cjs/cli/lib/aiFiles/skills.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/status.js +195 -0
- package/dist/cjs/cli/lib/aiFiles/status.js.map +7 -0
- package/dist/cjs/cli/lib/aiFiles/utils.js +111 -0
- package/dist/cjs/cli/lib/aiFiles/utils.js.map +7 -0
- package/dist/cjs/cli/lib/command.js +6 -1
- package/dist/cjs/cli/lib/command.js.map +2 -2
- package/dist/cjs/cli/lib/config.js +3 -4
- package/dist/cjs/cli/lib/config.js.map +2 -2
- package/dist/cjs/cli/lib/localDeployment/anonymous.js +2 -2
- package/dist/cjs/cli/lib/localDeployment/anonymous.js.map +2 -2
- package/dist/cjs/cli/lib/updates.js +8 -8
- package/dist/cjs/cli/lib/updates.js.map +2 -2
- package/dist/cjs/cli/lib/versionApi.js +7 -4
- package/dist/cjs/cli/lib/versionApi.js.map +2 -2
- package/dist/cjs/cli/lib/workos/workos.js +4 -6
- package/dist/cjs/cli/lib/workos/workos.js.map +2 -2
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs-types/browser/sync/authentication_manager.d.ts.map +1 -1
- package/dist/cjs-types/browser/sync/web_socket_manager.d.ts.map +1 -1
- package/dist/cjs-types/cli/aiFiles.d.ts.map +1 -1
- package/dist/cjs-types/cli/configure.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/aiFiles/agentsmd.d.ts +19 -0
- package/dist/cjs-types/cli/lib/aiFiles/agentsmd.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/agentsmd.test.d.ts +2 -0
- package/dist/cjs-types/cli/lib/aiFiles/agentsmd.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/claudemd.d.ts +19 -0
- package/dist/cjs-types/cli/lib/aiFiles/claudemd.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/claudemd.test.d.ts +2 -0
- package/dist/cjs-types/cli/lib/aiFiles/claudemd.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/config.d.ts +46 -0
- package/dist/cjs-types/cli/lib/aiFiles/config.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/config.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/cursorrules.d.ts +10 -0
- package/dist/cjs-types/cli/lib/aiFiles/cursorrules.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts +12 -0
- package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.test.d.ts +2 -0
- package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/index.d.ts +40 -0
- package/dist/cjs-types/cli/lib/aiFiles/index.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/index.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/integration.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/{ai → aiFiles}/paths.d.ts +4 -0
- package/dist/cjs-types/cli/lib/aiFiles/paths.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/prompt.test.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts +18 -0
- package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/status.d.ts +3 -0
- package/dist/cjs-types/cli/lib/aiFiles/status.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/aiFiles/utils.d.ts +46 -0
- package/dist/cjs-types/cli/lib/aiFiles/utils.d.ts.map +1 -0
- package/dist/cjs-types/cli/lib/config.d.ts +1 -0
- package/dist/cjs-types/cli/lib/config.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/versionApi.d.ts +7 -1
- package/dist/cjs-types/cli/lib/versionApi.d.ts.map +1 -1
- package/dist/cjs-types/cli/lib/workos/workos.d.ts.map +1 -1
- package/dist/cjs-types/index.d.ts +1 -1
- package/dist/cli.bundle.cjs +1605 -1548
- package/dist/cli.bundle.cjs.map +4 -4
- package/dist/esm/browser/sync/authentication_manager.js +4 -1
- package/dist/esm/browser/sync/authentication_manager.js.map +2 -2
- package/dist/esm/browser/sync/web_socket_manager.js +1 -7
- package/dist/esm/browser/sync/web_socket_manager.js.map +2 -2
- package/dist/esm/cli/aiFiles.js +17 -17
- package/dist/esm/cli/aiFiles.js.map +2 -2
- package/dist/esm/cli/configure.js +15 -10
- package/dist/esm/cli/configure.js.map +2 -2
- package/dist/esm/cli/lib/aiFiles/agentsmd.js +52 -0
- package/dist/esm/cli/lib/aiFiles/agentsmd.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/claudemd.js +52 -0
- package/dist/esm/cli/lib/aiFiles/claudemd.js.map +7 -0
- package/dist/esm/cli/lib/{ai → aiFiles}/config.js +71 -45
- package/dist/esm/cli/lib/aiFiles/config.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/cursorrules.js +16 -0
- package/dist/esm/cli/lib/aiFiles/cursorrules.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/guidelinesmd.js +28 -0
- package/dist/esm/cli/lib/aiFiles/guidelinesmd.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/index.js +210 -0
- package/dist/esm/cli/lib/aiFiles/index.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/paths.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/skills.js +147 -0
- package/dist/esm/cli/lib/aiFiles/skills.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/status.js +175 -0
- package/dist/esm/cli/lib/aiFiles/status.js.map +7 -0
- package/dist/esm/cli/lib/aiFiles/utils.js +82 -0
- package/dist/esm/cli/lib/aiFiles/utils.js.map +7 -0
- package/dist/esm/cli/lib/command.js +6 -1
- package/dist/esm/cli/lib/command.js.map +2 -2
- package/dist/esm/cli/lib/config.js +3 -4
- package/dist/esm/cli/lib/config.js.map +2 -2
- package/dist/esm/cli/lib/localDeployment/anonymous.js +2 -2
- package/dist/esm/cli/lib/localDeployment/anonymous.js.map +2 -2
- package/dist/esm/cli/lib/updates.js +8 -8
- package/dist/esm/cli/lib/updates.js.map +2 -2
- package/dist/esm/cli/lib/versionApi.js +7 -4
- package/dist/esm/cli/lib/versionApi.js.map +2 -2
- package/dist/esm/cli/lib/workos/workos.js +4 -6
- package/dist/esm/cli/lib/workos/workos.js.map +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm-types/browser/sync/authentication_manager.d.ts.map +1 -1
- package/dist/esm-types/browser/sync/web_socket_manager.d.ts.map +1 -1
- package/dist/esm-types/cli/aiFiles.d.ts.map +1 -1
- package/dist/esm-types/cli/configure.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/aiFiles/agentsmd.d.ts +19 -0
- package/dist/esm-types/cli/lib/aiFiles/agentsmd.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/agentsmd.test.d.ts +2 -0
- package/dist/esm-types/cli/lib/aiFiles/agentsmd.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/claudemd.d.ts +19 -0
- package/dist/esm-types/cli/lib/aiFiles/claudemd.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/claudemd.test.d.ts +2 -0
- package/dist/esm-types/cli/lib/aiFiles/claudemd.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/config.d.ts +46 -0
- package/dist/esm-types/cli/lib/aiFiles/config.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/config.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/cursorrules.d.ts +10 -0
- package/dist/esm-types/cli/lib/aiFiles/cursorrules.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts +12 -0
- package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.test.d.ts +2 -0
- package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/index.d.ts +40 -0
- package/dist/esm-types/cli/lib/aiFiles/index.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/index.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/integration.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/{ai → aiFiles}/paths.d.ts +4 -0
- package/dist/esm-types/cli/lib/aiFiles/paths.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/prompt.test.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/skills.d.ts +18 -0
- package/dist/esm-types/cli/lib/aiFiles/skills.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/status.d.ts +3 -0
- package/dist/esm-types/cli/lib/aiFiles/status.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/aiFiles/utils.d.ts +46 -0
- package/dist/esm-types/cli/lib/aiFiles/utils.d.ts.map +1 -0
- package/dist/esm-types/cli/lib/config.d.ts +1 -0
- package/dist/esm-types/cli/lib/config.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/versionApi.d.ts +7 -1
- package/dist/esm-types/cli/lib/versionApi.d.ts.map +1 -1
- package/dist/esm-types/cli/lib/workos/workos.d.ts.map +1 -1
- package/dist/esm-types/index.d.ts +1 -1
- package/dist/react.bundle.js +6 -9
- package/dist/react.bundle.js.map +2 -2
- package/package.json +1 -1
- package/schemas/convex.schema.json +7 -1
- package/src/browser/sync/authentication_manager.ts +9 -4
- package/src/browser/sync/client_node.test.ts +125 -0
- package/src/browser/sync/web_socket_manager.ts +1 -7
- package/src/cli/aiFiles.ts +20 -27
- package/src/cli/configure.ts +17 -11
- package/src/cli/deploymentSelection.test.ts +56 -2
- package/src/cli/lib/{ai → aiFiles}/MANUAL_TESTING.md +6 -2
- package/src/cli/lib/aiFiles/agentsmd.test.ts +133 -0
- package/src/cli/lib/aiFiles/agentsmd.ts +77 -0
- package/src/cli/lib/aiFiles/claudemd.test.ts +92 -0
- package/src/cli/lib/aiFiles/claudemd.ts +77 -0
- package/src/cli/lib/{ai → aiFiles}/config.test.ts +181 -59
- package/src/cli/lib/{ai → aiFiles}/config.ts +92 -63
- package/src/cli/lib/aiFiles/cursorrules.ts +25 -0
- package/src/cli/lib/aiFiles/guidelinesmd.test.ts +40 -0
- package/src/cli/lib/aiFiles/guidelinesmd.ts +41 -0
- package/src/cli/lib/{ai → aiFiles}/index.test.ts +200 -339
- package/src/cli/lib/aiFiles/index.ts +303 -0
- package/src/cli/lib/{ai → aiFiles}/integration.test.ts +117 -147
- package/src/cli/lib/{ai → aiFiles}/paths.ts +5 -0
- package/src/cli/lib/{ai → aiFiles}/prompt.test.ts +78 -30
- package/src/cli/lib/aiFiles/skills.ts +213 -0
- package/src/cli/lib/aiFiles/status.ts +240 -0
- package/src/cli/lib/aiFiles/utils.ts +163 -0
- package/src/cli/lib/command.ts +6 -1
- package/src/cli/lib/config.test.ts +1 -1
- package/src/cli/lib/config.ts +6 -5
- package/src/cli/lib/localDeployment/anonymous.ts +2 -2
- package/src/cli/lib/updates.test.ts +40 -30
- package/src/cli/lib/updates.ts +8 -8
- package/src/cli/lib/versionApi.test.ts +13 -10
- package/src/cli/lib/versionApi.ts +13 -5
- package/src/cli/lib/workos/workos.ts +4 -5
- package/src/index.ts +1 -1
- package/src/values/.claude/settings.local.json +10 -0
- package/dist/cjs/cli/lib/ai/config.js.map +0 -7
- package/dist/cjs/cli/lib/ai/index.js +0 -704
- package/dist/cjs/cli/lib/ai/index.js.map +0 -7
- package/dist/cjs/cli/lib/ai/paths.js.map +0 -7
- package/dist/cjs-types/cli/lib/ai/config.d.ts +0 -50
- package/dist/cjs-types/cli/lib/ai/config.d.ts.map +0 -1
- package/dist/cjs-types/cli/lib/ai/config.test.d.ts.map +0 -1
- package/dist/cjs-types/cli/lib/ai/index.d.ts +0 -56
- package/dist/cjs-types/cli/lib/ai/index.d.ts.map +0 -1
- package/dist/cjs-types/cli/lib/ai/index.test.d.ts.map +0 -1
- package/dist/cjs-types/cli/lib/ai/integration.test.d.ts.map +0 -1
- package/dist/cjs-types/cli/lib/ai/paths.d.ts.map +0 -1
- package/dist/cjs-types/cli/lib/ai/prompt.test.d.ts.map +0 -1
- package/dist/esm/cli/lib/ai/config.js.map +0 -7
- package/dist/esm/cli/lib/ai/index.js +0 -684
- package/dist/esm/cli/lib/ai/index.js.map +0 -7
- package/dist/esm/cli/lib/ai/paths.js.map +0 -7
- package/dist/esm-types/cli/lib/ai/config.d.ts +0 -50
- package/dist/esm-types/cli/lib/ai/config.d.ts.map +0 -1
- package/dist/esm-types/cli/lib/ai/config.test.d.ts.map +0 -1
- package/dist/esm-types/cli/lib/ai/index.d.ts +0 -56
- package/dist/esm-types/cli/lib/ai/index.d.ts.map +0 -1
- package/dist/esm-types/cli/lib/ai/index.test.d.ts.map +0 -1
- package/dist/esm-types/cli/lib/ai/integration.test.d.ts.map +0 -1
- package/dist/esm-types/cli/lib/ai/paths.d.ts.map +0 -1
- package/dist/esm-types/cli/lib/ai/prompt.test.d.ts.map +0 -1
- package/src/cli/lib/ai/index.ts +0 -1006
- /package/dist/cjs/cli/lib/{ai → aiFiles}/paths.js +0 -0
- /package/dist/cjs-types/cli/lib/{ai → aiFiles}/config.test.d.ts +0 -0
- /package/dist/cjs-types/cli/lib/{ai → aiFiles}/index.test.d.ts +0 -0
- /package/dist/cjs-types/cli/lib/{ai → aiFiles}/integration.test.d.ts +0 -0
- /package/dist/cjs-types/cli/lib/{ai → aiFiles}/prompt.test.d.ts +0 -0
- /package/dist/esm/cli/lib/{ai → aiFiles}/paths.js +0 -0
- /package/dist/esm-types/cli/lib/{ai → aiFiles}/config.test.d.ts +0 -0
- /package/dist/esm-types/cli/lib/{ai → aiFiles}/index.test.d.ts +0 -0
- /package/dist/esm-types/cli/lib/{ai → aiFiles}/integration.test.d.ts +0 -0
- /package/dist/esm-types/cli/lib/{ai → aiFiles}/prompt.test.d.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/cli/configure.ts"],
|
|
4
|
-
"sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { Context } from \"../bundler/context.js\";\nimport {\n logFailure,\n logFinishedStep,\n logMessage,\n logWarning,\n showSpinner,\n} from \"../bundler/log.js\";\nimport {\n DeploymentType,\n DeploymentName,\n fetchDeploymentCredentialsProvisioningDevOrProdMaybeThrows,\n createProject,\n loadSelectedDeploymentCredentials,\n checkAccessToSelectedProject,\n DeploymentSelectionWithinProject,\n} from \"./lib/api.js\";\nimport { readProjectConfig, writeProjectConfig } from \"./lib/config.js\";\nimport {\n DeploymentDetails,\n eraseDeploymentEnvVar,\n writeDeploymentEnvVar,\n} from \"./lib/deployment.js\";\nimport { finalizeConfiguration } from \"./lib/init.js\";\nimport {\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n functionsDir,\n hasProjects,\n logAndHandleFetchError,\n selectDevDeploymentType,\n selectRegionOrUseDefault,\n validateOrSelectProject,\n validateOrSelectTeam,\n} from \"./lib/utils/utils.js\";\nimport { writeUrlsToEnvFile } from \"./lib/envvars.js\";\nimport path from \"path\";\nimport { projectDashboardUrl } from \"./lib/dashboard.js\";\nimport { doInitConvexFolder } from \"./lib/codegen.js\";\nimport { handleLocalDeployment } from \"./lib/localDeployment/localDeployment.js\";\nimport {\n promptOptions,\n promptString,\n promptYesNo,\n} from \"./lib/utils/prompts.js\";\nimport { readGlobalConfig } from \"./lib/utils/globalConfig.js\";\nimport { maybeSetupAiFiles } from \"./lib/ai/index.js\";\nimport {\n DeploymentSelection,\n deploymentNameFromSelection,\n shouldAllowAnonymousDevelopment,\n} from \"./lib/deploymentSelection.js\";\nimport { ensureLoggedIn } from \"./lib/login.js\";\nimport { handleAnonymousDeployment } from \"./lib/localDeployment/anonymous.js\";\nimport { fetchDeploymentCanonicalSiteUrl } from \"./lib/env.js\";\ntype DeploymentCredentials = {\n url: string;\n adminKey: string;\n};\n\ntype ChosenConfiguration =\n // `--configure new`\n | \"new\"\n // `--configure existing`\n | \"existing\"\n // `--configure`\n | \"ask\"\n // `--configure` was not specified\n | null;\n\ntype ConfigureCmdOptions = {\n prod: boolean;\n localOptions: {\n ports?: {\n cloud: number;\n site: number;\n };\n backendVersion?: string | undefined;\n dashboardVersion?: string | undefined;\n forceUpgrade: boolean;\n };\n team?: string | undefined;\n project?: string | undefined;\n devDeployment?: \"cloud\" | \"local\" | undefined;\n local?: boolean | undefined;\n cloud?: boolean | undefined;\n url?: string | undefined;\n adminKey?: string | undefined;\n envFile?: string | undefined;\n overrideAuthUrl?: string | undefined;\n overrideAuthClient?: string | undefined;\n overrideAuthUsername?: string | undefined;\n overrideAuthPassword?: string | undefined;\n};\n\n/**\n * As of writing, this is used by:\n * - `npx convex dev`\n * - `npx convex codegen`\n *\n * But is not used by `npx convex deploy` or other commands.\n */\nexport async function deploymentCredentialsOrConfigure(\n ctx: Context,\n deploymentSelection: DeploymentSelection,\n chosenConfiguration: ChosenConfiguration,\n cmdOptions: ConfigureCmdOptions,\n): Promise<\n DeploymentCredentials & {\n deploymentFields: {\n deploymentName: DeploymentName;\n deploymentType: DeploymentType;\n projectSlug: string | null;\n teamSlug: string | null;\n siteUrl: string | null;\n } | null;\n }\n> {\n const selectedDeployment = await _deploymentCredentialsOrConfigure(\n ctx,\n deploymentSelection,\n chosenConfiguration,\n cmdOptions,\n );\n const siteUrl = await fetchDeploymentCanonicalSiteUrl(ctx, {\n adminKey: selectedDeployment.adminKey,\n deploymentUrl: selectedDeployment.url,\n });\n\n if (selectedDeployment.deploymentFields !== null) {\n // Set the `CONVEX_DEPLOYMENT` env var + the `CONVEX_URL` env var\n await updateEnvAndConfigForDeploymentSelection(\n ctx,\n {\n url: selectedDeployment.url,\n siteUrl,\n deploymentName: selectedDeployment.deploymentFields.deploymentName,\n teamSlug: selectedDeployment.deploymentFields.teamSlug,\n projectSlug: selectedDeployment.deploymentFields.projectSlug,\n deploymentType: selectedDeployment.deploymentFields.deploymentType,\n },\n deploymentNameFromSelection(deploymentSelection),\n );\n } else {\n // Clear the `CONVEX_DEPLOYMENT` env var + set the `CONVEX_URL` and\n // `CONVEX_SITE_URL` env vars.\n await handleManuallySetUrlAndAdminKey(ctx, {\n url: selectedDeployment.url,\n siteUrl,\n adminKey: selectedDeployment.adminKey,\n });\n }\n return {\n url: selectedDeployment.url,\n adminKey: selectedDeployment.adminKey,\n deploymentFields:\n selectedDeployment.deploymentFields === null\n ? null\n : { ...selectedDeployment.deploymentFields, siteUrl: siteUrl },\n };\n}\n\nexport async function _deploymentCredentialsOrConfigure(\n ctx: Context,\n deploymentSelection: DeploymentSelection,\n chosenConfiguration: ChosenConfiguration,\n cmdOptions: ConfigureCmdOptions,\n): Promise<\n DeploymentCredentials & {\n deploymentFields: {\n deploymentName: DeploymentName;\n deploymentType: DeploymentType;\n projectSlug: string | null;\n teamSlug: string | null;\n } | null;\n }\n> {\n const config = readGlobalConfig(ctx);\n const globallyForceCloud = !!config?.optOutOfLocalDevDeploymentsUntilBetaOver;\n if (globallyForceCloud && cmdOptions.local) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Can't specify --local when local deployments are disabled on this machine. Run `npx convex disable-local-deployments --undo-global` to allow use of --local.\",\n });\n }\n\n switch (deploymentSelection.kind) {\n case \"existingDeployment\":\n return {\n url: deploymentSelection.deploymentToActOn.url,\n adminKey: deploymentSelection.deploymentToActOn.adminKey,\n deploymentFields:\n deploymentSelection.deploymentToActOn.deploymentFields,\n };\n case \"chooseProject\": {\n await ensureLoggedIn(ctx, {\n overrideAuthUrl: cmdOptions.overrideAuthUrl,\n overrideAuthClient: cmdOptions.overrideAuthClient,\n overrideAuthUsername: cmdOptions.overrideAuthUsername,\n overrideAuthPassword: cmdOptions.overrideAuthPassword,\n });\n return await handleChooseProject(\n ctx,\n chosenConfiguration,\n deploymentSelection.selectionWithinProject,\n {\n globallyForceCloud,\n },\n cmdOptions,\n );\n }\n case \"preview\":\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Use `npx convex deploy` to use preview deployments.\",\n });\n case \"deploymentWithinProject\": {\n return await handleDeploymentWithinProject(ctx, {\n chosenConfiguration,\n deploymentSelection,\n cmdOptions,\n globallyForceCloud,\n });\n }\n case \"anonymous\": {\n const hasAuth = ctx.bigBrainAuth() !== null;\n const isAgentMode = process.env.CONVEX_AGENT_MODE === \"anonymous\";\n if (\n !isAgentMode &&\n hasAuth &&\n deploymentSelection.deploymentName !== null\n ) {\n const shouldConfigure =\n chosenConfiguration !== null ||\n (await promptYesNo(ctx, {\n message: `${CONVEX_DEPLOYMENT_ENV_VAR_NAME} is configured with deployment ${deploymentSelection.deploymentName}, which is not linked with your account. Would you like to link it now?`,\n }));\n if (!shouldConfigure) {\n return await ctx.crash({\n exitCode: 0,\n errorType: \"fatal\",\n printedMessage: `Run \\`npx convex login --link-deployments\\` first to link this deployment to your account, and then run \\`npx convex dev\\` again.`,\n });\n }\n return await handleChooseProject(\n ctx,\n chosenConfiguration,\n deploymentSelection.selectionWithinProject,\n {\n globallyForceCloud,\n },\n cmdOptions,\n );\n }\n const alreadyHasConfiguredAnonymousDeployment =\n deploymentSelection.deploymentName !== null &&\n chosenConfiguration === null;\n if (isAgentMode) {\n logWarning(\n chalkStderr.yellow.bold(\n \"CONVEX_AGENT_MODE=anonymous mode is in beta, functionality may change in the future.\",\n ),\n );\n }\n\n const shouldPromptForLogin = isAgentMode\n ? \"no\"\n : alreadyHasConfiguredAnonymousDeployment\n ? \"no\"\n : await promptOptions(ctx, {\n message:\n \"Welcome to Convex! Would you like to login to your account?\",\n choices: [\n {\n name: \"Start without an account (run Convex locally)\",\n value: \"no\",\n },\n { name: \"Login or create an account\", value: \"yes\" },\n ],\n default: \"no\",\n });\n if (shouldPromptForLogin === \"no\") {\n const result = await handleAnonymousDeployment(ctx, {\n chosenConfiguration,\n deploymentName: deploymentSelection.deploymentName,\n ...cmdOptions.localOptions,\n });\n return {\n adminKey: result.adminKey,\n url: result.deploymentUrl,\n deploymentFields: {\n deploymentName: result.deploymentName,\n deploymentType: \"anonymous\",\n projectSlug: null,\n teamSlug: null,\n },\n };\n }\n return await handleChooseProject(\n ctx,\n chosenConfiguration,\n deploymentSelection.selectionWithinProject,\n {\n globallyForceCloud,\n },\n cmdOptions,\n );\n }\n }\n}\n\nasync function handleDeploymentWithinProject(\n ctx: Context,\n {\n chosenConfiguration,\n deploymentSelection,\n cmdOptions,\n globallyForceCloud,\n }: {\n chosenConfiguration: ChosenConfiguration;\n deploymentSelection: DeploymentSelection & {\n kind: \"deploymentWithinProject\";\n };\n cmdOptions: ConfigureCmdOptions;\n globallyForceCloud: boolean;\n },\n) {\n const hasAuth = ctx.bigBrainAuth() !== null;\n const loginMessage =\n hasAuth && shouldAllowAnonymousDevelopment()\n ? undefined\n : \"Tip: You can try out Convex without creating an account by clearing the \" +\n `${CONVEX_DEPLOYMENT_ENV_VAR_NAME} environment variable (often in .env.local).`;\n await ensureLoggedIn(ctx, {\n message: loginMessage,\n overrideAuthUrl: cmdOptions.overrideAuthUrl,\n overrideAuthClient: cmdOptions.overrideAuthClient,\n overrideAuthUsername: cmdOptions.overrideAuthUsername,\n overrideAuthPassword: cmdOptions.overrideAuthPassword,\n });\n if (chosenConfiguration !== null) {\n const result = await handleChooseProject(\n ctx,\n chosenConfiguration,\n deploymentSelection.selectionWithinProject,\n {\n globallyForceCloud,\n },\n cmdOptions,\n );\n return result;\n }\n\n const accessResult = await checkAccessToSelectedProject(\n ctx,\n deploymentSelection.targetProject,\n );\n if (accessResult.kind === \"noAccess\") {\n logMessage(\"You don't have access to the selected project.\");\n const result = await handleChooseProject(\n ctx,\n chosenConfiguration,\n deploymentSelection.selectionWithinProject,\n {\n globallyForceCloud,\n },\n cmdOptions,\n );\n return result;\n }\n\n const selectedDeployment = await loadSelectedDeploymentCredentials(\n ctx,\n deploymentSelection,\n // We'll start running it below\n { ensureLocalRunning: false },\n );\n if (\n selectedDeployment.deploymentFields !== null &&\n selectedDeployment.deploymentFields.deploymentType === \"local\"\n ) {\n // Start running the local backend\n await handleLocalDeployment(ctx, {\n teamSlug: selectedDeployment.deploymentFields.teamSlug!,\n projectSlug: selectedDeployment.deploymentFields.projectSlug!,\n forceUpgrade: cmdOptions.localOptions.forceUpgrade,\n ports: cmdOptions.localOptions.ports,\n backendVersion: cmdOptions.localOptions.backendVersion,\n });\n }\n return {\n url: selectedDeployment.url,\n adminKey: selectedDeployment.adminKey,\n deploymentFields: selectedDeployment.deploymentFields,\n };\n}\n\nasync function handleChooseProject(\n ctx: Context,\n chosenConfiguration: ChosenConfiguration,\n selectionWithinProject: DeploymentSelectionWithinProject,\n args: {\n globallyForceCloud: boolean;\n },\n cmdOptions: ConfigureCmdOptions,\n): Promise<\n DeploymentCredentials & {\n deploymentFields: {\n deploymentName: DeploymentName;\n deploymentType: DeploymentType;\n projectSlug: string;\n teamSlug: string;\n };\n }\n> {\n await ensureLoggedIn(ctx, {\n overrideAuthUrl: cmdOptions.overrideAuthUrl,\n overrideAuthClient: cmdOptions.overrideAuthClient,\n overrideAuthUsername: cmdOptions.overrideAuthUsername,\n overrideAuthPassword: cmdOptions.overrideAuthPassword,\n });\n const project = await selectProject(ctx, chosenConfiguration, {\n team: cmdOptions.team,\n project: cmdOptions.project,\n devDeployment: cmdOptions.devDeployment,\n local: args.globallyForceCloud ? false : cmdOptions.local,\n cloud: args.globallyForceCloud ? true : cmdOptions.cloud,\n });\n // TODO complain about any non-default cmdOptions.localOptions here\n // because we're ignoring them if this isn't a local development.\n\n const deploymentOptions: DeploymentOptions =\n selectionWithinProject.kind === \"prod\"\n ? { kind: \"prod\" }\n : project.devDeployment === \"local\"\n ? { kind: \"local\", ...cmdOptions.localOptions }\n : { kind: \"dev\" };\n const {\n deploymentName,\n deploymentUrl: url,\n adminKey,\n } = await ensureDeploymentProvisioned(ctx, {\n teamSlug: project.teamSlug,\n projectSlug: project.projectSlug,\n deploymentOptions,\n });\n return {\n url,\n adminKey,\n deploymentFields: {\n deploymentName,\n deploymentType: deploymentOptions.kind,\n projectSlug: project.projectSlug,\n teamSlug: project.teamSlug,\n },\n };\n}\n\nasync function handleManuallySetUrlAndAdminKey(\n ctx: Context,\n cmdOptions: { url: string; siteUrl: string; adminKey: string },\n) {\n const { url, siteUrl, adminKey } = cmdOptions;\n const didErase = await eraseDeploymentEnvVar(ctx);\n if (didErase) {\n logMessage(\n chalkStderr.yellowBright(\n `Removed the CONVEX_DEPLOYMENT environment variable from .env.local`,\n ),\n );\n }\n const envFileConfig = await writeUrlsToEnvFile(ctx, {\n convexUrl: url,\n siteUrl,\n });\n if (\n envFileConfig !== null &&\n (envFileConfig.convexUrlEnvVar || envFileConfig.siteUrlEnvVar)\n ) {\n // Join both names with \" and \" if both exist, otherwise just use one of them.\n const updatedVars = [\n envFileConfig.convexUrlEnvVar,\n envFileConfig.siteUrlEnvVar,\n ]\n .filter(Boolean)\n .join(\" and \");\n logMessage(\n chalkStderr.green(`Saved ${updatedVars} to ${envFileConfig.envFile}`),\n );\n }\n return { url, adminKey };\n}\n\nexport async function selectProject(\n ctx: Context,\n chosenConfiguration: ChosenConfiguration,\n cmdOptions: {\n team?: string | undefined;\n project?: string | undefined;\n devDeployment?: \"cloud\" | \"local\" | undefined;\n local?: boolean | undefined;\n cloud?: boolean | undefined;\n defaultProjectName?: string | undefined;\n },\n): Promise<{\n teamSlug: string;\n projectSlug: string;\n devDeployment: \"cloud\" | \"local\";\n}> {\n // Prompt the user to select a project.\n const choice =\n chosenConfiguration !== \"ask\" && chosenConfiguration !== null\n ? chosenConfiguration\n : await askToConfigure(ctx);\n switch (choice) {\n case \"new\":\n return selectNewProject(ctx, chosenConfiguration, cmdOptions);\n case \"existing\":\n return selectExistingProject(ctx, chosenConfiguration, cmdOptions);\n default:\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"No project selected.\",\n });\n }\n}\n\nconst cwd = path.basename(process.cwd());\nasync function selectNewProject(\n ctx: Context,\n chosenConfiguration: ChosenConfiguration,\n config: {\n team?: string | undefined;\n project?: string | undefined;\n devDeployment?: \"cloud\" | \"local\" | undefined;\n cloud?: boolean | undefined;\n local?: boolean | undefined;\n defaultProjectName?: string | undefined;\n },\n) {\n const { team: selectedTeam, chosen: didChooseBetweenTeams } =\n await validateOrSelectTeam(ctx, config.team, \"Team:\");\n let projectName: string = config.project || cwd;\n let choseProjectInteractively = false;\n if (!config.project) {\n projectName = await promptString(ctx, {\n message: \"Project name:\",\n default: config.defaultProjectName || cwd,\n });\n choseProjectInteractively = true;\n }\n\n const { devDeployment } = await selectDevDeploymentType(ctx, {\n chosenConfiguration,\n newOrExisting: \"new\",\n teamSlug: selectedTeam.slug,\n userHasChosenSomethingInteractively:\n didChooseBetweenTeams || choseProjectInteractively,\n projectSlug: undefined,\n devDeploymentFromFlag: config.devDeployment,\n forceDevDeployment: config.local\n ? \"local\"\n : config.cloud\n ? \"cloud\"\n : undefined,\n });\n\n const region =\n devDeployment === \"cloud\"\n ? await selectRegionOrUseDefault(ctx, selectedTeam, \"dev\")\n : null;\n\n showSpinner(\"Creating new Convex project...\");\n\n const deploymentToProvision =\n devDeployment === \"cloud\"\n ? {\n deploymentType: \"dev\" as const,\n region,\n }\n : null;\n\n let projectSlug, teamSlug, projectsRemaining;\n try {\n ({ projectSlug, teamSlug, projectsRemaining } = await createProject(ctx, {\n teamSlug: selectedTeam.slug,\n projectName,\n deploymentToProvision,\n }));\n } catch (err) {\n logFailure(\"Unable to create project.\");\n return await logAndHandleFetchError(ctx, err);\n }\n const teamMessage = didChooseBetweenTeams\n ? \" in team \" + chalkStderr.bold(teamSlug)\n : \"\";\n logFinishedStep(\n `Created project ${chalkStderr.bold(\n projectSlug,\n )}${teamMessage}, manage it at ${chalkStderr.bold(\n projectDashboardUrl(teamSlug, projectSlug),\n )}`,\n );\n\n if (projectsRemaining <= 2) {\n logWarning(\n chalkStderr.yellow.bold(\n `Your account now has ${projectsRemaining} project${\n projectsRemaining === 1 ? \"\" : \"s\"\n } remaining.`,\n ),\n );\n }\n\n await doInitConvexFolder(ctx);\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n const folder = functionsDir(configPath, projectConfig);\n await maybeSetupAiFiles(\n ctx,\n path.resolve(folder),\n path.resolve(path.dirname(configPath)),\n );\n return { teamSlug, projectSlug, devDeployment };\n}\n\nasync function selectExistingProject(\n ctx: Context,\n chosenConfiguration: ChosenConfiguration,\n config: {\n team?: string | undefined;\n project?: string | undefined;\n devDeployment?: \"cloud\" | \"local\" | undefined;\n local?: boolean | undefined;\n cloud?: boolean | undefined;\n },\n): Promise<{\n teamSlug: string;\n projectSlug: string;\n devDeployment: \"cloud\" | \"local\";\n}> {\n const {\n team: { slug: teamSlug },\n chosen,\n } = await validateOrSelectTeam(ctx, config.team, \"Team:\");\n\n const projectSlug = await validateOrSelectProject(\n ctx,\n config.project,\n teamSlug,\n \"Configure project\",\n \"Project:\",\n );\n if (projectSlug === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Run the command again to create a new project instead.\",\n });\n }\n const { devDeployment } = await selectDevDeploymentType(ctx, {\n chosenConfiguration,\n newOrExisting: \"existing\",\n teamSlug,\n projectSlug,\n userHasChosenSomethingInteractively: chosen || !config.project,\n devDeploymentFromFlag: config.devDeployment,\n forceDevDeployment: config.local\n ? \"local\"\n : config.cloud\n ? \"cloud\"\n : undefined,\n });\n\n logFinishedStep(`Reinitialized project ${chalkStderr.bold(projectSlug)}`);\n\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n const folder = functionsDir(configPath, projectConfig);\n await maybeSetupAiFiles(\n ctx,\n path.resolve(folder),\n path.resolve(path.dirname(configPath)),\n );\n\n return { teamSlug, projectSlug, devDeployment };\n}\n\nasync function askToConfigure(ctx: Context): Promise<\"new\" | \"existing\"> {\n if (!(await hasProjects(ctx))) {\n return \"new\";\n }\n return await promptOptions(ctx, {\n message: \"What would you like to configure?\",\n default: \"new\",\n choices: [\n { name: \"create a new project\", value: \"new\" },\n { name: \"choose an existing project\", value: \"existing\" },\n ],\n });\n}\n\ntype DeploymentOptions =\n | {\n kind: \"prod\";\n }\n | { kind: \"dev\" }\n | {\n kind: \"local\";\n ports?:\n | {\n cloud: number;\n site: number;\n }\n | undefined;\n backendVersion?: string | undefined;\n forceUpgrade: boolean;\n };\n\n/**\n * This method assumes that the member has access to the selected project.\n */\nasync function ensureDeploymentProvisioned(\n ctx: Context,\n options: {\n teamSlug: string;\n projectSlug: string;\n deploymentOptions: DeploymentOptions;\n },\n): Promise<DeploymentDetails> {\n switch (options.deploymentOptions.kind) {\n case \"dev\":\n case \"prod\": {\n const credentials =\n await fetchDeploymentCredentialsProvisioningDevOrProdMaybeThrows(\n ctx,\n {\n kind: \"teamAndProjectSlugs\",\n teamSlug: options.teamSlug,\n projectSlug: options.projectSlug,\n },\n options.deploymentOptions.kind,\n );\n return {\n ...credentials,\n onActivity: null,\n };\n }\n case \"local\": {\n const credentials = await handleLocalDeployment(ctx, {\n teamSlug: options.teamSlug,\n projectSlug: options.projectSlug,\n ...options.deploymentOptions,\n });\n return credentials;\n }\n default:\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Invalid deployment type: ${(options.deploymentOptions as any).kind}`,\n errForSentry: `Invalid deployment type: ${(options.deploymentOptions as any).kind}`,\n });\n }\n}\n\nexport async function updateEnvAndConfigForDeploymentSelection(\n ctx: Context,\n options: {\n url: string;\n siteUrl?: string | null;\n deploymentName: string;\n teamSlug: string | null;\n projectSlug: string | null;\n deploymentType: DeploymentType;\n },\n existingValue: string | null,\n) {\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n\n const { wroteToGitIgnore, changedDeploymentEnvVar } =\n await writeDeploymentEnvVar(\n ctx,\n options.deploymentType,\n {\n team: options.teamSlug,\n project: options.projectSlug,\n deploymentName: options.deploymentName,\n },\n existingValue,\n );\n await writeProjectConfig(ctx, projectConfig);\n await finalizeConfiguration(ctx, {\n deploymentType: options.deploymentType,\n deploymentName: options.deploymentName,\n url: options.url,\n siteUrl: options.siteUrl,\n wroteToGitIgnore,\n changedDeploymentEnvVar,\n functionsPath: functionsDir(configPath, projectConfig),\n });\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { chalkStderr } from \"chalk\";\nimport { Context } from \"../bundler/context.js\";\nimport {\n logFailure,\n logFinishedStep,\n logMessage,\n logWarning,\n showSpinner,\n} from \"../bundler/log.js\";\nimport {\n DeploymentType,\n DeploymentName,\n fetchDeploymentCredentialsProvisioningDevOrProdMaybeThrows,\n createProject,\n loadSelectedDeploymentCredentials,\n checkAccessToSelectedProject,\n DeploymentSelectionWithinProject,\n} from \"./lib/api.js\";\nimport { readProjectConfig, writeProjectConfig } from \"./lib/config.js\";\nimport {\n DeploymentDetails,\n eraseDeploymentEnvVar,\n writeDeploymentEnvVar,\n} from \"./lib/deployment.js\";\nimport { finalizeConfiguration } from \"./lib/init.js\";\nimport {\n CONVEX_DEPLOYMENT_ENV_VAR_NAME,\n functionsDir,\n hasProjects,\n logAndHandleFetchError,\n selectDevDeploymentType,\n selectRegionOrUseDefault,\n validateOrSelectProject,\n validateOrSelectTeam,\n} from \"./lib/utils/utils.js\";\nimport { writeUrlsToEnvFile } from \"./lib/envvars.js\";\nimport path from \"path\";\nimport { projectDashboardUrl } from \"./lib/dashboard.js\";\nimport { doInitConvexFolder } from \"./lib/codegen.js\";\nimport { handleLocalDeployment } from \"./lib/localDeployment/localDeployment.js\";\nimport {\n promptOptions,\n promptString,\n promptYesNo,\n} from \"./lib/utils/prompts.js\";\nimport { readGlobalConfig } from \"./lib/utils/globalConfig.js\";\nimport { maybeSetupAiFiles } from \"./lib/aiFiles/index.js\";\nimport {\n DeploymentSelection,\n deploymentNameFromSelection,\n shouldAllowAnonymousDevelopment,\n} from \"./lib/deploymentSelection.js\";\nimport { ensureLoggedIn } from \"./lib/login.js\";\nimport { handleAnonymousDeployment } from \"./lib/localDeployment/anonymous.js\";\nimport { fetchDeploymentCanonicalSiteUrl } from \"./lib/env.js\";\ntype DeploymentCredentials = {\n url: string;\n adminKey: string;\n};\n\ntype ChosenConfiguration =\n // `--configure new`\n | \"new\"\n // `--configure existing`\n | \"existing\"\n // `--configure`\n | \"ask\"\n // `--configure` was not specified\n | null;\n\ntype ConfigureCmdOptions = {\n prod: boolean;\n localOptions: {\n ports?: {\n cloud: number;\n site: number;\n };\n backendVersion?: string | undefined;\n dashboardVersion?: string | undefined;\n forceUpgrade: boolean;\n };\n team?: string | undefined;\n project?: string | undefined;\n devDeployment?: \"cloud\" | \"local\" | undefined;\n local?: boolean | undefined;\n cloud?: boolean | undefined;\n url?: string | undefined;\n adminKey?: string | undefined;\n envFile?: string | undefined;\n overrideAuthUrl?: string | undefined;\n overrideAuthClient?: string | undefined;\n overrideAuthUsername?: string | undefined;\n overrideAuthPassword?: string | undefined;\n};\n\n/**\n * As of writing, this is used by:\n * - `npx convex dev`\n * - `npx convex codegen`\n *\n * But is not used by `npx convex deploy` or other commands.\n */\nexport async function deploymentCredentialsOrConfigure(\n ctx: Context,\n deploymentSelection: DeploymentSelection,\n chosenConfiguration: ChosenConfiguration,\n cmdOptions: ConfigureCmdOptions,\n): Promise<\n DeploymentCredentials & {\n deploymentFields: {\n deploymentName: DeploymentName;\n deploymentType: DeploymentType;\n projectSlug: string | null;\n teamSlug: string | null;\n siteUrl: string | null;\n } | null;\n }\n> {\n const selectedDeployment = await _deploymentCredentialsOrConfigure(\n ctx,\n deploymentSelection,\n chosenConfiguration,\n cmdOptions,\n );\n const siteUrl = await fetchDeploymentCanonicalSiteUrl(ctx, {\n adminKey: selectedDeployment.adminKey,\n deploymentUrl: selectedDeployment.url,\n });\n\n if (selectedDeployment.deploymentFields !== null) {\n // Set the `CONVEX_DEPLOYMENT` env var + the `CONVEX_URL` env var\n await updateEnvAndConfigForDeploymentSelection(\n ctx,\n {\n url: selectedDeployment.url,\n siteUrl,\n deploymentName: selectedDeployment.deploymentFields.deploymentName,\n teamSlug: selectedDeployment.deploymentFields.teamSlug,\n projectSlug: selectedDeployment.deploymentFields.projectSlug,\n deploymentType: selectedDeployment.deploymentFields.deploymentType,\n },\n deploymentNameFromSelection(deploymentSelection),\n );\n } else {\n // Clear the `CONVEX_DEPLOYMENT` env var + set the `CONVEX_URL` and\n // `CONVEX_SITE_URL` env vars.\n await handleManuallySetUrlAndAdminKey(ctx, {\n url: selectedDeployment.url,\n siteUrl,\n adminKey: selectedDeployment.adminKey,\n });\n }\n return {\n url: selectedDeployment.url,\n adminKey: selectedDeployment.adminKey,\n deploymentFields:\n selectedDeployment.deploymentFields === null\n ? null\n : { ...selectedDeployment.deploymentFields, siteUrl: siteUrl },\n };\n}\n\nexport async function _deploymentCredentialsOrConfigure(\n ctx: Context,\n deploymentSelection: DeploymentSelection,\n chosenConfiguration: ChosenConfiguration,\n cmdOptions: ConfigureCmdOptions,\n): Promise<\n DeploymentCredentials & {\n deploymentFields: {\n deploymentName: DeploymentName;\n deploymentType: DeploymentType;\n projectSlug: string | null;\n teamSlug: string | null;\n } | null;\n }\n> {\n const config = readGlobalConfig(ctx);\n const globallyForceCloud = !!config?.optOutOfLocalDevDeploymentsUntilBetaOver;\n if (globallyForceCloud && cmdOptions.local) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage:\n \"Can't specify --local when local deployments are disabled on this machine. Run `npx convex disable-local-deployments --undo-global` to allow use of --local.\",\n });\n }\n\n switch (deploymentSelection.kind) {\n case \"existingDeployment\":\n return {\n url: deploymentSelection.deploymentToActOn.url,\n adminKey: deploymentSelection.deploymentToActOn.adminKey,\n deploymentFields:\n deploymentSelection.deploymentToActOn.deploymentFields,\n };\n case \"chooseProject\": {\n await ensureLoggedIn(ctx, {\n overrideAuthUrl: cmdOptions.overrideAuthUrl,\n overrideAuthClient: cmdOptions.overrideAuthClient,\n overrideAuthUsername: cmdOptions.overrideAuthUsername,\n overrideAuthPassword: cmdOptions.overrideAuthPassword,\n });\n return await handleChooseProject(\n ctx,\n chosenConfiguration,\n deploymentSelection.selectionWithinProject,\n {\n globallyForceCloud,\n },\n cmdOptions,\n );\n }\n case \"preview\":\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Use `npx convex deploy` to use preview deployments.\",\n });\n case \"deploymentWithinProject\": {\n return await handleDeploymentWithinProject(ctx, {\n chosenConfiguration,\n deploymentSelection,\n cmdOptions,\n globallyForceCloud,\n });\n }\n case \"anonymous\": {\n const hasAuth = ctx.bigBrainAuth() !== null;\n const isAgentMode = process.env.CONVEX_AGENT_MODE === \"anonymous\";\n if (\n !isAgentMode &&\n hasAuth &&\n deploymentSelection.deploymentName !== null\n ) {\n const shouldConfigure =\n chosenConfiguration !== null ||\n (await promptYesNo(ctx, {\n message: `${CONVEX_DEPLOYMENT_ENV_VAR_NAME} is configured with deployment ${deploymentSelection.deploymentName}, which is not linked with your account. Would you like to link it now?`,\n }));\n if (!shouldConfigure) {\n return await ctx.crash({\n exitCode: 0,\n errorType: \"fatal\",\n printedMessage: `Run \\`npx convex login --link-deployments\\` first to link this deployment to your account, and then run \\`npx convex dev\\` again.`,\n });\n }\n return await handleChooseProject(\n ctx,\n chosenConfiguration,\n deploymentSelection.selectionWithinProject,\n {\n globallyForceCloud,\n },\n cmdOptions,\n );\n }\n const alreadyHasConfiguredAnonymousDeployment =\n deploymentSelection.deploymentName !== null &&\n chosenConfiguration === null;\n if (isAgentMode) {\n logWarning(\n chalkStderr.yellow.bold(\n \"CONVEX_AGENT_MODE=anonymous mode is in beta, functionality may change in the future.\",\n ),\n );\n }\n\n const shouldPromptForLogin = isAgentMode\n ? \"no\"\n : alreadyHasConfiguredAnonymousDeployment\n ? \"no\"\n : await promptOptions(ctx, {\n message:\n \"Welcome to Convex! Would you like to login to your account?\",\n choices: [\n {\n name: \"Start without an account (run Convex locally)\",\n value: \"no\",\n },\n { name: \"Login or create an account\", value: \"yes\" },\n ],\n default: \"no\",\n });\n if (shouldPromptForLogin === \"no\") {\n const result = await handleAnonymousDeployment(ctx, {\n chosenConfiguration,\n deploymentName: deploymentSelection.deploymentName,\n ...cmdOptions.localOptions,\n });\n return {\n adminKey: result.adminKey,\n url: result.deploymentUrl,\n deploymentFields: {\n deploymentName: result.deploymentName,\n deploymentType: \"anonymous\",\n projectSlug: null,\n teamSlug: null,\n },\n };\n }\n return await handleChooseProject(\n ctx,\n chosenConfiguration,\n deploymentSelection.selectionWithinProject,\n {\n globallyForceCloud,\n },\n cmdOptions,\n );\n }\n }\n}\n\nasync function handleDeploymentWithinProject(\n ctx: Context,\n {\n chosenConfiguration,\n deploymentSelection,\n cmdOptions,\n globallyForceCloud,\n }: {\n chosenConfiguration: ChosenConfiguration;\n deploymentSelection: DeploymentSelection & {\n kind: \"deploymentWithinProject\";\n };\n cmdOptions: ConfigureCmdOptions;\n globallyForceCloud: boolean;\n },\n) {\n const hasAuth = ctx.bigBrainAuth() !== null;\n const loginMessage =\n hasAuth && shouldAllowAnonymousDevelopment()\n ? undefined\n : \"Tip: You can try out Convex without creating an account by clearing the \" +\n `${CONVEX_DEPLOYMENT_ENV_VAR_NAME} environment variable (often in .env.local).`;\n await ensureLoggedIn(ctx, {\n message: loginMessage,\n overrideAuthUrl: cmdOptions.overrideAuthUrl,\n overrideAuthClient: cmdOptions.overrideAuthClient,\n overrideAuthUsername: cmdOptions.overrideAuthUsername,\n overrideAuthPassword: cmdOptions.overrideAuthPassword,\n });\n if (chosenConfiguration !== null) {\n const result = await handleChooseProject(\n ctx,\n chosenConfiguration,\n deploymentSelection.selectionWithinProject,\n {\n globallyForceCloud,\n },\n cmdOptions,\n );\n return result;\n }\n\n const accessResult = await checkAccessToSelectedProject(\n ctx,\n deploymentSelection.targetProject,\n );\n if (accessResult.kind === \"noAccess\") {\n logMessage(\"You don't have access to the selected project.\");\n const result = await handleChooseProject(\n ctx,\n chosenConfiguration,\n deploymentSelection.selectionWithinProject,\n {\n globallyForceCloud,\n },\n cmdOptions,\n );\n return result;\n }\n\n const selectedDeployment = await loadSelectedDeploymentCredentials(\n ctx,\n deploymentSelection,\n // We'll start running it below\n { ensureLocalRunning: false },\n );\n if (\n selectedDeployment.deploymentFields !== null &&\n selectedDeployment.deploymentFields.deploymentType === \"local\"\n ) {\n // Start running the local backend, which may bind to different ports\n // than what was saved from a previous run.\n const localDeployment = await handleLocalDeployment(ctx, {\n teamSlug: selectedDeployment.deploymentFields.teamSlug!,\n projectSlug: selectedDeployment.deploymentFields.projectSlug!,\n forceUpgrade: cmdOptions.localOptions.forceUpgrade,\n ports: cmdOptions.localOptions.ports,\n backendVersion: cmdOptions.localOptions.backendVersion,\n });\n return {\n url: localDeployment.deploymentUrl,\n adminKey: localDeployment.adminKey,\n deploymentFields: selectedDeployment.deploymentFields,\n };\n }\n return {\n url: selectedDeployment.url,\n adminKey: selectedDeployment.adminKey,\n deploymentFields: selectedDeployment.deploymentFields,\n };\n}\n\nasync function handleChooseProject(\n ctx: Context,\n chosenConfiguration: ChosenConfiguration,\n selectionWithinProject: DeploymentSelectionWithinProject,\n args: {\n globallyForceCloud: boolean;\n },\n cmdOptions: ConfigureCmdOptions,\n): Promise<\n DeploymentCredentials & {\n deploymentFields: {\n deploymentName: DeploymentName;\n deploymentType: DeploymentType;\n projectSlug: string;\n teamSlug: string;\n };\n }\n> {\n await ensureLoggedIn(ctx, {\n overrideAuthUrl: cmdOptions.overrideAuthUrl,\n overrideAuthClient: cmdOptions.overrideAuthClient,\n overrideAuthUsername: cmdOptions.overrideAuthUsername,\n overrideAuthPassword: cmdOptions.overrideAuthPassword,\n });\n const project = await selectProject(ctx, chosenConfiguration, {\n team: cmdOptions.team,\n project: cmdOptions.project,\n devDeployment: cmdOptions.devDeployment,\n local: args.globallyForceCloud ? false : cmdOptions.local,\n cloud: args.globallyForceCloud ? true : cmdOptions.cloud,\n });\n // TODO complain about any non-default cmdOptions.localOptions here\n // because we're ignoring them if this isn't a local development.\n\n const deploymentOptions: DeploymentOptions =\n selectionWithinProject.kind === \"prod\"\n ? { kind: \"prod\" }\n : project.devDeployment === \"local\"\n ? { kind: \"local\", ...cmdOptions.localOptions }\n : { kind: \"dev\" };\n const {\n deploymentName,\n deploymentUrl: url,\n adminKey,\n } = await ensureDeploymentProvisioned(ctx, {\n teamSlug: project.teamSlug,\n projectSlug: project.projectSlug,\n deploymentOptions,\n });\n return {\n url,\n adminKey,\n deploymentFields: {\n deploymentName,\n deploymentType: deploymentOptions.kind,\n projectSlug: project.projectSlug,\n teamSlug: project.teamSlug,\n },\n };\n}\n\nasync function handleManuallySetUrlAndAdminKey(\n ctx: Context,\n cmdOptions: { url: string; siteUrl: string; adminKey: string },\n) {\n const { url, siteUrl, adminKey } = cmdOptions;\n const didErase = await eraseDeploymentEnvVar(ctx);\n if (didErase) {\n logMessage(\n chalkStderr.yellowBright(\n `Removed the CONVEX_DEPLOYMENT environment variable from .env.local`,\n ),\n );\n }\n const envFileConfig = await writeUrlsToEnvFile(ctx, {\n convexUrl: url,\n siteUrl,\n });\n if (\n envFileConfig !== null &&\n (envFileConfig.convexUrlEnvVar || envFileConfig.siteUrlEnvVar)\n ) {\n // Join both names with \" and \" if both exist, otherwise just use one of them.\n const updatedVars = [\n envFileConfig.convexUrlEnvVar,\n envFileConfig.siteUrlEnvVar,\n ]\n .filter(Boolean)\n .join(\" and \");\n logMessage(\n chalkStderr.green(`Saved ${updatedVars} to ${envFileConfig.envFile}`),\n );\n }\n return { url, adminKey };\n}\n\nexport async function selectProject(\n ctx: Context,\n chosenConfiguration: ChosenConfiguration,\n cmdOptions: {\n team?: string | undefined;\n project?: string | undefined;\n devDeployment?: \"cloud\" | \"local\" | undefined;\n local?: boolean | undefined;\n cloud?: boolean | undefined;\n defaultProjectName?: string | undefined;\n },\n): Promise<{\n teamSlug: string;\n projectSlug: string;\n devDeployment: \"cloud\" | \"local\";\n}> {\n // Prompt the user to select a project.\n const choice =\n chosenConfiguration !== \"ask\" && chosenConfiguration !== null\n ? chosenConfiguration\n : await askToConfigure(ctx);\n switch (choice) {\n case \"new\":\n return selectNewProject(ctx, chosenConfiguration, cmdOptions);\n case \"existing\":\n return selectExistingProject(ctx, chosenConfiguration, cmdOptions);\n default:\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"No project selected.\",\n });\n }\n}\n\nconst cwd = path.basename(process.cwd());\nasync function selectNewProject(\n ctx: Context,\n chosenConfiguration: ChosenConfiguration,\n config: {\n team?: string | undefined;\n project?: string | undefined;\n devDeployment?: \"cloud\" | \"local\" | undefined;\n cloud?: boolean | undefined;\n local?: boolean | undefined;\n defaultProjectName?: string | undefined;\n },\n) {\n const { team: selectedTeam, chosen: didChooseBetweenTeams } =\n await validateOrSelectTeam(ctx, config.team, \"Team:\");\n let projectName: string = config.project || cwd;\n let choseProjectInteractively = false;\n if (!config.project) {\n projectName = await promptString(ctx, {\n message: \"Project name:\",\n default: config.defaultProjectName || cwd,\n });\n choseProjectInteractively = true;\n }\n\n const { devDeployment } = await selectDevDeploymentType(ctx, {\n chosenConfiguration,\n newOrExisting: \"new\",\n teamSlug: selectedTeam.slug,\n userHasChosenSomethingInteractively:\n didChooseBetweenTeams || choseProjectInteractively,\n projectSlug: undefined,\n devDeploymentFromFlag: config.devDeployment,\n forceDevDeployment: config.local\n ? \"local\"\n : config.cloud\n ? \"cloud\"\n : undefined,\n });\n\n const region =\n devDeployment === \"cloud\"\n ? await selectRegionOrUseDefault(ctx, selectedTeam, \"dev\")\n : null;\n\n showSpinner(\"Creating new Convex project...\");\n\n const deploymentToProvision =\n devDeployment === \"cloud\"\n ? {\n deploymentType: \"dev\" as const,\n region,\n }\n : null;\n\n let projectSlug, teamSlug, projectsRemaining;\n try {\n ({ projectSlug, teamSlug, projectsRemaining } = await createProject(ctx, {\n teamSlug: selectedTeam.slug,\n projectName,\n deploymentToProvision,\n }));\n } catch (err) {\n logFailure(\"Unable to create project.\");\n return await logAndHandleFetchError(ctx, err);\n }\n const teamMessage = didChooseBetweenTeams\n ? \" in team \" + chalkStderr.bold(teamSlug)\n : \"\";\n logFinishedStep(\n `Created project ${chalkStderr.bold(\n projectSlug,\n )}${teamMessage}, manage it at ${chalkStderr.bold(\n projectDashboardUrl(teamSlug, projectSlug),\n )}`,\n );\n\n if (projectsRemaining <= 2) {\n logWarning(\n chalkStderr.yellow.bold(\n `Your account now has ${projectsRemaining} project${\n projectsRemaining === 1 ? \"\" : \"s\"\n } remaining.`,\n ),\n );\n }\n\n await doInitConvexFolder(ctx);\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n const folder = functionsDir(configPath, projectConfig);\n await maybeSetupAiFiles({\n ctx,\n convexDir: path.resolve(folder),\n projectDir: path.resolve(path.dirname(configPath)),\n });\n return { teamSlug, projectSlug, devDeployment };\n}\n\nasync function selectExistingProject(\n ctx: Context,\n chosenConfiguration: ChosenConfiguration,\n config: {\n team?: string | undefined;\n project?: string | undefined;\n devDeployment?: \"cloud\" | \"local\" | undefined;\n local?: boolean | undefined;\n cloud?: boolean | undefined;\n },\n): Promise<{\n teamSlug: string;\n projectSlug: string;\n devDeployment: \"cloud\" | \"local\";\n}> {\n const {\n team: { slug: teamSlug },\n chosen,\n } = await validateOrSelectTeam(ctx, config.team, \"Team:\");\n\n const projectSlug = await validateOrSelectProject(\n ctx,\n config.project,\n teamSlug,\n \"Configure project\",\n \"Project:\",\n );\n if (projectSlug === null) {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: \"Run the command again to create a new project instead.\",\n });\n }\n const { devDeployment } = await selectDevDeploymentType(ctx, {\n chosenConfiguration,\n newOrExisting: \"existing\",\n teamSlug,\n projectSlug,\n userHasChosenSomethingInteractively: chosen || !config.project,\n devDeploymentFromFlag: config.devDeployment,\n forceDevDeployment: config.local\n ? \"local\"\n : config.cloud\n ? \"cloud\"\n : undefined,\n });\n\n logFinishedStep(`Reinitialized project ${chalkStderr.bold(projectSlug)}`);\n\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n const folder = functionsDir(configPath, projectConfig);\n await maybeSetupAiFiles({\n ctx,\n convexDir: path.resolve(folder),\n projectDir: path.resolve(path.dirname(configPath)),\n });\n\n return { teamSlug, projectSlug, devDeployment };\n}\n\nasync function askToConfigure(ctx: Context): Promise<\"new\" | \"existing\"> {\n if (!(await hasProjects(ctx))) {\n return \"new\";\n }\n return await promptOptions(ctx, {\n message: \"What would you like to configure?\",\n default: \"new\",\n choices: [\n { name: \"create a new project\", value: \"new\" },\n { name: \"choose an existing project\", value: \"existing\" },\n ],\n });\n}\n\ntype DeploymentOptions =\n | {\n kind: \"prod\";\n }\n | { kind: \"dev\" }\n | {\n kind: \"local\";\n ports?:\n | {\n cloud: number;\n site: number;\n }\n | undefined;\n backendVersion?: string | undefined;\n forceUpgrade: boolean;\n };\n\n/**\n * This method assumes that the member has access to the selected project.\n */\nasync function ensureDeploymentProvisioned(\n ctx: Context,\n options: {\n teamSlug: string;\n projectSlug: string;\n deploymentOptions: DeploymentOptions;\n },\n): Promise<DeploymentDetails> {\n switch (options.deploymentOptions.kind) {\n case \"dev\":\n case \"prod\": {\n const credentials =\n await fetchDeploymentCredentialsProvisioningDevOrProdMaybeThrows(\n ctx,\n {\n kind: \"teamAndProjectSlugs\",\n teamSlug: options.teamSlug,\n projectSlug: options.projectSlug,\n },\n options.deploymentOptions.kind,\n );\n return {\n ...credentials,\n onActivity: null,\n };\n }\n case \"local\": {\n const credentials = await handleLocalDeployment(ctx, {\n teamSlug: options.teamSlug,\n projectSlug: options.projectSlug,\n ...options.deploymentOptions,\n });\n return credentials;\n }\n default:\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: `Invalid deployment type: ${(options.deploymentOptions as any).kind}`,\n errForSentry: `Invalid deployment type: ${(options.deploymentOptions as any).kind}`,\n });\n }\n}\n\nexport async function updateEnvAndConfigForDeploymentSelection(\n ctx: Context,\n options: {\n url: string;\n siteUrl?: string | null;\n deploymentName: string;\n teamSlug: string | null;\n projectSlug: string | null;\n deploymentType: DeploymentType;\n },\n existingValue: string | null,\n) {\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n\n const { wroteToGitIgnore, changedDeploymentEnvVar } =\n await writeDeploymentEnvVar(\n ctx,\n options.deploymentType,\n {\n team: options.teamSlug,\n project: options.projectSlug,\n deploymentName: options.deploymentName,\n },\n existingValue,\n );\n await writeProjectConfig(ctx, projectConfig);\n await finalizeConfiguration(ctx, {\n deploymentType: options.deploymentType,\n deploymentName: options.deploymentName,\n url: options.url,\n siteUrl: options.siteUrl,\n wroteToGitIgnore,\n changedDeploymentEnvVar,\n functionsPath: functionsDir(configPath, projectConfig),\n });\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAS,mBAAmB;AAE5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,mBAAmB,0BAA0B;AACtD;AAAA,EAEE;AAAA,EACA;AAAA,OACK;AACP,SAAS,6BAA6B;AACtC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,0BAA0B;AACnC,OAAO,UAAU;AACjB,SAAS,2BAA2B;AACpC,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAClC;AAAA,EAEE;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAC/B,SAAS,iCAAiC;AAC1C,SAAS,uCAAuC;AAgDhD,sBAAsB,iCACpB,KACA,qBACA,qBACA,YAWA;AACA,QAAM,qBAAqB,MAAM;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,UAAU,MAAM,gCAAgC,KAAK;AAAA,IACzD,UAAU,mBAAmB;AAAA,IAC7B,eAAe,mBAAmB;AAAA,EACpC,CAAC;AAED,MAAI,mBAAmB,qBAAqB,MAAM;AAEhD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,QACE,KAAK,mBAAmB;AAAA,QACxB;AAAA,QACA,gBAAgB,mBAAmB,iBAAiB;AAAA,QACpD,UAAU,mBAAmB,iBAAiB;AAAA,QAC9C,aAAa,mBAAmB,iBAAiB;AAAA,QACjD,gBAAgB,mBAAmB,iBAAiB;AAAA,MACtD;AAAA,MACA,4BAA4B,mBAAmB;AAAA,IACjD;AAAA,EACF,OAAO;AAGL,UAAM,gCAAgC,KAAK;AAAA,MACzC,KAAK,mBAAmB;AAAA,MACxB;AAAA,MACA,UAAU,mBAAmB;AAAA,IAC/B,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL,KAAK,mBAAmB;AAAA,IACxB,UAAU,mBAAmB;AAAA,IAC7B,kBACE,mBAAmB,qBAAqB,OACpC,OACA,EAAE,GAAG,mBAAmB,kBAAkB,QAAiB;AAAA,EACnE;AACF;AAEA,sBAAsB,kCACpB,KACA,qBACA,qBACA,YAUA;AACA,QAAM,SAAS,iBAAiB,GAAG;AACnC,QAAM,qBAAqB,CAAC,CAAC,QAAQ;AACrC,MAAI,sBAAsB,WAAW,OAAO;AAC1C,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBACE;AAAA,IACJ,CAAC;AAAA,EACH;AAEA,UAAQ,oBAAoB,MAAM;AAAA,IAChC,KAAK;AACH,aAAO;AAAA,QACL,KAAK,oBAAoB,kBAAkB;AAAA,QAC3C,UAAU,oBAAoB,kBAAkB;AAAA,QAChD,kBACE,oBAAoB,kBAAkB;AAAA,MAC1C;AAAA,IACF,KAAK,iBAAiB;AACpB,YAAM,eAAe,KAAK;AAAA,QACxB,iBAAiB,WAAW;AAAA,QAC5B,oBAAoB,WAAW;AAAA,QAC/B,sBAAsB,WAAW;AAAA,QACjC,sBAAsB,WAAW;AAAA,MACnC,CAAC;AACD,aAAO,MAAM;AAAA,QACX;AAAA,QACA;AAAA,QACA,oBAAoB;AAAA,QACpB;AAAA,UACE;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA,KAAK;AACH,aAAO,MAAM,IAAI,MAAM;AAAA,QACrB,UAAU;AAAA,QACV,WAAW;AAAA,QACX,gBAAgB;AAAA,MAClB,CAAC;AAAA,IACH,KAAK,2BAA2B;AAC9B,aAAO,MAAM,8BAA8B,KAAK;AAAA,QAC9C;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,KAAK,aAAa;AAChB,YAAM,UAAU,IAAI,aAAa,MAAM;AACvC,YAAM,cAAc,QAAQ,IAAI,sBAAsB;AACtD,UACE,CAAC,eACD,WACA,oBAAoB,mBAAmB,MACvC;AACA,cAAM,kBACJ,wBAAwB,QACvB,MAAM,YAAY,KAAK;AAAA,UACtB,SAAS,GAAG,8BAA8B,kCAAkC,oBAAoB,cAAc;AAAA,QAChH,CAAC;AACH,YAAI,CAAC,iBAAiB;AACpB,iBAAO,MAAM,IAAI,MAAM;AAAA,YACrB,UAAU;AAAA,YACV,WAAW;AAAA,YACX,gBAAgB;AAAA,UAClB,CAAC;AAAA,QACH;AACA,eAAO,MAAM;AAAA,UACX;AAAA,UACA;AAAA,UACA,oBAAoB;AAAA,UACpB;AAAA,YACE;AAAA,UACF;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM,0CACJ,oBAAoB,mBAAmB,QACvC,wBAAwB;AAC1B,UAAI,aAAa;AACf;AAAA,UACE,YAAY,OAAO;AAAA,YACjB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,uBAAuB,cACzB,OACA,0CACE,OACA,MAAM,cAAc,KAAK;AAAA,QACvB,SACE;AAAA,QACF,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA,UACT;AAAA,UACA,EAAE,MAAM,8BAA8B,OAAO,MAAM;AAAA,QACrD;AAAA,QACA,SAAS;AAAA,MACX,CAAC;AACP,UAAI,yBAAyB,MAAM;AACjC,cAAM,SAAS,MAAM,0BAA0B,KAAK;AAAA,UAClD;AAAA,UACA,gBAAgB,oBAAoB;AAAA,UACpC,GAAG,WAAW;AAAA,QAChB,CAAC;AACD,eAAO;AAAA,UACL,UAAU,OAAO;AAAA,UACjB,KAAK,OAAO;AAAA,UACZ,kBAAkB;AAAA,YAChB,gBAAgB,OAAO;AAAA,YACvB,gBAAgB;AAAA,YAChB,aAAa;AAAA,YACb,UAAU;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AACA,aAAO,MAAM;AAAA,QACX;AAAA,QACA;AAAA,QACA,oBAAoB;AAAA,QACpB;AAAA,UACE;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,8BACb,KACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAQA;AACA,QAAM,UAAU,IAAI,aAAa,MAAM;AACvC,QAAM,eACJ,WAAW,gCAAgC,IACvC,SACA,2EACG,8BAA8B;AACvC,QAAM,eAAe,KAAK;AAAA,IACxB,SAAS;AAAA,IACT,iBAAiB,WAAW;AAAA,IAC5B,oBAAoB,WAAW;AAAA,IAC/B,sBAAsB,WAAW;AAAA,IACjC,sBAAsB,WAAW;AAAA,EACnC,CAAC;AACD,MAAI,wBAAwB,MAAM;AAChC,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,MACA,oBAAoB;AAAA,MACpB;AAAA,QACE;AAAA,MACF;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,MAAM;AAAA,IACzB;AAAA,IACA,oBAAoB;AAAA,EACtB;AACA,MAAI,aAAa,SAAS,YAAY;AACpC,eAAW,gDAAgD;AAC3D,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,MACA,oBAAoB;AAAA,MACpB;AAAA,QACE;AAAA,MACF;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,qBAAqB,MAAM;AAAA,IAC/B;AAAA,IACA;AAAA;AAAA,IAEA,EAAE,oBAAoB,MAAM;AAAA,EAC9B;AACA,MACE,mBAAmB,qBAAqB,QACxC,mBAAmB,iBAAiB,mBAAmB,SACvD;AAGA,UAAM,kBAAkB,MAAM,sBAAsB,KAAK;AAAA,MACvD,UAAU,mBAAmB,iBAAiB;AAAA,MAC9C,aAAa,mBAAmB,iBAAiB;AAAA,MACjD,cAAc,WAAW,aAAa;AAAA,MACtC,OAAO,WAAW,aAAa;AAAA,MAC/B,gBAAgB,WAAW,aAAa;AAAA,IAC1C,CAAC;AACD,WAAO;AAAA,MACL,KAAK,gBAAgB;AAAA,MACrB,UAAU,gBAAgB;AAAA,MAC1B,kBAAkB,mBAAmB;AAAA,IACvC;AAAA,EACF;AACA,SAAO;AAAA,IACL,KAAK,mBAAmB;AAAA,IACxB,UAAU,mBAAmB;AAAA,IAC7B,kBAAkB,mBAAmB;AAAA,EACvC;AACF;AAEA,eAAe,oBACb,KACA,qBACA,wBACA,MAGA,YAUA;AACA,QAAM,eAAe,KAAK;AAAA,IACxB,iBAAiB,WAAW;AAAA,IAC5B,oBAAoB,WAAW;AAAA,IAC/B,sBAAsB,WAAW;AAAA,IACjC,sBAAsB,WAAW;AAAA,EACnC,CAAC;AACD,QAAM,UAAU,MAAM,cAAc,KAAK,qBAAqB;AAAA,IAC5D,MAAM,WAAW;AAAA,IACjB,SAAS,WAAW;AAAA,IACpB,eAAe,WAAW;AAAA,IAC1B,OAAO,KAAK,qBAAqB,QAAQ,WAAW;AAAA,IACpD,OAAO,KAAK,qBAAqB,OAAO,WAAW;AAAA,EACrD,CAAC;AAID,QAAM,oBACJ,uBAAuB,SAAS,SAC5B,EAAE,MAAM,OAAO,IACf,QAAQ,kBAAkB,UACxB,EAAE,MAAM,SAAS,GAAG,WAAW,aAAa,IAC5C,EAAE,MAAM,MAAM;AACtB,QAAM;AAAA,IACJ;AAAA,IACA,eAAe;AAAA,IACf;AAAA,EACF,IAAI,MAAM,4BAA4B,KAAK;AAAA,IACzC,UAAU,QAAQ;AAAA,IAClB,aAAa,QAAQ;AAAA,IACrB;AAAA,EACF,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,MAChB;AAAA,MACA,gBAAgB,kBAAkB;AAAA,MAClC,aAAa,QAAQ;AAAA,MACrB,UAAU,QAAQ;AAAA,IACpB;AAAA,EACF;AACF;AAEA,eAAe,gCACb,KACA,YACA;AACA,QAAM,EAAE,KAAK,SAAS,SAAS,IAAI;AACnC,QAAM,WAAW,MAAM,sBAAsB,GAAG;AAChD,MAAI,UAAU;AACZ;AAAA,MACE,YAAY;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,QAAM,gBAAgB,MAAM,mBAAmB,KAAK;AAAA,IAClD,WAAW;AAAA,IACX;AAAA,EACF,CAAC;AACD,MACE,kBAAkB,SACjB,cAAc,mBAAmB,cAAc,gBAChD;AAEA,UAAM,cAAc;AAAA,MAClB,cAAc;AAAA,MACd,cAAc;AAAA,IAChB,EACG,OAAO,OAAO,EACd,KAAK,OAAO;AACf;AAAA,MACE,YAAY,MAAM,SAAS,WAAW,OAAO,cAAc,OAAO,EAAE;AAAA,IACtE;AAAA,EACF;AACA,SAAO,EAAE,KAAK,SAAS;AACzB;AAEA,sBAAsB,cACpB,KACA,qBACA,YAYC;AAED,QAAM,SACJ,wBAAwB,SAAS,wBAAwB,OACrD,sBACA,MAAM,eAAe,GAAG;AAC9B,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,iBAAiB,KAAK,qBAAqB,UAAU;AAAA,IAC9D,KAAK;AACH,aAAO,sBAAsB,KAAK,qBAAqB,UAAU;AAAA,IACnE;AACE,aAAO,MAAM,IAAI,MAAM;AAAA,QACrB,UAAU;AAAA,QACV,WAAW;AAAA,QACX,gBAAgB;AAAA,MAClB,CAAC;AAAA,EACL;AACF;AAEA,MAAM,MAAM,KAAK,SAAS,QAAQ,IAAI,CAAC;AACvC,eAAe,iBACb,KACA,qBACA,QAQA;AACA,QAAM,EAAE,MAAM,cAAc,QAAQ,sBAAsB,IACxD,MAAM,qBAAqB,KAAK,OAAO,MAAM,OAAO;AACtD,MAAI,cAAsB,OAAO,WAAW;AAC5C,MAAI,4BAA4B;AAChC,MAAI,CAAC,OAAO,SAAS;AACnB,kBAAc,MAAM,aAAa,KAAK;AAAA,MACpC,SAAS;AAAA,MACT,SAAS,OAAO,sBAAsB;AAAA,IACxC,CAAC;AACD,gCAA4B;AAAA,EAC9B;AAEA,QAAM,EAAE,cAAc,IAAI,MAAM,wBAAwB,KAAK;AAAA,IAC3D;AAAA,IACA,eAAe;AAAA,IACf,UAAU,aAAa;AAAA,IACvB,qCACE,yBAAyB;AAAA,IAC3B,aAAa;AAAA,IACb,uBAAuB,OAAO;AAAA,IAC9B,oBAAoB,OAAO,QACvB,UACA,OAAO,QACL,UACA;AAAA,EACR,CAAC;AAED,QAAM,SACJ,kBAAkB,UACd,MAAM,yBAAyB,KAAK,cAAc,KAAK,IACvD;AAEN,cAAY,gCAAgC;AAE5C,QAAM,wBACJ,kBAAkB,UACd;AAAA,IACE,gBAAgB;AAAA,IAChB;AAAA,EACF,IACA;AAEN,MAAI,aAAa,UAAU;AAC3B,MAAI;AACF,KAAC,EAAE,aAAa,UAAU,kBAAkB,IAAI,MAAM,cAAc,KAAK;AAAA,MACvE,UAAU,aAAa;AAAA,MACvB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,eAAW,2BAA2B;AACtC,WAAO,MAAM,uBAAuB,KAAK,GAAG;AAAA,EAC9C;AACA,QAAM,cAAc,wBAChB,cAAc,YAAY,KAAK,QAAQ,IACvC;AACJ;AAAA,IACE,mBAAmB,YAAY;AAAA,MAC7B;AAAA,IACF,CAAC,GAAG,WAAW,kBAAkB,YAAY;AAAA,MAC3C,oBAAoB,UAAU,WAAW;AAAA,IAC3C,CAAC;AAAA,EACH;AAEA,MAAI,qBAAqB,GAAG;AAC1B;AAAA,MACE,YAAY,OAAO;AAAA,QACjB,wBAAwB,iBAAiB,WACvC,sBAAsB,IAAI,KAAK,GACjC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,mBAAmB,GAAG;AAC5B,QAAM,EAAE,YAAY,cAAc,IAAI,MAAM,kBAAkB,GAAG;AACjE,QAAM,SAAS,aAAa,YAAY,aAAa;AACrD,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA,WAAW,KAAK,QAAQ,MAAM;AAAA,IAC9B,YAAY,KAAK,QAAQ,KAAK,QAAQ,UAAU,CAAC;AAAA,EACnD,CAAC;AACD,SAAO,EAAE,UAAU,aAAa,cAAc;AAChD;AAEA,eAAe,sBACb,KACA,qBACA,QAWC;AACD,QAAM;AAAA,IACJ,MAAM,EAAE,MAAM,SAAS;AAAA,IACvB;AAAA,EACF,IAAI,MAAM,qBAAqB,KAAK,OAAO,MAAM,OAAO;AAExD,QAAM,cAAc,MAAM;AAAA,IACxB;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,gBAAgB,MAAM;AACxB,WAAO,MAAM,IAAI,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH;AACA,QAAM,EAAE,cAAc,IAAI,MAAM,wBAAwB,KAAK;AAAA,IAC3D;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA,qCAAqC,UAAU,CAAC,OAAO;AAAA,IACvD,uBAAuB,OAAO;AAAA,IAC9B,oBAAoB,OAAO,QACvB,UACA,OAAO,QACL,UACA;AAAA,EACR,CAAC;AAED,kBAAgB,yBAAyB,YAAY,KAAK,WAAW,CAAC,EAAE;AAExE,QAAM,EAAE,YAAY,cAAc,IAAI,MAAM,kBAAkB,GAAG;AACjE,QAAM,SAAS,aAAa,YAAY,aAAa;AACrD,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA,WAAW,KAAK,QAAQ,MAAM;AAAA,IAC9B,YAAY,KAAK,QAAQ,KAAK,QAAQ,UAAU,CAAC;AAAA,EACnD,CAAC;AAED,SAAO,EAAE,UAAU,aAAa,cAAc;AAChD;AAEA,eAAe,eAAe,KAA2C;AACvE,MAAI,CAAE,MAAM,YAAY,GAAG,GAAI;AAC7B,WAAO;AAAA,EACT;AACA,SAAO,MAAM,cAAc,KAAK;AAAA,IAC9B,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,MAAM,wBAAwB,OAAO,MAAM;AAAA,MAC7C,EAAE,MAAM,8BAA8B,OAAO,WAAW;AAAA,IAC1D;AAAA,EACF,CAAC;AACH;AAsBA,eAAe,4BACb,KACA,SAK4B;AAC5B,UAAQ,QAAQ,kBAAkB,MAAM;AAAA,IACtC,KAAK;AAAA,IACL,KAAK,QAAQ;AACX,YAAM,cACJ,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,UAAU,QAAQ;AAAA,UAClB,aAAa,QAAQ;AAAA,QACvB;AAAA,QACA,QAAQ,kBAAkB;AAAA,MAC5B;AACF,aAAO;AAAA,QACL,GAAG;AAAA,QACH,YAAY;AAAA,MACd;AAAA,IACF;AAAA,IACA,KAAK,SAAS;AACZ,YAAM,cAAc,MAAM,sBAAsB,KAAK;AAAA,QACnD,UAAU,QAAQ;AAAA,QAClB,aAAa,QAAQ;AAAA,QACrB,GAAG,QAAQ;AAAA,MACb,CAAC;AACD,aAAO;AAAA,IACT;AAAA,IACA;AACE,aAAO,MAAM,IAAI,MAAM;AAAA,QACrB,UAAU;AAAA,QACV,WAAW;AAAA,QACX,gBAAgB,4BAA6B,QAAQ,kBAA0B,IAAI;AAAA,QACnF,cAAc,4BAA6B,QAAQ,kBAA0B,IAAI;AAAA,MACnF,CAAC;AAAA,EACL;AACF;AAEA,sBAAsB,yCACpB,KACA,SAQA,eACA;AACA,QAAM,EAAE,YAAY,cAAc,IAAI,MAAM,kBAAkB,GAAG;AAEjE,QAAM,EAAE,kBAAkB,wBAAwB,IAChD,MAAM;AAAA,IACJ;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,MACE,MAAM,QAAQ;AAAA,MACd,SAAS,QAAQ;AAAA,MACjB,gBAAgB,QAAQ;AAAA,IAC1B;AAAA,IACA;AAAA,EACF;AACF,QAAM,mBAAmB,KAAK,aAAa;AAC3C,QAAM,sBAAsB,KAAK;AAAA,IAC/B,gBAAgB,QAAQ;AAAA,IACxB,gBAAgB,QAAQ;AAAA,IACxB,KAAK,QAAQ;AAAA,IACb,SAAS,QAAQ;AAAA,IACjB;AAAA,IACA;AAAA,IACA,eAAe,aAAa,YAAY,aAAa;AAAA,EACvD,CAAC;AACH;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import {
|
|
3
|
+
AGENTS_MD_START_MARKER,
|
|
4
|
+
AGENTS_MD_END_MARKER,
|
|
5
|
+
agentsMdConvexSection
|
|
6
|
+
} from "../../codegen_templates/agentsmd.js";
|
|
7
|
+
import { agentsMdPath } from "./paths.js";
|
|
8
|
+
import {
|
|
9
|
+
injectManagedSection,
|
|
10
|
+
stripManagedSection,
|
|
11
|
+
hasManagedSection,
|
|
12
|
+
removeMarkdownSection
|
|
13
|
+
} from "./utils.js";
|
|
14
|
+
function target(projectDir) {
|
|
15
|
+
return {
|
|
16
|
+
filePath: agentsMdPath(projectDir),
|
|
17
|
+
startMarker: AGENTS_MD_START_MARKER,
|
|
18
|
+
endMarker: AGENTS_MD_END_MARKER
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export async function injectAgentsMdSection({
|
|
22
|
+
section,
|
|
23
|
+
projectDir
|
|
24
|
+
}) {
|
|
25
|
+
return injectManagedSection({ ...target(projectDir), section });
|
|
26
|
+
}
|
|
27
|
+
export async function stripAgentsMdSection(projectDir) {
|
|
28
|
+
return stripManagedSection(target(projectDir));
|
|
29
|
+
}
|
|
30
|
+
export async function removeAgentsMdSection(projectDir) {
|
|
31
|
+
return removeMarkdownSection({
|
|
32
|
+
projectDir,
|
|
33
|
+
strip: stripAgentsMdSection,
|
|
34
|
+
fileName: "AGENTS.md"
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export async function hasAgentsMdInstalled(projectDir) {
|
|
38
|
+
return hasManagedSection(target(projectDir));
|
|
39
|
+
}
|
|
40
|
+
export async function applyAgentsMdSection({
|
|
41
|
+
projectDir,
|
|
42
|
+
config,
|
|
43
|
+
convexDirName
|
|
44
|
+
}) {
|
|
45
|
+
const result = await injectAgentsMdSection({
|
|
46
|
+
section: agentsMdConvexSection(convexDirName),
|
|
47
|
+
projectDir
|
|
48
|
+
});
|
|
49
|
+
config.agentsMdSectionHash = result.sectionHash;
|
|
50
|
+
return result.didWrite;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=agentsmd.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/lib/aiFiles/agentsmd.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n AGENTS_MD_START_MARKER,\n AGENTS_MD_END_MARKER,\n agentsMdConvexSection,\n} from \"../../codegen_templates/agentsmd.js\";\nimport { agentsMdPath } from \"./paths.js\";\nimport { type AiFilesConfig } from \"./config.js\";\nimport {\n type ManagedSectionTarget,\n type InjectResult,\n type StripResult,\n injectManagedSection,\n stripManagedSection,\n hasManagedSection,\n removeMarkdownSection,\n} from \"./utils.js\";\n\nfunction target(projectDir?: string): ManagedSectionTarget {\n return {\n filePath: agentsMdPath(projectDir),\n startMarker: AGENTS_MD_START_MARKER,\n endMarker: AGENTS_MD_END_MARKER,\n };\n}\n\nexport async function injectAgentsMdSection({\n section,\n projectDir,\n}: {\n section: string;\n projectDir?: string;\n}): Promise<InjectResult> {\n return injectManagedSection({ ...target(projectDir), section });\n}\n\nexport async function stripAgentsMdSection(\n projectDir: string,\n): Promise<StripResult> {\n return stripManagedSection(target(projectDir));\n}\n\nexport async function removeAgentsMdSection(\n projectDir: string,\n): Promise<boolean> {\n return removeMarkdownSection({\n projectDir,\n strip: stripAgentsMdSection,\n fileName: \"AGENTS.md\",\n });\n}\n\nexport async function hasAgentsMdInstalled(\n projectDir: string,\n): Promise<boolean> {\n return hasManagedSection(target(projectDir));\n}\n\n/**\n * Inject (or update) the Convex section in AGENTS.md and record the hash.\n * Returns true if the file was actually written.\n */\nexport async function applyAgentsMdSection({\n projectDir,\n config,\n convexDirName,\n}: {\n projectDir: string;\n config: AiFilesConfig;\n convexDirName: string;\n}): Promise<boolean> {\n const result = await injectAgentsMdSection({\n section: agentsMdConvexSection(convexDirName),\n projectDir,\n });\n config.agentsMdSectionHash = result.sectionHash;\n return result.didWrite;\n}\n"],
|
|
5
|
+
"mappings": ";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,oBAAoB;AAE7B;AAAA,EAIE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,OAAO,YAA2C;AACzD,SAAO;AAAA,IACL,UAAU,aAAa,UAAU;AAAA,IACjC,aAAa;AAAA,IACb,WAAW;AAAA,EACb;AACF;AAEA,sBAAsB,sBAAsB;AAAA,EAC1C;AAAA,EACA;AACF,GAG0B;AACxB,SAAO,qBAAqB,EAAE,GAAG,OAAO,UAAU,GAAG,QAAQ,CAAC;AAChE;AAEA,sBAAsB,qBACpB,YACsB;AACtB,SAAO,oBAAoB,OAAO,UAAU,CAAC;AAC/C;AAEA,sBAAsB,sBACpB,YACkB;AAClB,SAAO,sBAAsB;AAAA,IAC3B;AAAA,IACA,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC;AACH;AAEA,sBAAsB,qBACpB,YACkB;AAClB,SAAO,kBAAkB,OAAO,UAAU,CAAC;AAC7C;AAMA,sBAAsB,qBAAqB;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AACF,GAIqB;AACnB,QAAM,SAAS,MAAM,sBAAsB;AAAA,IACzC,SAAS,sBAAsB,aAAa;AAAA,IAC5C;AAAA,EACF,CAAC;AACD,SAAO,sBAAsB,OAAO;AACpC,SAAO,OAAO;AAChB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import {
|
|
3
|
+
CLAUDE_MD_END_MARKER,
|
|
4
|
+
CLAUDE_MD_START_MARKER,
|
|
5
|
+
claudeMdConvexSection
|
|
6
|
+
} from "../../codegen_templates/claudemd.js";
|
|
7
|
+
import { claudeMdPath } from "./paths.js";
|
|
8
|
+
import {
|
|
9
|
+
injectManagedSection,
|
|
10
|
+
stripManagedSection,
|
|
11
|
+
hasManagedSection,
|
|
12
|
+
removeMarkdownSection
|
|
13
|
+
} from "./utils.js";
|
|
14
|
+
function target(projectDir) {
|
|
15
|
+
return {
|
|
16
|
+
filePath: claudeMdPath(projectDir),
|
|
17
|
+
startMarker: CLAUDE_MD_START_MARKER,
|
|
18
|
+
endMarker: CLAUDE_MD_END_MARKER
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export async function injectClaudeMdSection({
|
|
22
|
+
section,
|
|
23
|
+
projectDir
|
|
24
|
+
}) {
|
|
25
|
+
return injectManagedSection({ ...target(projectDir), section });
|
|
26
|
+
}
|
|
27
|
+
export async function stripClaudeMdSection(projectDir) {
|
|
28
|
+
return stripManagedSection(target(projectDir));
|
|
29
|
+
}
|
|
30
|
+
export async function removeClaudeMdSection(projectDir) {
|
|
31
|
+
return removeMarkdownSection({
|
|
32
|
+
projectDir,
|
|
33
|
+
strip: stripClaudeMdSection,
|
|
34
|
+
fileName: "CLAUDE.md"
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export async function hasClaudeMdInstalled(projectDir) {
|
|
38
|
+
return hasManagedSection(target(projectDir));
|
|
39
|
+
}
|
|
40
|
+
export async function applyClaudeMdSection({
|
|
41
|
+
projectDir,
|
|
42
|
+
config,
|
|
43
|
+
convexDirName
|
|
44
|
+
}) {
|
|
45
|
+
const result = await injectClaudeMdSection({
|
|
46
|
+
section: claudeMdConvexSection(convexDirName),
|
|
47
|
+
projectDir
|
|
48
|
+
});
|
|
49
|
+
config.claudeMdHash = result.sectionHash;
|
|
50
|
+
return result.didWrite;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=claudemd.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/lib/aiFiles/claudemd.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n CLAUDE_MD_END_MARKER,\n CLAUDE_MD_START_MARKER,\n claudeMdConvexSection,\n} from \"../../codegen_templates/claudemd.js\";\nimport { claudeMdPath } from \"./paths.js\";\nimport { type AiFilesConfig } from \"./config.js\";\nimport {\n type ManagedSectionTarget,\n type InjectResult,\n type StripResult,\n injectManagedSection,\n stripManagedSection,\n hasManagedSection,\n removeMarkdownSection,\n} from \"./utils.js\";\n\nfunction target(projectDir?: string): ManagedSectionTarget {\n return {\n filePath: claudeMdPath(projectDir),\n startMarker: CLAUDE_MD_START_MARKER,\n endMarker: CLAUDE_MD_END_MARKER,\n };\n}\n\nexport async function injectClaudeMdSection({\n section,\n projectDir,\n}: {\n section: string;\n projectDir?: string;\n}): Promise<InjectResult> {\n return injectManagedSection({ ...target(projectDir), section });\n}\n\nexport async function stripClaudeMdSection(\n projectDir: string,\n): Promise<StripResult> {\n return stripManagedSection(target(projectDir));\n}\n\nexport async function removeClaudeMdSection(\n projectDir: string,\n): Promise<boolean> {\n return removeMarkdownSection({\n projectDir,\n strip: stripClaudeMdSection,\n fileName: \"CLAUDE.md\",\n });\n}\n\nexport async function hasClaudeMdInstalled(\n projectDir: string,\n): Promise<boolean> {\n return hasManagedSection(target(projectDir));\n}\n\n/**\n * Inject (or update) the Convex section in CLAUDE.md and record the hash.\n * Returns true if the file was actually written.\n */\nexport async function applyClaudeMdSection({\n projectDir,\n config,\n convexDirName,\n}: {\n projectDir: string;\n config: AiFilesConfig;\n convexDirName: string;\n}): Promise<boolean> {\n const result = await injectClaudeMdSection({\n section: claudeMdConvexSection(convexDirName),\n projectDir,\n });\n config.claudeMdHash = result.sectionHash;\n return result.didWrite;\n}\n"],
|
|
5
|
+
"mappings": ";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,oBAAoB;AAE7B;AAAA,EAIE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,OAAO,YAA2C;AACzD,SAAO;AAAA,IACL,UAAU,aAAa,UAAU;AAAA,IACjC,aAAa;AAAA,IACb,WAAW;AAAA,EACb;AACF;AAEA,sBAAsB,sBAAsB;AAAA,EAC1C;AAAA,EACA;AACF,GAG0B;AACxB,SAAO,qBAAqB,EAAE,GAAG,OAAO,UAAU,GAAG,QAAQ,CAAC;AAChE;AAEA,sBAAsB,qBACpB,YACsB;AACtB,SAAO,oBAAoB,OAAO,UAAU,CAAC;AAC/C;AAEA,sBAAsB,sBACpB,YACkB;AAClB,SAAO,sBAAsB;AAAA,IAC3B;AAAA,IACA,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC;AACH;AAEA,sBAAsB,qBACpB,YACkB;AAClB,SAAO,kBAAkB,OAAO,UAAU,CAAC;AAC7C;AAMA,sBAAsB,qBAAqB;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AACF,GAIqB;AACnB,QAAM,SAAS,MAAM,sBAAsB;AAAA,IACzC,SAAS,sBAAsB,aAAa;AAAA,IAC5C;AAAA,EACF,CAAC;AACD,SAAO,eAAe,OAAO;AAC7B,SAAO,OAAO;AAChB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -4,7 +4,8 @@ import { promises as fs } from "fs";
|
|
|
4
4
|
import path from "path";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { aiFilesStatePathForConvexDir } from "./paths.js";
|
|
7
|
-
|
|
7
|
+
import { iife, readFileSafe } from "./utils.js";
|
|
8
|
+
export const aiFilesStateSchema = z.object({
|
|
8
9
|
guidelinesHash: z.string().nullable(),
|
|
9
10
|
agentsMdSectionHash: z.string().nullable(),
|
|
10
11
|
claudeMdHash: z.string().nullable(),
|
|
@@ -17,10 +18,15 @@ const aiFilesStateSchema = z.object({
|
|
|
17
18
|
});
|
|
18
19
|
const aiFilesProjectConfigSchema = z.object({
|
|
19
20
|
aiFiles: z.object({
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
// `enabled` is the canonical field. When present it takes full
|
|
22
|
+
// precedence - `enabled: true` will re-enable even if the legacy
|
|
23
|
+
// disableStalenessMessage field is still `true` in the file.
|
|
24
|
+
enabled: z.boolean().optional(),
|
|
25
|
+
// @deprecated - use `enabled` instead. Read for backward compat;
|
|
26
|
+
// new writes always emit `enabled` and drop this key.
|
|
27
|
+
disableStalenessMessage: z.boolean().optional()
|
|
28
|
+
}).default({})
|
|
22
29
|
}).passthrough();
|
|
23
|
-
export const aiFilesSchema = aiFilesStateSchema;
|
|
24
30
|
const EMPTY_AI_STATE = {
|
|
25
31
|
guidelinesHash: null,
|
|
26
32
|
agentsMdSectionHash: null,
|
|
@@ -28,64 +34,85 @@ const EMPTY_AI_STATE = {
|
|
|
28
34
|
agentSkillsSha: null,
|
|
29
35
|
installedSkillNames: []
|
|
30
36
|
};
|
|
31
|
-
async function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
raw = await fs.readFile(path.join(projectDir, "convex.json"), "utf8");
|
|
35
|
-
} catch {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
37
|
+
async function readAiEnabledFromProjectConfig(projectDir) {
|
|
38
|
+
const raw = await readFileSafe(path.join(projectDir, "convex.json"));
|
|
39
|
+
if (raw === null) return true;
|
|
38
40
|
try {
|
|
39
41
|
const parsed = aiFilesProjectConfigSchema.parse(JSON.parse(raw));
|
|
40
|
-
return parsed.aiFiles.
|
|
42
|
+
if (parsed.aiFiles.enabled !== void 0) return parsed.aiFiles.enabled;
|
|
43
|
+
return !(parsed.aiFiles.disableStalenessMessage ?? false);
|
|
41
44
|
} catch (err) {
|
|
42
45
|
Sentry.captureException(err);
|
|
43
|
-
return
|
|
46
|
+
return true;
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
|
-
export async function
|
|
49
|
+
export async function writeAiEnabledToProjectConfig({
|
|
50
|
+
projectDir,
|
|
51
|
+
enabled
|
|
52
|
+
}) {
|
|
47
53
|
const filePath = path.join(projectDir, "convex.json");
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
const existing = await iife(async () => {
|
|
55
|
+
try {
|
|
56
|
+
return JSON.parse(await fs.readFile(filePath, "utf8"));
|
|
57
|
+
} catch {
|
|
58
|
+
return {};
|
|
59
|
+
}
|
|
60
|
+
});
|
|
53
61
|
const base = existing !== null && typeof existing === "object" && !Array.isArray(existing) ? existing : {};
|
|
54
62
|
const aiFilesValue = base.aiFiles !== null && typeof base.aiFiles === "object" && !Array.isArray(base.aiFiles) ? base.aiFiles : {};
|
|
55
63
|
const { $schema, ...rest } = base;
|
|
64
|
+
const { disableStalenessMessage: _legacy, ...restAiFiles } = aiFilesValue;
|
|
56
65
|
const next = {
|
|
57
66
|
$schema: $schema ?? "node_modules/convex/schemas/convex.schema.json",
|
|
58
67
|
...rest,
|
|
59
|
-
aiFiles: {
|
|
60
|
-
...aiFilesValue,
|
|
61
|
-
disableStalenessMessage
|
|
62
|
-
}
|
|
68
|
+
aiFiles: { ...restAiFiles, enabled }
|
|
63
69
|
};
|
|
64
70
|
await fs.writeFile(filePath, JSON.stringify(next, null, 2) + "\n", "utf8");
|
|
65
71
|
}
|
|
66
|
-
export async function readAiConfig(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
} catch {
|
|
75
|
-
return disableStalenessMessage ? { ...EMPTY_AI_STATE, disableStalenessMessage } : null;
|
|
72
|
+
export async function readAiConfig({
|
|
73
|
+
projectDir,
|
|
74
|
+
convexDir
|
|
75
|
+
}) {
|
|
76
|
+
const enabled = await readAiEnabledFromProjectConfig(projectDir);
|
|
77
|
+
const rawState = await readFileSafe(aiFilesStatePathForConvexDir(convexDir));
|
|
78
|
+
if (rawState === null) {
|
|
79
|
+
return !enabled ? { ...EMPTY_AI_STATE, enabled } : null;
|
|
76
80
|
}
|
|
77
81
|
try {
|
|
78
82
|
const state = aiFilesStateSchema.parse(JSON.parse(rawState));
|
|
79
|
-
return {
|
|
80
|
-
...state,
|
|
81
|
-
disableStalenessMessage
|
|
82
|
-
};
|
|
83
|
+
return { ...state, enabled };
|
|
83
84
|
} catch (err) {
|
|
84
85
|
Sentry.captureException(err);
|
|
85
86
|
return null;
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
|
-
export async function
|
|
89
|
+
export async function hasAiFilesConfig({
|
|
90
|
+
projectDir,
|
|
91
|
+
convexDir
|
|
92
|
+
}) {
|
|
93
|
+
if (!await readAiEnabledFromProjectConfig(projectDir)) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const rawState = await fs.readFile(
|
|
98
|
+
aiFilesStatePathForConvexDir(convexDir),
|
|
99
|
+
"utf8"
|
|
100
|
+
);
|
|
101
|
+
aiFilesStateSchema.parse(JSON.parse(rawState));
|
|
102
|
+
return true;
|
|
103
|
+
} catch (err) {
|
|
104
|
+
if (err.code !== "ENOENT") {
|
|
105
|
+
Sentry.captureException(err);
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export async function writeAiConfig({
|
|
111
|
+
config,
|
|
112
|
+
projectDir,
|
|
113
|
+
convexDir,
|
|
114
|
+
options
|
|
115
|
+
}) {
|
|
89
116
|
const state = aiFilesStateSchema.parse({
|
|
90
117
|
guidelinesHash: config.guidelinesHash,
|
|
91
118
|
agentsMdSectionHash: config.agentsMdSectionHash,
|
|
@@ -98,12 +125,11 @@ export async function writeAiConfig(config, projectDir, convexDir, options) {
|
|
|
98
125
|
JSON.stringify(state, null, 2) + "\n",
|
|
99
126
|
"utf8"
|
|
100
127
|
);
|
|
101
|
-
const persistMode = options?.
|
|
102
|
-
if (persistMode === "always" || persistMode === "
|
|
103
|
-
await
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
);
|
|
107
|
-
}
|
|
128
|
+
const persistMode = options?.persistEnabledPreference ?? "ifFalse";
|
|
129
|
+
if (persistMode === "always" || persistMode === "ifFalse" && !config.enabled)
|
|
130
|
+
await writeAiEnabledToProjectConfig({
|
|
131
|
+
projectDir,
|
|
132
|
+
enabled: config.enabled
|
|
133
|
+
});
|
|
108
134
|
}
|
|
109
135
|
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/lib/aiFiles/config.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 path from \"path\";\nimport { z } from \"zod\";\nimport { aiFilesStatePathForConvexDir } from \"./paths.js\";\nimport { iife, readFileSafe } 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 get-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 // Names of skills installed by `npx skills add`, used by `remove` to\n // only remove Convex-managed skills.\n installedSkillNames: z.array(z.string()).default([]),\n});\n\nconst aiFilesProjectConfigSchema = z\n .object({\n aiFiles: z\n .object({\n // `enabled` is the canonical field. When present it takes full\n // precedence - `enabled: true` will re-enable even if the legacy\n // disableStalenessMessage field is still `true` in the file.\n enabled: z.boolean().optional(),\n // @deprecated - use `enabled` instead. Read for backward compat;\n // new writes always emit `enabled` and drop this key.\n disableStalenessMessage: z.boolean().optional(),\n })\n .default({}),\n })\n .passthrough();\n\ntype AiFilesState = z.infer<typeof aiFilesStateSchema>;\nexport type AiFilesConfig = AiFilesState & {\n enabled: boolean;\n};\n\nconst EMPTY_AI_STATE: AiFilesState = {\n guidelinesHash: null,\n agentsMdSectionHash: null,\n claudeMdHash: null,\n agentSkillsSha: null,\n installedSkillNames: [],\n};\n\nasync function readAiEnabledFromProjectConfig(\n projectDir: string,\n): Promise<boolean> {\n const raw = await readFileSafe(path.join(projectDir, \"convex.json\"));\n if (raw === null) return true;\n try {\n const parsed = aiFilesProjectConfigSchema.parse(JSON.parse(raw));\n // `enabled` takes full precedence when explicitly set.\n if (parsed.aiFiles.enabled !== undefined) return parsed.aiFiles.enabled;\n // Legacy `disableStalenessMessage` - invert it.\n return !(parsed.aiFiles.disableStalenessMessage ?? false);\n } catch (err) {\n Sentry.captureException(err);\n return true;\n }\n}\n\nexport async function writeAiEnabledToProjectConfig({\n projectDir,\n enabled,\n}: {\n projectDir: string;\n enabled: boolean;\n}): Promise<void> {\n const filePath = path.join(projectDir, \"convex.json\");\n const existing = await iife(async () => {\n try {\n return JSON.parse(await fs.readFile(filePath, \"utf8\")) as unknown;\n } catch {\n return {} as unknown;\n }\n });\n const base =\n existing !== null &&\n typeof existing === \"object\" &&\n !Array.isArray(existing)\n ? (existing as Record<string, unknown>)\n : {};\n const aiFilesValue =\n base.aiFiles !== null &&\n typeof base.aiFiles === \"object\" &&\n !Array.isArray(base.aiFiles)\n ? (base.aiFiles as Record<string, unknown>)\n : {};\n const { $schema, ...rest } = base;\n // Remove legacy keys on every write.\n const { disableStalenessMessage: _legacy, ...restAiFiles } = aiFilesValue;\n const next: Record<string, unknown> = {\n $schema: $schema ?? \"node_modules/convex/schemas/convex.schema.json\",\n ...rest,\n aiFiles: { ...restAiFiles, enabled },\n };\n await fs.writeFile(filePath, JSON.stringify(next, null, 2) + \"\\n\", \"utf8\");\n}\n\nexport async function readAiConfig({\n projectDir,\n convexDir,\n}: {\n projectDir: string;\n convexDir: string;\n}): Promise<AiFilesConfig | null> {\n const enabled = await readAiEnabledFromProjectConfig(projectDir);\n const rawState = await readFileSafe(aiFilesStatePathForConvexDir(convexDir));\n if (rawState === null) {\n // No state file means AI files are not installed, unless the user has\n // explicitly disabled in convex.json.\n return !enabled ? { ...EMPTY_AI_STATE, enabled } : null;\n }\n try {\n const state = aiFilesStateSchema.parse(JSON.parse(rawState));\n return { ...state, enabled };\n } catch (err) {\n Sentry.captureException(err);\n return null;\n }\n}\n\nexport async function hasAiFilesConfig({\n projectDir,\n convexDir,\n}: {\n projectDir: string;\n convexDir: string;\n}): Promise<boolean> {\n if (!(await readAiEnabledFromProjectConfig(projectDir))) {\n return true;\n }\n try {\n const rawState = await fs.readFile(\n aiFilesStatePathForConvexDir(convexDir),\n \"utf8\",\n );\n aiFilesStateSchema.parse(JSON.parse(rawState));\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n Sentry.captureException(err);\n }\n return false;\n }\n}\n\nexport async function writeAiConfig({\n config,\n projectDir,\n convexDir,\n options,\n}: {\n config: AiFilesConfig;\n projectDir: string;\n convexDir: string;\n options?: { persistEnabledPreference?: \"ifFalse\" | \"always\" | \"never\" };\n}): Promise<void> {\n const state = aiFilesStateSchema.parse({\n guidelinesHash: config.guidelinesHash,\n agentsMdSectionHash: config.agentsMdSectionHash,\n claudeMdHash: config.claudeMdHash,\n agentSkillsSha: config.agentSkillsSha,\n installedSkillNames: config.installedSkillNames,\n });\n await fs.writeFile(\n aiFilesStatePathForConvexDir(convexDir),\n JSON.stringify(state, null, 2) + \"\\n\",\n \"utf8\",\n );\n\n const persistMode = options?.persistEnabledPreference ?? \"ifFalse\";\n if (\n persistMode === \"always\" ||\n (persistMode === \"ifFalse\" && !config.enabled)\n )\n await writeAiEnabledToProjectConfig({\n projectDir,\n enabled: config.enabled,\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { chalkStderr } from "chalk";
|
|
4
|
+
import { logMessage } from "../../../bundler/log.js";
|
|
5
|
+
import { safelyDeleteFile } from "./utils.js";
|
|
6
|
+
export async function removeLegacyCursorRulesFile(projectDir) {
|
|
7
|
+
const removed = await safelyDeleteFile(
|
|
8
|
+
path.join(projectDir, ".cursor", "rules", "convex_rules.mdc")
|
|
9
|
+
);
|
|
10
|
+
if (removed)
|
|
11
|
+
logMessage(
|
|
12
|
+
`${chalkStderr.green("\u2714")} Removed legacy .cursor/rules/convex_rules.mdc (superseded by convex/_generated/ai/guidelines.md).`
|
|
13
|
+
);
|
|
14
|
+
return removed;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=cursorrules.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/lib/aiFiles/cursorrules.ts"],
|
|
4
|
+
"sourcesContent": ["import path from \"path\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { safelyDeleteFile } from \"./utils.js\";\n\n/**\n * Remove the legacy `.cursor/rules/convex_rules.mdc` file if it exists.\n * This file was written by the old cursor rules auto-update feature (removed\n * in favour of the AI files system). We clean it up unconditionally\n * during `writeAiFiles`, `convex ai-files update`, and `convex ai-files remove`\n * since it was always auto-managed and is now superseded by\n * `convex/_generated/ai/guidelines.md`.\n */\nexport async function removeLegacyCursorRulesFile(\n projectDir: string,\n): Promise<boolean> {\n const removed = await safelyDeleteFile(\n path.join(projectDir, \".cursor\", \"rules\", \"convex_rules.mdc\"),\n );\n if (removed)\n logMessage(\n `${chalkStderr.green(\"\u2714\")} Removed legacy .cursor/rules/convex_rules.mdc (superseded by convex/_generated/ai/guidelines.md).`,\n );\n return removed;\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,OAAO,UAAU;AACjB,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,wBAAwB;AAUjC,sBAAsB,4BACpB,YACkB;AAClB,QAAM,UAAU,MAAM;AAAA,IACpB,KAAK,KAAK,YAAY,WAAW,SAAS,kBAAkB;AAAA,EAC9D;AACA,MAAI;AACF;AAAA,MACE,GAAG,YAAY,MAAM,QAAG,CAAC;AAAA,IAC3B;AACF,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { promises as fs } from "fs";
|
|
3
|
+
import { chalkStderr } from "chalk";
|
|
4
|
+
import { logMessage } from "../../../bundler/log.js";
|
|
5
|
+
import { downloadGuidelines } from "../versionApi.js";
|
|
6
|
+
import { hashSha256 } from "../utils/hash.js";
|
|
7
|
+
import { guidelinesPathForConvexDir } from "./paths.js";
|
|
8
|
+
import { readFileSafe } from "./utils.js";
|
|
9
|
+
export async function hasGuidelinesInstalled(convexDir) {
|
|
10
|
+
return await readFileSafe(guidelinesPathForConvexDir(convexDir)) !== null;
|
|
11
|
+
}
|
|
12
|
+
export async function installGuidelinesFile({
|
|
13
|
+
convexDir,
|
|
14
|
+
config
|
|
15
|
+
}) {
|
|
16
|
+
const guidelines = await downloadGuidelines();
|
|
17
|
+
if (guidelines === null) {
|
|
18
|
+
logMessage(
|
|
19
|
+
chalkStderr.yellow(
|
|
20
|
+
"Could not download Convex AI guidelines right now. You can retry with: npx convex ai-files install"
|
|
21
|
+
)
|
|
22
|
+
);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
await fs.writeFile(guidelinesPathForConvexDir(convexDir), guidelines, "utf8");
|
|
26
|
+
config.guidelinesHash = hashSha256(guidelines);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=guidelinesmd.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 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 { guidelinesPathForConvexDir } from \"./paths.js\";\nimport { readFileSafe } from \"./utils.js\";\nimport { type AiFilesConfig } from \"./config.js\";\n\nexport async function hasGuidelinesInstalled(\n convexDir: string,\n): Promise<boolean> {\n return (await readFileSafe(guidelinesPathForConvexDir(convexDir))) !== null;\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 config,\n}: {\n convexDir: string;\n config: AiFilesConfig;\n}): Promise<void> {\n const guidelines = await downloadGuidelines();\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;\n }\n\n await fs.writeFile(guidelinesPathForConvexDir(convexDir), guidelines, \"utf8\");\n config.guidelinesHash = hashSha256(guidelines);\n}\n"],
|
|
5
|
+
"mappings": ";AACA,SAAS,YAAY,UAAU;AAC/B,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAC3B,SAAS,kCAAkC;AAC3C,SAAS,oBAAoB;AAG7B,sBAAsB,uBACpB,WACkB;AAClB,SAAQ,MAAM,aAAa,2BAA2B,SAAS,CAAC,MAAO;AACzE;AAOA,sBAAsB,sBAAsB;AAAA,EAC1C;AAAA,EACA;AACF,GAGkB;AAChB,QAAM,aAAa,MAAM,mBAAmB;AAC5C,MAAI,eAAe,MAAM;AACvB;AAAA,MACE,YAAY;AAAA,QACV;AAAA,MACF;AAAA,IACF;AACA;AAAA,EACF;AAEA,QAAM,GAAG,UAAU,2BAA2B,SAAS,GAAG,YAAY,MAAM;AAC5E,SAAO,iBAAiB,WAAW,UAAU;AAC/C;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|