 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>
		
			
				
	
	
		
			146 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| var identity = require('../nodes/identity.js');
 | |
| var stringify = require('./stringify.js');
 | |
| var stringifyComment = require('./stringifyComment.js');
 | |
| 
 | |
| function stringifyCollection(collection, ctx, options) {
 | |
|     const flow = ctx.inFlow ?? collection.flow;
 | |
|     const stringify = flow ? stringifyFlowCollection : stringifyBlockCollection;
 | |
|     return stringify(collection, ctx, options);
 | |
| }
 | |
| function stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, flowChars, itemIndent, onChompKeep, onComment }) {
 | |
|     const { indent, options: { commentString } } = ctx;
 | |
|     const itemCtx = Object.assign({}, ctx, { indent: itemIndent, type: null });
 | |
|     let chompKeep = false; // flag for the preceding node's status
 | |
|     const lines = [];
 | |
|     for (let i = 0; i < items.length; ++i) {
 | |
|         const item = items[i];
 | |
|         let comment = null;
 | |
|         if (identity.isNode(item)) {
 | |
|             if (!chompKeep && item.spaceBefore)
 | |
|                 lines.push('');
 | |
|             addCommentBefore(ctx, lines, item.commentBefore, chompKeep);
 | |
|             if (item.comment)
 | |
|                 comment = item.comment;
 | |
|         }
 | |
|         else if (identity.isPair(item)) {
 | |
|             const ik = identity.isNode(item.key) ? item.key : null;
 | |
|             if (ik) {
 | |
|                 if (!chompKeep && ik.spaceBefore)
 | |
|                     lines.push('');
 | |
|                 addCommentBefore(ctx, lines, ik.commentBefore, chompKeep);
 | |
|             }
 | |
|         }
 | |
|         chompKeep = false;
 | |
|         let str = stringify.stringify(item, itemCtx, () => (comment = null), () => (chompKeep = true));
 | |
|         if (comment)
 | |
|             str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
 | |
|         if (chompKeep && comment)
 | |
|             chompKeep = false;
 | |
|         lines.push(blockItemPrefix + str);
 | |
|     }
 | |
|     let str;
 | |
|     if (lines.length === 0) {
 | |
|         str = flowChars.start + flowChars.end;
 | |
|     }
 | |
|     else {
 | |
|         str = lines[0];
 | |
|         for (let i = 1; i < lines.length; ++i) {
 | |
|             const line = lines[i];
 | |
|             str += line ? `\n${indent}${line}` : '\n';
 | |
|         }
 | |
|     }
 | |
|     if (comment) {
 | |
|         str += '\n' + stringifyComment.indentComment(commentString(comment), indent);
 | |
|         if (onComment)
 | |
|             onComment();
 | |
|     }
 | |
|     else if (chompKeep && onChompKeep)
 | |
|         onChompKeep();
 | |
|     return str;
 | |
| }
 | |
| function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {
 | |
|     const { indent, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx;
 | |
|     itemIndent += indentStep;
 | |
|     const itemCtx = Object.assign({}, ctx, {
 | |
|         indent: itemIndent,
 | |
|         inFlow: true,
 | |
|         type: null
 | |
|     });
 | |
|     let reqNewline = false;
 | |
|     let linesAtValue = 0;
 | |
|     const lines = [];
 | |
|     for (let i = 0; i < items.length; ++i) {
 | |
|         const item = items[i];
 | |
|         let comment = null;
 | |
|         if (identity.isNode(item)) {
 | |
|             if (item.spaceBefore)
 | |
|                 lines.push('');
 | |
|             addCommentBefore(ctx, lines, item.commentBefore, false);
 | |
|             if (item.comment)
 | |
|                 comment = item.comment;
 | |
|         }
 | |
|         else if (identity.isPair(item)) {
 | |
|             const ik = identity.isNode(item.key) ? item.key : null;
 | |
|             if (ik) {
 | |
|                 if (ik.spaceBefore)
 | |
|                     lines.push('');
 | |
|                 addCommentBefore(ctx, lines, ik.commentBefore, false);
 | |
|                 if (ik.comment)
 | |
|                     reqNewline = true;
 | |
|             }
 | |
|             const iv = identity.isNode(item.value) ? item.value : null;
 | |
|             if (iv) {
 | |
|                 if (iv.comment)
 | |
|                     comment = iv.comment;
 | |
|                 if (iv.commentBefore)
 | |
|                     reqNewline = true;
 | |
|             }
 | |
|             else if (item.value == null && ik?.comment) {
 | |
|                 comment = ik.comment;
 | |
|             }
 | |
|         }
 | |
|         if (comment)
 | |
|             reqNewline = true;
 | |
|         let str = stringify.stringify(item, itemCtx, () => (comment = null));
 | |
|         if (i < items.length - 1)
 | |
|             str += ',';
 | |
|         if (comment)
 | |
|             str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
 | |
|         if (!reqNewline && (lines.length > linesAtValue || str.includes('\n')))
 | |
|             reqNewline = true;
 | |
|         lines.push(str);
 | |
|         linesAtValue = lines.length;
 | |
|     }
 | |
|     const { start, end } = flowChars;
 | |
|     if (lines.length === 0) {
 | |
|         return start + end;
 | |
|     }
 | |
|     else {
 | |
|         if (!reqNewline) {
 | |
|             const len = lines.reduce((sum, line) => sum + line.length + 2, 2);
 | |
|             reqNewline = ctx.options.lineWidth > 0 && len > ctx.options.lineWidth;
 | |
|         }
 | |
|         if (reqNewline) {
 | |
|             let str = start;
 | |
|             for (const line of lines)
 | |
|                 str += line ? `\n${indentStep}${indent}${line}` : '\n';
 | |
|             return `${str}\n${indent}${end}`;
 | |
|         }
 | |
|         else {
 | |
|             return `${start}${fcPadding}${lines.join(' ')}${fcPadding}${end}`;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| function addCommentBefore({ indent, options: { commentString } }, lines, comment, chompKeep) {
 | |
|     if (comment && chompKeep)
 | |
|         comment = comment.replace(/^\n+/, '');
 | |
|     if (comment) {
 | |
|         const ic = stringifyComment.indentComment(commentString(comment), indent);
 | |
|         lines.push(ic.trimStart()); // Avoid double indent on first line
 | |
|     }
 | |
| }
 | |
| 
 | |
| exports.stringifyCollection = stringifyCollection;
 |