@stackmemoryai/stackmemory 1.5.9 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/src/cli/commands/orchestrate.js +506 -33
  2. package/dist/src/cli/commands/orchestrator.js +208 -31
  3. package/dist/src/daemon/daemon-config.js +2 -3
  4. package/dist/src/daemon/session-daemon.js +4 -5
  5. package/dist/src/daemon/unified-daemon.js +4 -5
  6. package/dist/src/features/sweep/sweep-server-manager.js +3 -6
  7. package/dist/src/hooks/daemon.js +5 -8
  8. package/dist/src/utils/process-cleanup.js +9 -0
  9. package/package.json +1 -2
  10. package/scripts/gepa/.before-optimize.md +0 -112
  11. package/scripts/gepa/README.md +0 -275
  12. package/scripts/gepa/config.json +0 -59
  13. package/scripts/gepa/evals/coding-tasks.jsonl +0 -5
  14. package/scripts/gepa/evals/fixtures/api-endpoint.ts +0 -31
  15. package/scripts/gepa/evals/fixtures/brittle-integration.ts +0 -38
  16. package/scripts/gepa/evals/fixtures/buggy-loop.js +0 -18
  17. package/scripts/gepa/evals/fixtures/callback-hell.js +0 -53
  18. package/scripts/gepa/evals/fixtures/fts5-triggers.sql +0 -23
  19. package/scripts/gepa/evals/fixtures/leaky-service.ts +0 -70
  20. package/scripts/gepa/evals/fixtures/mcp-dispatch-stub.ts +0 -39
  21. package/scripts/gepa/evals/fixtures/pr-diff.txt +0 -24
  22. package/scripts/gepa/evals/fixtures/unsafe-webhook.ts +0 -34
  23. package/scripts/gepa/evals/fixtures/unwrapped-db-op.ts +0 -42
  24. package/scripts/gepa/evals/stackmemory-tasks.jsonl +0 -8
  25. package/scripts/gepa/generations/gen-000/baseline.md +0 -112
  26. package/scripts/gepa/generations/gen-001/baseline.md +0 -112
  27. package/scripts/gepa/generations/gen-001/variant-a.md +0 -107
  28. package/scripts/gepa/generations/gen-001/variant-b.md +0 -216
  29. package/scripts/gepa/generations/gen-001/variant-c.md +0 -83
  30. package/scripts/gepa/generations/gen-001/variant-d.md +0 -90
  31. package/scripts/gepa/hooks/auto-optimize.js +0 -494
  32. package/scripts/gepa/hooks/eval-tracker.js +0 -203
  33. package/scripts/gepa/hooks/reflect.js +0 -350
  34. package/scripts/gepa/optimize.js +0 -853
  35. package/scripts/gepa/results/eval-1-baseline.json +0 -218
  36. package/scripts/gepa/results/eval-1-variant-a.json +0 -218
  37. package/scripts/gepa/results/eval-1-variant-b.json +0 -218
  38. package/scripts/gepa/results/eval-1-variant-c.json +0 -218
  39. package/scripts/gepa/results/eval-1-variant-d.json +0 -218
  40. package/scripts/gepa/state.json +0 -49
