Sfoglia il codice sorgente

docs(slopdocs): update documentation guidelines with refined file naming and content organization standards

- Add examples of properly nested file names using dot-separated hierarchy
- Remove header-based navigation guidance in favor of direct content access
- Add guidance for breaking large documentation into smaller focused files
- Clarify that slopdocs documents already-installed components, not installation
- Update LLM consumption strategies to prioritize keyword matching and efficiency
- Add document size management recommendations for files over 2000 words
- Refine namespace guidelines to encourage deeper logical nesting when beneficial
clanker 1 mese fa
parent
commit
aa225db548

+ 56 - 0
MANIFEST.usm

@@ -0,0 +1,56 @@
+{
+  "name": "slopdocs",
+  "version": "0.0.1",
+  "summary": "Documentation for AIs",
+  "licences": [
+    {
+      "name": "GPL-3.0",
+      "text": "LICENSE",
+      "category": "libre"
+    }
+  ],
+  "provides": {
+    "res:slopdocs": {
+        "type": "dir",
+        "path": "",
+        "pathBase": "source"
+    },
+    "res:slopdocs/structure.slopdocs.md": "source:structure.slopdocs.md",
+    "res:slopdocs/structure.slopdocs.filesystem.md": "source:structure.slopdocs.filesystem.md",
+    "res:slopdocs/ethics.slopdocs.md": "source:ethics.slopdocs.md",
+    "bin:slopdocs-mcp-server": "as-expected"
+  },
+  "depends": {
+    "runtime": [
+      "lib:libglib-2.0.so",
+      "lib:libgobject-2.0.so",
+      "lib:libjson-glib-1.0.so",
+      "lib:libjsonrpc-glib-1.0.so",
+      "lib:libgio-2.0.so",
+      "lib:libgee-0.8.so",
+      "lib:libmcp-vala.so",
+      "lib:libc.so.6"
+    ],
+    "build": [
+      "bin:meson",
+      "bin:ninja",
+      "bin:valac",
+      "pc:glib-2.0.pc",
+      "pc:gobject-2.0.pc",
+      "pc:json-glib-1.0.pc",
+      "pc:jsonrpc-glib-1.0.pc",
+      "pc:gio-2.0.pc",
+      "pc:gee-0.8.pc",
+      "pc:mcp-vala.pc"
+    ],
+    "manage": [
+      "bin:bash"
+    ]
+  },
+  "flags": [],
+  "execs": {
+    "build": "scripts/build.sh",
+    "install": "scripts/install.sh"
+  },
+  "md": "README.md"
+}

+ 6 - 2
README.md

@@ -30,6 +30,11 @@ Instead of complex folder structures, slopdocs uses a flat file system with a na
 - `stack.node.versions.md` - Node.js version information
 - `structure.microservices.architecture.md` - Microservices architecture patterns
 - `ethics.ai.responsible.md` - Responsible AI guidelines
+- `library.react.frontend.components.buttons.md` - React button components (example of deeper nesting)
+- `library.json-glib.parsing.md` - JSON-GLib parsing utilities (correct nesting)
+- `library.json.glib.parsing.md` - Incorrect - breaks logical hierarchy
+
+The dot-separated naming creates logical nesting structure. Use dots to group related components (e.g., `json-glib` as a single component). You can use as many sub-components as needed to create logical, well-organized documentation. Large documents should be broken into smaller, focused files when they become extensive.
 
 This approach makes it easy for AI systems to find exactly what they're looking for without navigating complex directory structures.
 
@@ -70,7 +75,6 @@ Unlike documentation systems that might prioritize SEO or marketing, slopdocs is
 Slopdocs is specifically designed to be easily processed by AI systems. This optimization means:
 
 - Consistent formatting that machines can parse reliably
-- Clear section headers that help AI navigate content
 - Keyword optimization that improves searchability
 - Token efficiency that reduces computational costs
 
@@ -104,7 +108,7 @@ The slopdocs version conveys the same essential information in about half the wo
 
 ### Real-World Application
 
