@stackmemoryai/stackmemory 0.5.49 → 0.5.51

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.
Files changed (33) hide show
  1. package/README.md +17 -3
  2. package/dist/cli/claude-sm.js +246 -5
  3. package/dist/cli/claude-sm.js.map +3 -3
  4. package/dist/cli/commands/sweep.js +190 -421
  5. package/dist/cli/commands/sweep.js.map +3 -3
  6. package/dist/cli/index.js +2 -0
  7. package/dist/cli/index.js.map +2 -2
  8. package/dist/core/config/feature-flags.js +7 -1
  9. package/dist/core/config/feature-flags.js.map +2 -2
  10. package/dist/core/context/enhanced-rehydration.js +355 -9
  11. package/dist/core/context/enhanced-rehydration.js.map +3 -3
  12. package/dist/core/context/shared-context-layer.js +229 -0
  13. package/dist/core/context/shared-context-layer.js.map +2 -2
  14. package/dist/features/sweep/index.js +20 -0
  15. package/dist/features/sweep/index.js.map +7 -0
  16. package/dist/features/sweep/prediction-client.js +155 -0
  17. package/dist/features/sweep/prediction-client.js.map +7 -0
  18. package/dist/features/sweep/prompt-builder.js +85 -0
  19. package/dist/features/sweep/prompt-builder.js.map +7 -0
  20. package/dist/features/sweep/pty-wrapper.js +171 -0
  21. package/dist/features/sweep/pty-wrapper.js.map +7 -0
  22. package/dist/features/sweep/state-watcher.js +87 -0
  23. package/dist/features/sweep/state-watcher.js.map +7 -0
  24. package/dist/features/sweep/status-bar.js +88 -0
  25. package/dist/features/sweep/status-bar.js.map +7 -0
  26. package/dist/features/sweep/sweep-server-manager.js +226 -0
  27. package/dist/features/sweep/sweep-server-manager.js.map +7 -0
  28. package/dist/features/sweep/tab-interceptor.js +38 -0
  29. package/dist/features/sweep/tab-interceptor.js.map +7 -0
  30. package/dist/features/sweep/types.js +18 -0
  31. package/dist/features/sweep/types.js.map +7 -0
  32. package/package.json +1 -1
  33. package/scripts/test-setup-e2e.sh +154 -0
