@stackmemoryai/stackmemory 1.2.0 → 1.2.2

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 (47) hide show
  1. package/dist/src/cli/claude-sm.js +65 -0
  2. package/dist/src/cli/commands/skills.js +123 -1
  3. package/dist/src/hooks/graphiti-hooks.js +149 -0
  4. package/dist/src/hooks/session-summary.js +30 -0
  5. package/dist/src/integrations/graphiti/linear-graphiti-bridge.js +115 -0
  6. package/dist/src/integrations/greptile/client.js +101 -0
  7. package/dist/src/integrations/greptile/config.js +14 -0
  8. package/dist/src/integrations/greptile/index.js +11 -0
  9. package/dist/src/integrations/greptile/types.js +4 -0
  10. package/dist/src/integrations/linear/webhook.js +16 -0
  11. package/dist/src/integrations/mcp/handlers/greptile-handlers.js +456 -0
  12. package/dist/src/integrations/mcp/server.js +136 -0
  13. package/dist/src/integrations/mcp/tool-definitions.js +53 -1
  14. package/dist/src/skills/claude-skills.js +46 -1
  15. package/dist/src/skills/parallel-agent-skill.js +514 -0
  16. package/dist/src/utils/hook-installer.js +155 -0
  17. package/package.json +2 -2
  18. package/scripts/gepa/.before-optimize.md +140 -0
  19. package/scripts/gepa/config.json +7 -1
  20. package/scripts/gepa/evals/fixtures/api-endpoint.ts +31 -0
  21. package/scripts/gepa/evals/fixtures/brittle-integration.ts +38 -0
  22. package/scripts/gepa/evals/fixtures/fts5-triggers.sql +23 -0
  23. package/scripts/gepa/evals/fixtures/leaky-service.ts +70 -0
  24. package/scripts/gepa/evals/fixtures/mcp-dispatch-stub.ts +39 -0
  25. package/scripts/gepa/evals/fixtures/pr-diff.txt +24 -0
  26. package/scripts/gepa/evals/fixtures/unsafe-webhook.ts +34 -0
  27. package/scripts/gepa/evals/fixtures/unwrapped-db-op.ts +42 -0
  28. package/scripts/gepa/evals/stackmemory-tasks.jsonl +8 -0
  29. package/scripts/gepa/generations/gen-000/baseline.md +48 -0
  30. package/scripts/gepa/generations/gen-001/baseline.md +172 -0
  31. package/scripts/gepa/generations/gen-001/variant-a.md +176 -0
  32. package/scripts/gepa/generations/gen-001/variant-b.md +266 -0
  33. package/scripts/gepa/generations/gen-001/variant-c.md +142 -0
  34. package/scripts/gepa/generations/gen-001/variant-d.md +172 -0
  35. package/scripts/gepa/hooks/reflect.js +44 -5
  36. package/scripts/gepa/optimize.js +281 -39
  37. package/scripts/gepa/results/eval-1-baseline.json +218 -0
  38. package/scripts/gepa/results/eval-1-variant-a.json +218 -0
  39. package/scripts/gepa/results/eval-1-variant-b.json +218 -0
  40. package/scripts/gepa/results/eval-1-variant-c.json +198 -0
  41. package/scripts/gepa/results/eval-1-variant-d.json +198 -0
  42. package/scripts/gepa/state.json +44 -5
  43. package/scripts/install-claude-hooks-auto.js +176 -44
  44. package/templates/claude-hooks/auto-checkpoint.js +174 -0
  45. package/templates/claude-hooks/chime-on-stop.sh +22 -0
  46. package/templates/claude-hooks/session-rescue.sh +15 -0
  47. package/templates/claude-hooks/stop-checkpoint.js +120 -0
