contentrain 0.7.15 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -33,6 +33,8 @@ const OLD_RULE_FILES = [
|
|
|
33
33
|
"contentrain-workflow-rules.md",
|
|
34
34
|
"contentrain-normalize-rules.md"
|
|
35
35
|
];
|
|
36
|
+
/** First heading of the essentials rule file — marks our block in a shared file. */
|
|
37
|
+
const GUARDRAILS_MARKER = "# Contentrain — Essential Rules";
|
|
36
38
|
const IDE_CONFIGS = {
|
|
37
39
|
"claude-code": {
|
|
38
40
|
name: "Claude Code",
|
|
@@ -58,7 +60,15 @@ const IDE_CONFIGS = {
|
|
|
58
60
|
name: "GitHub Copilot",
|
|
59
61
|
rulesDir: ".github",
|
|
60
62
|
skillsDir: ".agents/skills",
|
|
61
|
-
guardrailsFileName: "copilot-instructions.md"
|
|
63
|
+
guardrailsFileName: "copilot-instructions.md",
|
|
64
|
+
sharedInstructionsFile: true
|
|
65
|
+
},
|
|
66
|
+
codex: {
|
|
67
|
+
name: "OpenAI Codex",
|
|
68
|
+
rulesDir: ".",
|
|
69
|
+
skillsDir: ".agents/skills",
|
|
70
|
+
guardrailsFileName: "AGENTS.md",
|
|
71
|
+
sharedInstructionsFile: true
|
|
62
72
|
}
|
|
63
73
|
};
|
|
64
74
|
const MCP_CONFIGS = {
|
|
@@ -66,7 +76,8 @@ const MCP_CONFIGS = {
|
|
|
66
76
|
cursor: ".cursor/mcp.json",
|
|
67
77
|
windsurf: ".windsurf/mcp.json",
|
|
68
78
|
vscode: ".vscode/mcp.json",
|
|
69
|
-
copilot: ".vscode/mcp.json"
|
|
79
|
+
copilot: ".vscode/mcp.json",
|
|
80
|
+
codex: ".codex/config.toml"
|
|
70
81
|
};
|
|
71
82
|
const STANDARD_MCP_CONFIG = { mcpServers: { contentrain: {
|
|
72
83
|
command: "npx",
|
|
@@ -76,14 +87,49 @@ const STANDARD_MCP_CONFIG = { mcpServers: { contentrain: {
|
|
|
76
87
|
"--stdio"
|
|
77
88
|
]
|
|
78
89
|
} } };
|
|
90
|
+
/** Codex configures MCP servers in TOML, not JSON. */
|
|
91
|
+
const CODEX_MCP_BLOCK = [
|
|
92
|
+
"[mcp_servers.contentrain]",
|
|
93
|
+
"command = \"npx\"",
|
|
94
|
+
"args = [\"contentrain\", \"serve\", \"--stdio\"]"
|
|
95
|
+
].join("\n");
|
|
79
96
|
async function detectIdes(projectRoot) {
|
|
80
97
|
const ides = [];
|
|
81
98
|
if (await pathExists(join(projectRoot, "CLAUDE.md")) || await pathExists(join(projectRoot, ".claude"))) ides.push("claude-code");
|
|
82
99
|
if (await pathExists(join(projectRoot, ".cursor"))) ides.push("cursor");
|
|
83
100
|
if (await pathExists(join(projectRoot, ".windsurf"))) ides.push("windsurf");
|
|
84
101
|
if (await pathExists(join(projectRoot, ".github"))) ides.push("copilot");
|
|
102
|
+
if (await pathExists(join(projectRoot, ".codex"))) ides.push("codex");
|
|
85
103
|
return ides;
|
|
86
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Codex keeps unrelated user settings (model, approval policy, sandbox) in the
|
|
107
|
+
* same file, so we append a table rather than parse and rewrite: appending is
|
|
108
|
+
* valid TOML, needs no parser dependency, and leaves the rest of the file
|
|
109
|
+
* byte-for-byte intact.
|
|
110
|
+
*/
|
|
111
|
+
async function writeCodexMcpConfig(projectRoot, relativePath) {
|
|
112
|
+
const configPath = join(projectRoot, relativePath);
|
|
113
|
+
if (await pathExists(configPath)) {
|
|
114
|
+
const existing = await readFile(configPath, "utf-8");
|
|
115
|
+
if (/^\s*\[mcp_servers\.contentrain\]/m.test(existing)) return {
|
|
116
|
+
written: false,
|
|
117
|
+
path: relativePath,
|
|
118
|
+
skipped: "Already configured"
|
|
119
|
+
};
|
|
120
|
+
await appendFile(configPath, `${existing.endsWith("\n") ? "\n" : "\n\n"}${CODEX_MCP_BLOCK}\n`);
|
|
121
|
+
return {
|
|
122
|
+
written: true,
|
|
123
|
+
path: relativePath
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
await ensureDir(join(configPath, ".."));
|
|
127
|
+
await writeFile(configPath, `${CODEX_MCP_BLOCK}\n`, "utf-8");
|
|
128
|
+
return {
|
|
129
|
+
written: true,
|
|
130
|
+
path: relativePath
|
|
131
|
+
};
|
|
132
|
+
}
|
|
87
133
|
async function writeMcpConfig(projectRoot, agent) {
|
|
88
134
|
const relativePath = MCP_CONFIGS[agent];
|
|
89
135
|
if (!relativePath) return {
|
|
@@ -91,6 +137,7 @@ async function writeMcpConfig(projectRoot, agent) {
|
|
|
91
137
|
path: "",
|
|
92
138
|
skipped: `Unknown agent: "${agent}"`
|
|
93
139
|
};
|
|
140
|
+
if (agent === "codex") return writeCodexMcpConfig(projectRoot, relativePath);
|
|
94
141
|
const configPath = join(projectRoot, relativePath);
|
|
95
142
|
if (await pathExists(configPath)) try {
|
|
96
143
|
const existing = JSON.parse(await readFile(configPath, "utf-8"));
|
|
@@ -150,14 +197,17 @@ async function installIdeRulesAndSkills(projectRoot, ide, resolveRuleFile, resol
|
|
|
150
197
|
let content = await readFile(resolveRuleFile("essential/contentrain-essentials.md"), "utf-8");
|
|
151
198
|
if (ide.guardrailsFrontmatter) content = ide.guardrailsFrontmatter + content;
|
|
152
199
|
if (await pathExists(guardrailsDest)) {
|
|
153
|
-
if (
|
|
200
|
+
if (ide.sharedInstructionsFile) {
|
|
201
|
+
if (!(await readFile(guardrailsDest, "utf-8")).includes(GUARDRAILS_MARKER)) {
|
|
202
|
+
await appendFile(guardrailsDest, `\n\n${content}`);
|
|
203
|
+
installed++;
|
|
204
|
+
}
|
|
205
|
+
} else if (forceUpdate) {
|
|
154
206
|
await writeFile(guardrailsDest, content, "utf-8");
|
|
155
207
|
updated++;
|
|
156
208
|
}
|
|
157
209
|
} else {
|
|
158
|
-
|
|
159
|
-
if (!(await readFile(guardrailsDest, "utf-8")).includes("# Contentrain")) await appendFile(guardrailsDest, `\n\n${content}`);
|
|
160
|
-
} else await writeFile(guardrailsDest, content, "utf-8");
|
|
210
|
+
await writeFile(guardrailsDest, content, "utf-8");
|
|
161
211
|
installed++;
|
|
162
212
|
}
|
|
163
213
|
filesToAdd.push(guardrailsDest);
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { i as pc } from "./ui-B8l_LC36.mjs";
|
|
3
3
|
import { defineCommand, runMain } from "citty";
|
|
4
4
|
//#region package.json
|
|
5
|
-
var version = "0.
|
|
5
|
+
var version = "0.8.0";
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region src/utils/debug.ts
|
|
8
8
|
/**
|
|
@@ -43,7 +43,7 @@ runMain(defineCommand({
|
|
|
43
43
|
description: "Contentrain CLI — AI content governance infrastructure"
|
|
44
44
|
},
|
|
45
45
|
subCommands: {
|
|
46
|
-
init: () => import("./init-
|
|
46
|
+
init: () => import("./init-BuoJKTt1.mjs").then((m) => m.default),
|
|
47
47
|
status: () => import("./status-CKHWrsUI.mjs").then((m) => m.default),
|
|
48
48
|
doctor: () => import("./doctor-MOf_LQEL.mjs").then((m) => m.default),
|
|
49
49
|
validate: () => import("./validate-CW8FCCd4.mjs").then((m) => m.default),
|
|
@@ -55,8 +55,8 @@ runMain(defineCommand({
|
|
|
55
55
|
describe: () => import("./describe-DJ5H9Cxm.mjs").then((m) => m.default),
|
|
56
56
|
"describe-format": () => import("./describe-format-CUAqB0C4.mjs").then((m) => m.default),
|
|
57
57
|
scaffold: () => import("./scaffold-irxW-vdX.mjs").then((m) => m.default),
|
|
58
|
-
setup: () => import("./setup-
|
|
59
|
-
skills: () => import("./skills-
|
|
58
|
+
setup: () => import("./setup-DdoWlLFE.mjs").then((m) => m.default),
|
|
59
|
+
skills: () => import("./skills-_LEBO_GH.mjs").then((m) => m.default),
|
|
60
60
|
studio: () => import("./studio-DVVkj4QL.mjs").then((m) => m.default)
|
|
61
61
|
}
|
|
62
62
|
}));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as pc } from "./ui-B8l_LC36.mjs";
|
|
2
2
|
import { r as resolveProjectRoot, t as loadProjectContext } from "./context-OskMGy8y.mjs";
|
|
3
|
-
import { a as createPackageResolver, c as writeMcpConfig, i as addClaudeMdReference, n as IDE_CONFIGS, o as detectIdes, s as installIdeRulesAndSkills } from "./ide-
|
|
3
|
+
import { a as createPackageResolver, c as writeMcpConfig, i as addClaudeMdReference, n as IDE_CONFIGS, o as detectIdes, s as installIdeRulesAndSkills } from "./ide-CQ9vEsPi.mjs";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
import { confirm, intro, isCancel, log, multiselect, outro, select, spinner } from "@clack/prompts";
|
|
6
6
|
import { join } from "node:path";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as pc } from "./ui-B8l_LC36.mjs";
|
|
2
2
|
import { r as resolveProjectRoot, t as loadProjectContext } from "./context-OskMGy8y.mjs";
|
|
3
|
-
import { a as createPackageResolver, c as writeMcpConfig, n as IDE_CONFIGS, o as detectIdes, r as MCP_CONFIGS, s as installIdeRulesAndSkills } from "./ide-
|
|
3
|
+
import { a as createPackageResolver, c as writeMcpConfig, n as IDE_CONFIGS, o as detectIdes, r as MCP_CONFIGS, s as installIdeRulesAndSkills } from "./ide-CQ9vEsPi.mjs";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
import { intro, log, outro, spinner } from "@clack/prompts";
|
|
6
6
|
//#region src/commands/setup.ts
|
|
@@ -39,6 +39,7 @@ var setup_default = defineCommand({
|
|
|
39
39
|
log.message(` ${pc.cyan("contentrain setup vscode")}`);
|
|
40
40
|
log.message(` ${pc.cyan("contentrain setup windsurf")}`);
|
|
41
41
|
log.message(` ${pc.cyan("contentrain setup copilot")}`);
|
|
42
|
+
log.message(` ${pc.cyan("contentrain setup codex")}`);
|
|
42
43
|
log.message(` ${pc.cyan("contentrain setup --all")}`);
|
|
43
44
|
outro("");
|
|
44
45
|
return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as pc } from "./ui-B8l_LC36.mjs";
|
|
2
2
|
import { r as resolveProjectRoot } from "./context-OskMGy8y.mjs";
|
|
3
|
-
import { a as createPackageResolver, n as IDE_CONFIGS, o as detectIdes, s as installIdeRulesAndSkills, t as AGENT_SKILL_NAMES } from "./ide-
|
|
3
|
+
import { a as createPackageResolver, n as IDE_CONFIGS, o as detectIdes, s as installIdeRulesAndSkills, t as AGENT_SKILL_NAMES } from "./ide-CQ9vEsPi.mjs";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
import { intro, log, outro, spinner } from "@clack/prompts";
|
|
6
6
|
import { join } from "node:path";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "contentrain",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "CLI for Contentrain — AI content governance infrastructure",
|
|
6
6
|
"type": "module",
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"ws": "^8.18.0",
|
|
49
49
|
"zod": "^3.24.0",
|
|
50
50
|
"@contentrain/rules": "0.6.0",
|
|
51
|
-
"@contentrain/skills": "0.7.0",
|
|
52
51
|
"@contentrain/mcp": "2.3.0",
|
|
53
52
|
"@contentrain/query": "7.0.1",
|
|
54
|
-
"@contentrain/types": "0.9.0"
|
|
53
|
+
"@contentrain/types": "0.9.0",
|
|
54
|
+
"@contentrain/skills": "0.7.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/ws": "^8.5.0",
|