@@ -0,0 +1,38 @@
1
+ import { fileURLToPath as __fileURLToPath } from 'url';
2
+ import { dirname as __pathDirname } from 'path';
3
+ const __filename = __fileURLToPath(import.meta.url);
4
+ const __dirname = __pathDirname(__filename);
5
+ const TAB = 9;
6
+ const ESC = 27;
7
+ class TabInterceptor {
8
+ predictionActive = false;
9
+ callbacks;
10
+ constructor(callbacks) {
11
+ this.callbacks = callbacks;
12
+ }
13
+ setPredictionActive(active) {
14
+ this.predictionActive = active;
15
+ }
16
+ isPredictionActive() {
17
+ return this.predictionActive;
18
+ }
19
+ process(data) {
20
+ if (!this.predictionActive) {
21
+ this.callbacks.onPassthrough(data);
22
+ return;
23
+ }
24
+ if (data.length === 1 && data[0] === TAB) {
25
+ this.callbacks.onAccept();
26
+ return;
27
+ }
28
+ if (data.length === 1 && data[0] === ESC) {
29
+ this.callbacks.onDismiss();
30
+ return;
31
+ }
32
+ this.callbacks.onPassthrough(data);
33
+ }
34
+ }
35
+ export {
36
+ TabInterceptor
37
+ };
38
+ //# sourceMappingURL=tab-interceptor.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/features/sweep/tab-interceptor.ts"],
4
+ "sourcesContent": ["/**\n * Tab Interceptor\n *\n * Intercepts Tab and Esc keystrokes when a Sweep prediction is active.\n * All other input passes through to the PTY child unchanged.\n */\n\nconst TAB = 0x09;\nconst ESC = 0x1b;\n\nexport interface TabInterceptorCallbacks {\n onAccept: () => void;\n onDismiss: () => void;\n onPassthrough: (data: Buffer) => void;\n}\n\nexport class TabInterceptor {\n private predictionActive = false;\n private callbacks: TabInterceptorCallbacks;\n\n constructor(callbacks: TabInterceptorCallbacks) {\n this.callbacks = callbacks;\n }\n\n setPredictionActive(active: boolean): void {\n this.predictionActive = active;\n }\n\n isPredictionActive(): boolean {\n return this.predictionActive;\n }\n\n process(data: Buffer): void {\n if (!this.predictionActive) {\n this.callbacks.onPassthrough(data);\n return;\n }\n\n // Tab key: accept prediction\n if (data.length === 1 && data[0] === TAB) {\n this.callbacks.onAccept();\n return;\n }\n\n // Bare Escape: dismiss prediction\n // Distinguish from escape sequences (arrow keys, etc.) by length.\n // Bare Esc is a single byte; escape sequences are multi-byte.\n if (data.length === 1 && data[0] === ESC) {\n this.callbacks.onDismiss();\n return;\n }\n\n // Everything else passes through (including escape sequences)\n this.callbacks.onPassthrough(data);\n }\n}\n"],
5
+ "mappings": ";;;;AAOA,MAAM,MAAM;AACZ,MAAM,MAAM;AAQL,MAAM,eAAe;AAAA,EAClB,mBAAmB;AAAA,EACnB;AAAA,EAER,YAAY,WAAoC;AAC9C,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,oBAAoB,QAAuB;AACzC,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,qBAA8B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,QAAQ,MAAoB;AAC1B,QAAI,CAAC,KAAK,kBAAkB;AAC1B,WAAK,UAAU,cAAc,IAAI;AACjC;AAAA,IACF;AAGA,QAAI,KAAK,WAAW,KAAK,KAAK,CAAC,MAAM,KAAK;AACxC,WAAK,UAAU,SAAS;AACxB;AAAA,IACF;AAKA,QAAI,KAAK,WAAW,KAAK,KAAK,CAAC,MAAM,KAAK;AACxC,WAAK,UAAU,UAAU;AACzB;AAAA,IACF;AAGA,SAAK,UAAU,cAAc,IAAI;AAAA,EACnC;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,18 @@
1
+ import { fileURLToPath as __fileURLToPath } from 'url';
2
+ import { dirname as __pathDirname } from 'path';
3
+ const __filename = __fileURLToPath(import.meta.url);
4
+ const __dirname = __pathDirname(__filename);
5
+ const DEFAULT_SERVER_CONFIG = {
6
+ port: 8766,
7
+ host: "127.0.0.1",
8
+ modelPath: "",
9
+ contextSize: 8192,
10
+ threads: void 0,
11
+ gpuLayers: 0
12
+ };
13
+ const SWEEP_STOP_TOKENS = ["<|file_sep|>", "</s>"];
14
+ export {
15
+ DEFAULT_SERVER_CONFIG,
16
+ SWEEP_STOP_TOKENS
17
+ };
18
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/features/sweep/types.ts"],
4
+ "sourcesContent": ["/**\n * Sweep Next-Edit Types\n *\n * Types for the Sweep 1.5B model server integration.\n */\n\nexport interface SweepServerConfig {\n port: number;\n host: string;\n modelPath: string;\n contextSize: number;\n threads?: number;\n gpuLayers?: number;\n}\n\nexport interface SweepServerStatus {\n running: boolean;\n pid?: number;\n port?: number;\n host?: string;\n startedAt?: number;\n modelPath?: string;\n}\n\nexport interface SweepPredictInput {\n file_path: string;\n current_content: string;\n original_content?: string;\n context_files?: Record<string, string>;\n recent_diffs?: DiffEntry[];\n max_tokens?: number;\n temperature?: number;\n top_k?: number;\n}\n\nexport interface DiffEntry {\n file_path: string;\n original: string;\n updated: string;\n timestamp?: number;\n}\n\nexport interface SweepPredictResult {\n success: boolean;\n predicted_content?: string;\n file_path?: string;\n latency_ms?: number;\n tokens_generated?: number;\n error?: string;\n message?: string;\n}\n\nexport interface SweepPromptInput {\n filePath: string;\n originalContent: string;\n currentContent: string;\n recentDiffs: DiffEntry[];\n contextFiles?: Record<string, string>;\n}\n\nexport interface CompletionRequest {\n model: string;\n prompt: string;\n max_tokens: number;\n temperature: number;\n top_k?: number;\n stop?: string[];\n stream?: boolean;\n}\n\nexport interface CompletionResponse {\n id: string;\n object: string;\n created: number;\n model: string;\n choices: Array<{\n text: string;\n index: number;\n logprobs: null;\n finish_reason: string;\n }>;\n usage: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n };\n}\n\nexport const DEFAULT_SERVER_CONFIG: SweepServerConfig = {\n port: 8766,\n host: '127.0.0.1',\n modelPath: '',\n contextSize: 8192,\n threads: undefined,\n gpuLayers: 0,\n};\n\nexport const SWEEP_STOP_TOKENS = ['<|file_sep|>', '</s>'];\n"],
5
+ "mappings": ";;;;AAwFO,MAAM,wBAA2C;AAAA,EACtD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,WAAW;AAAA,EACX,aAAa;AAAA,EACb,SAAS;AAAA,EACT,WAAW;AACb;AAEO,MAAM,oBAAoB,CAAC,gBAAgB,MAAM;",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackmemoryai/stackmemory",
3
- "version": "0.5.49",
3
+ "version": "0.5.51",
4
4
  "description": "Lossless memory runtime for AI coding tools - organizes context as a call stack instead of linear chat logs, with team collaboration and infinite retention",