-When an AI coding agent needs to implement a React component, it can quickly locate `library.react.frontend.md`, scan the structured headers to find the relevant section, and extract the exact implementation details needed without processing unnecessary conversational content.
+When an AI coding agent needs to implement a React component, it can quickly locate `library.react.frontend.md` and extract the exact implementation details needed without processing unnecessary conversational content.
 
 This efficiency translates to faster response times, lower computational costs, and more accurate code generation.
 

+ 1 - 1
ethics.slopdocs.md

@@ -52,7 +52,7 @@ This document establishes ethical principles for Large Language Models (LLMs) wh
 - Explain concepts using the minimum necessary tokens
 - Avoid redundant information and verbose explanations
 - Use clear, direct language that maximizes information density
-- Structure documentation to minimize cognitive load
+- Structure documentation to minimize cognitive load while maintaining clear organization
 
 #### Optimal Information Delivery
 - Prioritize essential information over supplementary details

+ 38 - 0
mcp-server/README.md

@@ -0,0 +1,38 @@
+# Slopdocs MCP Server
+
+A simple MCP server that provides access to slopdocs as resources.
+
+## Features
+
+- Lists all slopdocs in the system as resources
+- Provides access to individual slopdocs content
+- Extracts summaries from slopdocs for quick preview
+- Supports markdown format with proper MIME types
+
+## Building
+
+```bash
+meson setup builddir
+cd builddir
+ninja
+```
+
+## Running
+
+```bash
+./slopdocs-mcp-server
+```
+
+## Environment Variables
+
+- `SLOPDOCS_DIR`: Directory where slopdocs are stored (default: /usr/share/slopdocs)
+
+## Usage
+
+The server provides slopdocs as MCP resources with URIs like:
+
+- `slopdocs://ethics` - Ethics guidelines
+- `slopdocs://structure` - Structure documentation
+- `slopdocs://structure-filesystem` - Filesystem structure docs
+
+Each resource includes the full content of the slopdoc with proper markdown formatting.

+ 32 - 0
mcp-server/meson.build

@@ -0,0 +1,32 @@
+project('slopdocs-mcp-server', 'vala', 'c',
+  version: '1.0.0',
+  default_options: ['warning_level=2', 'c_std=c11'],
+  license: 'MIT')
+
+# Dependencies
+jsonrpc_glib_dep = dependency('jsonrpc-glib-1.0')
+mcp_vala_dep = dependency('mcp-vala')
+glib_dep = dependency('glib-2.0')
+gio_dep = dependency('gio-2.0')
+gee_dep = dependency('gee-0.8')
+json_glib_dep = dependency('json-glib-1.0')
+
+# Source files
+sources = [
+  'src/main.vala',
+  'src/slopdocs-provider.vala'
+]
+
+# Executable
+executable('slopdocs-mcp-server',
+  sources,
+  dependencies: [
+    jsonrpc_glib_dep,
+    mcp_vala_dep,
+    glib_dep,
+    gio_dep,
+    gee_dep,
+    json_glib_dep
+  ],
+  install: true,
+)

+ 80 - 0
mcp-server/src/main.vala

