This commit is contained in:
musistudio
2026-01-02 22:51:22 +08:00
parent 9309cc8655
commit 1579413f3d
16 changed files with 86 additions and 200 deletions

View File

@@ -51,7 +51,7 @@ async function listPresets(): Promise<void> {
const manifest = JSON5.parse(content);
// Extract metadata fields from manifest
const { Providers, Router, PORT, HOST, API_TIMEOUT_MS, PROXY_URL, LOG, LOG_LEVEL, StatusLine, NON_INTERACTIVE_MODE, requiredInputs, ...metadata } = manifest;
const { Providers, Router, PORT, HOST, API_TIMEOUT_MS, PROXY_URL, LOG, LOG_LEVEL, StatusLine, NON_INTERACTIVE_MODE, ...metadata } = manifest;
const name = metadata.name || dirName;
const description = metadata.description || '';

View File

@@ -234,7 +234,7 @@ export const createServer = async (config: any): Promise<any> => {
const manifest = JSON.parse(content);
// Extract metadata fields
const { Providers, Router, PORT, HOST, API_TIMEOUT_MS, PROXY_URL, LOG, LOG_LEVEL, StatusLine, NON_INTERACTIVE_MODE, requiredInputs, ...metadata } = manifest;
const { Providers, Router, PORT, HOST, API_TIMEOUT_MS, PROXY_URL, LOG, LOG_LEVEL, StatusLine, NON_INTERACTIVE_MODE, ...metadata } = manifest;
presets.push({
id: dirName, // Use directory name as unique identifier

View File

@@ -26,7 +26,6 @@ export interface ExportResult {
presetDir: string;
sanitizedConfig: any;
metadata: PresetMetadata;
requiredInputs: any[];
sanitizedCount: number;
}
@@ -41,8 +40,7 @@ export function createManifest(
presetName: string,
config: any,
sanitizedConfig: any,
options: ExportOptions,
requiredInputs: any[] = []
options: ExportOptions
): ManifestFile {
const metadata: PresetMetadata = {
name: presetName,
@@ -55,7 +53,6 @@ export function createManifest(
return {
...metadata,
...sanitizedConfig,
requiredInputs: options.includeSensitive ? undefined : requiredInputs,
};
}
@@ -81,13 +78,12 @@ export async function exportPreset(
};
// 2. Sanitize configuration
const { sanitizedConfig, requiredInputs, sanitizedCount } = await sanitizeConfig(config);
const { sanitizedConfig, sanitizedCount } = await sanitizeConfig(config);
// 3. Generate manifest.json (flattened structure)
const manifest: ManifestFile = {
...metadata,
...sanitizedConfig,
requiredInputs: options.includeSensitive ? undefined : requiredInputs,
};
// 4. Create preset directory
@@ -114,7 +110,6 @@ export async function exportPreset(
presetDir,
sanitizedConfig,
metadata,
requiredInputs,
sanitizedCount,
};
}

View File

@@ -2,7 +2,7 @@
* Sensitive field identification and sanitization functionality
*/
import { RequiredInput, SanitizeResult } from './types';
import { SanitizeResult } from './types';
// Sensitive field pattern list
const SENSITIVE_PATTERNS = [
@@ -88,17 +88,15 @@ function extractEnvVarName(value: string): string | null {
* Recursively traverse object to identify and sanitize sensitive fields
* @param config Configuration object
* @param path Current field path
* @param requiredInputs Required inputs array (cumulative)
* @param sanitizedCount Sanitized field count
*/
function sanitizeObject(
config: any,
path: string = '',
requiredInputs: RequiredInput[] = [],
sanitizedCount: number = 0
): { sanitized: any; requiredInputs: RequiredInput[]; count: number } {
): { sanitized: any; count: number } {
if (!config || typeof config !== 'object') {
return { sanitized: config, requiredInputs, count: sanitizedCount };
return { sanitized: config, count: sanitizedCount };
}
if (Array.isArray(config)) {
@@ -107,14 +105,12 @@ function sanitizeObject(
const result = sanitizeObject(
config[i],
path ? `${path}[${i}]` : `[${i}]`,
requiredInputs,
sanitizedCount
);
sanitizedArray.push(result.sanitized);
requiredInputs = result.requiredInputs;
sanitizedCount = result.count;
}
return { sanitized: sanitizedArray, requiredInputs, count: sanitizedCount };
return { sanitized: sanitizedArray, count: sanitizedCount };
}
const sanitizedObj: any = {};
@@ -126,15 +122,6 @@ function sanitizeObject(
// If value is already an environment variable, keep unchanged
if (isEnvPlaceholder(value)) {
sanitizedObj[key] = value;
// Still need to record as required input, but use existing environment variable
const envVarName = extractEnvVarName(value);
if (envVarName && !requiredInputs.some(input => input.id === currentPath)) {
requiredInputs.push({
id: currentPath,
prompt: `Enter ${key}`,
placeholder: envVarName,
});
}
} else {
// Sanitize: replace with environment variable placeholder
// Try to infer entity name from path
@@ -161,20 +148,12 @@ function sanitizeObject(
const envVarName = generateEnvVarName('global', entityName, key);
sanitizedObj[key] = `\${${envVarName}}`;
// Record as required input
requiredInputs.push({
id: currentPath,
prompt: `Enter ${key}`,
placeholder: envVarName,
});
sanitizedCount++;
}
} else if (typeof value === 'object' && value !== null) {
// Recursively process nested objects
const result = sanitizeObject(value, currentPath, requiredInputs, sanitizedCount);
const result = sanitizeObject(value, currentPath, sanitizedCount);
sanitizedObj[key] = result.sanitized;
requiredInputs = result.requiredInputs;
sanitizedCount = result.count;
} else {
// Keep original value
@@ -182,7 +161,7 @@ function sanitizeObject(
}
}
return { sanitized: sanitizedObj, requiredInputs, count: sanitizedCount };
return { sanitized: sanitizedObj, count: sanitizedCount };
}
/**
@@ -198,7 +177,6 @@ export async function sanitizeConfig(config: any): Promise<SanitizeResult> {
return {
sanitizedConfig: result.sanitized,
requiredInputs: result.requiredInputs,
sanitizedCount: result.count,
};
}

View File

@@ -147,6 +147,15 @@ export interface PresetConfigSection {
transformers?: TransformerConfig[];
StatusLine?: any;
NON_INTERACTIVE_MODE?: boolean;
// CLI-only fields (not used by server)
noServer?: boolean; // CLI: Whether to skip local server startup and use provider's API directly
claudeCodeSettings?: { // CLI: Claude Code specific settings
env?: Record<string, any>; // CLI: Environment variables to pass to Claude Code
statusLine?: any; // CLI: Status line configuration
[key: string]: any;
};
[key: string]: any;
}
@@ -244,7 +253,6 @@ export enum MergeStrategy {
// Sanitization result
export interface SanitizeResult {
sanitizedConfig: any;
requiredInputs: RequiredInput[];
sanitizedCount: number;
}