Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 57 additions & 2 deletions .cursor/rules/general.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,66 @@ globs: **/*
5. Run linting ONLY in venv: `source .venv/bin/activate && make lint`
6. Run type checking ONLY in venv: `source .venv/bin/activate && make type-check`
7. Format code ONLY in venv: `source .venv/bin/activate && make format`
8. Update documentation if needed
9. Create pull request
8. **CRITICAL**: Fix ALL errors before committing - never use `--no-verify`
9. Update documentation if needed
10. Create pull request

**REMINDER**: All Python commands must be run within the activated virtual environment

## Pre-commit and Push Rules

🚨 **CRITICAL**: Never use `--no-verify` flag when pushing commits

- **ALWAYS** fix all pre-commit hook errors before pushing
- **ALWAYS** fix all linting errors before pushing
- **ALWAYS** fix all type checking errors before pushing
- **ALWAYS** fix all test failures before pushing
- **ALWAYS** ensure all security scans pass before pushing

### Why Never Use --no-verify

- **CI/CD will fail**: GitHub Actions will catch the same errors and fail the build
- **Security risks**: Bypassing security scans defeats the purpose of automated checks
- **Code quality**: Skipping quality checks leads to technical debt
- **Team workflow**: Other developers expect clean, tested code
- **Production safety**: Errors that pass locally will fail in production

### When Pre-commit Hooks Fail

1. **Read the error message carefully**
2. **Fix the underlying issue** (don't just suppress the error)
3. **Run the specific command that failed** to understand the error
4. **Test your fix** by running the command again
5. **Only commit when all checks pass**

### Common Pre-commit Failures and Solutions

```bash
# If ruff linting fails
source .venv/bin/activate && make lint

# If black formatting fails
source .venv/bin/activate && make format

# If mypy type checking fails
source .venv/bin/activate && make type-check

# If tests fail
source .venv/bin/activate && make test

# If security scans fail
source .venv/bin/activate && pip-audit -r requirements.txt
```

### Emergency Situations

If you absolutely must bypass pre-commit hooks (emergency fixes only):

1. **Document why** in the commit message
2. **Create a follow-up issue** to fix the bypassed checks
3. **Fix the issues immediately** in the next commit
4. **Never merge** code that bypasses security or quality checks

## Testing Strategy

- **Dual-suite architecture**: Public API tests (`test_backfill_scanning.py`) + Integration tests (`test_backfill_integration.py`)
Expand Down
40 changes: 40 additions & 0 deletions .cursor/rules/python.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,46 @@ globs: **/*.py
- Use `from __future__ import annotations` for forward references - MUST be placed before any other imports or executable code, but may come after optional module-level elements (shebang, encoding declaration, license/comments block, or module docstring) to ensure consistent forward-reference behavior across the codebase
- Docstrings required for public functions and classes (Google style)

## Pre-commit and Quality Gates

🚨 **CRITICAL**: Never use `--no-verify` when pushing Python code

- **ALWAYS** fix all linting errors before pushing
- **ALWAYS** fix all type checking errors before pushing
- **ALWAYS** fix all formatting issues before pushing
- **ALWAYS** fix all security scan failures before pushing
- **ALWAYS** ensure all tests pass before pushing

### Python-Specific Quality Checks

```bash
# Activate virtual environment first
source .venv/bin/activate

# Run all quality checks
make lint # ruff linting
make format # black formatting
make type-check # mypy type checking
make test # pytest testing
pip-audit -r requirements.txt # security scanning
```

### Common Python Quality Issues

```python
# Fix import sorting issues
# Run: ruff check --fix

# Fix type annotation issues
# Run: mypy src/ --strict

# Fix formatting issues
# Run: black src/

# Fix security issues
# Run: pip-audit -r requirements.txt
```

## Type Hints

```python
Expand Down
33 changes: 33 additions & 0 deletions .cursor/rules/testing.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,39 @@ globs: **/tests/**/*.py

# Testing Guidelines

## Pre-commit Testing Rules

🚨 **CRITICAL**: Never use `--no-verify` when pushing test code

- **ALWAYS** ensure all tests pass before pushing
- **ALWAYS** fix all test failures before pushing
- **ALWAYS** ensure test coverage meets requirements before pushing
- **ALWAYS** run both API and integration tests before pushing

### Test Quality Gates

```bash
# Activate virtual environment first
source .venv/bin/activate

# Run all tests
make test-api # Quick API validation (recommended for development)
make test-integration # Comprehensive functionality testing
make test # Full test suite (for CI/CD)

