 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>
		
			
				
	
	
		
			489 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			489 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| const XHTMLEntities = require('./xhtml');
 | |
| 
 | |
| const hexNumber = /^[\da-fA-F]+$/;
 | |
| const decimalNumber = /^\d+$/;
 | |
| 
 | |
| // The map to `acorn-jsx` tokens from `acorn` namespace objects.
 | |
| const acornJsxMap = new WeakMap();
 | |
| 
 | |
| // Get the original tokens for the given `acorn` namespace object.
 | |
| function getJsxTokens(acorn) {
 | |
|   acorn = acorn.Parser.acorn || acorn;
 | |
|   let acornJsx = acornJsxMap.get(acorn);
 | |
|   if (!acornJsx) {
 | |
|     const tt = acorn.tokTypes;
 | |
|     const TokContext = acorn.TokContext;
 | |
|     const TokenType = acorn.TokenType;
 | |
|     const tc_oTag = new TokContext('<tag', false);
 | |
|     const tc_cTag = new TokContext('</tag', false);
 | |
|     const tc_expr = new TokContext('<tag>...</tag>', true, true);
 | |
|     const tokContexts = {
 | |
|       tc_oTag: tc_oTag,
 | |
|       tc_cTag: tc_cTag,
 | |
|       tc_expr: tc_expr
 | |
|     };
 | |
|     const tokTypes = {
 | |
|       jsxName: new TokenType('jsxName'),
 | |
|       jsxText: new TokenType('jsxText', {beforeExpr: true}),
 | |
|       jsxTagStart: new TokenType('jsxTagStart', {startsExpr: true}),
 | |
|       jsxTagEnd: new TokenType('jsxTagEnd')
 | |
|     };
 | |
| 
 | |
|     tokTypes.jsxTagStart.updateContext = function() {
 | |
|       this.context.push(tc_expr); // treat as beginning of JSX expression
 | |
|       this.context.push(tc_oTag); // start opening tag context
 | |
|       this.exprAllowed = false;
 | |
|     };
 | |
|     tokTypes.jsxTagEnd.updateContext = function(prevType) {
 | |
|       let out = this.context.pop();
 | |
|       if (out === tc_oTag && prevType === tt.slash || out === tc_cTag) {
 | |
|         this.context.pop();
 | |
|         this.exprAllowed = this.curContext() === tc_expr;
 | |
|       } else {
 | |
|         this.exprAllowed = true;
 | |
|       }
 | |
|     };
 | |
| 
 | |
|     acornJsx = { tokContexts: tokContexts, tokTypes: tokTypes };
 | |
|     acornJsxMap.set(acorn, acornJsx);
 | |
|   }
 | |
| 
 | |
|   return acornJsx;
 | |
| }
 | |
| 
 | |
| // Transforms JSX element name to string.
 | |
| 
 | |
| function getQualifiedJSXName(object) {
 | |
|   if (!object)
 | |
|     return object;
 | |
| 
 | |
|   if (object.type === 'JSXIdentifier')
 | |
|     return object.name;
 | |
| 
 | |
|   if (object.type === 'JSXNamespacedName')
 | |
|     return object.namespace.name + ':' + object.name.name;
 | |
| 
 | |
|   if (object.type === 'JSXMemberExpression')
 | |
|     return getQualifiedJSXName(object.object) + '.' +
 | |
|     getQualifiedJSXName(object.property);
 | |
| }
 | |
| 
 | |
| module.exports = function(options) {
 | |
|   options = options || {};
 | |
|   return function(Parser) {
 | |
|     return plugin({
 | |
|       allowNamespaces: options.allowNamespaces !== false,
 | |
|       allowNamespacedObjects: !!options.allowNamespacedObjects
 | |
|     }, Parser);
 | |
|   };
 | |
| };
 | |
| 
 | |
| // This is `tokTypes` of the peer dep.
 | |
| // This can be different instances from the actual `tokTypes` this plugin uses.
 | |
| Object.defineProperty(module.exports, "tokTypes", {
 | |
|   get: function get_tokTypes() {
 | |
|     return getJsxTokens(require("acorn")).tokTypes;
 | |
|   },
 | |
|   configurable: true,
 | |
|   enumerable: true
 | |
| });
 | |
| 
 | |
