Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
2745dc7
feat(teleop): add native voice control prototype
May 5, 2026
a226e45
feat(cli): add scaffold command for Company OS folder structure
May 8, 2026
92984d2
feat(daemon): add opt-out telemetry service
May 9, 2026
dcb1b6a
feat(hooks): add self-healing daemon health check for SessionStart
May 9, 2026
01300de
feat(daemon): add desire-path detector — auto-discover workflows, sug…
May 9, 2026
6ed3b4a
fix(desire-paths): adaptive backoff — hourly when active, exponential…
May 9, 2026
2ca73e0
feat(cli): add hermes-sm wrapper with StackMemory integration
May 9, 2026
290b34d
feat(desire-paths): auto-promote skills above 0.8 confidence + 5 sess…
May 9, 2026
65421a8
feat(daemon): add research stream scanner for market signal detection
May 9, 2026
6395ce0
fix(test): replace bun:test import with vitest in desire-path-service…
May 11, 2026
1831488
feat(tokens): replace char/4 heuristic with js-tiktoken (cl100k_base)
May 13, 2026
77f0105
feat(skill-packs): add content licenses (CC-BY-4.0) to registry metadata
May 14, 2026
fdbf38c
feat(tasks): add local-first master-tasks.md task management
May 14, 2026
482770d
feat(hooks): token optimization — dedup escalation, auto-route, prewa…
May 16, 2026
bff0d6c
feat(bench): add hook benchmark script + baseline report
May 17, 2026
46ac2b9
feat(hooks): weekly skill-mine reminder on SessionStart
May 17, 2026
1389bbb
fix(desire-paths): filter trivial patterns from suggestions + auto-de…
May 20, 2026
473af57
feat(subagent): design delegation — Claude-first routing for frontend…
May 27, 2026
9b91953
docs: rewrite CLAUDE.md as tool-agnostic agent guide
May 27, 2026
213113d
feat(hooks): project-aware prewarm tool cache
May 27, 2026
9ed1d52
feat(hooks): memory-loader SessionStart hook
May 27, 2026
1c1bc12
feat(hooks): image preprocessing + MCP vision extraction
May 27, 2026
ce84de1
feat(gepa): daemon watcher + session hook updates
May 27, 2026
dc7a026
chore(gepa): gen-001 variant updates from optimization run
May 27, 2026
3ee0269
Merge branch 'feat/token-optimization-hooks'
May 27, 2026
2569b23
feat(browser): Stagehand workflow capture, cache, replay + benchmark …
May 27, 2026
b50e9fe
feat(browser): CLI browser agent + benchmark updates
May 27, 2026
b3b57de
fix(hooks): add DISABLE_HOOKS skip guard to all Stop/SessionEnd hooks
May 27, 2026
b80fbeb
fix(browser): accept CLI output on non-zero exit from hook failures
May 27, 2026
d4c8c83
chore(deps): add stagehand + playwright for browser workflows
May 27, 2026
cb2ac88
docs(research): agent-readable web standards landscape 2026
May 27, 2026
2572a1d
chore(gepa): update generation variants + daemon state
May 27, 2026
af70a5c
feat(mcp): wire workflow tools into main MCP server
May 27, 2026
e46d2ff
feat(hooks): add cd-thrash, linear-dedup, and bash-dominance guardrails
May 27, 2026
82ce2c2
fix(benchmark): fix NPM selector timeout + use page.evaluate extraction
May 27, 2026
85746a2
chore(gepa): update daemon state + generation variants
May 27, 2026
e3b521a
chore(gepa): update hook state + scores
May 27, 2026
70206e2
chore(gepa): auto-optimizer state + eval results
May 27, 2026
a41dc02
chore(gepa): daemon state update
May 28, 2026
ab1287a
chore(gepa): auto-optimizer state update
May 28, 2026
60dcabd
feat(skill-packs): add ops/log-investigation pack
May 28, 2026
66cf258
fix(tests): update token estimator + subagent routing test expectations
May 28, 2026
95057db
feat(tracing): instrument MCP server with Raindrop Workshop
May 28, 2026
f8e260c
chore(gepa): auto-optimizer state update
May 28, 2026
f855fa3
chore: add Raindrop Workshop agent config files
May 28, 2026
d2c345e
refactor(mcp): extract handleTool from IIFE wrapper
May 28, 2026
c8474f2
feat(operator): autonomous Claude Code driver via screen control
Jun 9, 2026
3441eb9
fix(operator): nudge-then-escalate for stuck sessions + barrel export
Jun 9, 2026
327d1bf
feat(patterns): first-party learned patterns system (observe → learn …
Jun 9, 2026
91463a2
feat(patterns): add promote, projects, evolve commands — full CL-v2 p…
Jun 9, 2026
4ffb3bc
chore: handoff checkpoint on main
Jun 9, 2026
a9ccf87
chore: handoff checkpoint on main
Jun 9, 2026
1ff60a7
chore: handoff checkpoint on main
Jun 9, 2026
f95cc25
fix(test): skip OpenRouter live tests on invalid/missing API key
Jun 9, 2026
b97a8f8
feat(webhook): add persistent retry with exponential backoff
Jun 9, 2026
79e2ff7
fix(lint): resolve 46 pre-existing eslint errors across 8 files
Jun 9, 2026
f907c83
fix(storage): make redis import lazy in two-tier-storage
Jun 9, 2026
b106553
Merge remote-tracking branch 'origin/main' into feature/webhook-retry…
Jun 9, 2026
972d8e6
chore: handoff checkpoint on feature/webhook-retry-backoff
Jun 9, 2026
e96d327
fix: auto-load nvm in all scripts to prevent Node version mismatch
Jun 9, 2026
a53eb9a
docs: mark webhook retry backoff acceptance criteria as complete
Jun 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .claude/skills/instrument-agent
1 change: 1 addition & 0 deletions .claude/skills/setup-agent-replay
3 changes: 3 additions & 0 deletions .codex/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[mcp_servers.raindrop]
command = "/Users/jwu/.raindrop/bin/raindrop"
args = [ "workshop", "mcp" ]
11 changes: 11 additions & 0 deletions .cursor/mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"mcpServers": {
"raindrop": {
"command": "/Users/jwu/.raindrop/bin/raindrop",
"args": [
"workshop",
"mcp"
]
}
}
}
11 changes: 11 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"mcpServers": {
"raindrop": {
"command": "/Users/jwu/.raindrop/bin/raindrop",
"args": [
"workshop",
"mcp"
]
}
}
}
158 changes: 65 additions & 93 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,27 @@
# StackMemory - Project Configuration
You are a senior Node.js/Express engineer working on this codebase. Write working code over explanations. Run commands before asserting state — never assume branch, file, or test status without verification.

