Singularity System Enhancement Plan
Ecosistema completo para organización y gestión de contenido con interfaces espaciales
Singularity System: Comprehensive Enhancement Plan (Updated)
Completed Work (Phases 1-4)
Phase 1: Foundation & Persistence (COMPLETE)
- Perfect data synchronization between Logic Builder and Flow Composer
- Flash Persistence via @storage-system with autoFlashState
- Connection path persistence and finalization
- Race condition fixes (test inputs, block deletion persistence)
- Single Source of Truth pattern (service over local signals)
Phase 2: Functional Blocks (COMPLETE)
- 9 Math block templates (Add, Subtract, Multiply, Divide, Power, Square Root, Min/Max, Round, Average)
- 8 String block templates (Uppercase, Lowercase, Capitalize, Reverse, Length, Concat, Split, Replace)
- 16 Array operations (map, filter, reduce, sort, find, etc.)
- 11 Object operations (keys, values, merge, clone, etc.)
- Real execution engine with context.storage, context.theme, context.widgets
Phase 3: Database Integration (COMPLETE)
- 6 Database block templates (Save, Get, Update, Delete, List, Query)
- DatabaseMonitoringService wrapping @storage-system
- Real-time connection monitoring (IndexedDB, MongoDB, Firebase)
- Advanced query filtering ($gt, $gte, $lt, $lte, etc.)
- All operations delegate to @storage-system
Phase 4: Real-World Demo (COMPLETE)
- E-commerce Order Processing flow (9 interconnected blocks)
- Complete data flow: Trigger → Variable → Condition → Function → Action → Output
- Sample data generator
Recent Critical Fixes (COMPLETE)
- Test inputs now working (execution context pre-populates variables)
- Race condition fixed (read from service, not local signals)
- Block deletion persists across refreshes
- Flow Tester inputs are editable (signal reactivity fixed)
Priority Reorganization (Based on User Decisions)
User Decision Summary:
- Do Block Configuration + AI features IN PARALLEL (1C)
- Export/Import IMMEDIATELY AFTER block config (2A)
- Skip multi-user for now - single-user MVP (3B)
- AI: Block config assistant + Natural language to flow - BOTH using gograb-ai (4A + 4B)
Phase 5: Block Configuration System (IN PROGRESS - PARALLEL TRACK A)
Goal
Make blocks fully configurable so users can set inputs, operations, and outputs. Everything stored as JSON for shareability.
5.1: Enhanced Block Data Model
File: libs/singularity-lib/src/lib/models/logic-block.interface.ts
Add comprehensive config to LogicBlock interface:
interface LogicBlock {
id: string;
name: string;
type: BlockType;
category: string;
// NEW: Comprehensive configuration
config?: {
// Input configuration
inputs?: {
[inputName: string]: {
type: 'variable' | 'constant' | 'connection';
value?: any; // For constants
variableName?: string; // For variable references ($a)
connectionId?: string; // For port connections
defaultValue?: any;
};
};
// Output configuration
outputs?: {
[outputName: string]: {
variableName?: string; // Where to store result
};
};
// Block-specific settings
settings?: {
operation?: string; // For Calculate: 'add', 'subtract', etc.
[key: string]: any;
};
// UI/Visual settings
ui?: {
color?: string;
icon?: string;
collapsed?: boolean;
};
};
// Existing fields
position?: { x: number; y: number };
metadata?: any;
}
5.2: Block Configuration Modal Component
New File: libs/singularity-lib/src/lib/components/logic-builder/components/block-config-modal/block-config-modal.component.ts
Create modal component that opens when user double-clicks a block:
- Tabs: Inputs, Outputs, Settings, Appearance
- Input tab: Configure each input as Variable ($a), Constant (5), or Connection (from port)
- Output tab: Name output variables
- Settings tab: Block-specific settings (operation for Calculate, etc.)
- Appearance tab: Color picker, icon selector
- Save button: Updates block.config and persists via singularityService
5.3: Inline Quick Config
File: libs/singularity-lib/src/lib/components/logic-builder/components/block-card/block-card.component.ts
Add inline editing to block card UI:
- Operation selector for math blocks (add/subtract/multiply buttons)
- Inline input fields for a and b values
- Live result preview badge
- Click to expand full config modal
5.4: Update Execution Engine to Read Config
File: libs/singularity-lib/src/lib/services/logic-execution-engine.service.ts
Enhance execution to read from block.config:
private async executeBlock(block: LogicBlock, context: ExecutionContext): Promise<any> {
// NEW: Read from block.config if available
const args = block.config?.inputs
? this.resolveInputsFromConfig(block.config.inputs, context)
: block.properties; // Fallback to old properties
// Execute with resolved inputs
const result = await this.executeBlockType(block, args, context);
// NEW: Store result in configured output variable
if (block.config?.outputs) {
Object.entries(block.config.outputs).forEach(([outputName, outputConfig]) => {
if (outputConfig.variableName) {
context.variables.set(outputConfig.variableName, result);
}
});
}
return result;
}
Phase 6: AI Integration via gograb-ai (IN PROGRESS - PARALLEL TRACK B)
Goal
Leverage existing gograb-ai infrastructure for block configuration assistant and natural language to flow conversion.
6.1: Block Configuration AI Assistant
New File: libs/singularity-lib/src/lib/components/logic-builder/components/ai-block-assistant/ai-block-assistant.component.ts
Embed lib-simple-ai-chat component for block configuration help:
@Component({
selector: 'lib-ai-block-assistant',
template: `
<div class="ai-block-assistant-panel">
<h3>AI Block Assistant</h3>
<p>Describe what you want to do, and I'll configure the block for you!</p>
<!-- Leverage gograb-ai -->
<lib-simple-ai-chat
chatId="singularity-block-config"
title="Block Configuration Assistant"
[initialProvider]="AIProvider.ANTHROPIC"
(responseReceived)="onAIBlockConfigResponse($event)"
></lib-simple-ai-chat>
</div>
`
})
export class AiBlockAssistantComponent {
private aiFactory = inject(AIFactoryService);
private singularityService = inject(SingularityService);
onAIBlockConfigResponse(response: string): void {
// Parse AI response for block configuration
const config = this.extractBlockConfigFromAI(response);
if (config) {
// Apply configuration to selected block
this.singularityService.updateBlockConfig(this.selectedBlockId, config);
}
}
private extractBlockConfigFromAI(response: string): LogicBlockConfig | null {
// Parse JSON from AI response
// Look for structured config in response
const jsonMatch = response.match(/```json\n([\s\S]*?)\n```/);
if (jsonMatch) {
return JSON.parse(jsonMatch[1]);
}
return null;
}
}
System Prompt: Configure in component config:
systemPrompt = `You are an AI assistant helping users configure logic blocks in Singularity.
When a user describes what they want, respond with a JSON configuration.
Example: User says "I want to add two numbers a and b"
You respond:
\`\`\`json
{
"inputs": {
"a": { "type": "variable", "variableName": "a" },
"b": { "type": "variable", "variableName": "b" }
},
"settings": {
"operation": "add"
},
"outputs": {
"result": { "variableName": "sum" }
}
}
\`\`\`
Always respond with JSON in code blocks.`;
6.2: Natural Language to Flow Converter
New File: libs/singularity-lib/src/lib/components/logic-builder/components/nl-to-flow/nl-to-flow.component.ts
Button in Logic Builder header that opens AI chat for flow generation:
@Component({
selector: 'lib-nl-to-flow',
template: `
<div class="nl-to-flow-panel">
<h3>Describe Your Flow</h3>
<p>Tell me what you want to build, and I'll create the flow!</p>
<lib-simple-ai-chat
chatId="singularity-nl-to-flow"
title="Flow Generation Assistant"
[initialProvider]="AIProvider.ANTHROPIC"
(responseReceived)="onAIFlowResponse($event)"
></lib-simple-ai-chat>
</div>
`
})
export class NlToFlowComponent {
private aiFactory = inject(AIFactoryService);
private singularityService = inject(SingularityService);
private storage = inject(GgStorage);
async onAIFlowResponse(response: string): Promise<void> {
// Extract flow JSON from AI response
const flow = this.extractFlowFromAI(response);
if (flow) {
// Create blocks and connections
await this.createFlowFromAI(flow);
}
}
private async createFlowFromAI(flowSpec: any): Promise<void> {
const blocks: LogicBlock[] = [];
const connections: LogicConnection[] = [];
// Generate blocks from AI spec
flowSpec.blocks.forEach((blockSpec: any, index: number) => {
const block: LogicBlock = {
id: `block_${Date.now()}_${index}`,
name: blockSpec.name,
type: blockSpec.type,
category: blockSpec.category,
config: blockSpec.config,
position: { x: 100 + index * 300, y: 200 }
};
blocks.push(block);
});
// Generate connections from AI spec
flowSpec.connections.forEach((connSpec: any) => {
const connection: LogicConnection = {
id: `conn_${Date.now()}_${Math.random()}`,
sourceBlockId: blocks[connSpec.from].id,
sourcePortId: 'output',
targetBlockId: blocks[connSpec.to].id,
targetPortId: 'input'
};
connections.push(connection);
});
// Set blocks and connections via service
this.singularityService.setBlocks(blocks);
this.singularityService.setConnections(connections);
// Save as new flow
const flow: LogicFlow = {
id: `flow_${Date.now()}`,
name: flowSpec.name || 'AI Generated Flow',
blocks,
connections,
metadata: {
created: new Date(),
modified: new Date(),
author: 'AI Assistant',
description: flowSpec.description || 'Generated by AI'
}
};
await this.storage.put(flow.id, flow);
}
}
System Prompt:
systemPrompt = `You are an AI assistant that generates logic flows for Singularity from natural language.
When a user describes a workflow, respond with a JSON flow specification.
Example: User says "Get user by ID, calculate age, send email if age is 21"
You respond:
\`\`\`json
{
"name": "Birthday Email Flow",
"description": "Fetches user, calculates age, sends birthday email if 21",
"blocks": [
{
"name": "Get User",
"type": "action",
"category": "database",
"config": {
"settings": { "operation": "get", "collection": "users" },
"inputs": { "userId": { "type": "variable", "variableName": "userId" } },
"outputs": { "result": { "variableName": "user" } }
}
},
{
"name": "Calculate Age",
"type": "function",
"category": "math",
"config": {
"settings": { "operation": "calculate_age" },
"inputs": { "birthdate": { "type": "variable", "variableName": "user.birthdate" } },
"outputs": { "result": { "variableName": "age" } }
}
},
{
"name": "Check Age 21",
"type": "condition",
"category": "logic",
"config": {
"settings": { "condition": "$age === 21" }
}
},
{
"name": "Send Birthday Email",
"type": "action",
"category": "communication",
"config": {
"settings": { "operation": "send_email" },
"inputs": {
"to": { "type": "variable", "variableName": "user.email" },
"subject": { "type": "constant", "value": "Happy Birthday!" }
}
}
}
],
"connections": [
{ "from": 0, "to": 1 },
{ "from": 1, "to": 2 },
{ "from": 2, "to": 3 }
]
}
\`\`\`
Always respond with JSON in code blocks.`;
6.3: AI Panel in Logic Builder
File: libs/singularity-lib/src/lib/components/logic-builder/logic-builder.component.html
Add AI panel toggle button in header:
<div class="logic-builder-header">
<!-- Existing buttons -->
<button (click)="toggleAIPanel()" title="AI Assistant">
<i class="fas fa-robot"></i> AI
</button>
</div>
<!-- AI Panel (slides in from right) -->
<div class="ai-panel" *ngIf="showAIPanel()">
<ux-tabs>
<ux-tab label="Block Config">
<lib-ai-block-assistant></lib-ai-block-assistant>
</ux-tab>
<ux-tab label="Generate Flow">
<lib-nl-to-flow></lib-nl-to-flow>
</ux-tab>
</ux-tabs>
</div>
Phase 7: Export/Import System (AFTER Phase 5 & 6)
Goal
Complete JSON export/import so configured flows can be shared.
7.1: Export Flow Interface
File: libs/singularity-lib/src/lib/models/exported-flow.interface.ts
interface ExportedFlow {
version: '1.0.0';
flowId: string;
flowName: string;
description: string;
author: string;
created: string;
modified: string;
// Complete flow data (INCLUDING block.config!)
blocks: LogicBlock[]; // Now with full config
connections: LogicConnection[];
// Metadata
requiredVariables: string[]; // Variables this flow expects
outputVariables: string[]; // Variables this flow produces
dependencies: string[]; // External dependencies
// Visual state
canvasState: {
zoom: number;
panX: number;
panY: number;
};
}
7.2: Export Service
File: libs/singularity-lib/src/lib/services/flow-export.service.ts
@Injectable({ providedIn: 'root' })
export class FlowExportService {
async exportFlow(flowId: string): Promise<ExportedFlow> {
const flow = await this.storage.get<LogicFlow>(flowId);
return {
version: '1.0.0',
flowId: flow.id,
flowName: flow.name,
description: flow.metadata?.description || '',
author: flow.metadata?.author || 'Unknown',
created: flow.metadata?.created?.toISOString() || '',
modified: flow.metadata?.modified?.toISOString() || '',
blocks: flow.blocks, // Includes block.config
connections: flow.connections,
requiredVariables: this.extractRequiredVariables(flow.blocks),
outputVariables: this.extractOutputVariables(flow.blocks),
dependencies: [],
canvasState: this.getCanvasState()
};
}
downloadAsJSON(exportedFlow: ExportedFlow): void {
const json = JSON.stringify(exportedFlow, null, 2);
const blob = new Blob([json], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${exportedFlow.flowName}.json`;
a.click();
URL.revokeObjectURL(url);
}
copyToClipboard(exportedFlow: ExportedFlow): void {
const json = JSON.stringify(exportedFlow);
const encoded = btoa(json);
const shareUrl = `https://gograb.space/singularity/import?flow=${encoded}`;
navigator.clipboard.writeText(shareUrl);
}
}
7.3: Import Service
File: libs/singularity-lib/src/lib/services/flow-import.service.ts
@Injectable({ providedIn: 'root' })
export class FlowImportService {
async importFromFile(file: File): Promise<void> {
const text = await file.text();
const exportedFlow: ExportedFlow = JSON.parse(text);
await this.importFlow(exportedFlow);
}
async importFromJSON(json: string): Promise<void> {
const exportedFlow: ExportedFlow = JSON.parse(json);
await this.importFlow(exportedFlow);
}
async importFromURL(encodedFlow: string): Promise<void> {
const json = atob(encodedFlow);
const exportedFlow: ExportedFlow = JSON.parse(json);
await this.importFlow(exportedFlow);
}
private async importFlow(exportedFlow: ExportedFlow, mode: 'replace' | 'merge' | 'new' = 'new'): Promise<void> {
// Validate version
if (exportedFlow.version !== '1.0.0') {
throw new Error('Unsupported flow version');
}
// Create new flow or update existing
const flow: LogicFlow = {
id: mode === 'new' ? `flow_${Date.now()}` : exportedFlow.flowId,
name: exportedFlow.flowName,
blocks: exportedFlow.blocks, // Includes block.config
connections: exportedFlow.connections,
metadata: {
created: new Date(exportedFlow.created),
modified: new Date(),
author: exportedFlow.author,
description: exportedFlow.description
}
};
// Save to storage
await this.storage.put(flow.id, flow);
// Load in Logic Builder
await this.loadFlowInBuilder(flow.id);
}
}
7.4: UI Buttons
File: libs/singularity-lib/src/lib/components/logic-builder/logic-builder.component.html
Add export/import buttons:
<div class="logic-builder-header">
<!-- Existing buttons -->
<!-- Export/Import -->
<button (click)="exportFlow()" title="Export Flow">
<i class="fas fa-download"></i> Export
</button>
<button (click)="importFlow()" title="Import Flow">
<i class="fas fa-upload"></i> Import
</button>
</div>
Phase 8: Enhanced UX (AFTER Phase 7)
8.1: Block Templates Library
- Pre-configured block templates (e.g., "Add Two Variables", "Calculate Percentage")
- Sidebar with template browser
- Drag and drop to canvas with config already set
8.2: Smart Variable Suggestions
- Autocomplete dropdown when typing variable names
- Show available variables with types and values
- Recent/frequently used at top
8.3: Block Search & Filtering
- Search bar in block library
- Filter by category, operation, use case
- Recent blocks and favorites
8.4: Visual Enhancements
- Color-coded blocks by category
- Connection type indicators (normal, conditional, error)
- Minimap for large flows
- Animated execution visualization
Phase 9: Testing & Validation (AFTER Phase 8)
9.1: Unit Tests
- Test block configuration persistence
- Test AI response parsing
- Test export/import functionality
- Test execution engine with configured blocks
9.2: Integration Tests
- Test complete flow: create block → configure → export → import
- Test AI flow generation end-to-end
9.3: Flow Validation
- Validate flow before execution (missing inputs, undefined variables)
- Show errors and warnings
Implementation Order
Sprint 5 (Current): Parallel Tracks
Track A: Block Configuration (Phase 5)
- Enhanced block data model
- Block configuration modal component
- Update execution engine to read config
- Inline quick config
Track B: AI Integration (Phase 6)
- AI block assistant component (gograb-ai integration)
- Natural language to flow component
- AI panel in Logic Builder
- System prompts and response parsing
Sprint 6: Export/Import (Phase 7)
- Export flow interface and service
- Import flow service
- UI buttons and file handling
- Share URL generation
Sprint 7: Enhanced UX (Phase 8)
- Block templates library
- Smart variable suggestions
- Block search and filtering
- Visual enhancements
Sprint 8: Testing & Polish (Phase 9)
- Unit tests
- Integration tests
- Flow validation
- Documentation
Success Metrics
Technical
- All block configurations persist as JSON
- Export/import 100% data fidelity
- AI block config success rate > 80%
- AI flow generation success rate > 70%
User Experience
- Time to configure block: < 30 seconds
- Time to create flow with AI: < 2 minutes
- User satisfaction: > 4.5/5
Functionality
- Configured blocks work correctly
- Exported flows import perfectly
- AI-generated flows execute successfully
- Zero data loss on export/import
Key Files Summary
New Files (Phase 5-7)
libs/singularity-lib/src/lib/components/logic-builder/components/block-config-modal/(component, template, styles)libs/singularity-lib/src/lib/components/logic-builder/components/ai-block-assistant/(component)libs/singularity-lib/src/lib/components/logic-builder/components/nl-to-flow/(component)libs/singularity-lib/src/lib/models/exported-flow.interface.tslibs/singularity-lib/src/lib/services/flow-export.service.tslibs/singularity-lib/src/lib/services/flow-import.service.ts
Modified Files (Phase 5-7)
libs/singularity-lib/src/lib/models/logic-block.interface.ts(add config)libs/singularity-lib/src/lib/services/logic-execution-engine.service.ts(read config)libs/singularity-lib/src/lib/services/singularity.service.ts(updateBlockConfig method)libs/singularity-lib/src/lib/components/logic-builder/logic-builder.component.html(AI panel, export/import buttons)libs/singularity-lib/src/lib/components/logic-builder/logic-builder.component.ts(toggleAIPanel, exportFlow, importFlow methods)libs/singularity-lib/src/lib/components/logic-builder/components/block-card/block-card.component.ts(inline quick config)
Notes
- Single-user MVP: No user-scoped data changes needed (keep current implementation)
- Multi-user support: Deferred until storage-system implements per-user basis
- Leverage gograb-ai: Use existing AiChatComponent infrastructure, no need to rebuild
- Everything as JSON: Block.config ensures complete shareability
- Parallel development: Block config and AI can be developed simultaneously by different devs or in parallel commits