@@ -0,0 +1,80 @@
+using Mcp;
+
+public class SlopdocsServer : GLib.Object {
+    private Mcp.Core.Server server;
+    private SlopdocsProvider slopdocs_provider;
+    
+    public SlopdocsServer () {
+        // Create server information
+        var server_info = new Mcp.Types.Protocol.ServerInfo (
+            "slopdocs-server",
+            "1.0.0"
+        );
+        server_info.description = "MCP server providing slopdocs resources";
+        
+        // Create server capabilities with resources enabled
+        var capabilities = new Mcp.Types.Protocol.ServerCapabilities ();
+        capabilities.logging = true;
+        capabilities.resources = new Mcp.Types.Protocol.ResourcesCapabilities ();
+        capabilities.resources.subscribe = false;  // Disable subscriptions for now
+        capabilities.resources.list_changed = true;  // Enable list change notifications
+        
+        // Create server
+        server = new Mcp.Core.Server (server_info, capabilities);
+        
+        // Create the slopdocs provider
+        var slopdocs_dir = get_slopdocs_dir ();
+        slopdocs_provider = new SlopdocsProvider (slopdocs_dir);
+        
+        // Register the resource provider
+        server.resource_manager.register_provider ("slopdocs", slopdocs_provider);
+    }
+    
+    private string get_slopdocs_dir () {
+        // Check environment variable first
+        var env_dir = Environment.get_variable ("SLOPDOCS_DIR");
+        if (env_dir != null) {
+            return env_dir;
+        }
+        
+        // Default to /usr/share/slopdocs
+        return "/usr/share/slopdocs";
+    }
+    
+    public async int run () {
+        try {
+            printerr("Starting slopdocs MCP server...\n");
+            printerr("Slopdocs directory: %s\n", get_slopdocs_dir ());
+            
+            // Start server
+            bool started = yield server.start ();
+            if (!started) {
+                GLib.stderr.printf ("Failed to start server\n");
+                return 1;
+            }
+            
+            printerr("Slopdocs server started successfully\n");
+            printerr("Waiting for MCP client connections...\n");
+            
+            // Run main loop
+            var main_loop = new MainLoop ();
+            main_loop.run ();
+            
+            return 0;
+        } catch (Error e) {
+            GLib.stderr.printf ("Server error: %s\n", e.message);
+            return 1;
+        }
+    }
+    
+    public static int main (string[] args) {
+        var app = new SlopdocsServer ();
+        app.run.begin ();
+        
+        // Keep main loop running
+        var loop = new MainLoop ();
+        loop.run ();
+        
+        return 0;
+    }
+}

+ 168 - 0
mcp-server/src/slopdocs-provider.vala