# croissant.ai — Agent Guide

Tool-agnostic reference for AI coding agents working in this repository.

## Stack

Node.js / Express / PostgreSQL / Redis
Railway deployment | Stripe / Salesforce / QuickBooks integrations

## Project Structure

```
src/
cli/ # CLI commands and entry point
core/ # Core business logic
config/ # Config types and manager
context/ # Frame management, enrichment, rehydration
database/ # SQLite adapter, migrations, query cache
digest/ # Digest generation (hybrid, chronological)
errors/ # Error types and recovery
merge/ # Stack merge and conflict resolution
models/ # Model routing, complexity scoring
monitoring/ # Logging, metrics, session monitor
performance/ # Caching, profiling, benchmarks
query/ # Query parsing and routing
retrieval/ # Context retrieval, LLM provider
session/ # Handoff, session management
skills/ # Skill storage and types
storage/ # Tiered storage, remote sync
trace/ # Debug tracing, trace detection
integrations/ # External integrations
claude-code/ # Agent bridge, post-task hooks
linear/ # Linear sync, webhooks, OAuth
mcp/ # MCP server, 56 tool handlers
ralph/ # Multi-agent swarm orchestration
daemon/ # Unified daemon, session daemon
features/ # Analytics, browser, sweep, TUI
hooks/ # Claude Code hook handlers
skills/ # Built-in skill implementations
utils/ # Shared utilities
scripts/ # Build and utility scripts
docs/ # Documentation
api/ # Route handlers
core/ # monitoring-service, cache-service, queue-service, master-agent, api-validation
features/ # Feature modules
shared/ # Shared utilities
integrations/ # Third-party connectors
docs/ # Documentation
scripts/ # Automation scripts
docker/ # Container configs
prompts/ # Externalized LLM prompt templates
```

## Key Files
Expand Down Expand Up @@ -69,81 +58,64 @@ Full documentation (docs/):
## Commands

