 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>
		
			
				
	
	
		
			336 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			336 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { Alias } from '../nodes/Alias.js';
 | |
| import { isEmptyPath, collectionFromPath } from '../nodes/Collection.js';
 | |
| import { NODE_TYPE, DOC, isNode, isCollection, isScalar } from '../nodes/identity.js';
 | |
| import { Pair } from '../nodes/Pair.js';
 | |
| import { toJS } from '../nodes/toJS.js';
 | |
| import { Schema } from '../schema/Schema.js';
 | |
| import { stringifyDocument } from '../stringify/stringifyDocument.js';
 | |
| import { anchorNames, findNewAnchor, createNodeAnchors } from './anchors.js';
 | |
| import { applyReviver } from './applyReviver.js';
 | |
| import { createNode } from './createNode.js';
 | |
| import { Directives } from './directives.js';
 | |
| 
 | |
| class Document {
 | |
|     constructor(value, replacer, options) {
 | |
|         /** A comment before this Document */
 | |
|         this.commentBefore = null;
 | |
|         /** A comment immediately after this Document */
 | |
|         this.comment = null;
 | |
|         /** Errors encountered during parsing. */
 | |
|         this.errors = [];
 | |
|         /** Warnings encountered during parsing. */
 | |
|         this.warnings = [];
 | |
|         Object.defineProperty(this, NODE_TYPE, { value: DOC });
 | |
|         let _replacer = null;
 | |
|         if (typeof replacer === 'function' || Array.isArray(replacer)) {
 | |
|             _replacer = replacer;
 | |
|         }
 | |
|         else if (options === undefined && replacer) {
 | |
|             options = replacer;
 | |
|             replacer = undefined;
 | |
|         }
 | |
|         const opt = Object.assign({
 | |
|             intAsBigInt: false,
 | |
|             keepSourceTokens: false,
 | |
|             logLevel: 'warn',
 | |
|             prettyErrors: true,
 | |
|             strict: true,
 | |
|             stringKeys: false,
 | |
|             uniqueKeys: true,
 | |
|             version: '1.2'
 | |
|         }, options);
 | |
|         this.options = opt;
 | |
|         let { version } = opt;
 | |
|         if (options?._directives) {
 | |
|             this.directives = options._directives.atDocument();
 | |
|             if (this.directives.yaml.explicit)
 | |
|                 version = this.directives.yaml.version;
 | |
|         }
 | |
|         else
 | |
|             this.directives = new Directives({ version });
 | |
|         this.setSchema(version, options);
 | |
|         // @ts-expect-error We can't really know that this matches Contents.
 | |
|         this.contents =
 | |
|             value === undefined ? null : this.createNode(value, _replacer, options);
 | |
|     }
 | |
|     /**
 | |
|      * Create a deep copy of this Document and its contents.
 | |
|      *
 | |
|      * Custom Node values that inherit from `Object` still refer to their original instances.
 | |
|      */
 | |
|     clone() {
 | |
|         const copy = Object.create(Document.prototype, {
 | |
|             [NODE_TYPE]: { value: DOC }
 | |
|         });
 | |
|         copy.commentBefore = this.commentBefore;
 | |
|         copy.comment = this.comment;
 | |
|         copy.errors = this.errors.slice();
 | |
|         copy.warnings = this.warnings.slice();
 | |
|         copy.options = Object.assign({}, this.options);
 | |
|         if (this.directives)
 | |
|             copy.directives = this.directives.clone();
 | |
|         copy.schema = this.schema.clone();
 | |
|         // @ts-expect-error We can't really know that this matches Contents.
 | |
|         copy.contents = isNode(this.contents)
 | |
|             ? this.contents.clone(copy.schema)
 | |
|             : this.contents;
 | |
|         if (this.range)
 | |
|             copy.range = this.range.slice();
 | |
|         return copy;
 | |
|     }
 | |
|     /** Adds a value to the document. */
 | |
|     add(value) {
 | |
|         if (assertCollection(this.contents))
 | |
|             this.contents.add(value);
 | |
|     }
 | |
|     /** Adds a value to the document. */
 | |
|     addIn(path, value) {
 | |
|         if (assertCollection(this.contents))
 | |
|             this.contents.addIn(path, value);
 | |
|     }
 | |
|     /**
 | |
|      * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
 | |
|      *
 | |
|      * If `node` already has an anchor, `name` is ignored.
 | |
|      * Otherwise, the `node.anchor` value will be set to `name`,
 | |
|      * or if an anchor with that name is already present in the document,
 | |
|      * `name` will be used as a prefix for a new unique anchor.
 | |
|      * If `name` is undefined, the generated anchor will use 'a' as a prefix.
 | |
|      */
 | |
|     createAlias(node, name) {
 | |
|         if (!node.anchor) {
 | |
|             const prev = anchorNames(this);
 | |
|             node.anchor =
 | |
|                 // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
 | |
|                 !name || prev.has(name) ? findNewAnchor(name || 'a', prev) : name;
 | |
|         }
 | |
|         return new Alias(node.anchor);
 | |
|     }
 | |
|     createNode(value, replacer, options) {
 | |
|         let _replacer = undefined;
 | |
|         if (typeof replacer === 'function') {
 | |
|             value = replacer.call({ '': value }, '', value);
 | |
|             _replacer = replacer;
 | |
|         }
 | |
|         else if (Array.isArray(replacer)) {
 | |
|             const keyToStr = (v) => typeof v === 'number' || v instanceof String || v instanceof Number;
 | |
|             const asStr = replacer.filter(keyToStr).map(String);
 | |
|             if (asStr.length > 0)
 | |
|                 replacer = replacer.concat(asStr);
 | |
|             _replacer = replacer;
 | |
|         }
 | |
|         else if (options === undefined && replacer) {
 | |
|             options = replacer;
 | |
|             replacer = undefined;
 | |
|         }
 | |
|         const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options ?? {};
 | |
|         const { onAnchor, setAnchors, sourceObjects } = createNodeAnchors(this, 
 | |
|         // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
 | |
|         anchorPrefix || 'a');
 | |
|         const ctx = {
 | |
|             aliasDuplicateObjects: aliasDuplicateObjects ?? true,
 | |
|             keepUndefined: keepUndefined ?? false,
 | |
|             onAnchor,
 | |
|             onTagObj,
 | |
|             replacer: _replacer,
 | |
|             schema: this.schema,
 | |
|             sourceObjects
 | |
|         };
 | |
|         const node = createNode(value, tag, ctx);
 | |
|         if (flow && isCollection(node))
 | |
|             node.flow = true;
 | |
|         setAnchors();
 | |
|         return node;
 | |
|     }
 | |
|     /**
 | |
|      * Convert a key and a value into a `Pair` using the current schema,
 | |
|      * recursively wrapping all values as `Scalar` or `Collection` nodes.
 | |
|      */
 | |
|     createPair(key, value, options = {}) {
 | |
|         const k = this.createNode(key, null, options);
 | |
|         const v = this.createNode(value, null, options);
 | |
|         return new Pair(k, v);
 | |
|     }
 | |
|     /**
 | |
|      * Removes a value from the document.
 | |
|      * @returns `true` if the item was found and removed.
 | |
|      */
 | |
|     delete(key) {
 | |
|         return assertCollection(this.contents) ? this.contents.delete(key) : false;
 | |
|     }
 | |
|     /**
 | |
|      * Removes a value from the document.
 | |
|      * @returns `true` if the item was found and removed.
 | |
|      */
 | |
|     deleteIn(path) {
 | |
|         if (isEmptyPath(path)) {
 | |
|             if (this.contents == null)
 | |
|                 return false;
 | |
|             // @ts-expect-error Presumed impossible if Strict extends false
 | |
|             this.contents = null;
 | |
|             return true;
 | |
|         }
 | |
|         return assertCollection(this.contents)
 | |
|             ? this.contents.deleteIn(path)
 | |
|             : false;
 | |
|     }
 | |
|     /**
 | |
|      * Returns item at `key`, or `undefined` if not found. By default unwraps
 | |
|      * scalar values from their surrounding node; to disable set `keepScalar` to
 | |
|      * `true` (collections are always returned intact).
 | |
|      */
 | |
|     get(key, keepScalar) {
 | |
|         return isCollection(this.contents)
 | |
|             ? this.contents.get(key, keepScalar)
 | |
|             : undefined;
 | |
|     }
 | |
|     /**
 | |
|      * Returns item at `path`, or `undefined` if not found. By default unwraps
 | |
|      * scalar values from their surrounding node; to disable set `keepScalar` to
 | |
|      * `true` (collections are always returned intact).
 | |
|      */
 | |
|     getIn(path, keepScalar) {
 | |
|         if (isEmptyPath(path))
 | |
|             return !keepScalar && isScalar(this.contents)
 | |
|                 ? this.contents.value
 | |
|                 : this.contents;
 | |
|         return isCollection(this.contents)
 | |
|             ? this.contents.getIn(path, keepScalar)
 | |
|             : undefined;
 | |
|     }
 | |
|     /**
 | |
|      * Checks if the document includes a value with the key `key`.
 | |
|      */
 | |
|     has(key) {
 | |
|         return isCollection(this.contents) ? this.contents.has(key) : false;
 | |
|     }
 | |
|     /**
 | |
|      * Checks if the document includes a value at `path`.
 | |
|      */
 | |
|     hasIn(path) {
 | |
|         if (isEmptyPath(path))
 | |
|             return this.contents !== undefined;
 | |
|         return isCollection(this.contents) ? this.contents.hasIn(path) : false;
 | |
|     }
 | |
|     /**
 | |
|      * Sets a value in this document. For `!!set`, `value` needs to be a
 | |
|      * boolean to add/remove the item from the set.
 | |
|      */
 | |
|     set(key, value) {
 | |
|         if (this.contents == null) {
 | |
|             // @ts-expect-error We can't really know that this matches Contents.
 | |
|             this.contents = collectionFromPath(this.schema, [key], value);
 | |
|         }
 | |
|         else if (assertCollection(this.contents)) {
 | |
|             this.contents.set(key, value);
 | |
|         }
 | |
|     }
 | |
|     /**
 | |
|      * Sets a value in this document. For `!!set`, `value` needs to be a
 | |
|      * boolean to add/remove the item from the set.
 | |
|      */
 | |
|     setIn(path, value) {
 | |
|         if (isEmptyPath(path)) {
 | |
|             // @ts-expect-error We can't really know that this matches Contents.
 | |
|             this.contents = value;
 | |
|         }
 | |
|         else if (this.contents == null) {
 | |
|             // @ts-expect-error We can't really know that this matches Contents.
 | |
|             this.contents = collectionFromPath(this.schema, Array.from(path), value);
 | |
|         }
 | |
|         else if (assertCollection(this.contents)) {
 | |
|             this.contents.setIn(path, value);
 | |
|         }
 | |
|     }
 | |
|     /**
 | |
|      * Change the YAML version and schema used by the document.
 | |
|      * A `null` version disables support for directives, explicit tags, anchors, and aliases.
 | |
|      * It also requires the `schema` option to be given as a `Schema` instance value.
 | |
|      *
 | |
|      * Overrides all previously set schema options.
 | |
|      */
 | |
|     setSchema(version, options = {}) {
 | |
|         if (typeof version === 'number')
 | |
|             version = String(version);
 | |
|         let opt;
 | |
|         switch (version) {
 | |
|             case '1.1':
 | |
|                 if (this.directives)
 | |
|                     this.directives.yaml.version = '1.1';
 | |
|                 else
 | |
|                     this.directives = new Directives({ version: '1.1' });
 | |
|                 opt = { resolveKnownTags: false, schema: 'yaml-1.1' };
 | |
|                 break;
 | |
|             case '1.2':
 | |
|             case 'next':
 | |
|                 if (this.directives)
 | |
|                     this.directives.yaml.version = version;
 | |
|                 else
 | |
|                     this.directives = new Directives({ version });
 | |
|                 opt = { resolveKnownTags: true, schema: 'core' };
 | |
|                 break;
 | |
|             case null:
 | |
|                 if (this.directives)
 | |
|                     delete this.directives;
 | |
|                 opt = null;
 | |
|                 break;
 | |
|             default: {
 | |
|                 const sv = JSON.stringify(version);
 | |
|                 throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${sv}`);
 | |
|             }
 | |
|         }
 | |
|         // Not using `instanceof Schema` to allow for duck typing
 | |
|         if (options.schema instanceof Object)
 | |
|             this.schema = options.schema;
 | |
|         else if (opt)
 | |
|             this.schema = new Schema(Object.assign(opt, options));
 | |
|         else
 | |
|             throw new Error(`With a null YAML version, the { schema: Schema } option is required`);
 | |
|     }
 | |
|     // json & jsonArg are only used from toJSON()
 | |
|     toJS({ json, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {
 | |
|         const ctx = {
 | |
|             anchors: new Map(),
 | |
|             doc: this,
 | |
|             keep: !json,
 | |
|             mapAsMap: mapAsMap === true,
 | |
|             mapKeyWarned: false,
 | |
|             maxAliasCount: typeof maxAliasCount === 'number' ? maxAliasCount : 100
 | |
|         };
 | |
|         const res = toJS(this.contents, jsonArg ?? '', ctx);
 | |
|         if (typeof onAnchor === 'function')
 | |
|             for (const { count, res } of ctx.anchors.values())
 | |
|                 onAnchor(res, count);
 | |
|         return typeof reviver === 'function'
 | |
|             ? applyReviver(reviver, { '': res }, '', res)
 | |
|             : res;
 | |
|     }
 | |
|     /**
 | |
|      * A JSON representation of the document `contents`.
 | |
|      *
 | |
|      * @param jsonArg Used by `JSON.stringify` to indicate the array index or
 | |
|      *   property name.
 | |
|      */
 | |
|     toJSON(jsonArg, onAnchor) {
 | |
|         return this.toJS({ json: true, jsonArg, mapAsMap: false, onAnchor });
 | |
|     }
 | |
|     /** A YAML representation of the document. */
 | |
|     toString(options = {}) {
 | |
|         if (this.errors.length > 0)
 | |
|             throw new Error('Document with errors cannot be stringified');
 | |
|         if ('indent' in options &&
 | |
|             (!Number.isInteger(options.indent) || Number(options.indent) <= 0)) {
 | |
|             const s = JSON.stringify(options.indent);
 | |
|             throw new Error(`"indent" option must be a positive integer, not ${s}`);
 | |
|         }
 | |
|         return stringifyDocument(this, options);
 | |
|     }
 | |
| }
 | |
| function assertCollection(contents) {
 | |
|     if (isCollection(contents))
 | |
|         return true;
 | |
|     throw new Error('Expected a YAML collection as document contents');
 | |
| }
 | |
| 
 | |
| export { Document };
 |