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

@@ -9,7 +9,11 @@ import path from 'path';
*/
// Helper: generate a plist string the same way service.ts does
function generatePlist(nodePath: string, projectRoot: string, homeDir: string): string {
function generatePlist(
nodePath: string,
projectRoot: string,
homeDir: string,
): string {
return `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
@@ -69,22 +73,38 @@ WantedBy=${isSystem ? 'multi-user.target' : 'default.target'}`;
describe('plist generation', () => {
it('contains the correct label', () => {
const plist = generatePlist('/usr/local/bin/node', '/home/user/nanoclaw', '/home/user');
const plist = generatePlist(
'/usr/local/bin/node',
'/home/user/nanoclaw',
'/home/user',
);
expect(plist).toContain('<string>com.nanoclaw</string>');
});
it('uses the correct node path', () => {
const plist = generatePlist('/opt/node/bin/node', '/home/user/nanoclaw', '/home/user');
const plist = generatePlist(
'/opt/node/bin/node',
'/home/user/nanoclaw',
'/home/user',
);
expect(plist).toContain('<string>/opt/node/bin/node</string>');
});
it('points to dist/index.js', () => {
const plist = generatePlist('/usr/local/bin/node', '/home/user/nanoclaw', '/home/user');
const plist = generatePlist(
'/usr/local/bin/node',
'/home/user/nanoclaw',
'/home/user',
);
expect(plist).toContain('/home/user/nanoclaw/dist/index.js');
});
it('sets log paths', () => {
const plist = generatePlist('/usr/local/bin/node', '/home/user/nanoclaw', '/home/user');
const plist = generatePlist(
'/usr/local/bin/node',
'/home/user/nanoclaw',
'/home/user',
);
expect(plist).toContain('nanoclaw.log');
expect(plist).toContain('nanoclaw.error.log');
});
@@ -92,24 +112,46 @@ describe('plist generation', () => {
describe('systemd unit generation', () => {
it('user unit uses default.target', () => {
const unit = generateSystemdUnit('/usr/bin/node', '/home/user/nanoclaw', '/home/user', false);
const unit = generateSystemdUnit(
'/usr/bin/node',
'/home/user/nanoclaw',
'/home/user',
false,
);
expect(unit).toContain('WantedBy=default.target');
});
it('system unit uses multi-user.target', () => {
const unit = generateSystemdUnit('/usr/bin/node', '/home/user/nanoclaw', '/home/user', true);
const unit = generateSystemdUnit(
'/usr/bin/node',
'/home/user/nanoclaw',
'/home/user',
true,
);
expect(unit).toContain('WantedBy=multi-user.target');
});
it('contains restart policy', () => {
const unit = generateSystemdUnit('/usr/bin/node', '/home/user/nanoclaw', '/home/user', false);
const unit = generateSystemdUnit(
'/usr/bin/node',
'/home/user/nanoclaw',
'/home/user',
false,
);
expect(unit).toContain('Restart=always');
expect(unit).toContain('RestartSec=5');
});
it('sets correct ExecStart', () => {
const unit = generateSystemdUnit('/usr/bin/node', '/srv/nanoclaw', '/home/user', false);
expect(unit).toContain('ExecStart=/usr/bin/node /srv/nanoclaw/dist/index.js');
const unit = generateSystemdUnit(
'/usr/bin/node',
'/srv/nanoclaw',
'/home/user',
false,
);
expect(unit).toContain(
'ExecStart=/usr/bin/node /srv/nanoclaw/dist/index.js',
);
});
});