@stackmemoryai/stackmemory 0.3.17 → 0.3.19
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/claude-sm.js +51 -5
- package/dist/cli/claude-sm.js.map +2 -2
- package/dist/cli/codex-sm.js +52 -19
- package/dist/cli/codex-sm.js.map +2 -2
- package/dist/cli/commands/db.js +143 -0
- package/dist/cli/commands/db.js.map +7 -0
- package/dist/cli/commands/login.js +50 -0
- package/dist/cli/commands/login.js.map +7 -0
- package/dist/cli/commands/migrate.js +178 -0
- package/dist/cli/commands/migrate.js.map +7 -0
- package/dist/cli/commands/onboard.js +158 -2
- package/dist/cli/commands/onboard.js.map +2 -2
- package/dist/cli/commands/skills.js +15 -2
- package/dist/cli/commands/skills.js.map +2 -2
- package/dist/cli/index.js +118 -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-database.js +1 -0
- package/dist/core/context/frame-database.js.map +2 -2
- package/dist/core/context/frame-manager.js +59 -2
- package/dist/core/context/frame-manager.js.map +2 -2
- package/dist/core/database/database-adapter.js +6 -1
- package/dist/core/database/database-adapter.js.map +2 -2
- package/dist/core/database/sqlite-adapter.js +60 -2
- package/dist/core/database/sqlite-adapter.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/index.js +843 -82
- package/dist/servers/railway/index.js.map +3 -3
- 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 +13 -21
- 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-railway-deployment.sh +37 -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/scripts/verify-railway-schema.ts +35 -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,162 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Smart Compaction Detection and Auto-Rehydration
|
|
5
|
+
* Monitors Claude Code context and triggers rehydration when needed
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { exec } = require('child_process');
|
|
11
|
+
const { promisify } = require('util');
|
|
12
|
+
|
|
13
|
+
const execAsync = promisify(exec);
|
|
14
|
+
|
|
15
|
+
// Compaction detection patterns
|
|
16
|
+
const COMPACTION_INDICATORS = [
|
|
17
|
+
'earlier in this conversation',
|
|
18
|
+
'previously discussed',
|
|
19
|
+
'as mentioned before',
|
|
20
|
+
'summarized for brevity',
|
|
21
|
+
'[conversation compressed]',
|
|
22
|
+
'[context truncated]',
|
|
23
|
+
'⏺ Compact summary',
|
|
24
|
+
'Previous Conversation Compacted',
|
|
25
|
+
'Referenced file',
|
|
26
|
+
/⎿.*Referenced file/,
|
|
27
|
+
/⎿.*Read.*\(\d+ lines\)/
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
class CompactionDetector {
|
|
31
|
+
constructor() {
|
|
32
|
+
this.logFile = path.join(process.cwd(), '.stackmemory', 'compaction.log');
|
|
33
|
+
this.lastCheck = 0;
|
|
34
|
+
this.ensureLogDirectory();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
ensureLogDirectory() {
|
|
38
|
+
const dir = path.dirname(this.logFile);
|
|
39
|
+
if (!fs.existsSync(dir)) {
|
|
40
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
log(message) {
|
|
45
|
+
const timestamp = new Date().toISOString();
|
|
46
|
+
const logEntry = `${timestamp}: ${message}\n`;
|
|
47
|
+
|
|
48
|
+
console.log(`🔍 ${message}`);
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
fs.appendFileSync(this.logFile, logEntry);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('Failed to write to log:', error.message);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async detectCompaction(inputText) {
|
|
58
|
+
if (!inputText) return false;
|
|
59
|
+
|
|
60
|
+
const lowerText = inputText.toLowerCase();
|
|
61
|
+
|
|
62
|
+
// Check for exact string matches
|
|
63
|
+
const hasStringIndicator = COMPACTION_INDICATORS.some(indicator => {
|
|
64
|
+
if (typeof indicator === 'string') {
|
|
65
|
+
return lowerText.includes(indicator.toLowerCase());
|
|
66
|
+
} else if (indicator instanceof RegExp) {
|
|
67
|
+
return indicator.test(inputText);
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Check for compact summary patterns
|
|
73
|
+
const hasCompactPattern = /⏺.*compact summary|compact.*summary/i.test(inputText);
|
|
74
|
+
|
|
75
|
+
// Check for conversation compression indicators
|
|
76
|
+
const hasCompressionPattern = /previous conversation.*compacted|context.*truncated/i.test(inputText);
|
|
77
|
+
|
|
78
|
+
// Check for file reference patterns (common after compaction)
|
|
79
|
+
const hasFileReferencePattern = /⎿.*referenced file|⎿.*read.*\(\d+ lines\)/i.test(inputText);
|
|
80
|
+
|
|
81
|
+
return hasStringIndicator || hasCompactPattern || hasCompressionPattern || hasFileReferencePattern;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async triggerRehydration() {
|
|
85
|
+
this.log('Compaction detected, triggering context rehydration...');
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
// Check if StackMemory is available
|
|
89
|
+
await execAsync('stackmemory status');
|
|
90
|
+
|
|
91
|
+
// Check for existing checkpoints
|
|
92
|
+
const { stdout: listOutput } = await execAsync('stackmemory context rehydrate --list');
|
|
93
|
+
|
|
94
|
+
if (listOutput.includes('No rehydration checkpoints')) {
|
|
95
|
+
this.log('No checkpoints found, creating initial checkpoint...');
|
|
96
|
+
await execAsync('stackmemory context rehydrate --create');
|
|
97
|
+
this.log('Initial checkpoint created');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Perform rehydration
|
|
101
|
+
this.log('Performing context rehydration...');
|
|
102
|
+
const { stdout: rehydrateOutput } = await execAsync('stackmemory context rehydrate --verbose');
|
|
103
|
+
|
|
104
|
+
this.log('Context rehydration completed successfully');
|
|
105
|
+
console.log('\n✅ Rich context restored! Your session now includes:');
|
|
106
|
+
console.log(' 📁 File snapshots with content previews');
|
|
107
|
+
console.log(' 🗺️ Project structure and relationships');
|
|
108
|
+
console.log(' 🧠 Previous decisions and reasoning');
|
|
109
|
+
console.log(' 🎯 Active workflows and focus areas\n');
|
|
110
|
+
|
|
111
|
+
return true;
|
|
112
|
+
|
|
113
|
+
} catch (error) {
|
|
114
|
+
this.log(`Context rehydration failed: ${error.message}`);
|
|
115
|
+
console.error('❌ Failed to rehydrate context:', error.message);
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async checkInput(text) {
|
|
121
|
+
if (await this.detectCompaction(text)) {
|
|
122
|
+
// Debounce multiple detections
|
|
123
|
+
const now = Date.now();
|
|
124
|
+
if (now - this.lastCheck < 30000) { // 30 second cooldown
|
|
125
|
+
this.log('Compaction detected but within cooldown period, skipping...');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
this.lastCheck = now;
|
|
130
|
+
await this.triggerRehydration();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// CLI usage
|
|
136
|
+
async function main() {
|
|
137
|
+
const detector = new CompactionDetector();
|
|
138
|
+
|
|
139
|
+
if (process.argv.length > 2) {
|
|
140
|
+
// Check specific text
|
|
141
|
+
const text = process.argv.slice(2).join(' ');
|
|
142
|
+
const detected = await detector.detectCompaction(text);
|
|
143
|
+
console.log(`Compaction detected: ${detected}`);
|
|
144
|
+
|
|
145
|
+
if (detected) {
|
|
146
|
+
await detector.triggerRehydration();
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
// Monitor mode (could be enhanced to monitor clipboard, files, etc.)
|
|
150
|
+
console.log('📡 StackMemory Compaction Detector Ready');
|
|
151
|
+
console.log('💡 Usage: node detect-and-rehydrate.js "text to check"');
|
|
152
|
+
console.log('🔧 Integrate with Claude Code hooks for automatic detection');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Export for use as module
|
|
157
|
+
module.exports = { CompactionDetector };
|
|
158
|
+
|
|
159
|
+
// Run if called directly
|
|
160
|
+
if (require.main === module) {
|
|
161
|
+
main().catch(console.error);
|
|
162
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Smart Compaction Detection and Auto-Rehydration
|
|
5
|
+
* Monitors Claude Code context and triggers rehydration when needed
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import { exec } from 'child_process';
|
|
11
|
+
import { promisify } from 'util';
|
|
12
|
+
import { fileURLToPath } from 'url';
|
|
13
|
+
|
|
14
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
15
|
+
const __dirname = path.dirname(__filename);
|
|
16
|
+
|
|
17
|
+
const execAsync = promisify(exec);
|
|
18
|
+
|
|
19
|
+
// Compaction detection patterns
|
|
20
|
+
const COMPACTION_INDICATORS = [
|
|
21
|
+
'earlier in this conversation',
|
|
22
|
+
'previously discussed',
|
|
23
|
+
'as mentioned before',
|
|
24
|
+
'summarized for brevity',
|
|
25
|
+
'[conversation compressed]',
|
|
26
|
+
'[context truncated]',
|
|
27
|
+
'⏺ Compact summary',
|
|
28
|
+
'Previous Conversation Compacted',
|
|
29
|
+
'Referenced file',
|
|
30
|
+
/⎿.*Referenced file/,
|
|
31
|
+
/⎿.*Read.*\(\d+ lines\)/
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
class CompactionDetector {
|
|
35
|
+
constructor() {
|
|
36
|
+
this.logFile = path.join(process.cwd(), '.stackmemory', 'compaction.log');
|
|
37
|
+
this.lastCheck = 0;
|
|
38
|
+
this.ensureLogDirectory();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
ensureLogDirectory() {
|
|
42
|
+
const dir = path.dirname(this.logFile);
|
|
43
|
+
if (!fs.existsSync(dir)) {
|
|
44
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
log(message) {
|
|
49
|
+
const timestamp = new Date().toISOString();
|
|
50
|
+
const logEntry = `${timestamp}: ${message}\n`;
|
|
51
|
+
|
|
52
|
+
console.log(`🔍 ${message}`);
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
fs.appendFileSync(this.logFile, logEntry);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error('Failed to write to log:', error.message);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async detectCompaction(inputText) {
|
|
62
|
+
if (!inputText) return false;
|
|
63
|
+
|
|
64
|
+
const lowerText = inputText.toLowerCase();
|
|
65
|
+
|
|
66
|
+
// Check for exact string matches
|
|
67
|
+
const hasStringIndicator = COMPACTION_INDICATORS.some(indicator => {
|
|
68
|
+
if (typeof indicator === 'string') {
|
|
69
|
+
return lowerText.includes(indicator.toLowerCase());
|
|
70
|
+
} else if (indicator instanceof RegExp) {
|
|
71
|
+
return indicator.test(inputText);
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Check for compact summary patterns
|
|
77
|
+
const hasCompactPattern = /⏺.*compact summary|compact.*summary/i.test(inputText);
|
|
78
|
+
|
|
79
|
+
// Check for conversation compression indicators
|
|
80
|
+
const hasCompressionPattern = /previous conversation.*compacted|context.*truncated/i.test(inputText);
|
|
81
|
+
|
|
82
|
+
// Check for file reference patterns (common after compaction)
|
|
83
|
+
const hasFileReferencePattern = /⎿.*referenced file|⎿.*read.*\(\d+ lines\)/i.test(inputText);
|
|
84
|
+
|
|
85
|
+
return hasStringIndicator || hasCompactPattern || hasCompressionPattern || hasFileReferencePattern;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async triggerRehydration() {
|
|
89
|
+
this.log('Compaction detected, triggering context rehydration...');
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
// Check if StackMemory is available
|
|
93
|
+
await execAsync('~/.stackmemory/bin/stackmemory status');
|
|
94
|
+
|
|
95
|
+
// Check for existing checkpoints
|
|
96
|
+
const { stdout: listOutput } = await execAsync('~/.stackmemory/bin/stackmemory context rehydrate --list');
|
|
97
|
+
|
|
98
|
+
if (listOutput.includes('No rehydration checkpoints')) {
|
|
99
|
+
this.log('No checkpoints found, creating initial checkpoint...');
|
|
100
|
+
await execAsync('~/.stackmemory/bin/stackmemory context rehydrate --create');
|
|
101
|
+
this.log('Initial checkpoint created');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Perform rehydration
|
|
105
|
+
this.log('Performing context rehydration...');
|
|
106
|
+
const { stdout: rehydrateOutput } = await execAsync('~/.stackmemory/bin/stackmemory context rehydrate --verbose');
|
|
107
|
+
|
|
108
|
+
this.log('Context rehydration completed successfully');
|
|
109
|
+
console.log('\n✅ Rich context restored! Your session now includes:');
|
|
110
|
+
console.log(' 📁 File snapshots with content previews');
|
|
111
|
+
console.log(' 🗺️ Project structure and relationships');
|
|
112
|
+
console.log(' 🧠 Previous decisions and reasoning');
|
|
113
|
+
console.log(' 🎯 Active workflows and focus areas\n');
|
|
114
|
+
|
|
115
|
+
return true;
|
|
116
|
+
|
|
117
|
+
} catch (error) {
|
|
118
|
+
this.log(`Context rehydration failed: ${error.message}`);
|
|
119
|
+
console.error('❌ Failed to rehydrate context:', error.message);
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async checkInput(text) {
|
|
125
|
+
if (await this.detectCompaction(text)) {
|
|
126
|
+
// Debounce multiple detections
|
|
127
|
+
const now = Date.now();
|
|
128
|
+
if (now - this.lastCheck < 30000) { // 30 second cooldown
|
|
129
|
+
this.log('Compaction detected but within cooldown period, skipping...');
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
this.lastCheck = now;
|
|
134
|
+
await this.triggerRehydration();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// CLI usage
|
|
140
|
+
async function main() {
|
|
141
|
+
const detector = new CompactionDetector();
|
|
142
|
+
|
|
143
|
+
if (process.argv.length > 2) {
|
|
144
|
+
// Check specific text
|
|
145
|
+
const text = process.argv.slice(2).join(' ');
|
|
146
|
+
const detected = await detector.detectCompaction(text);
|
|
147
|
+
console.log(`Compaction detected: ${detected}`);
|
|
148
|
+
|
|
149
|
+
if (detected) {
|
|
150
|
+
await detector.triggerRehydration();
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
// Monitor mode
|
|
154
|
+
console.log('📡 StackMemory Compaction Detector Ready');
|
|
155
|
+
console.log('💡 Usage: node detect-and-rehydrate.mjs "text to check"');
|
|
156
|
+
console.log('🔧 Integrate with Claude Code hooks for automatic detection');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Run if called directly
|
|
161
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
162
|
+
main().catch(console.error);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export { CompactionDetector };
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Create demo tasks to review current system and plan Linear integration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import Database from 'better-sqlite3';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
import { PebblesTaskStore } from './dist/src/pebbles/pebbles-task-store.js';
|
|
9
|
+
import { FrameManager } from './dist/src/core/frame-manager.js';
|
|
10
|
+
|
|
11
|
+
const projectRoot = process.cwd();
|
|
12
|
+
const dbPath = join(projectRoot, '.stackmemory', 'context.db');
|
|
13
|
+
const db = new Database(dbPath);
|
|
14
|
+
|
|
15
|
+
// Initialize managers
|
|
16
|
+
const frameManager = new FrameManager(db, 'stackmemory-demo');
|
|
17
|
+
const taskStore = new PebblesTaskStore(projectRoot, db);
|
|
18
|
+
|
|
19
|
+
console.log('🚀 Creating demo development tasks...\n');
|
|
20
|
+
|
|
21
|
+
// Create a main development frame
|
|
22
|
+
const mainFrameId = frameManager.createFrame({
|
|
23
|
+
type: 'task',
|
|
24
|
+
name: 'StackMemory v0.3.0 Development',
|
|
25
|
+
inputs: {
|
|
26
|
+
constraints: [
|
|
27
|
+
'Must maintain git-native architecture',
|
|
28
|
+
'Zero infrastructure requirements',
|
|
29
|
+
],
|
|
30
|
+
goals: [
|
|
31
|
+
'Linear integration',
|
|
32
|
+
'Enhanced task management',
|
|
33
|
+
'Team collaboration',
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
console.log(`📋 Created main frame: ${mainFrameId}\n`);
|
|
39
|
+
|
|
40
|
+
// Create development tasks
|
|
41
|
+
const tasks = [
|
|
42
|
+
{
|
|
43
|
+
title: 'Linear API Integration',
|
|
44
|
+
description:
|
|
45
|
+
'Implement bi-directional sync with Linear for team collaboration. Include webhook handlers, status mapping, and conflict resolution.',
|
|
46
|
+
priority: 'high',
|
|
47
|
+
estimatedEffort: 240, // 4 hours
|
|
48
|
+
tags: ['integration', 'linear', 'api', 'team'],
|
|
49
|
+
dependsOn: [],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
title: 'Enhanced CLI Commands',
|
|
53
|
+
description:
|
|
54
|
+
'Add comprehensive task management commands to StackMemory CLI. Include list, update, create, and dependency management.',
|
|
55
|
+
priority: 'medium',
|
|
56
|
+
estimatedEffort: 120, // 2 hours
|
|
57
|
+
tags: ['cli', 'ux', 'commands'],
|
|
58
|
+
dependsOn: [],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
title: 'Git Hooks Integration',
|
|
62
|
+
description:
|
|
63
|
+
'Automate task state sync with git workflow. Pre-commit validation, post-commit updates, and branch-based task isolation.',
|
|
64
|
+
priority: 'medium',
|
|
65
|
+
estimatedEffort: 90, // 1.5 hours
|
|
66
|
+
tags: ['git', 'automation', 'hooks'],
|
|
67
|
+
dependsOn: [],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
title: 'Task Analytics Dashboard',
|
|
71
|
+
description:
|
|
72
|
+
'Web UI for task metrics and project insights. Show completion rates, effort accuracy, blocking issues, and team performance.',
|
|
73
|
+
priority: 'low',
|
|
74
|
+
estimatedEffort: 480, // 8 hours
|
|
75
|
+
tags: ['ui', 'analytics', 'web', 'dashboard'],
|
|
76
|
+
dependsOn: [],
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
title: 'Performance Optimization',
|
|
80
|
+
description:
|
|
81
|
+
'Optimize context assembly and JSONL parsing performance. Implement lazy loading, caching, and parallel processing.',
|
|
82
|
+
priority: 'high',
|
|
83
|
+
estimatedEffort: 180, // 3 hours
|
|
84
|
+
tags: ['performance', 'optimization', 'caching'],
|
|
85
|
+
dependsOn: [],
|
|
86
|
+
},
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
const createdTasks = [];
|
|
90
|
+
|
|
91
|
+
for (const task of tasks) {
|
|
92
|
+
const taskId = taskStore.createTask({
|
|
93
|
+
title: task.title,
|
|
94
|
+
description: task.description,
|
|
95
|
+
priority: task.priority,
|
|
96
|
+
frameId: mainFrameId,
|
|
97
|
+
tags: task.tags,
|
|
98
|
+
estimatedEffort: task.estimatedEffort,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
createdTasks.push({ id: taskId, ...task });
|
|
102
|
+
console.log(`✅ Created: ${task.title} (${taskId})`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
console.log(`\n📊 Created ${createdTasks.length} development tasks`);
|
|
106
|
+
|
|
107
|
+
// Set up some task dependencies
|
|
108
|
+
console.log('\n🔗 Setting up task dependencies...');
|
|
109
|
+
|
|
110
|
+
// Find Linear integration task
|
|
111
|
+
const linearTask = createdTasks.find((t) => t.title.includes('Linear'));
|
|
112
|
+
const cliTask = createdTasks.find((t) => t.title.includes('CLI'));
|
|
113
|
+
|
|
114
|
+
if (linearTask && cliTask) {
|
|
115
|
+
// CLI commands should depend on Linear integration being available
|
|
116
|
+
taskStore.addDependency(cliTask.id, linearTask.id);
|
|
117
|
+
console.log(`🔗 ${cliTask.title} depends on ${linearTask.title}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Start the Linear integration task as in_progress
|
|
121
|
+
if (linearTask) {
|
|
122
|
+
taskStore.updateTaskStatus(linearTask.id, 'in_progress');
|
|
123
|
+
console.log(`🚀 Started: ${linearTask.title}`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
console.log('\n📈 Current metrics:');
|
|
127
|
+
const metrics = taskStore.getMetrics();
|
|
128
|
+
console.log(`- Total tasks: ${metrics.total_tasks}`);
|
|
129
|
+
console.log(`- In progress: ${metrics.by_status.in_progress || 0}`);
|
|
130
|
+
console.log(`- Pending: ${metrics.by_status.pending || 0}`);
|
|
131
|
+
console.log(`- High priority: ${metrics.by_priority.high || 0}`);
|
|
132
|
+
|
|
133
|
+
console.log('\n🎯 Active tasks:');
|
|
134
|
+
const activeTasks = taskStore.getActiveTasks();
|
|
135
|
+
activeTasks.forEach((task) => {
|
|
136
|
+
const status = task.status.replace('_', ' ').toUpperCase();
|
|
137
|
+
const effort = task.estimated_effort ? ` (${task.estimated_effort}m)` : '';
|
|
138
|
+
console.log(`- [${status}] ${task.title}${effort}`);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
console.log('\n✅ Demo tasks created! Use MCP tools to interact with them.');
|
|
142
|
+
|
|
143
|
+
db.close();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Test the actual issue with a simpler approach
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
|
|
4
|
+
console.log('Testing simple UUID generation...');
|
|
5
|
+
const testId = uuidv4();
|
|
6
|
+
console.log('UUID result:', testId);
|
|
7
|
+
console.log('Type:', typeof testId);
|
|
8
|
+
|
|
9
|
+
// Let me check if this is a vitest issue
|
|
10
|
+
const simpleFunction = function () {
|
|
11
|
+
return 'string-result';
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const result = simpleFunction();
|
|
15
|
+
console.log('Simple function result:', result);
|
|
16
|
+
console.log('Simple function type:', typeof result);
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Demo: Linear Auto-Sync Functionality
|
|
4
|
+
* Demonstrates how the auto-sync works locally
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
initializeAutoSync,
|
|
9
|
+
getAutoSyncService,
|
|
10
|
+
} from './dist/src/integrations/linear-auto-sync.js';
|
|
11
|
+
|
|
12
|
+
console.log('🚀 Linear Auto-Sync Demo\n');
|
|
13
|
+
|
|
14
|
+
// Simulate a project directory
|
|
15
|
+
const projectRoot = process.cwd();
|
|
16
|
+
|
|
17
|
+
console.log('📋 Demo Scenario:');
|
|
18
|
+
console.log('- Configure auto-sync with 30-second intervals');
|
|
19
|
+
console.log('- Show service status and configuration');
|
|
20
|
+
console.log(
|
|
21
|
+
'- Simulate what happens during sync (without actual Linear connection)'
|
|
22
|
+
);
|
|
23
|
+
console.log('- Demonstrate configuration management\n');
|
|
24
|
+
|
|
25
|
+
// Step 1: Initialize auto-sync service
|
|
26
|
+
console.log('1️⃣ Initializing auto-sync service...');
|
|
27
|
+
const autoSyncService = initializeAutoSync(projectRoot, {
|
|
28
|
+
interval: 0.5, // 30 seconds for demo
|
|
29
|
+
direction: 'bidirectional',
|
|
30
|
+
conflictResolution: 'newest_wins',
|
|
31
|
+
enabled: true,
|
|
32
|
+
retryAttempts: 2,
|
|
33
|
+
retryDelay: 5000, // 5 seconds
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
console.log('✅ Auto-sync service initialized\n');
|
|
37
|
+
|
|
38
|
+
// Step 2: Show service status
|
|
39
|
+
console.log('2️⃣ Current service status:');
|
|
40
|
+
const status = autoSyncService.getStatus();
|
|
41
|
+
console.log(` Running: ${status.running ? '✅' : '❌'}`);
|
|
42
|
+
console.log(` Interval: ${status.config.interval} minutes`);
|
|
43
|
+
console.log(` Direction: ${status.config.direction}`);
|
|
44
|
+
console.log(` Conflict Resolution: ${status.config.conflictResolution}`);
|
|
45
|
+
console.log(` Retry Attempts: ${status.config.retryAttempts}`);
|
|
46
|
+
|
|
47
|
+
if (status.config.quietHours) {
|
|
48
|
+
console.log(
|
|
49
|
+
` Quiet Hours: ${status.config.quietHours.start}:00 - ${status.config.quietHours.end}:00`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
console.log('\n');
|
|
54
|
+
|
|
55
|
+
// Step 3: Simulate configuration updates
|
|
56
|
+
console.log('3️⃣ Demonstrating configuration updates...');
|
|
57
|
+
autoSyncService.updateConfig({
|
|
58
|
+
interval: 1, // Change to 1 minute
|
|
59
|
+
conflictResolution: 'linear_wins',
|
|
60
|
+
});
|
|
61
|
+
console.log('✅ Updated: interval=1min, conflict_resolution=linear_wins\n');
|
|
62
|
+
|
|
63
|
+
// Step 4: Show updated status
|
|
64
|
+
console.log('4️⃣ Updated service status:');
|
|
65
|
+
const updatedStatus = autoSyncService.getStatus();
|
|
66
|
+
console.log(` Interval: ${updatedStatus.config.interval} minutes`);
|
|
67
|
+
console.log(
|
|
68
|
+
` Conflict Resolution: ${updatedStatus.config.conflictResolution}\n`
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
// Step 5: Demonstrate the auto-sync would work with Linear
|
|
72
|
+
console.log('5️⃣ How auto-sync works with Linear:');
|
|
73
|
+
console.log('');
|
|
74
|
+
console.log('🔄 **Automatic Synchronization Process:**');
|
|
75
|
+
console.log(' 1. Every N minutes (configurable), check for changes');
|
|
76
|
+
console.log(' 2. Sync StackMemory tasks → Linear issues');
|
|
77
|
+
console.log(' 3. Sync Linear issues → StackMemory task updates');
|
|
78
|
+
console.log(
|
|
79
|
+
' 4. Handle conflicts based on strategy (newest_wins, linear_wins, etc.)'
|
|
80
|
+
);
|
|
81
|
+
console.log(' 5. Log results and schedule next sync');
|
|
82
|
+
console.log('');
|
|
83
|
+
console.log('📊 **Status Mapping:**');
|
|
84
|
+
console.log(' StackMemory pending → Linear Backlog');
|
|
85
|
+
console.log(' StackMemory in_progress → Linear In Progress');
|
|
86
|
+
console.log(' StackMemory completed → Linear Done');
|
|
87
|
+
console.log(' StackMemory blocked → Linear Blocked');
|
|
88
|
+
console.log('');
|
|
89
|
+
console.log('⚡ **Smart Features:**');
|
|
90
|
+
console.log(' • Quiet hours (no sync 10pm-7am by default)');
|
|
91
|
+
console.log(' • Automatic retry with exponential backoff');
|
|
92
|
+
console.log(' • Conflict detection and resolution');
|
|
93
|
+
console.log(' • Persistent configuration');
|
|
94
|
+
console.log(' • Background service support');
|
|
95
|
+
console.log('');
|
|
96
|
+
|
|
97
|
+
// Step 6: Show NPM integration
|
|
98
|
+
console.log('6️⃣ NPM Package Integration:');
|
|
99
|
+
console.log('');
|
|
100
|
+
console.log('📦 **Available Commands:**');
|
|
101
|
+
console.log(' npm run linear:setup # Setup Linear OAuth');
|
|
102
|
+
console.log(' npm run linear:status # Check integration status');
|
|
103
|
+
console.log(' npm run linear:config # View/edit configuration');
|
|
104
|
+
console.log(' npm run linear:auto-sync # Start auto-sync service');
|
|
105
|
+
console.log('');
|
|
106
|
+
console.log('🔧 **Manual Commands:**');
|
|
107
|
+
console.log(' stackmemory linear config --set-interval 10');
|
|
108
|
+
console.log(' stackmemory linear auto-sync --start');
|
|
109
|
+
console.log(' stackmemory linear force-sync');
|
|
110
|
+
console.log('');
|
|
111
|
+
|
|
112
|
+
// Step 7: Cleanup
|
|
113
|
+
console.log('7️⃣ Stopping demo service...');
|
|
114
|
+
autoSyncService.stop();
|
|
115
|
+
console.log('✅ Demo completed!\n');
|
|
116
|
+
|
|
117
|
+
console.log('🎯 **To Use in Production:**');
|
|
118
|
+
console.log('1. Set up Linear OAuth: stackmemory linear setup');
|
|
119
|
+
console.log('2. Authorize integration: stackmemory linear authorize <code>');
|
|
120
|
+
console.log(
|
|
121
|
+
'3. Configure auto-sync: stackmemory linear config --set-interval 5'
|
|
122
|
+
);
|
|
123
|
+
console.log('4. Start auto-sync: stackmemory linear auto-sync --start');
|
|
124
|
+
console.log('');
|
|
125
|
+
console.log('📖 **Documentation:**');
|
|
126
|
+
console.log(' All settings persist in .stackmemory/linear-auto-sync.json');
|
|
127
|
+
console.log(' Auto-sync runs as a background process within the npm package');
|
|
128
|
+
console.log(' No external services required - everything runs locally');
|