fixed all warnings and the docs
This commit is contained in:
parent
0da540b575
commit
b446771480
|
|
@ -17,13 +17,66 @@ How to view: open the .puml files with any PlantUML viewer (IDE plugin or web re
|
||||||
### 2.1 Safety-First Design
|
### 2.1 Safety-First Design
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// Configuration - MUST be manually enabled for production
|
// Configuration (persisted via localStorage)
|
||||||
const CONFIG = {
|
const DEFAULT_CONFIG = {
|
||||||
ENABLE_API: false, // Master kill switch
|
ENABLE_API: true,
|
||||||
DEBUG_MODE: true, // Development logging
|
DEBUG_MODE: true,
|
||||||
DEBOUNCE_DELAY: 5000, // 5-second bot typing protection
|
DEBUG_LEVEL: 2,
|
||||||
MAX_RETRIES: 2, // API retry attempts
|
DEBUG_WATCH_MS: 120000,
|
||||||
VERSION: '1.0.0'
|
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,
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -52,7 +105,7 @@ class CommandMonitor {
|
||||||
|
|
||||||
// Message states
|
// Message states
|
||||||
static STATES = {
|
static STATES = {
|
||||||
DETECTED: 'detected', // ^%$bridge found
|
DETECTED: 'detected', // @bridge@ found
|
||||||
PARSING: 'parsing', // YAML parsing in progress
|
PARSING: 'parsing', // YAML parsing in progress
|
||||||
VALIDATING: 'validating', // Field validation
|
VALIDATING: 'validating', // Field validation
|
||||||
DEBOUNCING: 'debouncing', // 5-second wait period
|
DEBOUNCING: 'debouncing', // 5-second wait period
|
||||||
|
|
@ -61,9 +114,9 @@ class CommandMonitor {
|
||||||
ERROR: 'error' // Command failed
|
ERROR: 'error' // Command failed
|
||||||
};
|
};
|
||||||
|
|
||||||
scanMessages(): void // Find new command messages
|
scanMessages(): void; // Find new command messages
|
||||||
trackMessage(element, text): void // Begin processing pipeline
|
trackMessage(element, text): void; // Begin processing pipeline
|
||||||
updateState(messageId, state): void // State machine transitions
|
updateState(messageId, state): void; // State machine transitions
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -74,14 +127,14 @@ class CommandMonitor {
|
||||||
**Input Format:**
|
**Input Format:**
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
^%$bridge
|
@bridge@
|
||||||
action: update_file
|
action: update_file
|
||||||
repo: ai-workflow-test
|
repo: ai-workflow-test
|
||||||
path: README.md
|
path: README.md
|
||||||
content: |
|
content: |
|
||||||
Multi-line content
|
Multi-line content
|
||||||
with proper formatting
|
with proper formatting
|
||||||
---
|
@end@
|
||||||
```
|
```
|
||||||
|
|
||||||
**Parsing Logic:**
|
**Parsing Logic:**
|
||||||
|
|
@ -89,7 +142,7 @@ content: |
|
||||||
```javascript
|
```javascript
|
||||||
class CommandParser {
|
class CommandParser {
|
||||||
parseYAMLCommand(text): ParsedCommand {
|
parseYAMLCommand(text): ParsedCommand {
|
||||||
// 1. Extract command block (^%$bridge to ---)
|
// 1. Extract command block (@bridge@ ... @end@ terminator required)
|
||||||
// 2. Parse key-value pairs
|
// 2. Parse key-value pairs
|
||||||
// 3. Handle multi-line content with | syntax
|
// 3. Handle multi-line content with | syntax
|
||||||
// 4. Set defaults (url, owner if missing)
|
// 4. Set defaults (url, owner if missing)
|
||||||
|
|
@ -204,19 +257,78 @@ class UIFeedback {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 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. Processing Pipeline
|
||||||
|
|
||||||
### 4.1 Step-by-Step Flow
|
### 4.1 Step-by-Step Flow
|
||||||
|
|
||||||
```
|
```
|
||||||
1. MONITOR: Detect ^%$bridge in new messages
|
1. MONITOR: Detect @bridge@ command blocks in assistant messages; extract all complete blocks per message.
|
||||||
2. TRACK: Assign unique ID and initial state
|
2. TRACK: Assign readable message ID; mark per-command history to avoid re-exec; show queue badge.
|
||||||
3. PARSE: Extract YAML into structured command
|
3. PARSE: Extract inner YAML-like key/values from @bridge@ ... @end@; apply defaults; expand owner/repo shorthand.
|
||||||
4. VALIDATE: Check required fields and formats
|
4. VALIDATE: Check required fields based on action; treat examples specially (skip execution).
|
||||||
5. DEBOUNCE: Wait 5 seconds for bot typing completion
|
5. DEBOUNCE: Wait DEBOUNCE_DELAY, then run SETTLE window to ensure the final, stable command text.
|
||||||
6. EXECUTE: Make API call (or mock if disabled)
|
6. EXECUTE (queue): Serialize via ExecutionQueue with rate limits; GM_xmlhttpRequest to bridge with retries.
|
||||||
7. FEEDBACK: Replace with status message
|
7. FEEDBACK: Render per-command status lines; paste response bodies via ResponseBuffer into the composer.
|
||||||
8. CLEANUP: Update state to complete
|
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
|
### 4.2 Error Handling Flow
|
||||||
|
|
@ -232,12 +344,14 @@ Network Error → [Action: Error] Cannot reach bridge
|
||||||
|
|
||||||
### 5.1 Multiple Protection Layers
|
### 5.1 Multiple Protection Layers
|
||||||
|
|
||||||
- **API Master Switch:** ENABLE_API must be explicitly true
|
- API Master Switch: ENABLE_API gate and runtime PAUSED toggle
|
||||||
- **Command Validation:** Required fields and format checking
|
- Command Validation: required fields per action, example detection
|
||||||
- **Bot Debouncing:** 5-second wait prevents partial command execution
|
- Streaming Hardened: DEBOUNCE_DELAY + SETTLE_CHECK_MS window ensures complete blocks
|
||||||
- **Network Timeouts:** 30-second API call limits
|
- Rate Limiting: ExecutionQueue caps per-minute and enforces inter-task delay
|
||||||
- **Error Boundaries:** Isolated error handling per command
|
- Persistent Dedupe: conversation-aware history with TTL to prevent re-exec across reloads
|
||||||
- **State Tracking:** Prevents duplicate processing
|
- 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
|
### 5.2 Emergency Stop Options
|
||||||
|
|
||||||
|
|
@ -259,18 +373,10 @@ window.AI_REPO_STOP = emergencyStop;
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const PLATFORM_SELECTORS = {
|
const PLATFORM_SELECTORS = {
|
||||||
'chat.openai.com': {
|
'chat.openai.com': { messages: '[data-message-author-role]', input: '#prompt-textarea, textarea, [contenteditable="true"]', content: '.markdown' },
|
||||||
messages: '[class*="message"]',
|
'chatgpt.com': { messages: '[data-message-author-role]', input: '#prompt-textarea, textarea, [contenteditable="true"]', content: '.markdown' },
|
||||||
input: '#prompt-textarea'
|
'claude.ai': { messages: '.chat-message', input: '[contenteditable="true"]', content: '.content' },
|
||||||
},
|
'gemini.google.com': { messages: '.message-content', input: 'textarea, [contenteditable="true"]', content: '.message-text' }
|
||||||
'claude.ai': {
|
|
||||||
messages: '.chat-message',
|
|
||||||
input: '[contenteditable="true"]'
|
|
||||||
},
|
|
||||||
'gemini.google.com': {
|
|
||||||
messages: '.message-content',
|
|
||||||
input: 'textarea, [contenteditable="true"]'
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -281,25 +387,9 @@ const PLATFORM_SELECTORS = {
|
||||||
```javascript
|
```javascript
|
||||||
// Test command generator for safe testing
|
// Test command generator for safe testing
|
||||||
const TEST_COMMANDS = {
|
const TEST_COMMANDS = {
|
||||||
validUpdate: `^%$bridge
|
validUpdate: '@bridge@\naction: update_file\nrepo: test-repo\npath: TEST.md\ncontent: |\n Test content\n Multiple lines\n@end@',
|
||||||
action: update_file
|
invalidCommand: '@bridge@\naction: update_file\nrepo: test-repo\n@end@',
|
||||||
repo: test-repo
|
getFile: '@bridge@\naction: get_file\nrepo: test-repo\npath: README.md\n@end@'
|
||||||
path: TEST.md
|
|
||||||
content: |
|
|
||||||
Test content
|
|
||||||
Multiple lines
|
|
||||||
---`,
|
|
||||||
|
|
||||||
invalidCommand: `^%$bridge
|
|
||||||
action: update_file
|
|
||||||
repo: test-repo
|
|
||||||
---`,
|
|
||||||
|
|
||||||
getFile: `^%$bridge
|
|
||||||
action: get_file
|
|
||||||
repo: test-repo
|
|
||||||
path: README.md
|
|
||||||
---`
|
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
@startuml Architecture Overview
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
skinparam shadowing false
|
||||||
|
skinparam ArrowColor #555
|
||||||
|
skinparam component {
|
||||||
|
BackgroundColor<<core>> #E8F5E9
|
||||||
|
BackgroundColor<<ui>> #E3F2FD
|
||||||
|
BackgroundColor<<ext>> #FFF3E0
|
||||||
|
}
|
||||||
|
|
||||||
|
package "Browser (Chat Sites)" <<ext>> {
|
||||||
|
[ChatGPT DOM]
|
||||||
|
[Claude DOM]
|
||||||
|
[Gemini DOM]
|
||||||
|
}
|
||||||
|
|
||||||
|
node "Userscript: AI Repo Commander" as Userscript {
|
||||||
|
component "Core Monitor" <<core>> as Monitor
|
||||||
|
component "Command Parser" <<core>> as Parser
|
||||||
|
component "Validation Engine" <<core>> as Validator
|
||||||
|
component "Execution Manager" <<core>> as Executor
|
||||||
|
component "Dedupe Store" <<core>> as Dedupe
|
||||||
|
component "Config Manager" <<core>> as Config
|
||||||
|
component "UI Panel (Tools/Settings)" <<ui>> as Panel
|
||||||
|
component "Inline Status UI" <<ui>> as InlineUI
|
||||||
|
}
|
||||||
|
|
||||||
|
cloud "Bridge API" <<ext>> as Bridge
|
||||||
|
|
||||||
|
' Relationships
|
||||||
|
[ChatGPT DOM] -down-> Monitor : observe assistant messages
|
||||||
|
[Claude DOM] -down-> Monitor
|
||||||
|
[Gemini DOM] -down-> Monitor
|
||||||
|
|
||||||
|
Monitor -> Parser : extract YAML blocks
|
||||||
|
Parser -> Validator : validate fields/actions
|
||||||
|
Validator -> Executor : approved commands
|
||||||
|
Executor -> Bridge : HTTP requests (key, action)
|
||||||
|
Executor --> InlineUI : progress + results
|
||||||
|
Monitor --> InlineUI : markers (processed, run again)
|
||||||
|
Panel <--> Config : view/edit config
|
||||||
|
Executor <--> Config : timeouts, retries
|
||||||
|
Monitor <--> Dedupe : per-convo records
|
||||||
|
|
||||||
|
@enduml
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
@startuml Command Execution Sequence
|
||||||
|
skinparam shadowing false
|
||||||
|
skinparam ArrowColor #555
|
||||||
|
|
||||||
|
actor User as U
|
||||||
|
participant "Assistant Message\n(DOM)" as DOM
|
||||||
|
participant "Core Monitor" as Monitor
|
||||||
|
participant "Command Parser" as Parser
|
||||||
|
participant "Validation Engine" as Validator
|
||||||
|
participant "Dedupe Store" as Dedupe
|
||||||
|
participant "Execution Manager" as Executor
|
||||||
|
participant "Inline Status UI" as UI
|
||||||
|
participant "Bridge API" as Bridge
|
||||||
|
|
||||||
|
U -> DOM : Produces message with YAML block
|
||||||
|
DOM -> Monitor : observe new/updated message
|
||||||
|
Monitor -> Monitor : debounce + streaming settle
|
||||||
|
Monitor -> Parser : extract YAML block
|
||||||
|
Parser --> Monitor : ParsedCommand
|
||||||
|
Monitor -> Validator : validate fields and action
|
||||||
|
Validator --> Monitor : ValidationResult
|
||||||
|
Monitor -> Dedupe : check de-duplication
|
||||||
|
Dedupe --> Monitor : isNew?
|
||||||
|
alt example: true or duplicate
|
||||||
|
Monitor -> UI : mark as processed (skipped)
|
||||||
|
return
|
||||||
|
else valid and new
|
||||||
|
Monitor -> UI : show "Ready" (runnable)
|
||||||
|
Monitor -> Executor : enqueue/execute command
|
||||||
|
Executor -> UI : state = executing
|
||||||
|
Executor -> Bridge : POST action with bridge key
|
||||||
|
Bridge --> Executor : response (success/failure)
|
||||||
|
Executor -> UI : show result + Run Again button
|
||||||
|
Executor -> Dedupe : record execution (ttl 30d)
|
||||||
|
end
|
||||||
|
|
||||||
|
@enduml
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
@startuml Command Processing State Machine
|
||||||
|
skinparam shadowing false
|
||||||
|
skinparam ArrowColor #555
|
||||||
|
skinparam state {
|
||||||
|
StartColor #A5D6A7
|
||||||
|
BackgroundColor #FAFAFA
|
||||||
|
}
|
||||||
|
|
||||||
|
[*] --> DETECTED : YAML block found
|
||||||
|
|
||||||
|
state DETECTED {
|
||||||
|
}
|
||||||
|
DETECTED --> PARSING : debounce/settle passed
|
||||||
|
PARSING --> VALIDATING : YAML parsed
|
||||||
|
PARSING --> ERROR : parse failure
|
||||||
|
|
||||||
|
VALIDATING --> DEDUPE_CHECK : required fields ok
|
||||||
|
VALIDATING --> ERROR : validation failed
|
||||||
|
|
||||||
|
state DEDUPE_CHECK
|
||||||
|
DEDUPE_CHECK --> SKIPPED : duplicate or example:true
|
||||||
|
DEDUPE_CHECK --> READY : new and runnable
|
||||||
|
|
||||||
|
state READY
|
||||||
|
READY --> EXECUTING : user intent or auto-exec policy
|
||||||
|
READY --> [*] : STOP triggered
|
||||||
|
|
||||||
|
state EXECUTING
|
||||||
|
EXECUTING --> COMPLETE : success
|
||||||
|
EXECUTING --> ERROR : API/network failure
|
||||||
|
|
||||||
|
state SKIPPED
|
||||||
|
SKIPPED --> [*]
|
||||||
|
|
||||||
|
state COMPLETE
|
||||||
|
COMPLETE --> [*]
|
||||||
|
|
||||||
|
state ERROR
|
||||||
|
ERROR --> [*]
|
||||||
|
|
||||||
|
@enduml
|
||||||
Loading…
Reference in New Issue