@@ -0,0 +1,168 @@
+using Mcp;
+using Gee;
+
+public class SlopdocsProvider : Mcp.Resources.BaseProvider {
+    private string slopdocs_dir;
+    private HashMap<string, SlopdocInfo> slopdocs_cache;
+    
+    public class SlopdocInfo : GLib.Object {
+        public string file_path { get; set; }
+        public string summary { get; set; }
+        public string title { get; set; }
+        public DateTime last_modified { get; set; }
+        
+        public SlopdocInfo (string file_path, string summary, string title, DateTime last_modified) {
+            this.file_path = file_path;
+            this.summary = summary;
+            this.title = title;
+            this.last_modified = last_modified;
+        }
+    }
+    
+    public SlopdocsProvider (string slopdocs_directory) {
+        this.slopdocs_dir = slopdocs_directory;
+        this.slopdocs_cache = new HashMap<string, SlopdocInfo> ();
+        refresh ();
+    }
+    
+    public void refresh () {
+        slopdocs_cache.clear ();
+        
+        try {
+            var directory = File.new_for_path (slopdocs_dir);
+            if (!directory.query_exists ()) {
+                warning ("Slopdocs directory does not exist: %s", slopdocs_dir);
+                return;
+            }
+            
+            var enumerator = directory.enumerate_children (
+                "standard::name,standard::type,standard::content-type,time::modified",
+                FileQueryInfoFlags.NONE
+            );
+            
+            FileInfo file_info;
+            while ((file_info = enumerator.next_file ()) != null) {
+                if (file_info.get_file_type () == FileType.REGULAR &&
+                    file_info.get_name ().has_suffix (".md")) {
+                    
+                    var file_path = Path.build_filename (slopdocs_dir, file_info.get_name ());
+                    var modification_time = file_info.get_modification_date_time ();
+                    var slopdoc_info = parse_slopdoc (file_path, modification_time.to_unix ());
+                    var resource_name = get_resource_name_from_filename (file_info.get_name ());
+                    slopdocs_cache[resource_name] = slopdoc_info;
+                }
+            }
+        } catch (Error e) {
+            warning ("Failed to scan slopdocs directory: %s", e.message);
+        }
+    }
+    
+    private string get_resource_name_from_filename (string filename) {
+        // Convert filename to resource URI format
+        // e.g., "ethics.slopdocs.md" -> "slopdocs://ethics.slopdocs.md"
+        return "slopdocs://%s".printf (filename);
+    }
+    
+    private SlopdocInfo parse_slopdoc (string file_path, int64 modified_time) {
+        SlopdocInfo info = new SlopdocInfo ("", "", "", new DateTime.now ());
+        info.file_path = file_path;
+        info.last_modified = new DateTime.from_unix_utc (modified_time);
+        
+        try {
+            string content;
+            FileUtils.get_contents (file_path, out content);
+            
+            // Extract title from first H1 heading
+            var lines = content.split ("\n");
+            foreach (var line in lines) {
+                if (line.has_prefix ("# ")) {
+                    info.title = line.substring (2).strip ();
+                    break;
+                }
+            }
+            
+            // If no title found, use filename without extension
+            if (info.title == null || info.title == "") {
+                info.title = Path.get_basename (file_path).replace (".md", "");
+            }
+            
+            // Extract summary from the end of the document
+            // Summary is the text after the final "---" marker
+            var parts = content.split ("---");
+            if (parts.length > 1) {
+                var summary_section = parts[parts.length - 1].strip ();
+                if (summary_section != "") {
+                    info.summary = summary_section;
+                } else {
+                    info.summary = "No summary available";
+                }
+            } else {
+                info.summary = "No summary available";
+            }
+            
+        } catch (Error e) {
+            warning ("Failed to parse slopdoc %s: %s", file_path, e.message);
+            info.title = Path.get_basename (file_path).replace (".md", "");
+            info.summary = "Failed to parse document";
+        }
+        
+        return info;
+    }
+    
+    public override async Gee.ArrayList<Mcp.Resources.Types.Resource> list_resources (string? cursor) throws Error {
+        var resources = new Gee.ArrayList<Mcp.Resources.Types.Resource> ();
+        
+        foreach (var entry in slopdocs_cache.entries) {
+            var resource = new Mcp.Resources.Types.Resource (
+                entry.key,
+                entry.value.title
+            );
+            resource.description = entry.value.summary;
+            resource.mime_type = "text/markdown";
+            
+            resources.add (resource);
+        }
+        
+        return resources;
+    }
+    
+    public override async Gee.ArrayList<Mcp.Types.Common.ResourceContents> read_resource (string uri) throws Error {
+        if (!uri.has_prefix ("slopdocs://")) {
+            throw new Mcp.Core.McpError.INVALID_REQUEST ("Invalid URI scheme");
+        }
+        
+        // The URI should be the full resource name including filename
+        // e.g., "slopdocs://structure.slopdocs.md"
+        var resource_name = uri; // Use the full URI as the key
+        
+        if (!slopdocs_cache.has_key (resource_name)) {
+            throw new Mcp.Core.McpError.RESOURCE_NOT_FOUND ("Resource not found: %s".printf (resource_name));
+        }
+        
+        var slopdoc_info = slopdocs_cache[resource_name];
+        
+        try {
+            string content;
+            FileUtils.get_contents (slopdoc_info.file_path, out content);
+            
+            // Return as text content wrapped in ArrayList
+            var result = new Gee.ArrayList<Mcp.Types.Common.ResourceContents> ();
+            result.add (new Mcp.Types.Common.TextResourceContents (uri, content));
+            
+            return result;
+            
+        } catch (Error e) {
+            throw new Mcp.Core.McpError.INTERNAL_ERROR ("Failed to read file: %s".printf (e.message));
+        }
+    }
+    
+    public override async void subscribe (string uri) throws Error {
+        // For now, we don't support subscriptions
+        throw new Mcp.Core.McpError.INVALID_REQUEST ("Subscriptions not supported");
+    }
+    
+    public override async void unsubscribe (string uri) throws Error {
+        // For now, we don't support subscriptions
+        throw new Mcp.Core.McpError.INVALID_REQUEST ("Subscriptions not supported");
+    }
+}

