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,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import * as Sentry from "@sentry/node";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { promises as fs } from "fs";
|
|
5
|
+
import { chalkStderr } from "chalk";
|
|
6
|
+
import { logMessage } from "../../../bundler/log.js";
|
|
7
|
+
import { promptYesNo } from "../utils/prompts.js";
|
|
8
|
+
import { aiDirForConvexDir } from "./paths.js";
|
|
9
|
+
import {
|
|
10
|
+
installGuidelinesFile,
|
|
11
|
+
hasGuidelinesInstalled
|
|
12
|
+
} from "./guidelinesmd.js";
|
|
13
|
+
import {
|
|
14
|
+
hasAiFilesConfig,
|
|
15
|
+
readAiConfig,
|
|
16
|
+
writeAiConfig,
|
|
17
|
+
writeAiEnabledToProjectConfig
|
|
18
|
+
} from "./config.js";
|
|
19
|
+
import { isInInteractiveTerminal } from "./utils.js";
|
|
20
|
+
import {
|
|
21
|
+
hasAgentsMdInstalled,
|
|
22
|
+
applyAgentsMdSection,
|
|
23
|
+
removeAgentsMdSection
|
|
24
|
+
} from "./agentsmd.js";
|
|
25
|
+
import {
|
|
26
|
+
hasClaudeMdInstalled,
|
|
27
|
+
applyClaudeMdSection,
|
|
28
|
+
removeClaudeMdSection
|
|
29
|
+
} from "./claudemd.js";
|
|
30
|
+
import { installSkills, removeInstalledSkills } from "./skills.js";
|
|
31
|
+
import { removeLegacyCursorRulesFile as removeLegacyCursorRules } from "./cursorrules.js";
|
|
32
|
+
async function hasExistingAiFilesArtifacts({
|
|
33
|
+
projectDir,
|
|
34
|
+
convexDir
|
|
35
|
+
}) {
|
|
36
|
+
return await hasGuidelinesInstalled(convexDir) || await hasAgentsMdInstalled(projectDir) || await hasClaudeMdInstalled(projectDir);
|
|
37
|
+
}
|
|
38
|
+
export async function installAiFiles({
|
|
39
|
+
projectDir,
|
|
40
|
+
convexDir,
|
|
41
|
+
shouldWriteGuidelines = true,
|
|
42
|
+
shouldWriteAgentsMd = true,
|
|
43
|
+
shouldWriteClaudeMd = true,
|
|
44
|
+
shouldWriteSkills = true
|
|
45
|
+
}) {
|
|
46
|
+
await fs.mkdir(aiDirForConvexDir(convexDir), { recursive: true });
|
|
47
|
+
const config = await readAiConfig({
|
|
48
|
+
projectDir,
|
|
49
|
+
convexDir
|
|
50
|
+
}) ?? {
|
|
51
|
+
enabled: true,
|
|
52
|
+
guidelinesHash: null,
|
|
53
|
+
agentsMdSectionHash: null,
|
|
54
|
+
claudeMdHash: null,
|
|
55
|
+
agentSkillsSha: null,
|
|
56
|
+
installedSkillNames: []
|
|
57
|
+
};
|
|
58
|
+
if (shouldWriteGuidelines) await installGuidelinesFile({ convexDir, config });
|
|
59
|
+
const convexDirName = path.relative(projectDir, convexDir);
|
|
60
|
+
if (shouldWriteAgentsMd)
|
|
61
|
+
await applyAgentsMdSection({ projectDir, config, convexDirName });
|
|
62
|
+
if (shouldWriteClaudeMd)
|
|
63
|
+
await applyClaudeMdSection({ projectDir, config, convexDirName });
|
|
64
|
+
if (shouldWriteSkills) await installSkills({ projectDir, config });
|
|
65
|
+
await removeLegacyCursorRules(projectDir);
|
|
66
|
+
await writeAiConfig({ config, projectDir, convexDir });
|
|
67
|
+
logMessage(`${chalkStderr.green("\u2714")} Convex AI files installed.`);
|
|
68
|
+
}
|
|
69
|
+
async function attemptToInstallAiFiles(opts) {
|
|
70
|
+
try {
|
|
71
|
+
await installAiFiles(opts);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
Sentry.captureException(error);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function determineAiFilesStaleness({
|
|
77
|
+
canonicalGuidelinesHash,
|
|
78
|
+
canonicalAgentSkillsSha,
|
|
79
|
+
projectDir,
|
|
80
|
+
convexDir
|
|
81
|
+
}) {
|
|
82
|
+
const config = await readAiConfig({ projectDir, convexDir });
|
|
83
|
+
if (config === null) {
|
|
84
|
+
const hasArtifacts = await hasExistingAiFilesArtifacts({
|
|
85
|
+
projectDir,
|
|
86
|
+
convexDir
|
|
87
|
+
});
|
|
88
|
+
return hasArtifacts ? "has-artifacts" : "not-installed";
|
|
89
|
+
}
|
|
90
|
+
if (!config.enabled) return "disabled";
|
|
91
|
+
if (canonicalGuidelinesHash === null && canonicalAgentSkillsSha === null)
|
|
92
|
+
return "up-to-date";
|
|
93
|
+
const guidelinesStale = canonicalGuidelinesHash !== null && config.guidelinesHash !== null && config.guidelinesHash !== canonicalGuidelinesHash;
|
|
94
|
+
const skillsStale = canonicalAgentSkillsSha !== null && config.agentSkillsSha !== null && config.agentSkillsSha !== canonicalAgentSkillsSha;
|
|
95
|
+
return guidelinesStale || skillsStale ? "stale" : "up-to-date";
|
|
96
|
+
}
|
|
97
|
+
export async function checkAiFilesStaleness(opts) {
|
|
98
|
+
const status = await determineAiFilesStaleness(opts);
|
|
99
|
+
if (status === "not-installed") {
|
|
100
|
+
logMessage(
|
|
101
|
+
chalkStderr.yellow(
|
|
102
|
+
`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.`
|
|
103
|
+
)
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
if (status === "stale") {
|
|
107
|
+
logMessage(
|
|
108
|
+
chalkStderr.yellow(
|
|
109
|
+
`Your Convex AI files are out of date. Run ${chalkStderr.bold(`npx convex ai-files update`)} to get the latest.`
|
|
110
|
+
)
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export async function enableAiFiles({
|
|
115
|
+
projectDir,
|
|
116
|
+
convexDir
|
|
117
|
+
}) {
|
|
118
|
+
await installAiFiles({ projectDir, convexDir });
|
|
119
|
+
const config = await readAiConfig({ projectDir, convexDir });
|
|
120
|
+
if (config === null) return;
|
|
121
|
+
config.enabled = true;
|
|
122
|
+
await writeAiConfig({
|
|
123
|
+
config,
|
|
124
|
+
projectDir,
|
|
125
|
+
convexDir,
|
|
126
|
+
options: { persistEnabledPreference: "always" }
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
export async function removeAiFiles({
|
|
130
|
+
projectDir,
|
|
131
|
+
convexDir
|
|
132
|
+
}) {
|
|
133
|
+
const config = await readAiConfig({ projectDir, convexDir });
|
|
134
|
+
if (config === null) {
|
|
135
|
+
logMessage("No Convex AI files found \u2014 nothing to remove.");
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const removals = [
|
|
139
|
+
await removeAgentsMdSection(projectDir),
|
|
140
|
+
await removeClaudeMdSection(projectDir),
|
|
141
|
+
await removeInstalledSkills({
|
|
142
|
+
projectDir,
|
|
143
|
+
skillNames: config.installedSkillNames
|
|
144
|
+
}),
|
|
145
|
+
await removeLegacyCursorRules(projectDir),
|
|
146
|
+
await attemptToDeleteAiDir({ projectDir, convexDir })
|
|
147
|
+
];
|
|
148
|
+
if (removals.some(Boolean)) logMessage("Convex AI files removed.");
|
|
149
|
+
}
|
|
150
|
+
export async function safelyAttemptToDisableAiFiles(projectDir) {
|
|
151
|
+
try {
|
|
152
|
+
await writeAiEnabledToProjectConfig({
|
|
153
|
+
projectDir,
|
|
154
|
+
enabled: false
|
|
155
|
+
});
|
|
156
|
+
logMessage(
|
|
157
|
+
`${chalkStderr.green(`\u2714`)} Convex AI files disabled. Run ${chalkStderr.bold(`npx convex ai-files enable`)} to re-enable.`
|
|
158
|
+
);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
Sentry.captureException(error);
|
|
161
|
+
logMessage(
|
|
162
|
+
chalkStderr.yellow(
|
|
163
|
+
"Could not write AI message suppression config. Message may reappear."
|
|
164
|
+
)
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async function attemptToDeleteAiDir({
|
|
169
|
+
projectDir,
|
|
170
|
+
convexDir
|
|
171
|
+
}) {
|
|
172
|
+
const aiDir = aiDirForConvexDir(convexDir);
|
|
173
|
+
const relPath = path.relative(projectDir, aiDir);
|
|
174
|
+
try {
|
|
175
|
+
await fs.rm(aiDir, { recursive: true, force: true });
|
|
176
|
+
logMessage(`${chalkStderr.green("\u2714")} Deleted ${relPath}/`);
|
|
177
|
+
return true;
|
|
178
|
+
} catch (error) {
|
|
179
|
+
Sentry.captureException(error);
|
|
180
|
+
logMessage(
|
|
181
|
+
chalkStderr.yellow(`Could not delete ${relPath}/. Remove it manually.`)
|
|
182
|
+
);
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async function hasAiFilesBeenInstalledBefore({
|
|
187
|
+
projectDir,
|
|
188
|
+
convexDir
|
|
189
|
+
}) {
|
|
190
|
+
return await hasAiFilesConfig({ projectDir, convexDir }) || await hasExistingAiFilesArtifacts({ projectDir, convexDir });
|
|
191
|
+
}
|
|
192
|
+
export async function maybeSetupAiFiles({
|
|
193
|
+
ctx,
|
|
194
|
+
convexDir,
|
|
195
|
+
projectDir
|
|
196
|
+
}) {
|
|
197
|
+
if (!isInInteractiveTerminal()) return;
|
|
198
|
+
const config = await readAiConfig({ projectDir, convexDir });
|
|
199
|
+
if (config !== null && !config.enabled) return;
|
|
200
|
+
if (await hasAiFilesBeenInstalledBefore({ projectDir, convexDir })) {
|
|
201
|
+
await attemptToInstallAiFiles({ projectDir, convexDir });
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const shouldInstall = await promptYesNo(ctx, {
|
|
205
|
+
message: "Set up Convex AI files? (guidelines, AGENTS.md, agent skills)",
|
|
206
|
+
default: true
|
|
207
|
+
});
|
|
208
|
+
if (shouldInstall) await attemptToInstallAiFiles({ projectDir, convexDir });
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/lib/aiFiles/index.ts"],
|
|
4
|
+
"sourcesContent": ["import * as Sentry from \"@sentry/node\";\nimport path from \"path\";\nimport { Context } from \"../../../bundler/context.js\";\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { promptYesNo } from \"../utils/prompts.js\";\nimport { type AiFilesPaths, aiDirForConvexDir } from \"./paths.js\";\nimport {\n installGuidelinesFile,\n hasGuidelinesInstalled,\n} from \"./guidelinesmd.js\";\nimport {\n type AiFilesConfig,\n hasAiFilesConfig,\n readAiConfig,\n writeAiConfig,\n writeAiEnabledToProjectConfig,\n} from \"./config.js\";\nimport { isInInteractiveTerminal } from \"./utils.js\";\nimport {\n hasAgentsMdInstalled,\n applyAgentsMdSection,\n removeAgentsMdSection,\n} from \"./agentsmd.js\";\nimport {\n hasClaudeMdInstalled,\n applyClaudeMdSection,\n removeClaudeMdSection,\n} from \"./claudemd.js\";\nimport { installSkills, removeInstalledSkills } from \"./skills.js\";\nimport { removeLegacyCursorRulesFile as removeLegacyCursorRules } from \"./cursorrules.js\";\nasync function hasExistingAiFilesArtifacts({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<boolean> {\n return (\n (await hasGuidelinesInstalled(convexDir)) ||\n (await hasAgentsMdInstalled(projectDir)) ||\n (await hasClaudeMdInstalled(projectDir))\n );\n}\n\n/**\n * Install or refresh all Convex AI files.\n *\n * Reads the existing config if present, or starts from a blank one for a\n * fresh install. Each component can be individually skipped via the optional\n * flags (all default to true).\n */\nexport async function installAiFiles({\n projectDir,\n convexDir,\n shouldWriteGuidelines = true,\n shouldWriteAgentsMd = true,\n shouldWriteClaudeMd = true,\n shouldWriteSkills = true,\n}: AiFilesPaths & {\n shouldWriteGuidelines?: boolean;\n shouldWriteAgentsMd?: boolean;\n shouldWriteClaudeMd?: boolean;\n shouldWriteSkills?: boolean;\n}): Promise<void> {\n await fs.mkdir(aiDirForConvexDir(convexDir), { recursive: true });\n\n const config: AiFilesConfig = (await readAiConfig({\n projectDir,\n convexDir,\n })) ?? {\n enabled: true,\n guidelinesHash: null,\n agentsMdSectionHash: null,\n claudeMdHash: null,\n agentSkillsSha: null,\n installedSkillNames: [],\n };\n\n if (shouldWriteGuidelines) await installGuidelinesFile({ convexDir, config });\n\n const convexDirName = path.relative(projectDir, convexDir);\n\n if (shouldWriteAgentsMd)\n await applyAgentsMdSection({ projectDir, config, convexDirName });\n\n if (shouldWriteClaudeMd)\n await applyClaudeMdSection({ projectDir, config, convexDirName });\n\n if (shouldWriteSkills) await installSkills({ projectDir, config });\n\n await removeLegacyCursorRules(projectDir);\n await writeAiConfig({ config, projectDir, convexDir });\n\n logMessage(`${chalkStderr.green(\"\u2714\")} Convex AI files installed.`);\n}\n\nasync function attemptToInstallAiFiles(\n opts: Parameters<typeof installAiFiles>[0],\n): Promise<void> {\n try {\n await installAiFiles(opts);\n } catch (error) {\n Sentry.captureException(error);\n }\n}\n\ntype AiFilesStalenessStatus =\n | \"not-installed\" // no config AND no artifacts \u2014 show install nag\n | \"has-artifacts\" // no config but files exist on disk (e.g. fresh checkout) \u2014 stay quiet\n | \"disabled\" // user opted out of nag messages\n | \"stale\" // one or more files are out of date\n | \"up-to-date\"; // everything looks fine\n\nasync function determineAiFilesStaleness({\n canonicalGuidelinesHash,\n canonicalAgentSkillsSha,\n projectDir,\n convexDir,\n}: {\n canonicalGuidelinesHash: string | null;\n canonicalAgentSkillsSha: string | null;\n} & AiFilesPaths): Promise<AiFilesStalenessStatus> {\n const config = await readAiConfig({ projectDir, convexDir });\n\n if (config === null) {\n const hasArtifacts = await hasExistingAiFilesArtifacts({\n projectDir,\n convexDir,\n });\n return hasArtifacts ? \"has-artifacts\" : \"not-installed\";\n }\n\n if (!config.enabled) return \"disabled\";\n\n if (canonicalGuidelinesHash === null && canonicalAgentSkillsSha === null)\n return \"up-to-date\";\n\n const guidelinesStale =\n canonicalGuidelinesHash !== null &&\n config.guidelinesHash !== null &&\n config.guidelinesHash !== canonicalGuidelinesHash;\n\n const skillsStale =\n canonicalAgentSkillsSha !== null &&\n config.agentSkillsSha !== null &&\n config.agentSkillsSha !== canonicalAgentSkillsSha;\n\n return guidelinesStale || skillsStale ? \"stale\" : \"up-to-date\";\n}\n\n/**\n * Check whether the Convex AI files are out of date and log a nag message\n * if so.\n */\nexport async function checkAiFilesStaleness(\n opts: {\n canonicalGuidelinesHash: string | null;\n canonicalAgentSkillsSha: string | null;\n } & AiFilesPaths,\n): Promise<void> {\n const status = await determineAiFilesStaleness(opts);\n\n if (status === \"not-installed\") {\n logMessage(\n chalkStderr.yellow(\n `Convex AI files are not installed. Run ${chalkStderr.bold(`npx convex ai-files install`)} to get started or ${chalkStderr.bold(`npx convex ai-files disable`)} to hide this message.`,\n ),\n );\n }\n\n if (status === \"stale\") {\n logMessage(\n chalkStderr.yellow(\n `Your Convex AI files are out of date. Run ${chalkStderr.bold(`npx convex ai-files update`)} to get the latest.`,\n ),\n );\n }\n}\n\nexport async function enableAiFiles({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<void> {\n await installAiFiles({ projectDir, convexDir });\n const config = await readAiConfig({ projectDir, convexDir });\n if (config === null) return;\n config.enabled = true;\n await writeAiConfig({\n config,\n projectDir,\n convexDir,\n options: { persistEnabledPreference: \"always\" },\n });\n}\n\n/**\n * Remove all Convex AI files from the project.\n * Called by `npx convex ai-files remove`.\n */\nexport async function removeAiFiles({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<void> {\n const config = await readAiConfig({ projectDir, convexDir });\n if (config === null) {\n logMessage(\"No Convex AI files found \u2014 nothing to remove.\");\n return;\n }\n\n const removals = [\n await removeAgentsMdSection(projectDir),\n await removeClaudeMdSection(projectDir),\n await removeInstalledSkills({\n projectDir,\n skillNames: config.installedSkillNames,\n }),\n await removeLegacyCursorRules(projectDir),\n await attemptToDeleteAiDir({ projectDir, convexDir }),\n ];\n\n if (removals.some(Boolean)) logMessage(\"Convex AI files removed.\");\n}\n\n/**\n * Called by `npx convex ai-files disable`.\n *\n * Writes a suppression flag into `convex.json` so `npx convex dev` stops\n * showing AI files install/staleness messages. Files are left in place.\n */\nexport async function safelyAttemptToDisableAiFiles(\n projectDir: string,\n): Promise<void> {\n try {\n await writeAiEnabledToProjectConfig({\n projectDir,\n enabled: false,\n });\n logMessage(\n `${chalkStderr.green(`\u2714`)} Convex AI files disabled. Run ${chalkStderr.bold(`npx convex ai-files enable`)} to re-enable.`,\n );\n } catch (error) {\n Sentry.captureException(error);\n logMessage(\n chalkStderr.yellow(\n \"Could not write AI message suppression config. Message may reappear.\",\n ),\n );\n }\n}\n\nasync function attemptToDeleteAiDir({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<boolean> {\n const aiDir = aiDirForConvexDir(convexDir);\n const relPath = path.relative(projectDir, aiDir);\n try {\n await fs.rm(aiDir, { recursive: true, force: true });\n logMessage(`${chalkStderr.green(\"\u2714\")} Deleted ${relPath}/`);\n return true;\n } catch (error) {\n Sentry.captureException(error);\n logMessage(\n chalkStderr.yellow(`Could not delete ${relPath}/. Remove it manually.`),\n );\n return false;\n }\n}\n\nasync function hasAiFilesBeenInstalledBefore({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<boolean> {\n return (\n (await hasAiFilesConfig({ projectDir, convexDir })) ||\n (await hasExistingAiFilesArtifacts({ projectDir, convexDir }))\n );\n}\n\nexport async function maybeSetupAiFiles({\n ctx,\n convexDir,\n projectDir,\n}: {\n ctx: Context;\n} & AiFilesPaths): Promise<void> {\n if (!isInInteractiveTerminal()) return;\n\n const config = await readAiConfig({ projectDir, convexDir });\n if (config !== null && !config.enabled) return;\n\n if (await hasAiFilesBeenInstalledBefore({ projectDir, convexDir })) {\n await attemptToInstallAiFiles({ projectDir, convexDir });\n return;\n }\n\n const shouldInstall = await promptYesNo(ctx, {\n message: \"Set up Convex AI files? (guidelines, AGENTS.md, agent skills)\",\n default: true,\n });\n\n if (shouldInstall) await attemptToInstallAiFiles({ projectDir, convexDir });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/lib/aiFiles/paths.ts"],
|
|
4
|
+
"sourcesContent": ["import path from \"path\";\n\nexport type AiFilesPaths = {\n projectDir: string;\n convexDir: string;\n};\n\nconst AI_FILES_PARENT_DIR = \"_generated\";\nconst AI_FILES_DIR = \"ai\";\n\nexport function aiDirForConvexDir(convexDir: string): string {\n return path.join(convexDir, AI_FILES_PARENT_DIR, AI_FILES_DIR);\n}\n\nexport function guidelinesPathForConvexDir(convexDir: string): string {\n return path.join(aiDirForConvexDir(convexDir), \"guidelines.md\");\n}\n\nexport function aiFilesStatePathForConvexDir(convexDir: string): string {\n return path.join(aiDirForConvexDir(convexDir), \"ai-files.state.json\");\n}\n\nexport function agentsMdPath(projectDir?: string): string {\n return path.join(projectDir ?? process.cwd(), \"AGENTS.md\");\n}\n\nexport function claudeMdPath(projectDir?: string): string {\n return path.join(projectDir ?? process.cwd(), \"CLAUDE.md\");\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,OAAO,UAAU;AAOjB,MAAM,sBAAsB;AAC5B,MAAM,eAAe;AAEd,gBAAS,kBAAkB,WAA2B;AAC3D,SAAO,KAAK,KAAK,WAAW,qBAAqB,YAAY;AAC/D;AAEO,gBAAS,2BAA2B,WAA2B;AACpE,SAAO,KAAK,KAAK,kBAAkB,SAAS,GAAG,eAAe;AAChE;AAEO,gBAAS,6BAA6B,WAA2B;AACtE,SAAO,KAAK,KAAK,kBAAkB,SAAS,GAAG,qBAAqB;AACtE;AAEO,gBAAS,aAAa,YAA6B;AACxD,SAAO,KAAK,KAAK,cAAc,QAAQ,IAAI,GAAG,WAAW;AAC3D;AAEO,gBAAS,aAAa,YAA6B;AACxD,SAAO,KAAK,KAAK,cAAc,QAAQ,IAAI,GAAG,WAAW;AAC3D;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import child_process from "child_process";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { promises as fs } from "fs";
|
|
5
|
+
import { chalkStderr } from "chalk";
|
|
6
|
+
import { logMessage } from "../../../bundler/log.js";
|
|
7
|
+
import { getVersion, fetchAgentSkillsSha } from "../versionApi.js";
|
|
8
|
+
import { iife, readFileSafe } from "./utils.js";
|
|
9
|
+
async function readInstalledSkillNames(projectDir) {
|
|
10
|
+
const skillsDir = path.join(projectDir, ".agents", "skills");
|
|
11
|
+
const entries = await iife(async () => {
|
|
12
|
+
try {
|
|
13
|
+
const dirents = await fs.readdir(skillsDir, { withFileTypes: true });
|
|
14
|
+
return dirents.filter((d) => d.isDirectory() || d.isSymbolicLink()).map((d) => d.name);
|
|
15
|
+
} catch {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
if (entries.length === 0) return [];
|
|
20
|
+
const names = [];
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
const skillMdPath = path.join(skillsDir, entry, "SKILL.md");
|
|
23
|
+
const content = await readFileSafe(skillMdPath);
|
|
24
|
+
if (content === null) continue;
|
|
25
|
+
const match = content.match(/^---[\s\S]*?^name:\s*(.+?)\s*$/m);
|
|
26
|
+
if (match) {
|
|
27
|
+
names.push(match[1]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return names;
|
|
31
|
+
}
|
|
32
|
+
function runSkillsAdd(cwd) {
|
|
33
|
+
return runSkillsCommand(cwd, ["add", "get-convex/agent-skills", "--yes"]);
|
|
34
|
+
}
|
|
35
|
+
function runSkillsRemove({
|
|
36
|
+
cwd,
|
|
37
|
+
skillNames
|
|
38
|
+
}) {
|
|
39
|
+
return runSkillsCommand(cwd, ["remove", ...skillNames, "--yes"]);
|
|
40
|
+
}
|
|
41
|
+
async function shouldRunSkillsCli() {
|
|
42
|
+
const versionData = await getVersion();
|
|
43
|
+
if (versionData.kind === "error") return true;
|
|
44
|
+
if (versionData.data.disableSkillsCli) {
|
|
45
|
+
logMessage(chalkStderr.yellow(`Agent skills are temporarily disabled.`));
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
async function removeSkillsLockIfEmpty({
|
|
51
|
+
projectDir,
|
|
52
|
+
removedSkillNames
|
|
53
|
+
}) {
|
|
54
|
+
const lockPath = path.join(projectDir, "skills-lock.json");
|
|
55
|
+
try {
|
|
56
|
+
const content = await fs.readFile(lockPath, "utf8");
|
|
57
|
+
const lock = JSON.parse(content);
|
|
58
|
+
if (!lock || typeof lock !== "object" || !lock.skills || typeof lock.skills !== "object") {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
const remainingSkills = Object.keys(lock.skills).filter(
|
|
62
|
+
(name) => !removedSkillNames.includes(name)
|
|
63
|
+
);
|
|
64
|
+
if (remainingSkills.length === 0) {
|
|
65
|
+
await fs.unlink(lockPath);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
} catch {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export async function installSkills({
|
|
74
|
+
projectDir,
|
|
75
|
+
config
|
|
76
|
+
}) {
|
|
77
|
+
if (!await shouldRunSkillsCli()) return;
|
|
78
|
+
logMessage("Installing Convex agent skills...");
|
|
79
|
+
const skillsOk = await runSkillsAdd(projectDir);
|
|
80
|
+
if (!skillsOk) {
|
|
81
|
+
logMessage(
|
|
82
|
+
chalkStderr.yellow(
|
|
83
|
+
"Could not install agent skills. You can retry manually with: npx skills add get-convex/agent-skills"
|
|
84
|
+
)
|
|
85
|
+
);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const sha = await fetchAgentSkillsSha();
|
|
89
|
+
if (sha) config.agentSkillsSha = sha;
|
|
90
|
+
const names = await readInstalledSkillNames(projectDir);
|
|
91
|
+
if (names.length > 0) config.installedSkillNames = names;
|
|
92
|
+
}
|
|
93
|
+
export async function removeInstalledSkills({
|
|
94
|
+
projectDir,
|
|
95
|
+
skillNames
|
|
96
|
+
}) {
|
|
97
|
+
if (skillNames.length === 0 || !await shouldRunSkillsCli()) return false;
|
|
98
|
+
logMessage(`Removing Convex agent skills: ${skillNames.join(", ")}`);
|
|
99
|
+
const skillsOk = await runSkillsRemove({ cwd: projectDir, skillNames });
|
|
100
|
+
if (!skillsOk) {
|
|
101
|
+
logMessage(
|
|
102
|
+
chalkStderr.yellow(
|
|
103
|
+
"Could not remove agent skills automatically. Remove them manually with: npx skills remove"
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
const lockRemoved = await removeSkillsLockIfEmpty({
|
|
109
|
+
projectDir,
|
|
110
|
+
removedSkillNames: skillNames
|
|
111
|
+
});
|
|
112
|
+
if (lockRemoved)
|
|
113
|
+
logMessage(`${chalkStderr.green("\u2714")} Deleted skills-lock.json.`);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
function runSkillsCommand(cwd, args) {
|
|
117
|
+
return new Promise((resolve) => {
|
|
118
|
+
const proc = child_process.spawn(
|
|
119
|
+
"npx",
|
|
120
|
+
["--yes", "skills@latest", ...args],
|
|
121
|
+
{
|
|
122
|
+
cwd,
|
|
123
|
+
stdio: "pipe",
|
|
124
|
+
// .cmd files on Windows require shell execution.
|
|
125
|
+
shell: process.platform === "win32"
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
let capturedOutput = "";
|
|
129
|
+
proc.stdout?.on("data", (chunk) => {
|
|
130
|
+
capturedOutput += chunk.toString();
|
|
131
|
+
});
|
|
132
|
+
proc.stderr?.on("data", (chunk) => {
|
|
133
|
+
capturedOutput += chunk.toString();
|
|
134
|
+
});
|
|
135
|
+
proc.on("close", (code) => {
|
|
136
|
+
if (code !== 0 && capturedOutput.trim().length > 0) {
|
|
137
|
+
const lines = capturedOutput.trim().split(/\r?\n/);
|
|
138
|
+
const tail = lines.slice(-10).join("\n");
|
|
139
|
+
logMessage(chalkStderr.gray(`skills output (tail):
|
|
140
|
+
${tail}`));
|
|
141
|
+
}
|
|
142
|
+
resolve(code === 0);
|
|
143
|
+
});
|
|
144
|
+
proc.on("error", () => resolve(false));
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/lib/aiFiles/skills.ts"],
|
|
4
|
+
"sourcesContent": ["import child_process from \"child_process\";\nimport path from \"path\";\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { getVersion, fetchAgentSkillsSha } from \"../versionApi.js\";\nimport { type AiFilesConfig } from \"./config.js\";\nimport { iife, readFileSafe } from \"./utils.js\";\n\n/**\n * Read the frontmatter `name:` values from skills installed by the skills CLI.\n */\nasync function readInstalledSkillNames(projectDir: string): Promise<string[]> {\n const skillsDir = path.join(projectDir, \".agents\", \"skills\");\n const entries = await iife(async () => {\n try {\n const dirents = await fs.readdir(skillsDir, { withFileTypes: true });\n return dirents\n .filter((d) => d.isDirectory() || d.isSymbolicLink())\n .map((d) => d.name);\n } catch {\n return [] as string[];\n }\n });\n if (entries.length === 0) return [];\n\n const names: string[] = [];\n for (const entry of entries) {\n const skillMdPath = path.join(skillsDir, entry, \"SKILL.md\");\n const content = await readFileSafe(skillMdPath);\n if (content === null) continue;\n const match = content.match(/^---[\\s\\S]*?^name:\\s*(.+?)\\s*$/m);\n if (match) {\n names.push(match[1]);\n }\n }\n return names;\n}\n\n/**\n * Runs `npx skills add get-convex/agent-skills --yes` in the given directory.\n * Returns true on success, false if the process fails or cannot be started.\n */\nfunction runSkillsAdd(cwd: string): Promise<boolean> {\n return runSkillsCommand(cwd, [\"add\", \"get-convex/agent-skills\", \"--yes\"]);\n}\n\n/**\n * Runs `npx skills remove <name...> --yes` to surgically remove only the\n * Convex-managed skills, leaving any skills from other sources intact.\n */\nfunction runSkillsRemove({\n cwd,\n skillNames,\n}: {\n cwd: string;\n skillNames: string[];\n}): Promise<boolean> {\n return runSkillsCommand(cwd, [\"remove\", ...skillNames, \"--yes\"]);\n}\n\n/**\n * This function exists so we have a way to disable skills installs without pushing a new\n * version of the convex CLI\n */\nasync function shouldRunSkillsCli(): Promise<boolean> {\n const versionData = await getVersion();\n\n if (versionData.kind === \"error\") return true;\n\n if (versionData.data.disableSkillsCli) {\n logMessage(chalkStderr.yellow(`Agent skills are temporarily disabled.`));\n return false;\n }\n\n return true;\n}\n\n/**\n * Remove the skills-lock.json file if it only contains skills that we\n * are removing. The `npx skills remove` command leaves the lockfile behind\n * even when it's logically empty.\n */\nasync function removeSkillsLockIfEmpty({\n projectDir,\n removedSkillNames,\n}: {\n projectDir: string;\n removedSkillNames: string[];\n}): Promise<boolean> {\n const lockPath = path.join(projectDir, \"skills-lock.json\");\n try {\n const content = await fs.readFile(lockPath, \"utf8\");\n const lock = JSON.parse(content);\n\n if (\n !lock ||\n typeof lock !== \"object\" ||\n !lock.skills ||\n typeof lock.skills !== \"object\"\n ) {\n return false;\n }\n\n const remainingSkills = Object.keys(lock.skills).filter(\n (name) => !removedSkillNames.includes(name),\n );\n\n if (remainingSkills.length === 0) {\n await fs.unlink(lockPath);\n return true;\n }\n return false;\n } catch {\n return false;\n }\n}\n\n/**\n * Install Convex agent skills and record the SHA and names into the config.\n * Handles the kill-switch check and all logging internally.\n */\nexport async function installSkills({\n projectDir,\n config,\n}: {\n projectDir: string;\n config: AiFilesConfig;\n}): Promise<void> {\n if (!(await shouldRunSkillsCli())) return;\n\n logMessage(\"Installing Convex agent skills...\");\n const skillsOk = await runSkillsAdd(projectDir);\n if (!skillsOk) {\n logMessage(\n chalkStderr.yellow(\n \"Could not install agent skills. You can retry manually with: npx skills add get-convex/agent-skills\",\n ),\n );\n return;\n }\n\n const sha = await fetchAgentSkillsSha();\n if (sha) config.agentSkillsSha = sha;\n\n const names = await readInstalledSkillNames(projectDir);\n if (names.length > 0) config.installedSkillNames = names;\n}\n\n/**\n * Remove Convex-managed agent skills and clean up the lock file if empty.\n * Returns true if any removal occurred.\n */\nexport async function removeInstalledSkills({\n projectDir,\n skillNames,\n}: {\n projectDir: string;\n skillNames: string[];\n}): Promise<boolean> {\n if (skillNames.length === 0 || !(await shouldRunSkillsCli())) return false;\n\n logMessage(`Removing Convex agent skills: ${skillNames.join(\", \")}`);\n const skillsOk = await runSkillsRemove({ cwd: projectDir, skillNames });\n if (!skillsOk) {\n logMessage(\n chalkStderr.yellow(\n \"Could not remove agent skills automatically. Remove them manually with: npx skills remove\",\n ),\n );\n return false;\n }\n\n const lockRemoved = await removeSkillsLockIfEmpty({\n projectDir,\n removedSkillNames: skillNames,\n });\n if (lockRemoved)\n logMessage(`${chalkStderr.green(\"\u2714\")} Deleted skills-lock.json.`);\n return true;\n}\n\nfunction runSkillsCommand(cwd: string, args: string[]): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = child_process.spawn(\n \"npx\",\n [\"--yes\", \"skills@latest\", ...args],\n {\n cwd,\n stdio: \"pipe\",\n // .cmd files on Windows require shell execution.\n shell: process.platform === \"win32\",\n },\n );\n let capturedOutput = \"\";\n proc.stdout?.on(\"data\", (chunk) => {\n capturedOutput += chunk.toString();\n });\n proc.stderr?.on(\"data\", (chunk) => {\n capturedOutput += chunk.toString();\n });\n proc.on(\"close\", (code) => {\n if (code !== 0 && capturedOutput.trim().length > 0) {\n const lines = capturedOutput.trim().split(/\\r?\\n/);\n const tail = lines.slice(-10).join(\"\\n\");\n logMessage(chalkStderr.gray(`skills output (tail):\\n${tail}`));\n }\n resolve(code === 0);\n });\n proc.on(\"error\", () => resolve(false));\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { chalkStderr } from "chalk";
|
|
4
|
+
import { logMessage } from "../../../bundler/log.js";
|
|
5
|
+
import {
|
|
6
|
+
AGENTS_MD_START_MARKER,
|
|
7
|
+
AGENTS_MD_END_MARKER,
|
|
8
|
+
agentsMdConvexSection
|
|
9
|
+
} from "../../codegen_templates/agentsmd.js";
|
|
10
|
+
import {
|
|
11
|
+
CLAUDE_MD_START_MARKER,
|
|
12
|
+
CLAUDE_MD_END_MARKER,
|
|
13
|
+
claudeMdConvexSection
|
|
14
|
+
} from "../../codegen_templates/claudemd.js";
|
|
15
|
+
import { getVersion } from "../versionApi.js";
|
|
16
|
+
import { hashSha256 } from "../utils/hash.js";
|
|
17
|
+
import {
|
|
18
|
+
agentsMdPath,
|
|
19
|
+
claudeMdPath,
|
|
20
|
+
guidelinesPathForConvexDir
|
|
21
|
+
} from "./paths.js";
|
|
22
|
+
import { readAiConfig } from "./config.js";
|
|
23
|
+
import { readFileSafe } from "./utils.js";
|
|
24
|
+
function logGuidelinesStatus({
|
|
25
|
+
guidelinesFile,
|
|
26
|
+
guidelinesRelPath,
|
|
27
|
+
config,
|
|
28
|
+
canonicalGuidelinesHash,
|
|
29
|
+
networkAvailable
|
|
30
|
+
}) {
|
|
31
|
+
if (guidelinesFile === null) {
|
|
32
|
+
logMessage(
|
|
33
|
+
` ${chalkStderr.yellow("\u26A0")} ${guidelinesRelPath}: not on disk \u2014 run ${chalkStderr.bold("npx convex ai-files install")} to reinstall`
|
|
34
|
+
);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const isLocallyModified = config.guidelinesHash !== null && hashSha256(guidelinesFile) !== config.guidelinesHash;
|
|
38
|
+
if (isLocallyModified) {
|
|
39
|
+
logMessage(
|
|
40
|
+
` ${chalkStderr.yellow("\u26A0")} ${guidelinesRelPath}: installed, modified locally (changes will be overwritten on next update)`
|
|
41
|
+
);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const isOutOfDate = networkAvailable && canonicalGuidelinesHash !== null && config.guidelinesHash !== null && config.guidelinesHash !== canonicalGuidelinesHash;
|
|
45
|
+
if (isOutOfDate) {
|
|
46
|
+
logMessage(
|
|
47
|
+
` ${chalkStderr.yellow("\u26A0")} ${guidelinesRelPath}: installed, out of date \u2014 run ${chalkStderr.bold("npx convex ai-files update")}`
|
|
48
|
+
);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
logMessage(
|
|
52
|
+
` ${chalkStderr.green("\u2714")} ${guidelinesRelPath}: installed${networkAvailable ? ", up to date" : ""}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
function logAgentsMdStatus({
|
|
56
|
+
agentsContent,
|
|
57
|
+
config,
|
|
58
|
+
convexDirName
|
|
59
|
+
}) {
|
|
60
|
+
const hasSection = agentsContent !== null && agentsContent.includes(AGENTS_MD_START_MARKER) && agentsContent.includes(AGENTS_MD_END_MARKER);
|
|
61
|
+
if (!hasSection) {
|
|
62
|
+
logMessage(
|
|
63
|
+
` ${chalkStderr.yellow("\u26A0")} AGENTS.md: Convex section missing \u2014 run ${chalkStderr.bold("npx convex ai-files install")} to reinstall`
|
|
64
|
+
);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const currentHash = hashSha256(agentsMdConvexSection(convexDirName));
|
|
68
|
+
if (config.agentsMdSectionHash !== null && config.agentsMdSectionHash !== currentHash) {
|
|
69
|
+
logMessage(
|
|
70
|
+
` ${chalkStderr.yellow("\u26A0")} AGENTS.md: Convex section out of date \u2014 run ${chalkStderr.bold("npx convex ai-files update")}`
|
|
71
|
+
);
|
|
72
|
+
} else {
|
|
73
|
+
logMessage(
|
|
74
|
+
` ${chalkStderr.green("\u2714")} AGENTS.md: Convex section present, up to date`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function logClaudeMdStatus({
|
|
79
|
+
claudeContent,
|
|
80
|
+
config,
|
|
81
|
+
convexDirName
|
|
82
|
+
}) {
|
|
83
|
+
const hasSection = claudeContent !== null && claudeContent.includes(CLAUDE_MD_START_MARKER) && claudeContent.includes(CLAUDE_MD_END_MARKER);
|
|
84
|
+
if (!hasSection) {
|
|
85
|
+
if (claudeContent === null) {
|
|
86
|
+
logMessage(
|
|
87
|
+
` ${chalkStderr.yellow("\u26A0")} CLAUDE.md: missing - run ${chalkStderr.bold("npx convex ai-files install")} to create it`
|
|
88
|
+
);
|
|
89
|
+
} else {
|
|
90
|
+
logMessage(
|
|
91
|
+
` ${chalkStderr.yellow("\u26A0")} CLAUDE.md: no Convex section present - run ${chalkStderr.bold("npx convex ai-files update")} to add it`
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const currentHash = hashSha256(claudeMdConvexSection(convexDirName));
|
|
97
|
+
if (config.claudeMdHash !== null && config.claudeMdHash !== currentHash) {
|
|
98
|
+
logMessage(
|
|
99
|
+
` ${chalkStderr.yellow("\u26A0")} CLAUDE.md: Convex section out of date - run ${chalkStderr.bold("npx convex ai-files update")}`
|
|
100
|
+
);
|
|
101
|
+
} else {
|
|
102
|
+
logMessage(
|
|
103
|
+
` ${chalkStderr.green("\u2714")} CLAUDE.md: Convex section present, up to date`
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function logSkillsStatus({
|
|
108
|
+
config,
|
|
109
|
+
canonicalAgentSkillsSha,
|
|
110
|
+
networkAvailable
|
|
111
|
+
}) {
|
|
112
|
+
if (config.installedSkillNames.length === 0) {
|
|
113
|
+
logMessage(
|
|
114
|
+
` ${chalkStderr.yellow("\u26A0")} Agent skills: not installed \u2014 run ${chalkStderr.bold("npx convex ai-files install")} to install`
|
|
115
|
+
);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const skillsList = config.installedSkillNames.join(", ");
|
|
119
|
+
const isStale = networkAvailable && canonicalAgentSkillsSha !== null && config.agentSkillsSha !== null && config.agentSkillsSha !== canonicalAgentSkillsSha;
|
|
120
|
+
if (isStale) {
|
|
121
|
+
logMessage(
|
|
122
|
+
` ${chalkStderr.yellow("\u26A0")} Agent skills: ${skillsList} \u2014 out of date, run ${chalkStderr.bold("npx convex ai-files update")}`
|
|
123
|
+
);
|
|
124
|
+
} else {
|
|
125
|
+
logMessage(
|
|
126
|
+
` ${chalkStderr.green("\u2714")} Agent skills: ${skillsList}${networkAvailable ? " (up to date)" : ""}`
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export async function statusAiFiles({
|
|
131
|
+
projectDir,
|
|
132
|
+
convexDir
|
|
133
|
+
}) {
|
|
134
|
+
const convexDirName = path.relative(projectDir, convexDir);
|
|
135
|
+
const guidelinesRelPath = path.relative(
|
|
136
|
+
projectDir,
|
|
137
|
+
guidelinesPathForConvexDir(convexDir)
|
|
138
|
+
);
|
|
139
|
+
const config = await readAiConfig({ projectDir, convexDir });
|
|
140
|
+
if (config === null) {
|
|
141
|
+
logMessage(`Convex AI files: ${chalkStderr.yellow("not installed")}`);
|
|
142
|
+
logMessage(
|
|
143
|
+
` Run ${chalkStderr.bold("npx convex ai-files install")} to get started, or ${chalkStderr.bold("npx convex ai-files disable")} to opt out.`
|
|
144
|
+
);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (!config.enabled) {
|
|
148
|
+
logMessage(`Convex AI files: ${chalkStderr.yellow("disabled")}`);
|
|
149
|
+
logMessage(
|
|
150
|
+
` Run ${chalkStderr.bold("npx convex ai-files enable")} to re-enable.`
|
|
151
|
+
);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
logMessage(`Convex AI files: ${chalkStderr.green("enabled")}`);
|
|
155
|
+
const [versionData, guidelinesFile, agentsContent, claudeContent] = await Promise.all([
|
|
156
|
+
getVersion(),
|
|
157
|
+
readFileSafe(guidelinesPathForConvexDir(convexDir)),
|
|
158
|
+
readFileSafe(agentsMdPath(projectDir)),
|
|
159
|
+
readFileSafe(claudeMdPath(projectDir))
|
|
160
|
+
]);
|
|
161
|
+
const networkAvailable = versionData.kind === "ok";
|
|
162
|
+
const canonicalGuidelinesHash = networkAvailable ? versionData.data.guidelinesHash : null;
|
|
163
|
+
const canonicalAgentSkillsSha = networkAvailable ? versionData.data.agentSkillsSha : null;
|
|
164
|
+
logGuidelinesStatus({
|
|
165
|
+
guidelinesFile,
|
|
166
|
+
guidelinesRelPath,
|
|
167
|
+
config,
|
|
168
|
+
canonicalGuidelinesHash,
|
|
169
|
+
networkAvailable
|
|
170
|
+
});
|
|
171
|
+
logAgentsMdStatus({ agentsContent, config, convexDirName });
|
|
172
|
+
logClaudeMdStatus({ claudeContent, config, convexDirName });
|
|
173
|
+
logSkillsStatus({ config, canonicalAgentSkillsSha, networkAvailable });
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/lib/aiFiles/status.ts"],
|
|
4
|
+
"sourcesContent": ["import path from \"path\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport {\n AGENTS_MD_START_MARKER,\n AGENTS_MD_END_MARKER,\n agentsMdConvexSection,\n} from \"../../codegen_templates/agentsmd.js\";\nimport {\n CLAUDE_MD_START_MARKER,\n CLAUDE_MD_END_MARKER,\n claudeMdConvexSection,\n} from \"../../codegen_templates/claudemd.js\";\nimport { getVersion } from \"../versionApi.js\";\nimport { hashSha256 } from \"../utils/hash.js\";\nimport {\n type AiFilesPaths,\n agentsMdPath,\n claudeMdPath,\n guidelinesPathForConvexDir,\n} from \"./paths.js\";\nimport { type AiFilesConfig, readAiConfig } from \"./config.js\";\nimport { readFileSafe } from \"./utils.js\";\n\nfunction logGuidelinesStatus({\n guidelinesFile,\n guidelinesRelPath,\n config,\n canonicalGuidelinesHash,\n networkAvailable,\n}: {\n guidelinesFile: string | null;\n guidelinesRelPath: string;\n config: AiFilesConfig;\n canonicalGuidelinesHash: string | null;\n networkAvailable: boolean;\n}): void {\n if (guidelinesFile === null) {\n logMessage(\n ` ${chalkStderr.yellow(\"\u26A0\")} ${guidelinesRelPath}: not on disk \u2014 run ${chalkStderr.bold(\"npx convex ai-files install\")} to reinstall`,\n );\n return;\n }\n\n const isLocallyModified =\n config.guidelinesHash !== null &&\n hashSha256(guidelinesFile) !== config.guidelinesHash;\n\n if (isLocallyModified) {\n logMessage(\n ` ${chalkStderr.yellow(\"\u26A0\")} ${guidelinesRelPath}: installed, modified locally (changes will be overwritten on next update)`,\n );\n return;\n }\n\n const isOutOfDate =\n networkAvailable &&\n canonicalGuidelinesHash !== null &&\n config.guidelinesHash !== null &&\n config.guidelinesHash !== canonicalGuidelinesHash;\n\n if (isOutOfDate) {\n logMessage(\n ` ${chalkStderr.yellow(\"\u26A0\")} ${guidelinesRelPath}: installed, out of date \u2014 run ${chalkStderr.bold(\"npx convex ai-files update\")}`,\n );\n return;\n }\n\n logMessage(\n ` ${chalkStderr.green(\"\u2714\")} ${guidelinesRelPath}: installed${networkAvailable ? \", up to date\" : \"\"}`,\n );\n}\n\nfunction logAgentsMdStatus({\n agentsContent,\n config,\n convexDirName,\n}: {\n agentsContent: string | null;\n config: AiFilesConfig;\n convexDirName: string;\n}): void {\n const hasSection =\n agentsContent !== null &&\n agentsContent.includes(AGENTS_MD_START_MARKER) &&\n agentsContent.includes(AGENTS_MD_END_MARKER);\n\n if (!hasSection) {\n logMessage(\n ` ${chalkStderr.yellow(\"\u26A0\")} AGENTS.md: Convex section missing \u2014 run ${chalkStderr.bold(\"npx convex ai-files install\")} to reinstall`,\n );\n return;\n }\n\n const currentHash = hashSha256(agentsMdConvexSection(convexDirName));\n if (\n config.agentsMdSectionHash !== null &&\n config.agentsMdSectionHash !== currentHash\n ) {\n logMessage(\n ` ${chalkStderr.yellow(\"\u26A0\")} AGENTS.md: Convex section out of date \u2014 run ${chalkStderr.bold(\"npx convex ai-files update\")}`,\n );\n } else {\n logMessage(\n ` ${chalkStderr.green(\"\u2714\")} AGENTS.md: Convex section present, up to date`,\n );\n }\n}\n\nfunction logClaudeMdStatus({\n claudeContent,\n config,\n convexDirName,\n}: {\n claudeContent: string | null;\n config: AiFilesConfig;\n convexDirName: string;\n}): void {\n const hasSection =\n claudeContent !== null &&\n claudeContent.includes(CLAUDE_MD_START_MARKER) &&\n claudeContent.includes(CLAUDE_MD_END_MARKER);\n\n if (!hasSection) {\n if (claudeContent === null) {\n logMessage(\n ` ${chalkStderr.yellow(\"\u26A0\")} CLAUDE.md: missing - run ${chalkStderr.bold(\"npx convex ai-files install\")} to create it`,\n );\n } else {\n logMessage(\n ` ${chalkStderr.yellow(\"\u26A0\")} CLAUDE.md: no Convex section present - run ${chalkStderr.bold(\"npx convex ai-files update\")} to add it`,\n );\n }\n return;\n }\n\n const currentHash = hashSha256(claudeMdConvexSection(convexDirName));\n if (config.claudeMdHash !== null && config.claudeMdHash !== currentHash) {\n logMessage(\n ` ${chalkStderr.yellow(\"\u26A0\")} CLAUDE.md: Convex section out of date - run ${chalkStderr.bold(\"npx convex ai-files update\")}`,\n );\n } else {\n logMessage(\n ` ${chalkStderr.green(\"\u2714\")} CLAUDE.md: Convex section present, up to date`,\n );\n }\n}\n\nfunction logSkillsStatus({\n config,\n canonicalAgentSkillsSha,\n networkAvailable,\n}: {\n config: AiFilesConfig;\n canonicalAgentSkillsSha: string | null;\n networkAvailable: boolean;\n}): void {\n if (config.installedSkillNames.length === 0) {\n logMessage(\n ` ${chalkStderr.yellow(\"\u26A0\")} Agent skills: not installed \u2014 run ${chalkStderr.bold(\"npx convex ai-files install\")} to install`,\n );\n return;\n }\n\n const skillsList = config.installedSkillNames.join(\", \");\n const isStale =\n networkAvailable &&\n canonicalAgentSkillsSha !== null &&\n config.agentSkillsSha !== null &&\n config.agentSkillsSha !== canonicalAgentSkillsSha;\n\n if (isStale) {\n logMessage(\n ` ${chalkStderr.yellow(\"\u26A0\")} Agent skills: ${skillsList} \u2014 out of date, run ${chalkStderr.bold(\"npx convex ai-files update\")}`,\n );\n } else {\n logMessage(\n ` ${chalkStderr.green(\"\u2714\")} Agent skills: ${skillsList}${networkAvailable ? \" (up to date)\" : \"\"}`,\n );\n }\n}\n\nexport async function statusAiFiles({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<void> {\n const convexDirName = path.relative(projectDir, convexDir);\n const guidelinesRelPath = path.relative(\n projectDir,\n guidelinesPathForConvexDir(convexDir),\n );\n\n const config = await readAiConfig({ projectDir, convexDir });\n\n if (config === null) {\n logMessage(`Convex AI files: ${chalkStderr.yellow(\"not installed\")}`);\n logMessage(\n ` Run ${chalkStderr.bold(\"npx convex ai-files install\")} to get started, ` +\n `or ${chalkStderr.bold(\"npx convex ai-files disable\")} to opt out.`,\n );\n return;\n }\n\n if (!config.enabled) {\n logMessage(`Convex AI files: ${chalkStderr.yellow(\"disabled\")}`);\n logMessage(\n ` Run ${chalkStderr.bold(\"npx convex ai-files enable\")} to re-enable.`,\n );\n return;\n }\n\n logMessage(`Convex AI files: ${chalkStderr.green(\"enabled\")}`);\n\n const [versionData, guidelinesFile, agentsContent, claudeContent] =\n await Promise.all([\n getVersion(),\n readFileSafe(guidelinesPathForConvexDir(convexDir)),\n readFileSafe(agentsMdPath(projectDir)),\n readFileSafe(claudeMdPath(projectDir)),\n ]);\n\n const networkAvailable = versionData.kind === \"ok\";\n const canonicalGuidelinesHash = networkAvailable\n ? versionData.data.guidelinesHash\n : null;\n const canonicalAgentSkillsSha = networkAvailable\n ? versionData.data.agentSkillsSha\n : null;\n\n logGuidelinesStatus({\n guidelinesFile,\n guidelinesRelPath,\n config,\n canonicalGuidelinesHash,\n networkAvailable,\n });\n logAgentsMdStatus({ agentsContent, config, convexDirName });\n logClaudeMdStatus({ claudeContent, config, convexDirName });\n logSkillsStatus({ config, canonicalAgentSkillsSha, networkAvailable });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|