@stackmemoryai/stackmemory 0.3.16 ā 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/README.md +48 -2
- 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,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { dirname, join } from 'path';
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = dirname(__filename);
|
|
11
|
+
|
|
12
|
+
const ALIAS_NAME = 'claude-sm';
|
|
13
|
+
const WRAPPER_SCRIPT = 'claude-code-wrapper.sh';
|
|
14
|
+
|
|
15
|
+
function getShellConfigFiles() {
|
|
16
|
+
const shell = process.env.SHELL || '';
|
|
17
|
+
const home = os.homedir();
|
|
18
|
+
const files = [];
|
|
19
|
+
|
|
20
|
+
if (shell.includes('zsh')) {
|
|
21
|
+
files.push(path.join(home, '.zshrc'));
|
|
22
|
+
// Also check .zprofile for some systems
|
|
23
|
+
const zprofile = path.join(home, '.zprofile');
|
|
24
|
+
if (fs.existsSync(zprofile)) {
|
|
25
|
+
files.push(zprofile);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (shell.includes('bash') || !shell.includes('zsh')) {
|
|
30
|
+
const profilePath = path.join(home, '.bash_profile');
|
|
31
|
+
const rcPath = path.join(home, '.bashrc');
|
|
32
|
+
if (fs.existsSync(profilePath)) files.push(profilePath);
|
|
33
|
+
if (fs.existsSync(rcPath)) files.push(rcPath);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (shell.includes('fish')) {
|
|
37
|
+
files.push(path.join(home, '.config', 'fish', 'config.fish'));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return files.length > 0 ? files : [path.join(home, '.bashrc')];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function setupAlias() {
|
|
44
|
+
try {
|
|
45
|
+
const wrapperPath = join(dirname(__dirname), 'scripts', WRAPPER_SCRIPT);
|
|
46
|
+
|
|
47
|
+
if (!fs.existsSync(wrapperPath)) {
|
|
48
|
+
console.log(`ā ļø Wrapper script not found at ${wrapperPath}`);
|
|
49
|
+
console.log(
|
|
50
|
+
' Please ensure claude-code-wrapper.sh exists in the scripts directory'
|
|
51
|
+
);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const configFiles = getShellConfigFiles();
|
|
56
|
+
const aliasLine = `alias ${ALIAS_NAME}="${wrapperPath}"`;
|
|
57
|
+
const marker = '# StackMemory Claude alias';
|
|
58
|
+
let alreadyConfigured = false;
|
|
59
|
+
let configuredIn = [];
|
|
60
|
+
|
|
61
|
+
for (const configFile of configFiles) {
|
|
62
|
+
let config = '';
|
|
63
|
+
if (fs.existsSync(configFile)) {
|
|
64
|
+
config = fs.readFileSync(configFile, 'utf8');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Check if already has the alias (with marker or just the alias itself)
|
|
68
|
+
if (config.includes(marker) || config.includes(`alias ${ALIAS_NAME}=`)) {
|
|
69
|
+
configuredIn.push(configFile);
|
|
70
|
+
alreadyConfigured = true;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Only add to primary shell config (first in the list)
|
|
75
|
+
if (configuredIn.length === 0 && configFiles.indexOf(configFile) === 0) {
|
|
76
|
+
const aliasBlock = `\n${marker}\n${aliasLine}\n`;
|
|
77
|
+
fs.appendFileSync(configFile, aliasBlock);
|
|
78
|
+
configuredIn.push(configFile);
|
|
79
|
+
console.log(`ā
Added ${ALIAS_NAME} alias to ${configFile}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (alreadyConfigured && configuredIn.length > 0) {
|
|
84
|
+
console.log(
|
|
85
|
+
`ā ${ALIAS_NAME} alias already configured in: ${configuredIn.join(', ')}`
|
|
86
|
+
);
|
|
87
|
+
} else if (configuredIn.length > 0) {
|
|
88
|
+
console.log(
|
|
89
|
+
` Run 'source ${configuredIn[0]}' or restart your terminal to use it`
|
|
90
|
+
);
|
|
91
|
+
console.log(` You can then use: ${ALIAS_NAME} [your message]`);
|
|
92
|
+
}
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error('Error setting up alias:', error.message);
|
|
95
|
+
console.log('\nManual setup:');
|
|
96
|
+
console.log(`Add this line to your shell config file:`);
|
|
97
|
+
console.log(
|
|
98
|
+
`alias ${ALIAS_NAME}="${join(dirname(__dirname), 'scripts', WRAPPER_SCRIPT)}"`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (process.argv.includes('--check')) {
|
|
104
|
+
const configFiles = getShellConfigFiles();
|
|
105
|
+
let found = false;
|
|
106
|
+
|
|
107
|
+
for (const configFile of configFiles) {
|
|
108
|
+
if (fs.existsSync(configFile)) {
|
|
109
|
+
const config = fs.readFileSync(configFile, 'utf8');
|
|
110
|
+
if (config.includes(`alias ${ALIAS_NAME}=`)) {
|
|
111
|
+
console.log(`ā ${ALIAS_NAME} alias is configured in ${configFile}`);
|
|
112
|
+
found = true;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!found) {
|
|
119
|
+
console.log(`ā ${ALIAS_NAME} alias not found`);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
process.exit(0);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
setupAlias();
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import path, { dirname, join } from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
|
|
11
|
+
const ALIAS_NAME = 'codex-sm';
|
|
12
|
+
const WRAPPER_SCRIPT = 'codex-wrapper.sh';
|
|
13
|
+
|
|
14
|
+
function getShellConfigFiles() {
|
|
15
|
+
const shell = process.env.SHELL || '';
|
|
16
|
+
const home = os.homedir();
|
|
17
|
+
const files = [];
|
|
18
|
+
|
|
19
|
+
if (shell.includes('zsh')) {
|
|
20
|
+
files.push(path.join(home, '.zshrc'));
|
|
21
|
+
const zprofile = path.join(home, '.zprofile');
|
|
22
|
+
if (fs.existsSync(zprofile)) files.push(zprofile);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (shell.includes('bash') || !shell.includes('zsh')) {
|
|
26
|
+
const profilePath = path.join(home, '.bash_profile');
|
|
27
|
+
const rcPath = path.join(home, '.bashrc');
|
|
28
|
+
if (fs.existsSync(profilePath)) files.push(profilePath);
|
|
29
|
+
if (fs.existsSync(rcPath)) files.push(rcPath);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (shell.includes('fish')) {
|
|
33
|
+
files.push(path.join(home, '.config', 'fish', 'config.fish'));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return files.length > 0 ? files : [path.join(home, '.bashrc')];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function setupAlias() {
|
|
40
|
+
try {
|
|
41
|
+
const scriptsDir = dirname(__dirname);
|
|
42
|
+
const repoRoot = dirname(scriptsDir);
|
|
43
|
+
const distBin = join(repoRoot, 'dist', 'src', 'cli', 'codex-sm.js');
|
|
44
|
+
const wrapperPath = join(scriptsDir, WRAPPER_SCRIPT);
|
|
45
|
+
|
|
46
|
+
// Prefer TypeScript bin (built file); fallback to shell wrapper
|
|
47
|
+
const targetCmd = fs.existsSync(distBin)
|
|
48
|
+
? `node ${distBin}`
|
|
49
|
+
: (fs.existsSync(wrapperPath)
|
|
50
|
+
? `${wrapperPath}`
|
|
51
|
+
: null);
|
|
52
|
+
|
|
53
|
+
if (!targetCmd) {
|
|
54
|
+
console.log('ā ļø Neither built TS bin nor wrapper script found.');
|
|
55
|
+
console.log(' Build first: npm run build');
|
|
56
|
+
console.log(` Or ensure ${WRAPPER_SCRIPT} exists in scripts/`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const configFiles = getShellConfigFiles();
|
|
61
|
+
const aliasLine = `alias ${ALIAS_NAME}="${targetCmd}"`;
|
|
62
|
+
const marker = '# StackMemory Codex alias';
|
|
63
|
+
let updatedOrConfigured = false;
|
|
64
|
+
const touched = [];
|
|
65
|
+
|
|
66
|
+
for (const configFile of configFiles) {
|
|
67
|
+
let config = '';
|
|
68
|
+
if (fs.existsSync(configFile)) config = fs.readFileSync(configFile, 'utf8');
|
|
69
|
+
|
|
70
|
+
// If already present, replace existing alias line in-place
|
|
71
|
+
if (config.includes(`alias ${ALIAS_NAME}=`)) {
|
|
72
|
+
const newConfig = config.replace(
|
|
73
|
+
new RegExp(`^.*alias\\s+${ALIAS_NAME}=.*$`, 'm'),
|
|
74
|
+
aliasLine
|
|
75
|
+
);
|
|
76
|
+
if (newConfig !== config) {
|
|
77
|
+
fs.writeFileSync(configFile, newConfig, 'utf8');
|
|
78
|
+
console.log(`ā
Updated ${ALIAS_NAME} alias in ${configFile}`);
|
|
79
|
+
updatedOrConfigured = true;
|
|
80
|
+
touched.push(configFile);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Otherwise, add once to the first config file available
|
|
86
|
+
if (!updatedOrConfigured && configFiles.indexOf(configFile) === 0) {
|
|
87
|
+
const aliasBlock = `\n${marker}\n${aliasLine}\n`;
|
|
88
|
+
fs.appendFileSync(configFile, aliasBlock);
|
|
89
|
+
console.log(`ā
Added ${ALIAS_NAME} alias to ${configFile}`);
|
|
90
|
+
updatedOrConfigured = true;
|
|
91
|
+
touched.push(configFile);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (touched.length > 0) {
|
|
96
|
+
console.log(` Run 'source ${touched[0]}' or restart your terminal to use it`);
|
|
97
|
+
console.log(` You can then use: ${ALIAS_NAME} [your message]`);
|
|
98
|
+
} else {
|
|
99
|
+
console.log(`ā¹ļø No suitable shell config found to modify.`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
console.log(`\nš Usage:`);
|
|
103
|
+
console.log(` ${ALIAS_NAME} # Start Codex with StackMemory`);
|
|
104
|
+
console.log(` ${ALIAS_NAME} --auto-sync # With Linear auto-sync`);
|
|
105
|
+
console.log(` ${ALIAS_NAME} --sync-interval=10 # Custom sync interval (minutes)`);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error('Error setting up alias:', error.message);
|
|
108
|
+
console.log('\nManual setup:');
|
|
109
|
+
console.log(`Add this line to your shell config file:`);
|
|
110
|
+
console.log(`alias ${ALIAS_NAME}="${join(dirname(__dirname), WRAPPER_SCRIPT)}"`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (process.argv.includes('--check')) {
|
|
115
|
+
const configFiles = getShellConfigFiles();
|
|
116
|
+
let found = false;
|
|
117
|
+
for (const configFile of configFiles) {
|
|
118
|
+
if (fs.existsSync(configFile)) {
|
|
119
|
+
const config = fs.readFileSync(configFile, 'utf8');
|
|
120
|
+
if (config.includes(`alias ${ALIAS_NAME}=`)) {
|
|
121
|
+
console.log(`ā ${ALIAS_NAME} alias is configured in ${configFile}`);
|
|
122
|
+
found = true;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (!found) {
|
|
128
|
+
console.log(`ā ${ALIAS_NAME} alias not found`);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
process.exit(0);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (process.argv.includes('--remove')) {
|
|
135
|
+
const configFiles = getShellConfigFiles();
|
|
136
|
+
let removed = false;
|
|
137
|
+
for (const configFile of configFiles) {
|
|
138
|
+
if (fs.existsSync(configFile)) {
|
|
139
|
+
let config = fs.readFileSync(configFile, 'utf8');
|
|
140
|
+
const marker = '# StackMemory Codex alias';
|
|
141
|
+
if (config.includes(marker) || config.includes(`alias ${ALIAS_NAME}=`)) {
|
|
142
|
+
const lines = config.split('\n');
|
|
143
|
+
const newLines = [];
|
|
144
|
+
let skipNext = false;
|
|
145
|
+
for (const line of lines) {
|
|
146
|
+
if (line.includes(marker)) { skipNext = true; continue; }
|
|
147
|
+
if (skipNext && line.includes(`alias ${ALIAS_NAME}=`)) { skipNext = false; continue; }
|
|
148
|
+
skipNext = false;
|
|
149
|
+
newLines.push(line);
|
|
150
|
+
}
|
|
151
|
+
fs.writeFileSync(configFile, newLines.join('\n'));
|
|
152
|
+
console.log(`ā
Removed ${ALIAS_NAME} alias from ${configFile}`);
|
|
153
|
+
removed = true;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (!removed) console.log(`ā ${ALIAS_NAME} alias not found in any config file`);
|
|
158
|
+
process.exit(0);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
setupAlias();
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { dirname, join } from 'path';
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = dirname(__filename);
|
|
11
|
+
|
|
12
|
+
const ALIAS_NAME = 'opencode-sm';
|
|
13
|
+
const WRAPPER_SCRIPT = 'opencode-wrapper.sh';
|
|
14
|
+
|
|
15
|
+
function getShellConfigFiles() {
|
|
16
|
+
const shell = process.env.SHELL || '';
|
|
17
|
+
const home = os.homedir();
|
|
18
|
+
const files = [];
|
|
19
|
+
|
|
20
|
+
if (shell.includes('zsh')) {
|
|
21
|
+
files.push(path.join(home, '.zshrc'));
|
|
22
|
+
// Also check .zprofile for some systems
|
|
23
|
+
const zprofile = path.join(home, '.zprofile');
|
|
24
|
+
if (fs.existsSync(zprofile)) {
|
|
25
|
+
files.push(zprofile);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (shell.includes('bash') || !shell.includes('zsh')) {
|
|
30
|
+
const profilePath = path.join(home, '.bash_profile');
|
|
31
|
+
const rcPath = path.join(home, '.bashrc');
|
|
32
|
+
if (fs.existsSync(profilePath)) files.push(profilePath);
|
|
33
|
+
if (fs.existsSync(rcPath)) files.push(rcPath);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (shell.includes('fish')) {
|
|
37
|
+
files.push(path.join(home, '.config', 'fish', 'config.fish'));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return files.length > 0 ? files : [path.join(home, '.bashrc')];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function setupAlias() {
|
|
44
|
+
try {
|
|
45
|
+
const wrapperPath = join(dirname(__dirname), WRAPPER_SCRIPT);
|
|
46
|
+
|
|
47
|
+
if (!fs.existsSync(wrapperPath)) {
|
|
48
|
+
console.log(`ā ļø Wrapper script not found at ${wrapperPath}`);
|
|
49
|
+
console.log(
|
|
50
|
+
' Please ensure opencode-wrapper.sh exists in the scripts directory'
|
|
51
|
+
);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const configFiles = getShellConfigFiles();
|
|
56
|
+
const aliasLine = `alias ${ALIAS_NAME}="${wrapperPath}"`;
|
|
57
|
+
const marker = '# StackMemory OpenCode alias';
|
|
58
|
+
let alreadyConfigured = false;
|
|
59
|
+
let configuredIn = [];
|
|
60
|
+
|
|
61
|
+
for (const configFile of configFiles) {
|
|
62
|
+
let config = '';
|
|
63
|
+
if (fs.existsSync(configFile)) {
|
|
64
|
+
config = fs.readFileSync(configFile, 'utf8');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Check if already has the alias (with marker or just the alias itself)
|
|
68
|
+
if (config.includes(marker) || config.includes(`alias ${ALIAS_NAME}=`)) {
|
|
69
|
+
configuredIn.push(configFile);
|
|
70
|
+
alreadyConfigured = true;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Only add to primary shell config (first in the list)
|
|
75
|
+
if (configuredIn.length === 0 && configFiles.indexOf(configFile) === 0) {
|
|
76
|
+
const aliasBlock = `\n${marker}\n${aliasLine}\n`;
|
|
77
|
+
fs.appendFileSync(configFile, aliasBlock);
|
|
78
|
+
configuredIn.push(configFile);
|
|
79
|
+
console.log(`ā
Added ${ALIAS_NAME} alias to ${configFile}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (alreadyConfigured && configuredIn.length > 0) {
|
|
84
|
+
console.log(
|
|
85
|
+
`ā ${ALIAS_NAME} alias already configured in: ${configuredIn.join(', ')}`
|
|
86
|
+
);
|
|
87
|
+
} else if (configuredIn.length > 0) {
|
|
88
|
+
console.log(
|
|
89
|
+
` Run 'source ${configuredIn[0]}' or restart your terminal to use it`
|
|
90
|
+
);
|
|
91
|
+
console.log(` You can then use: ${ALIAS_NAME} [your message]`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
console.log(`\nš Usage:`);
|
|
95
|
+
console.log(
|
|
96
|
+
` ${ALIAS_NAME} # Start OpenCode with StackMemory`
|
|
97
|
+
);
|
|
98
|
+
console.log(` ${ALIAS_NAME} --auto-sync # With Linear auto-sync`);
|
|
99
|
+
console.log(
|
|
100
|
+
` ${ALIAS_NAME} --sync-interval=10 # Custom sync interval (minutes)`
|
|
101
|
+
);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.error('Error setting up alias:', error.message);
|
|
104
|
+
console.log('\nManual setup:');
|
|
105
|
+
console.log(`Add this line to your shell config file:`);
|
|
106
|
+
console.log(
|
|
107
|
+
`alias ${ALIAS_NAME}="${join(dirname(__dirname), WRAPPER_SCRIPT)}"`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (process.argv.includes('--check')) {
|
|
113
|
+
const configFiles = getShellConfigFiles();
|
|
114
|
+
let found = false;
|
|
115
|
+
|
|
116
|
+
for (const configFile of configFiles) {
|
|
117
|
+
if (fs.existsSync(configFile)) {
|
|
118
|
+
const config = fs.readFileSync(configFile, 'utf8');
|
|
119
|
+
if (config.includes(`alias ${ALIAS_NAME}=`)) {
|
|
120
|
+
console.log(`ā ${ALIAS_NAME} alias is configured in ${configFile}`);
|
|
121
|
+
found = true;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!found) {
|
|
128
|
+
console.log(`ā ${ALIAS_NAME} alias not found`);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
process.exit(0);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (process.argv.includes('--remove')) {
|
|
135
|
+
const configFiles = getShellConfigFiles();
|
|
136
|
+
let removed = false;
|
|
137
|
+
|
|
138
|
+
for (const configFile of configFiles) {
|
|
139
|
+
if (fs.existsSync(configFile)) {
|
|
140
|
+
let config = fs.readFileSync(configFile, 'utf8');
|
|
141
|
+
const marker = '# StackMemory OpenCode alias';
|
|
142
|
+
|
|
143
|
+
if (config.includes(marker)) {
|
|
144
|
+
// Remove the alias block
|
|
145
|
+
const lines = config.split('\n');
|
|
146
|
+
const newLines = [];
|
|
147
|
+
let skipNext = false;
|
|
148
|
+
|
|
149
|
+
for (const line of lines) {
|
|
150
|
+
if (line.includes(marker)) {
|
|
151
|
+
skipNext = true;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (skipNext && line.includes(`alias ${ALIAS_NAME}=`)) {
|
|
155
|
+
skipNext = false;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
skipNext = false;
|
|
159
|
+
newLines.push(line);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
fs.writeFileSync(configFile, newLines.join('\n'));
|
|
163
|
+
console.log(`ā
Removed ${ALIAS_NAME} alias from ${configFile}`);
|
|
164
|
+
removed = true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (!removed) {
|
|
170
|
+
console.log(`ā ${ALIAS_NAME} alias not found in any config file`);
|
|
171
|
+
}
|
|
172
|
+
process.exit(0);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
setupAlias();
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* StackMemory Claude Code Integration Setup
|
|
4
|
+
* Automatically configures Claude Code to use StackMemory MCP server
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { execSync } from 'child_process';
|
|
8
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import { homedir } from 'os';
|
|
11
|
+
|
|
12
|
+
const CLAUDE_CONFIG_DIR = join(homedir(), '.claude');
|
|
13
|
+
const CLAUDE_CONFIG_FILE = join(CLAUDE_CONFIG_DIR, 'config.json');
|
|
14
|
+
const STACKMEMORY_MCP_CONFIG = join(CLAUDE_CONFIG_DIR, 'stackmemory-mcp.json');
|
|
15
|
+
const HOOKS_DIR = join(CLAUDE_CONFIG_DIR, 'hooks');
|
|
16
|
+
const STACKMEMORY_HOOK = join(HOOKS_DIR, 'stackmemory_init.sh');
|
|
17
|
+
|
|
18
|
+
console.log('š Setting up StackMemory + Claude Code integration...\n');
|
|
19
|
+
|
|
20
|
+
// 1. Create Claude config directory
|
|
21
|
+
if (!existsSync(CLAUDE_CONFIG_DIR)) {
|
|
22
|
+
console.log('š Creating ~/.claude directory...');
|
|
23
|
+
mkdirSync(CLAUDE_CONFIG_DIR, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 2. Create hooks directory
|
|
27
|
+
if (!existsSync(HOOKS_DIR)) {
|
|
28
|
+
console.log('š Creating ~/.claude/hooks directory...');
|
|
29
|
+
mkdirSync(HOOKS_DIR, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 3. Create StackMemory MCP configuration
|
|
33
|
+
console.log('āļø Creating StackMemory MCP configuration...');
|
|
34
|
+
const mcpConfig = {
|
|
35
|
+
mcpServers: {
|
|
36
|
+
stackmemory: {
|
|
37
|
+
command: "stackmemory",
|
|
38
|
+
args: ["mcp-server"],
|
|
39
|
+
env: {
|
|
40
|
+
NODE_ENV: "production"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
writeFileSync(STACKMEMORY_MCP_CONFIG, JSON.stringify(mcpConfig, null, 2));
|
|
47
|
+
console.log(`ā
Created: ${STACKMEMORY_MCP_CONFIG}`);
|
|
48
|
+
|
|
49
|
+
// 4. Create session initialization hook
|
|
50
|
+
console.log('šŖ Creating StackMemory session hook...');
|
|
51
|
+
const hookScript = `#!/bin/bash
|
|
52
|
+
# StackMemory Session Initialization Hook
|
|
53
|
+
# Automatically loads context and starts frame tracking
|
|
54
|
+
|
|
55
|
+
if [ -d "./.stackmemory" ]; then
|
|
56
|
+
echo "š§ StackMemory context tracking active"
|
|
57
|
+
|
|
58
|
+
# Show current stack status
|
|
59
|
+
STACK_STATUS=$(stackmemory status --project 2>/dev/null)
|
|
60
|
+
if echo "$STACK_STATUS" | grep -q "Stack depth: 0"; then
|
|
61
|
+
echo "š Starting fresh work session"
|
|
62
|
+
else
|
|
63
|
+
echo "š Resuming context stack:"
|
|
64
|
+
echo "$STACK_STATUS" | grep -E "(Stack depth|Active frames|āā)" | head -5
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# Quick context summary
|
|
68
|
+
ACTIVE_TASKS=$(stackmemory status --project 2>/dev/null | grep -c "āā" || echo "0")
|
|
69
|
+
if [ "$ACTIVE_TASKS" -gt 0 ]; then
|
|
70
|
+
echo "š $ACTIVE_TASKS active frames loaded"
|
|
71
|
+
fi
|
|
72
|
+
fi
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
writeFileSync(STACKMEMORY_HOOK, hookScript);
|
|
76
|
+
execSync(`chmod +x "${STACKMEMORY_HOOK}"`);
|
|
77
|
+
console.log(`ā
Created: ${STACKMEMORY_HOOK}`);
|
|
78
|
+
|
|
79
|
+
// 4b. Create startup hook with Linear sync
|
|
80
|
+
const STARTUP_HOOK = join(HOOKS_DIR, 'on-startup');
|
|
81
|
+
console.log('šŖ Creating StackMemory startup hook with Linear sync...');
|
|
82
|
+
const startupHookScript = `#!/bin/bash
|
|
83
|
+
# Auto-start StackMemory monitor on Claude Code startup
|
|
84
|
+
|
|
85
|
+
# Start monitor if project has StackMemory
|
|
86
|
+
if [ -d ".stackmemory" ]; then
|
|
87
|
+
stackmemory monitor --start 2>/dev/null || true
|
|
88
|
+
echo "š StackMemory monitor started"
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# Load previous handoff if exists
|
|
92
|
+
if [ -d ".stackmemory/handoffs" ]; then
|
|
93
|
+
stackmemory handoff --load 2>/dev/null || true
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Check and restore from ledger if needed
|
|
97
|
+
stackmemory clear --restore 2>/dev/null || true
|
|
98
|
+
|
|
99
|
+
# Trigger Linear sync on StackMemory instance loading
|
|
100
|
+
if [ -d ".stackmemory" ] && [ -f "scripts/sync-linear-graphql.js" ]; then
|
|
101
|
+
echo "š Triggering Linear sync..."
|
|
102
|
+
npm run linear:sync >/dev/null 2>&1 || node scripts/sync-linear-graphql.js >/dev/null 2>&1 || true
|
|
103
|
+
echo "ā
Linear sync triggered"
|
|
104
|
+
fi
|
|
105
|
+
`;
|
|
106
|
+
|
|
107
|
+
writeFileSync(STARTUP_HOOK, startupHookScript);
|
|
108
|
+
execSync(`chmod +x "${STARTUP_HOOK}"`);
|
|
109
|
+
console.log(`ā
Created: ${STARTUP_HOOK}`);
|
|
110
|
+
|
|
111
|
+
// 5. Update or create Claude config.json
|
|
112
|
+
console.log('š Updating Claude Code configuration...');
|
|
113
|
+
|
|
114
|
+
let claudeConfig = {};
|
|
115
|
+
if (existsSync(CLAUDE_CONFIG_FILE)) {
|
|
116
|
+
try {
|
|
117
|
+
const existing = readFileSync(CLAUDE_CONFIG_FILE, 'utf-8');
|
|
118
|
+
claudeConfig = JSON.parse(existing);
|
|
119
|
+
console.log(' Found existing config, merging...');
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.log(' Existing config invalid, creating new...');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Merge configuration
|
|
126
|
+
if (!claudeConfig.mcp) {
|
|
127
|
+
claudeConfig.mcp = {};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (!claudeConfig.mcp.configFiles) {
|
|
131
|
+
claudeConfig.mcp.configFiles = [];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Add StackMemory MCP config if not already present
|
|
135
|
+
if (!claudeConfig.mcp.configFiles.includes(STACKMEMORY_MCP_CONFIG)) {
|
|
136
|
+
claudeConfig.mcp.configFiles.push(STACKMEMORY_MCP_CONFIG);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Update session start hook
|
|
140
|
+
if (!claudeConfig.hooks) {
|
|
141
|
+
claudeConfig.hooks = {};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (!claudeConfig.hooks.session_start) {
|
|
145
|
+
claudeConfig.hooks.session_start = [];
|
|
146
|
+
} else if (typeof claudeConfig.hooks.session_start === 'string') {
|
|
147
|
+
claudeConfig.hooks.session_start = [claudeConfig.hooks.session_start];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Add StackMemory hook if not already present
|
|
151
|
+
if (!claudeConfig.hooks.session_start.includes(STACKMEMORY_HOOK)) {
|
|
152
|
+
claudeConfig.hooks.session_start.unshift(STACKMEMORY_HOOK);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
writeFileSync(CLAUDE_CONFIG_FILE, JSON.stringify(claudeConfig, null, 2));
|
|
156
|
+
console.log(`ā
Updated: ${CLAUDE_CONFIG_FILE}`);
|
|
157
|
+
|
|
158
|
+
// 6. Verify setup
|
|
159
|
+
console.log('\nš Verifying setup...');
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
// Check if stackmemory command is available
|
|
163
|
+
execSync('stackmemory --version', { stdio: 'ignore' });
|
|
164
|
+
console.log('ā
StackMemory CLI available');
|
|
165
|
+
} catch {
|
|
166
|
+
console.log('ā ļø StackMemory CLI not in PATH - you may need to restart your terminal');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
// Check if Claude Code is available
|
|
171
|
+
execSync('claude --help', { stdio: 'ignore' });
|
|
172
|
+
console.log('ā
Claude Code available');
|
|
173
|
+
} catch {
|
|
174
|
+
console.log('ā ļø Claude Code not found - install from https://claude.ai/code');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 7. Usage instructions
|
|
178
|
+
console.log(`
|
|
179
|
+
š Setup complete!
|
|
180
|
+
|
|
181
|
+
š To use StackMemory with Claude Code:
|
|
182
|
+
|
|
183
|
+
1. Initialize StackMemory in your project:
|
|
184
|
+
cd your-project
|
|
185
|
+
stackmemory init
|
|
186
|
+
|
|
187
|
+
2. Start Claude Code (will auto-load StackMemory):
|
|
188
|
+
claude
|
|
189
|
+
|
|
190
|
+
3. Or explicitly load StackMemory MCP:
|
|
191
|
+
claude --mcp-config ~/.claude/stackmemory-mcp.json
|
|
192
|
+
|
|
193
|
+
š Available MCP tools in Claude Code:
|
|
194
|
+
⢠start_frame, close_frame - Frame lifecycle
|
|
195
|
+
⢠create_task, get_active_tasks - Task management
|
|
196
|
+
⢠linear_sync, linear_status - Linear integration
|
|
197
|
+
⢠get_context, add_decision - Context management
|
|
198
|
+
|
|
199
|
+
š Full documentation: docs/claude-code-integration.md
|
|
200
|
+
|
|
201
|
+
š§ To reconfigure: npm run claude:setup
|
|
202
|
+
`);
|
|
203
|
+
|
|
204
|
+
console.log('⨠Integration setup successful!');
|