@stackmemoryai/stackmemory 1.10.5 → 1.14.0
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/LICENSE +131 -64
- package/README.md +107 -24
- package/bin/claude-sm +16 -1
- package/bin/claude-smd +16 -1
- package/bin/codex-smd +16 -1
- package/bin/gemini-sm +16 -1
- package/bin/hermes-sm +21 -0
- package/bin/hermes-smd +21 -0
- package/bin/opencode-sm +16 -1
- package/dist/src/cli/claude-sm.js +266 -84
- package/dist/src/cli/codex-sm.js +225 -33
- package/dist/src/cli/commands/bench.js +209 -2
- package/dist/src/cli/commands/brain.js +206 -0
- package/dist/src/cli/commands/cache.js +126 -0
- package/dist/src/cli/commands/company-os.js +184 -0
- package/dist/src/cli/commands/context.js +5 -0
- package/dist/src/cli/commands/daemon.js +41 -0
- package/dist/src/cli/commands/handoff.js +40 -9
- package/dist/src/cli/commands/onboard.js +70 -3
- package/dist/src/cli/commands/operator.js +127 -0
- package/dist/src/cli/commands/optimize.js +117 -0
- package/dist/src/cli/commands/orchestrate.js +232 -5
- package/dist/src/cli/commands/orchestrator.js +315 -26
- package/dist/src/cli/commands/pack.js +322 -0
- package/dist/src/cli/commands/patterns.js +254 -0
- package/dist/src/cli/commands/portal.js +161 -0
- package/dist/src/cli/commands/scaffold.js +92 -0
- package/dist/src/cli/commands/search.js +40 -1
- package/dist/src/cli/commands/setup.js +178 -11
- package/dist/src/cli/commands/skills.js +10 -1
- package/dist/src/cli/commands/state.js +265 -0
- package/dist/src/cli/commands/sync.js +253 -0
- package/dist/src/cli/commands/tasks.js +130 -1
- package/dist/src/cli/commands/vision.js +221 -0
- package/dist/src/cli/gemini-sm.js +19 -29
- package/dist/src/cli/hermes-sm.js +224 -0
- package/dist/src/cli/index.js +105 -39
- package/dist/src/cli/opencode-sm.js +38 -21
- package/dist/src/cli/utils/determinism-watcher.js +66 -0
- package/dist/src/cli/utils/real-cli-bin.js +116 -0
- package/dist/src/core/brain/brain-store.js +187 -0
- package/dist/src/core/brain/brain-sync.js +193 -0
- package/dist/src/core/brain/index.js +78 -0
- package/dist/src/core/brain/types.js +10 -0
- package/dist/src/core/cache/content-cache.js +238 -0
- package/dist/src/{integrations/diffmem → core/cache}/index.js +5 -5
- package/dist/src/core/cache/token-estimator.js +39 -0
- package/dist/src/core/config/feature-flags.js +2 -6
- package/dist/src/core/context/frame-database.js +79 -27
- package/dist/src/core/context/recursive-context-manager.js +1 -1
- package/dist/src/core/context/rehydration.js +2 -1
- package/dist/src/core/cross-search/cross-project-search.js +269 -0
- package/dist/src/core/cross-search/index.js +10 -0
- package/dist/src/core/database/sqlite-adapter.js +14 -84
- package/dist/src/core/extensions/provider-adapter.js +5 -0
- package/dist/src/core/models/model-router.js +54 -2
- package/dist/src/core/models/provider-pricing.js +58 -4
- package/dist/src/core/monitoring/logger.js +2 -1
- package/dist/src/core/optimization/trace-optimizer.js +413 -0
- package/dist/src/core/patterns/index.js +22 -0
- package/dist/src/core/patterns/pattern-applier.js +39 -0
- package/dist/src/core/patterns/pattern-observer.js +157 -0
- package/dist/src/core/patterns/pattern-store.js +259 -0
- package/dist/src/core/patterns/types.js +19 -0
- package/dist/src/core/provenance/confidence-scorer.js +128 -0
- package/dist/src/core/provenance/index.js +40 -0
- package/dist/src/core/provenance/provenance-store.js +194 -0
- package/dist/src/core/provenance/types.js +82 -0
- package/dist/src/core/retrieval/llm-context-retrieval.js +5 -4
- package/dist/src/core/retrieval/unified-context-assembler.js +11 -66
- package/dist/src/core/session/project-handoff.js +64 -0
- package/dist/src/core/session/session-manager.js +28 -0
- package/dist/src/core/shared-state/canonical-store.js +564 -0
- package/dist/src/core/skill-packs/index.js +18 -0
- package/dist/src/core/skill-packs/parser.js +42 -0
- package/dist/src/core/skill-packs/registry.js +224 -0
- package/dist/src/core/skill-packs/types.js +79 -0
- package/dist/src/core/storage/cloud-sync-manager.js +116 -0
- package/dist/src/core/storage/cloud-sync.js +574 -0
- package/dist/src/core/storage/two-tier-storage.js +5 -1
- package/dist/src/core/tasks/master-tasks-template.js +43 -0
- package/dist/src/core/tasks/md-task-parser.js +138 -0
- package/dist/src/core/trace/trace-event-store.js +282 -0
- package/dist/src/core/vision/index.js +27 -0
- package/dist/src/core/vision/signals.js +79 -0
- package/dist/src/core/vision/types.js +22 -0
- package/dist/src/core/vision/vision-file.js +146 -0
- package/dist/src/core/vision/vision-loop.js +220 -0
- package/dist/src/core/wiki/wiki-compiler.js +103 -1
- package/dist/src/daemon/daemon-config.js +52 -0
- package/dist/src/daemon/services/desire-path-service.js +566 -0
- package/dist/src/daemon/services/github-service.js +126 -0
- package/dist/src/daemon/services/research-stream-service.js +320 -0
- package/dist/src/daemon/services/telemetry-service.js +192 -0
- package/dist/src/daemon/unified-daemon.js +58 -1
- package/dist/src/features/browser/cli-browser-agent.js +417 -0
- package/dist/src/features/browser/stagehand-workflows.js +578 -0
- package/dist/src/features/operator/adapter-factory.js +62 -0
- package/dist/src/features/operator/browser-adapter.js +109 -0
- package/dist/src/features/operator/desktop-adapter.js +125 -0
- package/dist/src/features/operator/index.js +39 -0
- package/dist/src/features/operator/llm-decision.js +137 -0
- package/dist/src/features/operator/operator-logger.js +92 -0
- package/dist/src/features/operator/overnight-runner.js +327 -0
- package/dist/src/features/operator/screen-adapter.js +91 -0
- package/dist/src/features/operator/session-manager.js +127 -0
- package/dist/src/features/operator/state-machine.js +227 -0
- package/dist/src/features/operator/task-queue.js +81 -0
- package/dist/src/features/portal/index.js +26 -0
- package/dist/src/features/portal/server.js +240 -0
- package/dist/src/features/portal/types.js +14 -0
- package/dist/src/features/portal/ui.js +195 -0
- package/dist/src/features/sweep/pty-wrapper.js +13 -5
- package/dist/src/features/tasks/task-aware-context.js +2 -1
- package/dist/src/features/tui/simple-monitor.js +0 -23
- package/dist/src/features/tui/swarm-monitor.js +8 -66
- package/dist/src/features/web/client/hooks/use-socket.js +12 -0
- package/dist/src/{core/merge/index.js → features/web/client/lib/utils.js} +8 -4
- package/dist/src/features/web/client/next-env.d.js +4 -0
- package/dist/src/features/web/client/stores/session-store.js +12 -0
- package/dist/src/features/web/server/gcp-billing.js +76 -0
- package/dist/src/features/web/server/index.js +10 -0
- package/dist/src/features/web/server/spend-calculator.js +228 -0
- package/dist/src/hooks/schemas.js +6 -1
- package/dist/src/integrations/anthropic/client.js +3 -2
- package/dist/src/integrations/claude-code/agent-bridge.js +0 -3
- package/dist/src/integrations/claude-code/subagent-client.js +307 -11
- package/dist/src/integrations/claude-code/task-coordinator.js +2 -1
- package/dist/src/integrations/github/pr-state.js +158 -0
- package/dist/src/integrations/linear/client.js +4 -1
- package/dist/src/integrations/linear/webhook-retry.js +196 -0
- package/dist/src/integrations/linear/webhook-server.js +18 -22
- package/dist/src/integrations/mcp/handlers/cloud-sync-handlers.js +101 -0
- package/dist/src/integrations/mcp/handlers/index.js +40 -84
- package/dist/src/integrations/mcp/server.js +542 -641
- package/dist/src/integrations/mcp/tool-alias-registry.js +297 -0
- package/dist/src/integrations/mcp/tool-definitions.js +152 -682
- package/dist/src/mcp/stackmemory-mcp-server.js +571 -231
- package/dist/src/orchestrators/multimodal/determinism.js +244 -0
- package/dist/src/orchestrators/multimodal/harness.js +149 -78
- package/dist/src/orchestrators/multimodal/providers.js +44 -3
- package/dist/src/skills/recursive-agent-orchestrator.js +2 -4
- package/dist/src/utils/hook-installer.js +0 -8
- package/dist/src/utils/process-cleanup.js +1 -7
- package/docs/README.md +42 -0
- package/docs/guides/README_INSTALL.md +208 -0
- package/package.json +27 -9
- package/packs/coding/python-fastapi/instructions.md +60 -0
- package/packs/coding/python-fastapi/pack.yaml +28 -0
- package/packs/coding/typescript-react/instructions.md +47 -0
- package/packs/coding/typescript-react/pack.yaml +28 -0
- package/packs/core/commands/capture.md +32 -0
- package/packs/core/commands/learn.md +73 -0
- package/packs/core/commands/next.md +36 -0
- package/packs/core/commands/restart.md +58 -0
- package/packs/core/commands/restore.md +29 -0
- package/packs/core/commands/start.md +57 -0
- package/packs/core/commands/stop.md +65 -0
- package/packs/core/commands/summary.md +40 -0
- package/packs/core/manifest.json +24 -0
- package/packs/ops/decision-recovery/instructions.md +65 -0
- package/packs/ops/decision-recovery/pack.yaml +89 -0
- package/scripts/claude-code-wrapper.sh +11 -0
- package/scripts/claude-sm-setup.sh +12 -1
- package/scripts/codex-wrapper.sh +11 -0
- package/scripts/git-hooks/branch-context-manager.sh +11 -0
- package/scripts/git-hooks/post-checkout-stackmemory.sh +11 -0
- package/scripts/git-hooks/post-commit-stackmemory.sh +11 -0
- package/scripts/git-hooks/pre-commit-stackmemory.sh +11 -0
- package/scripts/hooks/cleanup-shell.sh +12 -1
- package/scripts/hooks/task-complete.sh +12 -1
- package/scripts/install-code-execution-hooks.sh +12 -1
- package/scripts/install-sweep-hook.sh +12 -0
- package/scripts/install.sh +11 -0
- package/scripts/opencode-wrapper.sh +11 -0
- package/scripts/portal/cloud-init.yaml +69 -0
- package/scripts/portal/setup.sh +69 -0
- package/scripts/portal/stackmemory-portal.service +34 -0
- package/scripts/setup-claude-integration.sh +12 -1
- package/scripts/smoke-init-db.sh +23 -0
- package/scripts/stackmemory-daemon.sh +11 -0
- package/scripts/verify-dist.cjs +11 -4
- package/dist/src/cli/commands/ralph.js +0 -1053
- package/dist/src/cli/commands/team.js +0 -168
- package/dist/src/core/context/shared-context-layer.js +0 -620
- package/dist/src/core/context/stack-merge-resolver.js +0 -748
- package/dist/src/core/merge/conflict-detector.js +0 -430
- package/dist/src/core/merge/resolution-engine.js +0 -557
- package/dist/src/core/merge/stack-diff.js +0 -531
- package/dist/src/core/merge/unified-merge-resolver.js +0 -302
- package/dist/src/hooks/diffmem-hooks.js +0 -376
- package/dist/src/integrations/diffmem/client.js +0 -208
- package/dist/src/integrations/diffmem/config.js +0 -14
- package/dist/src/integrations/greptile/client.js +0 -101
- package/dist/src/integrations/greptile/config.js +0 -14
- package/dist/src/integrations/greptile/index.js +0 -11
- package/dist/src/integrations/mcp/handlers/cord-handlers.js +0 -397
- package/dist/src/integrations/mcp/handlers/diffmem-handlers.js +0 -455
- package/dist/src/integrations/mcp/handlers/greptile-handlers.js +0 -456
- package/dist/src/integrations/mcp/handlers/provider-handlers.js +0 -227
- package/dist/src/integrations/mcp/handlers/team-handlers.js +0 -211
- package/dist/src/integrations/ralph/bridge/ralph-stackmemory-bridge.js +0 -863
- package/dist/src/integrations/ralph/context/context-budget-manager.js +0 -308
- package/dist/src/integrations/ralph/context/stackmemory-context-loader.js +0 -391
- package/dist/src/integrations/ralph/index.js +0 -17
- package/dist/src/integrations/ralph/learning/pattern-learner.js +0 -435
- package/dist/src/integrations/ralph/lifecycle/iteration-lifecycle.js +0 -448
- package/dist/src/integrations/ralph/loopmax.js +0 -488
- package/dist/src/integrations/ralph/monitoring/swarm-dashboard.js +0 -293
- package/dist/src/integrations/ralph/monitoring/swarm-registry.js +0 -107
- package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js +0 -508
- package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js +0 -407
- package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js +0 -495
- package/dist/src/integrations/ralph/patterns/oracle-worker-pattern.js +0 -387
- package/dist/src/integrations/ralph/performance/performance-optimizer.js +0 -357
- package/dist/src/integrations/ralph/recovery/crash-recovery.js +0 -461
- package/dist/src/integrations/ralph/state/state-reconciler.js +0 -420
- package/dist/src/integrations/ralph/swarm/git-workflow-manager.js +0 -444
- package/dist/src/integrations/ralph/swarm/swarm-coordinator.js +0 -1007
- package/dist/src/integrations/ralph/visualization/ralph-debugger.js +0 -635
- package/scripts/ralph-loop-implementation.js +0 -404
- /package/dist/src/core/{merge → cache}/types.js +0 -0
- /package/dist/src/{integrations/diffmem/types.js → core/storage/cloud-sync-types.js} +0 -0
- /package/dist/src/{integrations/greptile/types.js → core/trace/trace-event.js} +0 -0
- /package/dist/src/{integrations/ralph → features/operator}/types.js +0 -0
|
@@ -1,302 +0,0 @@
|
|
|
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
|
-
import { v4 as uuidv4 } from "uuid";
|
|
6
|
-
import { ConflictDetector } from "./conflict-detector.js";
|
|
7
|
-
import { StackDiffVisualizer } from "./stack-diff.js";
|
|
8
|
-
import { ResolutionEngine } from "./resolution-engine.js";
|
|
9
|
-
import { logger } from "../monitoring/logger.js";
|
|
10
|
-
class UnifiedMergeResolver {
|
|
11
|
-
conflictDetector;
|
|
12
|
-
diffVisualizer;
|
|
13
|
-
resolutionEngine;
|
|
14
|
-
activeSessions = /* @__PURE__ */ new Map();
|
|
15
|
-
rollbackSnapshots = /* @__PURE__ */ new Map();
|
|
16
|
-
statistics = {
|
|
17
|
-
totalConflicts: 0,
|
|
18
|
-
resolvedConflicts: 0,
|
|
19
|
-
averageResolutionTime: 0,
|
|
20
|
-
successRate: 0,
|
|
21
|
-
rollbackCount: 0
|
|
22
|
-
};
|
|
23
|
-
constructor() {
|
|
24
|
-
this.conflictDetector = new ConflictDetector();
|
|
25
|
-
this.diffVisualizer = new StackDiffVisualizer();
|
|
26
|
-
this.resolutionEngine = new ResolutionEngine();
|
|
27
|
-
logger.debug("UnifiedMergeResolver initialized");
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Start a new merge session with automatic conflict detection
|
|
31
|
-
*/
|
|
32
|
-
async startMergeSession(stack1, stack2, options) {
|
|
33
|
-
const sessionId = `unified-merge-${Date.now()}-${uuidv4().substring(0, 8)}`;
|
|
34
|
-
const conflicts = this.conflictDetector.detectConflicts(stack1, stack2);
|
|
35
|
-
let rollbackPoint;
|
|
36
|
-
if (options?.preserveRollback !== false) {
|
|
37
|
-
rollbackPoint = this.createRollbackSnapshot(sessionId, stack1, stack2);
|
|
38
|
-
}
|
|
39
|
-
const session = {
|
|
40
|
-
sessionId,
|
|
41
|
-
stack1,
|
|
42
|
-
stack2,
|
|
43
|
-
conflicts,
|
|
44
|
-
status: "analyzing",
|
|
45
|
-
rollbackPoint,
|
|
46
|
-
startedAt: Date.now(),
|
|
47
|
-
metadata: {
|
|
48
|
-
totalFrames: stack1.frames.length + stack2.frames.length,
|
|
49
|
-
conflictCount: conflicts.length,
|
|
50
|
-
resolvedCount: 0
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
this.activeSessions.set(sessionId, session);
|
|
54
|
-
this.statistics.totalConflicts += conflicts.length;
|
|
55
|
-
logger.info(`Merge session started: ${sessionId}`, {
|
|
56
|
-
stack1Id: stack1.id,
|
|
57
|
-
stack2Id: stack2.id,
|
|
58
|
-
conflictCount: conflicts.length
|
|
59
|
-
});
|
|
60
|
-
if (options?.autoResolve && conflicts.length > 0 && options.context) {
|
|
61
|
-
const defaultStrategy = options.strategy || "ai_suggest";
|
|
62
|
-
await this.resolveConflicts(sessionId, defaultStrategy, options.context);
|
|
63
|
-
}
|
|
64
|
-
return sessionId;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Generate a preview of the merge result
|
|
68
|
-
*/
|
|
69
|
-
async generatePreview(sessionId, strategy) {
|
|
70
|
-
const session = this.activeSessions.get(sessionId);
|
|
71
|
-
if (!session) {
|
|
72
|
-
throw new Error(`Session not found: ${sessionId}`);
|
|
73
|
-
}
|
|
74
|
-
const preview = this.diffVisualizer.generateMergePreview(
|
|
75
|
-
session.stack1,
|
|
76
|
-
session.stack2,
|
|
77
|
-
strategy
|
|
78
|
-
);
|
|
79
|
-
session.preview = preview;
|
|
80
|
-
session.status = "preview";
|
|
81
|
-
session.metadata.strategyUsed = strategy;
|
|
82
|
-
this.activeSessions.set(sessionId, session);
|
|
83
|
-
logger.info(`Preview generated for session: ${sessionId}`, {
|
|
84
|
-
mergedFrameCount: preview.mergedFrames.length,
|
|
85
|
-
estimatedSuccess: preview.estimatedSuccess
|
|
86
|
-
});
|
|
87
|
-
return preview;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Resolve conflicts using the specified strategy
|
|
91
|
-
*/
|
|
92
|
-
async resolveConflicts(sessionId, strategy, context) {
|
|
93
|
-
const session = this.activeSessions.get(sessionId);
|
|
94
|
-
if (!session) {
|
|
95
|
-
throw new Error(`Session not found: ${sessionId}`);
|
|
96
|
-
}
|
|
97
|
-
session.status = "resolving";
|
|
98
|
-
try {
|
|
99
|
-
const result = await this.resolutionEngine.resolveConflicts(
|
|
100
|
-
session.stack1,
|
|
101
|
-
session.stack2,
|
|
102
|
-
strategy,
|
|
103
|
-
context
|
|
104
|
-
);
|
|
105
|
-
session.resolution = result.resolution;
|
|
106
|
-
session.status = result.success ? "completed" : "failed";
|
|
107
|
-
session.completedAt = Date.now();
|
|
108
|
-
session.metadata.resolvedCount = session.conflicts.filter(
|
|
109
|
-
(c) => c.resolution !== void 0
|
|
110
|
-
).length;
|
|
111
|
-
session.metadata.strategyUsed = strategy;
|
|
112
|
-
this.activeSessions.set(sessionId, session);
|
|
113
|
-
if (result.success) {
|
|
114
|
-
this.statistics.resolvedConflicts += session.metadata.resolvedCount;
|
|
115
|
-
this.updateSuccessRate();
|
|
116
|
-
this.updateAverageResolutionTime(session);
|
|
117
|
-
}
|
|
118
|
-
logger.info(`Conflicts resolved for session: ${sessionId}`, {
|
|
119
|
-
success: result.success,
|
|
120
|
-
strategy,
|
|
121
|
-
resolvedCount: session.metadata.resolvedCount
|
|
122
|
-
});
|
|
123
|
-
return result;
|
|
124
|
-
} catch (error) {
|
|
125
|
-
session.status = "failed";
|
|
126
|
-
this.activeSessions.set(sessionId, session);
|
|
127
|
-
logger.error(
|
|
128
|
-
`Failed to resolve conflicts for session: ${sessionId}`,
|
|
129
|
-
error
|
|
130
|
-
);
|
|
131
|
-
throw error;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Rollback a merge to its original state
|
|
136
|
-
*/
|
|
137
|
-
async rollback(sessionId) {
|
|
138
|
-
const session = this.activeSessions.get(sessionId);
|
|
139
|
-
if (!session || !session.rollbackPoint) {
|
|
140
|
-
logger.warn(`Cannot rollback session: ${sessionId} - no rollback point`);
|
|
141
|
-
return false;
|
|
142
|
-
}
|
|
143
|
-
const snapshot = this.rollbackSnapshots.get(session.rollbackPoint);
|
|
144
|
-
if (!snapshot) {
|
|
145
|
-
logger.error(`Rollback snapshot not found: ${session.rollbackPoint}`);
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
session.stack1 = snapshot.stack1;
|
|
149
|
-
session.stack2 = snapshot.stack2;
|
|
150
|
-
session.status = "rolled_back";
|
|
151
|
-
session.resolution = void 0;
|
|
152
|
-
session.conflicts = this.conflictDetector.detectConflicts(
|
|
153
|
-
snapshot.stack1,
|
|
154
|
-
snapshot.stack2
|
|
155
|
-
);
|
|
156
|
-
session.metadata.resolvedCount = 0;
|
|
157
|
-
this.activeSessions.set(sessionId, session);
|
|
158
|
-
this.statistics.rollbackCount++;
|
|
159
|
-
logger.info(`Session rolled back: ${sessionId}`);
|
|
160
|
-
return true;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Get merge session details
|
|
164
|
-
*/
|
|
165
|
-
getSession(sessionId) {
|
|
166
|
-
return this.activeSessions.get(sessionId);
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* List all active merge sessions
|
|
170
|
-
*/
|
|
171
|
-
listActiveSessions() {
|
|
172
|
-
return Array.from(this.activeSessions.values()).filter(
|
|
173
|
-
(s) => s.status !== "completed" && s.status !== "rolled_back" && s.status !== "failed"
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Get merge statistics
|
|
178
|
-
*/
|
|
179
|
-
getStatistics() {
|
|
180
|
-
return { ...this.statistics };
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Analyze parallel solutions across stacks
|
|
184
|
-
*/
|
|
185
|
-
analyzeParallelSolutions(frames) {
|
|
186
|
-
const solutions = this.conflictDetector.analyzeParallelSolutions(frames);
|
|
187
|
-
const recommendations = [];
|
|
188
|
-
if (solutions.length > 1) {
|
|
189
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
190
|
-
for (const sol of solutions) {
|
|
191
|
-
const key = sol.approach.toLowerCase();
|
|
192
|
-
if (!grouped.has(key)) {
|
|
193
|
-
grouped.set(key, []);
|
|
194
|
-
}
|
|
195
|
-
grouped.get(key).push(sol);
|
|
196
|
-
}
|
|
197
|
-
for (const [approach, group] of grouped) {
|
|
198
|
-
if (group.length > 1) {
|
|
199
|
-
const avgEffectiveness = group.reduce((sum, s) => sum + (s.effectiveness || 0), 0) / group.length;
|
|
200
|
-
recommendations.push(
|
|
201
|
-
`${group.length} parallel solutions using "${approach}" approach (avg effectiveness: ${(avgEffectiveness * 100).toFixed(1)}%)`
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
const best = solutions.reduce(
|
|
206
|
-
(a, b) => (a.effectiveness || 0) > (b.effectiveness || 0) ? a : b,
|
|
207
|
-
solutions[0]
|
|
208
|
-
);
|
|
209
|
-
if (best && best.effectiveness && best.effectiveness > 0.7) {
|
|
210
|
-
recommendations.push(
|
|
211
|
-
`Recommended: Use solution from frame "${best.frameId}" (${(best.effectiveness * 100).toFixed(1)}% effectiveness)`
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return {
|
|
216
|
-
solutions: solutions.map((s) => ({
|
|
217
|
-
frameId: s.frameId,
|
|
218
|
-
approach: s.approach,
|
|
219
|
-
effectiveness: s.effectiveness || 0
|
|
220
|
-
})),
|
|
221
|
-
recommendations
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Create a visual diff between two stacks
|
|
226
|
-
*/
|
|
227
|
-
createVisualDiff(baseFrame, stack1, stack2) {
|
|
228
|
-
const diff = this.diffVisualizer.visualizeDivergence(
|
|
229
|
-
baseFrame,
|
|
230
|
-
stack1,
|
|
231
|
-
stack2
|
|
232
|
-
);
|
|
233
|
-
const conflicts = this.conflictDetector.detectConflicts(stack1, stack2);
|
|
234
|
-
return {
|
|
235
|
-
nodes: diff.nodes.map((n) => ({
|
|
236
|
-
id: n.id,
|
|
237
|
-
type: n.type,
|
|
238
|
-
depth: n.frame?.depth
|
|
239
|
-
})),
|
|
240
|
-
edges: diff.edges.map((e) => ({
|
|
241
|
-
source: e.source,
|
|
242
|
-
target: e.target,
|
|
243
|
-
type: e.type
|
|
244
|
-
})),
|
|
245
|
-
conflicts: conflicts.map((c) => ({
|
|
246
|
-
frameId1: c.frameId1,
|
|
247
|
-
frameId2: c.frameId2,
|
|
248
|
-
severity: c.severity
|
|
249
|
-
}))
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Close a merge session and clean up resources
|
|
254
|
-
*/
|
|
255
|
-
closeSession(sessionId) {
|
|
256
|
-
const session = this.activeSessions.get(sessionId);
|
|
257
|
-
if (session) {
|
|
258
|
-
if (session.rollbackPoint) {
|
|
259
|
-
this.rollbackSnapshots.delete(session.rollbackPoint);
|
|
260
|
-
}
|
|
261
|
-
this.activeSessions.delete(sessionId);
|
|
262
|
-
logger.debug(`Session closed: ${sessionId}`);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
// Private helpers
|
|
266
|
-
createRollbackSnapshot(sessionId, stack1, stack2) {
|
|
267
|
-
const snapshotId = `rollback-${sessionId}`;
|
|
268
|
-
this.rollbackSnapshots.set(snapshotId, {
|
|
269
|
-
stack1: this.deepCloneStack(stack1),
|
|
270
|
-
stack2: this.deepCloneStack(stack2)
|
|
271
|
-
});
|
|
272
|
-
return snapshotId;
|
|
273
|
-
}
|
|
274
|
-
deepCloneStack(stack) {
|
|
275
|
-
return {
|
|
276
|
-
...stack,
|
|
277
|
-
frames: stack.frames.map((f) => ({ ...f })),
|
|
278
|
-
events: stack.events.map((e) => ({ ...e }))
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
updateSuccessRate() {
|
|
282
|
-
if (this.statistics.totalConflicts > 0) {
|
|
283
|
-
this.statistics.successRate = this.statistics.resolvedConflicts / this.statistics.totalConflicts;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
updateAverageResolutionTime(session) {
|
|
287
|
-
if (session.completedAt && session.startedAt) {
|
|
288
|
-
const duration = session.completedAt - session.startedAt;
|
|
289
|
-
const completedSessions = Array.from(this.activeSessions.values()).filter(
|
|
290
|
-
(s) => s.completedAt
|
|
291
|
-
).length;
|
|
292
|
-
if (completedSessions === 1) {
|
|
293
|
-
this.statistics.averageResolutionTime = duration;
|
|
294
|
-
} else {
|
|
295
|
-
this.statistics.averageResolutionTime = (this.statistics.averageResolutionTime * (completedSessions - 1) + duration) / completedSessions;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
export {
|
|
301
|
-
UnifiedMergeResolver
|
|
302
|
-
};
|
|
@@ -1,376 +0,0 @@
|
|
|
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
|
-
import { logger } from "../core/monitoring/logger.js";
|
|
6
|
-
const DEFAULT_CONFIG = {
|
|
7
|
-
enabled: !!process.env.DIFFMEM_ENDPOINT,
|
|
8
|
-
endpoint: process.env.DIFFMEM_ENDPOINT || "http://localhost:3100",
|
|
9
|
-
autoFetchCategories: ["preference", "expertise", "pattern"],
|
|
10
|
-
autoLearnEnabled: true,
|
|
11
|
-
learningConfidenceThreshold: 0.7,
|
|
12
|
-
maxMemoriesPerSession: 50
|
|
13
|
-
};
|
|
14
|
-
class DiffMemHooks {
|
|
15
|
-
config;
|
|
16
|
-
fetchedMemories = [];
|
|
17
|
-
learningBuffer = [];
|
|
18
|
-
isConnected = false;
|
|
19
|
-
frameManager;
|
|
20
|
-
sessionStartTime = 0;
|
|
21
|
-
constructor(config = {}) {
|
|
22
|
-
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Register session hooks with the event emitter
|
|
26
|
-
*/
|
|
27
|
-
register(emitter, frameManager) {
|
|
28
|
-
this.frameManager = frameManager;
|
|
29
|
-
if (!this.config.enabled) {
|
|
30
|
-
logger.debug("DiffMem hooks disabled - skipping registration");
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
emitter.registerHandler("session_start", this.onSessionStart.bind(this));
|
|
34
|
-
emitter.registerHandler("session_end", this.onSessionEnd.bind(this));
|
|
35
|
-
logger.info("DiffMem hooks registered", {
|
|
36
|
-
endpoint: this.config.endpoint,
|
|
37
|
-
autoFetchCategories: this.config.autoFetchCategories,
|
|
38
|
-
autoLearnEnabled: this.config.autoLearnEnabled
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Handle session start - fetch user knowledge
|
|
43
|
-
*/
|
|
44
|
-
async onSessionStart(event) {
|
|
45
|
-
const sessionEvent = event;
|
|
46
|
-
this.sessionStartTime = Date.now();
|
|
47
|
-
try {
|
|
48
|
-
const status = await this.checkStatus();
|
|
49
|
-
this.isConnected = status.connected;
|
|
50
|
-
if (!this.isConnected) {
|
|
51
|
-
logger.debug("DiffMem not available - skipping memory fetch");
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
const query = {
|
|
55
|
-
categories: this.config.autoFetchCategories,
|
|
56
|
-
limit: this.config.maxMemoriesPerSession,
|
|
57
|
-
minConfidence: this.config.learningConfidenceThreshold
|
|
58
|
-
};
|
|
59
|
-
this.fetchedMemories = await this.fetchMemories(query);
|
|
60
|
-
if (this.frameManager && this.fetchedMemories.length > 0) {
|
|
61
|
-
await this.injectAsAnchors(sessionEvent.data.sessionId);
|
|
62
|
-
}
|
|
63
|
-
logger.info("DiffMem session start completed", {
|
|
64
|
-
memoriesFetched: this.fetchedMemories.length,
|
|
65
|
-
sessionId: sessionEvent.data.sessionId
|
|
66
|
-
});
|
|
67
|
-
} catch (error) {
|
|
68
|
-
logger.warn("DiffMem session start failed", {
|
|
69
|
-
error: error instanceof Error ? error.message : String(error)
|
|
70
|
-
});
|
|
71
|
-
this.isConnected = false;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Handle session end - sync buffered learnings
|
|
76
|
-
*/
|
|
77
|
-
async onSessionEnd(event) {
|
|
78
|
-
const sessionEvent = event;
|
|
79
|
-
if (!this.config.autoLearnEnabled || this.learningBuffer.length === 0) {
|
|
80
|
-
logger.debug("No learnings to sync on session end");
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
if (!this.isConnected) {
|
|
84
|
-
const status = await this.checkStatus();
|
|
85
|
-
if (!status.connected) {
|
|
86
|
-
logger.warn("DiffMem not available - learnings not synced", {
|
|
87
|
-
bufferedCount: this.learningBuffer.length
|
|
88
|
-
});
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
this.isConnected = true;
|
|
92
|
-
}
|
|
93
|
-
try {
|
|
94
|
-
await this.syncLearnings();
|
|
95
|
-
const sessionDuration = Date.now() - this.sessionStartTime;
|
|
96
|
-
logger.info("DiffMem session end completed", {
|
|
97
|
-
learningSynced: this.learningBuffer.length,
|
|
98
|
-
sessionId: sessionEvent.data.sessionId,
|
|
99
|
-
sessionDurationMs: sessionDuration
|
|
100
|
-
});
|
|
101
|
-
this.learningBuffer = [];
|
|
102
|
-
} catch (error) {
|
|
103
|
-
logger.warn("DiffMem session end sync failed", {
|
|
104
|
-
error: error instanceof Error ? error.message : String(error),
|
|
105
|
-
bufferedCount: this.learningBuffer.length
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Record a learning during session
|
|
111
|
-
*/
|
|
112
|
-
recordLearning(insight) {
|
|
113
|
-
if (!this.config.autoLearnEnabled) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
if (insight.confidence < this.config.learningConfidenceThreshold) {
|
|
117
|
-
logger.debug("Learning below confidence threshold", {
|
|
118
|
-
confidence: insight.confidence,
|
|
119
|
-
threshold: this.config.learningConfidenceThreshold
|
|
120
|
-
});
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
const learning = {
|
|
124
|
-
...insight,
|
|
125
|
-
timestamp: Date.now()
|
|
126
|
-
};
|
|
127
|
-
this.learningBuffer.push(learning);
|
|
128
|
-
logger.debug("Learning recorded", {
|
|
129
|
-
category: learning.category,
|
|
130
|
-
confidence: learning.confidence,
|
|
131
|
-
bufferSize: this.learningBuffer.length
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Get fetched memories
|
|
136
|
-
*/
|
|
137
|
-
getUserKnowledge() {
|
|
138
|
-
return [...this.fetchedMemories];
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Format memories for LLM context with token budget
|
|
142
|
-
*/
|
|
143
|
-
formatForContext(maxTokens = 2e3) {
|
|
144
|
-
if (this.fetchedMemories.length === 0) {
|
|
145
|
-
return "";
|
|
146
|
-
}
|
|
147
|
-
const sortedMemories = [...this.fetchedMemories].sort((a, b) => {
|
|
148
|
-
if (b.confidence !== a.confidence) {
|
|
149
|
-
return b.confidence - a.confidence;
|
|
150
|
-
}
|
|
151
|
-
return b.timestamp - a.timestamp;
|
|
152
|
-
});
|
|
153
|
-
const sections = /* @__PURE__ */ new Map();
|
|
154
|
-
for (const memory of sortedMemories) {
|
|
155
|
-
const category = memory.category;
|
|
156
|
-
if (!sections.has(category)) {
|
|
157
|
-
sections.set(category, []);
|
|
158
|
-
}
|
|
159
|
-
const categoryMemories = sections.get(category);
|
|
160
|
-
if (categoryMemories) {
|
|
161
|
-
categoryMemories.push(memory.content);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
const lines = ["## User Knowledge"];
|
|
165
|
-
let estimatedTokens = 5;
|
|
166
|
-
const categoryLabels = {
|
|
167
|
-
preference: "Preferences",
|
|
168
|
-
expertise: "Expertise",
|
|
169
|
-
project_knowledge: "Project Knowledge",
|
|
170
|
-
pattern: "Patterns",
|
|
171
|
-
correction: "Corrections"
|
|
172
|
-
};
|
|
173
|
-
for (const [category, contents] of sections) {
|
|
174
|
-
const label = categoryLabels[category] || category;
|
|
175
|
-
const categoryHeader = `
|
|
176
|
-
### ${label}`;
|
|
177
|
-
const headerTokens = Math.ceil(categoryHeader.length / 4);
|
|
178
|
-
if (estimatedTokens + headerTokens > maxTokens) {
|
|
179
|
-
break;
|
|
180
|
-
}
|
|
181
|
-
lines.push(categoryHeader);
|
|
182
|
-
estimatedTokens += headerTokens;
|
|
183
|
-
for (const content of contents) {
|
|
184
|
-
const contentLine = `- ${content}`;
|
|
185
|
-
const contentTokens = Math.ceil(contentLine.length / 4);
|
|
186
|
-
if (estimatedTokens + contentTokens > maxTokens) {
|
|
187
|
-
lines.push("- (additional items truncated for token budget)");
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
lines.push(contentLine);
|
|
191
|
-
estimatedTokens += contentTokens;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return lines.join("\n");
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Get current connection status
|
|
198
|
-
*/
|
|
199
|
-
getStatus() {
|
|
200
|
-
return {
|
|
201
|
-
connected: this.isConnected,
|
|
202
|
-
memoriesLoaded: this.fetchedMemories.length,
|
|
203
|
-
learningsBuffered: this.learningBuffer.length
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Update configuration
|
|
208
|
-
*/
|
|
209
|
-
updateConfig(config) {
|
|
210
|
-
this.config = { ...this.config, ...config };
|
|
211
|
-
logger.debug("DiffMem config updated", { config: this.config });
|
|
212
|
-
}
|
|
213
|
-
// Private methods
|
|
214
|
-
/**
|
|
215
|
-
* Check DiffMem service status
|
|
216
|
-
*/
|
|
217
|
-
async checkStatus() {
|
|
218
|
-
try {
|
|
219
|
-
const controller = new AbortController();
|
|
220
|
-
const timeoutId = setTimeout(() => controller.abort(), 3e3);
|
|
221
|
-
const response = await fetch(`${this.config.endpoint}/status`, {
|
|
222
|
-
method: "GET",
|
|
223
|
-
signal: controller.signal
|
|
224
|
-
});
|
|
225
|
-
clearTimeout(timeoutId);
|
|
226
|
-
if (!response.ok) {
|
|
227
|
-
return { connected: false, memoryCount: 0, lastSync: null };
|
|
228
|
-
}
|
|
229
|
-
const status = await response.json();
|
|
230
|
-
return {
|
|
231
|
-
connected: true,
|
|
232
|
-
memoryCount: status.memoryCount || 0,
|
|
233
|
-
lastSync: status.lastSync || null,
|
|
234
|
-
version: status.version
|
|
235
|
-
};
|
|
236
|
-
} catch {
|
|
237
|
-
return { connected: false, memoryCount: 0, lastSync: null };
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Fetch memories from DiffMem
|
|
242
|
-
*/
|
|
243
|
-
async fetchMemories(query) {
|
|
244
|
-
try {
|
|
245
|
-
const controller = new AbortController();
|
|
246
|
-
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
247
|
-
const response = await fetch(`${this.config.endpoint}/memories/query`, {
|
|
248
|
-
method: "POST",
|
|
249
|
-
headers: { "Content-Type": "application/json" },
|
|
250
|
-
body: JSON.stringify(query),
|
|
251
|
-
signal: controller.signal
|
|
252
|
-
});
|
|
253
|
-
clearTimeout(timeoutId);
|
|
254
|
-
if (!response.ok) {
|
|
255
|
-
logger.warn("DiffMem query failed", { status: response.status });
|
|
256
|
-
return [];
|
|
257
|
-
}
|
|
258
|
-
const data = await response.json();
|
|
259
|
-
return data.memories || [];
|
|
260
|
-
} catch (error) {
|
|
261
|
-
logger.debug("DiffMem fetch failed", {
|
|
262
|
-
error: error instanceof Error ? error.message : String(error)
|
|
263
|
-
});
|
|
264
|
-
return [];
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Sync buffered learnings to DiffMem
|
|
269
|
-
*/
|
|
270
|
-
async syncLearnings() {
|
|
271
|
-
if (this.learningBuffer.length === 0) {
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
const controller = new AbortController();
|
|
275
|
-
const timeoutId = setTimeout(() => controller.abort(), 1e4);
|
|
276
|
-
try {
|
|
277
|
-
const response = await fetch(`${this.config.endpoint}/memories/learn`, {
|
|
278
|
-
method: "POST",
|
|
279
|
-
headers: { "Content-Type": "application/json" },
|
|
280
|
-
body: JSON.stringify({ insights: this.learningBuffer }),
|
|
281
|
-
signal: controller.signal
|
|
282
|
-
});
|
|
283
|
-
clearTimeout(timeoutId);
|
|
284
|
-
if (!response.ok) {
|
|
285
|
-
throw new Error(`Sync failed with status ${response.status}`);
|
|
286
|
-
}
|
|
287
|
-
logger.info("Learnings synced to DiffMem", {
|
|
288
|
-
count: this.learningBuffer.length
|
|
289
|
-
});
|
|
290
|
-
} catch (error) {
|
|
291
|
-
clearTimeout(timeoutId);
|
|
292
|
-
throw error;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Inject fetched memories as frame anchors
|
|
297
|
-
*/
|
|
298
|
-
async injectAsAnchors(sessionId) {
|
|
299
|
-
if (!this.frameManager || this.fetchedMemories.length === 0) {
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
try {
|
|
303
|
-
const byCategory = /* @__PURE__ */ new Map();
|
|
304
|
-
for (const memory of this.fetchedMemories) {
|
|
305
|
-
if (!byCategory.has(memory.category)) {
|
|
306
|
-
byCategory.set(memory.category, []);
|
|
307
|
-
}
|
|
308
|
-
const categoryList = byCategory.get(memory.category);
|
|
309
|
-
if (categoryList) {
|
|
310
|
-
categoryList.push(memory);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
for (const [category, memories] of byCategory) {
|
|
314
|
-
const highConfidence = memories.filter((m) => m.confidence >= 0.8);
|
|
315
|
-
for (const memory of highConfidence.slice(0, 5)) {
|
|
316
|
-
const anchorType = this.categoryToAnchorType(category);
|
|
317
|
-
const priority = Math.round(memory.confidence * 10);
|
|
318
|
-
this.frameManager.addAnchor(anchorType, memory.content, priority, {
|
|
319
|
-
source: "diffmem",
|
|
320
|
-
category: memory.category,
|
|
321
|
-
memoryId: memory.id,
|
|
322
|
-
confidence: memory.confidence,
|
|
323
|
-
sessionId
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
logger.debug("Memories injected as anchors", {
|
|
328
|
-
totalMemories: this.fetchedMemories.length,
|
|
329
|
-
anchorsCreated: Math.min(
|
|
330
|
-
this.fetchedMemories.filter((m) => m.confidence >= 0.8).length,
|
|
331
|
-
25
|
|
332
|
-
)
|
|
333
|
-
});
|
|
334
|
-
} catch (error) {
|
|
335
|
-
logger.warn("Failed to inject memories as anchors", {
|
|
336
|
-
error: error instanceof Error ? error.message : String(error)
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
/**
|
|
341
|
-
* Map memory category to anchor type
|
|
342
|
-
*/
|
|
343
|
-
categoryToAnchorType(category) {
|
|
344
|
-
switch (category) {
|
|
345
|
-
case "preference":
|
|
346
|
-
return "CONSTRAINT";
|
|
347
|
-
case "expertise":
|
|
348
|
-
return "FACT";
|
|
349
|
-
case "project_knowledge":
|
|
350
|
-
return "FACT";
|
|
351
|
-
case "pattern":
|
|
352
|
-
return "INTERFACE_CONTRACT";
|
|
353
|
-
case "correction":
|
|
354
|
-
return "DECISION";
|
|
355
|
-
default:
|
|
356
|
-
return "FACT";
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
let instance = null;
|
|
361
|
-
function getDiffMemHooks(config) {
|
|
362
|
-
if (!instance) {
|
|
363
|
-
instance = new DiffMemHooks(config);
|
|
364
|
-
} else if (config) {
|
|
365
|
-
instance.updateConfig(config);
|
|
366
|
-
}
|
|
367
|
-
return instance;
|
|
368
|
-
}
|
|
369
|
-
function resetDiffMemHooks() {
|
|
370
|
-
instance = null;
|
|
371
|
-
}
|
|
372
|
-
export {
|
|
373
|
-
DiffMemHooks,
|
|
374
|
-
getDiffMemHooks,
|
|
375
|
-
resetDiffMemHooks
|
|
376
|
-
};
|