Skip to content

Commit d885cfb

Browse files
author
StackMemory Bot (CLI)
committed
chore: handoff checkpoint on main
1 parent 26b0880 commit d885cfb

19 files changed

Lines changed: 2023 additions & 44 deletions

File tree

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,38 @@ Frames can span:
9797

9898
Runs as an MCP server. Editors (e.g., Claude Code) call StackMemory on each interaction to fetch a compiled context bundle; editors don’t store memory themselves.
9999

100+
### MCP Quick Usage
101+
102+
Use these JSON snippets with Claude Code’s MCP “tools/call”. Responses are returned as a single text item containing JSON.
103+
104+
- Plan only (no code):
105+
```json
106+
{"method":"tools/call","params":{"name":"plan_only","arguments":{"task":"Refactor config loader","plannerModel":"claude-3-5-sonnet-latest"}}}
107+
```
108+
109+
- Approval‑gated plan (phase 1):
110+
```json
111+
{"method":"tools/call","params":{"name":"plan_gate","arguments":{"task":"Refactor config loader","compact":true}}}
112+
```
113+
114+
- Approve + execute (phase 2):
115+
```json
116+
{"method":"tools/call","params":{"name":"approve_plan","arguments":{"approvalId":"<copy from plan_gate>","implementer":"codex","execute":true,"recordFrame":true,"compact":true}}}
117+
```
118+
119+
- Manage approvals:
120+
```json
121+
{"method":"tools/call","params":{"name":"pending_list","arguments":{}}}
122+
{"method":"tools/call","params":{"name":"pending_show","arguments":{"approvalId":"<id>","compact":true}}}
123+
{"method":"tools/call","params":{"name":"pending_clear","arguments":{"approvalId":"<id>"}}}
124+
```
125+
126+
Env defaults (optional):
127+
- `STACKMEMORY_MM_PLANNER_MODEL` (e.g., `claude-3-5-sonnet-latest` or `claude-3-opus-latest`)
128+
- `STACKMEMORY_MM_REVIEWER_MODEL` (defaults to planner if unset)
129+
- `STACKMEMORY_MM_IMPLEMENTER` (`codex` or `claude`)
130+
- `STACKMEMORY_MM_MAX_ITERS` (e.g., `2`)
131+
100132
---
101133

