@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,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { SharedContextLayer } from './dist/core/context/shared-context-layer.js';
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
|
|
10
|
+
async function testPersistence() {
|
|
11
|
+
console.log('Testing StackMemory Persistence...\n');
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
// Initialize shared context layer
|
|
15
|
+
const layer = new SharedContextLayer();
|
|
16
|
+
await layer.initialize();
|
|
17
|
+
console.log('ā
SharedContextLayer initialized');
|
|
18
|
+
|
|
19
|
+
// Add test context
|
|
20
|
+
const testFrame = {
|
|
21
|
+
type: 'test',
|
|
22
|
+
name: 'Persistence test frame',
|
|
23
|
+
tags: ['test', 'persistence', 'verification'],
|
|
24
|
+
data: {
|
|
25
|
+
timestamp: new Date().toISOString(),
|
|
26
|
+
test_id: `test-${Date.now()}`,
|
|
27
|
+
message: 'This is a test frame to verify persistence'
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
await layer.addToSharedContext(testFrame);
|
|
32
|
+
console.log('ā
Added test frame to shared context');
|
|
33
|
+
|
|
34
|
+
// Query to verify it's there
|
|
35
|
+
const results = await layer.querySharedContext({ tags: ['test', 'persistence'] });
|
|
36
|
+
console.log(`ā
Query returned ${results.length} matching frames`);
|
|
37
|
+
|
|
38
|
+
// Get the full context
|
|
39
|
+
const context = await layer.getSharedContext();
|
|
40
|
+
console.log('\nContext Summary:');
|
|
41
|
+
console.log(` Total sessions: ${context.sessions?.length || 0}`);
|
|
42
|
+
console.log(` Global patterns: ${context.globalPatterns?.length || 0}`);
|
|
43
|
+
console.log(` Decision log entries: ${context.decisionLog?.length || 0}`);
|
|
44
|
+
console.log(` Last updated: ${new Date(context.lastUpdated).toLocaleString()}`);
|
|
45
|
+
|
|
46
|
+
// Check persistence file
|
|
47
|
+
const contextPath = path.join(process.env.HOME, '.stackmemory', 'data', 'shared-context.json');
|
|
48
|
+
try {
|
|
49
|
+
const fileContent = await fs.readFile(contextPath, 'utf-8');
|
|
50
|
+
const savedContext = JSON.parse(fileContent);
|
|
51
|
+
console.log(`\nā
Persistence file exists at: ${contextPath}`);
|
|
52
|
+
console.log(` File contains ${savedContext.sessions?.length || 0} sessions`);
|
|
53
|
+
|
|
54
|
+
// Find our test frame in the sessions
|
|
55
|
+
let foundFrame = null;
|
|
56
|
+
for (const session of savedContext.sessions || []) {
|
|
57
|
+
const frame = session.keyFrames?.find(f =>
|
|
58
|
+
f.title === 'Persistence test frame' &&
|
|
59
|
+
f.tags?.includes('persistence')
|
|
60
|
+
);
|
|
61
|
+
if (frame) {
|
|
62
|
+
foundFrame = frame;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (foundFrame) {
|
|
68
|
+
console.log('ā
Test frame found in persisted data!');
|
|
69
|
+
console.log(' Frame ID:', foundFrame.frameId);
|
|
70
|
+
console.log(' Frame type:', foundFrame.type);
|
|
71
|
+
console.log(' Frame score:', foundFrame.score);
|
|
72
|
+
} else {
|
|
73
|
+
console.log('ā ļø Test frame not found in persisted data');
|
|
74
|
+
console.log(' Current sessions:', savedContext.sessions?.length || 0);
|
|
75
|
+
}
|
|
76
|
+
} catch (err) {
|
|
77
|
+
console.log(`ā ļø Could not read persistence file: ${err.message}`);
|
|
78
|
+
console.log(' Creating new persistence structure...');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Test patterns
|
|
82
|
+
await layer.addToSharedContext({
|
|
83
|
+
type: 'error',
|
|
84
|
+
name: 'Test error frame',
|
|
85
|
+
data: {
|
|
86
|
+
error: 'Test error message',
|
|
87
|
+
resolution: 'Test resolution'
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const updatedContext = await layer.getSharedContext();
|
|
92
|
+
console.log('\nā
Added error frame for pattern detection');
|
|
93
|
+
console.log(` Global patterns now: ${updatedContext.globalPatterns?.length || 0}`);
|
|
94
|
+
|
|
95
|
+
const errorPatterns = updatedContext.globalPatterns?.filter(p => p.type === 'error');
|
|
96
|
+
if (errorPatterns?.length > 0) {
|
|
97
|
+
console.log('ā
Error pattern detected and stored');
|
|
98
|
+
console.log(` Error patterns: ${errorPatterns.length}`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
console.log('\nš Persistence test completed successfully!');
|
|
102
|
+
console.log('\nTo verify manually:');
|
|
103
|
+
console.log(` cat ${contextPath} | jq '.sessions | length'`);
|
|
104
|
+
console.log(` cat ${contextPath} | jq '.sessions[-1].keyFrames'`);
|
|
105
|
+
console.log(` cat ${contextPath} | jq '.globalPatterns'`);
|
|
106
|
+
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error('ā Test failed:', error.message);
|
|
109
|
+
console.error(error.stack);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
testPersistence().catch(console.error);
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Test script to validate Pebbles task management through MCP
|
|
4
|
+
* This demonstrates the full task workflow
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { spawn } from 'child_process';
|
|
8
|
+
|
|
9
|
+
async function testTaskWorkflow() {
|
|
10
|
+
console.log('š Testing StackMemory Pebbles Task Management\n');
|
|
11
|
+
|
|
12
|
+
// Sample tasks for v0.2.0 release
|
|
13
|
+
const tasks = [
|
|
14
|
+
{
|
|
15
|
+
name: 'Linear API Integration',
|
|
16
|
+
description:
|
|
17
|
+
'Implement bi-directional sync with Linear for team collaboration',
|
|
18
|
+
priority: 'high',
|
|
19
|
+
estimatedEffort: 240, // 4 hours
|
|
20
|
+
tags: ['integration', 'linear', 'team'],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'Enhanced CLI Commands',
|
|
24
|
+
description: 'Add task management commands to StackMemory CLI',
|
|
25
|
+
priority: 'medium',
|
|
26
|
+
estimatedEffort: 120, // 2 hours
|
|
27
|
+
tags: ['cli', 'ux'],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Git Hooks Integration',
|
|
31
|
+
description: 'Automate task state sync with git workflow',
|
|
32
|
+
priority: 'medium',
|
|
33
|
+
estimatedEffort: 90, // 1.5 hours
|
|
34
|
+
tags: ['git', 'automation'],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'Task Analytics Dashboard',
|
|
38
|
+
description: 'Web UI for task metrics and project insights',
|
|
39
|
+
priority: 'low',
|
|
40
|
+
estimatedEffort: 480, // 8 hours
|
|
41
|
+
tags: ['ui', 'analytics', 'web'],
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'Performance Optimization',
|
|
45
|
+
description: 'Optimize context assembly and JSONL parsing performance',
|
|
46
|
+
priority: 'high',
|
|
47
|
+
estimatedEffort: 180, // 3 hours
|
|
48
|
+
tags: ['performance', 'optimization'],
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
console.log(
|
|
53
|
+
`š Creating ${tasks.length} example tasks for StackMemory development...\n`
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
tasks.forEach((task, index) => {
|
|
57
|
+
console.log(`${index + 1}. **${task.name}** (${task.priority})`);
|
|
58
|
+
console.log(` ${task.description}`);
|
|
59
|
+
console.log(
|
|
60
|
+
` Estimated: ${task.estimatedEffort}m | Tags: ${task.tags.join(', ')}\n`
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
console.log('⨠These tasks demonstrate:');
|
|
65
|
+
console.log('- Git-native JSONL storage (.stackmemory/tasks.jsonl)');
|
|
66
|
+
console.log('- Content-hash task IDs for merge-friendly collaboration');
|
|
67
|
+
console.log('- Priority-based context assembly');
|
|
68
|
+
console.log('- Automatic time tracking');
|
|
69
|
+
console.log('- Dependency management');
|
|
70
|
+
console.log('- Integration readiness for Linear API sync\n');
|
|
71
|
+
|
|
72
|
+
console.log('š§ To create these tasks with StackMemory MCP:');
|
|
73
|
+
console.log(
|
|
74
|
+
'1. Start frame: start_frame("StackMemory v0.2.0 Development", "task")'
|
|
75
|
+
);
|
|
76
|
+
console.log(
|
|
77
|
+
'2. Create tasks: create_task("Linear API Integration", priority="high", ...)'
|
|
78
|
+
);
|
|
79
|
+
console.log('3. Track progress: update_task_status(taskId, "in_progress")');
|
|
80
|
+
console.log('4. View metrics: get_task_metrics()');
|
|
81
|
+
console.log('5. Check active work: get_active_tasks()');
|
|
82
|
+
|
|
83
|
+
return tasks;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Run the test
|
|
87
|
+
testTaskWorkflow()
|
|
88
|
+
.then((tasks) => {
|
|
89
|
+
console.log(
|
|
90
|
+
`\nā
Ready to create ${tasks.length} tasks in StackMemory v0.2.0!`
|
|
91
|
+
);
|
|
92
|
+
})
|
|
93
|
+
.catch(console.error);
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Update import paths after folder reorganization
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { readFileSync, writeFileSync, readdirSync, statSync } from 'fs';
|
|
8
|
+
import { join, relative, dirname } from 'path';
|
|
9
|
+
|
|
10
|
+
const importMappings = {
|
|
11
|
+
// Core mappings
|
|
12
|
+
'../core/frame-manager': '../core/context/frame-manager',
|
|
13
|
+
'../core/project-manager': '../core/projects/project-manager',
|
|
14
|
+
'../core/logger': '../core/monitoring/logger',
|
|
15
|
+
'../core/error-handler': '../core/monitoring/error-handler',
|
|
16
|
+
'../core/progress-tracker': '../core/monitoring/progress-tracker',
|
|
17
|
+
'../core/update-checker': '../core/utils/update-checker',
|
|
18
|
+
|
|
19
|
+
// Features mappings
|
|
20
|
+
'../pebbles/pebbles-task-store': '../features/tasks/task-store',
|
|
21
|
+
'../pebbles/task-aware-context': '../features/tasks/task-context',
|
|
22
|
+
'../analytics/': '../features/analytics/',
|
|
23
|
+
'../integrations/browser-mcp': '../features/browser/browser-mcp',
|
|
24
|
+
|
|
25
|
+
// Integrations mappings
|
|
26
|
+
'../integrations/linear-auth': '../integrations/linear/auth',
|
|
27
|
+
'../integrations/linear-sync': '../integrations/linear/sync',
|
|
28
|
+
'../integrations/linear-client': '../integrations/linear/client',
|
|
29
|
+
'../integrations/linear-config': '../integrations/linear/config',
|
|
30
|
+
'../integrations/linear-auto-sync': '../integrations/linear/auto-sync',
|
|
31
|
+
'../mcp/mcp-server': '../integrations/mcp/server',
|
|
32
|
+
|
|
33
|
+
// CLI mappings
|
|
34
|
+
'./cli': './index',
|
|
35
|
+
'./project-commands': './commands/projects',
|
|
36
|
+
'./analytics-viewer': './utils/viewer',
|
|
37
|
+
'../cli/cli': '../cli/index',
|
|
38
|
+
|
|
39
|
+
// Server mappings
|
|
40
|
+
'../railway/': '../servers/railway/',
|
|
41
|
+
'./railway/': './servers/railway/',
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function updateImportsInFile(filePath) {
|
|
45
|
+
if (!filePath.endsWith('.ts') && !filePath.endsWith('.js')) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
let content = readFileSync(filePath, 'utf-8');
|
|
51
|
+
let modified = false;
|
|
52
|
+
|
|
53
|
+
// Update import statements
|
|
54
|
+
for (const [oldPath, newPath] of Object.entries(importMappings)) {
|
|
55
|
+
const importRegex = new RegExp(
|
|
56
|
+
`(import.*from\\s+['"]\\.?)${escapeRegex(oldPath)}(['"])`,
|
|
57
|
+
'g'
|
|
58
|
+
);
|
|
59
|
+
const newContent = content.replace(importRegex, `$1${newPath}$2`);
|
|
60
|
+
|
|
61
|
+
if (newContent !== content) {
|
|
62
|
+
content = newContent;
|
|
63
|
+
modified = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Special case: Update shebang for CLI entry point
|
|
68
|
+
if (filePath.endsWith('src/cli/index.ts')) {
|
|
69
|
+
if (!content.startsWith('#!/usr/bin/env node')) {
|
|
70
|
+
content = '#!/usr/bin/env node\n' + content;
|
|
71
|
+
modified = true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (modified) {
|
|
76
|
+
writeFileSync(filePath, content);
|
|
77
|
+
console.log(`ā
Updated: ${relative(process.cwd(), filePath)}`);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return false;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error(`ā Error updating ${filePath}:`, error.message);
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function escapeRegex(string) {
|
|
89
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function walkDirectory(dir) {
|
|
93
|
+
const files = [];
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
const items = readdirSync(dir);
|
|
97
|
+
|
|
98
|
+
for (const item of items) {
|
|
99
|
+
const fullPath = join(dir, item);
|
|
100
|
+
const stat = statSync(fullPath);
|
|
101
|
+
|
|
102
|
+
if (stat.isDirectory()) {
|
|
103
|
+
// Skip node_modules, dist, and .git
|
|
104
|
+
if (
|
|
105
|
+
!item.startsWith('.') &&
|
|
106
|
+
item !== 'node_modules' &&
|
|
107
|
+
item !== 'dist'
|
|
108
|
+
) {
|
|
109
|
+
files.push(...walkDirectory(fullPath));
|
|
110
|
+
}
|
|
111
|
+
} else if (stat.isFile()) {
|
|
112
|
+
files.push(fullPath);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.error(`Error walking directory ${dir}:`, error.message);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return files;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function updatePackageJson() {
|
|
123
|
+
try {
|
|
124
|
+
const packagePath = join(process.cwd(), 'package.json');
|
|
125
|
+
const pkg = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
|
126
|
+
|
|
127
|
+
// Update bin path
|
|
128
|
+
if (pkg.bin && pkg.bin.stackmemory) {
|
|
129
|
+
pkg.bin.stackmemory = 'dist/src/cli/index.js';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Update main entry
|
|
133
|
+
if (pkg.main) {
|
|
134
|
+
pkg.main = pkg.main.replace('dist/src/index.js', 'dist/src/index.js');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Update scripts
|
|
138
|
+
if (pkg.scripts) {
|
|
139
|
+
// Update MCP server paths
|
|
140
|
+
if (pkg.scripts['mcp:start']) {
|
|
141
|
+
pkg.scripts['mcp:start'] = pkg.scripts['mcp:start'].replace(
|
|
142
|
+
'dist/src/mcp/mcp-server.js',
|
|
143
|
+
'dist/src/integrations/mcp/server.js'
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
if (pkg.scripts['mcp:local']) {
|
|
147
|
+
pkg.scripts['mcp:local'] = pkg.scripts['mcp:local'].replace(
|
|
148
|
+
'dist/src/mcp/mcp-server.js',
|
|
149
|
+
'dist/src/integrations/mcp/server.js'
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Update lint fix script
|
|
154
|
+
if (pkg.scripts['lint:autofix']) {
|
|
155
|
+
pkg.scripts['lint:autofix'] = pkg.scripts['lint:autofix'].replace(
|
|
156
|
+
'scripts/fix-lint-loop.cjs',
|
|
157
|
+
'scripts/development/fix-lint-loop.cjs'
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
writeFileSync(packagePath, JSON.stringify(pkg, null, 2) + '\n');
|
|
163
|
+
console.log('ā
Updated package.json');
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.error('ā Error updating package.json:', error.message);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function updateTsConfig() {
|
|
170
|
+
try {
|
|
171
|
+
const tsconfigPath = join(process.cwd(), 'tsconfig.json');
|
|
172
|
+
const tsconfig = JSON.parse(readFileSync(tsconfigPath, 'utf-8'));
|
|
173
|
+
|
|
174
|
+
// Update exclude paths if needed
|
|
175
|
+
if (tsconfig.exclude) {
|
|
176
|
+
tsconfig.exclude = tsconfig.exclude
|
|
177
|
+
.map((path) => {
|
|
178
|
+
if (path === 'src/runway.bak') return null;
|
|
179
|
+
if (path === 'src/runway') return null;
|
|
180
|
+
return path;
|
|
181
|
+
})
|
|
182
|
+
.filter(Boolean);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\n');
|
|
186
|
+
console.log('ā
Updated tsconfig.json');
|
|
187
|
+
} catch (error) {
|
|
188
|
+
console.error('ā Error updating tsconfig.json:', error.message);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Main execution
|
|
193
|
+
console.log('š Updating import paths after reorganization...\n');
|
|
194
|
+
|
|
195
|
+
const srcFiles = walkDirectory(join(process.cwd(), 'src'));
|
|
196
|
+
const testFiles = walkDirectory(join(process.cwd(), 'tests'));
|
|
197
|
+
const scriptFiles = walkDirectory(join(process.cwd(), 'scripts'));
|
|
198
|
+
|
|
199
|
+
let updatedCount = 0;
|
|
200
|
+
|
|
201
|
+
for (const file of [...srcFiles, ...testFiles, ...scriptFiles]) {
|
|
202
|
+
if (updateImportsInFile(file)) {
|
|
203
|
+
updatedCount++;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Update configuration files
|
|
208
|
+
updatePackageJson();
|
|
209
|
+
updateTsConfig();
|
|
210
|
+
|
|
211
|
+
console.log(`\nā
Updated ${updatedCount} files`);
|
|
212
|
+
console.log('š¦ Run "npm run build" to verify all imports are correct');
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import 'dotenv/config';
|
|
3
|
+
import { LinearClient } from '@linear/sdk';
|
|
4
|
+
|
|
5
|
+
const API_KEY = process.env.LINEAR_API_KEY;
|
|
6
|
+
|
|
7
|
+
if (!API_KEY) {
|
|
8
|
+
console.error('ā LINEAR_API_KEY not found in environment');
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async function fetchLinearTasks() {
|
|
13
|
+
const client = new LinearClient({ apiKey: API_KEY });
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const me = await client.viewer;
|
|
17
|
+
console.log(`\nš¤ Connected as: ${me.name || me.email}\n`);
|
|
18
|
+
|
|
19
|
+
// Get teams
|
|
20
|
+
const teams = await client.teams();
|
|
21
|
+
console.log(`š Teams: ${teams.nodes.map(t => t.key).join(', ')}\n`);
|
|
22
|
+
|
|
23
|
+
// Fetch all issues
|
|
24
|
+
const issues = await client.issues({
|
|
25
|
+
filter: {
|
|
26
|
+
state: {
|
|
27
|
+
name: { nin: ["Done", "Canceled"] }
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
orderBy: "priority"
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Group by state
|
|
34
|
+
const byState = {};
|
|
35
|
+
for (const issue of issues.nodes) {
|
|
36
|
+
const state = issue.state?.name || 'Unknown';
|
|
37
|
+
if (!byState[state]) byState[state] = [];
|
|
38
|
+
byState[state].push(issue);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Display by state
|
|
42
|
+
const stateOrder = ['In Progress', 'Todo', 'Triage', 'Backlog', 'Unknown'];
|
|
43
|
+
|
|
44
|
+
for (const state of stateOrder) {
|
|
45
|
+
if (byState[state] && byState[state].length > 0) {
|
|
46
|
+
console.log(`š ${state.toUpperCase()} (${byState[state].length}):`);
|
|
47
|
+
|
|
48
|
+
// Show top 10 from each state
|
|
49
|
+
const topIssues = byState[state].slice(0, 10);
|
|
50
|
+
for (const issue of topIssues) {
|
|
51
|
+
const priority = issue.priority ? `[P${issue.priority}]` : '';
|
|
52
|
+
const assignee = issue.assignee ? `@${issue.assignee.name}` : '[Unassigned]';
|
|
53
|
+
const labels = issue.labels ? (await issue.labels()).nodes.map(l => l.name).join(', ') : '';
|
|
54
|
+
const labelStr = labels ? ` š·ļø ${labels}` : '';
|
|
55
|
+
|
|
56
|
+
console.log(` ⢠${issue.identifier}: ${issue.title} ${priority} ${assignee}${labelStr}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (byState[state].length > 10) {
|
|
60
|
+
console.log(` ... and ${byState[state].length - 10} more`);
|
|
61
|
+
}
|
|
62
|
+
console.log('');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Summary stats
|
|
67
|
+
const total = issues.nodes.length;
|
|
68
|
+
const inProgress = byState['In Progress']?.length || 0;
|
|
69
|
+
const todo = byState['Todo']?.length || 0;
|
|
70
|
+
const triage = byState['Triage']?.length || 0;
|
|
71
|
+
|
|
72
|
+
console.log('š SUMMARY:');
|
|
73
|
+
console.log(` Total active issues: ${total}`);
|
|
74
|
+
console.log(` In Progress: ${inProgress}`);
|
|
75
|
+
console.log(` Todo: ${todo}`);
|
|
76
|
+
console.log(` Triage: ${triage}`);
|
|
77
|
+
|
|
78
|
+
// High priority items
|
|
79
|
+
console.log('\nš„ HIGH PRIORITY ITEMS:');
|
|
80
|
+
const highPriority = issues.nodes
|
|
81
|
+
.filter(i => i.priority && i.priority <= 2)
|
|
82
|
+
.slice(0, 5);
|
|
83
|
+
|
|
84
|
+
for (const issue of highPriority) {
|
|
85
|
+
const state = issue.state?.name || 'Unknown';
|
|
86
|
+
const assignee = issue.assignee ? `@${issue.assignee.name}` : '[Unassigned]';
|
|
87
|
+
console.log(` ⢠${issue.identifier}: ${issue.title} [${state}] ${assignee}`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Suggested next tasks
|
|
91
|
+
console.log('\nš” SUGGESTED NEXT TASKS:');
|
|
92
|
+
console.log('Based on priority and status, consider working on:');
|
|
93
|
+
|
|
94
|
+
// Find unassigned high priority or in-progress items
|
|
95
|
+
const suggestions = issues.nodes
|
|
96
|
+
.filter(i => {
|
|
97
|
+
const isHighPriority = i.priority && i.priority <= 2;
|
|
98
|
+
const isInProgress = i.state?.name === 'In Progress';
|
|
99
|
+
const isTodo = i.state?.name === 'Todo';
|
|
100
|
+
const isUnassigned = !i.assignee;
|
|
101
|
+
|
|
102
|
+
return (isHighPriority || isInProgress) && (isTodo || isInProgress);
|
|
103
|
+
})
|
|
104
|
+
.slice(0, 3);
|
|
105
|
+
|
|
106
|
+
if (suggestions.length > 0) {
|
|
107
|
+
for (const issue of suggestions) {
|
|
108
|
+
const state = issue.state?.name || 'Unknown';
|
|
109
|
+
const priority = issue.priority ? `P${issue.priority}` : 'No priority';
|
|
110
|
+
console.log(` 1. ${issue.identifier}: ${issue.title}`);
|
|
111
|
+
console.log(` Status: ${state}, Priority: ${priority}`);
|
|
112
|
+
console.log(` URL: https://linear.app/issue/${issue.identifier}`);
|
|
113
|
+
console.log('');
|
|
114
|
+
}
|
|
115
|
+
} else {
|
|
116
|
+
console.log(' No high-priority unassigned tasks found.');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error('Error fetching Linear tasks:', error.message);
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
fetchLinearTasks();
|