@@ -0,0 +1,142 @@
1
+ # StackMemory - Project Configuration
2
+
3
+ ## Project Structure
4
+
5
+ ```
6
+ src/
7
+ cli/ # CLI commands and entry point
8
+ core/ # Core business logic
9
+ context/ # Frame and context management
10
+ database/ # Database adapters (SQLite, ParadeDB)
11
+ digest/ # Digest generation
12
+ query/ # Query parsing and routing
13
+ integrations/ # External integrations (Linear, MCP)
14
+ services/ # Business services
15
+ skills/ # Claude Code skills
16
+ utils/ # Shared utilities
17
+ scripts/ # Build and utility scripts
18
+ config/ # Configuration files
19
+ docs/ # Documentation
20
+ ```
21
+
22
+ ## Key Files
23
+
24
+ - Entry: src/cli/index.ts
25
+ - MCP Server: src/integrations/mcp/server.ts
26
+ - Frame Manager: src/core/context/frame-manager.ts
27
+ - Database: src/core/database/sqlite-adapter.ts
28
+
29
+ ## Documentation
30
+
31
+ Quick reference (agent_docs/): linear_integration.md | mcp_server.md | database_storage.md | claude_hooks.md
32
+
33
+ Full docs (docs/): principles.md | architecture.md | SPEC.md | API_REFERENCE.md | DEVELOPMENT.md | SETUP.md
34
+
35
+ ## Commands
36
+
37
+ ```bash
38
+ npm run build|lint|lint:fix|test|test:run|linear:sync
39
+ stackmemory capture|restore # Session state handoff
40
+ ```
41
+
42
+ ## Working Directory
43
+
44
+ PRIMARY: /Users/jwu/Dev/stackmemory | ALLOWED: All subdirectories | TEMP: /tmp
45
+
46
+ ## Validation (MUST DO)
47
+
48
+ After code changes:
49
+ 1. `npm run lint` - fix errors AND warnings
50
+ 2. `npm run test:run` - verify no regressions
51
+ 3. `npm run build` - ensure compilation
52
+ 4. Run code to verify it works
53
+
54
+ Test coverage:
55
+ - New features require tests in `src/**/__tests__/`
56
+ - Maintain or improve coverage (no untested code paths)
57
+ - Critical paths: context management, handoff, Linear sync
58
+
59
+ Never: Assume success | Skip testing | Use mock data as fallback
60
+
61
+ ## Git Rules (CRITICAL)
62
+
63
+ - NEVER use `--no-verify` on commit/push
64
+ - ALWAYS fix lint/test errors before pushing
65
+ - Run `npm run lint && npm run test:run` before pushing
66
+ - Commit format: `type(scope): message`
67
+ - Branch naming: `feature/STA-XXX-desc` | `fix/STA-XXX-desc` | `chore/desc`
68
+
69
+ ## Security
70
+
71
+ NEVER hardcode secrets - use process.env with dotenv/config
72
+
73
+ ```javascript
74
+ import 'dotenv/config';
75
+ const API_KEY = process.env.LINEAR_API_KEY;
76
+ if (!API_KEY) {
77
+ console.error('LINEAR_API_KEY not set');
78
+ process.exit(1);
79
+ }
80
+ ```
81
+
82
+ Environment sources (check in order): .env | .env.local | ~/.zshrc | process.env
83
+
84
+ Secret patterns to block: lin_api_* | lin_oauth_* | sk-* | npm_*
85
+
86
+ ## Deploy
87
+
88
+ ```bash
89
+ # npm publish (uses NPM_TOKEN from .env)
90
+ git stash -- scripts/gepa/
91
+ NPM_TOKEN=$(grep '^NPM_TOKEN=' .env | cut -d= -f2) \
92
+ npm publish --registry https://registry.npmjs.org/ \
93
+ --//registry.npmjs.org/:_authToken="$NPM_TOKEN"
94
+ git stash pop
95
+
96
+ # Railway
97
+ railway up
98
+
99
+ # Pre-publish requires clean git — stash GEPA files first
100
+ ```
101
+
102
+ ## Task Delegation Model
103
+
104
+ Route effort by complexity:
105
+
106
+ **AUTOMATE** — Execute immediately, lint+test sufficient:
107
+ - CRUD, boilerplate, formatting, simple transforms
108
+ - Tool handler following existing pattern
109
+ - Config additions (env var, feature flag)
110
+
111
+ **STANDARD** — Normal workflow, lint+test+build:
112
+ - Features, bug fixes, refactoring
113
+ - Tests, docs, integration wiring
114
+
115
+ **CAREFUL** — Review approach before implementation:
116
+ - API/schema changes, migrations, auth flows
117
+ - New integration patterns (MCP, webhooks)
118
+ - Changes to frame-manager, sqlite-adapter, daemon lifecycle
119
+ - Error handling chains
120
+
121
+ **ARCHITECT** — Plan mode required, explore patterns first:
122
+ - New service boundaries, system integrations
123
+ - Performance-critical paths (FTS5, search scoring)
124
+ - Breaking changes to MCP protocol or CLI
125
+
126
+ **HUMAN** — Explicit approval required:
127
+ - Security decisions, secret handling
128
+ - Irreversible operations (migrations, schema drops)
129
+ - Publishing (npm, Railway)
130
+
131
+ Quality gates scale with tier — don't over-engineer AUTOMATE, don't under-review CAREFUL.
132
+
133
+ ## Workflow
134
+
135
+ - Check .env for API keys before asking
136
+ - Run npm run linear:sync after task completion
137
+ - Use browser MCP for visual testing
138
+ - Review recent commits and stackmemory.json on session start
139
+ - Use TodoWrite for 3+ steps or multiple requests
140
+ - Keep one task in_progress at a time
141
+ - Update task status immediately on completion
142
+ - Ask 1-3 clarifying questions for complex commands (one at a time)
@@ -0,0 +1,172 @@
1
+ # StackMemory - Project Configuration
2
+
3
+ ## Overview
4
+
5
+ StackMemory is an agent programming platform with CLI, MCP server, and Linear integration.
6
+
7
+ **Primary**: /Users/jwu/Dev/stackmemory
8
+ **Tech**: TypeScript, Node.js, SQLite, Vitest, ESLint, esbuild
9
+
10
+ ## Architecture
11
+
12
+ ```
13
+ src/
14
+ cli/ # CLI entry (index.ts)
15
+ core/ # Business logic
16
+ context/ # Frame management (frame-manager.ts)
17
+ database/ # Storage adapters (sqlite-adapter.ts)
18
+ digest/ # Digest generation
19
+ query/ # Query routing
20
+ integrations/ # Linear, MCP (mcp/server.ts)
21
+ services/ # Business services
22
+ skills/ # Claude Code skills
23
+ utils/ # Shared utilities
24
+ ```
25
+
26
+ ## Documentation
27
+
28
+ **Quick reference** (agent_docs/):
29
+ - linear_integration.md
30
+ - mcp_server.md
31
+ - database_storage.md
32
+ - claude_hooks.md
33
+
34
+ **Full docs** (docs/):
35
+ - principles.md - Agent paradigm
36
+ - architecture.md - Extension model
37
+ - SPEC.md - Technical spec
38
+ - API_REFERENCE.md
39
+ - DEVELOPMENT.md
40
+ - SETUP.md
41
+
42
+ ## Commands
43
+
44
+ ```bash
45
+ # Build & Quality
46
+ npm run build # Compile (esbuild)
47
+ npm run lint # Check
48
+ npm run lint:fix # Auto-fix
49
+ npm test # Watch mode
50
+ npm run test:run # Run once
51
+
52
+ # Integration
53
+ npm run linear:sync # Sync Linear
54
+
55
+ # CLI
56
+ stackmemory capture # Save session state
57
+ stackmemory restore # Restore session
58
+ ```
59
+
60
+ ## Validation Checklist
61
+
62
+ After EVERY code change:
63
+
64
+ 1. **Lint**: `npm run lint` - fix ALL errors AND warnings
65
+ 2. **Test**: `npm run test:run` - verify no regressions
66
+ 3. **Build**: `npm run build` - ensure compilation
67
+ 4. **Run**: Execute code to verify functionality
68
+
69
+ **Test coverage**:
70
+ - New features require tests in `src/**/__tests__/`
71
+ - Maintain or improve coverage (no untested paths)
72
+ - Critical: context management, handoff, Linear sync
73
+
74
+ **Never**: Assume success | Skip testing | Use mock fallbacks
75
+
76
+ ## Git Workflow
77
+
78
+ **Commit format**: `type(scope): message`
79
+ **Branch naming**: `feature/STA-XXX-desc` | `fix/STA-XXX-desc` | `chore/desc`
80
+
81
+ **Critical rules**:
82
+ - NEVER use `--no-verify` on commit/push
83
+ - ALWAYS fix lint/test errors before pushing
84
+ - Run `npm run lint && npm run test:run` before pushing
85
+ - If pre-push hooks fail, fix the underlying issue
86
+
87
+ ## Task Delegation Model
88
+
89
+ Route effort by complexity:
90
+
91
+ ### AUTOMATE
92
+ Execute immediately, lint+test is sufficient:
93
+ - CRUD, boilerplate, formatting, simple transforms
94
+ - Tool handler following existing switch/case
95
+ - Config additions (env var, feature flag)
96
+
97
+ ### STANDARD
98
+ Normal workflow, lint+test+build:
99
+ - Features, bug fixes, refactoring
100
+ - Test coverage, documentation
101
+ - Integration wiring (server.ts dispatch)
102
+
103
+ ### CAREFUL
104
+ Review approach before implementation:
105
+ - API/schema changes, database migrations, auth
106
+ - New integration patterns (MCP tools, webhooks)
107
+ - Changes to frame-manager, sqlite-adapter, daemon lifecycle
108
+ - Error handling chains
109
+
110
+ ### ARCHITECT
111
+ Plan mode required, explore patterns first:
112
+ - New service boundaries, system integrations
113
+ - Performance-critical (FTS5 queries, search scoring)
114
+ - Breaking changes (MCP protocol, CLI interface)
115
+
116
+ ### HUMAN
117
+ Explicit approval before changes:
118
+ - Security decisions, secret handling
119
+ - Irreversible operations (migrations, schema drops)
120
+ - Publishing (npm, Railway)
121
+
122
+ ## Security
123
+
124
+ **NEVER hardcode secrets** - use process.env with dotenv/config:
125
+
126
+ ```javascript
127
+ import 'dotenv/config';
128
+ const API_KEY = process.env.LINEAR_API_KEY;
129
+ if (!API_KEY) {
130
+ console.error('LINEAR_API_KEY not set');
131
+ process.exit(1);
132
+ }
133
+ ```
134
+
135
+ **Env sources** (check in order):
136
+ 1. .env file
137
+ 2. .env.local
138
+ 3. ~/.zshrc
139
+ 4. Process environment
140
+
141
+ **Block patterns**: lin_api_* | lin_oauth_* | sk-* | npm_*
142
+
143
+ ## Deployment
144
+
145
+ ```bash
146
+ # npm publish (uses NPM_TOKEN from .env, no OTP)
147
+ git stash -- scripts/gepa/ # stash GEPA state
148
+ NPM_TOKEN=$(grep '^NPM_TOKEN=' .env | cut -d= -f2) \
149
+ npm publish --registry https://registry.npmjs.org/ \
150
+ --//registry.npmjs.org/:_authToken="$NPM_TOKEN"
151
+ git stash pop # restore GEPA state
152
+
153
+ # Railway
154
+ railway up
155
+
156
+ # Note: Pre-publish checks require clean git status
157
+ ```
158
+
159
+ ## Task Management
160
+
161
+ - Use TodoWrite for 3+ steps or multiple requests
162
+ - Keep one task in_progress at a time
163
+ - Update status immediately on completion
164
+
165
+ ## Workflow Tips
166
+
167
+ - Check .env for API keys before asking
168
+ - Run `npm run linear:sync` after task completion
169
+ - Use browser MCP for visual testing
170
+ - Review recent commits and stackmemory.json on session start
171
+ - Use subagents for multi-step tasks
172
+ - Ask 1-3 clarifying questions for complex commands (one at a time)
@@ -9,9 +9,51 @@
9
9
  import fs from 'fs';
