418 lines
13 KiB
Markdown
418 lines
13 KiB
Markdown
# AI Repo Commander - Technical Design Document
|
|
|
|
## 1. Overview
|
|
|
|
A browser userscript that enables AI assistants to securely interact with git repositories via YAML-style commands, with comprehensive safety measures and real-time feedback.
|
|
|
|
## 1.1 Diagrams (PlantUML)
|
|
|
|
- Architecture Overview: Docs/diagrams/architecture-overview.puml
|
|
- Command Execution Sequence: Docs/diagrams/sequence-command-execution.puml
|
|
- Command Processing State Machine: Docs/diagrams/state-machine.puml
|
|
|
|
How to view: open the .puml files with any PlantUML viewer (IDE plugin or web renderer) to generate images.
|
|
|
|
## 2. Core Architecture
|
|
|
|
### 2.1 Safety-First Design
|
|
|
|
```javascript
|
|
// Configuration (persisted via localStorage)
|
|
const DEFAULT_CONFIG = {
|
|
ENABLE_API: true,
|
|
DEBUG_MODE: true,
|
|
DEBUG_LEVEL: 2,
|
|
DEBUG_WATCH_MS: 120000,
|
|
DEBUG_MAX_LINES: 400,
|
|
DEBUG_SHOW_PANEL: true,
|
|
|
|
// Timing & API
|
|
DEBOUNCE_DELAY: 6500, // streaming debounce before settle
|
|
MAX_RETRIES: 2,
|
|
VERSION: '1.6.2',
|
|
API_TIMEOUT_MS: 60000,
|
|
|
|
PROCESS_EXISTING: false, // resume-safe guard
|
|
ASSISTANT_ONLY: true,
|
|
BRIDGE_KEY: '',
|
|
|
|
// Persistent dedupe window
|
|
DEDUPE_TTL_MS: 30 * 24 * 60 * 60 * 1000, // 30 days
|
|
|
|
COLD_START_MS: 2000, // avoid immediate re-exec on reload
|
|
SHOW_EXECUTED_MARKER: true,
|
|
|
|
// Housekeeping
|
|
CLEANUP_AFTER_MS: 30000,
|
|
CLEANUP_INTERVAL_MS: 60000,
|
|
|
|
// Paste + submit behavior
|
|
APPEND_TRAILING_NEWLINE: true,
|
|
AUTO_SUBMIT: true,
|
|
POST_PASTE_DELAY_MS: 250,
|
|
SUBMIT_MODE: 'button_first',
|
|
|
|
// Streaming complete hardening
|
|
REQUIRE_TERMINATOR: true, // requires @end@
|
|
SETTLE_CHECK_MS: 1300, // stable window after last change
|
|
SETTLE_POLL_MS: 250, // settle poll frequency
|
|
|
|
// Runtime toggles
|
|
RUNTIME: { PAUSED: false },
|
|
|
|
// Hardening & perf
|
|
STUCK_AFTER_MS: 10 * 60 * 1000,
|
|
SCAN_DEBOUNCE_MS: 400,
|
|
FAST_WARN_MS: 50,
|
|
SLOW_WARN_MS: 60_000,
|
|
|
|
// Queue management
|
|
QUEUE_MIN_DELAY_MS: 800,
|
|
QUEUE_MAX_PER_MINUTE: 15,
|
|
QUEUE_MAX_PER_MESSAGE: 5,
|
|
QUEUE_WAIT_FOR_COMPOSER_MS: 6000,
|
|
|
|
RESPONSE_BUFFER_FLUSH_DELAY_MS: 500,
|
|
RESPONSE_BUFFER_SECTION_HEADINGS: true,
|
|
|
|
MAX_PASTE_CHARS: 250_000,
|
|
SPLIT_LONG_RESPONSES: true,
|
|
};
|
|
```
|
|
|
|
### 2.2 Module Structure
|
|
|
|
```
|
|
AI Repo Commander
|
|
├── Core Monitor
|
|
├── Command Parser
|
|
├── Validation Engine
|
|
├── Execution Manager
|
|
└── UI Feedback System
|
|
```
|
|
|
|
## 3. Detailed Component Specifications
|
|
|
|
### 3.1 Core Monitor
|
|
|
|
**Purpose:** Detect and track command messages safely
|
|
|
|
**Implementation:**
|
|
|
|
```javascript
|
|
class CommandMonitor {
|
|
private trackedMessages: Map<string, CommandState>;
|
|
|
|
// Message states
|
|
static STATES = {
|
|
DETECTED: 'detected', // @bridge@ found
|
|
PARSING: 'parsing', // YAML parsing in progress
|
|
VALIDATING: 'validating', // Field validation
|
|
DEBOUNCING: 'debouncing', // 5-second wait period
|
|
EXECUTING: 'executing', // API call in progress
|
|
COMPLETE: 'complete', // Command finished
|
|
ERROR: 'error' // Command failed
|
|
};
|
|
|
|
scanMessages(): void; // Find new command messages
|
|
trackMessage(element, text): void; // Begin processing pipeline
|
|
updateState(messageId, state): void; // State machine transitions
|
|
}
|
|
```
|
|
|
|
### 3.2 Command Parser
|
|
|
|
**Purpose:** Extract structured data from YAML commands
|
|
|
|
**Input Format:**
|
|
|
|
```yaml
|
|
@bridge@
|
|
action: update_file
|
|
repo: ai-workflow-test
|
|
path: README.md
|
|
content: |
|
|
Multi-line content
|
|
with proper formatting
|
|
@end@
|
|
```
|
|
|
|
**Parsing Logic:**
|
|
|
|
```javascript
|
|
class CommandParser {
|
|
parseYAMLCommand(text): ParsedCommand {
|
|
// 1. Extract command block (@bridge@ ... @end@ terminator required)
|
|
// 2. Parse key-value pairs
|
|
// 3. Handle multi-line content with | syntax
|
|
// 4. Set defaults (url, owner if missing)
|
|
// 5. Return structured object
|
|
}
|
|
|
|
validateStructure(parsed): ValidationResult {
|
|
// Check for required fields based on action type
|
|
// Validate field formats
|
|
// Return { isValid: boolean, errors: string[] }
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3.3 Validation Engine
|
|
|
|
**Purpose:** Ensure command completeness and safety
|
|
|
|
**Required Fields Matrix:**
|
|
|
|
```javascript
|
|
const REQUIRED_FIELDS = {
|
|
'update_file': ['action', 'repo', 'path', 'content'],
|
|
'get_file': ['action', 'repo', 'path'],
|
|
'create_repo': ['action', 'repo'],
|
|
'create_file': ['action', 'repo', 'path', 'content'],
|
|
'delete_file': ['action', 'repo', 'path'],
|
|
'list_files': ['action', 'repo', 'path']
|
|
};
|
|
|
|
const FIELD_VALIDATORS = {
|
|
'repo': (value) => /^[\w\-\.]+$/.test(value),
|
|
'path': (value) => !value.includes('..') && !value.startsWith('/'),
|
|
'action': (value) => Object.keys(REQUIRED_FIELDS).includes(value)
|
|
};
|
|
```
|
|
|
|
### 3.4 Execution Manager
|
|
|
|
**Purpose:** Handle API calls with comprehensive safety
|
|
|
|
**Execution Flow:**
|
|
|
|
```javascript
|
|
class ExecutionManager {
|
|
async executeCommand(command, sourceElement): Promise<ExecutionResult> {
|
|
// 1. Pre-execution safety checks
|
|
if (!CONFIG.ENABLE_API) {
|
|
return this.mockExecution(command, sourceElement);
|
|
}
|
|
|
|
// 2. API call with retry logic
|
|
try {
|
|
const response = await this.makeAPICall(command);
|
|
return this.handleSuccess(response, sourceElement);
|
|
} catch (error) {
|
|
return this.handleError(error, sourceElement);
|
|
}
|
|
}
|
|
|
|
makeAPICall(command): Promise<APIResponse> {
|
|
return new Promise((resolve, reject) => {
|
|
GM_xmlhttpRequest({
|
|
method: 'POST',
|
|
url: command.url || 'https://n8n.brrd.tech/webhook/ai-gitea-bridge',
|
|
headers: {
|
|
'X-Bridge-Key': 'mango-rocket-82',
|
|
'Content-Type': 'application/json'
|
|
},
|
|
data: JSON.stringify(command),
|
|
timeout: 30000,
|
|
onload: resolve,
|
|
onerror: reject,
|
|
ontimeout: reject
|
|
});
|
|
});
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3.5 UI Feedback System
|
|
|
|
**Purpose:** Provide clear, consistent user feedback
|
|
|
|
**Status Message Templates:**
|
|
|
|
```javascript
|
|
const STATUS_TEMPLATES = {
|
|
SUCCESS: '[{action}: Success] {details}',
|
|
ERROR: '[{action}: Error] {details}',
|
|
VALIDATION_ERROR: '[{action}: Invalid] {details}',
|
|
EXECUTING: '[{action}: Processing...]',
|
|
MOCK: '[{action}: Mock] {details}'
|
|
};
|
|
|
|
class UIFeedback {
|
|
replaceWithStatus(sourceElement, template, data): void {
|
|
// 1. Create status element matching original style
|
|
// 2. Apply appropriate color coding
|
|
// 3. Replace original message
|
|
// 4. Add copy-friendly formatting
|
|
}
|
|
|
|
colorCodeStatus(type): string {
|
|
return {
|
|
'success': '#10B981', // Green
|
|
'error': '#EF4444', // Red
|
|
'warning': '#F59E0B', // Yellow
|
|
'info': '#3B82F6' // Blue
|
|
}[type];
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3.6 Execution Queue
|
|
|
|
Purpose: Serialize command execution with rate limits and minimal spacing between actions.
|
|
|
|
Highlights:
|
|
- Min delay between tasks: CONFIG.QUEUE_MIN_DELAY_MS
|
|
- Rate cap: CONFIG.QUEUE_MAX_PER_MINUTE
|
|
- Fire-and-forget push; internal drain loop ensures sequential execution
|
|
|
|
```javascript
|
|
class ExecutionQueue {
|
|
push(task) { /* queue and begin drain */ }
|
|
async _drain() { /* rate-limit and run */ }
|
|
}
|
|
```
|
|
|
|
### 3.7 Response Buffer (paste pipeline)
|
|
|
|
Purpose: Collect response chunks (e.g., get_file content or list_files listing) and paste them into the composer once nearby tasks finish, respecting size limits.
|
|
|
|
Highlights:
|
|
- Delayed flush (CONFIG.RESPONSE_BUFFER_FLUSH_DELAY_MS) to batch sibling results
|
|
- Splitting long responses (CONFIG.SPLIT_LONG_RESPONSES, CONFIG.MAX_PASTE_CHARS)
|
|
- Uses pasteAndMaybeSubmit(text) which pastes and optionally auto-submits
|
|
|
|
### 3.8 Conversation-Aware History (dedupe)
|
|
|
|
Purpose: Avoid re-executing the same command in the same conversation across reloads.
|
|
|
|
Highlights:
|
|
- Fingerprint of message element (plus optional sub-index) stored in localStorage with TTL (CONFIG.DEDUPE_TTL_MS)
|
|
- Per-message, per-command "Run again" UI allows manual re-exec
|
|
- SHOW_EXECUTED_MARKER outlines executed messages in green
|
|
|
|
### 3.9 Paste + Submit Mechanics
|
|
|
|
Purpose: Robustly paste text into the site-specific composer and submit.
|
|
|
|
Paste flow (tries in order):
|
|
- Dispatch ClipboardEvent('paste', clipboardData)
|
|
- ProseMirror innerHTML paragraphs with input/change events
|
|
- Selection/Range insertion for contentEditable; setRangeText for inputs/textareas
|
|
- Direct value/textContent assignment as a fallback
|
|
- GM_setClipboard as last resort (manual paste)
|
|
|
|
Submit flow:
|
|
- Find send button scoped to nearest form/composer/main first
|
|
- If no button or enter-only mode, simulate Enter key events on the input
|
|
|
|
### 3.10 Notifications
|
|
|
|
Purpose: Present OS-level notifications via userscript APIs when available.
|
|
|
|
- Implementation: Direct calls to GM_notification for OS-level notifications.
|
|
- Userscript header includes: `@grant GM_notification` to enable the API in Tampermonkey/Violentmonkey.
|
|
- IDE hint: A top-of-file comment `/* global GM_notification */` is present to silence unresolved symbol warnings in WebStorm.
|
|
- Portability note: No wrapper is used. If the script is executed outside a userscript manager, GM_notification will not exist and notifications are skipped; the in-page debug panel/toasts provide fallback visibility.
|
|
|
|
## 4. Processing Pipeline
|
|
|
|
### 4.1 Step-by-Step Flow
|
|
|
|
```
|
|
1. MONITOR: Detect @bridge@ command blocks in assistant messages; extract all complete blocks per message.
|
|
2. TRACK: Assign readable message ID; mark per-command history to avoid re-exec; show queue badge.
|
|
3. PARSE: Extract inner YAML-like key/values from @bridge@ ... @end@; apply defaults; expand owner/repo shorthand.
|
|
4. VALIDATE: Check required fields based on action; treat examples specially (skip execution).
|
|
5. DEBOUNCE: Wait DEBOUNCE_DELAY, then run SETTLE window to ensure the final, stable command text.
|
|
6. EXECUTE (queue): Serialize via ExecutionQueue with rate limits; GM_xmlhttpRequest to bridge with retries.
|
|
7. FEEDBACK: Render per-command status lines; paste response bodies via ResponseBuffer into the composer.
|
|
8. SUBMIT: Optionally auto-submit after paste using scoped send button or Enter key events.
|
|
9. COMPLETE: Update state and timestamps; maintain history TTL; attach per-command "Run again" buttons for manual control.
|
|
```
|
|
|
|
### 4.2 Error Handling Flow
|
|
|
|
```
|
|
Parse Error → [Action: Invalid] Invalid YAML format
|
|
Validation Error → [Action: Invalid] Missing field: content
|
|
API Error → [Action: Error] Network timeout
|
|
Network Error → [Action: Error] Cannot reach bridge
|
|
```
|
|
|
|
## 5. Safety Mechanisms
|
|
|
|
### 5.1 Multiple Protection Layers
|
|
|
|
- API Master Switch: ENABLE_API gate and runtime PAUSED toggle
|
|
- Command Validation: required fields per action, example detection
|
|
- Streaming Hardened: DEBOUNCE_DELAY + SETTLE_CHECK_MS window ensures complete blocks
|
|
- Rate Limiting: ExecutionQueue caps per-minute and enforces inter-task delay
|
|
- Persistent Dedupe: conversation-aware history with TTL to prevent re-exec across reloads
|
|
- UI Safeguards: per-command "Run again" instead of auto-reexec; executed marker on messages
|
|
- Network Limits: API_TIMEOUT_MS and bounded retries
|
|
- Error Isolation: per-command try/catch with inline validation handling (no throw/catch ping-pong)
|
|
|
|
### 5.2 Emergency Stop Options
|
|
|
|
```javascript
|
|
// Manual stop mechanisms
|
|
const emergencyStop = () => {
|
|
CONFIG.ENABLE_API = false;
|
|
CommandMonitor.stopAllProcessing();
|
|
clearAllIntervals();
|
|
};
|
|
|
|
// Browser console commands
|
|
window.AI_REPO_STOP = emergencyStop;
|
|
```
|
|
|
|
## 6. Cross-Platform Compatibility
|
|
|
|
### 6.1 DOM Selectors by Platform
|
|
|
|
```javascript
|
|
const PLATFORM_SELECTORS = {
|
|
'chat.openai.com': { messages: '[data-message-author-role]', input: '#prompt-textarea, textarea, [contenteditable="true"]', content: '.markdown' },
|
|
'chatgpt.com': { messages: '[data-message-author-role]', input: '#prompt-textarea, textarea, [contenteditable="true"]', content: '.markdown' },
|
|
'claude.ai': { messages: '.chat-message', input: '[contenteditable="true"]', content: '.content' },
|
|
'gemini.google.com': { messages: '.message-content', input: 'textarea, [contenteditable="true"]', content: '.message-text' }
|
|
};
|
|
```
|
|
|
|
## 7. Testing Strategy
|
|
|
|
### 7.1 Development Testing Commands
|
|
|
|
```javascript
|
|
// Test command generator for safe testing
|
|
const TEST_COMMANDS = {
|
|
validUpdate: '@bridge@\naction: update_file\nrepo: test-repo\npath: TEST.md\ncontent: |\n Test content\n Multiple lines\n@end@',
|
|
invalidCommand: '@bridge@\naction: update_file\nrepo: test-repo\n@end@',
|
|
getFile: '@bridge@\naction: get_file\nrepo: test-repo\npath: README.md\n@end@'
|
|
};
|
|
```
|
|
|
|
## 8. Deployment Checklist
|
|
|
|
### 8.1 Pre-Launch Verification
|
|
|
|
- ENABLE_API = false in production code
|
|
- All error cases handled gracefully
|
|
- Status messages clear and informative
|
|
- Bot typing protection working
|
|
- Cross-browser compatibility verified
|
|
- Memory leaks checked (interval cleanup)
|
|
- Performance impact acceptable
|
|
|
|
### 8.2 Production Enablement Steps
|
|
|
|
1. Test thoroughly with ENABLE_API = false
|
|
2. Verify mock executions work correctly
|
|
3. Enable API for single test command
|
|
4. Monitor real API interactions
|
|
5. Enable for full usage
|
|
|
|
---
|
|
|
|
This design provides a comprehensive, safe, and extensible foundation for your AI Repo Commander. |