contentrain 0.4.2 → 0.4.3
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/dist/{ide-Bg-Z8QZk.mjs → ide-4ZGiAtYB.mjs} +41 -19
- package/dist/index.mjs +4 -4
- package/dist/{init-DFyQ-l-E.mjs → init-BVlisNcW.mjs} +18 -25
- package/dist/{setup-DJy-jNEU.mjs → setup-4mS8RuCy.mjs} +16 -14
- package/dist/{skills-D-tFY7WA.mjs → skills-4nhto0AZ.mjs} +12 -15
- package/package.json +3 -2
|
@@ -117,31 +117,53 @@ async function writeMcpConfig(projectRoot, agent) {
|
|
|
117
117
|
path: relativePath
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Create a resolver function for a package's files.
|
|
122
|
+
* Tries multiple strategies to handle npm, pnpm, and workspace layouts.
|
|
123
|
+
*/
|
|
124
|
+
async function createPackageResolver(packageName, projectRoot) {
|
|
125
|
+
const { createRequire } = await import("node:module");
|
|
126
|
+
try {
|
|
127
|
+
const req = createRequire(import.meta.url);
|
|
128
|
+
req.resolve(packageName);
|
|
129
|
+
return (p) => req.resolve(`${packageName}/${p}`);
|
|
130
|
+
} catch {}
|
|
131
|
+
try {
|
|
132
|
+
const req = createRequire(join(projectRoot, "package.json"));
|
|
133
|
+
req.resolve(packageName);
|
|
134
|
+
return (p) => req.resolve(`${packageName}/${p}`);
|
|
135
|
+
} catch {}
|
|
136
|
+
const directBase = join(projectRoot, "node_modules", packageName);
|
|
137
|
+
if (await pathExists(directBase)) return (p) => join(directBase, p);
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
120
140
|
async function installIdeRulesAndSkills(projectRoot, ide, resolveRuleFile, resolveSkillFile, forceUpdate = false) {
|
|
121
141
|
let installed = 0;
|
|
122
142
|
let updated = 0;
|
|
123
143
|
const rulesDir = join(projectRoot, ide.rulesDir);
|
|
124
144
|
const git = simpleGit(projectRoot);
|
|
125
145
|
const filesToAdd = [];
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
|
|
146
|
+
if (resolveRuleFile) {
|
|
147
|
+
await ensureDir(rulesDir);
|
|
148
|
+
const guardrailsDest = join(rulesDir, ide.guardrailsFileName);
|
|
149
|
+
try {
|
|
150
|
+
let content = await readFile(resolveRuleFile("essential/contentrain-essentials.md"), "utf-8");
|
|
151
|
+
if (ide.guardrailsFrontmatter) content = ide.guardrailsFrontmatter + content;
|
|
152
|
+
if (await pathExists(guardrailsDest)) {
|
|
153
|
+
if (forceUpdate) {
|
|
154
|
+
await writeFile(guardrailsDest, content, "utf-8");
|
|
155
|
+
updated++;
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
if (ide.name === "GitHub Copilot" && await pathExists(guardrailsDest)) {
|
|
159
|
+
if (!(await readFile(guardrailsDest, "utf-8")).includes("# Contentrain")) await appendFile(guardrailsDest, `\n\n${content}`);
|
|
160
|
+
} else await writeFile(guardrailsDest, content, "utf-8");
|
|
161
|
+
installed++;
|
|
135
162
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
installed++;
|
|
141
|
-
}
|
|
142
|
-
filesToAdd.push(guardrailsDest);
|
|
143
|
-
} catch {}
|
|
144
|
-
for (const oldFile of OLD_RULE_FILES) {
|
|
163
|
+
filesToAdd.push(guardrailsDest);
|
|
164
|
+
} catch {}
|
|
165
|
+
}
|
|
166
|
+
if (await pathExists(rulesDir)) for (const oldFile of OLD_RULE_FILES) {
|
|
145
167
|
const oldPath = join(rulesDir, oldFile);
|
|
146
168
|
if (await pathExists(oldPath)) {
|
|
147
169
|
const { unlink } = await import("node:fs/promises");
|
|
@@ -224,4 +246,4 @@ async function addClaudeMdReference(projectRoot) {
|
|
|
224
246
|
}
|
|
225
247
|
}
|
|
226
248
|
//#endregion
|
|
227
|
-
export {
|
|
249
|
+
export { createPackageResolver as a, writeMcpConfig as c, addClaudeMdReference as i, IDE_CONFIGS as n, detectIdes as o, MCP_CONFIGS as r, installIdeRulesAndSkills as s, AGENT_SKILL_NAMES as t };
|
package/dist/index.mjs
CHANGED
|
@@ -5,19 +5,19 @@ import { defineCommand, runMain } from "citty";
|
|
|
5
5
|
runMain(defineCommand({
|
|
6
6
|
meta: {
|
|
7
7
|
name: "contentrain",
|
|
8
|
-
version: "0.4.
|
|
8
|
+
version: "0.4.3",
|
|
9
9
|
description: "Contentrain CLI — AI content governance infrastructure"
|
|
10
10
|
},
|
|
11
11
|
subCommands: {
|
|
12
|
-
init: () => import("./init-
|
|
12
|
+
init: () => import("./init-BVlisNcW.mjs").then((m) => m.default),
|
|
13
13
|
status: () => import("./status-CoHgz6HN.mjs").then((m) => m.default),
|
|
14
14
|
doctor: () => import("./doctor-DyKjAIKH.mjs").then((m) => m.default),
|
|
15
15
|
validate: () => import("./validate-B10L7RL7.mjs").then((m) => m.default),
|
|
16
16
|
serve: () => import("./serve-CNeFIQ1i.mjs").then((m) => m.default),
|
|
17
17
|
generate: () => import("./generate-DrUojrk8.mjs").then((m) => m.default),
|
|
18
18
|
diff: () => import("./diff--halNUpG.mjs").then((m) => m.default),
|
|
19
|
-
setup: () => import("./setup-
|
|
20
|
-
skills: () => import("./skills-
|
|
19
|
+
setup: () => import("./setup-4mS8RuCy.mjs").then((m) => m.default),
|
|
20
|
+
skills: () => import("./skills-4nhto0AZ.mjs").then((m) => m.default),
|
|
21
21
|
studio: () => import("./studio-CJUGiIMd.mjs").then((m) => m.default)
|
|
22
22
|
}
|
|
23
23
|
}));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as resolveProjectRoot, t as loadProjectContext } from "./context-An3xrvcP.mjs";
|
|
2
2
|
import { i as pc } from "./ui-B5mXontH.mjs";
|
|
3
|
-
import { a as
|
|
3
|
+
import { a as createPackageResolver, c as writeMcpConfig, i as addClaudeMdReference, n as IDE_CONFIGS, o as detectIdes, s as installIdeRulesAndSkills } from "./ide-4ZGiAtYB.mjs";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
import { confirm, intro, isCancel, log, multiselect, outro, select, spinner } from "@clack/prompts";
|
|
6
6
|
import { simpleGit } from "simple-git";
|
|
@@ -356,32 +356,25 @@ async function executeInit(projectRoot, opts) {
|
|
|
356
356
|
}
|
|
357
357
|
}
|
|
358
358
|
async function installRules(projectRoot) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
359
|
+
const resolveRuleFile = await createPackageResolver("@contentrain/rules", projectRoot);
|
|
360
|
+
const resolveSkillFile = await createPackageResolver("@contentrain/skills", projectRoot);
|
|
361
|
+
if (!resolveRuleFile && !resolveSkillFile) return;
|
|
362
|
+
const detectedIdeKeys = await detectIdes(projectRoot);
|
|
363
|
+
const noIDEDetected = detectedIdeKeys.length === 0;
|
|
364
|
+
for (const ideKey of detectedIdeKeys) {
|
|
365
|
+
const ide = IDE_CONFIGS[ideKey];
|
|
366
|
+
await installIdeRulesAndSkills(projectRoot, ide, resolveRuleFile, resolveSkillFile);
|
|
367
|
+
}
|
|
368
|
+
if (detectedIdeKeys.includes("claude-code")) await addClaudeMdReference(projectRoot);
|
|
369
|
+
if (noIDEDetected && resolveRuleFile) try {
|
|
370
|
+
const essentials = await readFile(resolveRuleFile("essential/contentrain-essentials.md"), "utf-8");
|
|
371
|
+
const dest = join(projectRoot, "CLAUDE.md");
|
|
372
|
+
await writeFile(dest, essentials, "utf-8");
|
|
373
|
+
const git = simpleGit(projectRoot);
|
|
374
|
+
await git.add(dest);
|
|
364
375
|
try {
|
|
365
|
-
|
|
366
|
-
resolveSkillFile = (p) => requireSkills.resolve(`@contentrain/skills/${p}`);
|
|
376
|
+
await git.commit("[contentrain] install AI rules");
|
|
367
377
|
} catch {}
|
|
368
|
-
const detectedIdeKeys = await detectIdes(projectRoot);
|
|
369
|
-
const noIDEDetected = detectedIdeKeys.length === 0;
|
|
370
|
-
for (const ideKey of detectedIdeKeys) {
|
|
371
|
-
const ide = IDE_CONFIGS[ideKey];
|
|
372
|
-
await installIdeRulesAndSkills(projectRoot, ide, resolveRuleFile, resolveSkillFile);
|
|
373
|
-
}
|
|
374
|
-
if (detectedIdeKeys.includes("claude-code")) await addClaudeMdReference(projectRoot);
|
|
375
|
-
if (noIDEDetected) {
|
|
376
|
-
const essentials = await readFile(resolveRuleFile("essential/contentrain-essentials.md"), "utf-8");
|
|
377
|
-
const dest = join(projectRoot, "CLAUDE.md");
|
|
378
|
-
await writeFile(dest, essentials, "utf-8");
|
|
379
|
-
const git = simpleGit(projectRoot);
|
|
380
|
-
await git.add(dest);
|
|
381
|
-
try {
|
|
382
|
-
await git.commit("[contentrain] install AI rules");
|
|
383
|
-
} catch {}
|
|
384
|
-
}
|
|
385
378
|
} catch {}
|
|
386
379
|
}
|
|
387
380
|
async function configureMcp(projectRoot) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as resolveProjectRoot, t as loadProjectContext } from "./context-An3xrvcP.mjs";
|
|
2
2
|
import { i as pc } from "./ui-B5mXontH.mjs";
|
|
3
|
-
import { a as
|
|
3
|
+
import { a as createPackageResolver, c as writeMcpConfig, n as IDE_CONFIGS, o as detectIdes, r as MCP_CONFIGS, s as installIdeRulesAndSkills } from "./ide-4ZGiAtYB.mjs";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
import { intro, log, outro, spinner } from "@clack/prompts";
|
|
6
6
|
//#region src/commands/setup.ts
|
|
@@ -69,19 +69,21 @@ var setup_default = defineCommand({
|
|
|
69
69
|
const mcpResult = await writeMcpConfig(projectRoot, agentKey);
|
|
70
70
|
let rulesStatus = "skipped";
|
|
71
71
|
const ideConfig = IDE_CONFIGS[agentKey];
|
|
72
|
-
if (ideConfig)
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
72
|
+
if (ideConfig) {
|
|
73
|
+
const resolveRuleFile = await createPackageResolver("@contentrain/rules", projectRoot);
|
|
74
|
+
const resolveSkillFile = await createPackageResolver("@contentrain/skills", projectRoot);
|
|
75
|
+
if (!resolveRuleFile && !resolveSkillFile) rulesStatus = "failed (install @contentrain/rules @contentrain/skills)";
|
|
76
|
+
else try {
|
|
77
|
+
const result = await installIdeRulesAndSkills(projectRoot, ideConfig, resolveRuleFile, resolveSkillFile);
|
|
78
|
+
const parts = [];
|
|
79
|
+
if (result.installed > 0) parts.push(`${result.installed} installed`);
|
|
80
|
+
if (result.updated > 0) parts.push(`${result.updated} updated`);
|
|
81
|
+
rulesStatus = parts.length > 0 ? parts.join(", ") : "up to date";
|
|
82
|
+
if (!resolveRuleFile) rulesStatus += " (rules package not found)";
|
|
83
|
+
if (!resolveSkillFile) rulesStatus += " (skills package not found)";
|
|
84
|
+
} catch (err) {
|
|
85
|
+
rulesStatus = `failed (${err instanceof Error ? err.message : String(err)})`;
|
|
86
|
+
}
|
|
85
87
|
}
|
|
86
88
|
results.push({
|
|
87
89
|
agent: agentKey,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as resolveProjectRoot } from "./context-An3xrvcP.mjs";
|
|
2
2
|
import { i as pc } from "./ui-B5mXontH.mjs";
|
|
3
|
-
import { a as
|
|
3
|
+
import { a as createPackageResolver, n as IDE_CONFIGS, o as detectIdes, s as installIdeRulesAndSkills, t as AGENT_SKILL_NAMES } from "./ide-4ZGiAtYB.mjs";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
import { intro, log, outro, spinner } from "@clack/prompts";
|
|
6
6
|
import { join } from "node:path";
|
|
@@ -37,21 +37,16 @@ var skills_default = defineCommand({
|
|
|
37
37
|
}
|
|
38
38
|
const s = spinner();
|
|
39
39
|
s.start("Installing skills and rules...");
|
|
40
|
+
const resolveRuleFile = await createPackageResolver("@contentrain/rules", projectRoot);
|
|
41
|
+
const resolveSkillFile = await createPackageResolver("@contentrain/skills", projectRoot);
|
|
42
|
+
if (!resolveRuleFile && !resolveSkillFile) {
|
|
43
|
+
s.stop("Failed");
|
|
44
|
+
log.error("Required packages not found. Install them:");
|
|
45
|
+
log.message(pc.cyan(" pnpm add -D @contentrain/skills @contentrain/rules"));
|
|
46
|
+
outro("");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
40
49
|
try {
|
|
41
|
-
const { createRequire } = await import("node:module");
|
|
42
|
-
const require = createRequire(import.meta.url);
|
|
43
|
-
const resolveRuleFile = (p) => require.resolve(`@contentrain/rules/${p}`);
|
|
44
|
-
let resolveSkillFile = null;
|
|
45
|
-
try {
|
|
46
|
-
const requireSkills = createRequire(import.meta.url);
|
|
47
|
-
resolveSkillFile = (p) => requireSkills.resolve(`@contentrain/skills/${p}`);
|
|
48
|
-
} catch {
|
|
49
|
-
s.stop("Failed");
|
|
50
|
-
log.error("@contentrain/skills package not found. Install it:");
|
|
51
|
-
log.message(pc.cyan(" pnpm add -D @contentrain/skills @contentrain/rules"));
|
|
52
|
-
outro("");
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
50
|
const detectedIdes = await detectIdes(projectRoot);
|
|
56
51
|
if (detectedIdes.length === 0) detectedIdes.push("claude-code");
|
|
57
52
|
let totalInstalled = 0;
|
|
@@ -66,6 +61,8 @@ var skills_default = defineCommand({
|
|
|
66
61
|
if (totalUpdated > 0) log.success(`Updated ${totalUpdated} skill(s)`);
|
|
67
62
|
if (totalInstalled > 0) log.success(`Installed ${totalInstalled} new skill(s)`);
|
|
68
63
|
if (totalInstalled === 0 && totalUpdated === 0) log.info("All skills are up to date");
|
|
64
|
+
if (!resolveRuleFile) log.warning("@contentrain/rules package not found — rules skipped");
|
|
65
|
+
if (!resolveSkillFile) log.warning("@contentrain/skills package not found — skills skipped");
|
|
69
66
|
outro("");
|
|
70
67
|
} catch (error) {
|
|
71
68
|
s.stop("Failed");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "contentrain",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "CLI for Contentrain — AI content governance infrastructure",
|
|
6
6
|
"type": "module",
|
|
@@ -46,8 +46,9 @@
|
|
|
46
46
|
"picocolors": "^1.1.0",
|
|
47
47
|
"simple-git": "^3.27.0",
|
|
48
48
|
"ws": "^8.18.0",
|
|
49
|
-
"@contentrain/rules": "0.3.
|
|
49
|
+
"@contentrain/rules": "0.3.3",
|
|
50
50
|
"@contentrain/mcp": "1.2.0",
|
|
51
|
+
"@contentrain/skills": "0.3.0",
|
|
51
52
|
"@contentrain/query": "5.1.4",
|
|
52
53
|
"@contentrain/types": "0.4.2"
|
|
53
54
|
},
|