mit einem Klick
report-error
Report Error Command
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Menü
Report Error Command
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Basierend auf der SOC-Berufsklassifikation
Canonical turn protocol for agents writing to Neotoma. Bounded retrieval on the user message, store user message PART_OF conversation with REFERS_TO edges to retrieved entities, store assistant reply the same way. Use this skill in any agent loop that should persist conversation state to Neotoma.
Session-end audit. Files remaining work as task entities and lists them as bullets, verifies all data intended for Neotoma storage from this session is actually stored, and persists what's missing. Invoke at the natural close of a working session, before context is lost.
Mid-session status report. Summarizes what's been achieved so far this session and what work remains, in succinct qualitative prose and bullets with only light technical detail. Read-only — stores nothing, files nothing. Invoke any time to take stock without closing the session.
Close a Neotoma working session — store the assistant reply and a session-close summary.
Retrieve the bounded context for the current session — recent interactions and relevant entities.
Begin a Neotoma working session — open a conversation and record the opening interaction.
| name | report_error |
| description | Report Error Command |
Enable agents to report errors for automated resolution by Cursor Cloud Agent. This command detects, classifies, and documents errors in a structured format for systematic resolution.
Supports cross-repo reporting: Report errors to sibling repositories (repos sharing the same parent directory) by passing the target repo name.
/report_error [target-repo-name] [--no-wait] [--timeout SECONDS] [--poll-interval SECONDS]
Parameters:
target-repo-name (optional): Name of sibling repository to report error to
/Users/user/Projects/personal, target neotoma resolves to /Users/user/Projects/neotoma--no-wait (optional): Disable wait-for-resolution mode (default: wait mode is enabled)--timeout SECONDS (optional): Maximum time to wait for resolution (default: 300 seconds / 5 minutes)--poll-interval SECONDS (optional): How often to check error status (default: 5 seconds)Default Behavior:
Examples:
# Auto-detect target repo and wait for resolution (default behavior)
/report_error
# Explicitly specify target repo (auto-detection disabled)
/report_error neotoma
# Disable wait mode (report and continue immediately)
/report_error --no-wait
# Custom timeout (10 minutes, default is 5 minutes)
/report_error --timeout 600
# Custom poll interval (check every 2 seconds, default is 5 seconds)
/report_error --poll-interval 2
# Explicit target repo with custom timeout
/report_error neotoma --timeout 600
Use this command when you encounter:
Auto-Detection: The command automatically detects the target repository when errors originate from MCP servers or external modules. For example:
mcp_neotoma_* functions → automatically report to neotoma repomcp_asana_* functions → automatically report to asana repo (if exists)/Projects/neotoma/ → automatically report to neotoma repoGet Current Repository Path:
git rev-parse --show-toplevel
Store as current_repo_path
Auto-Detect Target Repository (if target-repo-name not provided):
Analyze error context to determine target repository:
MCP Error Detection:
MCP error or mcp_ prefix:
agent_context.command for MCP function names (e.g., mcp_neotoma_ingest_structured)mcp_neotoma → neotomamcp_asana → asana (if exists)mcp_gmail → gmail (if exists)mcp_google-calendar or mcp_google_calendar → google-calendar (if exists)mcp_<server-name> → lookup in mcp_server_mapping config or use <server-name>Module Path Detection:
/Users/user/Projects/neotoma/ → neotoma/Users/user/Projects/foundation/ → foundationError Source Detection:
agent_context.command for MCP function namesmcp_neotoma_ingest_structured → neotoma)Fallback:
current_repo_path (local reporting)Resolve Target Repository Path:
target-repo-name parameter provided:
dirname(current_repo_path)parent_dir/target-repo-name/Users/user/Projects/personal, target neotoma → /Users/user/Projects/neotomacurrent_repo_path (local reporting)Sanitize Repository Name (if provided or auto-detected):
.., /, \)Validate Target Repository:
.git directory (is a git repository)Extract the following from context:
For Auto-Detection:
mcp_neotoma)mcp_neotoma_ingest_structured)Classify error into one of these categories:
Assign severity based on impact:
Create a structured error report with:
Ensure Target Directory Structure:
target_repo/.cursor/error_reports/ if missingtarget_repo/.cursor/error_reports/pending/ if missingtarget_repo/.cursor/error_reports/resolved/ if missingWrite Error Report Files:
target_repo/.cursor/error_reports/pending/error_[timestamp]_[category].jsontarget_repo/.cursor/error_reports/pending/error_[timestamp]_[category].mdUpdate Pending Queue:
target_repo/.cursor/error_reports/pending.jsonPresent to user:
IMPORTANT: Wait mode is enabled by default unless --no-wait is specified.
After creating error report, monitor resolution status:
Check Wait Mode:
--no-wait flag provided: Skip wait mode, exit immediatelyMonitor Resolution:
pending/ and resolved/ directories on each poll
pending/ to resolved/ by Cursor Cloud Agent upon resolutionpending/, check resolved/ before assuming file is missingresolution_status field in JSON reportpending → in_progress → resolved | failedResolution Detection:
"resolved"
"failed"
pending or in_progress
Resume/Retry Logic:
{
"error_id": "uuid-v7",
"timestamp": "ISO-8601",
"category": "build|runtime|test|dependency|configuration",
"severity": "critical|high|medium|low",
"error_message": "sanitized error message",
"stack_trace": "truncated stack trace",
"affected_files": ["path/to/file1.ts", "path/to/file2.ts"],
"affected_modules": ["module_name"],
"agent_context": {
"agent_id": "cursor-agent",
"task": "description of task",
"command": "command_name if applicable"
},
"repositories": {
"source_repo": {
"path": "/absolute/path/to/source/repo",
"name": "repo-name",
"remote_url": "git@github.com:user/repo.git"
},
"target_repo": {
"path": "/absolute/path/to/target/repo",
"name": "target-repo-name",
"remote_url": "git@github.com:user/target.git"
}
},
"environment": {
"node_version": "v20.x.x",
"os": "darwin|linux|windows",
"neotoma_env": "development|production"
},
"resolution_status": "pending|in_progress|resolved|failed",
"resolution_notes": ""
}
Repository Name Validation:
.., /, \^[a-zA-Z0-9._-]+$neotoma, personal-project, my_repo, repo.2../other, repo/subdir, ../../secretPath Construction:
// Get current repo root
const currentRepoPath = execSync('git rev-parse --show-toplevel').toString().trim();
// If target repo name provided
if (targetRepoName) {
// Sanitize repo name first
if (!/^[a-zA-Z0-9._-]+$/.test(targetRepoName)) {
throw new Error(`Invalid repo name: ${targetRepoName}. Only alphanumeric, hyphens, underscores, and dots allowed.`);
}
// Get parent directory
const parentDir = path.dirname(currentRepoPath);
// Construct target repo path
const targetPath = path.join(parentDir, targetRepoName);
return targetPath;
} else {
// Use current repo
return currentRepoPath;
}
Before writing error report, validate target repository:
Path Exists:
if (!fs.existsSync(targetPath)) {
throw new Error(`Target repository not found: ${targetPath}`);
}
Is Directory:
if (!fs.statSync(targetPath).isDirectory()) {
throw new Error(`Target path is not a directory: ${targetPath}`);
}
Is Git Repository:
const gitPath = path.join(targetPath, '.git');
if (!fs.existsSync(gitPath)) {
throw new Error(`Target path is not a git repository: ${targetPath}`);
}
Is Writable:
try {
fs.accessSync(targetPath, fs.constants.W_OK);
} catch {
throw new Error(`No write permission for target repository: ${targetPath}`);
}
If any validation fails, abort with clear error message and do not write error report.
Apply these rules when generating reports:
Validation Failures:
Invalid Repo Name:
Error: Invalid repo name: ../other. Only alphanumeric, hyphens, underscores, and dots allowed.
Target Repo Not Found:
Error: Target repository not found: /Users/user/Projects/non-existent-repo
Available sibling repositories:
- neotoma
- personal-project
- another-repo
Not a Git Repository:
Error: Target path is not a git repository: /Users/user/Projects/some-dir
Target must be a git repository (contains .git directory).
No Write Permission:
Error: No write permission for target repository: /Users/user/Projects/neotoma
Check file permissions and try again.
Success Feedback:
Error report created successfully.
Error ID: 01JQZ8X9K2M3N4P5Q6R7S8T9U0
Category: build
Severity: high
Target: /Users/user/Projects/neotoma
Report saved to:
- /Users/user/Projects/neotoma/.cursor/error_reports/pending/error_20250131_143022_build.json
- /Users/user/Projects/neotoma/.cursor/error_reports/pending/error_20250131_143022_build.md
Added to pending queue for resolution.
Agent: I encountered a TypeScript compilation error while building the project.
Error: Cannot find module '../db'
at Object.<anonymous> (/Users/user/Projects/neotoma/src/services/raw_storage.ts:1:1)
...
Command: /report_error
Agent will:
/Users/user/Projects/neotoma/ from stack trace → target: neotomasrc/services/raw_storage.ts, etc..cursor/error_reports/pending/error_20250131_143022_build.jsonAgent: Working in personal-project repo, encountered MCP error.
Error: MCP error -32603: Failed to upload to storage: Bucket not found
Command: mcp_neotoma_ingest_structured
Command: /report_error
Agent will:
mcp_neotoma from command context → target: neotoma/Users/user/Projects/neotoma (sibling of personal-project).cursor/error_reports/pending/Agent: Working in personal-project repo, want to explicitly report to neotoma.
Error: MCP error -32603: Failed to upload to storage: Bucket not found
Command: /report_error neotoma
Agent will:
/Users/user/Projects/neotoma (sibling of personal-project).cursor/error_reports/pending/Agent: Encountered error with no clear repository origin.
Error: Generic runtime error
Command: /report_error
Agent will:
.cursor/error_reports/pending/Command: /report_error ../secret-repo
Agent will:
..)Directory Creation:
const errorReportsDir = path.join(targetRepoPath, '.cursor', 'error_reports');
const pendingDir = path.join(errorReportsDir, 'pending');
const resolvedDir = path.join(errorReportsDir, 'resolved');
// Create directories if they don't exist
fs.mkdirSync(errorReportsDir, { recursive: true });
fs.mkdirSync(pendingDir, { recursive: true });
fs.mkdirSync(resolvedDir, { recursive: true });
File Naming:
const timestamp = new Date().toISOString().replace(/[:.]/g, '').slice(0, 15);
const jsonFilename = `error_${timestamp}_${category}.json`;
const mdFilename = `error_${timestamp}_${category}.md`;
const jsonPath = path.join(pendingDir, jsonFilename);
const mdPath = path.join(pendingDir, mdFilename);
Write Error Reports:
// Write JSON report
fs.writeFileSync(jsonPath, JSON.stringify(errorReport, null, 2), 'utf8');
// Write Markdown summary
fs.writeFileSync(mdPath, markdownSummary, 'utf8');
// Update pending queue
const pendingPath = path.join(errorReportsDir, 'pending.json');
let pending = [];
if (fs.existsSync(pendingPath)) {
pending = JSON.parse(fs.readFileSync(pendingPath, 'utf8'));
}
pending.push({
error_id: errorReport.error_id,
timestamp: errorReport.timestamp,
category: errorReport.category,
severity: errorReport.severity,
file_path: jsonPath
});
fs.writeFileSync(pendingPath, JSON.stringify(pending, null, 2), 'utf8');
Error reports are stored in the target repository's .cursor/error_reports/ directory:
target_repo/.cursor/
error_reports/
pending.json # Queue of errors awaiting resolution
pending/ # Pending error reports
error_20250131_143022_build.json # Individual error reports (JSON)
error_20250131_143022_build.md # Human-readable summaries (Markdown)
resolved/ # Archived resolved errors
error_20250131_143022_build.json
error_20250131_143022_build.md
The Cursor Cloud Agent will:
.cursor/error_reports/pending.jsonresolution_status when working on error.cursor/error_reports/pending/ to .cursor/error_reports/resolved/Important for Wait Mode: When monitoring for resolution, the agent must check both pending/ and resolved/ directories, as the Cursor Cloud Agent moves files upon resolution. If a file is not found in pending/, check resolved/ before assuming the file is missing.
fix_feature_bugfix-feature-bug skillanalyzeError reporting behavior can be configured in foundation-config.yaml:
development:
error_reporting:
enabled: true
auto_detect: true # Enable automatic target repository detection
auto_classify_bugs: true
severity_threshold: "medium"
max_stack_trace_length: 5000
retention_days: 30
output_directory: ".cursor/error_reports"
wait_by_default: true # Enable wait mode by default (can disable with --no-wait)
mcp_server_mapping: # Map MCP server names to repository names
neotoma: "neotoma"
asana: "asana"
gmail: "gmail"
google_calendar: "google-calendar"
google-calendar: "google-calendar"
wait_mode:
default_timeout: 300 # Default timeout in seconds (5 minutes)
default_poll_interval: 5 # Default poll interval in seconds
max_timeout: 3600 # Maximum allowed timeout (1 hour)
min_poll_interval: 1 # Minimum allowed poll interval
Auto-detect errors matching these patterns:
MCP error -32603, UNKNOWN_CAPABILITY, etc.tsc errorsCannot find module, Module not foundError:, Exception:Test failed, AssertionErrorWhen reporting an error:
MCP error, mcp_ prefix)error_20250131_143022_build.json)Example: Local Reporting
{
"error_id": "01JQZ8X9K2M3N4P5Q6R7S8T9U0",
"timestamp": "2025-01-31T14:30:22Z",
"category": "build",
"severity": "high",
"error_message": "Cannot find module '../db'",
"stack_trace": "Error: Cannot find module '../db'\n at Object.<anonymous> (src/services/raw_storage.ts:1:1)\n at Module._compile (node:internal/modules/cjs/loader:1376:14)\n ...",
"affected_files": [
"src/services/raw_storage.ts",
"src/services/interpretation.ts",
"src/services/entity_queries.ts"
],
"affected_modules": ["db"],
"agent_context": {
"agent_id": "cursor-agent",
"task": "Transfer contacts from Parquet to Neotoma",
"command": null
},
"repositories": {
"source_repo": {
"path": "/Users/user/Projects/neotoma",
"name": "neotoma",
"remote_url": "git@github.com:user/neotoma.git"
},
"target_repo": {
"path": "/Users/user/Projects/neotoma",
"name": "neotoma",
"remote_url": "git@github.com:user/neotoma.git"
}
},
"environment": {
"node_version": "v20.11.0",
"os": "darwin",
"neotoma_env": "development"
},
"resolution_status": "pending",
"resolution_notes": ""
}
Example: Cross-Repo Reporting
{
"error_id": "01JQZ8X9K2M3N4P5Q6R7S8T9U1",
"timestamp": "2025-01-31T14:35:10Z",
"category": "runtime",
"severity": "high",
"error_message": "MCP error -32603: Failed to upload to storage: Bucket not found",
"stack_trace": "...",
"affected_files": ["src/actions.ts"],
"affected_modules": ["mcp_neotoma"],
"agent_context": {
"agent_id": "cursor-agent",
"task": "Ingest structured contact data",
"command": "ingest_structured"
},
"repositories": {
"source_repo": {
"path": "/Users/user/Projects/personal-project",
"name": "personal-project",
"remote_url": "git@github.com:user/personal-project.git"
},
"target_repo": {
"path": "/Users/user/Projects/neotoma",
"name": "neotoma",
"remote_url": "git@github.com:user/neotoma.git"
}
},
"environment": {
"node_version": "v20.11.0",
"os": "darwin",
"neotoma_env": "development"
},
"resolution_status": "pending",
"resolution_notes": ""
}
error_20250131_143022_build.md)Example: Cross-Repo Reporting
# Error Report: Runtime Error
**Error ID:** `01JQZ8X9K2M3N4P5Q6R7S8T9U1`
**Timestamp:** 2025-01-31T14:35:10Z
**Category:** runtime
**Severity:** high
**Status:** pending
## Error Message
MCP error -32603: Failed to upload to storage: Bucket not found
## Source Repository
- **Name:** personal-project
- **Path:** /Users/user/Projects/personal-project
- **Remote:** git@github.com:user/personal-project.git
## Target Repository
- **Name:** neotoma
- **Path:** /Users/user/Projects/neotoma
- **Remote:** git@github.com:user/neotoma.git
## Affected Files
- `src/actions.ts`
## Affected Modules
- mcp_neotoma
## Stack Trace
...
## Context
Agent was ingesting structured contact data when this runtime error occurred.
## Environment
- Node: v20.11.0
- OS: darwin
- Environment: development
## Resolution
Awaiting resolution by Cursor Cloud Agent.
/report_error
Error: "MCP error -32603: Failed to create interpretation run" Expected:
neotoma (from mcp_neotoma in error context)../neotoma/.cursor/error_reports/pending//report_error neotoma
Expected:
../neotoma/.cursor/error_reports/pending//report_error non-existent-repo
Expected: Error message: "Target repository not found: /Users/user/Projects/non-existent-repo"
/report_error ../other-dir
Expected: Error message: "Invalid repo name: ../other-dir. Only alphanumeric, hyphens, underscores, and dots allowed."
/report_error some-directory
Expected: Error message: "Target path is not a git repository: /Users/user/Projects/some-directory"
/report_error neotoma
(Where neotoma repo exists but .cursor/error_reports/pending/ doesn't exist yet)
Expected: Directories created automatically, error report written successfully
Wait mode is enabled by default. The agent will automatically monitor the error report status and wait for resolution before continuing, unless --no-wait is specified.
Report Error:
/report_error (wait mode enabled by default)resolution_status: "pending"Monitor Resolution:
pending/ and resolved/ directories, as resolved errors are moved from pending/ to resolved/ by the Cursor Cloud Agentresolution_status field in JSON reportpending → in_progress → resolved | failedResolution Detection:
"resolved"
resolution_notes for details about the fix"failed"
resolution_notes for failure reasonTimeout Handling:
pending or in_progress:
Resume/Retry Logic:
Wait mode settings are read from foundation-config.yaml:
error_reporting.wait_mode.default_timeout - Default timeout (overridden by --timeout)error_reporting.wait_mode.default_poll_interval - Default poll interval (overridden by --poll-interval)error_reporting.wait_mode.max_timeout - Maximum allowed timeouterror_reporting.wait_mode.min_poll_interval - Minimum allowed poll intervalfunction autoDetectTargetRepo(error, currentRepoPath) {
const parentDir = path.dirname(currentRepoPath);
// 1. Check for MCP errors
if (error.message && error.message.includes('MCP error')) {
// Extract MCP server name from error context
const mcpMatch = error.message.match(/mcp_(\w+)/i) ||
error.stack?.match(/mcp_(\w+)/i);
if (mcpMatch) {
const serverName = mcpMatch[1];
// Map common MCP servers to repos
const repoMap = {
'neotoma': 'neotoma',
'asana': 'asana',
'gmail': 'gmail',
'google-calendar': 'google-calendar',
'google_calendar': 'google-calendar'
};
const targetRepo = repoMap[serverName] || serverName;
const targetPath = path.join(parentDir, targetRepo);
if (fs.existsSync(targetPath) && fs.existsSync(path.join(targetPath, '.git'))) {
return targetPath;
}
}
}
// 2. Check agent context for MCP commands
if (error.agent_context?.command) {
const cmd = error.agent_context.command;
if (cmd.startsWith('mcp_')) {
const serverName = cmd.split('_')[1];
const targetPath = path.join(parentDir, serverName);
if (fs.existsSync(targetPath) && fs.existsSync(path.join(targetPath, '.git'))) {
return targetPath;
}
}
}
// 3. Check affected files/modules for repo paths
if (error.affected_files) {
for (const file of error.affected_files) {
const repoMatch = file.match(/\/Projects\/([^\/]+)\//);
if (repoMatch) {
const repoName = repoMatch[1];
const targetPath = path.join(parentDir, repoName);
if (fs.existsSync(targetPath) && fs.existsSync(path.join(targetPath, '.git'))) {
return targetPath;
}
}
}
}
// 4. Fallback to current repo
return currentRepoPath;
}
// Agent workflow (wait mode enabled by default)
try {
await performOperation();
} catch (error) {
// Report error with auto-detection and wait for resolution (default)
const result = await reportError('--timeout', '600');
if (result.resolved) {
// Retry operation after resolution
console.log(`Retrying operation after error resolution: ${result.errorId}`);
await performOperation(); // Retry
} else if (result.failed) {
// Handle failure case
console.log(`Error resolution failed: ${result.resolutionNotes}`);
throw new Error(`Operation failed and could not be resolved: ${result.errorId}`);
} else if (result.timeout) {
// Timeout - proceed or skip
console.log(`Timeout waiting for resolution, skipping operation`);
// Agent decides whether to skip or continue
}
}
The agent polls the error report JSON file for status changes. Important: When errors are resolved, the Cursor Cloud Agent moves the report files from pending/ to resolved/. The wait logic must check both directories.
async function waitForErrorResolution(errorId, errorReportPath, options = {}) {
const {
timeout = 300, // 5 minutes default
pollInterval = 5, // 5 seconds default
} = options;
const startTime = Date.now();
const timeoutMs = timeout * 1000;
// Normalize error report path - extract base filename
let baseFilename = path.basename(errorReportPath);
if (!baseFilename.endsWith('.json')) {
baseFilename = `${baseFilename}.json`;
}
// Get directory structure
const errorReportsDir = path.dirname(path.dirname(errorReportPath)); // Go up from pending/ or resolved/
const pendingDir = path.join(errorReportsDir, 'pending');
const resolvedDir = path.join(errorReportsDir, 'resolved');
// Start with pending path
let currentPath = path.join(pendingDir, baseFilename);
while (true) {
// Check timeout
if (Date.now() - startTime > timeoutMs) {
throw new Error(`Timeout waiting for error resolution: ${errorId}`);
}
// Check if file exists in pending/ or resolved/
let reportPath = null;
if (fs.existsSync(path.join(pendingDir, baseFilename))) {
reportPath = path.join(pendingDir, baseFilename);
} else if (fs.existsSync(path.join(resolvedDir, baseFilename))) {
reportPath = path.join(resolvedDir, baseFilename);
} else {
// File not found in either location - might have been deleted or moved
throw new Error(`Error report file not found: ${baseFilename}`);
}
// Read error report
const report = JSON.parse(fs.readFileSync(reportPath, 'utf8'));
const status = report.resolution_status;
// Check if resolved or failed
if (status === 'resolved') {
return {
status: 'resolved',
errorId,
resolutionNotes: report.resolution_notes || '',
report,
reportPath // Return actual path (may be in resolved/)
};
}
if (status === 'failed') {
return {
status: 'failed',
errorId,
resolutionNotes: report.resolution_notes || '',
report,
reportPath // Return actual path (may be in resolved/)
};
}
// Still pending or in_progress, wait and check again
console.log(`[WAIT] Error ${errorId} status: ${status}, waiting...`);
await new Promise(resolve => setTimeout(resolve, pollInterval * 1000));
}
}
For shell-based implementations, check both directories:
ERROR_REPORT_PATH="/path/to/target/.cursor/error_reports/pending/error_TIMESTAMP_runtime.json"
ERROR_REPORTS_DIR="/path/to/target/.cursor/error_reports"
PENDING_DIR="$ERROR_REPORTS_DIR/pending"
RESOLVED_DIR="$ERROR_REPORTS_DIR/resolved"
BASE_FILENAME=$(basename "$ERROR_REPORT_PATH")
TIMEOUT=300
POLL_INTERVAL=5
START_TIME=$(date +%s)
while true; do
CURRENT_TIME=$(date +%s)
ELAPSED=$((CURRENT_TIME - START_TIME))
# Check timeout
if [ $ELAPSED -ge $TIMEOUT ]; then
echo "⏱️ Timeout reached (${TIMEOUT}s) while waiting for resolution"
# Check final status in either directory
if [ -f "$RESOLVED_DIR/$BASE_FILENAME" ]; then
STATUS=$(cat "$RESOLVED_DIR/$BASE_FILENAME" | jq -r '.resolution_status' || echo "unknown")
elif [ -f "$PENDING_DIR/$BASE_FILENAME" ]; then
STATUS=$(cat "$PENDING_DIR/$BASE_FILENAME" | jq -r '.resolution_status' || echo "unknown")
else
STATUS="unknown"
fi
echo "Final status: $STATUS"
exit 0
fi
# Check both pending/ and resolved/ directories
REPORT_PATH=""
if [ -f "$PENDING_DIR/$BASE_FILENAME" ]; then
REPORT_PATH="$PENDING_DIR/$BASE_FILENAME"
elif [ -f "$RESOLVED_DIR/$BASE_FILENAME" ]; then
REPORT_PATH="$RESOLVED_DIR/$BASE_FILENAME"
else
echo "⚠️ Error report file not found in pending/ or resolved/: $BASE_FILENAME"
exit 1
fi
# Read status
STATUS=$(cat "$REPORT_PATH" | jq -r '.resolution_status' 2>/dev/null || echo "pending")
echo "[WAIT] Error status: $STATUS (elapsed: ${ELAPSED}s)"
# Check if resolved or failed
if [ "$STATUS" = "resolved" ]; then
echo "✅ Error resolved!"
cat "$REPORT_PATH" | jq -r '.resolution_notes // "No resolution notes provided."'
exit 0
fi
if [ "$STATUS" = "failed" ]; then
echo "❌ Error resolution failed"
cat "$REPORT_PATH" | jq -r '.resolution_notes // "No failure reason provided."'
exit 1
fi
# Still pending or in_progress, wait and check again
sleep $POLL_INTERVAL
done
The following scripts are provided in foundation/scripts/ to simplify error reporting implementation. These can be used by agents when implementing the /report_error command.
Script Location: foundation/scripts/report_error_*.sh
Usage: Scripts can be called directly from the foundation submodule, or copied/referenced as needed.
File: foundation/scripts/report_error_validate_target.sh
#!/bin/bash
# validate_target_repo.sh
# Usage: validate_target_repo.sh <target-repo-path>
TARGET_REPO="$1"
if [ -z "$TARGET_REPO" ]; then
echo "❌ Error: Target repository path required"
exit 1
fi
# Check if path exists
if [ ! -d "$TARGET_REPO" ]; then
echo "❌ Error: Target repository not found: $TARGET_REPO"
exit 1
fi
# Check if it's a git repository
if [ ! -d "$TARGET_REPO/.git" ]; then
echo "❌ Error: Target path is not a git repository: $TARGET_REPO"
exit 1
fi
# Check write permissions
if [ ! -w "$TARGET_REPO" ]; then
echo "❌ Error: No write permission for target repository: $TARGET_REPO"
exit 1
fi
echo "✅ Target repository validated: $TARGET_REPO"
exit 0
File: foundation/scripts/report_error_generate_id.sh
#!/bin/bash
# generate_error_id.sh
# Outputs: ERROR_ID|TIMESTAMP
TIMESTAMP=$(date -u +"%Y%m%dT%H%M%S")
ERROR_ID="01JQ$(echo $TIMESTAMP | tr -d 'T' | cut -c1-20)"
echo "${ERROR_ID}|${TIMESTAMP}"
File: foundation/scripts/report_error_create_dirs.sh
#!/bin/bash
# create_error_report_dirs.sh
# Usage: create_error_report_dirs.sh <target-repo-path>
TARGET_REPO="$1"
ERROR_REPORTS_DIR="$TARGET_REPO/.cursor/error_reports"
PENDING_DIR="$ERROR_REPORTS_DIR/pending"
RESOLVED_DIR="$ERROR_REPORTS_DIR/resolved"
mkdir -p "$PENDING_DIR" "$RESOLVED_DIR"
echo "✅ Created error report directories in $TARGET_REPO"
#!/bin/bash
# create_error_report.sh
# Usage: create_error_report.sh <target-repo-path> <error-id> <timestamp> <category> <severity> <error-message> <json-data>
TARGET_REPO="$1"
ERROR_ID="$2"
TIMESTAMP="$3"
CATEGORY="$4"
SEVERITY="$5"
ERROR_MSG="$6"
JSON_DATA="$7"
ERROR_REPORTS_DIR="$TARGET_REPO/.cursor/error_reports"
PENDING_DIR="$ERROR_REPORTS_DIR/pending"
# Generate filenames
JSON_FILENAME="error_${TIMESTAMP}_${CATEGORY}.json"
MD_FILENAME="error_${TIMESTAMP}_${CATEGORY}.md"
JSON_PATH="$PENDING_DIR/$JSON_FILENAME"
MD_PATH="$PENDING_DIR/$MD_FILENAME"
# Write JSON report
echo "$JSON_DATA" > "$JSON_PATH"
# Generate Markdown summary
cat > "$MD_PATH" << EOF
# Error Report: $(echo $CATEGORY | tr '[:lower:]' '[:upper:]') Error
**Error ID:** \`$ERROR_ID\`
**Timestamp:** $(echo $TIMESTAMP | sed 's/\(....\)\(..\)\(..\)T\(..\)\(..\)\(..\)/\1-\2-\3T\4:\5:\6Z/')
**Category:** $CATEGORY
**Severity:** $SEVERITY
**Status:** pending
## Error Message
$ERROR_MSG
## Resolution
Awaiting resolution by Cursor Cloud Agent.
EOF
echo "$JSON_PATH|$MD_PATH"
#!/bin/bash
# update_pending_queue.sh
# Usage: update_pending_queue.sh <target-repo-path> <error-id> <timestamp> <category> <severity> <json-path>
TARGET_REPO="$1"
ERROR_ID="$2"
TIMESTAMP="$3"
CATEGORY="$4"
SEVERITY="$5"
JSON_PATH="$6"
PENDING_FILE="$TARGET_REPO/.cursor/error_reports/pending.json"
NEW_ENTRY="{\"error_id\": \"$ERROR_ID\", \"timestamp\": \"$(echo $TIMESTAMP | sed 's/\(....\)\(..\)\(..\)T\(..\)\(..\)\(..\)/\1-\2-\3T\4:\5:\6Z/')\", \"category\": \"$CATEGORY\", \"severity\": \"$SEVERITY\", \"file_path\": \"$JSON_PATH\"}"
if [ -f "$PENDING_FILE" ]; then
cat "$PENDING_FILE" | jq ". + [$NEW_ENTRY]" > "$PENDING_FILE.tmp" && mv "$PENDING_FILE.tmp" "$PENDING_FILE"
else
echo "[$NEW_ENTRY]" > "$PENDING_FILE"
fi
echo "✅ Pending queue updated"
File: foundation/scripts/report_error_wait_resolution.sh
#!/bin/bash
# wait_for_resolution.sh
# Usage: wait_for_resolution.sh <target-repo-path> <base-filename> [timeout] [poll-interval]
TARGET_REPO="$1"
BASE_FILENAME="$2"
TIMEOUT="${3:-300}"
POLL_INTERVAL="${4:-5}"
ERROR_REPORTS_DIR="$TARGET_REPO/.cursor/error_reports"
PENDING_DIR="$ERROR_REPORTS_DIR/pending"
RESOLVED_DIR="$ERROR_REPORTS_DIR/resolved"
START_TIME=$(date +%s)
while true; do
CURRENT_TIME=$(date +%s)
ELAPSED=$((CURRENT_TIME - START_TIME))
# Check timeout
if [ $ELAPSED -ge $TIMEOUT ]; then
echo "⏱️ Timeout reached (${TIMEOUT}s) while waiting for resolution"
# Check final status in either directory
if [ -f "$RESOLVED_DIR/$BASE_FILENAME" ]; then
STATUS=$(cat "$RESOLVED_DIR/$BASE_FILENAME" | jq -r '.resolution_status' || echo "unknown")
elif [ -f "$PENDING_DIR/$BASE_FILENAME" ]; then
STATUS=$(cat "$PENDING_DIR/$BASE_FILENAME" | jq -r '.resolution_status' || echo "unknown")
else
STATUS="unknown"
fi
echo "Final status: $STATUS"
exit 0
fi
# Check both pending/ and resolved/ directories
REPORT_PATH=""
if [ -f "$PENDING_DIR/$BASE_FILENAME" ]; then
REPORT_PATH="$PENDING_DIR/$BASE_FILENAME"
elif [ -f "$RESOLVED_DIR/$BASE_FILENAME" ]; then
REPORT_PATH="$RESOLVED_DIR/$BASE_FILENAME"
else
echo "⚠️ Error report file not found in pending/ or resolved/: $BASE_FILENAME"
exit 1
fi
# Read status
STATUS=$(cat "$REPORT_PATH" | jq -r '.resolution_status' 2>/dev/null || echo "pending")
echo "[WAIT] Error status: $STATUS (elapsed: ${ELAPSED}s)"
# Check if resolved or failed
if [ "$STATUS" = "resolved" ]; then
echo "✅ Error resolved!"
cat "$REPORT_PATH" | jq -r '.resolution_notes // "No resolution notes provided."'
exit 0
fi
if [ "$STATUS" = "failed" ]; then
echo "❌ Error resolution failed"
cat "$REPORT_PATH" | jq -r '.resolution_notes // "No failure reason provided."'
exit 1
fi
# Still pending or in_progress, wait and check again
sleep $POLL_INTERVAL
done
#!/bin/bash
# report_error_workflow.sh
# Complete workflow for reporting an error
# Usage: report_error_workflow.sh <target-repo-name> <error-message> <category> <severity> [--no-wait] [--timeout SECONDS]
set -e
# Parse arguments
TARGET_REPO_NAME="$1"
ERROR_MSG="$2"
CATEGORY="$3"
SEVERITY="$4"
NO_WAIT=false
TIMEOUT=300
shift 4
while [[ $# -gt 0 ]]; do
case $1 in
--no-wait)
NO_WAIT=true
shift
;;
--timeout)
TIMEOUT="$2"
shift 2
;;
*)
shift
;;
esac
done
# Get current repo path
CURRENT_REPO=$(git rev-parse --show-toplevel)
PARENT_DIR=$(dirname "$CURRENT_REPO")
# Resolve target repo
if [ -n "$TARGET_REPO_NAME" ]; then
TARGET_REPO="$PARENT_DIR/$TARGET_REPO_NAME"
else
# Auto-detect (simplified - would need full MCP detection logic)
TARGET_REPO="$CURRENT_REPO"
fi
# Validate target repo
if [ ! -d "$TARGET_REPO" ] || [ ! -d "$TARGET_REPO/.git" ]; then
echo "❌ Error: Invalid target repository: $TARGET_REPO"
exit 1
fi
# Generate error ID and timestamp
ID_TIMESTAMP=$(TIMESTAMP=$(date -u +"%Y%m%dT%H%M%S") && ERROR_ID="01JQ$(echo $TIMESTAMP | tr -d 'T' | cut -c1-20)" && echo "${ERROR_ID}|${TIMESTAMP}")
ERROR_ID=$(echo "$ID_TIMESTAMP" | cut -d'|' -f1)
TIMESTAMP=$(echo "$ID_TIMESTAMP" | cut -d'|' -f2)
# Create directories
mkdir -p "$TARGET_REPO/.cursor/error_reports/pending" "$TARGET_REPO/.cursor/error_reports/resolved"
# Create error report (simplified - would need full JSON structure)
JSON_FILENAME="error_${TIMESTAMP}_${CATEGORY}.json"
JSON_PATH="$TARGET_REPO/.cursor/error_reports/pending/$JSON_FILENAME"
# Generate JSON report (simplified structure)
cat > "$JSON_PATH" << EOF
{
"error_id": "$ERROR_ID",
"timestamp": "$(echo $TIMESTAMP | sed 's/\(....\)\(..\)\(..\)T\(..\)\(..\)\(..\)/\1-\2-\3T\4:\5:\6Z/')",
"category": "$CATEGORY",
"severity": "$SEVERITY",
"error_message": "$(echo "$ERROR_MSG" | jq -Rs .)",
"resolution_status": "pending",
"resolution_notes": ""
}
EOF
# Update pending queue
PENDING_FILE="$TARGET_REPO/.cursor/error_reports/pending.json"
NEW_ENTRY="{\"error_id\": \"$ERROR_ID\", \"timestamp\": \"$(echo $TIMESTAMP | sed 's/\(....\)\(..\)\(..\)T\(..\)\(..\)\(..\)/\1-\2-\3T\4:\5:\6Z/')\", \"category\": \"$CATEGORY\", \"severity\": \"$SEVERITY\", \"file_path\": \"$JSON_PATH\"}"
if [ -f "$PENDING_FILE" ]; then
cat "$PENDING_FILE" | jq ". + [$NEW_ENTRY]" > "$PENDING_FILE.tmp" && mv "$PENDING_FILE.tmp" "$PENDING_FILE"
else
echo "[$NEW_ENTRY]" > "$PENDING_FILE"
fi
echo "Error report created successfully."
echo "Error ID: $ERROR_ID"
echo "Category: $CATEGORY"
echo "Severity: $SEVERITY"
echo "Target: $TARGET_REPO"
echo "Report saved to: $JSON_PATH"
# Wait for resolution if enabled
if [ "$NO_WAIT" = false ]; then
echo ""
echo "⏳ Waiting for resolution (timeout: ${TIMEOUT}s)..."
BASE_FILENAME=$(basename "$JSON_PATH")
"$(dirname "$0")/wait_for_resolution.sh" "$TARGET_REPO" "$BASE_FILENAME" "$TIMEOUT"
fi
Agents can use these scripts as building blocks. Scripts are located in foundation/scripts/:
# Example: Report error using helper scripts
FOUNDATION_DIR="foundation" # or path to foundation submodule
TARGET_REPO_NAME="neotoma"
CURRENT_REPO=$(git rev-parse --show-toplevel)
PARENT_DIR=$(dirname "$CURRENT_REPO")
TARGET_REPO="$PARENT_DIR/$TARGET_REPO_NAME"
# Validate target repository
"$FOUNDATION_DIR/scripts/report_error_validate_target.sh" "$TARGET_REPO"
# Generate error ID and timestamp
ID_TIMESTAMP=$("$FOUNDATION_DIR/scripts/report_error_generate_id.sh")
ERROR_ID=$(echo "$ID_TIMESTAMP" | cut -d'|' -f1)
TIMESTAMP=$(echo "$ID_TIMESTAMP" | cut -d'|' -f2)
# Create directories
"$FOUNDATION_DIR/scripts/report_error_create_dirs.sh" "$TARGET_REPO"
# ... create error report files (JSON and Markdown) ...
# ... update pending queue ...
# Wait for resolution (if wait mode enabled)
BASE_FILENAME="error_${TIMESTAMP}_runtime.json"
"$FOUNDATION_DIR/scripts/report_error_wait_resolution.sh" "$TARGET_REPO" "$BASE_FILENAME" 300 5
Note: If foundation is a submodule, use the relative path from the repository root. If scripts are symlinked or copied, adjust paths accordingly.
fix-feature-bug (.cursor/skills/fix-feature-bug/SKILL.md) - Bug fix workflowanalyze (.cursor/skills/analyze/SKILL.md) - Analysis workflowdebug (.cursor/skills/debug/SKILL.md) - Debug workflowfoundation-config.yaml - Configuration file (in repository root)