feat(discovery): enhance discovery index reading and issue exporting

- Improved the reading of the discovery index by adding a fallback mechanism to scan directories for discovery folders if the index.json is invalid or missing.
- Added sorting of discoveries by creation time in descending order.
- Enhanced the `appendToIssuesJsonl` function to include deduplication logic for issues based on ID and source finding ID.
- Updated the discovery route handler to reflect the number of issues added and skipped during export.
- Introduced UI elements for selecting and deselecting findings in the dashboard.
- Added CSS styles for exported findings and action buttons.
- Implemented search functionality for filtering findings based on title, file, and description.
- Added internationalization support for new UI elements.
- Created scripts for automated API extraction from various project types, including FastAPI and TypeScript.
- Documented the API extraction process and library bundling instructions.
This commit is contained in:
catlog22
2025-12-28 19:27:34 +08:00
parent 3ef1e54412
commit 169f218f7a
18 changed files with 1602 additions and 612 deletions

View File

@@ -1,10 +1,10 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "discovery-state-schema",
"title": "Discovery State Schema",
"description": "Schema for issue discovery session state machine",
"title": "Discovery State Schema (Merged)",
"description": "Unified schema for issue discovery session (state + progress merged)",
"type": "object",
"required": ["discovery_id", "target_pattern", "metadata", "phase"],
"required": ["discovery_id", "target_pattern", "phase", "created_at"],
"properties": {
"discovery_id": {
"type": "string",
@@ -15,94 +15,111 @@
"target_pattern": {
"type": "string",
"description": "File/directory pattern being analyzed",
"examples": ["src/auth/**", "src/payment/**,src/api/**"]
},
"metadata": {
"type": "object",
"required": ["created_at", "resolved_files", "perspectives"],
"properties": {
"created_at": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 timestamp of discovery creation"
},
"resolved_files": {
"type": "array",
"items": { "type": "string" },
"description": "List of resolved file paths from pattern"
},
"perspectives": {
"type": "array",
"items": {
"type": "string",
"enum": ["bug", "ux", "test", "quality", "security", "performance", "maintainability", "best-practices"]
},
"description": "Selected discovery perspectives"
},
"external_research_enabled": {
"type": "boolean",
"default": false,
"description": "Whether Exa research is enabled"
}
}
"examples": ["src/auth/**", "codex-lens/**/*.py"]
},
"phase": {
"type": "string",
"enum": ["initialization", "parallel", "external", "aggregation", "complete"],
"enum": ["initialization", "parallel", "aggregation", "complete"],
"description": "Current execution phase"
},
"perspectives_completed": {
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"target": {
"type": "object",
"description": "Target module information",
"properties": {
"files_count": {
"type": "object",
"properties": {
"source": { "type": "integer" },
"tests": { "type": "integer" },
"total": { "type": "integer" }
}
},
"project": {
"type": "object",
"properties": {
"name": { "type": "string" },
"version": { "type": "string" }
}
}
}
},
"perspectives": {
"type": "array",
"items": { "type": "string" },
"description": "List of completed perspective analyses"
"description": "Perspective analysis status (merged from progress)",
"items": {
"type": "object",
"required": ["name", "status"],
"properties": {
"name": {
"type": "string",
"enum": ["bug", "ux", "test", "quality", "security", "performance", "maintainability", "best-practices"]
},
"status": {
"type": "string",
"enum": ["pending", "in_progress", "completed", "failed"]
},
"findings": {
"type": "integer",
"minimum": 0
}
}
}
},
"total_findings": {
"type": "integer",
"minimum": 0,
"description": "Total number of findings across all perspectives"
},
"priority_distribution": {
"external_research": {
"type": "object",
"properties": {
"critical": { "type": "integer", "minimum": 0 },
"high": { "type": "integer", "minimum": 0 },
"medium": { "type": "integer", "minimum": 0 },
"low": { "type": "integer", "minimum": 0 }
},
"description": "Count of findings by priority level"
"enabled": { "type": "boolean", "default": false },
"completed": { "type": "boolean", "default": false }
}
},
"issues_generated": {
"type": "integer",
"minimum": 0,
"description": "Number of issues generated from discoveries"
},
"completed_at": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 timestamp of discovery completion"
"results": {
"type": "object",
"description": "Aggregated results (final phase)",
"properties": {
"total_findings": { "type": "integer", "minimum": 0 },
"issues_generated": { "type": "integer", "minimum": 0 },
"priority_distribution": {
"type": "object",
"properties": {
"critical": { "type": "integer" },
"high": { "type": "integer" },
"medium": { "type": "integer" },
"low": { "type": "integer" }
}
}
}
}
},
"examples": [
{
"discovery_id": "DSC-20250128-143022",
"target_pattern": "src/auth/**",
"metadata": {
"created_at": "2025-01-28T14:30:22Z",
"resolved_files": ["src/auth/service.ts", "src/auth/validator.ts"],
"perspectives": ["bug", "ux", "test", "quality", "security"],
"external_research_enabled": true
},
"discovery_id": "DSC-20251228-182237",
"target_pattern": "codex-lens/**/*.py",
"phase": "complete",
"perspectives_completed": ["bug", "ux", "test", "quality", "security"],
"total_findings": 45,
"priority_distribution": {
"critical": 2,
"high": 8,
"medium": 20,
"low": 15
"created_at": "2025-12-28T18:22:37+08:00",
"updated_at": "2025-12-28T18:35:00+08:00",
"target": {
"files_count": { "source": 48, "tests": 44, "total": 93 },
"project": { "name": "codex-lens", "version": "0.1.0" }
},
"issues_generated": 10,
"completed_at": "2025-01-28T14:45:00Z"
"perspectives": [
{ "name": "bug", "status": "completed", "findings": 15 },
{ "name": "test", "status": "completed", "findings": 11 },
{ "name": "quality", "status": "completed", "findings": 12 }
],
"external_research": { "enabled": false, "completed": false },
"results": {
"total_findings": 37,
"issues_generated": 15,
"priority_distribution": { "critical": 4, "high": 13, "medium": 16, "low": 6 }
}
}
]
}

View File

@@ -7,7 +7,7 @@
"properties": {
"id": {
"type": "string",
"description": "Issue ID (e.g., GH-123, TEXT-xxx)"
"description": "Issue ID (GH-123, ISS-xxx, DSC-001)"
},
"title": {
"type": "string"
@@ -21,24 +21,16 @@
"type": "integer",
"minimum": 1,
"maximum": 5,
"default": 3
"default": 3,
"description": "1=critical, 2=high, 3=medium, 4=low, 5=trivial"
},
"context": {
"type": "string",
"description": "Issue context/description (markdown)"
},
"bound_solution_id": {
"type": "string",
"description": "ID of the bound solution (null if none bound)"
},
"solution_count": {
"type": "integer",
"default": 0,
"description": "Number of candidate solutions in solutions/{id}.jsonl"
},
"source": {
"type": "string",
"enum": ["github", "text", "file"],
"enum": ["github", "text", "discovery"],
"description": "Source of the issue"
},
"source_url": {
@@ -50,6 +42,81 @@
"items": { "type": "string" },
"description": "Issue labels/tags"
},
"discovery_context": {
"type": "object",
"description": "Enriched context from issue:discover (only when source=discovery)",
"properties": {
"discovery_id": {
"type": "string",
"description": "Source discovery session ID"
},
"perspective": {
"type": "string",
"enum": ["bug", "ux", "test", "quality", "security", "performance", "maintainability", "best-practices"]
},
"category": {
"type": "string",
"description": "Finding category (e.g., edge-case, race-condition)"
},
"file": {
"type": "string",
"description": "Primary affected file"
},
"line": {
"type": "integer",
"description": "Line number in primary file"
},
"snippet": {
"type": "string",
"description": "Code snippet showing the issue"
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Agent confidence score"
},
"suggested_fix": {
"type": "string",
"description": "Suggested remediation from discovery"
}
}
},
"affected_components": {
"type": "array",
"items": { "type": "string" },
"description": "Files/modules affected"
},
"lifecycle_requirements": {
"type": "object",
"properties": {
"test_strategy": {
"type": "string",
"enum": ["unit", "integration", "e2e", "manual", "auto"]
},
"regression_scope": {
"type": "string",
"enum": ["affected", "related", "full"]
},
"acceptance_type": {
"type": "string",
"enum": ["automated", "manual", "both"]
},
"commit_strategy": {
"type": "string",
"enum": ["per-task", "squash", "atomic"]
}
}
},
"bound_solution_id": {
"type": "string",
"description": "ID of the bound solution (null if none bound)"
},
"solution_count": {
"type": "integer",
"default": 0,
"description": "Number of candidate solutions"
},
"created_at": {
"type": "string",
"format": "date-time"
@@ -62,13 +129,40 @@
"type": "string",
"format": "date-time"
},
"queued_at": {
"type": "string",
"format": "date-time"
},
"completed_at": {
"type": "string",
"format": "date-time"
}
}
},
"examples": [
{
"id": "DSC-001",
"title": "Fix: SQLite connection pool memory leak",
"status": "registered",
"priority": 1,
"context": "Connection pool cleanup only happens when MAX_POOL_SIZE is reached...",
"source": "discovery",
"labels": ["bug", "resource-leak", "critical"],
"discovery_context": {
"discovery_id": "DSC-20251228-182237",
"perspective": "bug",
"category": "resource-leak",
"file": "storage/sqlite_store.py",
"line": 59,
"snippet": "if len(self._pool) >= self.MAX_POOL_SIZE:\n self._cleanup_stale_connections()",
"confidence": 0.85,
"suggested_fix": "Implement periodic cleanup or weak references"
},
"affected_components": ["storage/sqlite_store.py"],
"lifecycle_requirements": {
"test_strategy": "unit",
"regression_scope": "affected",
"acceptance_type": "automated",
"commit_strategy": "per-task"
},
"bound_solution_id": null,
"solution_count": 0,
"created_at": "2025-12-28T18:22:37Z"
}
]
}