# Run with coverage
make test-coverage # Run tests with coverage reporting
```

### When Tests Fail

1. **Read the test failure message carefully**
2. **Run the specific test that failed** to understand the issue
3. **Fix the underlying problem** (don't just skip the test)
4. **Re-run the test** to confirm the fix
5. **Run the full test suite** to ensure no regressions
6. **Only commit when all tests pass**

## Testing Strategy

### Dual Test Suite Architecture
Expand Down
7 changes: 0 additions & 7 deletions .github/scripts/test_vulnerability_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,6 @@ def test_create_issue_body_with_empty_vulns(self):
self.assertIn("HIGH/CRITICAL vulnerabilities: 0", body)

@patch("create_security_issue.subprocess.run")
@@
@patch("create_security_issue.subprocess.run")
@@
@patch("create_security_issue.subprocess.run")
@@
@patch("create_security_issue.subprocess.run")
@patch("subprocess.run")
def test_create_github_issue_failure(self, mock_run):
"""Test handling GitHub issue creation failure."""
from subprocess import CalledProcessError
Expand Down
58 changes: 51 additions & 7 deletions clients/typescript/contextforgeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ export class ContextForgeClient {
}
return false;
}

/**
* Parses error response body for better error messages.
* @private
*/
Expand Down Expand Up @@ -247,7 +249,7 @@ export class ContextForgeClient {
}

// Decide whether to retry
if (attempt < this.retryConfig.maxRetries && lastError !== undefined && this.shouldRetry(lastError, lastResponse)) {
if (attempt < this.retryConfig.maxRetries && lastError !== undefined && this.shouldRetry(lastError)) {
const delay = this.calculateDelay(attempt);
// Log retry decision
this.logger?.warn(`Retry attempt ${attempt + 1}/${this.retryConfig.maxRetries} for ${url}`, {
Expand Down Expand Up @@ -499,12 +501,54 @@ export class ContextForgeClient {
return r.json() as Promise<{ vectors: number[][] }>;
}

if (summary !== undefined && typeof summary !== 'string') {
throw new Error('summary must be a string when provided');
}
if (summary !== undefined && summary.trim() === '') {
throw new Error('summary must be a non-empty string when provided');
}
/**
* Creates a checkpoint for a session using the v1 API.
*
* @param session_id - The session ID to create a checkpoint for
* @param phase - The phase of the session (planning, execution, review)
* @param summary - Optional summary of the checkpoint
* @param metadata - Optional metadata for the checkpoint
* @returns Promise resolving to an object indicating success
* @throws Error if the API request fails
*/
async v1Checkpoint(
session_id: string,
phase: 'planning' | 'execution' | 'review',
summary?: string,
metadata?: Record<string, unknown>
): Promise<{ ok: boolean }> {
// Validate input
if (!session_id || typeof session_id !== 'string' || session_id.trim() === '') {
throw new Error('session_id must be a non-empty string');
}
if (!phase || !['planning', 'execution', 'review'].includes(phase)) {
throw new Error('phase must be one of: planning, execution, review');
}
if (summary !== undefined && (typeof summary !== 'string' || summary.trim() === '')) {
throw new Error('summary must be a non-empty string when provided');
}
if (metadata !== undefined) {
if (typeof metadata !== 'object' || metadata === null || Array.isArray(metadata)) {
throw new Error('metadata must be a non-null object when provided');
}
}

const body: {
session_id: string;
phase: string;
summary?: string;
metadata?: Record<string, unknown>;
} = { session_id, phase };
if (summary !== undefined) body.summary = summary;
if (metadata !== undefined) body.metadata = metadata;

const r = await this.fetchWithRetry(`${this.baseUrl}/v1/checkpoint`, {
method: "POST",
headers: this.authHeaders(true),
body: JSON.stringify(body),
});
return r.json() as Promise<{ ok: boolean }>;
}

/**
* Restores context for a session using the v1 API with retry logic.
Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ dev = [
"safety==3.6.2",
"pip-audit==2.9.0",
]
openai = [
"openai>=1.0.0,<3.0.0",
"tiktoken>=0.5.0,<1.0.0",
]

[tool.setuptools.packages.find]
where = ["src"]
Expand Down
1 change: 1 addition & 0 deletions requirements-dev.in
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ tomli>=2.0.0
tomli-w>=1.0.0
pip-tools>=7.0.0
pyright>=1.1.0
mypy>=1.0.0
14 changes: 11 additions & 3 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,12 @@ mdurl==0.1.2
# via markdown-it-py
msgpack==1.1.2
# via cachecontrol
mypy==1.18.2
# via -r requirements-dev.in
mypy-extensions==1.1.0
# via black
# via
# black
# mypy
nodeenv==1.9.1
# via
# pre-commit
Expand All @@ -81,7 +85,9 @@ packaging==25.0
# pip-requirements-parser
# pytest
pathspec==0.12.1
# via black
# via
# black
# mypy
pip-api==0.0.34
# via pip-audit
pip-audit==2.9.0
Expand Down Expand Up @@ -152,7 +158,9 @@ types-aiofiles==25.1.0.20251011
types-pyyaml==6.0.12.20250915
# via -r requirements-dev.in
typing-extensions==4.15.0
# via pyright
# via
# mypy
# pyright
urllib3==2.5.0
# via requests
virtualenv==20.35.3
Expand Down
23 changes: 23 additions & 0 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Core dependencies
fastapi==0.120.0
uvicorn[standard]==0.38.0
pydantic==2.12.3
orjson==3.11.3
numpy==2.3.4
pytest==8.4.2
httpx==0.28.1
ruff==0.14.2
black==25.9.0
starlette==0.48.0
safety==3.6.2
pip-audit==2.9.0
tenacity==9.1.2
aiofiles==25.1.0
filelock==3.20.0
click==8.3.0
rich==14.2.0
tomli==2.3.0
tomli_w==1.2.0
tiktoken>=0.5.0,<1.0.0
openai>=1.0.0,<3.0.0
# setuptools==80.9.0
Loading
Loading