From 38bb57723fc2be3132676b6bc4e87926b93d54e4 Mon Sep 17 00:00:00 2001
From: emredursun
-
+
diff --git a/docs/architecture.md b/docs/architecture.md
index 9b6d86b..d96f76b 100644
--- a/docs/architecture.md
+++ b/docs/architecture.md
@@ -1,6 +1,6 @@
# Architecture
-Devran AI Kit v5.2.6 is an engineered framework with a **43-module runtime engine**, 26 agents, 39 skills, 40 commands, 25 workflows, and 15 governance rules.
+Devran AI Kit v5.2.7 is an engineered framework with a **43-module runtime engine**, 26 agents, 39 skills, 40 commands, 25 workflows, and 15 governance rules.
---
diff --git a/lib/updater.js b/lib/updater.js
index db44bd4..57cf0db 100644
--- a/lib/updater.js
+++ b/lib/updater.js
@@ -268,7 +268,16 @@ function applyUpdate(sourceRoot, targetRoot, dryRun = false) {
report.warnings.push(`Legacy gitignore cleanup failed: ${err.message}`);
}
- // Step 3: Regenerate worktree support files
+ // Step 3: Add any missing gitignore entries (bridges, configs, worktreeinclude)
+ try {
+ const { addToGitignore } = require('./io');
+ addToGitignore(targetRoot, detectedIDEs);
+ } catch (err) {
+ report.warnings = report.warnings || [];
+ report.warnings.push(`Gitignore entry addition failed: ${err.message}`);
+ }
+
+ // Step 4: Regenerate worktree support files
try {
const { generateWorktreeInclude, installPostCheckoutHook } = require('./worktree');
generateWorktreeInclude(targetRoot, detectedIDEs);
diff --git a/package-lock.json b/package-lock.json
index b8b5b14..da20fcc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@devran-ai/kit",
- "version": "5.2.6",
+ "version": "5.2.7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@devran-ai/kit",
- "version": "5.2.6",
+ "version": "5.2.7",
"hasInstallScript": true,
"license": "MIT",
"bin": {
diff --git a/package.json b/package.json
index 489d28e..46ee426 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@devran-ai/kit",
- "version": "5.2.6",
+ "version": "5.2.7",
"description": "Trust-grade AI development framework — zero-dependency runtime engine for agent orchestration, workflow governance, and skill management.",
"main": "bin/kit.js",
"bin": {
diff --git a/tests/unit/updater.test.js b/tests/unit/updater.test.js
index 6a70f48..cb69493 100644
--- a/tests/unit/updater.test.js
+++ b/tests/unit/updater.test.js
@@ -149,3 +149,53 @@ describe('CLI Updater — Non-Destructive Merge', () => {
expect(report.added.length).toBeGreaterThan(0);
});
});
+
+describe('CLI Updater — Gitignore Pipeline', () => {
+ beforeEach(() => { setupTestDirs(); });
+ afterEach(() => { teardownTestDirs(); });
+
+ it('should add missing .cursor/commands/ to gitignore during update', async () => {
+ // Simulate a project that has .gitignore with only .claude/ blanket ignore
+ const gitignorePath = path.join(TMP_TARGET, '.gitignore');
+ fs.writeFileSync(gitignorePath, 'node_modules/\n.claude/\n', 'utf-8');
+
+ const updater = await loadUpdater();
+ updater.applyUpdate(TMP_SOURCE, TMP_TARGET);
+
+ const content = fs.readFileSync(gitignorePath, 'utf-8');
+ // narrowBlanketClaudeIgnore should have narrowed .claude/ to .claude/commands/
+ expect(content).toContain('.claude/commands/');
+ // addToGitignore should have added .cursor/commands/ if cursor detected
+ expect(content).toContain('.agent/');
+ });
+
+ it('should narrow blanket .claude/ to .claude/commands/ during update', async () => {
+ const gitignorePath = path.join(TMP_TARGET, '.gitignore');
+ fs.writeFileSync(gitignorePath, 'node_modules/\n.claude/\n.agent/\n', 'utf-8');
+
+ const updater = await loadUpdater();
+ updater.applyUpdate(TMP_SOURCE, TMP_TARGET);
+
+ const content = fs.readFileSync(gitignorePath, 'utf-8');
+ // Should have narrowed blanket .claude/ to .claude/commands/
+ expect(content).toContain('.claude/commands/');
+ // Should not have the blanket pattern anymore
+ const lines = content.split('\n').map(l => l.trim());
+ expect(lines).not.toContain('.claude/');
+ });
+
+ it('should add gitignore entries even when no .gitignore exists', async () => {
+ const gitignorePath = path.join(TMP_TARGET, '.gitignore');
+ // Ensure no .gitignore exists
+ if (fs.existsSync(gitignorePath)) fs.unlinkSync(gitignorePath);
+
+ const updater = await loadUpdater();
+ updater.applyUpdate(TMP_SOURCE, TMP_TARGET);
+
+ // addToGitignore creates .gitignore if missing
+ expect(fs.existsSync(gitignorePath)).toBe(true);
+ const content = fs.readFileSync(gitignorePath, 'utf-8');
+ expect(content).toContain('.agent/');
+ expect(content).toContain('.claude/commands/');
+ });
+});