 85bf1341f3
			
		
	
	85bf1341f3
	
	
	
		
			
			Frontend Enhancements: - Complete React TypeScript frontend with modern UI components - Distributed workflows management interface with real-time updates - Socket.IO integration for live agent status monitoring - Agent management dashboard with cluster visualization - Project management interface with metrics and task tracking - Responsive design with proper error handling and loading states Backend Infrastructure: - Distributed coordinator for multi-agent workflow orchestration - Cluster management API with comprehensive agent operations - Enhanced database models for agents and projects - Project service for filesystem-based project discovery - Performance monitoring and metrics collection - Comprehensive API documentation and error handling Documentation: - Complete distributed development guide (README_DISTRIBUTED.md) - Comprehensive development report with architecture insights - System configuration templates and deployment guides The platform now provides a complete web interface for managing the distributed AI cluster with real-time monitoring, workflow orchestration, and agent coordination capabilities. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			448 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			448 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict'
 | |
| 
 | |
| let Comment = require('./comment')
 | |
| let Declaration = require('./declaration')
 | |
| let Node = require('./node')
 | |
| let { isClean, my } = require('./symbols')
 | |
| 
 | |
| let AtRule, parse, Root, Rule
 | |
| 
 | |
| function cleanSource(nodes) {
 | |
|   return nodes.map(i => {
 | |
|     if (i.nodes) i.nodes = cleanSource(i.nodes)
 | |
|     delete i.source
 | |
|     return i
 | |
|   })
 | |
| }
 | |
| 
 | |
