Story 18: Token-by-token streaming responses
- Backend: Added OllamaProvider::chat_stream() with newline-delimited JSON parsing - Backend: Emit chat:token events for each token received from Ollama - Backend: Added futures dependency and stream feature for reqwest - Frontend: Added streamingContent state and chat:token event listener - Frontend: Real-time token display with auto-scroll - Frontend: Markdown and syntax highlighting support for streaming content - Fixed all TypeScript errors (tsc --noEmit) - Fixed all Biome warnings and errors - Fixed all Clippy warnings - Added comprehensive code quality documentation - Added tsc --noEmit to verification checklist Tested and verified: - Tokens stream in real-time - Auto-scroll works during streaming - Tool calls interrupt streaming correctly - Multi-turn conversations work - Smooth performance with no lag
This commit is contained in:
227
.living_spec/CODE_QUALITY_CHECKLIST.md
Normal file
227
.living_spec/CODE_QUALITY_CHECKLIST.md
Normal file
@@ -0,0 +1,227 @@
|
||||
# Code Quality Checklist
|
||||
|
||||
This document provides a quick reference for code quality checks that MUST be performed before completing any story.
|
||||
|
||||
## Pre-Completion Checklist
|
||||
|
||||
Before asking for user acceptance in Step 4 (Verification), ALL of the following must pass:
|
||||
|
||||
### Rust Backend
|
||||
|
||||
```bash
|
||||
# 1. Run Clippy (linter)
|
||||
cd src-tauri
|
||||
cargo clippy --all-targets --all-features
|
||||
# Expected: 0 errors, 0 warnings
|
||||
|
||||
# 2. Run cargo check (compilation)
|
||||
cargo check
|
||||
# Expected: successful compilation
|
||||
|
||||
# 3. Run tests
|
||||
cargo test
|
||||
# Expected: all tests pass
|
||||
```
|
||||
|
||||
**Result Required:** ✅ 0 errors, 0 warnings, all tests pass
|
||||
|
||||
### TypeScript Frontend
|
||||
|
||||
```bash
|
||||
# 1. Run TypeScript compiler check (type errors)
|
||||
npx tsc --noEmit
|
||||
# Expected: 0 errors
|
||||
|
||||
# 2. Run Biome check (linter + formatter)
|
||||
npx @biomejs/biome check src/
|
||||
# Expected: 0 errors, 0 warnings
|
||||
|
||||
# 3. Apply fixes if needed
|
||||
npx @biomejs/biome check --write src/
|
||||
npx @biomejs/biome check --write --unsafe src/ # for unsafe fixes
|
||||
|
||||
# 4. Build
|
||||
npm run build
|
||||
# Expected: successful build
|
||||
```
|
||||
|
||||
**Result Required:** ✅ 0 errors, 0 warnings, successful build
|
||||
|
||||
## Common Biome Issues and Fixes
|
||||
|
||||
### 1. `noExplicitAny` - No `any` types
|
||||
|
||||
**Bad:**
|
||||
```typescript
|
||||
const handler = (data: any) => { ... }
|
||||
```
|
||||
|
||||
**Good:**
|
||||
```typescript
|
||||
const handler = (data: { className?: string; children?: React.ReactNode; [key: string]: unknown }) => { ... }
|
||||
```
|
||||
|
||||
### 2. `noArrayIndexKey` - Don't use array index as key
|
||||
|
||||
**Bad:**
|
||||
```typescript
|
||||
{items.map((item, idx) => <div key={idx}>...</div>)}
|
||||
```
|
||||
|
||||
**Good:**
|
||||
```typescript
|
||||
{items.map((item, idx) => <div key={`item-${idx}-${item.id}`}>...</div>)}
|
||||
```
|
||||
|
||||
### 3. `useButtonType` - Always specify button type
|
||||
|
||||
**Bad:**
|
||||
```typescript
|
||||
<button onClick={handler}>Click</button>
|
||||
```
|
||||
|
||||
**Good:**
|
||||
```typescript
|
||||
<button type="button" onClick={handler}>Click</button>
|
||||
```
|
||||
|
||||
### 4. `noAssignInExpressions` - No assignments in expressions
|
||||
|
||||
**Bad:**
|
||||
```typescript
|
||||
onMouseOver={(e) => (e.currentTarget.style.background = "#333")}
|
||||
```
|
||||
|
||||
**Good:**
|
||||
```typescript
|
||||
onMouseOver={(e) => {
|
||||
e.currentTarget.style.background = "#333";
|
||||
}}
|
||||
```
|
||||
|
||||
### 5. `useKeyWithMouseEvents` - Add keyboard alternatives
|
||||
|
||||
**Bad:**
|
||||
```typescript
|
||||
<button onMouseOver={handler} onMouseOut={handler2}>...</button>
|
||||
```
|
||||
|
||||
**Good:**
|
||||
```typescript
|
||||
<button
|
||||
onMouseOver={handler}
|
||||
onMouseOut={handler2}
|
||||
onFocus={handler}
|
||||
onBlur={handler2}
|
||||
>...</button>
|
||||
```
|
||||
|
||||
### 6. `useImportType` - Import types with `import type`
|
||||
|
||||
**Bad:**
|
||||
```typescript
|
||||
import { Message, Config } from "./types";
|
||||
```
|
||||
|
||||
**Good:**
|
||||
```typescript
|
||||
import type { Message, Config } from "./types";
|
||||
```
|
||||
|
||||
## Common Clippy Issues and Fixes
|
||||
|
||||
### 1. Unused variables
|
||||
|
||||
**Bad:**
|
||||
```rust
|
||||
} catch (e) {
|
||||
```
|
||||
|
||||
**Good:**
|
||||
```rust
|
||||
} catch (_e) { // prefix with underscore
|
||||
```
|
||||
|
||||
### 2. Dead code warnings
|
||||
|
||||
**Option 1:** Remove the code if truly unused
|
||||
|
||||
**Option 2:** Mark as allowed if used conditionally
|
||||
```rust
|
||||
#[allow(dead_code)]
|
||||
struct UnusedStruct {
|
||||
field: String,
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Explicit return
|
||||
|
||||
**Bad:**
|
||||
```rust
|
||||
fn get_value() -> i32 {
|
||||
return 42;
|
||||
}
|
||||
```
|
||||
|
||||
**Good:**
|
||||
```rust
|
||||
fn get_value() -> i32 {
|
||||
42
|
||||
}
|
||||
```
|
||||
|
||||
## Quick Verification Script
|
||||
|
||||
Save this as `check.sh` and run before every story completion:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=== Checking Rust Backend ==="
|
||||
cd src-tauri
|
||||
cargo clippy --all-targets --all-features
|
||||
cargo check
|
||||
cargo test
|
||||
cd ..
|
||||
|
||||
echo ""
|
||||
echo "=== Checking TypeScript Frontend ==="
|
||||
npx tsc --noEmit
|
||||
npx @biomejs/biome check src/
|
||||
npm run build
|
||||
|
||||
echo ""
|
||||
echo "✅ ALL CHECKS PASSED!"
|
||||
```
|
||||
|
||||
## Zero Tolerance Policy
|
||||
|
||||
- **No exceptions:** All errors and warnings MUST be fixed
|
||||
- **No workarounds:** Don't disable rules unless absolutely necessary
|
||||
- **No "will fix later":** Fix immediately before story completion
|
||||
- **User must see clean output:** When running checks, show clean results to user
|
||||
|
||||
## When Rules Conflict with Requirements
|
||||
|
||||
If a linting rule conflicts with a legitimate requirement:
|
||||
|
||||
1. Document why the rule must be bypassed
|
||||
2. Use the minimal scope for the exception (line/function, not file)
|
||||
3. Add a comment explaining the exception
|
||||
4. Get user approval
|
||||
|
||||
Example:
|
||||
```typescript
|
||||
// Biome requires proper types, but react-markdown types are incompatible
|
||||
// Using unknown for compatibility
|
||||
const code = ({ className, children }: { className?: string; children?: React.ReactNode; [key: string]: unknown }) => {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Integration with SDSW
|
||||
|
||||
This checklist is part of **Step 4: Verification** in the Story-Driven Spec Workflow.
|
||||
|
||||
**You cannot proceed to story acceptance without passing all checks.**
|
||||
Reference in New Issue
Block a user