@stackmemoryai/stackmemory 0.3.17 → 0.3.18
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.
- package/dist/cli/commands/skills.js +15 -2
- package/dist/cli/commands/skills.js.map +2 -2
- package/dist/cli/index.js +113 -834
- package/dist/cli/index.js.map +3 -3
- package/dist/core/context/dual-stack-manager.js +1 -1
- package/dist/core/context/dual-stack-manager.js.map +1 -1
- package/dist/core/context/frame-manager.js +3 -0
- package/dist/core/context/frame-manager.js.map +2 -2
- package/dist/integrations/claude-code/subagent-client.js +106 -3
- package/dist/integrations/claude-code/subagent-client.js.map +2 -2
- package/dist/servers/railway/config.js +51 -0
- package/dist/servers/railway/config.js.map +7 -0
- package/dist/servers/railway/index-enhanced.js +156 -0
- package/dist/servers/railway/index-enhanced.js.map +7 -0
- package/dist/servers/railway/minimal.js +48 -3
- package/dist/servers/railway/minimal.js.map +2 -2
- package/dist/servers/railway/storage-test.js +455 -0
- package/dist/servers/railway/storage-test.js.map +7 -0
- package/dist/skills/claude-skills.js +13 -12
- package/dist/skills/claude-skills.js.map +2 -2
- package/dist/skills/recursive-agent-orchestrator.js +27 -18
- package/dist/skills/recursive-agent-orchestrator.js.map +2 -2
- package/dist/skills/unified-rlm-orchestrator.js.map +2 -2
- package/package.json +6 -18
- package/scripts/README-TESTING.md +186 -0
- package/scripts/analyze-cli-security.js +288 -0
- package/scripts/archive/add-phase-tasks-to-linear.js +163 -0
- package/scripts/archive/analyze-linear-duplicates.js +214 -0
- package/scripts/archive/analyze-remaining-duplicates.js +230 -0
- package/scripts/archive/analyze-sta-duplicates.js +292 -0
- package/scripts/archive/analyze-sta-graphql.js +399 -0
- package/scripts/archive/cancel-duplicate-tasks.ts +246 -0
- package/scripts/archive/check-all-duplicates.ts +419 -0
- package/scripts/archive/clean-duplicate-tasks.js +114 -0
- package/scripts/archive/cleanup-duplicate-tasks.ts +286 -0
- package/scripts/archive/create-phase-tasks.js +387 -0
- package/scripts/archive/delete-linear-duplicates.js +182 -0
- package/scripts/archive/delete-remaining-duplicates.js +158 -0
- package/scripts/archive/delete-sta-duplicates.js +201 -0
- package/scripts/archive/delete-sta-oauth.js +201 -0
- package/scripts/archive/export-sta-tasks.js +62 -0
- package/scripts/archive/install-auto-sync.js +266 -0
- package/scripts/archive/install-chromadb-hooks.sh +133 -0
- package/scripts/archive/install-enhanced-clear-hooks.sh +431 -0
- package/scripts/archive/install-post-task-hooks.sh +289 -0
- package/scripts/archive/install-stackmemory-hooks.sh +420 -0
- package/scripts/archive/merge-linear-duplicates-safe.ts +362 -0
- package/scripts/archive/merge-linear-duplicates.ts +180 -0
- package/scripts/archive/remove-sta-tasks.js +70 -0
- package/scripts/archive/setup-background-sync.sh +168 -0
- package/scripts/archive/setup-claude-auto-triggers.sh +181 -0
- package/scripts/archive/setup-claude-autostart.sh +305 -0
- package/scripts/archive/setup-git-hooks.sh +25 -0
- package/scripts/archive/setup-linear-oauth.sh +46 -0
- package/scripts/archive/setup-mcp.sh +113 -0
- package/scripts/archive/setup-railway-deployment.sh +81 -0
- package/scripts/auto-handoff.sh +262 -0
- package/scripts/background-sync-manager.js +416 -0
- package/scripts/benchmark-performance.ts +57 -0
- package/scripts/check-redis.ts +48 -0
- package/scripts/chromadb-auto-loader.sh +128 -0
- package/scripts/chromadb-context-loader.js +479 -0
- package/scripts/claude-chromadb-hook.js +460 -0
- package/scripts/claude-code-wrapper.sh +66 -0
- package/scripts/claude-linear-skill.js +455 -0
- package/scripts/claude-pre-commit.sh +302 -0
- package/scripts/claude-sm-autostart.js +532 -0
- package/scripts/claude-sm-setup.sh +367 -0
- package/scripts/claude-with-chromadb.sh +69 -0
- package/scripts/claude-worktree-manager.sh +323 -0
- package/scripts/claude-worktree-monitor.sh +371 -0
- package/scripts/claude-worktree-setup.sh +327 -0
- package/scripts/clean-linear-backlog.js +273 -0
- package/scripts/cleanup-old-sessions.sh +57 -0
- package/scripts/codex-wrapper.sh +88 -0
- package/scripts/create-sandbox.sh +269 -0
- package/scripts/debug-linear-update.js +174 -0
- package/scripts/delete-linear-tasks.js +167 -0
- package/scripts/deploy.sh +89 -0
- package/scripts/deployment/railway.sh +352 -0
- package/scripts/deployment/test-deployment.js +194 -0
- package/scripts/detect-and-rehydrate.js +162 -0
- package/scripts/detect-and-rehydrate.mjs +165 -0
- package/scripts/development/create-demo-tasks.js +143 -0
- package/scripts/development/debug-frame-test.js +16 -0
- package/scripts/development/demo-auto-sync.js +128 -0
- package/scripts/development/fix-all-imports.js +213 -0
- package/scripts/development/fix-imports.js +229 -0
- package/scripts/development/fix-lint-loop.cjs +103 -0
- package/scripts/development/fix-project-id.ts +161 -0
- package/scripts/development/fix-strict-mode-issues.ts +291 -0
- package/scripts/development/reorganize-structure.sh +228 -0
- package/scripts/development/test-persistence-direct.js +148 -0
- package/scripts/development/test-persistence.js +114 -0
- package/scripts/development/test-tasks.js +93 -0
- package/scripts/development/update-imports.js +212 -0
- package/scripts/fetch-linear-status.js +125 -0
- package/scripts/git-hooks/README.md +310 -0
- package/scripts/git-hooks/branch-context-manager.sh +342 -0
- package/scripts/git-hooks/post-checkout-stackmemory.sh +63 -0
- package/scripts/git-hooks/post-commit-stackmemory.sh +305 -0
- package/scripts/git-hooks/pre-commit-stackmemory.sh +275 -0
- package/scripts/hooks/cleanup-shell.sh +130 -0
- package/scripts/hooks/task-complete.sh +114 -0
- package/scripts/initialize.ts +129 -0
- package/scripts/install-claude-hooks-auto.js +104 -0
- package/scripts/install-claude-hooks.sh +133 -0
- package/scripts/install-global.sh +296 -0
- package/scripts/install.sh +235 -0
- package/scripts/linear-auto-sync.js +262 -0
- package/scripts/linear-auto-sync.sh +161 -0
- package/scripts/linear-sync-daemon.js +150 -0
- package/scripts/linear-task-review.js +237 -0
- package/scripts/list-linear-tasks.ts +178 -0
- package/scripts/mcp-proxy.js +66 -0
- package/scripts/opencode-wrapper.sh +85 -0
- package/scripts/publish-local.js +74 -0
- package/scripts/query-chromadb.ts +201 -0
- package/scripts/railway-env-setup.sh +39 -0
- package/scripts/reconcile-local-tasks.js +170 -0
- package/scripts/recreate-frames-db.js +89 -0
- package/scripts/setup/claude-integration.js +138 -0
- package/scripts/setup/configure-alias.js +125 -0
- package/scripts/setup/configure-codex-alias.js +161 -0
- package/scripts/setup/configure-opencode-alias.js +175 -0
- package/scripts/setup-claude-integration.js +204 -0
- package/scripts/setup-claude-integration.sh +183 -0
- package/scripts/setup.sh +31 -0
- package/scripts/show-linear-summary.ts +172 -0
- package/scripts/stackmemory-auto-handoff.sh +231 -0
- package/scripts/stackmemory-daemon.sh +40 -0
- package/scripts/start-linear-sync-daemon.sh +141 -0
- package/scripts/start-temporal-paradox.sh +214 -0
- package/scripts/status.ts +159 -0
- package/scripts/sync-and-clean-tasks.js +258 -0
- package/scripts/sync-frames-from-railway.js +228 -0
- package/scripts/sync-linear-graphql.js +303 -0
- package/scripts/sync-linear-tasks.js +186 -0
- package/scripts/test-auto-triggers.sh +57 -0
- package/scripts/test-browser-mcp.js +74 -0
- package/scripts/test-chromadb-full.js +115 -0
- package/scripts/test-chromadb-hooks.sh +28 -0
- package/scripts/test-chromadb-sync.ts +245 -0
- package/scripts/test-cli-security.js +293 -0
- package/scripts/test-hooks-persistence.sh +220 -0
- package/scripts/test-installation-scenarios.sh +359 -0
- package/scripts/test-installation.sh +224 -0
- package/scripts/test-mcp.js +163 -0
- package/scripts/test-pre-publish-quick.sh +75 -0
- package/scripts/test-quality-gates.sh +263 -0
- package/scripts/test-railway-db.js +222 -0
- package/scripts/test-redis-storage.ts +490 -0
- package/scripts/test-rlm-basic.sh +122 -0
- package/scripts/test-rlm-comprehensive.sh +260 -0
- package/scripts/test-rlm-e2e.sh +268 -0
- package/scripts/test-rlm-simple.js +90 -0
- package/scripts/test-rlm.js +110 -0
- package/scripts/test-session-handoff.sh +165 -0
- package/scripts/test-shell-integration.sh +275 -0
- package/scripts/testing/ab-test-runner.ts +508 -0
- package/scripts/testing/collect-metrics.ts +457 -0
- package/scripts/testing/quick-effectiveness-demo.js +187 -0
- package/scripts/testing/real-performance-test.js +422 -0
- package/scripts/testing/run-effectiveness-tests.sh +176 -0
- package/scripts/testing/scripts/testing/ab-test-runner.js +363 -0
- package/scripts/testing/scripts/testing/collect-metrics.js +292 -0
- package/scripts/testing/simple-effectiveness-test.js +310 -0
- package/scripts/testing/src/core/context/context-bridge.js +253 -0
- package/scripts/testing/src/core/context/frame-manager.js +746 -0
- package/scripts/testing/src/core/context/shared-context-layer.js +437 -0
- package/scripts/testing/src/core/database/database-adapter.js +54 -0
- package/scripts/testing/src/core/errors/index.js +291 -0
- package/scripts/testing/src/core/errors/recovery.js +268 -0
- package/scripts/testing/src/core/monitoring/logger.js +145 -0
- package/scripts/testing/src/core/retrieval/context-retriever.js +516 -0
- package/scripts/testing/src/core/session/index.js +1 -0
- package/scripts/testing/src/core/session/session-manager.js +323 -0
- package/scripts/testing/src/core/trace/cli-trace-wrapper.js +140 -0
- package/scripts/testing/src/core/trace/db-trace-wrapper.js +251 -0
- package/scripts/testing/src/core/trace/debug-trace.js +398 -0
- package/scripts/testing/src/core/trace/index.js +120 -0
- package/scripts/testing/src/core/trace/linear-api-wrapper.js +204 -0
- package/scripts/update-linear-status.js +268 -0
- package/scripts/update-linear-tasks-fixed.js +284 -0
- package/templates/claude-hooks/hooks.json +5 -0
- package/templates/claude-hooks/on-clear.js +56 -0
- package/templates/claude-hooks/on-startup.js +56 -0
- package/templates/claude-hooks/tool-use-trace.js +67 -0
- package/dist/features/tui/components/analytics-panel.js +0 -157
- package/dist/features/tui/components/analytics-panel.js.map +0 -7
- package/dist/features/tui/components/frame-visualizer.js +0 -377
- package/dist/features/tui/components/frame-visualizer.js.map +0 -7
- package/dist/features/tui/components/pr-tracker.js +0 -135
- package/dist/features/tui/components/pr-tracker.js.map +0 -7
- package/dist/features/tui/components/session-monitor.js +0 -299
- package/dist/features/tui/components/session-monitor.js.map +0 -7
- package/dist/features/tui/components/subagent-fleet.js +0 -395
- package/dist/features/tui/components/subagent-fleet.js.map +0 -7
- package/dist/features/tui/components/task-board.js +0 -1139
- package/dist/features/tui/components/task-board.js.map +0 -7
- package/dist/features/tui/index.js +0 -408
- package/dist/features/tui/index.js.map +0 -7
- package/dist/features/tui/services/data-service.js +0 -641
- package/dist/features/tui/services/data-service.js.map +0 -7
- package/dist/features/tui/services/linear-task-reader.js +0 -102
- package/dist/features/tui/services/linear-task-reader.js.map +0 -7
- package/dist/features/tui/services/websocket-client.js +0 -162
- package/dist/features/tui/services/websocket-client.js.map +0 -7
- package/dist/features/tui/terminal-compat.js +0 -220
- package/dist/features/tui/terminal-compat.js.map +0 -7
- package/dist/features/tui/types.js +0 -1
- package/dist/features/tui/types.js.map +0 -7
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# StackMemory Claude Integration Setup Script
|
|
4
|
+
# Automatically configures Claude Desktop to use StackMemory MCP server
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
echo "🚀 Setting up StackMemory integration with Claude Desktop..."
|
|
9
|
+
|
|
10
|
+
# Colors for output
|
|
11
|
+
GREEN='\033[0;32m'
|
|
12
|
+
YELLOW='\033[1;33m'
|
|
13
|
+
RED='\033[0;31m'
|
|
14
|
+
NC='\033[0m' # No Color
|
|
15
|
+
|
|
16
|
+
# Get the directory of this script
|
|
17
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
18
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
19
|
+
|
|
20
|
+
# Claude Desktop config path (macOS)
|
|
21
|
+
CLAUDE_CONFIG_DIR="$HOME/Library/Application Support/Claude"
|
|
22
|
+
CLAUDE_CONFIG_FILE="$CLAUDE_CONFIG_DIR/claude_desktop_config.json"
|
|
23
|
+
|
|
24
|
+
# Check if running on macOS
|
|
25
|
+
if [[ "$OSTYPE" != "darwin"* ]]; then
|
|
26
|
+
echo -e "${RED}This script currently only supports macOS.${NC}"
|
|
27
|
+
echo "For other platforms, manually add the configuration to your Claude Desktop config."
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Build the project first
|
|
32
|
+
echo "📦 Building StackMemory..."
|
|
33
|
+
cd "$PROJECT_ROOT"
|
|
34
|
+
npm run build
|
|
35
|
+
|
|
36
|
+
# Create Claude config directory if it doesn't exist
|
|
37
|
+
mkdir -p "$CLAUDE_CONFIG_DIR"
|
|
38
|
+
|
|
39
|
+
# Function to merge MCP server config
|
|
40
|
+
merge_mcp_config() {
|
|
41
|
+
local mcp_config='{
|
|
42
|
+
"stackmemory": {
|
|
43
|
+
"command": "node",
|
|
44
|
+
"args": ["'$PROJECT_ROOT'/dist/mcp/stackmemory-mcp-server.js"],
|
|
45
|
+
"env": {
|
|
46
|
+
"STACKMEMORY_PROJECT": "'$PROJECT_ROOT'"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}'
|
|
50
|
+
|
|
51
|
+
if [ -f "$CLAUDE_CONFIG_FILE" ]; then
|
|
52
|
+
echo "📝 Updating existing Claude config..."
|
|
53
|
+
|
|
54
|
+
# Backup existing config
|
|
55
|
+
cp "$CLAUDE_CONFIG_FILE" "$CLAUDE_CONFIG_FILE.backup.$(date +%Y%m%d_%H%M%S)"
|
|
56
|
+
|
|
57
|
+
# Use Node.js to merge configs properly
|
|
58
|
+
node -e "
|
|
59
|
+
const fs = require('fs');
|
|
60
|
+
const existingConfig = JSON.parse(fs.readFileSync('$CLAUDE_CONFIG_FILE', 'utf8'));
|
|
61
|
+
const newServer = $mcp_config;
|
|
62
|
+
|
|
63
|
+
if (!existingConfig.mcpServers) {
|
|
64
|
+
existingConfig.mcpServers = {};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
existingConfig.mcpServers.stackmemory = newServer.stackmemory;
|
|
68
|
+
|
|
69
|
+
fs.writeFileSync('$CLAUDE_CONFIG_FILE', JSON.stringify(existingConfig, null, 2));
|
|
70
|
+
console.log('✅ Configuration merged successfully');
|
|
71
|
+
"
|
|
72
|
+
else
|
|
73
|
+
echo "📝 Creating new Claude config..."
|
|
74
|
+
cat > "$CLAUDE_CONFIG_FILE" << EOF
|
|
75
|
+
{
|
|
76
|
+
"mcpServers": $mcp_config
|
|
77
|
+
}
|
|
78
|
+
EOF
|
|
79
|
+
fi
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# Add MCP server to Claude config
|
|
83
|
+
merge_mcp_config
|
|
84
|
+
|
|
85
|
+
# Create a convenience command for manual testing
|
|
86
|
+
echo "📝 Creating stackmemory-mcp command..."
|
|
87
|
+
cat > "$PROJECT_ROOT/stackmemory-mcp" << 'EOF'
|
|
88
|
+
#!/bin/bash
|
|
89
|
+
# Run StackMemory MCP server for testing
|
|
90
|
+
node "$(dirname "$0")/dist/mcp/stackmemory-mcp-server.js"
|
|
91
|
+
EOF
|
|
92
|
+
chmod +x "$PROJECT_ROOT/stackmemory-mcp"
|
|
93
|
+
|
|
94
|
+
# Create example usage documentation
|
|
95
|
+
cat > "$PROJECT_ROOT/docs/CLAUDE-INTEGRATION.md" << 'EOF'
|
|
96
|
+
# StackMemory Claude Integration
|
|
97
|
+
|
|
98
|
+
## Setup Complete! 🎉
|
|
99
|
+
|
|
100
|
+
StackMemory is now integrated with Claude Desktop. Restart Claude Desktop to activate the integration.
|
|
101
|
+
|
|
102
|
+
## Available Tools in Claude
|
|
103
|
+
|
|
104
|
+
Once activated, you can use these commands in any Claude conversation:
|
|
105
|
+
|
|
106
|
+
### Task Management
|
|
107
|
+
- `create_task` - Create a new task with optional auto-execution
|
|
108
|
+
- `execute_task` - Start agent execution for a task
|
|
109
|
+
- `task_status` - Check task status
|
|
110
|
+
- `breakdown_task` - Break complex tasks into subtasks
|
|
111
|
+
|
|
112
|
+
### Agent Execution
|
|
113
|
+
- `agent_turn` - Execute a single turn in an active session
|
|
114
|
+
- `session_feedback` - Get feedback from the last turn
|
|
115
|
+
- `list_active_sessions` - View all active agent sessions
|
|
116
|
+
- `retry_session` - Retry a failed session with learned context
|
|
117
|
+
|
|
118
|
+
### Context Management
|
|
119
|
+
- `save_context` - Save important information from the conversation
|
|
120
|
+
- `load_context` - Retrieve relevant context from StackMemory
|
|
121
|
+
|
|
122
|
+
## Example Usage in Claude
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
"Create a task to refactor the authentication module"
|
|
126
|
+
-> Claude will use create_task with auto_execute
|
|
127
|
+
|
|
128
|
+
"What's the status of my current tasks?"
|
|
129
|
+
-> Claude will use task_status to show active tasks
|
|
130
|
+
|
|
131
|
+
"Save this architecture decision for future reference"
|
|
132
|
+
-> Claude will use save_context to persist the information
|
|
133
|
+
|
|
134
|
+
"What did we decide about the API structure last week?"
|
|
135
|
+
-> Claude will use load_context to retrieve relevant decisions
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Troubleshooting
|
|
139
|
+
|
|
140
|
+
1. **Restart Claude Desktop** after installation
|
|
141
|
+
2. Check logs at: `~/.stackmemory/logs/`
|
|
142
|
+
3. Verify MCP server is running: `ps aux | grep stackmemory-mcp`
|
|
143
|
+
4. Test manually: `./stackmemory-mcp`
|
|
144
|
+
|
|
145
|
+
## Configuration
|
|
146
|
+
|
|
147
|
+
The MCP server configuration is stored at:
|
|
148
|
+
`~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
149
|
+
|
|
150
|
+
You can modify environment variables in the config:
|
|
151
|
+
- `STACKMEMORY_PROJECT` - Set the project directory
|
|
152
|
+
- `LOG_LEVEL` - Set logging verbosity (debug, info, warn, error)
|
|
153
|
+
EOF
|
|
154
|
+
|
|
155
|
+
echo ""
|
|
156
|
+
echo -e "${GREEN}✅ StackMemory Claude integration setup complete!${NC}"
|
|
157
|
+
echo ""
|
|
158
|
+
echo -e "${YELLOW}Next steps:${NC}"
|
|
159
|
+
echo "1. Restart Claude Desktop to activate the integration"
|
|
160
|
+
echo "2. In any Claude conversation, the StackMemory tools will be automatically available"
|
|
161
|
+
echo "3. Claude will automatically use these tools when relevant to your tasks"
|
|
162
|
+
echo ""
|
|
163
|
+
echo "📚 Documentation created at: $PROJECT_ROOT/docs/CLAUDE-INTEGRATION.md"
|
|
164
|
+
echo ""
|
|
165
|
+
echo -e "${GREEN}Example usage in Claude:${NC}"
|
|
166
|
+
echo ' "Create a task to implement user authentication"'
|
|
167
|
+
echo ' "Show me the status of my current tasks"'
|
|
168
|
+
echo ' "Save this important decision about the architecture"'
|
|
169
|
+
echo ""
|
|
170
|
+
|
|
171
|
+
# Check if Claude is running and suggest restart
|
|
172
|
+
if pgrep -x "Claude" > /dev/null; then
|
|
173
|
+
echo -e "${YELLOW}⚠️ Claude Desktop is currently running. Please restart it to activate the integration.${NC}"
|
|
174
|
+
echo ""
|
|
175
|
+
read -p "Would you like to restart Claude Desktop now? (y/n) " -n 1 -r
|
|
176
|
+
echo ""
|
|
177
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
178
|
+
osascript -e 'quit app "Claude"'
|
|
179
|
+
sleep 2
|
|
180
|
+
open -a "Claude"
|
|
181
|
+
echo -e "${GREEN}✅ Claude Desktop restarted!${NC}"
|
|
182
|
+
fi
|
|
183
|
+
fi
|
package/scripts/setup.sh
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# StackMemory Quick Setup Script
|
|
4
|
+
|
|
5
|
+
echo "🚀 Setting up StackMemory..."
|
|
6
|
+
|
|
7
|
+
# Install dependencies
|
|
8
|
+
echo "📦 Installing dependencies..."
|
|
9
|
+
npm install
|
|
10
|
+
|
|
11
|
+
# Build TypeScript
|
|
12
|
+
echo "🔨 Building TypeScript..."
|
|
13
|
+
npm run build
|
|
14
|
+
|
|
15
|
+
# Initialize StackMemory
|
|
16
|
+
echo "🎯 Initializing StackMemory..."
|
|
17
|
+
npm run init
|
|
18
|
+
|
|
19
|
+
echo ""
|
|
20
|
+
echo "✅ Setup complete!"
|
|
21
|
+
echo ""
|
|
22
|
+
echo "📝 Next steps:"
|
|
23
|
+
echo "1. Copy the MCP configuration shown above to your Claude Code settings"
|
|
24
|
+
echo "2. Restart Claude Code"
|
|
25
|
+
echo "3. The StackMemory tools will be available in Claude Code!"
|
|
26
|
+
echo ""
|
|
27
|
+
echo "🎮 Commands:"
|
|
28
|
+
echo " npm run mcp:dev - Start MCP server in dev mode"
|
|
29
|
+
echo " npm run status - Check StackMemory status"
|
|
30
|
+
echo " npm run analyze - Analyze context usage"
|
|
31
|
+
echo ""
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Show Linear task summary with all statuses
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { readFileSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
|
|
10
|
+
interface LinearIssue {
|
|
11
|
+
identifier: string;
|
|
12
|
+
title: string;
|
|
13
|
+
state: {
|
|
14
|
+
name: string;
|
|
15
|
+
type: string;
|
|
16
|
+
};
|
|
17
|
+
createdAt: string;
|
|
18
|
+
updatedAt: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function showLinearSummary() {
|
|
22
|
+
// Load Linear tokens
|
|
23
|
+
const tokensPath = join(process.cwd(), '.stackmemory', 'linear-tokens.json');
|
|
24
|
+
let accessToken: string;
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const tokensData = readFileSync(tokensPath, 'utf8');
|
|
28
|
+
const tokens = JSON.parse(tokensData);
|
|
29
|
+
accessToken = tokens.accessToken;
|
|
30
|
+
} catch {
|
|
31
|
+
console.error(
|
|
32
|
+
'❌ Failed to load Linear tokens. Please run: stackmemory linear setup'
|
|
33
|
+
);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// GraphQL helper
|
|
38
|
+
const linearApiUrl = 'https://api.linear.app/graphql';
|
|
39
|
+
|
|
40
|
+
async function graphqlRequest(
|
|
41
|
+
query: string,
|
|
42
|
+
variables: Record<string, unknown> = {}
|
|
43
|
+
) {
|
|
44
|
+
const response = await fetch(linearApiUrl, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: {
|
|
47
|
+
Authorization: `Bearer ${accessToken}`,
|
|
48
|
+
'Content-Type': 'application/json',
|
|
49
|
+
},
|
|
50
|
+
body: JSON.stringify({ query, variables }),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
`Linear API error: ${response.status} ${response.statusText}`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const result = (await response.json()) as {
|
|
60
|
+
errors?: unknown[];
|
|
61
|
+
data: unknown;
|
|
62
|
+
};
|
|
63
|
+
if (result.errors) {
|
|
64
|
+
throw new Error(`GraphQL errors: ${JSON.stringify(result.errors)}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return result.data;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Get issues grouped by state
|
|
71
|
+
const issuesQuery = `
|
|
72
|
+
query {
|
|
73
|
+
issues(first: 250) {
|
|
74
|
+
nodes {
|
|
75
|
+
identifier
|
|
76
|
+
title
|
|
77
|
+
state {
|
|
78
|
+
name
|
|
79
|
+
type
|
|
80
|
+
}
|
|
81
|
+
createdAt
|
|
82
|
+
updatedAt
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
`;
|
|
87
|
+
|
|
88
|
+
const data = (await graphqlRequest(issuesQuery)) as {
|
|
89
|
+
issues: { nodes: LinearIssue[] };
|
|
90
|
+
};
|
|
91
|
+
const issues = data.issues.nodes;
|
|
92
|
+
|
|
93
|
+
// Group by state type
|
|
94
|
+
const grouped = new Map<string, LinearIssue[]>();
|
|
95
|
+
|
|
96
|
+
for (const issue of issues) {
|
|
97
|
+
const stateType = issue.state.type;
|
|
98
|
+
if (!grouped.has(stateType)) {
|
|
99
|
+
grouped.set(stateType, []);
|
|
100
|
+
}
|
|
101
|
+
const stateIssues = grouped.get(stateType);
|
|
102
|
+
if (stateIssues) {
|
|
103
|
+
stateIssues.push(issue);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Display summary
|
|
108
|
+
console.log('\n📊 Linear Task Summary\n');
|
|
109
|
+
console.log('='.repeat(60));
|
|
110
|
+
|
|
111
|
+
const stateOrder = [
|
|
112
|
+
'backlog',
|
|
113
|
+
'unstarted',
|
|
114
|
+
'started',
|
|
115
|
+
'completed',
|
|
116
|
+
'canceled',
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
for (const state of stateOrder) {
|
|
120
|
+
const stateIssues = grouped.get(state) || [];
|
|
121
|
+
if (stateIssues.length === 0) continue;
|
|
122
|
+
|
|
123
|
+
const emoji =
|
|
124
|
+
{
|
|
125
|
+
backlog: '📋',
|
|
126
|
+
unstarted: '⏳',
|
|
127
|
+
started: '🔄',
|
|
128
|
+
completed: '✅',
|
|
129
|
+
canceled: '❌',
|
|
130
|
+
}[state] || '⚪';
|
|
131
|
+
|
|
132
|
+
console.log(
|
|
133
|
+
`\n${emoji} ${state.toUpperCase()} (${stateIssues.length} tasks)`
|
|
134
|
+
);
|
|
135
|
+
console.log('-'.repeat(40));
|
|
136
|
+
|
|
137
|
+
// Show recent items (last 5)
|
|
138
|
+
const recent = stateIssues
|
|
139
|
+
.sort(
|
|
140
|
+
(a, b) =>
|
|
141
|
+
new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
142
|
+
)
|
|
143
|
+
.slice(0, state === 'canceled' ? 20 : 5);
|
|
144
|
+
|
|
145
|
+
for (const issue of recent) {
|
|
146
|
+
const updatedDate = new Date(issue.updatedAt).toLocaleDateString();
|
|
147
|
+
console.log(
|
|
148
|
+
` ${issue.identifier.padEnd(10)} ${issue.title.slice(0, 50).padEnd(50)} ${updatedDate}`
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (stateIssues.length > recent.length) {
|
|
153
|
+
console.log(` ... and ${stateIssues.length - recent.length} more`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
console.log('\n' + '='.repeat(60));
|
|
158
|
+
console.log('\n📈 Total Issues: ' + issues.length);
|
|
159
|
+
const activeCount =
|
|
160
|
+
(grouped.get('started')?.length ?? 0) +
|
|
161
|
+
(grouped.get('unstarted')?.length ?? 0) +
|
|
162
|
+
(grouped.get('backlog')?.length ?? 0);
|
|
163
|
+
console.log(' Active: ' + activeCount);
|
|
164
|
+
console.log(' Completed: ' + (grouped.get('completed')?.length ?? 0));
|
|
165
|
+
console.log(' Canceled: ' + (grouped.get('canceled')?.length ?? 0));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Run
|
|
169
|
+
showLinearSummary().catch((error) => {
|
|
170
|
+
console.error('❌ Error:', error);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
});
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# StackMemory Auto-Handoff Wrapper
|
|
3
|
+
# Wraps any command and captures context on termination
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Configuration
|
|
8
|
+
STACKMEMORY_BIN="${STACKMEMORY_BIN:-stackmemory}"
|
|
9
|
+
HANDOFF_DIR="${HOME}/.stackmemory/handoffs"
|
|
10
|
+
LOG_FILE="${HANDOFF_DIR}/auto-handoff.log"
|
|
11
|
+
|
|
12
|
+
# Colors
|
|
13
|
+
RED='\033[0;31m'
|
|
14
|
+
GREEN='\033[0;32m'
|
|
15
|
+
YELLOW='\033[1;33m'
|
|
16
|
+
BLUE='\033[0;34m'
|
|
17
|
+
NC='\033[0m'
|
|
18
|
+
|
|
19
|
+
# Ensure directories exist
|
|
20
|
+
mkdir -p "$HANDOFF_DIR"
|
|
21
|
+
|
|
22
|
+
# Log function
|
|
23
|
+
log() {
|
|
24
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Function to capture handoff
|
|
28
|
+
capture_handoff() {
|
|
29
|
+
local reason="$1"
|
|
30
|
+
local exit_code="${2:-0}"
|
|
31
|
+
|
|
32
|
+
echo -e "${YELLOW}📸 Capturing handoff context...${NC}"
|
|
33
|
+
log "Capturing handoff: reason=$reason, exit_code=$exit_code"
|
|
34
|
+
|
|
35
|
+
# Run stackmemory handoff command
|
|
36
|
+
if command -v "$STACKMEMORY_BIN" &> /dev/null; then
|
|
37
|
+
# Capture the handoff
|
|
38
|
+
"$STACKMEMORY_BIN" handoff --no-commit 2>&1 | tee -a "$LOG_FILE"
|
|
39
|
+
|
|
40
|
+
# Save additional metadata
|
|
41
|
+
local metadata_file="${HANDOFF_DIR}/last-handoff-meta.json"
|
|
42
|
+
cat > "$metadata_file" << EOF
|
|
43
|
+
{
|
|
44
|
+
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
45
|
+
"reason": "$reason",
|
|
46
|
+
"exit_code": $exit_code,
|
|
47
|
+
"command": "$WRAPPED_COMMAND",
|
|
48
|
+
"pid": $$,
|
|
49
|
+
"cwd": "$(pwd)",
|
|
50
|
+
"user": "$USER",
|
|
51
|
+
"session_duration": $(($(date +%s) - SESSION_START))
|
|
52
|
+
}
|
|
53
|
+
EOF
|
|
54
|
+
|
|
55
|
+
echo -e "${GREEN}✅ Handoff captured successfully${NC}"
|
|
56
|
+
log "Handoff captured: $metadata_file"
|
|
57
|
+
|
|
58
|
+
# Show quick summary
|
|
59
|
+
echo -e "${BLUE}📋 Session Summary:${NC}"
|
|
60
|
+
echo " Duration: $(($(date +%s) - SESSION_START)) seconds"
|
|
61
|
+
echo " Exit reason: $reason"
|
|
62
|
+
|
|
63
|
+
# Check for uncommitted changes
|
|
64
|
+
if git status --short 2>/dev/null | grep -q .; then
|
|
65
|
+
echo -e "${YELLOW}⚠️ You have uncommitted changes${NC}"
|
|
66
|
+
echo " Run 'git status' to review"
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Check for active tasks
|
|
70
|
+
local active_tasks=$("$STACKMEMORY_BIN" task list --state in_progress --format json 2>/dev/null | jq -r '.[].title' 2>/dev/null)
|
|
71
|
+
if [ -n "$active_tasks" ]; then
|
|
72
|
+
echo -e "${BLUE}📝 Active tasks:${NC}"
|
|
73
|
+
echo "$active_tasks" | while read -r task; do
|
|
74
|
+
echo " • $task"
|
|
75
|
+
done
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
echo -e "${GREEN}✨ Run 'stackmemory handoff restore' in your next session${NC}"
|
|
79
|
+
else
|
|
80
|
+
echo -e "${RED}❌ StackMemory not found${NC}"
|
|
81
|
+
log "ERROR: StackMemory binary not found"
|
|
82
|
+
fi
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# Signal handlers
|
|
86
|
+
handle_sigint() {
|
|
87
|
+
echo -e "\n${YELLOW}⚠️ Interrupted (Ctrl+C)${NC}"
|
|
88
|
+
capture_handoff "SIGINT" 130
|
|
89
|
+
exit 130
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
handle_sigterm() {
|
|
93
|
+
echo -e "\n${YELLOW}⚠️ Terminated${NC}"
|
|
94
|
+
capture_handoff "SIGTERM" 143
|
|
95
|
+
exit 143
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
handle_sighup() {
|
|
99
|
+
echo -e "\n${YELLOW}⚠️ Hangup signal${NC}"
|
|
100
|
+
capture_handoff "SIGHUP" 129
|
|
101
|
+
exit 129
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
handle_exit() {
|
|
105
|
+
local exit_code=$?
|
|
106
|
+
if [ $exit_code -ne 0 ] && [ $exit_code -ne 130 ] && [ $exit_code -ne 143 ] && [ $exit_code -ne 129 ]; then
|
|
107
|
+
echo -e "${YELLOW}⚠️ Unexpected exit (code: $exit_code)${NC}"
|
|
108
|
+
capture_handoff "unexpected_exit" $exit_code
|
|
109
|
+
elif [ $exit_code -eq 0 ]; then
|
|
110
|
+
# Normal exit - ask if user wants to capture handoff
|
|
111
|
+
if [ "$AUTO_CAPTURE_ON_EXIT" = "true" ]; then
|
|
112
|
+
capture_handoff "normal_exit" 0
|
|
113
|
+
else
|
|
114
|
+
echo -e "${BLUE}💡 Session ending normally. Create handoff? (y/N):${NC} \c"
|
|
115
|
+
read -t 5 -n 1 response || response="n"
|
|
116
|
+
echo
|
|
117
|
+
if [[ "$response" =~ ^[Yy]$ ]]; then
|
|
118
|
+
capture_handoff "normal_exit" 0
|
|
119
|
+
fi
|
|
120
|
+
fi
|
|
121
|
+
fi
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# Usage information
|
|
125
|
+
usage() {
|
|
126
|
+
cat << EOF
|
|
127
|
+
Usage: $0 [OPTIONS] COMMAND [ARGS...]
|
|
128
|
+
|
|
129
|
+
Wraps a command with automatic handoff capture on termination.
|
|
130
|
+
|
|
131
|
+
Options:
|
|
132
|
+
-h, --help Show this help message
|
|
133
|
+
-a, --auto Auto-capture on normal exit (no prompt)
|
|
134
|
+
-q, --quiet Suppress output
|
|
135
|
+
-t, --tag TAG Tag this session
|
|
136
|
+
|
|
137
|
+
Examples:
|
|
138
|
+
$0 claude # Wrap Claude session
|
|
139
|
+
$0 -a npm run dev # Auto-capture on exit
|
|
140
|
+
$0 -t "feature-work" vim # Tagged session
|
|
141
|
+
|
|
142
|
+
Environment Variables:
|
|
143
|
+
STACKMEMORY_BIN Path to stackmemory binary
|
|
144
|
+
AUTO_CAPTURE_ON_EXIT Set to 'true' for auto-capture
|
|
145
|
+
|
|
146
|
+
Without arguments, enables handoff mode for current shell session.
|
|
147
|
+
EOF
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
# Parse arguments
|
|
151
|
+
AUTO_CAPTURE_ON_EXIT="${AUTO_CAPTURE_ON_EXIT:-false}"
|
|
152
|
+
SESSION_TAG=""
|
|
153
|
+
QUIET_MODE="false"
|
|
154
|
+
|
|
155
|
+
while [[ $# -gt 0 ]]; do
|
|
156
|
+
case "$1" in
|
|
157
|
+
-h|--help)
|
|
158
|
+
usage
|
|
159
|
+
exit 0
|
|
160
|
+
;;
|
|
161
|
+
-a|--auto)
|
|
162
|
+
AUTO_CAPTURE_ON_EXIT="true"
|
|
163
|
+
shift
|
|
164
|
+
;;
|
|
165
|
+
-q|--quiet)
|
|
166
|
+
QUIET_MODE="true"
|
|
167
|
+
shift
|
|
168
|
+
;;
|
|
169
|
+
-t|--tag)
|
|
170
|
+
SESSION_TAG="$2"
|
|
171
|
+
shift 2
|
|
172
|
+
;;
|
|
173
|
+
*)
|
|
174
|
+
break
|
|
175
|
+
;;
|
|
176
|
+
esac
|
|
177
|
+
done
|
|
178
|
+
|
|
179
|
+
# If no command provided, just set up handlers for current session
|
|
180
|
+
if [ $# -eq 0 ]; then
|
|
181
|
+
echo -e "${BLUE}🛡️ StackMemory Auto-Handoff Enabled${NC}"
|
|
182
|
+
echo -e "${GRAY}Context will be captured on session termination${NC}"
|
|
183
|
+
echo -e "${YELLOW}Press Ctrl+C to test or exit normally to continue${NC}"
|
|
184
|
+
|
|
185
|
+
# Set up signal handlers
|
|
186
|
+
trap handle_sigint SIGINT
|
|
187
|
+
trap handle_sigterm SIGTERM
|
|
188
|
+
trap handle_sighup SIGHUP
|
|
189
|
+
trap handle_exit EXIT
|
|
190
|
+
|
|
191
|
+
# Record session start
|
|
192
|
+
export SESSION_START=$(date +%s)
|
|
193
|
+
export WRAPPED_COMMAND="interactive_shell"
|
|
194
|
+
|
|
195
|
+
# Keep running
|
|
196
|
+
while true; do
|
|
197
|
+
sleep 1
|
|
198
|
+
done
|
|
199
|
+
else
|
|
200
|
+
# Wrap the provided command
|
|
201
|
+
WRAPPED_COMMAND="$*"
|
|
202
|
+
|
|
203
|
+
if [ "$QUIET_MODE" = "false" ]; then
|
|
204
|
+
echo -e "${BLUE}🛡️ StackMemory Auto-Handoff Wrapper${NC}"
|
|
205
|
+
echo -e "Wrapping: $WRAPPED_COMMAND"
|
|
206
|
+
if [ -n "$SESSION_TAG" ]; then
|
|
207
|
+
echo -e "Tag: $SESSION_TAG"
|
|
208
|
+
fi
|
|
209
|
+
echo -e "${GRAY}Handoff will be captured on termination${NC}"
|
|
210
|
+
echo
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
# Set up signal handlers
|
|
214
|
+
trap handle_sigint SIGINT
|
|
215
|
+
trap handle_sigterm SIGTERM
|
|
216
|
+
trap handle_sighup SIGHUP
|
|
217
|
+
trap handle_exit EXIT
|
|
218
|
+
|
|
219
|
+
# Record session start
|
|
220
|
+
export SESSION_START=$(date +%s)
|
|
221
|
+
|
|
222
|
+
log "Starting wrapped session: $WRAPPED_COMMAND"
|
|
223
|
+
|
|
224
|
+
# Execute the wrapped command
|
|
225
|
+
"$@"
|
|
226
|
+
|
|
227
|
+
# Command completed normally
|
|
228
|
+
exit_code=$?
|
|
229
|
+
log "Command completed with exit code: $exit_code"
|
|
230
|
+
exit $exit_code
|
|
231
|
+
fi
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# StackMemory background daemon
|
|
4
|
+
# Automatically saves context every 5 minutes and on exit
|
|
5
|
+
|
|
6
|
+
INTERVAL=${1:-300} # Default 5 minutes
|
|
7
|
+
PID_FILE="/tmp/stackmemory-daemon.pid"
|
|
8
|
+
|
|
9
|
+
cleanup() {
|
|
10
|
+
echo "🛑 Stopping StackMemory daemon..."
|
|
11
|
+
if [ -d ".stackmemory" ]; then
|
|
12
|
+
stackmemory status
|
|
13
|
+
[ -n "$LINEAR_API_KEY" ] && stackmemory linear sync
|
|
14
|
+
fi
|
|
15
|
+
rm -f "$PID_FILE"
|
|
16
|
+
exit 0
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
trap cleanup EXIT INT TERM
|
|
20
|
+
|
|
21
|
+
# Save PID
|
|
22
|
+
echo $$ > "$PID_FILE"
|
|
23
|
+
|
|
24
|
+
echo "🚀 StackMemory daemon started (PID: $$)"
|
|
25
|
+
echo " Auto-save interval: ${INTERVAL}s"
|
|
26
|
+
echo " Press Ctrl+C to stop"
|
|
27
|
+
|
|
28
|
+
while true; do
|
|
29
|
+
sleep "$INTERVAL"
|
|
30
|
+
|
|
31
|
+
if [ -d ".stackmemory" ]; then
|
|
32
|
+
echo "[$(date)] Auto-saving StackMemory context..."
|
|
33
|
+
stackmemory status 2>/dev/null || true
|
|
34
|
+
|
|
35
|
+
# Only sync with Linear once per hour
|
|
36
|
+
if [ $(($(date +%s) % 3600)) -lt "$INTERVAL" ] && [ -n "$LINEAR_API_KEY" ]; then
|
|
37
|
+
stackmemory linear sync 2>/dev/null || true
|
|
38
|
+
fi
|
|
39
|
+
fi
|
|
40
|
+
done
|