@@ -1,42 +0,0 @@
1
- // Database operation with no error handling — needs StackMemory error wrapping
2
-
3
- interface Frame {
4
- id: string;
5
- name: string;
6
- status: string;
7
- }
8
-
9
- // Simulated database
10
- const db = {
11
- prepare(sql: string) {
12
- return {
13
- get(...params: unknown[]): Frame | undefined {
14
- // May throw: SQLITE_BUSY, SQLITE_CONSTRAINT, SQLITE_CORRUPT
15
- throw new Error('SQLITE_BUSY: database is locked');
16
- },
17
- run(...params: unknown[]) {
18
- // May throw various SQLite errors
19
- },
20
- };
21
- },
22
- };
23
-
24
- // This function has NO error handling. Wrap it properly using:
25
- // - DatabaseError from core/errors
26
- // - Appropriate ErrorCode (DB_QUERY_FAILED, DB_CONNECTION_FAILED)
27
- // - Preserve the original error as cause
28
- // - Set isRetryable = true for connection/busy errors, false for constraint errors
29
- // - Log with structured context (operation name, frameId)
30
- async function getFrameById(frameId: string): Promise<Frame | null> {
31
- const row = db.prepare('SELECT * FROM frames WHERE id = ?').get(frameId);
32
- return row || null;
33
- }
34
-
35
- async function updateFrameStatus(
36
- frameId: string,
37
- status: string
38
- ): Promise<void> {
39
- db.prepare('UPDATE frames SET status = ? WHERE id = ?').run(status, frameId);
40
- }
41
-
42
- export { getFrameById, updateFrameStatus };
@@ -1,8 +0,0 @@
1
- {"id": "sm-001", "name": "add_mcp_tool_handler", "prompt": "Add a new MCP tool handler called 'get_frame_summary' that takes a frameId (required string) and returns { frameId, name, status, eventCount }. Follow the existing switch/case dispatch pattern in server.ts. Include Zod input validation.", "input_file": "fixtures/mcp-dispatch-stub.ts", "expected": {"has_switch_case": true, "has_zod_schema": true, "validates_input": true, "returns_typed_response": true, "handles_not_found": true}, "weight": 1.5}
2
- {"id": "sm-002", "name": "fix_fts5_trigger_bug", "prompt": "The FTS5 DELETE trigger is missing — when a frame is deleted from the frames table, the frames_fts index is not updated. Add the missing AFTER DELETE trigger following the pattern of the existing INSERT and UPDATE triggers.", "input_file": "fixtures/fts5-triggers.sql", "expected": {"has_delete_trigger": true, "uses_fts_delete_syntax": true, "references_old_row": true, "matches_column_list": true}, "weight": 1.8}
3
- {"id": "sm-003", "name": "daemon_service_lifecycle", "prompt": "This daemon service has a timer leak — when updateConfig() restarts the service, the old interval is not cleared before creating a new one if start() is called while already running. Fix the bug and add a getState() method that returns { isRunning, intervalMs, lastRunTime, errorCount }.", "input_file": "fixtures/leaky-service.ts", "expected": {"clears_old_interval": true, "prevents_double_start": true, "has_getstate_method": true, "returns_correct_state_shape": true}, "weight": 1.5}
4
- {"id": "sm-004", "name": "webhook_payload_validation", "prompt": "This webhook handler is vulnerable to prototype pollution and has no input length limits. Fix the validation to: 1) reject __proto__ and constructor keys, 2) limit title to 500 chars, 3) limit description to 5000 chars, 4) validate that action is one of create/update/remove.", "input_file": "fixtures/unsafe-webhook.ts", "expected": {"blocks_proto_pollution": true, "limits_title_length": true, "limits_description_length": true, "validates_action_enum": true, "returns_null_on_invalid": true}, "weight": 2.0}
5
- {"id": "sm-005", "name": "error_handling_chain", "prompt": "Wrap this database operation in proper StackMemory error handling: use DatabaseError with appropriate ErrorCode, preserve the cause chain, set isRetryable based on error type (connection errors are retryable, constraint violations are not), and log with structured context.", "input_file": "fixtures/unwrapped-db-op.ts", "expected": {"uses_database_error": true, "preserves_cause": true, "sets_retryable_correctly": true, "has_structured_logging": true, "catches_unknown_type": true}, "weight": 1.3}
6
- {"id": "sm-006", "name": "integration_graceful_degradation", "prompt": "This integration handler crashes the MCP server when the external API is down. Refactor it to degrade gracefully: catch connection errors, return a user-friendly MCPResponse with metadata.unavailable=true, log at debug level (not error), and don't retry on 4xx errors.", "input_file": "fixtures/brittle-integration.ts", "expected": {"catches_connection_errors": true, "returns_mcp_response": true, "sets_unavailable_metadata": true, "logs_at_debug": true, "no_retry_on_4xx": true}, "weight": 1.5}
7
- {"id": "sm-007", "name": "sqlite_migration_safety", "prompt": "Write a safe SQLite migration that adds a 'tags' TEXT column to the frames table. The migration must: 1) check if column already exists first (idempotent), 2) wrap in a transaction, 3) update the schema_version table, 4) handle the case where schema_version table doesn't exist yet.", "expected": {"checks_column_exists": true, "uses_transaction": true, "updates_schema_version": true, "is_idempotent": true, "handles_missing_version_table": true}, "weight": 1.5}
8
- {"id": "sm-008", "name": "review_pr_security", "prompt": "Review this PR diff and identify all security issues, performance problems, and code quality concerns. Provide actionable feedback for each issue found.", "input_file": "fixtures/pr-diff.txt", "expected": {"identifies_sql_injection": true, "identifies_plaintext_password": true, "identifies_credential_logging": true, "identifies_weak_session": true, "provides_fix_suggestions": true}, "weight": 2.0}
@@ -1,112 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Project Overview
6
-
7
- Sol is the monorepo for **Rize**, an automatic time tracking application. The stack consists of:
8
- - **api/** - Rails 7.1 GraphQL backend (Ruby 3.3.5)
9
- - **web/** - Next.js 14 React web app (Node 22)
10
- - **electron/** - Electron desktop app (Node 22)
11
- - **services/** - Bun-based TypeScript event consumers/workers
12
- - **vanity/** - Webflow marketing site scripts (deprecated)
13
- - **voyager/** - Marketing website for home and landing pageas (Next.js)
14
- - **puppet/** - Puppeteer server for images/PDFs
15
- - **chrome/** - Chrome browser extension
16
- - **docs/** - Docusaurus documentation site
17
- - **zapier/** - Zapier integration
18
-
19
- ## Development Commands
20
-
21
- ### Starting Development Environment
22
- ```bash
23
- # Start all services (requires iTerm2 on macOS)
24
- ./scripts/run-dev.sh
25
-
26
- # Or start individually:
27
- cd api && hivemind Procfile.dev # Rails + AnyCable + Sidekiq + Clockwork
28
- cd web && npm run dev # Next.js dev server
29
- cd electron && npm run dev # Electron with hot reload
30
- cd services && hivemind Procfile.dev # Bun services
31
- ```
32
-
33
- ### Docker Dependencies (api/docker-compose.yml)
34
- ```bash
35
- cd api && docker-compose up -d
36
- # TimescaleDB: localhost:15432
37
- # Redis: localhost:16379
38
- # Kafka: localhost:9092
39
- # MySQL: localhost:13306
40
- ```
41
-
42
- ### Testing
43
- ```bash
44
- # API (RSpec)
45
- cd api && bundle exec rspec
46
- cd api && bundle exec rspec spec/path/to/file_spec.rb # Single file
47
- cd api && bundle exec rspec spec/path/to/file_spec.rb:42 # Single test at line
48
-
49
- # Electron (Jest)
50
- cd electron && npm test
51
- cd electron && npm run test:watch
52
- cd electron && npm run test:coverage
53
-
54
- # Web - no active tests (exits 0)
55
- ```
56
-
57
- ### Building
58
- ```bash
59
- cd api && bundle install && rake db:migrate
60
- cd web && npm run build # Runs gql-gen, tailwind, next build
61
- cd electron && npm run build # Electron Forge make
62
- cd services && bun install
63
- ```
64
-
65
- ### GraphQL Code Generation
66
- ```bash
67
- cd web && npm run build # Includes gql codegen
68
- cd electron && npm run dev # Runs gql codegen as part of dev
69
- ```
70
-
71
- ## Architecture
72
-
73
- ### GraphQL API Structure
74
- The API exposes two GraphQL endpoints:
75
- - **api/v1** - Public API (OAuth consumers, Zapier)
76
- - **private/v1** - Private API (web, electron apps)
77
-
78
- Located at `api/app/graphql/{api,private}/v1/`
79
-
80
- ### Real-time Communication
81
- - **AnyCable** WebSocket server for subscriptions
82
- - ActionCable channels in `api/app/channels/`
83
- - WebSocket config: `api/config/cable.yml` and `api/config/anycable.yml`
84
-
85
- ### Background Jobs
86
- - **Sidekiq** for async job processing (`api/config/sidekiq.yml`)
87
- - **Clockwork** for scheduled jobs (`api/config/clock.rb`)
88
-
89
- ### Event Streaming
90
- - **Kafka** for event publishing/consumption
91
- - Services consume events via `services/consumers/`
92
- - Kafka config: `api/config/initializers/kafka.rb`
93
-
94
- ### Databases
95
- - **Primary PostgreSQL** - Main application data
96
- - **TimescaleDB** - Time-series data (separate connection in `database.yml`)
97
- - **MySQL** - Legacy/external integrations
98
- - **Redis** - Caching, ActionCable, Sidekiq
99
-
100
- ## Style Guidelines
101
-
102
- ### JavaScript/TypeScript
103
- - Use `test()` instead of `it()` in tests
104
- - Use `toBeCalled()` instead of `toHaveBeenCalledWith()` in jest assertions
105
-
106
- ## Key Configuration Files
107
-
108
- - `api/config/database.yml` - Database connections (primary + timescale)
109
- - `api/config/cable.yml` - AnyCable WebSocket config
110
- - `api/Procfile.dev` - Development processes (rails, anycable, sidekiq, clockwork)
111
- - `sol.code-workspace` - VS Code multi-folder workspace
112
- - Each project requires its own `.env` file (not in repo)
@@ -1,112 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Project Overview
6
-
7
- Sol is the monorepo for **Rize**, an automatic time tracking application. The stack consists of:
8
- - **api/** - Rails 7.1 GraphQL backend (Ruby 3.3.5)
9
- - **web/** - Next.js 14 React web app (Node 22)
10
- - **electron/** - Electron desktop app (Node 22)
11
- - **services/** - Bun-based TypeScript event consumers/workers
12
- - **vanity/** - Webflow marketing site scripts (deprecated)
13
- - **voyager/** - Marketing website for home and landing pageas (Next.js)
14
- - **puppet/** - Puppeteer server for images/PDFs
15
- - **chrome/** - Chrome browser extension
16
- - **docs/** - Docusaurus documentation site
17
- - **zapier/** - Zapier integration
18
-
19
- ## Development Commands
20
-
21
- ### Starting Development Environment
22
- ```bash
23
- # Start all services (requires iTerm2 on macOS)
24
- ./scripts/run-dev.sh
25
-
26
- # Or start individually:
27
- cd api && hivemind Procfile.dev # Rails + AnyCable + Sidekiq + Clockwork
28
- cd web && npm run dev # Next.js dev server
29
- cd electron && npm run dev # Electron with hot reload
30
- cd services && hivemind Procfile.dev # Bun services
31
- ```
32
-
33
- ### Docker Dependencies (api/docker-compose.yml)
34
- ```bash
35
- cd api && docker-compose up -d
36
- # TimescaleDB: localhost:15432
37
- # Redis: localhost:16379
38
- # Kafka: localhost:9092
39
- # MySQL: localhost:13306
40
- ```
41
-
42
- ### Testing
43
- ```bash
44
- # API (RSpec)
45
- cd api && bundle exec rspec
46
- cd api && bundle exec rspec spec/path/to/file_spec.rb # Single file
47
- cd api && bundle exec rspec spec/path/to/file_spec.rb:42 # Single test at line
48
-
49
- # Electron (Jest)
50
- cd electron && npm test
51
- cd electron && npm run test:watch
52
- cd electron && npm run test:coverage
53
-
54
- # Web - no active tests (exits 0)
55
- ```
56
-
57
- ### Building
58
- ```bash
59
- cd api && bundle install && rake db:migrate
60
- cd web && npm run build # Runs gql-gen, tailwind, next build
61
- cd electron && npm run build # Electron Forge make
62
- cd services && bun install
63
- ```
64
-
65
- ### GraphQL Code Generation
66
- ```bash
67
- cd web && npm run build # Includes gql codegen
68
- cd electron && npm run dev # Runs gql codegen as part of dev
69
- ```
70
-
71
- ## Architecture
72
-
73
- ### GraphQL API Structure
74
- The API exposes two GraphQL endpoints:
75
- - **api/v1** - Public API (OAuth consumers, Zapier)
76
- - **private/v1** - Private API (web, electron apps)
77
-
78
- Located at `api/app/graphql/{api,private}/v1/`
79
-
80
- ### Real-time Communication
81
- - **AnyCable** WebSocket server for subscriptions
82
- - ActionCable channels in `api/app/channels/`
83
- - WebSocket config: `api/config/cable.yml` and `api/config/anycable.yml`
84
-
85
- ### Background Jobs
86
- - **Sidekiq** for async job processing (`api/config/sidekiq.yml`)
87
- - **Clockwork** for scheduled jobs (`api/config/clock.rb`)
88
-
89
- ### Event Streaming
90
- - **Kafka** for event publishing/consumption
91
- - Services consume events via `services/consumers/`
92
- - Kafka config: `api/config/initializers/kafka.rb`
93
-
94
- ### Databases
95
- - **Primary PostgreSQL** - Main application data
96
- - **TimescaleDB** - Time-series data (separate connection in `database.yml`)
97
- - **MySQL** - Legacy/external integrations
98
- - **Redis** - Caching, ActionCable, Sidekiq
99
-
100
- ## Style Guidelines
101
-
102
- ### JavaScript/TypeScript
103
- - Use `test()` instead of `it()` in tests
104
- - Use `toBeCalled()` instead of `toHaveBeenCalledWith()` in jest assertions
105
-
106
- ## Key Configuration Files
107
-
108
- - `api/config/database.yml` - Database connections (primary + timescale)
109
- - `api/config/cable.yml` - AnyCable WebSocket config
110
- - `api/Procfile.dev` - Development processes (rails, anycable, sidekiq, clockwork)
111
- - `sol.code-workspace` - VS Code multi-folder workspace
112
- - Each project requires its own `.env` file (not in repo)
@@ -1,107 +0,0 @@
1
- # CLAUDE.md
2
-
3
- Guidance for Claude Code when working in this repository.
4
-
5
- ## Project Overview
6
-
7
- Sol is the **Rize** monorepo (automatic time tracking). Stack:
8
- - **api/** - Rails 7.1 GraphQL backend (Ruby 3.3.5)
9
- - **web/** - Next.js 14 React app (Node 22)
10
- - **electron/** - Electron desktop app (Node 22)
11
- - **services/** - Bun TypeScript event consumers/workers
12
- - **vanity/** - Webflow marketing scripts (deprecated)
13
- - **voyager/** - Marketing website (Next.js)
14
- - **puppet/** - Puppeteer server for images/PDFs
15
- - **chrome/** - Chrome extension
16
- - **docs/** - Docusaurus site
17
- - **zapier/** - Zapier integration
18
-
19
- ## Development Commands
20
-
21
- ### Start Dev Environment
22
- ```bash
23
- ./scripts/run-dev.sh # All services (requires iTerm2 on macOS)
24
-
25
- # Individually:
26
- cd api && hivemind Procfile.dev # Rails + AnyCable + Sidekiq + Clockwork
27
- cd web && npm run dev # Next.js (port 3001)
28
- cd electron && npm run dev # Electron with hot reload
29
- cd services && hivemind Procfile.dev # Bun services
30
- ```
31
-
32
- ### Docker (required before api/services)
33
- ```bash
34
- cd api && docker-compose up -d
35
- # TimescaleDB: localhost:15432 | Redis: localhost:16379
36
- # Kafka: localhost:9092 | MySQL: localhost:13306
37
- ```
38
-
39
- ### Testing
40
- ```bash
41
- # API (RSpec)
42
- cd api && bundle exec rspec
43
- cd api && bundle exec rspec spec/path/to/file_spec.rb
44
- cd api && bundle exec rspec spec/path/to/file_spec.rb:42
45
-
46
- # Electron (Jest)
47
- cd electron && npm test
48
- cd electron && npm run test:watch
49
- cd electron && npm run test:coverage
50
-
51
- # Web: no active tests (exits 0)
52
- ```
53
-
54
- ### Building
55
- ```bash
56
- cd api && bundle install && rake db:migrate
57
- cd web && npm run build # gql-gen + tailwind + next build
58
- cd electron && npm run build # Electron Forge make
59
- cd services && bun install
60
- ```
61
-
62
- ### GraphQL Code Generation
63
- - `cd web && npm run build` — includes gql codegen
64
- - `cd electron && npm run dev` — runs gql codegen automatically
65
-
66
- ## Architecture
67
-
68
- ### GraphQL API
69
- Two endpoints:
70
- - **api/v1** — Public API (OAuth, Zapier) → `api/app/graphql/api/v1/`
71
- - **private/v1** — Internal API (web, electron) → `api/app/graphql/private/v1/`
72
-
73
- ### Real-time
74
- - AnyCable WebSocket subscriptions
75
- - ActionCable channels: `api/app/channels/`
76
- - Config: `api/config/cable.yml`, `api/config/anycable.yml`
77
-
78
- ### Background Jobs
79
- - Sidekiq (async): `api/config/sidekiq.yml`
80
- - Clockwork (scheduled): `api/config/clock.rb`
81
-
82
- ### Event Streaming
83
- - Kafka publish/consume via `services/consumers/`
84
- - Config: `api/config/initializers/kafka.rb`
85
-
86
- ### Databases
87
- - **PostgreSQL** — primary app data
88
- - **TimescaleDB** — time-series (separate connection in `database.yml`)
89
- - **MySQL** — legacy integrations
90
- - **Redis** — caching, ActionCable, Sidekiq
91
-
92
- ## Style Guidelines
93
-
94
- ### JavaScript/TypeScript Tests
95
- - Use `test()` not `it()`
96
- - Use `toBeCalled()` not `toHaveBeenCalledWith()`
97
-
98
- ## Key Config Files
99
-
100
- | File | Purpose |
101
- |------|---------|
102
- | `api/config/database.yml` | DB connections (primary + timescale) |
103
- | `api/config/cable.yml` | AnyCable WebSocket config |
104
- | `api/Procfile.dev` | Dev processes (rails, anycable, sidekiq, clockwork) |
105
- | `sol.code-workspace` | VS Code multi-folder workspace |
106
-
107
- Each subproject needs its own `.env` file (not committed).
@@ -1,216 +0,0 @@
1
- ```markdown
2
- # CLAUDE.md
3
-
4
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
5
-
6
- ## Project Overview
7
-
8
- Sol is the monorepo for **Rize**, an automatic time tracking application. The stack consists of:
9
- - **api/** - Rails 7.1 GraphQL backend (Ruby 3.3.5)
10
- - **web/** - Next.js 14 React web app (Node 22)
11
- - **electron/** - Electron desktop app (Node 22)
12
- - **services/** - Bun-based TypeScript event consumers/workers
13
- - **vanity/** - Webflow marketing site scripts (deprecated)
14
- - **voyager/** - Marketing website for home and landing pages (Next.js)
15
- - **puppet/** - Puppeteer server for images/PDFs
16
- - **chrome/** - Chrome browser extension
17
- - **docs/** - Docusaurus documentation site
18
- - **zapier/** - Zapier integration
19
-
20
- ## Development Commands
21
-
22
- ### Starting Development Environment
23
- ```bash
24
- # Start all services (requires iTerm2 on macOS)
25
- ./scripts/run-dev.sh
26
-
27
- # Or start individually:
28
- cd api && hivemind Procfile.dev # Rails + AnyCable + Sidekiq + Clockwork
29
- cd web && npm run dev # Next.js dev server
30
- cd electron && npm run dev # Electron with hot reload
31
- cd services && hivemind Procfile.dev # Bun services
32
- ```
33
-
34
- ### Docker Dependencies (api/docker-compose.yml)
35
- ```bash
36
- cd api && docker-compose up -d
37
- # TimescaleDB: localhost:15432
38
- # Redis: localhost:16379
39
- # Kafka: localhost:9092
40
- # MySQL: localhost:13306
41
- ```
42
-
43
- ### Testing
44
- ```bash
45
- # API (RSpec)
46
- cd api && bundle exec rspec
47
- cd api && bundle exec rspec spec/path/to/file_spec.rb # Single file
48
- cd api && bundle exec rspec spec/path/to/file_spec.rb:42 # Single test at line
49
-
50
- # Electron (Jest)
51
- cd electron && npm test
52
- cd electron && npm run test:watch
53
- cd electron && npm run test:coverage
54
-
55
- # Web - no active tests (exits 0)
56
- ```
57
-
58
- ### Building
59
- ```bash
60
- cd api && bundle install && rake db:migrate
61
- cd web && npm run build # Runs gql-gen, tailwind, next build
62
- cd electron && npm run build # Electron Forge make
63
- cd services && bun install
64
- ```
65
-
66
- ### GraphQL Code Generation
67
- ```bash
68
- cd web && npm run build # Includes gql codegen
69
- cd electron && npm run dev # Runs gql codegen as part of dev
70
- ```
71
-
72
- ## Architecture
73
-
74
- ### GraphQL API Structure
75
- The API exposes two GraphQL endpoints:
76
- - **api/v1** - Public API (OAuth consumers, Zapier)
77
- - **private/v1** - Private API (web, electron apps)
78
-
79
- Located at `api/app/graphql/{api,private}/v1/`
80
-
81
- <example>
82
- # Adding a new mutation to the private API:
83
- # File: api/app/graphql/private/v1/mutations/update_something.rb
84
- module Private
85
- module V1
86
- module Mutations
87
- class UpdateSomething < BaseMutation
88
- argument :id, ID, required: true
89
- field :something, Types::SomethingType, null: true
90
-
91
- def resolve(id:)
92
- something = Something.find(id)
93
- something.update!(...)
94
- { something: something }
95
- end
96
- end
97
- end
98
- end
99
- end
100
- </example>
101
-
102
- ### Real-time Communication
103
- - **AnyCable** WebSocket server for subscriptions
104
- - ActionCable channels in `api/app/channels/`
105
- - WebSocket config: `api/config/cable.yml` and `api/config/anycable.yml`
106
-
107
- ### Background Jobs
108
- - **Sidekiq** for async job processing (`api/config/sidekiq.yml`)
109
- - **Clockwork** for scheduled jobs (`api/config/clock.rb`)
110
-
111
- <example>
112
- # Adding a new Sidekiq job:
113
- class MyWorker
114
- include Sidekiq::Worker
115
- sidekiq_options queue: :default
116
-
117
- def perform(user_id)
118
- user = User.find(user_id)
119
- # do work
120
- end
121
- end
122
-
123
- # Enqueue it:
124
- MyWorker.perform_async(user.id)
125
- </example>
126
-
127
- ### Event Streaming
128
- - **Kafka** for event publishing/consumption
129
- - Services consume events via `services/consumers/`
130
- - Kafka config: `api/config/initializers/kafka.rb`
131
-
132
- ### Databases
133
- - **Primary PostgreSQL** - Main application data
134
- - **TimescaleDB** - Time-series data (separate connection in `database.yml`)
135
- - **MySQL** - Legacy/external integrations
136
- - **Redis** - Caching, ActionCable, Sidekiq
137
-
138
- ## Style Guidelines
139
-
140
- ### JavaScript/TypeScript
141
-
142
- Use `test()` instead of `it()` in tests:
143
-
144
- <example>
145
- // CORRECT
146
- test('returns the user name', () => {
147
- expect(getUser().name).toBe('Alice')
148
- })
149
-
150
- // WRONG
151
- it('returns the user name', () => {
152
- expect(getUser().name).toBe('Alice')
153
- })
154
- </example>
155
-
156
- Use `toBeCalled()` instead of `toHaveBeenCalledWith()` in jest assertions:
157
-
158
- <example>
159
- // CORRECT
160
- expect(mockFn).toBeCalled()
161
-
162
- // WRONG
163
- expect(mockFn).toHaveBeenCalledWith(someArg)
164
- </example>
165
-
166
- ### Ruby/RSpec
167
-
168
- Use `be_between` for time assertions (no `freeze_time` or `travel_to` in this repo):
169
-
170
- <example>
171
- # CORRECT
172
- before = Time.current
173
- subject.call
174
- after = Time.current
175
- expect(record.updated_at).to be_between(before, after)
176
-
177
- # WRONG - freeze_time not available
178
- freeze_time do
179
- subject.call
180
- expect(record.updated_at).to eq(Time.current)
181
- end
182
- </example>
183
-
184
- Use `create(:user_with_default_workspace)` for a user with identity + workspace:
185
-
186
- <example>
187
- let(:user) { create(:user_with_default_workspace) }
188
- let(:identity) { user.identities.first }
189
- let(:workspace) { identity.workspaces.first }
190
- </example>
191
-
192
- Use `private_v1_execute_query` / `private_v1_execute_mutation` in GraphQL specs:
193
-
194
- <example>
195
- RSpec.describe 'someQuery', type: :request do
196
- let(:user) { create(:user_with_default_workspace) }
197
-
198
- it 'returns expected data' do
199
- private_v1_execute_query(
200
- query: SOME_QUERY,
201
- variables: { id: user.id },
202
- user: user
203
- )
204
- expect(response_data['someQuery']['field']).to eq('value')
205
- end
206
- end
207
- </example>
208
-
209
- ## Key Configuration Files
210
-
211
- - `api/config/database.yml` - Database connections (primary + timescale)
212
- - `api/config/cable.yml` - AnyCable WebSocket config
213
- - `api/Procfile.dev` - Development processes (rails, anycable, sidekiq, clockwork)
214
- - `sol.code-workspace` - VS Code multi-folder workspace
215
- - Each project requires its own `.env` file (not in repo)
216
- ```
@@ -1,83 +0,0 @@
1
- ```markdown
2
- # CLAUDE.md
3
-
4
- Sol is the monorepo for **Rize**, an automatic time tracking application.
5
-
6
- ## Stack
7
- - **api/** - Rails 7.1 GraphQL backend (Ruby 3.3.5)
8
- - **web/** - Next.js 14 React web app (Node 22)
9
- - **electron/** - Electron desktop app (Node 22)
10
- - **services/** - Bun-based TypeScript event consumers/workers
11
- - **voyager/** - Marketing website (Next.js)
12
- - **puppet/** - Puppeteer server for images/PDFs
13
- - **chrome/** - Chrome browser extension
14
- - **docs/** - Docusaurus documentation site
15
- - **zapier/** - Zapier integration
16
- - **vanity/** - Webflow scripts (deprecated)
17
-
18
- ## Development Commands
19
-
20
- ```bash
21
- # Start all (requires iTerm2)
22
- ./scripts/run-dev.sh
23
-
24
- # Individual services
25
- cd api && hivemind Procfile.dev # Rails + AnyCable + Sidekiq + Clockwork
26
- cd web && npm run dev # Next.js (port 3001)
27
- cd electron && npm run dev # Electron + gql codegen
28
- cd services && hivemind Procfile.dev # Bun consumers
29
-
30
- # Docker deps (TimescaleDB:15432, Redis:16379, Kafka:9092, MySQL:13306)
31
- cd api && docker-compose up -d
32
- ```
33
-
34
- ## Testing & Building
35
-
36
- ```bash
37
- # API (RSpec)
38
- cd api && bundle exec rspec
39
- cd api && bundle exec rspec spec/path/to/file_spec.rb:42
40
-
41
- # Electron (Jest)
42
- cd electron && npm test
43
-
44
- # Web - no active tests (exits 0)
45
-
46
- # Build
47
- cd api && bundle install && rake db:migrate
48
- cd web && npm run build # gql-gen + tailwind + next build
49
- cd electron && npm run build
50
- cd services && bun install
51
- ```
52
-
53
- ## Architecture
54
-
55
- ### GraphQL API
56
- Two endpoints at `api/app/graphql/{api,private}/v1/`:
57
- - **api/v1** - Public API (OAuth, Zapier)
58
- - **private/v1** - Private API (web, electron)
59
-
60
- ### Infrastructure
61
- - **AnyCable** WebSocket subscriptions (`api/config/cable.yml`, `anycable.yml`)
62
- - **Sidekiq** async jobs (`api/config/sidekiq.yml`)
63
- - **Clockwork** scheduled jobs (`api/config/clock.rb`)
64
- - **Kafka** event streaming (`api/config/initializers/kafka.rb`, `services/consumers/`)
65
-
66
- ### Databases
67
- - **PostgreSQL** - Primary app data
68
- - **TimescaleDB** - Time-series (separate connection in `database.yml`)
69
- - **MySQL** - Legacy integrations
70
- - **Redis** - Caching, ActionCable, Sidekiq
71
-
72
- ## Style Guidelines
73
-
74
- ### JavaScript/TypeScript
75
- - Use `test()` not `it()` in tests
76
- - Use `toBeCalled()` not `toHaveBeenCalledWith()` in Jest assertions
77
-
78
- ## Key Config Files
79
- - `api/config/database.yml` - DB connections
80
- - `api/Procfile.dev` - Dev processes
81
- - `sol.code-workspace` - VS Code workspace
82
- - Each project requires its own `.env` (not in repo)
83
- ```