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
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import * as Sentry from "@sentry/node";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { Context } from "../../../bundler/context.js";
|
|
4
|
+
// eslint-disable-next-line no-restricted-imports
|
|
5
|
+
import { promises as fs } from "fs";
|
|
6
|
+
import { chalkStderr } from "chalk";
|
|
7
|
+
import { logMessage } from "../../../bundler/log.js";
|
|
8
|
+
import { promptYesNo } from "../utils/prompts.js";
|
|
9
|
+
import { type AiFilesPaths, aiDirForConvexDir } from "./paths.js";
|
|
10
|
+
import {
|
|
11
|
+
installGuidelinesFile,
|
|
12
|
+
hasGuidelinesInstalled,
|
|
13
|
+
} from "./guidelinesmd.js";
|
|
14
|
+
import {
|
|
15
|
+
type AiFilesConfig,
|
|
16
|
+
hasAiFilesConfig,
|
|
17
|
+
readAiConfig,
|
|
18
|
+
writeAiConfig,
|
|
19
|
+
writeAiEnabledToProjectConfig,
|
|
20
|
+
} from "./config.js";
|
|
21
|
+
import { isInInteractiveTerminal } from "./utils.js";
|
|
22
|
+
import {
|
|
23
|
+
hasAgentsMdInstalled,
|
|
24
|
+
applyAgentsMdSection,
|
|
25
|
+
removeAgentsMdSection,
|
|
26
|
+
} from "./agentsmd.js";
|
|
27
|
+
import {
|
|
28
|
+
hasClaudeMdInstalled,
|
|
29
|
+
applyClaudeMdSection,
|
|
30
|
+
removeClaudeMdSection,
|
|
31
|
+
} from "./claudemd.js";
|
|
32
|
+
import { installSkills, removeInstalledSkills } from "./skills.js";
|
|
33
|
+
import { removeLegacyCursorRulesFile as removeLegacyCursorRules } from "./cursorrules.js";
|
|
34
|
+
async function hasExistingAiFilesArtifacts({
|
|
35
|
+
projectDir,
|
|
36
|
+
convexDir,
|
|
37
|
+
}: AiFilesPaths): Promise<boolean> {
|
|
38
|
+
return (
|
|
39
|
+
(await hasGuidelinesInstalled(convexDir)) ||
|
|
40
|
+
(await hasAgentsMdInstalled(projectDir)) ||
|
|
41
|
+
(await hasClaudeMdInstalled(projectDir))
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Install or refresh all Convex AI files.
|
|
47
|
+
*
|
|
48
|
+
* Reads the existing config if present, or starts from a blank one for a
|
|
49
|
+
* fresh install. Each component can be individually skipped via the optional
|
|
50
|
+
* flags (all default to true).
|
|
51
|
+
*/
|
|
52
|
+
export async function installAiFiles({
|
|
53
|
+
projectDir,
|
|
54
|
+
convexDir,
|
|
55
|
+
shouldWriteGuidelines = true,
|
|
56
|
+
shouldWriteAgentsMd = true,
|
|
57
|
+
shouldWriteClaudeMd = true,
|
|
58
|
+
shouldWriteSkills = true,
|
|
59
|
+
}: AiFilesPaths & {
|
|
60
|
+
shouldWriteGuidelines?: boolean;
|
|
61
|
+
shouldWriteAgentsMd?: boolean;
|
|
62
|
+
shouldWriteClaudeMd?: boolean;
|
|
63
|
+
shouldWriteSkills?: boolean;
|
|
64
|
+
}): Promise<void> {
|
|
65
|
+
await fs.mkdir(aiDirForConvexDir(convexDir), { recursive: true });
|
|
66
|
+
|
|
67
|
+
const config: AiFilesConfig = (await readAiConfig({
|
|
68
|
+
projectDir,
|
|
69
|
+
convexDir,
|
|
70
|
+
})) ?? {
|
|
71
|
+
enabled: true,
|
|
72
|
+
guidelinesHash: null,
|
|
73
|
+
agentsMdSectionHash: null,
|
|
74
|
+
claudeMdHash: null,
|
|
75
|
+
agentSkillsSha: null,
|
|
76
|
+
installedSkillNames: [],
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
if (shouldWriteGuidelines) await installGuidelinesFile({ convexDir, config });
|
|
80
|
+
|
|
81
|
+
const convexDirName = path.relative(projectDir, convexDir);
|
|
82
|
+
|
|
83
|
+
if (shouldWriteAgentsMd)
|
|
84
|
+
await applyAgentsMdSection({ projectDir, config, convexDirName });
|
|
85
|
+
|
|
86
|
+
if (shouldWriteClaudeMd)
|
|
87
|
+
await applyClaudeMdSection({ projectDir, config, convexDirName });
|
|
88
|
+
|
|
89
|
+
if (shouldWriteSkills) await installSkills({ projectDir, config });
|
|
90
|
+
|
|
91
|
+
await removeLegacyCursorRules(projectDir);
|
|
92
|
+
await writeAiConfig({ config, projectDir, convexDir });
|
|
93
|
+
|
|
94
|
+
logMessage(`${chalkStderr.green("✔")} Convex AI files installed.`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function attemptToInstallAiFiles(
|
|
98
|
+
opts: Parameters<typeof installAiFiles>[0],
|
|
99
|
+
): Promise<void> {
|
|
100
|
+
try {
|
|
101
|
+
await installAiFiles(opts);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
Sentry.captureException(error);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
type AiFilesStalenessStatus =
|
|
108
|
+
| "not-installed" // no config AND no artifacts — show install nag
|
|
109
|
+
| "has-artifacts" // no config but files exist on disk (e.g. fresh checkout) — stay quiet
|
|
110
|
+
| "disabled" // user opted out of nag messages
|
|
111
|
+
| "stale" // one or more files are out of date
|
|
112
|
+
| "up-to-date"; // everything looks fine
|
|
113
|
+
|
|
114
|
+
async function determineAiFilesStaleness({
|
|
115
|
+
canonicalGuidelinesHash,
|
|
116
|
+
canonicalAgentSkillsSha,
|
|
117
|
+
projectDir,
|
|
118
|
+
convexDir,
|
|
119
|
+
}: {
|
|
120
|
+
canonicalGuidelinesHash: string | null;
|
|
121
|
+
canonicalAgentSkillsSha: string | null;
|
|
122
|
+
} & AiFilesPaths): Promise<AiFilesStalenessStatus> {
|
|
123
|
+
const config = await readAiConfig({ projectDir, convexDir });
|
|
124
|
+
|
|
125
|
+
if (config === null) {
|
|
126
|
+
const hasArtifacts = await hasExistingAiFilesArtifacts({
|
|
127
|
+
projectDir,
|
|
128
|
+
convexDir,
|
|
129
|
+
});
|
|
130
|
+
return hasArtifacts ? "has-artifacts" : "not-installed";
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!config.enabled) return "disabled";
|
|
134
|
+
|
|
135
|
+
if (canonicalGuidelinesHash === null && canonicalAgentSkillsSha === null)
|
|
136
|
+
return "up-to-date";
|
|
137
|
+
|
|
138
|
+
const guidelinesStale =
|
|
139
|
+
canonicalGuidelinesHash !== null &&
|
|
140
|
+
config.guidelinesHash !== null &&
|
|
141
|
+
config.guidelinesHash !== canonicalGuidelinesHash;
|
|
142
|
+
|
|
143
|
+
const skillsStale =
|
|
144
|
+
canonicalAgentSkillsSha !== null &&
|
|
145
|
+
config.agentSkillsSha !== null &&
|
|
146
|
+
config.agentSkillsSha !== canonicalAgentSkillsSha;
|
|
147
|
+
|
|
148
|
+
return guidelinesStale || skillsStale ? "stale" : "up-to-date";
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Check whether the Convex AI files are out of date and log a nag message
|
|
153
|
+
* if so.
|
|
154
|
+
*/
|
|
155
|
+
export async function checkAiFilesStaleness(
|
|
156
|
+
opts: {
|
|
157
|
+
canonicalGuidelinesHash: string | null;
|
|
158
|
+
canonicalAgentSkillsSha: string | null;
|
|
159
|
+
} & AiFilesPaths,
|
|
160
|
+
): Promise<void> {
|
|
161
|
+
const status = await determineAiFilesStaleness(opts);
|
|
162
|
+
|
|
163
|
+
if (status === "not-installed") {
|
|
164
|
+
logMessage(
|
|
165
|
+
chalkStderr.yellow(
|
|
166
|
+
`Convex AI files are not installed. Run ${chalkStderr.bold(`npx convex ai-files install`)} to get started or ${chalkStderr.bold(`npx convex ai-files disable`)} to hide this message.`,
|
|
167
|
+
),
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (status === "stale") {
|
|
172
|
+
logMessage(
|
|
173
|
+
chalkStderr.yellow(
|
|
174
|
+
`Your Convex AI files are out of date. Run ${chalkStderr.bold(`npx convex ai-files update`)} to get the latest.`,
|
|
175
|
+
),
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export async function enableAiFiles({
|
|
181
|
+
projectDir,
|
|
182
|
+
convexDir,
|
|
183
|
+
}: AiFilesPaths): Promise<void> {
|
|
184
|
+
await installAiFiles({ projectDir, convexDir });
|
|
185
|
+
const config = await readAiConfig({ projectDir, convexDir });
|
|
186
|
+
if (config === null) return;
|
|
187
|
+
config.enabled = true;
|
|
188
|
+
await writeAiConfig({
|
|
189
|
+
config,
|
|
190
|
+
projectDir,
|
|
191
|
+
convexDir,
|
|
192
|
+
options: { persistEnabledPreference: "always" },
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Remove all Convex AI files from the project.
|
|
198
|
+
* Called by `npx convex ai-files remove`.
|
|
199
|
+
*/
|
|
200
|
+
export async function removeAiFiles({
|
|
201
|
+
projectDir,
|
|
202
|
+
convexDir,
|
|
203
|
+
}: AiFilesPaths): Promise<void> {
|
|
204
|
+
const config = await readAiConfig({ projectDir, convexDir });
|
|
205
|
+
if (config === null) {
|
|
206
|
+
logMessage("No Convex AI files found — nothing to remove.");
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const removals = [
|
|
211
|
+
await removeAgentsMdSection(projectDir),
|
|
212
|
+
await removeClaudeMdSection(projectDir),
|
|
213
|
+
await removeInstalledSkills({
|
|
214
|
+
projectDir,
|
|
215
|
+
skillNames: config.installedSkillNames,
|
|
216
|
+
}),
|
|
217
|
+
await removeLegacyCursorRules(projectDir),
|
|
218
|
+
await attemptToDeleteAiDir({ projectDir, convexDir }),
|
|
219
|
+
];
|
|
220
|
+
|
|
221
|
+
if (removals.some(Boolean)) logMessage("Convex AI files removed.");
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Called by `npx convex ai-files disable`.
|
|
226
|
+
*
|
|
227
|
+
* Writes a suppression flag into `convex.json` so `npx convex dev` stops
|
|
228
|
+
* showing AI files install/staleness messages. Files are left in place.
|
|
229
|
+
*/
|
|
230
|
+
export async function safelyAttemptToDisableAiFiles(
|
|
231
|
+
projectDir: string,
|
|
232
|
+
): Promise<void> {
|
|
233
|
+
try {
|
|
234
|
+
await writeAiEnabledToProjectConfig({
|
|
235
|
+
projectDir,
|
|
236
|
+
enabled: false,
|
|
237
|
+
});
|
|
238
|
+
logMessage(
|
|
239
|
+
`${chalkStderr.green(`✔`)} Convex AI files disabled. Run ${chalkStderr.bold(`npx convex ai-files enable`)} to re-enable.`,
|
|
240
|
+
);
|
|
241
|
+
} catch (error) {
|
|
242
|
+
Sentry.captureException(error);
|
|
243
|
+
logMessage(
|
|
244
|
+
chalkStderr.yellow(
|
|
245
|
+
"Could not write AI message suppression config. Message may reappear.",
|
|
246
|
+
),
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async function attemptToDeleteAiDir({
|
|
252
|
+
projectDir,
|
|
253
|
+
convexDir,
|
|
254
|
+
}: AiFilesPaths): Promise<boolean> {
|
|
255
|
+
const aiDir = aiDirForConvexDir(convexDir);
|
|
256
|
+
const relPath = path.relative(projectDir, aiDir);
|
|
257
|
+
try {
|
|
258
|
+
await fs.rm(aiDir, { recursive: true, force: true });
|
|
259
|
+
logMessage(`${chalkStderr.green("✔")} Deleted ${relPath}/`);
|
|
260
|
+
return true;
|
|
261
|
+
} catch (error) {
|
|
262
|
+
Sentry.captureException(error);
|
|
263
|
+
logMessage(
|
|
264
|
+
chalkStderr.yellow(`Could not delete ${relPath}/. Remove it manually.`),
|
|
265
|
+
);
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async function hasAiFilesBeenInstalledBefore({
|
|
271
|
+
projectDir,
|
|
272
|
+
convexDir,
|
|
273
|
+
}: AiFilesPaths): Promise<boolean> {
|
|
274
|
+
return (
|
|
275
|
+
(await hasAiFilesConfig({ projectDir, convexDir })) ||
|
|
276
|
+
(await hasExistingAiFilesArtifacts({ projectDir, convexDir }))
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export async function maybeSetupAiFiles({
|
|
281
|
+
ctx,
|
|
282
|
+
convexDir,
|
|
283
|
+
projectDir,
|
|
284
|
+
}: {
|
|
285
|
+
ctx: Context;
|
|
286
|
+
} & AiFilesPaths): Promise<void> {
|
|
287
|
+
if (!isInInteractiveTerminal()) return;
|
|
288
|
+
|
|
289
|
+
const config = await readAiConfig({ projectDir, convexDir });
|
|
290
|
+
if (config !== null && !config.enabled) return;
|
|
291
|
+
|
|
292
|
+
if (await hasAiFilesBeenInstalledBefore({ projectDir, convexDir })) {
|
|
293
|
+
await attemptToInstallAiFiles({ projectDir, convexDir });
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const shouldInstall = await promptYesNo(ctx, {
|
|
298
|
+
message: "Set up Convex AI files? (guidelines, AGENTS.md, agent skills)",
|
|
299
|
+
default: true,
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
if (shouldInstall) await attemptToInstallAiFiles({ projectDir, convexDir });
|
|
303
|
+
}
|