| function markTreeDirty(node) {
 | |
|   node[isClean] = false
 | |
|   if (node.proxyOf.nodes) {
 | |
|     for (let i of node.proxyOf.nodes) {
 | |
|       markTreeDirty(i)
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| class Container extends Node {
 | |
|   get first() {
 | |
|     if (!this.proxyOf.nodes) return undefined
 | |
|     return this.proxyOf.nodes[0]
 | |
|   }
 | |
| 
 | |
|   get last() {
 | |
|     if (!this.proxyOf.nodes) return undefined
 | |
|     return this.proxyOf.nodes[this.proxyOf.nodes.length - 1]
 | |
|   }
 | |
| 
 | |
|   append(...children) {
 | |
|     for (let child of children) {
 | |
|       let nodes = this.normalize(child, this.last)
 | |
|       for (let node of nodes) this.proxyOf.nodes.push(node)
 | |
|     }
 | |
| 
 | |
|     this.markDirty()
 | |
| 
 | |
|     return this
 | |
|   }
 | |
| 
 | |
|   cleanRaws(keepBetween) {
 | |
|     super.cleanRaws(keepBetween)
 | |
|     if (this.nodes) {
 | |
|       for (let node of this.nodes) node.cleanRaws(keepBetween)
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   each(callback) {
 | |
|     if (!this.proxyOf.nodes) return undefined
 | |
|     let iterator = this.getIterator()
 | |
| 
 | |
|     let index, result
 | |
|     while (this.indexes[iterator] < this.proxyOf.nodes.length) {
 | |
|       index = this.indexes[iterator]
 | |
|       result = callback(this.proxyOf.nodes[index], index)
 | |
|       if (result === false) break
 | |
| 
 | |
|       this.indexes[iterator] += 1
 | |
|     }
 | |
| 
 | |
|     delete this.indexes[iterator]
 | |
|     return result
 | |
|   }
 | |
| 
 | |
|   every(condition) {
 | |
|     return this.nodes.every(condition)
 | |
|   }
 | |
| 
 | |
|   getIterator() {
 | |
|     if (!this.lastEach) this.lastEach = 0
 | |
|     if (!this.indexes) this.indexes = {}
 | |
| 
 | |
|     this.lastEach += 1
 | |
|     let iterator = this.lastEach
 | |
|     this.indexes[iterator] = 0
 | |
| 
 | |
|     return iterator
 | |
|   }
 | |
| 
 | |
|   getProxyProcessor() {
 | |
|     return {
 | |
|       get(node, prop) {
 | |
|         if (prop === 'proxyOf') {
 | |
|           return node
 | |
|         } else if (!node[prop]) {
 | |
|           return node[prop]
 | |
|         } else if (
 | |
|           prop === 'each' ||
 | |
|           (typeof prop === 'string' && prop.startsWith('walk'))
 | |
|         ) {
 | |
|           return (...args) => {
 | |
|             return node[prop](
 | |
|               ...args.map(i => {
 | |
|                 if (typeof i === 'function') {
 | |
|                   return (child, index) => i(child.toProxy(), index)
 | |
|                 } else {
 | |
|                   return i
 | |
|                 }
 | |
|               })
 | |
|             )
 | |
|           }
 | |
|         } else if (prop === 'every' || prop === 'some') {
 | |
|           return cb => {
 | |
|             return node[prop]((child, ...other) =>
 | |
|               cb(child.toProxy(), ...other)
 | |
|             )
 | |
|           }
 | |
|         } else if (prop === 'root') {
 | |
|           return () => node.root().toProxy()
 | |
|         } else if (prop === 'nodes') {
 | |
|           return node.nodes.map(i => i.toProxy())
 | |
|         } else if (prop === 'first' || prop === 'last') {
 | |
|           return node[prop].toProxy()
 | |
|         } else {
 | |
|           return node[prop]
 | |
|         }
 | |
|       },
 | |
| 
 | |
|       set(node, prop, value) {
 | |
|         if (node[prop] === value) return true
 | |
|         node[prop] = value
 | |
|         if (prop === 'name' || prop === 'params' || prop === 'selector') {
 | |
|           node.markDirty()
 | |
|         }
 | |
|         return true
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   index(child) {
 | |
|     if (typeof child === 'number') return child
 | |
|     if (child.proxyOf) child = child.proxyOf
 | |
|     return this.proxyOf.nodes.indexOf(child)
 | |
|   }
 | |
| 
 | |
|   insertAfter(exist, add) {
 | |
|     let existIndex = this.index(exist)
 | |
|     let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse()
 | |
|     existIndex = this.index(exist)
 | |
|     for (let node of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node)
 | |
| 
 | |
|     let index
 | |
|     for (let id in this.indexes) {
 | |
|       index = this.indexes[id]
 | |
|       if (existIndex < index) {
 | |
|         this.indexes[id] = index + nodes.length
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     this.markDirty()
 | |
| 
 | |
|     return this
 | |
|   }
 | |
| 
 | |
|   insertBefore(exist, add) {
 | |
|     let existIndex = this.index(exist)
 | |
|     let type = existIndex === 0 ? 'prepend' : false
 | |
|     let nodes = this.normalize(
 | |
|       add,
 | |
|       this.proxyOf.nodes[existIndex],
 | |
|       type
 | |
|     ).reverse()
 | |
|     existIndex = this.index(exist)
 | |
|     for (let node of nodes) this.proxyOf.nodes.splice(existIndex, 0, node)
 | |
| 
 | |
|     let index
 | |
|     for (let id in this.indexes) {
 | |
|       index = this.indexes[id]
 | |
|       if (existIndex <= index) {
 | |
|         this.indexes[id] = index + nodes.length
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     this.markDirty()
 | |
| 
 | |
|     return this
 | |
|   }
 | |
| 
 | |
|   normalize(nodes, sample) {
 | |
|     if (typeof nodes === 'string') {
 | |
|       nodes = cleanSource(parse(nodes).nodes)
 | |
|     } else if (typeof nodes === 'undefined') {
 | |
|       nodes = []
 | |
|     } else if (Array.isArray(nodes)) {
 | |
|       nodes = nodes.slice(0)
 | |
|       for (let i of nodes) {
 | |
|         if (i.parent) i.parent.removeChild(i, 'ignore')
 | |
|       }
 | |
|     } else if (nodes.type === 'root' && this.type !== 'document') {
 | |
|       nodes = nodes.nodes.slice(0)
 | |
|       for (let i of nodes) {
 | |
|         if (i.parent) i.parent.removeChild(i, 'ignore')
 | |
|       }
 | |
|     } else if (nodes.type) {
 | |
|       nodes = [nodes]
 | |
|     } else if (nodes.prop) {
 | |
|       if (typeof nodes.value === 'undefined') {
 | |
|         throw new Error('Value field is missed in node creation')
 | |
|       } else if (typeof nodes.value !== 'string') {
 | |
|         nodes.value = String(nodes.value)
 | |
|       }
 | |
|       nodes = [new Declaration(nodes)]
 | |
|     } else if (nodes.selector || nodes.selectors) {
 | |
|       nodes = [new Rule(nodes)]
 | |
|     } else if (nodes.name) {
 | |
|       nodes = [new AtRule(nodes)]
 | |
|     } else if (nodes.text) {
 | |
|       nodes = [new Comment(nodes)]
 | |
|     } else {
 | |
|       throw new Error('Unknown node type in node creation')
 | |
|     }
 | |
| 
 | |
|     let processed = nodes.map(i => {
 | |
|       /* c8 ignore next */
 | |
|       if (!i[my]) Container.rebuild(i)
 | |
|       i = i.proxyOf
 | |
|       if (i.parent) i.parent.removeChild(i)
 | |
|       if (i[isClean]) markTreeDirty(i)
 | |
| 
 | |
|       if (!i.raws) i.raws = {}
 | |
|       if (typeof i.raws.before === 'undefined') {
 | |
|         if (sample && typeof sample.raws.before !== 'undefined') {
 | |
|           i.raws.before = sample.raws.before.replace(/\S/g, '')
 | |
|         }
 | |
|       }
 | |
|       i.parent = this.proxyOf
 | |
|       return i
 | |
|     })
 | |
| 
 | |
|     return processed
 | |
|   }
 | |
| 
 | |
|   prepend(...children) {
 | |
|     children = children.reverse()
 | |
|     for (let child of children) {
 | |
|       let nodes = this.normalize(child, this.first, 'prepend').reverse()
 | |
|       for (let node of nodes) this.proxyOf.nodes.unshift(node)
 | |
|       for (let id in this.indexes) {
 | |
|         this.indexes[id] = this.indexes[id] + nodes.length
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     this.markDirty()
 | |
| 
 | |
|     return this
 | |
|   }
 | |
| 
 | |
|   push(child) {
 | |
|     child.parent = this
 | |
|     this.proxyOf.nodes.push(child)
 | |
|     return this
 | |
|   }
 | |
| 
 | |
|   removeAll() {
 | |
|     for (let node of this.proxyOf.nodes) node.parent = undefined
 | |
|     this.proxyOf.nodes = []
 | |
| 
 | |
|     this.markDirty()
 | |
| 
 | |
|     return this
 | |
|   }
 | |
| 
 | |
|   removeChild(child) {
 | |
|     child = this.index(child)
 | |
|     this.proxyOf.nodes[child].parent = undefined
 | |
|     this.proxyOf.nodes.splice(child, 1)
 | |
| 
 | |
|     let index
 | |
|     for (let id in this.indexes) {
 | |
|       index = this.indexes[id]
 | |
|       if (index >= child) {
 | |
|         this.indexes[id] = index - 1
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     this.markDirty()
 | |
| 
 | |
|     return this
 | |
|   }
 | |
| 
 | |
|   replaceValues(pattern, opts, callback) {
 | |
|     if (!callback) {
 | |
|       callback = opts
 | |
|       opts = {}
 | |
|     }
 | |
| 
 | |
|     this.walkDecls(decl => {
 | |
|       if (opts.props && !opts.props.includes(decl.prop)) return
 | |
|       if (opts.fast && !decl.value.includes(opts.fast)) return
 | |
| 
 | |
|       decl.value = decl.value.replace(pattern, callback)
 | |
|     })
 | |
| 
 | |
|     this.markDirty()
 | |
| 
 | |
|     return this
 | |
|   }
 | |
| 
 | |
|   some(condition) {
 | |
|     return this.nodes.some(condition)
 | |
|   }
 | |
| 
 | |
|   walk(callback) {
 | |
|     return this.each((child, i) => {
 | |
|       let result
 | |
|       try {
 | |
|         result = callback(child, i)
 | |
|       } catch (e) {
 | |
|         throw child.addToError(e)
 | |
|       }
 | |
|       if (result !== false && child.walk) {
 | |
|         result = child.walk(callback)
 | |
|       }
 | |
| 
 | |
|       return result
 | |
|     })
 | |
|   }
 | |
| 
 | |
|   walkAtRules(name, callback) {
 | |
|     if (!callback) {
 | |
|       callback = name
 | |
|       return this.walk((child, i) => {
 | |
|         if (child.type === 'atrule') {
 | |
|           return callback(child, i)
 | |
|         }
 | |
|       })
 | |
|     }
 | |
|     if (name instanceof RegExp) {
 | |
|       return this.walk((child, i) => {
 | |
|         if (child.type === 'atrule' && name.test(child.name)) {
 | |
|           return callback(child, i)
 | |
|         }
 | |
|       })
 | |
|     }
 | |
|     return this.walk((child, i) => {
 | |
|       if (child.type === 'atrule' && child.name === name) {
 | |
|         return callback(child, i)
 | |
|       }
 | |
|     })
 | |
|   }
 | |
| 
 | |
|   walkComments(callback) {
 | |
|     return this.walk((child, i) => {
 | |
|       if (child.type === 'comment') {
 | |
|         return callback(child, i)
 | |
|       }
 | |
|     })
 | |
|   }
 | |
| 
 | |
|   walkDecls(prop, callback) {
 | |
|     if (!callback) {
 | |
|       callback = prop
 | |
|       return this.walk((child, i) => {
 | |
|         if (child.type === 'decl') {
 | |
|           return callback(child, i)
 | |
|         }
 | |
|       })
 | |
|     }
 | |
|     if (prop instanceof RegExp) {
 | |
|       return this.walk((child, i) => {
 | |
|         if (child.type === 'decl' && prop.test(child.prop)) {
 | |
|           return callback(child, i)
 | |
|         }
 | |
|       })
 | |
|     }
 | |
|     return this.walk((child, i) => {
 | |
|       if (child.type === 'decl' && child.prop === prop) {
 | |
|         return callback(child, i)
 | |
|       }
 | |
|     })
 | |
|   }
 | |
| 
 | |
|   walkRules(selector, callback) {
 | |
|     if (!callback) {
 | |
|       callback = selector
 | |
| 
 | |
|       return this.walk((child, i) => {
 | |
|         if (child.type === 'rule') {
 | |
|           return callback(child, i)
 | |
|         }
 | |
|       })
 | |
|     }
 | |
|     if (selector instanceof RegExp) {
 | |
|       return this.walk((child, i) => {
 | |
|         if (child.type === 'rule' && selector.test(child.selector)) {
 | |
|           return callback(child, i)
 | |
|         }
 | |
|       })
 | |
|     }
 | |
|     return this.walk((child, i) => {
 | |
|       if (child.type === 'rule' && child.selector === selector) {
 | |
|         return callback(child, i)
 | |
|       }
 | |
|     })
 | |
|   }
 | |
| }
 | |
| 
 | |
| Container.registerParse = dependant => {
 | |
|   parse = dependant
 | |
| }
 | |
| 
 | |
| Container.registerRule = dependant => {
 | |
|   Rule = dependant
 | |
| }
 | |
| 
 | |
| Container.registerAtRule = dependant => {
 | |
|   AtRule = dependant
 | |
| }
 | |
| 
 | |
| Container.registerRoot = dependant => {
 | |
|   Root = dependant
 | |
| }
 | |
| 
 | |
| module.exports = Container
 | |
| Container.default = Container
 | |
| 
 | |
| /* c8 ignore start */
 | |
| Container.rebuild = node => {
 | |
|   if (node.type === 'atrule') {
 | |
|     Object.setPrototypeOf(node, AtRule.prototype)
 | |
|   } else if (node.type === 'rule') {
 | |
|     Object.setPrototypeOf(node, Rule.prototype)
 | |
|   } else if (node.type === 'decl') {
 | |
|     Object.setPrototypeOf(node, Declaration.prototype)
 | |
|   } else if (node.type === 'comment') {
 | |
|     Object.setPrototypeOf(node, Comment.prototype)
 | |
|   } else if (node.type === 'root') {
 | |
|     Object.setPrototypeOf(node, Root.prototype)
 | |
|   }
 | |
| 
 | |
|   node[my] = true
 | |
| 
 | |
|   if (node.nodes) {
 | |
|     node.nodes.forEach(child => {
 | |
|       Container.rebuild(child)
 | |
|     })
 | |
|   }
 | |
| }
 | |
| /* c8 ignore stop */
 |