| function plugin(options, Parser) {
 | |
|   const acorn = Parser.acorn || require("acorn");
 | |
|   const acornJsx = getJsxTokens(acorn);
 | |
|   const tt = acorn.tokTypes;
 | |
|   const tok = acornJsx.tokTypes;
 | |
|   const tokContexts = acorn.tokContexts;
 | |
|   const tc_oTag = acornJsx.tokContexts.tc_oTag;
 | |
|   const tc_cTag = acornJsx.tokContexts.tc_cTag;
 | |
|   const tc_expr = acornJsx.tokContexts.tc_expr;
 | |
|   const isNewLine = acorn.isNewLine;
 | |
|   const isIdentifierStart = acorn.isIdentifierStart;
 | |
|   const isIdentifierChar = acorn.isIdentifierChar;
 | |
| 
 | |
|   return class extends Parser {
 | |
|     // Expose actual `tokTypes` and `tokContexts` to other plugins.
 | |
|     static get acornJsx() {
 | |
|       return acornJsx;
 | |
|     }
 | |
| 
 | |
|     // Reads inline JSX contents token.
 | |
|     jsx_readToken() {
 | |
|       let out = '', chunkStart = this.pos;
 | |
|       for (;;) {
 | |
|         if (this.pos >= this.input.length)
 | |
|           this.raise(this.start, 'Unterminated JSX contents');
 | |
|         let ch = this.input.charCodeAt(this.pos);
 | |
| 
 | |
|         switch (ch) {
 | |
|         case 60: // '<'
 | |
|         case 123: // '{'
 | |
|           if (this.pos === this.start) {
 | |
|             if (ch === 60 && this.exprAllowed) {
 | |
|               ++this.pos;
 | |
|               return this.finishToken(tok.jsxTagStart);
 | |
|             }
 | |
|             return this.getTokenFromCode(ch);
 | |
|           }
 | |
|           out += this.input.slice(chunkStart, this.pos);
 | |
|           return this.finishToken(tok.jsxText, out);
 | |
| 
 | |
|         case 38: // '&'
 | |
|           out += this.input.slice(chunkStart, this.pos);
 | |
|           out += this.jsx_readEntity();
 | |
|           chunkStart = this.pos;
 | |
|           break;
 | |
| 
 | |
|         case 62: // '>'
 | |
|         case 125: // '}'
 | |
|           this.raise(
 | |
|             this.pos,
 | |
|             "Unexpected token `" + this.input[this.pos] + "`. Did you mean `" +
 | |
|               (ch === 62 ? ">" : "}") + "` or " + "`{\"" + this.input[this.pos] + "\"}" + "`?"
 | |
|           );
 | |
| 
 | |
|         default:
 | |
|           if (isNewLine(ch)) {
 | |
|             out += this.input.slice(chunkStart, this.pos);
 | |
|             out += this.jsx_readNewLine(true);
 | |
|             chunkStart = this.pos;
 | |
|           } else {
 | |
|             ++this.pos;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     jsx_readNewLine(normalizeCRLF) {
 | |
|       let ch = this.input.charCodeAt(this.pos);
 | |
|       let out;
 | |
|       ++this.pos;
 | |
|       if (ch === 13 && this.input.charCodeAt(this.pos) === 10) {
 | |
|         ++this.pos;
 | |
|         out = normalizeCRLF ? '\n' : '\r\n';
 | |
|       } else {
 | |
|         out = String.fromCharCode(ch);
 | |
|       }
 | |
|       if (this.options.locations) {
 | |
|         ++this.curLine;
 | |
|         this.lineStart = this.pos;
 | |
|       }
 | |
| 
 | |
|       return out;
 | |
|     }
 | |
| 
 | |
|     jsx_readString(quote) {
 | |
|       let out = '', chunkStart = ++this.pos;
 | |
|       for (;;) {
 | |
|         if (this.pos >= this.input.length)
 | |
|           this.raise(this.start, 'Unterminated string constant');
 | |
|         let ch = this.input.charCodeAt(this.pos);
 | |
|         if (ch === quote) break;
 | |
|         if (ch === 38) { // '&'
 | |
|           out += this.input.slice(chunkStart, this.pos);
 | |
|           out += this.jsx_readEntity();
 | |
|           chunkStart = this.pos;
 | |
|         } else if (isNewLine(ch)) {
 | |
|           out += this.input.slice(chunkStart, this.pos);
 | |
|           out += this.jsx_readNewLine(false);
 | |
|           chunkStart = this.pos;
 | |
|         } else {
 | |
|           ++this.pos;
 | |
|         }
 | |
|       }
 | |
|       out += this.input.slice(chunkStart, this.pos++);
 | |
|       return this.finishToken(tt.string, out);
 | |
|     }
 | |
| 
 | |
|     jsx_readEntity() {
 | |
|       let str = '', count = 0, entity;
 | |
|       let ch = this.input[this.pos];
 | |
|       if (ch !== '&')
 | |
|         this.raise(this.pos, 'Entity must start with an ampersand');
 | |
|       let startPos = ++this.pos;
 | |
|       while (this.pos < this.input.length && count++ < 10) {
 | |
|         ch = this.input[this.pos++];
 | |
|         if (ch === ';') {
 | |
|           if (str[0] === '#') {
 | |
|             if (str[1] === 'x') {
 | |
|               str = str.substr(2);
 | |
|               if (hexNumber.test(str))
 | |
|                 entity = String.fromCharCode(parseInt(str, 16));
 | |
|             } else {
 | |
|               str = str.substr(1);
 | |
|               if (decimalNumber.test(str))
 | |
|                 entity = String.fromCharCode(parseInt(str, 10));
 | |
|             }
 | |
|           } else {
 | |
|             entity = XHTMLEntities[str];
 | |
|           }
 | |
|           break;
 | |
|         }
 | |
|         str += ch;
 | |
|       }
 | |
|       if (!entity) {
 | |
|         this.pos = startPos;
 | |
|         return '&';
 | |
|       }
 | |
|       return entity;
 | |
|     }
 | |
| 
 | |
|     // Read a JSX identifier (valid tag or attribute name).
 | |
|     //
 | |
|     // Optimized version since JSX identifiers can't contain
 | |
|     // escape characters and so can be read as single slice.
 | |
|     // Also assumes that first character was already checked
 | |
|     // by isIdentifierStart in readToken.
 | |
| 
 | |
|     jsx_readWord() {
 | |
|       let ch, start = this.pos;
 | |
|       do {
 | |
|         ch = this.input.charCodeAt(++this.pos);
 | |
|       } while (isIdentifierChar(ch) || ch === 45); // '-'
 | |
|       return this.finishToken(tok.jsxName, this.input.slice(start, this.pos));
 | |
|     }
 | |
| 
 | |
|     // Parse next token as JSX identifier
 | |
| 
 | |
|     jsx_parseIdentifier() {
 | |
|       let node = this.startNode();
 | |
|       if (this.type === tok.jsxName)
 | |
|         node.name = this.value;
 | |
|       else if (this.type.keyword)
 | |
|         node.name = this.type.keyword;
 | |
|       else
 | |
|         this.unexpected();
 | |
|       this.next();
 | |
|       return this.finishNode(node, 'JSXIdentifier');
 | |
|     }
 | |
| 
 | |
|     // Parse namespaced identifier.
 | |
| 
 | |
|     jsx_parseNamespacedName() {
 | |
|       let startPos = this.start, startLoc = this.startLoc;
 | |
|       let name = this.jsx_parseIdentifier();
 | |
|       if (!options.allowNamespaces || !this.eat(tt.colon)) return name;
 | |
|       var node = this.startNodeAt(startPos, startLoc);
 | |
|       node.namespace = name;
 | |
|       node.name = this.jsx_parseIdentifier();
 | |
|       return this.finishNode(node, 'JSXNamespacedName');
 | |
|     }
 | |
| 
 | |
|     // Parses element name in any form - namespaced, member
 | |
|     // or single identifier.
 | |
| 
 | |
|     jsx_parseElementName() {
 | |
|       if (this.type === tok.jsxTagEnd) return '';
 | |
|       let startPos = this.start, startLoc = this.startLoc;
 | |
|       let node = this.jsx_parseNamespacedName();
 | |
|       if (this.type === tt.dot && node.type === 'JSXNamespacedName' && !options.allowNamespacedObjects) {
 | |
|         this.unexpected();
 | |
|       }
 | |
|       while (this.eat(tt.dot)) {
 | |
|         let newNode = this.startNodeAt(startPos, startLoc);
 | |
|         newNode.object = node;
 | |
|         newNode.property = this.jsx_parseIdentifier();
 | |
|         node = this.finishNode(newNode, 'JSXMemberExpression');
 | |
|       }
 | |
|       return node;
 | |
|     }
 | |
| 
 | |
|     // Parses any type of JSX attribute value.
 | |
| 
 | |
|     jsx_parseAttributeValue() {
 | |
|       switch (this.type) {
 | |
|       case tt.braceL:
 | |
|         let node = this.jsx_parseExpressionContainer();
 | |
|         if (node.expression.type === 'JSXEmptyExpression')
 | |
|           this.raise(node.start, 'JSX attributes must only be assigned a non-empty expression');
 | |
|         return node;
 | |
| 
 | |
|       case tok.jsxTagStart:
 | |
|       case tt.string:
 | |
|         return this.parseExprAtom();
 | |
| 
 | |
|       default:
 | |
|         this.raise(this.start, 'JSX value should be either an expression or a quoted JSX text');
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // JSXEmptyExpression is unique type since it doesn't actually parse anything,
 | |
|     // and so it should start at the end of last read token (left brace) and finish
 | |
|     // at the beginning of the next one (right brace).
 | |
| 
 | |
|     jsx_parseEmptyExpression() {
 | |
|       let node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc);
 | |
|       return this.finishNodeAt(node, 'JSXEmptyExpression', this.start, this.startLoc);
 | |
|     }
 | |
| 
 | |
|     // Parses JSX expression enclosed into curly brackets.
 | |
| 
 | |
|     jsx_parseExpressionContainer() {
 | |
|       let node = this.startNode();
 | |
|       this.next();
 | |
|       node.expression = this.type === tt.braceR
 | |
|         ? this.jsx_parseEmptyExpression()
 | |
|         : this.parseExpression();
 | |
|       this.expect(tt.braceR);
 | |
|       return this.finishNode(node, 'JSXExpressionContainer');
 | |
|     }
 | |
| 
 | |
|     // Parses following JSX attribute name-value pair.
 | |
| 
 | |
|     jsx_parseAttribute() {
 | |
|       let node = this.startNode();
 | |
|       if (this.eat(tt.braceL)) {
 | |
|         this.expect(tt.ellipsis);
 | |
|         node.argument = this.parseMaybeAssign();
 | |
|         this.expect(tt.braceR);
 | |
|         return this.finishNode(node, 'JSXSpreadAttribute');
 | |
|       }
 | |
|       node.name = this.jsx_parseNamespacedName();
 | |
|       node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null;
 | |
|       return this.finishNode(node, 'JSXAttribute');
 | |
|     }
 | |
| 
 | |
|     // Parses JSX opening tag starting after '<'.
 | |
| 
 | |
|     jsx_parseOpeningElementAt(startPos, startLoc) {
 | |
|       let node = this.startNodeAt(startPos, startLoc);
 | |
|       node.attributes = [];
 | |
|       let nodeName = this.jsx_parseElementName();
 | |
|       if (nodeName) node.name = nodeName;
 | |
|       while (this.type !== tt.slash && this.type !== tok.jsxTagEnd)
 | |
|         node.attributes.push(this.jsx_parseAttribute());
 | |
|       node.selfClosing = this.eat(tt.slash);
 | |
|       this.expect(tok.jsxTagEnd);
 | |
|       return this.finishNode(node, nodeName ? 'JSXOpeningElement' : 'JSXOpeningFragment');
 | |
|     }
 | |
| 
 | |
|     // Parses JSX closing tag starting after '</'.
 | |
| 
 | |
|     jsx_parseClosingElementAt(startPos, startLoc) {
 | |
|       let node = this.startNodeAt(startPos, startLoc);
 | |
|       let nodeName = this.jsx_parseElementName();
 | |
|       if (nodeName) node.name = nodeName;
 | |
|       this.expect(tok.jsxTagEnd);
 | |
|       return this.finishNode(node, nodeName ? 'JSXClosingElement' : 'JSXClosingFragment');
 | |
|     }
 | |
| 
 | |
|     // Parses entire JSX element, including it's opening tag
 | |
|     // (starting after '<'), attributes, contents and closing tag.
 | |
| 
 | |
|     jsx_parseElementAt(startPos, startLoc) {
 | |
|       let node = this.startNodeAt(startPos, startLoc);
 | |
|       let children = [];
 | |
|       let openingElement = this.jsx_parseOpeningElementAt(startPos, startLoc);
 | |
|       let closingElement = null;
 | |
| 
 | |
|       if (!openingElement.selfClosing) {
 | |
|         contents: for (;;) {
 | |
|           switch (this.type) {
 | |
|           case tok.jsxTagStart:
 | |
|             startPos = this.start; startLoc = this.startLoc;
 | |
|             this.next();
 | |
|             if (this.eat(tt.slash)) {
 | |
|               closingElement = this.jsx_parseClosingElementAt(startPos, startLoc);
 | |
|               break contents;
 | |
|             }
 | |
|             children.push(this.jsx_parseElementAt(startPos, startLoc));
 | |
|             break;
 | |
| 
 | |
|           case tok.jsxText:
 | |
|             children.push(this.parseExprAtom());
 | |
|             break;
 | |
| 
 | |
|           case tt.braceL:
 | |
|             children.push(this.jsx_parseExpressionContainer());
 | |
|             break;
 | |
| 
 | |
|           default:
 | |
|             this.unexpected();
 | |
|           }
 | |
|         }
 | |
|         if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) {
 | |
|           this.raise(
 | |
|             closingElement.start,
 | |
|             'Expected corresponding JSX closing tag for <' + getQualifiedJSXName(openingElement.name) + '>');
 | |
|         }
 | |
|       }
 | |
|       let fragmentOrElement = openingElement.name ? 'Element' : 'Fragment';
 | |
| 
 | |
|       node['opening' + fragmentOrElement] = openingElement;
 | |
|       node['closing' + fragmentOrElement] = closingElement;
 | |
|       node.children = children;
 | |
|       if (this.type === tt.relational && this.value === "<") {
 | |
|         this.raise(this.start, "Adjacent JSX elements must be wrapped in an enclosing tag");
 | |
|       }
 | |
|       return this.finishNode(node, 'JSX' + fragmentOrElement);
 | |
|     }
 | |
| 
 | |
|     // Parse JSX text
 | |
| 
 | |
|     jsx_parseText() {
 | |
|       let node = this.parseLiteral(this.value);
 | |
|       node.type = "JSXText";
 | |
|       return node;
 | |
|     }
 | |
| 
 | |
|     // Parses entire JSX element from current position.
 | |
| 
 | |
|     jsx_parseElement() {
 | |
|       let startPos = this.start, startLoc = this.startLoc;
 | |
|       this.next();
 | |
|       return this.jsx_parseElementAt(startPos, startLoc);
 | |
|     }
 | |
| 
 | |
|     parseExprAtom(refShortHandDefaultPos) {
 | |
|       if (this.type === tok.jsxText)
 | |
|         return this.jsx_parseText();
 | |
|       else if (this.type === tok.jsxTagStart)
 | |
|         return this.jsx_parseElement();
 | |
|       else
 | |
|         return super.parseExprAtom(refShortHandDefaultPos);
 | |
|     }
 | |
| 
 | |
|     readToken(code) {
 | |
|       let context = this.curContext();
 | |
| 
 | |
|       if (context === tc_expr) return this.jsx_readToken();
 | |
| 
 | |
|       if (context === tc_oTag || context === tc_cTag) {
 | |
|         if (isIdentifierStart(code)) return this.jsx_readWord();
 | |
| 
 | |
|         if (code == 62) {
 | |
|           ++this.pos;
 | |
|           return this.finishToken(tok.jsxTagEnd);
 | |
|         }
 | |
| 
 | |
|         if ((code === 34 || code === 39) && context == tc_oTag)
 | |
|           return this.jsx_readString(code);
 | |
|       }
 | |
| 
 | |
|       if (code === 60 && this.exprAllowed && this.input.charCodeAt(this.pos + 1) !== 33) {
 | |
|         ++this.pos;
 | |
|         return this.finishToken(tok.jsxTagStart);
 | |
|       }
 | |
|       return super.readToken(code);
 | |
|     }
 | |
| 
 | |
|     updateContext(prevType) {
 | |
|       if (this.type == tt.braceL) {
 | |
|         var curContext = this.curContext();
 | |
|         if (curContext == tc_oTag) this.context.push(tokContexts.b_expr);
 | |
|         else if (curContext == tc_expr) this.context.push(tokContexts.b_tmpl);
 | |
|         else super.updateContext(prevType);
 | |
|         this.exprAllowed = true;
 | |
|       } else if (this.type === tt.slash && prevType === tok.jsxTagStart) {
 | |
|         this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore
 | |
|         this.context.push(tc_cTag); // reconsider as closing tag context
 | |
|         this.exprAllowed = false;
 | |
|       } else {
 | |
|         return super.updateContext(prevType);
 | |
|       }
 | |
|     }
 | |
|   };
 | |
| }
 |