tasq/node_modules/@claude-flow/codex/dist/generators/config-toml.js

910 lines
29 KiB
JavaScript

/**
* @claude-flow/codex - config.toml Generator
*
* Generates Codex CLI configuration files in TOML format
*/
/**
* Generate a config.toml file based on the provided options
*/
export async function generateConfigToml(options = {}) {
const { model = 'gpt-5.3-codex', approvalPolicy = 'on-request', sandboxMode = 'workspace-write', webSearch = 'cached', projectDocMaxBytes = 65536, features = {}, mcpServers = [], skills = [], profiles = {}, historyPersistence = 'save-all', security = {}, performance = {}, logging = {}, } = options;
const lines = [];
// Header
lines.push('# =============================================================================');
lines.push('# Claude Flow V3 - Codex Configuration');
lines.push('# =============================================================================');
lines.push('# Generated by: @claude-flow/codex');
lines.push('# Documentation: https://github.com/ruvnet/claude-flow');
lines.push('# ');
lines.push('# This file configures the Codex CLI for Claude Flow integration.');
lines.push('# Place in .agents/config.toml (project) or .codex/config.toml (user).');
lines.push('# =============================================================================');
lines.push('');
lines.push('# =============================================================================');
lines.push('# Core Settings');
lines.push('# =============================================================================');
lines.push('');
lines.push('# Model selection - the AI model to use for code generation');
lines.push('# Options: gpt-5.3-codex, gpt-4o, claude-sonnet, claude-opus');
lines.push(`model = "${model}"`);
lines.push('');
lines.push('# Approval policy determines when human approval is required');
lines.push('# - untrusted: Always require approval');
lines.push('# - on-failure: Require approval only after failures');
lines.push('# - on-request: Require approval for significant changes');
lines.push('# - never: Auto-approve all actions (use with caution)');
lines.push(`approval_policy = "${approvalPolicy}"`);
lines.push('');
lines.push('# Sandbox mode controls file system access');
lines.push('# - read-only: Can only read files, no modifications');
lines.push('# - workspace-write: Can write within workspace directory');
lines.push('# - danger-full-access: Full file system access (dangerous)');
lines.push(`sandbox_mode = "${sandboxMode}"`);
lines.push('');
lines.push('# Web search enables internet access for research');
lines.push('# - disabled: No web access');
lines.push('# - cached: Use cached results when available');
lines.push('# - live: Always fetch fresh results');
lines.push(`web_search = "${webSearch}"`);
lines.push('');
// Project Documentation
lines.push('# =============================================================================');
lines.push('# Project Documentation');
lines.push('# =============================================================================');
lines.push('');
lines.push('# Maximum bytes to read from AGENTS.md files');
lines.push(`project_doc_max_bytes = ${projectDocMaxBytes}`);
lines.push('');
lines.push('# Fallback filenames if AGENTS.md not found');
lines.push('project_doc_fallback_filenames = [');
lines.push(' "AGENTS.md",');
lines.push(' "TEAM_GUIDE.md",');
lines.push(' ".agents.md"');
lines.push(']');
lines.push('');
// Features
lines.push('# =============================================================================');
lines.push('# Features');
lines.push('# =============================================================================');
lines.push('');
lines.push('[features]');
lines.push('# Enable child AGENTS.md guidance');
lines.push(`child_agents_md = ${features.childAgentsMd ?? true}`);
lines.push('');
lines.push('# Cache shell environment for faster repeated commands');
lines.push(`shell_snapshot = ${features.shellSnapshot ?? true}`);
lines.push('');
lines.push('# Smart approvals based on request context');
lines.push(`request_rule = ${features.requestRule ?? true}`);
lines.push('');
lines.push('# Enable remote compaction for large histories');
lines.push(`remote_compaction = ${features.remoteCompaction ?? true}`);
lines.push('');
// MCP Servers
if (mcpServers.length > 0 || true) { // Always include claude-flow by default
lines.push('# =============================================================================');
lines.push('# MCP Servers');
lines.push('# =============================================================================');
lines.push('');
// Default claude-flow server
const hasClaudeFlow = mcpServers.some(s => s.name === 'claude-flow');
if (!hasClaudeFlow) {
lines.push(...generateMcpServer({
name: 'claude-flow',
command: 'npx',
args: ['-y', '@claude-flow/cli@latest'],
enabled: true,
toolTimeout: 120,
}));
lines.push('');
}
for (const server of mcpServers) {
lines.push(...generateMcpServer(server));
lines.push('');
}
}
// Skills Configuration
if (skills.length > 0) {
lines.push('# =============================================================================');
lines.push('# Skills Configuration');
lines.push('# =============================================================================');
lines.push('');
for (const skill of skills) {
lines.push(...generateSkillConfig(skill));
lines.push('');
}
}
// Profiles
lines.push('# =============================================================================');
lines.push('# Profiles');
lines.push('# =============================================================================');
lines.push('');
// Default profiles
const defaultProfiles = {
dev: {
approvalPolicy: 'never',
sandboxMode: 'danger-full-access',
webSearch: 'live',
},
safe: {
approvalPolicy: 'untrusted',
sandboxMode: 'read-only',
webSearch: 'disabled',
},
ci: {
approvalPolicy: 'never',
sandboxMode: 'workspace-write',
webSearch: 'cached',
},
...profiles,
};
for (const [name, profile] of Object.entries(defaultProfiles)) {
lines.push(...generateProfile(name, profile));
lines.push('');
}
// History
lines.push('# =============================================================================');
lines.push('# History');
lines.push('# =============================================================================');
lines.push('');
lines.push('[history]');
lines.push('# Save all session transcripts');
lines.push(`persistence = "${historyPersistence}"`);
lines.push('');
// Shell Environment Policy
lines.push('# =============================================================================');
lines.push('# Shell Environment');
lines.push('# =============================================================================');
lines.push('');
lines.push('[shell_environment_policy]');
lines.push('# Inherit environment variables');
lines.push('inherit = "core"');
lines.push('');
lines.push('# Exclude sensitive variables');
lines.push('exclude = ["*_KEY", "*_SECRET", "*_TOKEN", "*_PASSWORD"]');
lines.push('');
// Sandbox Workspace Write Settings
lines.push('# =============================================================================');
lines.push('# Sandbox Workspace Write Settings');
lines.push('# =============================================================================');
lines.push('');
lines.push('[sandbox_workspace_write]');
lines.push('# Additional writable paths beyond workspace');
lines.push('writable_roots = []');
lines.push('');
lines.push('# Allow network access');
lines.push('network_access = true');
lines.push('');
lines.push('# Exclude temp directories');
lines.push('exclude_slash_tmp = false');
lines.push('');
// Security Settings
lines.push('# =============================================================================');
lines.push('# Security Settings');
lines.push('# =============================================================================');
lines.push('');
lines.push('[security]');
lines.push('# Enable input validation for all user inputs');
lines.push(`input_validation = ${security.inputValidation ?? true}`);
lines.push('');
lines.push('# Prevent directory traversal attacks');
lines.push(`path_traversal_prevention = ${security.pathTraversal ?? true}`);
lines.push('');
lines.push('# Scan for hardcoded secrets');
lines.push(`secret_scanning = ${security.secretScanning ?? true}`);
lines.push('');
lines.push('# Scan dependencies for known CVEs');
lines.push(`cve_scanning = ${security.cveScanning ?? true}`);
lines.push('');
lines.push('# Maximum file size for operations (bytes)');
lines.push(`max_file_size = ${security.maxFileSize ?? 10485760}`);
lines.push('');
lines.push('# Allowed file extensions (empty = allow all)');
const allowedExts = security.allowedExtensions ?? [];
if (allowedExts.length > 0) {
lines.push(`allowed_extensions = [${allowedExts.map((e) => `"${e}"`).join(', ')}]`);
}
else {
lines.push('allowed_extensions = []');
}
lines.push('');
lines.push('# Blocked file patterns (regex)');
const blockedPatterns = security.blockedPatterns ?? ['\\.env$', 'credentials\\.json$', '\\.pem$', '\\.key$'];
lines.push(`blocked_patterns = [${blockedPatterns.map((p) => `"${escapeTomlString(p)}"`).join(', ')}]`);
lines.push('');
// Performance Settings
lines.push('# =============================================================================');
lines.push('# Performance Settings');
lines.push('# =============================================================================');
lines.push('');
lines.push('[performance]');
lines.push('# Maximum concurrent agents');
lines.push(`max_agents = ${performance.maxAgents ?? 8}`);
lines.push('');
lines.push('# Task timeout in seconds');
lines.push(`task_timeout = ${performance.taskTimeout ?? 300}`);
lines.push('');
lines.push('# Memory limit per agent');
lines.push(`memory_limit = "${performance.memoryLimit ?? '512MB'}"`);
lines.push('');
lines.push('# Enable response caching');
lines.push(`cache_enabled = ${performance.cacheEnabled ?? true}`);
lines.push('');
lines.push('# Cache TTL in seconds');
lines.push(`cache_ttl = ${performance.cacheTtl ?? 3600}`);
lines.push('');
lines.push('# Enable parallel task execution');
lines.push(`parallel_execution = ${performance.parallelExecution ?? true}`);
lines.push('');
// Logging Settings
lines.push('# =============================================================================');
lines.push('# Logging Settings');
lines.push('# =============================================================================');
lines.push('');
lines.push('[logging]');
lines.push('# Log level: debug, info, warn, error');
lines.push(`level = "${logging.level ?? 'info'}"`);
lines.push('');
lines.push('# Log format: json, text, pretty');
lines.push(`format = "${logging.format ?? 'pretty'}"`);
lines.push('');
lines.push('# Log destination: stdout, file, both');
lines.push(`destination = "${logging.destination ?? 'stdout'}"`);
lines.push('');
if (logging.filePath || logging.destination === 'file' || logging.destination === 'both') {
lines.push('# Log file path');
lines.push(`file_path = "${logging.filePath ?? './logs/claude-flow.log'}"`);
lines.push('');
lines.push('# Maximum number of log files to retain');
lines.push(`max_files = ${logging.maxFiles ?? 10}`);
lines.push('');
lines.push('# Maximum size per log file');
lines.push(`max_size = "${logging.maxSize ?? '10MB'}"`);
lines.push('');
}
// Neural/Intelligence Settings
lines.push('# =============================================================================');
lines.push('# Neural Intelligence Settings');
lines.push('# =============================================================================');
lines.push('');
lines.push('[neural]');
lines.push('# Enable SONA (Self-Optimizing Neural Architecture)');
lines.push('sona_enabled = true');
lines.push('');
lines.push('# Enable HNSW vector search');
lines.push('hnsw_enabled = true');
lines.push('');
lines.push('# HNSW index parameters');
lines.push('hnsw_m = 16');
lines.push('hnsw_ef_construction = 200');
lines.push('hnsw_ef_search = 100');
lines.push('');
lines.push('# Enable pattern learning');
lines.push('pattern_learning = true');
lines.push('');
lines.push('# Learning rate for neural adaptation');
lines.push('learning_rate = 0.01');
lines.push('');
// Swarm Settings
lines.push('# =============================================================================');
lines.push('# Swarm Orchestration Settings');
lines.push('# =============================================================================');
lines.push('');
lines.push('[swarm]');
lines.push('# Default topology: hierarchical, mesh, ring, star');
lines.push('default_topology = "hierarchical"');
lines.push('');
lines.push('# Default strategy: balanced, specialized, adaptive');
lines.push('default_strategy = "specialized"');
lines.push('');
lines.push('# Consensus algorithm: raft, byzantine, gossip');
lines.push('consensus = "raft"');
lines.push('');
lines.push('# Enable anti-drift measures');
lines.push('anti_drift = true');
lines.push('');
lines.push('# Checkpoint interval (tasks)');
lines.push('checkpoint_interval = 10');
lines.push('');
// Hooks Settings
lines.push('# =============================================================================');
lines.push('# Hooks Configuration');
lines.push('# =============================================================================');
lines.push('');
lines.push('[hooks]');
lines.push('# Enable lifecycle hooks');
lines.push('enabled = true');
lines.push('');
lines.push('# Pre-task hook');
lines.push('pre_task = true');
lines.push('');
lines.push('# Post-task hook (for learning)');
lines.push('post_task = true');
lines.push('');
lines.push('# Enable neural training on post-edit');
lines.push('train_on_edit = true');
lines.push('');
// Background Workers
lines.push('# =============================================================================');
lines.push('# Background Workers');
lines.push('# =============================================================================');
lines.push('');
lines.push('[workers]');
lines.push('# Enable background workers');
lines.push('enabled = true');
lines.push('');
lines.push('# Worker configuration');
lines.push('[workers.audit]');
lines.push('enabled = true');
lines.push('priority = "critical"');
lines.push('interval = 300');
lines.push('');
lines.push('[workers.optimize]');
lines.push('enabled = true');
lines.push('priority = "high"');
lines.push('interval = 600');
lines.push('');
lines.push('[workers.consolidate]');
lines.push('enabled = true');
lines.push('priority = "low"');
lines.push('interval = 1800');
lines.push('');
return lines.join('\n');
}
/**
* Escape special characters in TOML strings
*/
function escapeTomlString(str) {
return str
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
.replace(/\t/g, '\\t');
}
/**
* Generate MCP server configuration lines
*/
function generateMcpServer(server) {
const lines = [];
lines.push(`[mcp_servers.${server.name}]`);
lines.push(`command = "${server.command}"`);
if (server.args && server.args.length > 0) {
const argsStr = server.args.map(a => `"${a}"`).join(', ');
lines.push(`args = [${argsStr}]`);
}
lines.push(`enabled = ${server.enabled ?? true}`);
if (server.toolTimeout) {
lines.push(`tool_timeout_sec = ${server.toolTimeout}`);
}
if (server.env && Object.keys(server.env).length > 0) {
lines.push('');
lines.push(`[mcp_servers.${server.name}.env]`);
for (const [key, value] of Object.entries(server.env)) {
lines.push(`${key} = "${value}"`);
}
}
return lines;
}
/**
* Generate skill configuration lines
*/
function generateSkillConfig(skill) {
const lines = [];
lines.push('[[skills.config]]');
lines.push(`path = "${skill.path}"`);
lines.push(`enabled = ${skill.enabled ?? true}`);
return lines;
}
/**
* Generate profile configuration lines
*/
function generateProfile(name, profile) {
const lines = [];
const comment = name === 'dev' ? 'Development profile - more permissive for local work'
: name === 'safe' ? 'Safe profile - maximum restrictions'
: name === 'ci' ? 'CI profile - for automated pipelines'
: `${name} profile`;
lines.push(`# ${comment}`);
lines.push(`[profiles.${name}]`);
if (profile.approvalPolicy) {
lines.push(`approval_policy = "${profile.approvalPolicy}"`);
}
if (profile.sandboxMode) {
lines.push(`sandbox_mode = "${profile.sandboxMode}"`);
}
if (profile.webSearch) {
lines.push(`web_search = "${profile.webSearch}"`);
}
return lines;
}
/**
* Generate minimal config.toml
*/
export async function generateMinimalConfigToml(options = {}) {
const { model = 'gpt-5.3-codex', approvalPolicy = 'on-request', sandboxMode = 'workspace-write', } = options;
return `# Claude Flow V3 - Minimal Codex Configuration
model = "${model}"
approval_policy = "${approvalPolicy}"
sandbox_mode = "${sandboxMode}"
[mcp_servers.claude-flow]
command = "npx"
args = ["-y", "@claude-flow/cli@latest"]
enabled = true
`;
}
/**
* Generate CI/CD config.toml
*/
export async function generateCIConfigToml() {
return `# =============================================================================
# Claude Flow V3 - CI/CD Pipeline Configuration
# =============================================================================
# Optimized for automated CI/CD environments
# No interactive approvals, ephemeral history, minimal overhead
# =============================================================================
model = "gpt-5.3-codex"
approval_policy = "never"
sandbox_mode = "workspace-write"
web_search = "disabled"
# Project documentation
project_doc_max_bytes = 65536
[features]
# Disable interactive features for CI
shell_snapshot = false
remote_compaction = false
child_agents_md = true
request_rule = false
[mcp_servers.claude-flow]
command = "npx"
args = ["-y", "@claude-flow/cli@latest"]
enabled = true
tool_timeout_sec = 300
[history]
persistence = "none"
[shell_environment_policy]
inherit = "core"
exclude = ["*_KEY", "*_SECRET", "*_TOKEN", "*_PASSWORD", "CI_*"]
[security]
input_validation = true
path_traversal_prevention = true
secret_scanning = true
cve_scanning = true
[performance]
max_agents = 4
task_timeout = 600
cache_enabled = false
parallel_execution = true
[logging]
level = "info"
format = "json"
destination = "stdout"
[swarm]
default_topology = "hierarchical"
default_strategy = "specialized"
anti_drift = true
[hooks]
enabled = true
pre_task = true
post_task = false
train_on_edit = false
`;
}
/**
* Generate enterprise config.toml with full governance
*/
export async function generateEnterpriseConfigToml() {
return `# =============================================================================
# Claude Flow V3 - Enterprise Configuration
# =============================================================================
# Full governance, audit logging, and compliance features enabled
# Suitable for enterprise environments with strict security requirements
# =============================================================================
model = "gpt-5.3-codex"
approval_policy = "on-request"
sandbox_mode = "workspace-write"
web_search = "cached"
# Project documentation
project_doc_max_bytes = 131072
project_doc_fallback_filenames = [
"AGENTS.md",
"TEAM_GUIDE.md",
".agents.md",
"CONTRIBUTING.md"
]
[features]
child_agents_md = true
shell_snapshot = true
request_rule = true
remote_compaction = true
# =============================================================================
# MCP Servers
# =============================================================================
[mcp_servers.claude-flow]
command = "npx"
args = ["-y", "@claude-flow/cli@latest"]
enabled = true
tool_timeout_sec = 120
[mcp_servers.claude-flow.env]
CLAUDE_FLOW_LOG_LEVEL = "info"
# =============================================================================
# Profiles
# =============================================================================
# Development profile - more permissive for local work
[profiles.dev]
approval_policy = "never"
sandbox_mode = "danger-full-access"
web_search = "live"
# Safe profile - maximum restrictions
[profiles.safe]
approval_policy = "untrusted"
sandbox_mode = "read-only"
web_search = "disabled"
# CI profile - for automated pipelines
[profiles.ci]
approval_policy = "never"
sandbox_mode = "workspace-write"
web_search = "disabled"
# Production profile - careful changes only
[profiles.production]
approval_policy = "untrusted"
sandbox_mode = "workspace-write"
web_search = "cached"
# =============================================================================
# History
# =============================================================================
[history]
persistence = "save-all"
retention_days = 90
audit_log = true
# =============================================================================
# Shell Environment
# =============================================================================
[shell_environment_policy]
inherit = "core"
exclude = ["*_KEY", "*_SECRET", "*_TOKEN", "*_PASSWORD", "AWS_*", "AZURE_*"]
[sandbox_workspace_write]
writable_roots = []
network_access = true
exclude_slash_tmp = false
# =============================================================================
# Security (Enterprise)
# =============================================================================
[security]
input_validation = true
path_traversal_prevention = true
secret_scanning = true
cve_scanning = true
max_file_size = 10485760
blocked_patterns = ["\\\\.env$", "credentials\\\\.json$", "\\\\.pem$", "\\\\.key$", "secrets\\\\.yaml$"]
# RBAC configuration
[security.rbac]
enabled = true
default_role = "developer"
# Audit configuration
[security.audit]
enabled = true
destination = "file"
file_path = "./logs/audit.json"
retention_days = 90
# =============================================================================
# Performance
# =============================================================================
[performance]
max_agents = 8
task_timeout = 300
memory_limit = "1GB"
cache_enabled = true
cache_ttl = 3600
parallel_execution = true
# =============================================================================
# Logging (Enterprise)
# =============================================================================
[logging]
level = "info"
format = "json"
destination = "both"
file_path = "./logs/claude-flow.log"
max_files = 30
max_size = "50MB"
# =============================================================================
# Neural Intelligence
# =============================================================================
[neural]
sona_enabled = true
hnsw_enabled = true
hnsw_m = 16
hnsw_ef_construction = 200
hnsw_ef_search = 100
pattern_learning = true
learning_rate = 0.01
# =============================================================================
# Swarm Orchestration
# =============================================================================
[swarm]
default_topology = "hierarchical"
default_strategy = "specialized"
consensus = "raft"
anti_drift = true
checkpoint_interval = 10
# =============================================================================
# Hooks
# =============================================================================
[hooks]
enabled = true
pre_task = true
post_task = true
train_on_edit = true
# =============================================================================
# Background Workers
# =============================================================================
[workers]
enabled = true
[workers.audit]
enabled = true
priority = "critical"
interval = 300
[workers.optimize]
enabled = true
priority = "high"
interval = 600
[workers.consolidate]
enabled = true
priority = "low"
interval = 1800
[workers.testgaps]
enabled = true
priority = "normal"
interval = 3600
# =============================================================================
# Compliance
# =============================================================================
[compliance]
soc2 = true
gdpr = true
pci_dss = false
hipaa = false
`;
}
/**
* Generate development config.toml with permissive settings
*/
export async function generateDevConfigToml() {
return `# =============================================================================
# Claude Flow V3 - Development Configuration
# =============================================================================
# Permissive settings for local development
# Auto-approve most actions, full access, live web search
# =============================================================================
model = "gpt-5.3-codex"
approval_policy = "never"
sandbox_mode = "danger-full-access"
web_search = "live"
# Project documentation
project_doc_max_bytes = 65536
[features]
child_agents_md = true
shell_snapshot = true
request_rule = false
remote_compaction = true
[mcp_servers.claude-flow]
command = "npx"
args = ["-y", "@claude-flow/cli@latest"]
enabled = true
tool_timeout_sec = 120
[history]
persistence = "save-all"
[shell_environment_policy]
inherit = "all"
exclude = []
[sandbox_workspace_write]
writable_roots = ["/tmp", "~/.cache"]
network_access = true
exclude_slash_tmp = false
[security]
input_validation = true
path_traversal_prevention = true
secret_scanning = true
cve_scanning = false
[performance]
max_agents = 8
task_timeout = 600
cache_enabled = true
parallel_execution = true
[logging]
level = "debug"
format = "pretty"
destination = "stdout"
[neural]
sona_enabled = true
hnsw_enabled = true
pattern_learning = true
[swarm]
default_topology = "hierarchical"
default_strategy = "specialized"
anti_drift = true
[hooks]
enabled = true
pre_task = true
post_task = true
train_on_edit = true
[workers]
enabled = true
`;
}
/**
* Generate security-focused config.toml
*/
export async function generateSecureConfigToml() {
return `# =============================================================================
# Claude Flow V3 - Security-Focused Configuration
# =============================================================================
# Maximum security restrictions for sensitive environments
# All actions require approval, read-only access, no web search
# =============================================================================
model = "gpt-5.3-codex"
approval_policy = "untrusted"
sandbox_mode = "read-only"
web_search = "disabled"
# Project documentation
project_doc_max_bytes = 32768
[features]
child_agents_md = true
shell_snapshot = false
request_rule = true
remote_compaction = false
[mcp_servers.claude-flow]
command = "npx"
args = ["-y", "@claude-flow/cli@latest"]
enabled = true
tool_timeout_sec = 60
[history]
persistence = "save-all"
retention_days = 365
[shell_environment_policy]
inherit = "none"
exclude = ["*"]
[sandbox_workspace_write]
writable_roots = []
network_access = false
exclude_slash_tmp = true
[security]
input_validation = true
path_traversal_prevention = true
secret_scanning = true
cve_scanning = true
max_file_size = 1048576
allowed_extensions = [".ts", ".js", ".json", ".md", ".yaml", ".yml"]
blocked_patterns = ["\\\\.env", "secret", "credential", "password", "key", "token", "\\\\.pem", "\\\\.p12"]
[security.rbac]
enabled = true
default_role = "observer"
[security.audit]
enabled = true
destination = "both"
file_path = "./logs/security-audit.json"
retention_days = 365
[performance]
max_agents = 4
task_timeout = 120
cache_enabled = false
parallel_execution = false
[logging]
level = "info"
format = "json"
destination = "both"
file_path = "./logs/claude-flow.log"
max_files = 100
max_size = "10MB"
[neural]
sona_enabled = false
hnsw_enabled = true
pattern_learning = false
[swarm]
default_topology = "hierarchical"
default_strategy = "specialized"
consensus = "byzantine"
anti_drift = true
checkpoint_interval = 5
[hooks]
enabled = true
pre_task = true
post_task = true
train_on_edit = false
[workers]
enabled = true
[workers.audit]
enabled = true
priority = "critical"
interval = 60
[workers.optimize]
enabled = false
[workers.consolidate]
enabled = false
`;
}
//# sourceMappingURL=config-toml.js.map