```bash
npm run build # Compile TypeScript (esbuild)
npm run lint # ESLint check
npm run lint:fix # Auto-fix lint issues
npm run lint:fast # Fast lint via oxlint
npm run typecheck # tsc --noEmit (8GB heap, avoids OOM)
npm test # Run Vitest (watch)
npm run test:run # Run tests once
npm run linear:sync # Sync with Linear

# StackMemory CLI
stackmemory capture # Save session state for handoff
stackmemory restore # Restore from captured state
stackmemory snapshot save # Post-run context snapshot (alias: snap)
stackmemory snapshot list # List recent snapshots
stackmemory preflight # File overlap check for parallel tasks (alias: pf)
stackmemory conductor start # Autonomous Linear→worktree→agent orchestrator
stackmemory conductor learn # Analyze agent outcomes (success rate, failure phases, error patterns)
stackmemory conductor learn --evolve # Auto-mutate prompt template from failure data (GEPA)
stackmemory conductor status # Live agent status dashboard

# GEPA Optimizer (scripts/gepa/optimize.js)
node scripts/gepa/optimize.js run [gens] [--auto-apply] # Full optimization loop
node scripts/gepa/optimize.js score [--auto-apply] # Score variants, select best
node scripts/gepa/optimize.js run --target skill:start # Optimize specific target
node scripts/gepa/optimize.js mutate --auto-phase # Auto-detect worst phase
# Flags: --auto-apply (deploy winner), --no-cache (fresh eval), --target <name>, --phase <name>
stackmemory conductor monitor # Real-time TUI with phase tracking
stackmemory conductor finalize # Clean up dead/stale agents
stackmemory conductor traces <issue-id> # View conversation traces for an agent run
stackmemory conductor replay <session-id> # Replay full agent conversation from traces
stackmemory conductor trace-stats # Aggregate trace statistics
stackmemory loop "<cmd>" --until "<pattern>" # Poll until condition met (alias: watch)
npm run dev # Start dev server
npm run test # Run test suites (3 parallel Jest workers, maxWorkers=4)
npm run lint # Lint check
npm run migrate # Run DB migrations
docker-compose up -d # Start local DBs
```

## Working Directory
## Git Conventions

- Branch prefixes: `feature/`, `fix/`, `chore/`
- Commit format: `type(scope): message`
- Do NOT add `Co-Authored-By` lines to commits
- Pre-commit hook runs: `npm run lint` + `npm run test` + E2E browser screenshots

## Testing Rules

- PRIMARY: /Users/jwu/Dev/stackmemory
- ALLOWED: All subdirectories
- TEMP: /tmp for temporary operations
- **Framework**: Jest + SWC
- **DB mocking**: Use dependency injection (DI), not global mocks
- **Supertest**: Pass `app` (NOT `server`) to supertest
- **Global jest**: src/ tests use global `jest` — do NOT import from `@jest/globals` (causes redeclaration errors)
- **Mock reset**: `jest.clearAllMocks()` resets `mockReturnValue` — always re-set mocks in `beforeEach`
- **Test runner**: `npm test` is long-running; run in a background process or sub-agent, not inline

## Validation
## ESLint Rules

Verify each step after code changes — pre-commit hooks catch 80% of CI failures locally:
1. `npm run lint` - fix any errors AND warnings
2. `npm run test:run` - verify no regressions
3. `npm run build` - ensure compilation
4. Run code to verify it works
- Use `catch {}` not `catch (_err) {}` — underscore prefix not in the allowed pattern
- CJS format for JS files in `src/`

Test coverage:
- New features require tests in `src/**/__tests__/`
- Maintain or improve coverage (no untested code paths)
- Critical paths: context management, handoff, Linear sync
## Key Patterns

Testing rules:
- Run `npm run test:run` via subagent or background task — never inline (blocks context)
- ESLint: use `catch {}` not `catch (_err) {}` (lint rule)
- `vi.clearAllMocks()` resets `mockReturnValue` — re-set mocks in `beforeEach`
- Pre-commit hook runs: lint + parallel vitest + build — fix issues before commit, never skip
- Provenance tracking: every data point includes source, timestamp, lineage
- Multi-tenant container isolation
- DI route factories for testability
- Error handling: return undefined over throwing; log and continue over crashing
- Add `.js` extension to relative ESM imports

## Git Rules
## Task Steering

The pre-commit hook enforces lint + test + build. Fix the underlying issue rather than bypassing it.
**`master-tasks.md`** is the single source of truth for what to build. Agents must:

- Do not use `--no-verify` on git push or commit — fix the hook failure instead
- Fix lint/test errors before pushing
- If pre-push hooks fail, fix the underlying issue
- Run `npm run lint && npm run test:run` before pushing
- Commit message format: `type(scope): message`
- Branch naming: `feature/STA-XXX-description` | `fix/STA-XXX-description` | `chore/description`
1. Read `master-tasks.md` before starting work (especially via `/next`)
2. Pick the highest-priority (`P0` > `P1` > `P2`) non-blocked `todo` task
3. Prefer tasks with `owner=@agent` over `owner=@me` (unless user overrides)
4. Update task status to `active` when starting, `done` when complete
5. Add branch/PR info to the table row
6. Never create tasks in Linear or GitHub unless `sync` column says so

## Task Management
## StackMemory Context Rule