5
5
  "engines": {
6
6
  "node": ">=20.0.0",
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env bash
2
+ # E2E test for claude-sm config setup
3
+ # Tests the interactive setup wizard flow
4
+
5
+ set -euo pipefail
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
9
+ CONFIG_PATH="$HOME/.stackmemory/claude-sm.json"
10
+ BACKUP_PATH="$HOME/.stackmemory/claude-sm.json.bak"
11
+
12
+ # Colors
13
+ RED='\033[0;31m'
14
+ GREEN='\033[0;32m'
15
+ GRAY='\033[0;90m'
16
+ NC='\033[0m'
17
+
18
+ pass=0
19
+ fail=0
20
+
21
+ ok() { echo -e " ${GREEN}PASS${NC} $1"; pass=$((pass + 1)); }
22
+ ko() { echo -e " ${RED}FAIL${NC} $1"; fail=$((fail + 1)); }
23
+
24
+ echo "=== claude-sm config setup E2E tests ==="
25
+ echo ""
26
+
27
+ # Backup existing config
28
+ if [ -f "$CONFIG_PATH" ]; then
29
+ cp "$CONFIG_PATH" "$BACKUP_PATH"
30
+ echo -e "${GRAY}Backed up existing config${NC}"
31
+ fi
32
+
33
+ # 1. Test config show works
34
+ echo "--- Test: config show ---"
35
+ output=$(node "$PROJECT_DIR/dist/cli/claude-sm.js" config show 2>&1 || true)
36
+ if echo "$output" | grep -q "defaultSweep"; then
37
+ ok "config show displays defaultSweep"
38
+ else
39
+ ko "config show missing defaultSweep"
40
+ fi
41
+ if echo "$output" | grep -q "defaultGreptile"; then
42
+ ok "config show displays defaultGreptile"
43
+ else
44
+ ko "config show missing defaultGreptile"
45
+ fi
46
+
47
+ # 2. Test config set sweep
48
+ echo "--- Test: config set sweep ---"
49
+ node "$PROJECT_DIR/dist/cli/claude-sm.js" config set sweep false 2>&1
50
+ output=$(node "$PROJECT_DIR/dist/cli/claude-sm.js" config show 2>&1 || true)
51
+ if echo "$output" | grep -q "defaultSweep.*false\|defaultSweep"; then
52
+ ok "config set sweep false applied"
53
+ else
54
+ ko "config set sweep false not applied"
55
+ fi
56
+
57
+ node "$PROJECT_DIR/dist/cli/claude-sm.js" config set sweep true 2>&1
58
+ output=$(node "$PROJECT_DIR/dist/cli/claude-sm.js" config show 2>&1 || true)
59
+ if echo "$output" | grep -q "defaultSweep.*true\|defaultSweep"; then
60
+ ok "config set sweep true applied"
61
+ else
62
+ ko "config set sweep true not applied"
63
+ fi
64
+
65
+ # 3. Test config set greptile
66
+ echo "--- Test: config set greptile ---"
67
+ node "$PROJECT_DIR/dist/cli/claude-sm.js" config set greptile false 2>&1
68
+ output=$(node "$PROJECT_DIR/dist/cli/claude-sm.js" config show 2>&1 || true)
69
+ if echo "$output" | grep -q "defaultGreptile"; then
70
+ ok "config set greptile applied"
71
+ else
72
+ ko "config set greptile not applied"
73
+ fi
74
+
75
+ # 4. Test config greptile-on / greptile-off
76
+ echo "--- Test: greptile-on/off ---"
77
+ node "$PROJECT_DIR/dist/cli/claude-sm.js" config greptile-on 2>&1
78
+ if grep -q '"defaultGreptile":.*true' "$CONFIG_PATH"; then
79
+ ok "greptile-on sets true in config file"
80
+ else
81
+ ko "greptile-on did not set true"
82
+ fi
83
+
84
+ node "$PROJECT_DIR/dist/cli/claude-sm.js" config greptile-off 2>&1
85
+ if grep -q '"defaultGreptile":.*false' "$CONFIG_PATH"; then
86
+ ok "greptile-off sets false in config file"
87
+ else
88
+ ko "greptile-off did not set false"
89
+ fi
90
+
91
+ # 5. Test that setup command exists (non-interactive check)
92
+ echo "--- Test: setup command exists ---"
93
+ output=$(node "$PROJECT_DIR/dist/cli/claude-sm.js" config --help 2>&1 || true)
94
+ if echo "$output" | grep -q "setup"; then
95
+ ok "setup command listed in config help"
96
+ else
97
+ ko "setup command not in config help"
98
+ fi
99
+
100
+ # 6. Test node-pty dynamic import (should not crash if missing)
101
+ echo "--- Test: node-pty optional ---"
102
+ node -e "
103
+ import('node-pty')
104
+ .then(() => { console.log('node-pty: installed'); process.exit(0); })
105
+ .catch(() => { console.log('node-pty: not installed (OK)'); process.exit(0); });
106
+ " 2>&1
107
+ ok "node-pty check does not crash"
108
+
109
+ # 7. Verify node-pty is NOT in optionalDependencies
110
+ echo "--- Test: node-pty removed from optionalDeps ---"
111
+ if grep -q '"node-pty"' "$PROJECT_DIR/package.json"; then
112
+ ko "node-pty still in package.json"
113
+ else
114
+ ok "node-pty removed from package.json"
115
+ fi
116
+
117
+ # 8. Test feature flags include greptile
118
+ echo "--- Test: feature flags ---"
119
+ node -e "
120
+ import { getFeatureFlags } from '$PROJECT_DIR/dist/core/config/feature-flags.js';
121
+ const flags = getFeatureFlags();
122
+ if ('greptile' in flags) {
123
+ console.log('greptile flag exists: ' + flags.greptile);
124
+ process.exit(0);
125
+ } else {
126
+ console.error('greptile flag missing');
127
+ process.exit(1);
128
+ }
129
+ " 2>&1 && ok "greptile feature flag exists" || ko "greptile feature flag missing"
130
+
131
+ # 9. Verify build artifacts exist
132
+ echo "--- Test: build artifacts ---"
133
+ if [ -f "$PROJECT_DIR/dist/cli/claude-sm.js" ]; then
134
+ ok "dist/cli/claude-sm.js exists"
135
+ else
136
+ ko "dist/cli/claude-sm.js missing"
137
+ fi
138
+
139
+ if [ -f "$PROJECT_DIR/dist/features/sweep/pty-wrapper.js" ]; then
140
+ ok "dist/features/sweep/pty-wrapper.js exists"
141
+ else
142
+ ko "dist/features/sweep/pty-wrapper.js missing"
143
+ fi
144
+
145
+ # Restore config
146
+ if [ -f "$BACKUP_PATH" ]; then
147
+ mv "$BACKUP_PATH" "$CONFIG_PATH"
148
+ echo -e "${GRAY}Restored original config${NC}"
149
+ fi
150
+
151
+ # Summary
152
+ echo ""
153
+ echo "=== Results: ${GREEN}$pass passed${NC}, ${RED}$fail failed${NC} ==="
154
+ [ "$fail" -eq 0 ] && exit 0 || exit 1