10
10
  import path from 'path';
11
11
  import { fileURLToPath } from 'url';
12
- import { execSync } from 'child_process';
12
+ import { spawn } from 'child_process';
13
13
 
14
14
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
15
+ const PROJECT_ROOT = path.resolve(__dirname, '../../..');
16
+
17
+ // Load .env from project root
18
+ const envPath = path.join(PROJECT_ROOT, '.env');
19
+ if (fs.existsSync(envPath)) {
20
+ for (const line of fs.readFileSync(envPath, 'utf8').split('\n')) {
21
+ const match = line.match(/^([A-Z_][A-Z0-9_]*)=(.*)$/);
22
+ if (match && !process.env[match[1]]) {
23
+ process.env[match[1]] = match[2].replace(/^["']|["']$/g, '');
24
+ }
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Call Claude CLI via spawn (stdin pipe, no shell interpolation)
30
+ */
31
+ function spawnClaude(prompt) {
32
+ return new Promise((resolve, reject) => {
33
+ const child = spawn('claude', ['--print'], {
34
+ stdio: ['pipe', 'pipe', 'pipe'],
35
+ env: { ...process.env },
36
+ });
37
+
38
+ let stdout = '';
39
+ let stderr = '';
40
+
41
+ child.stdout.on('data', (d) => (stdout += d));
42
+ child.stderr.on('data', (d) => (stderr += d));
43
+
44
+ child.on('close', (code) => {
45
+ if (code !== 0 && !stdout)
46
+ return reject(new Error(stderr || `claude exited ${code}`));
47
+ resolve(stdout);
48
+ });
49
+
50
+ child.on('error', reject);
51
+
52
+ child.stdin.write(prompt);
53
+ child.stdin.end();
54
+ });
55
+ }
56
+
15
57
  const GEPA_DIR = path.join(__dirname, '..');
16
58
  const RESULTS_DIR = path.join(GEPA_DIR, 'results');
17
59
  const GENERATIONS_DIR = path.join(GEPA_DIR, 'generations');
@@ -212,10 +254,7 @@ Format as JSON:
212
254
  }`;
213
255
 
214
256
  try {
215
- const result = execSync(
216
- `echo ${JSON.stringify(reflectionPrompt)} | claude --print`,
217
- { encoding: 'utf8', maxBuffer: 10 * 1024 * 1024 }
218
- );
257
+ const result = await spawnClaude(reflectionPrompt);
219
258
 
220
259
  // Parse JSON from response
221
260
  const jsonMatch = result.match(/\{[\s\S]*\}/);