@constraint/cli 0.3.6 → 0.3.7
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/package.json +1 -1
- package/src/cli.js +1 -1
- package/src/skills.js +30 -0
package/package.json
CHANGED
package/src/cli.js
CHANGED
package/src/skills.js
CHANGED
|
@@ -45,6 +45,35 @@ async function loadLock(scope, projectRoot) {
|
|
|
45
45
|
return scope === 'global' ? loadInstallations() : loadProjectInstallations(projectRoot);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
// Installed skill files are per-machine (symlinks into the canonical store);
|
|
49
|
+
// only skills-lock.json belongs in version control. Keep the project's
|
|
50
|
+
// .gitignore covering the generated paths, npm-style.
|
|
51
|
+
const GITIGNORE_ENTRIES = ['.constraint/', '.claude/skills/', '.agents/skills/'];
|
|
52
|
+
|
|
53
|
+
async function ensureProjectGitignore(projectRoot) {
|
|
54
|
+
try {
|
|
55
|
+
await fs.stat(path.join(projectRoot, '.git'));
|
|
56
|
+
} catch {
|
|
57
|
+
return; // not a git repository; nothing to manage
|
|
58
|
+
}
|
|
59
|
+
const gitignorePath = path.join(projectRoot, '.gitignore');
|
|
60
|
+
let existing = '';
|
|
61
|
+
try {
|
|
62
|
+
existing = await fs.readFile(gitignorePath, 'utf8');
|
|
63
|
+
} catch {
|
|
64
|
+
existing = '';
|
|
65
|
+
}
|
|
66
|
+
const lines = new Set(existing.split('\n').map((line) => line.trim()));
|
|
67
|
+
const missing = GITIGNORE_ENTRIES.filter(
|
|
68
|
+
(entry) => !lines.has(entry) && !lines.has(entry.slice(0, -1)),
|
|
69
|
+
);
|
|
70
|
+
if (!missing.length) return;
|
|
71
|
+
const block = `${missing.join('\n')}\n`;
|
|
72
|
+
const prefix = existing && !existing.endsWith('\n') ? '\n' : '';
|
|
73
|
+
const header = existing ? '\n# Constraint skill installs (commit skills-lock.json instead)\n' : '# Constraint skill installs (commit skills-lock.json instead)\n';
|
|
74
|
+
await fs.writeFile(gitignorePath, `${existing}${prefix}${header}${block}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
48
77
|
async function saveLock(scope, projectRoot, value) {
|
|
49
78
|
if (scope === 'global') return saveInstallations(value);
|
|
50
79
|
return saveProjectInstallations(projectRoot, value);
|
|
@@ -96,6 +125,7 @@ export async function installSkill(config, identifier, {
|
|
|
96
125
|
const lock = await loadLock(scope, root);
|
|
97
126
|
lock.lockfile_version = 1;
|
|
98
127
|
lock.installations ||= {};
|
|
128
|
+
if (scope === 'project') await ensureProjectGitignore(root);
|
|
99
129
|
const packageFiles = filesFromDetail(detail);
|
|
100
130
|
const contentHash = packageDigest(packageFiles);
|
|
101
131
|
const canonical = copy === true ? null : canonicalSkillPath({
|