102134
## Quick Start
@@ -386,5 +418,6 @@ See https://github.com/stackmemoryai/stackmemory/blob/main/docs/roadmap.md for o
386418
- [Product Requirements](./PRD.md) - Detailed product specifications
387419
- [Technical Architecture](./TECHNICAL_ARCHITECTURE.md) - System design and database schemas
388420
- [Beads Integration](./BEADS_INTEGRATION.md) - Git-native memory patterns from Beads ecosystem
421+
- [MCP: plan_and_code](https://github.com/stackmemoryai/stackmemory/blob/main/docs/mcp.md) - Trigger planning + coding via MCP with JSON results
389422

390423
---

docs/SETUP.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,47 @@ stackmemory init --chromadb
6262
| `linear_update_task` | Update Linear issue |
6363
| `linear_get_tasks` | Get tasks from Linear |
6464

65+
### Quick: plan_and_code (planning + coding)
66+
67+
- Trigger a full plan → implement → critique loop and get a single JSON result.
68+
- Tool: `plan_and_code`
69+
- Args:
70+
- `task`: short description
71+
- `implementer`: `codex` (default) or `claude`
72+
- `maxIters`: retries (default 2)
73+
- `execute`: true to actually call the implementer (otherwise dry‑run)
74+
- `record`: write plan/critique to simple context
75+
- `recordFrame`: write a real frame + anchors
76+
- Env defaults: `STACKMEMORY_MM_PLANNER_MODEL`, `STACKMEMORY_MM_REVIEWER_MODEL`, `STACKMEMORY_MM_IMPLEMENTER`, `STACKMEMORY_MM_MAX_ITERS`
77+
78+
Example request (tools/call):
79+
80+
```json
81+
{
82+
"method": "tools/call",
83+
"params": {
84+
"name": "plan_and_code",
85+
"arguments": {
86+
"task": "Refactor config loader into provider pattern",
87+
"implementer": "codex",
88+
"maxIters": 2,
89+
"execute": true,
90+
"recordFrame": true
91+
}
92+
}
93+
}
94+
```
95+
96+
CLI equivalents for quick checks:
97+
98+
```bash
99+
# Quiet JSON (UI-friendly)
100+
stackmemory mm-spike --task "Refactor config loader" --json
101+
102+
# Execute implementer and record as frame
103+
stackmemory skills spike --task "Refactor" --execute --max-iters 3 --json --record-frame
104+
```
105+
65106
## Open-Source Local Mode
66107

67108
### Step 1: Clone & Build

docs/mcp.md

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# MCP: plan_and_code Tool
2+
3+
The `plan_and_code` MCP tool lets Claude Code trigger StackMemory’s multi‑agent flow silently and receive a single JSON result. It plans with Claude, implements with Codex or Claude, and critiques the result — with optional retry loops and context recording.
4+
5+
## What it does
6+
- Planner (Claude): generates a concise plan with acceptance criteria and risks.
7+
- Implementer (Codex/Claude): applies a focused change per step.
8+
- Critic (Claude): returns `{ approved, issues[], suggestions[] }` to gate retries.
9+
- Returns a single JSON payload: `{ plan, implementation, critique, iterations[] }`.
10+
11+
## Tool definition
12+
- name: `plan_and_code`
13+
- arguments:
14+
- `task` (string, required): short task description
15+
- `implementer` ("codex" | "claude", default: `codex`)
16+
- `maxIters` (number, default: `2`): retry loop iterations
17+
- `execute` (boolean, default: `false`): if `false`, implementer is dry‑run
18+
- `record` (boolean, default: `false`): write plan/critique as simple context rows
19+
- `recordFrame` (boolean, default: `false`): write a real frame + anchors
20+
21+
## Environment defaults
22+
If not specified in arguments, the MCP handler reads these env vars:
23+
- `STACKMEMORY_MM_PLANNER_MODEL` (e.g., `claude-3-5-sonnet-latest`)
24+
- `STACKMEMORY_MM_REVIEWER_MODEL` (defaults to planner model if unset)
25+
- `STACKMEMORY_MM_IMPLEMENTER` (`codex` or `claude`)
26+
- `STACKMEMORY_MM_MAX_ITERS` (e.g., `3`)
27+
28+
## Example (MCP request)
29+
```json
30+
{
31+
"method": "tools/call",
32+
"params": {
33+
"name": "plan_and_code",
34+
"arguments": {
35+
"task": "Refactor config loader into provider pattern",
36+
"implementer": "codex",
37+
"maxIters": 2,
38+
"execute": true,
39+
"recordFrame": true
40+
}
41+
}
42+
}
43+
```
44+
45+
Response content is a single `text` item containing a JSON string:
46+
```json
47+
{
48+
"ok": true,
49+
"result": {
50+
"plan": { "summary": "...", "steps": [ ... ], "risks": [ ... ] },
51+
"implementation": { "success": true, "summary": "...", "commands": [ ... ] },
52+
"critique": { "approved": true, "issues": [], "suggestions": [] },
53+
"iterations": [
54+
{ "command": "...", "ok": true, "outputPreview": "...", "critique": { ... } }
55+
]
56+
}
57+
}
58+
```
59+
60+
## Recording behavior
61+
- `record: true` writes two entries into `.stackmemory/context.db` (simple `contexts` table):
62+
- `Plan: <summary>` (importance 0.8)
63+
- `Critique: approved|needs_changes` (importance 0.6)
64+
- `recordFrame: true` writes a real frame + anchors using the FrameManager:
65+
- Frame: `Plan & Code: <task>`
66+
- Anchors: `DECISION` (plan summary), `FACT` (commands), `RISK` (first few issues), `TODO` (first few suggestions)
67+
- Closes the frame with `{ approved: true|false }`
68+
- Both modes are best‑effort. If the DB isn’t ready, handler returns JSON without failing.
69+
70+
## Notes
71+
- Implementer `codex` calls `codex-sm` (must be on PATH). Use `--execute` in CLI, or `execute: true` in MCP, to actually run it; otherwise it’s a dry‑run.
72+
- Audit files are saved to `.stackmemory/mm-spike/spike-<timestamp>.json` to support review/debugging.
73+
- You can compare models:
74+
- Planner/critic: override with `STACKMEMORY_MM_PLANNER_MODEL` / `STACKMEMORY_MM_REVIEWER_MODEL`.
75+
- Implementer: set to `claude` to A/B against Codex, or keep `codex` (default).
76+
77+
## CLI equivalents (for quick checks)
78+
- Quiet JSON output:
79+
- `stackmemory mm-spike --task "Refactor config loader" --json`
80+
- `stackmemory skills spike --task "Refactor config loader" --json`
81+
- Execute implementer and record as frame:
82+
- `stackmemory skills spike --task "Refactor" --execute --max-iters 3 --json --record-frame`
83+
84+
---
85+
86+
## Approval‑Gated Flow (plan_gate → approve_plan)
87+
88+
Use this two‑phase flow when you want the plan reviewed before any code runs.
89+
90+
### Phase 1: plan_gate
91+
92+
Request (tools/call):
93+
94+
```json
95+
{
96+
"method": "tools/call",
97+
"params": {
98+
"name": "plan_gate",
99+
"arguments": {
100+
"task": "Refactor config loader into provider pattern",
101+
"plannerModel": "claude-3-5-sonnet-latest"
102+
}
103+
}
104+
}
105+
```
106+
107+
Response (content[0].text is a JSON string):
108+
109+
```json
110+
{
111+
"ok": true,
112+
"approvalId": "appr_1738612345678_ab12cd",
113+
"plan": { "summary": "...", "steps": [ ... ], "risks": [ ... ] }
114+
}
115+
```
116+
117+
Render `plan` for review; store `approvalId` for Phase 2.
118+
119+
### Phase 2: approve_plan
120+
121+
Request (tools/call):
122+
123+
```json
124+
{
125+
"method": "tools/call",
126+
"params": {
127+
"name": "approve_plan",
128+
"arguments": {
129+
"approvalId": "appr_1738612345678_ab12cd",
130+
"implementer": "codex",
131+
"maxIters": 2,
132+
"execute": true,
133+
"recordFrame": true
134+
}
135+
}
136+
}
137+
```
138+
139+
Response (content[0].text is a JSON string):
140+
141+
```json
142+
{
143+
"ok": true,
144+
"approvalId": "appr_1738612345678_ab12cd",
145+
"result": {
146+
"plan": { ... },
147+
"implementation": { "success": true, "commands": [ ... ] },
148+
"critique": { "approved": true, "issues": [], "suggestions": [] },
149+
"iterations": [ { "command": "...", "ok": true, "critique": { ... } } ]
150+
}
151+
}
152+
```
153+
154+
Notes:
155+
- `recordFrame: true` creates a real StackMemory frame + anchors (plan summary, commands, issues, suggestions).
156+
- `execute: true` actually invokes the implementer; otherwise it’s a dry‑run.
157+
- Approval IDs are persisted to `.stackmemory/mm-spike/pending.json` so editor restarts don’t lose pending approvals.
158+
159+
### Optional helper tools
160+
- `plan_only`: Returns a plan JSON without running code.
161+
- `call_claude`: Calls Claude directly (prompt/model/system).
162+
- `call_codex`: Calls Codex via `codex-sm` (prompt/args/execute).
163+
- `pending_list`: Lists pending approval-gated plans with `approvalId`, `task`, and `createdAt`. Supports optional filters:
164+
- `{ taskContains: "refactor", sort: "desc", limit: 10 }`
165+
- `{ olderThanMs: 3600000 }` (older than 1 hour)
166+
- `{ newerThanMs: 600000 }` (newer than 10 minutes)
167+
- `pending_clear`: Clears pending approvals. Args: `{ approvalId }`, or `{ all: true }`, or `{ olderThanMs: <ms> }`.
168+
- `pending_show`: Returns a stored pending plan by `{ approvalId }`.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@
8787
"sync:start": "node scripts/background-sync-manager.js",
8888
"sync:setup": "./scripts/setup-background-sync.sh",
8989
"prepare": "echo 'Prepare step completed'",
90-
"verify:dist": "node scripts/verify-dist.cjs"
90+
"verify:dist": "node scripts/verify-dist.cjs",
91+
"rebuild:native": "npm rebuild better-sqlite3 || true",
92+
"deps:reset": "rm -rf node_modules package-lock.json && npm ci"
9193
},
9294
"dependencies": {
9395
"@anthropic-ai/sdk": "^0.71.2",

scripts/demos/ralph-integration-demo.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
*/
66

77
import { RalphStackMemoryBridge } from './bridge/ralph-stackmemory-bridge.js';
8-
import { logger } from '../../core/monitoring/logger.js';
98
import { RalphStackMemoryConfig } from './types.js';
109

1110
class RalphIntegrationDemo {
@@ -60,9 +59,12 @@ class RalphIntegrationDemo {
6059
await this.demonstrateMetrics();
6160

6261
console.log('\n✅ Demo completed successfully!\n');
63-
} catch (error: any) {
64-
console.error('\n❌ Demo failed:', error.message);
65-
throw error;
62+
} catch (err: unknown) {
63+
console.error(
64+
'\n❌ Demo failed:',
65+
err instanceof Error ? err.message : err
66+
);
67+
throw err;
6668
} finally {
6769
await this.cleanup();
6870
}
@@ -158,9 +160,6 @@ class RalphIntegrationDemo {
158160
console.log('\n🚑 Phase 3: Crash Recovery');
159161
console.log('===========================');
160162

161-
// Simulate getting session ID
162-
const sessionId = 'demo-session-123';
163-
164163
try {
165164
console.log('🔄 Simulating session rehydration...');
166165

@@ -177,8 +176,10 @@ class RalphIntegrationDemo {
177176
console.log(' - State reconciled: 0.3s');
178177
console.log(' - Memory usage: 45MB');
179178
console.log(' - Cache hit rate: 78%');
180-
} catch (error: any) {
181-
console.log(`⚠️ Recovery simulation: ${error.message}`);
179+
} catch (err: unknown) {
180+
console.log(
181+
`⚠️ Recovery simulation: ${err instanceof Error ? err.message : err}`
182+
);
182183
}
183184
}
184185

@@ -227,10 +228,10 @@ async function main() {
227228

228229
try {
229230
await demo.run();
230-
} catch (error: any) {
231-
console.error('Demo failed:', error.message);
232-
if (process.env.DEBUG) {
233-
console.error(error.stack);
231+
} catch (err: unknown) {
232+
console.error('Demo failed:', err instanceof Error ? err.message : err);
233+
if (process.env.DEBUG && err instanceof Error) {
234+
console.error(err.stack);
234235
}
235236
process.exit(1);
236237
}

0 commit comments

Comments
 (0)