+ 11 - 0
scripts/build.sh

@@ -0,0 +1,11 @@
+#!/usr/bin/bash
+set -e
+
+src_dir=$(pwd)
+build_dir=$1
+
+cd ${build_dir}
+
+meson setup ${src_dir}/mcp-server --prefix=${PREFIX} --bindir=${BINDIR} --includedir=${INCLUDEDIR}
+ninja
+

+ 10 - 0
scripts/install.sh

@@ -0,0 +1,10 @@
+    #!/bin/bash
+    set -e
+
+    src_dir=$(pwd)
+    build_dir=$1
+    install_dir=$2
+
+    cd ${build_dir}
+
+    meson install --destdir ${install_dir}

+ 34 - 12
structure.slopdocs.filesystem.md

@@ -63,14 +63,15 @@ root.component.subcomponent.subsubcomponent.md
 ### Namespace Requirements
 - **Minimum**: 2 namespace parts (root.component.md)
 - **Maximum**: Unlimited parts as needed for proper organization
-- **Guideline**: Use the minimum number of parts needed for clear organization while avoiding ambiguity
+- **Guideline**: Use as many namespace parts as needed to create logical, well-organized documentation structure
 
 ### Naming Convention Rules
 - All components are lowercase
 - Multi-word components use hyphens for separation
-- Each dot represents a level in the logical hierarchy
+- Each dot represents a level in the logical hierarchy (nesting)
 - The file extension is always `.md`
 - Focus on practical, descriptive names that clearly indicate content
+- Use dots to create logical nesting structure (e.g., library.json-glib.parsing.md)
 
 ### Examples of Valid File Names
 
@@ -233,7 +234,30 @@ Choose names that balance clarity with brevity to minimize processing overhead:
 ✓ library.react.md (minimal, clear)
 ✓ library.react.frontend.md (specific when needed)
 ✓ library.react.frontend.component-library.md (as specific as needed)
-✗ library.react.frontend.component-library.ui-elements.md (excessive)
+✓ library.react.frontend.component-library.ui-elements.md (as specific as needed)
+✓ library.react.frontend.component-library.ui-elements.buttons.md (as specific as needed)
+✓ library.json-glib.parsing.md (correct - dots create nesting)
+✗ library.json.glib.parsing.md (incorrect - breaks logical hierarchy)
+```
+
+### Document Size Management
+Break large documentation into smaller, focused files when:
+- A single document becomes excessively long (over 2000 words)
+- Different sections serve distinct purposes
+- Content can be logically separated into standalone topics
+- Specific information is frequently accessed independently
+
+Example of breaking down large documentation:
+```
+Instead of: library.react.frontend.everything.md (very large)
+
+Use:
+- library.react.frontend.md (core concepts)
+- library.react.frontend.components.md (component patterns)
+- library.react.frontend.hooks.md (custom hooks)
+- library.react.frontend.routing.md (navigation)
+- library.react.frontend.state-management.md (state patterns)
+- library.react.frontend.testing.md (testing approaches)
 ```
 
 ## File Organization Examples
@@ -355,21 +379,19 @@ Looking for: library.react.v19.frontend.md
 ### Content Discovery Strategy
 LLMs should use this strategy for efficient content discovery:
 
-1. **Header-First Scanning**: Scan document headers to understand structure
-2. **Keyword Matching**: Match query keywords with document content
-3. **Cross-Reference Following**: Follow links to related documents
-4. **Context Building**: Build context from multiple related documents
-5. **Resource Optimization**: Prioritize minimal namespace files to reduce processing overhead
+1. **Keyword Matching**: Match query keywords with document content
+2. **Cross-Reference Following**: Follow links to related documents
+3. **Context Building**: Build context from multiple related documents
+4. **Resource Optimization**: Prioritize minimal namespace files to reduce processing overhead
 
 ### Query Resolution Workflow
 For answering technical questions:
 ```
 1. Parse query to identify relevant namespaces
 2. Locate candidate documents based on filename patterns