- Use TodoWrite for 3+ steps or multiple requests
- Keep one task in_progress at a time
- Update task status immediately on completion
- When an agent fetches conversation context for active work, it must pass the exact current assignment or question as `task_query`.
- Prefer the MCP shape:
- `org_id`
- `conversation_id`
- `worker_mode: true`
- `task_query`
- `recover_on_low_signal: true`
- Do not fetch raw `get_conversation` context for worker execution unless full transcript behavior is explicitly required.
- The current assignment is persisted under `.stackmemory/worker-context/current-assignment.json` so wrappers and hooks can auto-fill or enforce `task_query`.

## Security

Expand Down
94 changes: 94 additions & 0 deletions docs/plans/webhook-retry-exponential-backoff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Plan: Webhook Retry with Exponential Backoff

## Summary

Add persistent retry with exponential backoff to webhook event processing. Replace the in-memory `eventQueue` in `webhook-server.ts` with a SQLite-backed delivery queue that tracks attempts, applies exponential backoff with jitter, and respects circuit breaker state.

## Existing Infrastructure to Leverage

- **`src/core/errors/recovery.ts`**: `retry()`, `calculateBackoff()`, `CircuitBreaker` — all production-ready
- **`src/integrations/linear/webhook-server.ts`**: Current in-memory queue (`eventQueue[]`, `processQueue()`)
- **`src/core/database/sqlite-adapter.ts`**: SQLite persistence layer
- **Error codes**: `LINEAR_WEBHOOK_FAILED`, `LINEAR_API_ERROR` already exist

## Files to Change

| File | Action | Purpose |
|---|---|---|
| `src/integrations/linear/webhook-retry.ts` | CREATE | Delivery queue + retry worker |
| `src/integrations/linear/webhook-server.ts` | MODIFY | Replace in-memory queue with persistent queue |
| `src/integrations/linear/__tests__/webhook-retry.test.ts` | CREATE | Tests for retry logic |

## Data Model

New table: `webhook_deliveries` (added inline in webhook-retry.ts, not in global migrations — this is integration-scoped)

```sql
CREATE TABLE IF NOT EXISTS webhook_deliveries (
id TEXT PRIMARY KEY,
event_type TEXT NOT NULL,
payload TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending', -- pending | processing | completed | failed | dead
attempts INTEGER NOT NULL DEFAULT 0,
max_attempts INTEGER NOT NULL DEFAULT 5,
next_retry_at INTEGER, -- unix ms
last_error TEXT,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_status_retry
ON webhook_deliveries(status, next_retry_at);
```

## Implementation Steps

### Step 1: Create `webhook-retry.ts`

- `WebhookDeliveryQueue` class
- `constructor(dbPath: string, options?: RetryConfig)` — opens/creates SQLite DB, ensures table
- `enqueue(eventType: string, payload: object): string` — inserts delivery, returns ID
- `processNext(): Promise<boolean>` — picks oldest `pending` or retriable `failed` delivery where `next_retry_at <= now`, marks `processing`, calls handler, updates status
- `startWorker(intervalMs?: number): void` — setInterval loop calling `processNext()`
- `stopWorker(): void` — clearInterval
- `getStats(): { pending, processing, completed, failed, dead }` — counts by status
- Uses `calculateBackoff()` from `recovery.ts` for next_retry_at computation
- Marks delivery `dead` after max_attempts exceeded
- Config: `{ maxAttempts: 5, initialDelay: 1000, maxDelay: 300_000, backoffFactor: 2 }`

### Step 2: Modify `webhook-server.ts`

- Replace `eventQueue: LinearWebhookPayload[]` with `WebhookDeliveryQueue` instance
- In webhook endpoint handler: call `queue.enqueue()` instead of `eventQueue.push()`
- Start worker in `start()`, stop in `stop()`
- Remove `processQueue()` method and `isProcessing` flag

### Step 3: Write tests

- Unit tests for `WebhookDeliveryQueue`:
- enqueue creates a delivery record
- processNext picks the oldest pending delivery
- failed delivery gets exponential backoff schedule
- delivery marked dead after max_attempts
- concurrent processNext doesn't double-process (status = processing guard)
- getStats returns correct counts

## Acceptance Criteria

- [x] Failed webhook events are retried up to 5 times with exponential backoff
- [x] Backoff schedule: 1s, 2s, 4s, 8s, 16s (capped at 300s)
- [x] Delivery state persisted in SQLite — survives process restart
- [x] Dead deliveries (exceeded max attempts) are logged but not retried
- [x] Existing webhook signature verification unchanged
- [x] Tests pass with 80%+ coverage on new code

## Risks

- **LOW**: SQLite write contention if webhook volume is high — mitigated by WAL mode (already used)
- **LOW**: Worker interval drift — acceptable for webhook retry cadence (not real-time)

## Non-Goals

- Redis/BullMQ queue (overkill for single-process webhook handler)
- Webhook delivery UI/dashboard
- Dead letter queue notification
- Outbound webhook sending (this is for processing *received* webhooks)
Loading
Loading