refactor: CI optimization, logging improvements, and codebase formatting (#456)

* fix(db): remove unique constraint on folder to support multi-channel agents

* ci: implement automated skill drift detection and self-healing PRs

* fix: align registration logic with Gavriel's feedback and fix build/test issues from Daniel Mi

* style: conform to prettier standards for CI validation

* test: fix branch naming inconsistency in CI (master vs main)

* fix(ci): robust module resolution by removing file extensions in scripts

* refactor(ci): simplify skill validation by removing redundant combination tests

* style: conform skills-engine to prettier, unify logging in index.ts and cleanup unused imports

* refactor: extract multi-channel DB changes to separate branch

Move channel column, folder suffix logic, and related migrations
to feat/multi-channel-db-v2 for independent review. This PR now
contains only CI/CD optimizations, Prettier formatting, and
logging improvements.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Gabi Simons
2026-02-25 23:13:36 +02:00
committed by GitHub
parent bd2e236f73
commit 11c201088b
76 changed files with 2333 additions and 1308 deletions

View File

@@ -19,7 +19,12 @@ import {
} from './manifest.js';
import { loadPathRemap, resolvePathRemap } from './path-remap.js';
import { mergeFile } from './merge.js';
import { computeFileHash, readState, recordSkillApplication, writeState } from './state.js';
import {
computeFileHash,
readState,
recordSkillApplication,
writeState,
} from './state.js';
import {
mergeDockerComposeServices,
mergeEnvAdditions,
@@ -116,11 +121,17 @@ export async function applySkill(skillDir: string): Promise<ApplyResult> {
try {
// --- Backup ---
const filesToBackup = [
...manifest.modifies.map((f) => path.join(projectRoot, resolvePathRemap(f, pathRemap))),
...manifest.adds.map((f) => path.join(projectRoot, resolvePathRemap(f, pathRemap))),
...manifest.modifies.map((f) =>
path.join(projectRoot, resolvePathRemap(f, pathRemap)),
),
...manifest.adds.map((f) =>
path.join(projectRoot, resolvePathRemap(f, pathRemap)),
),
...(manifest.file_ops || [])
.filter((op) => op.from)
.map((op) => path.join(projectRoot, resolvePathRemap(op.from!, pathRemap))),
.map((op) =>
path.join(projectRoot, resolvePathRemap(op.from!, pathRemap)),
),
path.join(projectRoot, 'package.json'),
path.join(projectRoot, 'package-lock.json'),
path.join(projectRoot, '.env.example'),
@@ -167,7 +178,12 @@ export async function applySkill(skillDir: string): Promise<ApplyResult> {
for (const relPath of manifest.modifies) {
const resolvedPath = resolvePathRemap(relPath, pathRemap);
const currentPath = path.join(projectRoot, resolvedPath);
const basePath = path.join(projectRoot, NANOCLAW_DIR, 'base', resolvedPath);
const basePath = path.join(
projectRoot,
NANOCLAW_DIR,
'base',
resolvedPath,
);
// skillPath uses original relPath — skill packages are never mutated
const skillPath = path.join(skillDir, 'modify', relPath);
@@ -259,7 +275,9 @@ export async function applySkill(skillDir: string): Promise<ApplyResult> {
for (const f of addedFiles) {
try {
if (fs.existsSync(f)) fs.unlinkSync(f);
} catch { /* best effort */ }
} catch {
/* best effort */
}
}
restoreBackup();
clearBackup();
@@ -311,7 +329,9 @@ export async function applySkill(skillDir: string): Promise<ApplyResult> {
for (const f of addedFiles) {
try {
if (fs.existsSync(f)) fs.unlinkSync(f);
} catch { /* best effort */ }
} catch {
/* best effort */
}
}
restoreBackup();
// Re-read state and remove the skill we just recorded
@@ -345,7 +365,9 @@ export async function applySkill(skillDir: string): Promise<ApplyResult> {
for (const f of addedFiles) {
try {
if (fs.existsSync(f)) fs.unlinkSync(f);
} catch { /* best effort */ }
} catch {
/* best effort */
}
}
restoreBackup();
clearBackup();
@@ -354,4 +376,3 @@ export async function applySkill(skillDir: string): Promise<ApplyResult> {
releaseLock();
}
}