talkback-mcp 0.1.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/dist/context-assembler.d.ts +7 -0
- package/dist/context-assembler.d.ts.map +1 -0
- package/dist/context-assembler.js +181 -0
- package/dist/context-assembler.js.map +1 -0
- package/dist/heuristics/dynamics.d.ts +3 -0
- package/dist/heuristics/dynamics.d.ts.map +1 -0
- package/dist/heuristics/dynamics.js +53 -0
- package/dist/heuristics/dynamics.js.map +1 -0
- package/dist/heuristics/frequency-buildup.d.ts +3 -0
- package/dist/heuristics/frequency-buildup.d.ts.map +1 -0
- package/dist/heuristics/frequency-buildup.js +69 -0
- package/dist/heuristics/frequency-buildup.js.map +1 -0
- package/dist/heuristics/headroom.d.ts +3 -0
- package/dist/heuristics/headroom.d.ts.map +1 -0
- package/dist/heuristics/headroom.js +54 -0
- package/dist/heuristics/headroom.js.map +1 -0
- package/dist/heuristics/index.d.ts +3 -0
- package/dist/heuristics/index.d.ts.map +1 -0
- package/dist/heuristics/index.js +22 -0
- package/dist/heuristics/index.js.map +1 -0
- package/dist/heuristics/routing.d.ts +3 -0
- package/dist/heuristics/routing.d.ts.map +1 -0
- package/dist/heuristics/routing.js +60 -0
- package/dist/heuristics/routing.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +4 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +437 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/param-maps/compressor.d.ts +3 -0
- package/dist/param-maps/compressor.d.ts.map +1 -0
- package/dist/param-maps/compressor.js +51 -0
- package/dist/param-maps/compressor.js.map +1 -0
- package/dist/param-maps/eq-eight.d.ts +3 -0
- package/dist/param-maps/eq-eight.d.ts.map +1 -0
- package/dist/param-maps/eq-eight.js +55 -0
- package/dist/param-maps/eq-eight.js.map +1 -0
- package/dist/param-maps/generic.d.ts +3 -0
- package/dist/param-maps/generic.d.ts.map +1 -0
- package/dist/param-maps/generic.js +11 -0
- package/dist/param-maps/generic.js.map +1 -0
- package/dist/param-maps/index.d.ts +14 -0
- package/dist/param-maps/index.d.ts.map +1 -0
- package/dist/param-maps/index.js +42 -0
- package/dist/param-maps/index.js.map +1 -0
- package/dist/plugin-library.d.ts +4 -0
- package/dist/plugin-library.d.ts.map +1 -0
- package/dist/plugin-library.js +63 -0
- package/dist/plugin-library.js.map +1 -0
- package/dist/spectral.d.ts +9 -0
- package/dist/spectral.d.ts.map +1 -0
- package/dist/spectral.js +63 -0
- package/dist/spectral.js.map +1 -0
- package/dist/stdio.d.ts +3 -0
- package/dist/stdio.d.ts.map +1 -0
- package/dist/stdio.js +32 -0
- package/dist/stdio.js.map +1 -0
- package/dist/types.d.ts +171 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/ws-bridge.d.ts +15 -0
- package/dist/ws-bridge.d.ts.map +1 -0
- package/dist/ws-bridge.js +139 -0
- package/dist/ws-bridge.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SemanticSession, SessionCache } from "./types.js";
|
|
2
|
+
export declare function rawVolumeToDb(raw: number): string;
|
|
3
|
+
export declare function rawPanToHuman(raw: number): string;
|
|
4
|
+
export declare function rawSendToPercent(raw: number): string;
|
|
5
|
+
export declare function rawMeterToDb(left: number, right: number): string;
|
|
6
|
+
export declare function assembleContext(cache: SessionCache): SemanticSession | null;
|
|
7
|
+
//# sourceMappingURL=context-assembler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-assembler.d.ts","sourceRoot":"","sources":["../src/context-assembler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,eAAe,EAGf,YAAY,EACb,MAAM,YAAY,CAAC;AAOpB,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOjD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOhE;AAsJD,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,eAAe,GAAG,IAAI,CA6C3E"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { lookupParamMap, translateParameter } from "./param-maps/index.js";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// Volume / pan / meter conversions
|
|
4
|
+
// ============================================================
|
|
5
|
+
export function rawVolumeToDb(raw) {
|
|
6
|
+
if (raw <= 0)
|
|
7
|
+
return "-inf dB";
|
|
8
|
+
const db = 20 * Math.log10(raw / 0.85);
|
|
9
|
+
if (db <= -70)
|
|
10
|
+
return "-inf dB";
|
|
11
|
+
const rounded = Math.round(db * 10) / 10;
|
|
12
|
+
const sign = rounded > 0 ? "+" : "";
|
|
13
|
+
return `${sign}${rounded}dB`;
|
|
14
|
+
}
|
|
15
|
+
export function rawPanToHuman(raw) {
|
|
16
|
+
if (Math.abs(raw) < 0.01)
|
|
17
|
+
return "center";
|
|
18
|
+
const pct = Math.round(Math.abs(raw) * 100);
|
|
19
|
+
const side = raw < 0 ? "left" : "right";
|
|
20
|
+
if (pct >= 99)
|
|
21
|
+
return `hard ${side}`;
|
|
22
|
+
return `${pct}% ${side}`;
|
|
23
|
+
}
|
|
24
|
+
export function rawSendToPercent(raw) {
|
|
25
|
+
return `${Math.round(raw * 100)}%`;
|
|
26
|
+
}
|
|
27
|
+
export function rawMeterToDb(left, right) {
|
|
28
|
+
const peak = Math.max(left, right);
|
|
29
|
+
if (peak <= 0)
|
|
30
|
+
return "silent";
|
|
31
|
+
const db = 20 * Math.log10(peak);
|
|
32
|
+
if (db <= -60)
|
|
33
|
+
return "silent";
|
|
34
|
+
const rounded = Math.round(db * 10) / 10;
|
|
35
|
+
return `${rounded}dB`;
|
|
36
|
+
}
|
|
37
|
+
// ============================================================
|
|
38
|
+
// Device assembly
|
|
39
|
+
// ============================================================
|
|
40
|
+
function assembleDevice(device) {
|
|
41
|
+
const paramMap = lookupParamMap(device.className);
|
|
42
|
+
const isThirdParty = device.type === "PluginDevice";
|
|
43
|
+
const parameters = {};
|
|
44
|
+
const observations = [];
|
|
45
|
+
for (const param of device.parameters) {
|
|
46
|
+
parameters[param.name] = translateParameter(device.className, param.name, param.value, paramMap);
|
|
47
|
+
}
|
|
48
|
+
// Generate observations from param map advisors
|
|
49
|
+
if (paramMap) {
|
|
50
|
+
for (const param of device.parameters) {
|
|
51
|
+
const mapEntry = paramMap.parameters[param.name];
|
|
52
|
+
if (mapEntry?.observe) {
|
|
53
|
+
const observation = mapEntry.observe(param.value, parameters[param.name]);
|
|
54
|
+
if (observation)
|
|
55
|
+
observations.push(observation);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
id: device.id,
|
|
61
|
+
name: device.name,
|
|
62
|
+
active: device.isActive,
|
|
63
|
+
isThirdParty,
|
|
64
|
+
parameters,
|
|
65
|
+
observations,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// ============================================================
|
|
69
|
+
// Track assembly
|
|
70
|
+
// ============================================================
|
|
71
|
+
function assembleTrack(track, returnTrackNames, trackNameMap) {
|
|
72
|
+
const sends = {};
|
|
73
|
+
if (Array.isArray(track.sends)) {
|
|
74
|
+
for (const send of track.sends) {
|
|
75
|
+
const returnName = returnTrackNames.get(send.returnTrackId) ?? send.returnTrackId;
|
|
76
|
+
sends[returnName] = rawSendToPercent(send.amount);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Handle both full device objects and lightweight device name arrays
|
|
80
|
+
const devices = Array.isArray(track.devices)
|
|
81
|
+
? track.devices.map(assembleDevice)
|
|
82
|
+
: [];
|
|
83
|
+
// If we only have deviceNames (lightweight snapshot), show them as simple entries
|
|
84
|
+
const deviceNameList = track.deviceNames ?? [];
|
|
85
|
+
if (devices.length === 0 && deviceNameList.length > 0) {
|
|
86
|
+
for (const dn of deviceNameList) {
|
|
87
|
+
devices.push({
|
|
88
|
+
id: dn,
|
|
89
|
+
name: dn,
|
|
90
|
+
active: true,
|
|
91
|
+
isThirdParty: false,
|
|
92
|
+
parameters: {},
|
|
93
|
+
observations: [],
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Resolve group name from ID
|
|
98
|
+
const groupName = track.groupId
|
|
99
|
+
? trackNameMap.get(track.groupId) ?? track.groupId
|
|
100
|
+
: null;
|
|
101
|
+
// Output level from meters
|
|
102
|
+
const meterLeft = track.outputMeterLeft ?? 0;
|
|
103
|
+
const meterRight = track.outputMeterRight ?? 0;
|
|
104
|
+
return {
|
|
105
|
+
id: track.id,
|
|
106
|
+
name: track.name,
|
|
107
|
+
type: track.type,
|
|
108
|
+
volume: rawVolumeToDb(track.volume),
|
|
109
|
+
panning: rawPanToHuman(track.panning),
|
|
110
|
+
muted: track.mute,
|
|
111
|
+
soloed: track.solo,
|
|
112
|
+
armed: track.arm ?? false,
|
|
113
|
+
monitoring: track.monitoring ?? "off",
|
|
114
|
+
group: groupName,
|
|
115
|
+
outputRouting: track.outputRouting,
|
|
116
|
+
outputLevel: rawMeterToDb(meterLeft, meterRight),
|
|
117
|
+
sends,
|
|
118
|
+
devices,
|
|
119
|
+
clipNames: track.clipNames ?? [],
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// ============================================================
|
|
123
|
+
// Session assembly
|
|
124
|
+
// ============================================================
|
|
125
|
+
function generateSessionSummary(tracks, returnTracks, masterTrack) {
|
|
126
|
+
const parts = [];
|
|
127
|
+
const groupCount = tracks.filter((t) => t.type === "group").length;
|
|
128
|
+
parts.push(`${tracks.length} tracks${groupCount > 0 ? ` (${groupCount} groups)` : ""}, ${returnTracks.length} returns.`);
|
|
129
|
+
// Master output level
|
|
130
|
+
if (masterTrack.outputLevel !== "silent") {
|
|
131
|
+
parts.push(`Master output: ${masterTrack.outputLevel}.`);
|
|
132
|
+
}
|
|
133
|
+
// Note any devices on master
|
|
134
|
+
const masterDevices = masterTrack.devices.filter((d) => d.active);
|
|
135
|
+
if (masterDevices.length > 0) {
|
|
136
|
+
parts.push(`Master chain: ${masterDevices.map((d) => d.name).join(" → ")}.`);
|
|
137
|
+
}
|
|
138
|
+
// Collect observations across all tracks
|
|
139
|
+
for (const track of [...tracks, ...returnTracks, masterTrack]) {
|
|
140
|
+
for (const device of track.devices) {
|
|
141
|
+
for (const obs of device.observations) {
|
|
142
|
+
parts.push(`[${track.name}] ${obs}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return parts.join(" ");
|
|
147
|
+
}
|
|
148
|
+
export function assembleContext(cache) {
|
|
149
|
+
if (!cache.raw)
|
|
150
|
+
return null;
|
|
151
|
+
const { tempo, signature, tracks, returnTracks, masterTrack } = cache.raw;
|
|
152
|
+
const sampleRate = cache.raw.sampleRate ?? 44100;
|
|
153
|
+
// Build return track name map for send labels
|
|
154
|
+
const returnTrackNames = new Map();
|
|
155
|
+
for (const rt of returnTracks) {
|
|
156
|
+
returnTrackNames.set(rt.id, rt.name);
|
|
157
|
+
}
|
|
158
|
+
// Build track name map for group resolution
|
|
159
|
+
const trackNameMap = new Map();
|
|
160
|
+
for (const t of tracks) {
|
|
161
|
+
trackNameMap.set(t.id, t.name);
|
|
162
|
+
}
|
|
163
|
+
const semanticTracks = tracks.map((t) => assembleTrack(t, returnTrackNames, trackNameMap));
|
|
164
|
+
const semanticReturns = returnTracks.map((t) => assembleTrack(t, returnTrackNames, trackNameMap));
|
|
165
|
+
const semanticMaster = assembleTrack(masterTrack, returnTrackNames, trackNameMap);
|
|
166
|
+
const groupCount = tracks.filter((t) => t.isGroupTrack).length;
|
|
167
|
+
return {
|
|
168
|
+
tempo: `${tempo} BPM`,
|
|
169
|
+
signature: `${signature.numerator}/${signature.denominator}`,
|
|
170
|
+
sampleRate: `${sampleRate} Hz`,
|
|
171
|
+
trackCount: tracks.length,
|
|
172
|
+
groupCount,
|
|
173
|
+
returnTrackCount: returnTracks.length,
|
|
174
|
+
m4lConnected: cache.isConnected,
|
|
175
|
+
tracks: semanticTracks,
|
|
176
|
+
returnTracks: semanticReturns,
|
|
177
|
+
masterTrack: semanticMaster,
|
|
178
|
+
sessionSummary: generateSessionSummary(semanticTracks, semanticReturns, semanticMaster),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=context-assembler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-assembler.js","sourceRoot":"","sources":["../src/context-assembler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamics.d.ts","sourceRoot":"","sources":["../../src/heuristics/dynamics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AASnE,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,gBAAgB,EAAE,CAmDzE"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const TRANSIENT_KEYWORDS = ["kick", "snare", "808", "drum", "perc", "hat", "clap", "rim"];
|
|
2
|
+
function isTransientTrack(track) {
|
|
3
|
+
const lower = track.name.toLowerCase();
|
|
4
|
+
return TRANSIENT_KEYWORDS.some((kw) => lower.includes(kw));
|
|
5
|
+
}
|
|
6
|
+
export function checkDynamics(tracks) {
|
|
7
|
+
const findings = [];
|
|
8
|
+
for (const track of tracks) {
|
|
9
|
+
for (const device of track.devices) {
|
|
10
|
+
if (!device.active)
|
|
11
|
+
continue;
|
|
12
|
+
// Slow attack on transient-heavy tracks
|
|
13
|
+
if (device.name === "Compressor" &&
|
|
14
|
+
isTransientTrack(track)) {
|
|
15
|
+
const attack = device.parameters["Attack"];
|
|
16
|
+
if (attack) {
|
|
17
|
+
const ms = parseFloat(attack);
|
|
18
|
+
if (ms > 50) {
|
|
19
|
+
findings.push({
|
|
20
|
+
id: "slow_attack_on_transient_track",
|
|
21
|
+
severity: "warning",
|
|
22
|
+
track: track.name,
|
|
23
|
+
device: device.name,
|
|
24
|
+
message: `Compressor attack is ${attack} — transients passing through uncompressed on a percussive track`,
|
|
25
|
+
suggestion: `Try 10-20ms for tighter transient control`,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// High ratio without matching fast attack
|
|
31
|
+
if (device.name === "Compressor") {
|
|
32
|
+
const ratio = device.parameters["Ratio"];
|
|
33
|
+
const attack = device.parameters["Attack"];
|
|
34
|
+
if (ratio && attack) {
|
|
35
|
+
const ratioVal = parseFloat(ratio);
|
|
36
|
+
const attackMs = parseFloat(attack);
|
|
37
|
+
if (ratioVal > 10 && attackMs > 30) {
|
|
38
|
+
findings.push({
|
|
39
|
+
id: "high_ratio_slow_attack",
|
|
40
|
+
severity: "info",
|
|
41
|
+
track: track.name,
|
|
42
|
+
device: device.name,
|
|
43
|
+
message: `High ratio (${ratio}) with slow attack (${attack}) — not catching transients despite aggressive ratio`,
|
|
44
|
+
suggestion: `Either lower the ratio or speed up the attack`,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return findings;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=dynamics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamics.js","sourceRoot":"","sources":["../../src/heuristics/dynamics.ts"],"names":[],"mappings":"AAEA,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAE1F,SAAS,gBAAgB,CAAC,KAAoB;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IACvC,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAuB;IACnD,MAAM,QAAQ,GAAuB,EAAE,CAAC;IAExC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,CAAC,MAAM;gBAAE,SAAS;YAE7B,wCAAwC;YACxC,IACE,MAAM,CAAC,IAAI,KAAK,YAAY;gBAC5B,gBAAgB,CAAC,KAAK,CAAC,EACvB,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;gBAC3C,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;oBAC9B,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;wBACZ,QAAQ,CAAC,IAAI,CAAC;4BACZ,EAAE,EAAE,gCAAgC;4BACpC,QAAQ,EAAE,SAAS;4BACnB,KAAK,EAAE,KAAK,CAAC,IAAI;4BACjB,MAAM,EAAE,MAAM,CAAC,IAAI;4BACnB,OAAO,EAAE,wBAAwB,MAAM,kEAAkE;4BACzG,UAAU,EAAE,2CAA2C;yBACxD,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;YAED,0CAA0C;YAC1C,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBACzC,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;gBAC3C,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;oBACpB,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;oBACnC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;oBACpC,IAAI,QAAQ,GAAG,EAAE,IAAI,QAAQ,GAAG,EAAE,EAAE,CAAC;wBACnC,QAAQ,CAAC,IAAI,CAAC;4BACZ,EAAE,EAAE,wBAAwB;4BAC5B,QAAQ,EAAE,MAAM;4BAChB,KAAK,EAAE,KAAK,CAAC,IAAI;4BACjB,MAAM,EAAE,MAAM,CAAC,IAAI;4BACnB,OAAO,EAAE,eAAe,KAAK,uBAAuB,MAAM,sDAAsD;4BAChH,UAAU,EAAE,+CAA+C;yBAC5D,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frequency-buildup.d.ts","sourceRoot":"","sources":["../../src/heuristics/frequency-buildup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AASnE,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,aAAa,EAAE,GACtB,gBAAgB,EAAE,CAiEpB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const BASS_KEYWORDS = ["bass", "808", "sub", "kick", "low"];
|
|
2
|
+
function isBassTrack(track) {
|
|
3
|
+
const lower = track.name.toLowerCase();
|
|
4
|
+
return BASS_KEYWORDS.some((kw) => lower.includes(kw));
|
|
5
|
+
}
|
|
6
|
+
export function checkFrequencyBuildup(tracks) {
|
|
7
|
+
const findings = [];
|
|
8
|
+
// Check for non-bass tracks missing a high-pass
|
|
9
|
+
for (const track of tracks) {
|
|
10
|
+
if (isBassTrack(track) || track.type === "group")
|
|
11
|
+
continue;
|
|
12
|
+
const hasHighPass = track.devices.some((d) => {
|
|
13
|
+
if (d.name !== "EQ Eight" && d.name !== "Eq8")
|
|
14
|
+
return false;
|
|
15
|
+
// Check if band 1 is configured as a high-pass (heuristic: low frequency + active)
|
|
16
|
+
// This is a simplification — full implementation checks filter type parameter
|
|
17
|
+
return d.active;
|
|
18
|
+
});
|
|
19
|
+
// Only flag if track has devices at all (empty tracks aren't a concern)
|
|
20
|
+
if (!hasHighPass && track.devices.length > 0) {
|
|
21
|
+
findings.push({
|
|
22
|
+
id: "no_high_pass",
|
|
23
|
+
severity: "info",
|
|
24
|
+
track: track.name,
|
|
25
|
+
device: null,
|
|
26
|
+
message: `No EQ with high-pass detected — sub-bass accumulation possible`,
|
|
27
|
+
suggestion: `Consider adding a high-pass filter around 30-80Hz to clean up low-end`,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Check for multiple tracks boosting low-mids
|
|
32
|
+
// This requires EQ Eight gain analysis across tracks
|
|
33
|
+
let lowMidBoostCount = 0;
|
|
34
|
+
const lowMidBoostTracks = [];
|
|
35
|
+
for (const track of tracks) {
|
|
36
|
+
for (const device of track.devices) {
|
|
37
|
+
if (!device.active)
|
|
38
|
+
continue;
|
|
39
|
+
if (device.name !== "EQ Eight" && device.name !== "Eq8")
|
|
40
|
+
continue;
|
|
41
|
+
// Check bands in the 150-500Hz range for boosts
|
|
42
|
+
for (const [paramName, value] of Object.entries(device.parameters)) {
|
|
43
|
+
if (!paramName.includes("Gain"))
|
|
44
|
+
continue;
|
|
45
|
+
const db = parseFloat(value);
|
|
46
|
+
if (db > 3) {
|
|
47
|
+
// Check if the corresponding frequency is in the low-mid range
|
|
48
|
+
// This is a simplified check — full implementation correlates gain with frequency
|
|
49
|
+
lowMidBoostCount++;
|
|
50
|
+
if (!lowMidBoostTracks.includes(track.name)) {
|
|
51
|
+
lowMidBoostTracks.push(track.name);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (lowMidBoostTracks.length >= 3) {
|
|
58
|
+
findings.push({
|
|
59
|
+
id: "low_mid_buildup",
|
|
60
|
+
severity: "warning",
|
|
61
|
+
track: null,
|
|
62
|
+
device: null,
|
|
63
|
+
message: `${lowMidBoostTracks.length} tracks have EQ boosts in the low-mid range (${lowMidBoostTracks.join(", ")}) — likely causing muddiness`,
|
|
64
|
+
suggestion: `Review these tracks for competing boosts in the 150-500Hz range. Consider cutting on some tracks rather than boosting on others.`,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return findings;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=frequency-buildup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frequency-buildup.js","sourceRoot":"","sources":["../../src/heuristics/frequency-buildup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headroom.d.ts","sourceRoot":"","sources":["../../src/heuristics/headroom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEnE,wBAAgB,aAAa,CAC3B,MAAM,EAAE,aAAa,EAAE,EACvB,WAAW,EAAE,aAAa,GACzB,gBAAgB,EAAE,CA0DpB"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export function checkHeadroom(tracks, masterTrack) {
|
|
2
|
+
const findings = [];
|
|
3
|
+
// Master volume above 0dB
|
|
4
|
+
const masterDb = parseFloat(masterTrack.volume);
|
|
5
|
+
if (!isNaN(masterDb) && masterDb > 0) {
|
|
6
|
+
findings.push({
|
|
7
|
+
id: "master_above_unity",
|
|
8
|
+
severity: "issue",
|
|
9
|
+
track: "Master",
|
|
10
|
+
device: null,
|
|
11
|
+
message: `Master track volume is ${masterTrack.volume} — no headroom`,
|
|
12
|
+
suggestion: `Bring master fader to 0dB or below. Gain should come from individual tracks.`,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
// Count tracks near or above 0dB
|
|
16
|
+
const hotTracks = tracks.filter((t) => {
|
|
17
|
+
const db = parseFloat(t.volume);
|
|
18
|
+
return !isNaN(db) && db >= -1;
|
|
19
|
+
});
|
|
20
|
+
if (hotTracks.length > 5) {
|
|
21
|
+
findings.push({
|
|
22
|
+
id: "many_hot_tracks",
|
|
23
|
+
severity: "warning",
|
|
24
|
+
track: null,
|
|
25
|
+
device: null,
|
|
26
|
+
message: `${hotTracks.length} tracks are near or above 0dB — gain staging may need attention`,
|
|
27
|
+
suggestion: `Consider pulling track volumes down collectively and using makeup gain or bus volume to compensate.`,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
// Master limiter working hard (check for limiter on master with low threshold)
|
|
31
|
+
for (const device of masterTrack.devices) {
|
|
32
|
+
if (!device.active)
|
|
33
|
+
continue;
|
|
34
|
+
if (device.name.toLowerCase().includes("limiter") ||
|
|
35
|
+
device.name.toLowerCase().includes("glue compressor")) {
|
|
36
|
+
const threshold = device.parameters["Threshold"];
|
|
37
|
+
if (threshold) {
|
|
38
|
+
const threshDb = parseFloat(threshold);
|
|
39
|
+
if (!isNaN(threshDb) && threshDb < -6) {
|
|
40
|
+
findings.push({
|
|
41
|
+
id: "master_limiter_overloaded",
|
|
42
|
+
severity: "warning",
|
|
43
|
+
track: "Master",
|
|
44
|
+
device: device.name,
|
|
45
|
+
message: `Master ${device.name} threshold at ${threshold} — likely doing heavy gain reduction`,
|
|
46
|
+
suggestion: `Mix may be hitting the master too hot. Pull back track/bus levels to reduce limiter workload.`,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return findings;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=headroom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headroom.js","sourceRoot":"","sources":["../../src/heuristics/headroom.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,aAAa,CAC3B,MAAuB,EACvB,WAA0B;IAE1B,MAAM,QAAQ,GAAuB,EAAE,CAAC;IAExC,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,oBAAoB;YACxB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,0BAA0B,WAAW,CAAC,MAAM,gBAAgB;YACrE,UAAU,EAAE,8EAA8E;SAC3F,CAAC,CAAC;IACL,CAAC;IAED,iCAAiC;IACjC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACpC,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,iBAAiB;YACrB,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,GAAG,SAAS,CAAC,MAAM,iEAAiE;YAC7F,UAAU,EAAE,qGAAqG;SAClH,CAAC,CAAC;IACL,CAAC;IAED,+EAA+E;IAC/E,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,SAAS;QAC7B,IACE,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EACrD,CAAC;YACD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YACjD,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;gBACvC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC;oBACtC,QAAQ,CAAC,IAAI,CAAC;wBACZ,EAAE,EAAE,2BAA2B;wBAC/B,QAAQ,EAAE,SAAS;wBACnB,KAAK,EAAE,QAAQ;wBACf,MAAM,EAAE,MAAM,CAAC,IAAI;wBACnB,OAAO,EAAE,UAAU,MAAM,CAAC,IAAI,iBAAiB,SAAS,sCAAsC;wBAC9F,UAAU,EAAE,+FAA+F;qBAC5G,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/heuristics/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EAEf,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAMrB,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,gBAAgB,EAAE,CAmB1E"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { checkDynamics } from "./dynamics.js";
|
|
2
|
+
import { checkFrequencyBuildup } from "./frequency-buildup.js";
|
|
3
|
+
import { checkHeadroom } from "./headroom.js";
|
|
4
|
+
import { checkRouting } from "./routing.js";
|
|
5
|
+
export function runHeuristics(session) {
|
|
6
|
+
const allTracks = [
|
|
7
|
+
...session.tracks,
|
|
8
|
+
...session.returnTracks,
|
|
9
|
+
session.masterTrack,
|
|
10
|
+
];
|
|
11
|
+
const findings = [
|
|
12
|
+
...checkDynamics(session.tracks),
|
|
13
|
+
...checkFrequencyBuildup(session.tracks),
|
|
14
|
+
...checkHeadroom(session.tracks, session.masterTrack),
|
|
15
|
+
...checkRouting(session.tracks, session.returnTracks),
|
|
16
|
+
];
|
|
17
|
+
// Sort by severity: issue > warning > info
|
|
18
|
+
const severityOrder = { issue: 0, warning: 1, info: 2 };
|
|
19
|
+
findings.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
|
|
20
|
+
return findings;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/heuristics/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,UAAU,aAAa,CAAC,OAAwB;IACpD,MAAM,SAAS,GAAoB;QACjC,GAAG,OAAO,CAAC,MAAM;QACjB,GAAG,OAAO,CAAC,YAAY;QACvB,OAAO,CAAC,WAAW;KACpB,CAAC;IAEF,MAAM,QAAQ,GAAuB;QACnC,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC;QAChC,GAAG,qBAAqB,CAAC,OAAO,CAAC,MAAM,CAAC;QACxC,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC;QACrD,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC;KACtD,CAAC;IAEF,2CAA2C;IAC3C,MAAM,aAAa,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACxD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE/E,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/heuristics/routing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEnE,wBAAgB,YAAY,CAC1B,MAAM,EAAE,aAAa,EAAE,EACvB,YAAY,EAAE,aAAa,EAAE,GAC5B,gBAAgB,EAAE,CAoEpB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export function checkRouting(tracks, returnTracks) {
|
|
2
|
+
const findings = [];
|
|
3
|
+
// Check for many tracks routing directly to master with no bus structure
|
|
4
|
+
const directToMaster = tracks.filter((t) => t.type !== "group" &&
|
|
5
|
+
(t.outputRouting.toLowerCase() === "master" ||
|
|
6
|
+
t.outputRouting === ""));
|
|
7
|
+
if (directToMaster.length > 12 && tracks.some((t) => t.type !== "group")) {
|
|
8
|
+
const groupCount = tracks.filter((t) => t.type === "group").length;
|
|
9
|
+
if (groupCount === 0) {
|
|
10
|
+
findings.push({
|
|
11
|
+
id: "no_bus_structure",
|
|
12
|
+
severity: "info",
|
|
13
|
+
track: null,
|
|
14
|
+
device: null,
|
|
15
|
+
message: `${directToMaster.length} tracks routing directly to master with no group buses — session could benefit from bus structure`,
|
|
16
|
+
suggestion: `Consider creating group tracks (e.g., Drums Bus, Music Bus, Vocal Bus) for better mix management and processing.`,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
// Check for duplicate reverb settings across tracks
|
|
21
|
+
const reverbDevices = [];
|
|
22
|
+
for (const track of tracks) {
|
|
23
|
+
for (const device of track.devices) {
|
|
24
|
+
if (!device.active)
|
|
25
|
+
continue;
|
|
26
|
+
if (device.name.toLowerCase().includes("reverb") ||
|
|
27
|
+
device.name === "Reverb") {
|
|
28
|
+
// Create a rough fingerprint of the reverb settings
|
|
29
|
+
const fingerprint = Object.entries(device.parameters)
|
|
30
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
31
|
+
.map(([k, v]) => `${k}:${v}`)
|
|
32
|
+
.join("|");
|
|
33
|
+
reverbDevices.push({ track: track.name, params: fingerprint });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (reverbDevices.length >= 4) {
|
|
38
|
+
// Check if many have similar settings
|
|
39
|
+
const fingerprints = new Map();
|
|
40
|
+
for (const rd of reverbDevices) {
|
|
41
|
+
const existing = fingerprints.get(rd.params) ?? [];
|
|
42
|
+
existing.push(rd.track);
|
|
43
|
+
fingerprints.set(rd.params, existing);
|
|
44
|
+
}
|
|
45
|
+
for (const [, trackNames] of fingerprints) {
|
|
46
|
+
if (trackNames.length >= 3) {
|
|
47
|
+
findings.push({
|
|
48
|
+
id: "duplicate_reverbs",
|
|
49
|
+
severity: "info",
|
|
50
|
+
track: null,
|
|
51
|
+
device: null,
|
|
52
|
+
message: `${trackNames.length} tracks have similar reverb settings (${trackNames.join(", ")}) — consider consolidating to a return track`,
|
|
53
|
+
suggestion: `Move the reverb to a return track and use sends. This gives a more cohesive space and saves CPU.`,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return findings;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=routing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing.js","sourceRoot":"","sources":["../../src/heuristics/routing.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
import express from "express";
|
|
3
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4
|
+
import { WsBridge } from "./ws-bridge.js";
|
|
5
|
+
import { createMcpServer } from "./mcp-server.js";
|
|
6
|
+
const WS_PORT = parseInt(process.env.WS_PORT ?? "8765", 10);
|
|
7
|
+
const MCP_PORT = parseInt(process.env.MCP_PORT ?? "3000", 10);
|
|
8
|
+
// ============================================================
|
|
9
|
+
// Start WebSocket bridge
|
|
10
|
+
// ============================================================
|
|
11
|
+
const bridge = new WsBridge();
|
|
12
|
+
await bridge.start(WS_PORT);
|
|
13
|
+
bridge.on("connected", () => {
|
|
14
|
+
console.log("[main] M4L bridge connected — session data will flow");
|
|
15
|
+
});
|
|
16
|
+
bridge.on("disconnected", () => {
|
|
17
|
+
console.log("[main] M4L bridge disconnected");
|
|
18
|
+
});
|
|
19
|
+
bridge.on("session_updated", () => {
|
|
20
|
+
const trackCount = bridge.cache.raw?.tracks.length ?? 0;
|
|
21
|
+
console.log(`[main] Session updated — ${trackCount} tracks`);
|
|
22
|
+
});
|
|
23
|
+
// ============================================================
|
|
24
|
+
// Start MCP server with streamable HTTP transport
|
|
25
|
+
// ============================================================
|
|
26
|
+
const mcpServer = createMcpServer(bridge);
|
|
27
|
+
const app = express();
|
|
28
|
+
app.post("/mcp", async (req, res) => {
|
|
29
|
+
const transport = new StreamableHTTPServerTransport({
|
|
30
|
+
sessionIdGenerator: undefined, // stateless for now
|
|
31
|
+
});
|
|
32
|
+
await mcpServer.connect(transport);
|
|
33
|
+
await transport.handleRequest(req, res);
|
|
34
|
+
});
|
|
35
|
+
// Health check
|
|
36
|
+
app.get("/health", (_req, res) => {
|
|
37
|
+
res.json({
|
|
38
|
+
status: "ok",
|
|
39
|
+
m4lConnected: bridge.cache.isConnected,
|
|
40
|
+
lastUpdated: bridge.cache.lastUpdated,
|
|
41
|
+
trackCount: bridge.cache.raw?.tracks.length ?? 0,
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
app.listen(MCP_PORT, () => {
|
|
45
|
+
console.log(`[main] AbletonMCP server running`);
|
|
46
|
+
console.log(`[main] MCP endpoint: http://localhost:${MCP_PORT}/mcp`);
|
|
47
|
+
console.log(`[main] WebSocket bridge: ws://localhost:${WS_PORT}`);
|
|
48
|
+
console.log(`[main] Health check: http://localhost:${MCP_PORT}/health`);
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAC5D,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAE9D,+DAA+D;AAC/D,yBAAyB;AACzB,+DAA+D;AAE/D,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;AAC9B,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAE5B,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;IAC1B,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;IAC7B,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAChC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,4BAA4B,UAAU,SAAS,CAAC,CAAC;AAC/D,CAAC,CAAC,CAAC;AAEH,+DAA+D;AAC/D,kDAAkD;AAClD,+DAA+D;AAE/D,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;AAC1C,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AAEtB,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAClC,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC;QAClD,kBAAkB,EAAE,SAAS,EAAE,oBAAoB;KACpD,CAAC,CAAC;IACH,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH,eAAe;AACf,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IAC/B,GAAG,CAAC,IAAI,CAAC;QACP,MAAM,EAAE,IAAI;QACZ,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW;QACtC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW;QACrC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC;KACjD,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,2CAA2C,QAAQ,MAAM,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,6CAA6C,OAAO,EAAE,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,2CAA2C,QAAQ,SAAS,CAAC,CAAC;AAC5E,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AA+C/C,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CA2e3D"}
|