feat: enhance AI commands and logging system

- Update @kevisual/query to 0.0.32 and @kevisual/router to 0.0.37
- Restructure AI command interface with run and deploy subcommands
- Add comprehensive logging throughout cmd-execution flow
- Improve sync module with better configuration handling
- Add clickable link functionality in logger
- Enhance error handling and debugging capabilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-10 17:45:09 +08:00
parent 5b83f7a6d1
commit 4aeb3637bf
13 changed files with 167 additions and 73 deletions

View File

@@ -1,6 +1,6 @@
import path from 'node:path';
import fs from 'node:fs';
import { Config, SyncList, SyncConfigType } from './type.ts';
import { Config, SyncList, SyncConfigType, SyncConfig } from './type.ts';
import { fileIsExist } from '@/uitls/file.ts';
import { getHash } from '@/uitls/hash.ts';
import glob from 'fast-glob';
@@ -32,6 +32,15 @@ export class SyncBase {
this.baseURL = opts?.baseURL ?? '';
this.init();
}
get dir() {
return this.#dir;
}
get configFilename() {
return this.#filename;
}
get configPath() {
return path.join(this.#dir, this.#filename);
}
async init() {
try {
const dir = this.#dir;
@@ -120,38 +129,67 @@ export class SyncBase {
return syncList;
}
async getCheckList() {
const checkDir = this.config?.checkDir || {};
const checkDir = this.config?.clone || {};
const dirKeys = Object.keys(checkDir);
const registry = this.config?.registry || '';
const files = dirKeys.map((key) => {
return { key, ...this.getRelativePath(key) };
});
return files
.map((item) => {
if (!item) return;
let auth = checkAuth(checkDir[item.key]?.url, this.baseURL);
let url = checkDir[item.key]?.url || registry;
let auth = checkAuth(url, this.baseURL);
return {
key: item.key,
...checkDir[item.key],
url: url,
filepath: item?.absolute,
auth,
};
})
.filter((item) => item);
}
/**
* sync 是已有的,优先级高于 fileSync
*
* @param sync
* @param fileSync
* @returns
*/
getMergeSync(sync: Config['sync'] = {}, fileSync: Config['sync'] = {}) {
const syncFileSyncKeys = Object.keys(fileSync);
const syncKeys = Object.keys(sync);
const config = this.config!;
const registry = config?.registry;
const keys = [...syncKeys, ...syncFileSyncKeys];
const obj: Config['sync'] = {};
const wrapperRegistry = (value: SyncConfig | string) => {
if (typeof value === 'object') {
const url = value.url;
if (registry && !url.startsWith('http')) {
return {
...value,
url: registry.replace(/\/+$/g, '') + '/' + url.replace(/^\/+/g, ''),
};
}
return value;
}
const url = value;
if (registry && !url.startsWith('http')) {
return registry.replace(/\/+$/g, '') + '/' + url.replace(/^\/+/g, '');
}
return url;
}
for (let key of keys) {
const value = sync[key] ?? fileSync[key];
obj[key] = value;
obj[key] = wrapperRegistry(value);
}
return obj;
}
async getSyncDirectoryList() {
const config = this.config;
const syncDirectory = config?.syncDirectory || [];
const syncDirectory = config?.syncd || [];
let obj: Record<string, any> = {};
const keys: string[] = [];
for (let item of syncDirectory) {