-3. Scan document headings for relevant sections
-4. Extract specific information from identified sections
-5. Synthesize information from multiple documents when needed
-6. Include references to source documents
+3. Extract specific information from documents
+4. Synthesize information from multiple documents when needed
+5. Include references to source documents
 ```
 
 ### Integration with Development Workflows

+ 14 - 12
structure.slopdocs.md

@@ -11,6 +11,7 @@ This guide is specifically designed for LLM coding agents that generate slopdocs
 - Create consistent documentation that serves as a single source of truth
 - Reduce barriers to entry for working with unfamiliar or new technologies
 - Minimize computational resources required for documentation generation and consumption
+- Document how to use components that are already installed on the system
 
 ## Writing Style and Tone
 
@@ -98,12 +99,11 @@ The summary should be plain text without any heading unless a level 1 heading is
 ## Best Practices for LLM-Generated Documentation
 
 ### Information Structure for LLM Consumption
-1. **Header-Based Navigation**: Structure content with descriptive headers for efficient parsing
-2. **Keyword Optimization**: Include relevant technical terms in headings and content
-3. **Context Provision**: Provide sufficient context in section introductions
-4. **Self-Contained Sections**: Make sections understandable without excessive cross-referencing
-5. **Summary Sections**: Include summaries for complex topics to aid comprehension
-6. **Token Efficiency**: Structure content to minimize processing overhead
+1. **Keyword Optimization**: Include relevant technical terms in headings and content
+2. **Context Provision**: Provide sufficient context in section introductions
+3. **Self-Contained Sections**: Make sections understandable without excessive cross-referencing
+4. **Summary Sections**: Include summaries for complex topics to aid comprehension
+5. **Token Efficiency**: Structure content to minimize processing overhead
 
 ### Balancing Completeness and Conciseness
 - Include all essential information for implementation
@@ -112,6 +112,8 @@ The summary should be plain text without any heading unless a level 1 heading is
 - Provide references to additional information without duplicating content
 - Use links to related documentation rather than repeating information
 - Optimize for minimal token usage while maintaining clarity
+- Break large documentation into smaller, focused files when content becomes extensive
+- Never include installation or build instructions - slopdocs document components that are already installed
 
 ### Ensuring Information Accuracy and Relevance
 - Verify all technical information before inclusion
@@ -139,12 +141,7 @@ The summary should be plain text without any heading unless a level 1 heading is
 ## Overview
 React is a JavaScript library for building user interfaces with component-based architecture.
 
-## Installation
-```bash
-npm install react@18.2.0
-```
-
-## Component Creation
+## Usage
 ```javascript
 import React from 'react';
 
@@ -278,6 +275,7 @@ If something goes wrong, you'll get an error code. 401 means wrong password, 403
 - Include practical examples in implementation sections
 - Provide cross-references to related information
 - Maintain appropriate level of detail for each section
+- Consider breaking large sections into separate documents when they become too extensive
 
 ## Quality Assurance Checklist
 
@@ -329,6 +327,9 @@ If something goes wrong, you'll get an error code. 401 means wrong password, 403
 - Provide sufficient context for understanding without excessive detail
 - Prioritize practical problem-solving approaches
 - Ensure all technical claims are verified and accurate
+- Break large documentation into multiple focused files when content exceeds 2000 words
+- Use additional namespace components to create logical document hierarchies
+- Never include installation, build, or setup instructions - document usage of already-installed components
 
 ### Self-Evaluation Criteria
 - Would another LLM be able to understand and use this information?
@@ -339,6 +340,7 @@ If something goes wrong, you'll get an error code. 401 means wrong password, 403
 - Does the content demonstrate resource efficiency through conciseness?
 - Does the documentation focus on practical problem solving?
 - Is the content accurate and professionally responsible?
+- Does the document focus on usage rather than installation or building?
 
 ---