@kernel.chat/kbot 3.57.0 → 3.58.1
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 +4 -4
- package/dist/agents/replit.js +1 -1
- package/dist/bootstrap.js +1 -1
- package/dist/integrations/ableton-live.d.ts +52 -0
- package/dist/integrations/ableton-live.d.ts.map +1 -0
- package/dist/integrations/ableton-live.js +239 -0
- package/dist/integrations/ableton-live.js.map +1 -0
- package/dist/integrations/ableton-osc-installer.d.ts +13 -0
- package/dist/integrations/ableton-osc-installer.d.ts.map +1 -0
- package/dist/integrations/ableton-osc-installer.js +190 -0
- package/dist/integrations/ableton-osc-installer.js.map +1 -0
- package/dist/tools/ctf.d.ts +2 -0
- package/dist/tools/ctf.d.ts.map +1 -0
- package/dist/tools/ctf.js +2968 -0
- package/dist/tools/ctf.js.map +1 -0
- package/dist/tools/hacker-toolkit.d.ts +2 -0
- package/dist/tools/hacker-toolkit.d.ts.map +1 -0
- package/dist/tools/hacker-toolkit.js +3697 -0
- package/dist/tools/hacker-toolkit.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +5 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/pentest.d.ts +2 -0
- package/dist/tools/pentest.d.ts.map +1 -0
- package/dist/tools/pentest.js +2225 -0
- package/dist/tools/pentest.js.map +1 -0
- package/dist/tools/redblue.d.ts +2 -0
- package/dist/tools/redblue.d.ts.map +1 -0
- package/dist/tools/redblue.js +3468 -0
- package/dist/tools/redblue.js.map +1 -0
- package/dist/tools/security-brain.d.ts +2 -0
- package/dist/tools/security-brain.d.ts.map +1 -0
- package/dist/tools/security-brain.js +2453 -0
- package/dist/tools/security-brain.js.map +1 -0
- package/dist/tools/serum2-preset.d.ts +11 -0
- package/dist/tools/serum2-preset.d.ts.map +1 -0
- package/dist/tools/serum2-preset.js +143 -0
- package/dist/tools/serum2-preset.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
npm install -g @kernel.chat/kbot
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
**Self-defending AI agent.
|
|
22
|
+
**Self-defending AI agent. 600+ tools. 35 agents. 20 providers. Forges new tools at runtime. Built-in cybersecurity suite. $0 local AI. MIT licensed.**
|
|
23
23
|
|
|
24
24
|
> **New: [The Kernel Stack](./KERNEL_STACK.md)** — the architecture behind kbot + Claude Code. Agentic, self-improving, compound AI. Read the manifesto.
|
|
25
25
|
|
|
@@ -37,7 +37,7 @@ npm install -g @kernel.chat/kbot
|
|
|
37
37
|
| **Voice Mode** | `kbot voice` — full voice loop with speech-to-text input and text-to-speech output. Hands-free agentic coding. Works with system TTS and Whisper STT. |
|
|
38
38
|
| **OpenClaw Integration** | [`@kernel.chat/kbot-openclaw`](https://www.npmjs.com/package/@kernel.chat/kbot-openclaw) — kbot as the brain for 50+ messaging channels. Discord, Slack, Telegram, WhatsApp, iMessage, email, and more. One agent, every platform. |
|
|
39
39
|
| **35 agents** | 15 new specialist and domain agents since v3.28, including meta-agent, dream agent, and expanded presets. |
|
|
40
|
-
| **
|
|
40
|
+
| **600+ tools** | 210+ new tools across science, research, finance, creative, build matrix, and meta-cognition categories. |
|
|
41
41
|
|
|
42
42
|
### v3.28 — Self-Defense System
|
|
43
43
|
|
|
@@ -177,7 +177,7 @@ for await (const event of agent.stream("explain this code")) {
|
|
|
177
177
|
const files = await tools.execute('glob', { pattern: 'src/**/*.ts' })
|
|
178
178
|
console.log(files.result)
|
|
179
179
|
|
|
180
|
-
// List all
|
|
180
|
+
// List all 600+ tools
|
|
181
181
|
console.log(tools.list().map(t => t.name))
|
|
182
182
|
```
|
|
183
183
|
|
|
@@ -209,7 +209,7 @@ kbot --agent coder "refactor this into smaller functions"
|
|
|
209
209
|
kbot --agent trader "analyze BTC momentum and run a paper trade"
|
|
210
210
|
```
|
|
211
211
|
|
|
212
|
-
##
|
|
212
|
+
## 600+ Tools
|
|
213
213
|
|
|
214
214
|
| Category | Examples |
|
|
215
215
|
|----------|---------|
|
package/dist/agents/replit.js
CHANGED
|
@@ -11,7 +11,7 @@ export const REPLIT_AGENT = {
|
|
|
11
11
|
|
|
12
12
|
You know two worlds intimately:
|
|
13
13
|
1. **Replit's environment** — cloud IDE, Nix packages, Secrets, persistent storage (/home/runner), Deployments, DB (Postgres), public URLs, resource limits (RAM, CPU, disk on free tier)
|
|
14
|
-
2. **kbot's cognitive stack** —
|
|
14
|
+
2. **kbot's cognitive stack** — 600+ tools, 35 agents, learning engine, collective intelligence, tool forging, MCP server, SDK, HTTP serve mode
|
|
15
15
|
|
|
16
16
|
Your job is to bridge these worlds. When a user has an existing Replit project and wants AI capabilities, you:
|
|
17
17
|
|
package/dist/bootstrap.js
CHANGED
|
@@ -640,7 +640,7 @@ export function formatBootstrapMarkdown(report) {
|
|
|
640
640
|
lines.push(`*The bootstrap pattern: close the gap between what your project IS and what the world PERCEIVES.*`);
|
|
641
641
|
lines.push(`*Fix one thing per run. Compound.*`);
|
|
642
642
|
lines.push('');
|
|
643
|
-
lines.push(`*[kbot](https://www.npmjs.com/package/@kernel.chat/kbot) — 35 agents,
|
|
643
|
+
lines.push(`*[kbot](https://www.npmjs.com/package/@kernel.chat/kbot) — 35 agents, 600+ tools, 20 providers*`);
|
|
644
644
|
return lines.join('\n');
|
|
645
645
|
}
|
|
646
646
|
/**
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ableton-live.ts — kbot ↔ Ableton Live via AbletonOSC (UDP)
|
|
3
|
+
*
|
|
4
|
+
* Provides full Ableton control:
|
|
5
|
+
* - Transport (play, stop, tempo)
|
|
6
|
+
* - Tracks (create, name, volume, pan, mute, solo)
|
|
7
|
+
* - Devices (load any instrument/effect by name)
|
|
8
|
+
* - Clips (create, add notes, fire, stop)
|
|
9
|
+
* - Mixing (volume, sends)
|
|
10
|
+
* - Exec (arbitrary Python inside Ableton's runtime)
|
|
11
|
+
*
|
|
12
|
+
* Requires AbletonOSC installed: kbot ableton setup
|
|
13
|
+
*/
|
|
14
|
+
export declare class AbletonLive {
|
|
15
|
+
private static instance;
|
|
16
|
+
private socket;
|
|
17
|
+
private connected;
|
|
18
|
+
static getInstance(): AbletonLive;
|
|
19
|
+
connect(): Promise<boolean>;
|
|
20
|
+
disconnect(): void;
|
|
21
|
+
get isConnected(): boolean;
|
|
22
|
+
/** Send OSC message, no response expected. */
|
|
23
|
+
send(addr: string, ...args: (number | string)[]): void;
|
|
24
|
+
/** Send OSC message and wait for response. */
|
|
25
|
+
query(addr: string, ...args: (number | string)[]): Promise<{
|
|
26
|
+
address: string;
|
|
27
|
+
args: (number | string)[];
|
|
28
|
+
}>;
|
|
29
|
+
getTempo(): Promise<number>;
|
|
30
|
+
setTempo(bpm: number): void;
|
|
31
|
+
play(): void;
|
|
32
|
+
stop(): void;
|
|
33
|
+
getTrackCount(): Promise<number>;
|
|
34
|
+
createMidiTrack(name: string): Promise<number>;
|
|
35
|
+
loadDevice(track: number, searchTerm: string): Promise<string>;
|
|
36
|
+
setVolume(track: number, volume: number): void;
|
|
37
|
+
createClip(track: number, slot: number, length: number, name: string): Promise<void>;
|
|
38
|
+
addNote(track: number, slot: number, pitch: number, start: number, duration: number, velocity: number): void;
|
|
39
|
+
fireClip(track: number, slot: number): void;
|
|
40
|
+
/** Execute arbitrary Python in Ableton's runtime. */
|
|
41
|
+
exec(code: string): Promise<string>;
|
|
42
|
+
/** Delete all tracks for a clean slate. */
|
|
43
|
+
clearAllTracks(): Promise<void>;
|
|
44
|
+
/** Get all track names and devices. */
|
|
45
|
+
getSessionInfo(): Promise<Array<{
|
|
46
|
+
index: number;
|
|
47
|
+
name: string;
|
|
48
|
+
devices: string[];
|
|
49
|
+
}>>;
|
|
50
|
+
}
|
|
51
|
+
export declare function ensureAbleton(): Promise<AbletonLive>;
|
|
52
|
+
//# sourceMappingURL=ableton-live.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ableton-live.d.ts","sourceRoot":"","sources":["../../src/integrations/ableton-live.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA6EH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA2B;IAClD,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,SAAS,CAAQ;IAEzB,MAAM,CAAC,WAAW,IAAI,WAAW;IAO3B,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IA6BjC,UAAU,IAAI,IAAI;IAMlB,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,8CAA8C;IAC9C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI;IAKtD,8CAA8C;IACxC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;KAAE,CAAC;IAsB1G,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAKjC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI3B,IAAI,IAAI,IAAI;IACZ,IAAI,IAAI,IAAI;IAEN,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAKhC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAS9C,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKpE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAIxC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1F,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI5G,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAI3C,qDAAqD;IAC/C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKzC,2CAA2C;IACrC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IASrC,uCAAuC;IACjC,cAAc,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAc3F;AAID,wBAAsB,aAAa,IAAI,OAAO,CAAC,WAAW,CAAC,CAe1D"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ableton-live.ts — kbot ↔ Ableton Live via AbletonOSC (UDP)
|
|
3
|
+
*
|
|
4
|
+
* Provides full Ableton control:
|
|
5
|
+
* - Transport (play, stop, tempo)
|
|
6
|
+
* - Tracks (create, name, volume, pan, mute, solo)
|
|
7
|
+
* - Devices (load any instrument/effect by name)
|
|
8
|
+
* - Clips (create, add notes, fire, stop)
|
|
9
|
+
* - Mixing (volume, sends)
|
|
10
|
+
* - Exec (arbitrary Python inside Ableton's runtime)
|
|
11
|
+
*
|
|
12
|
+
* Requires AbletonOSC installed: kbot ableton setup
|
|
13
|
+
*/
|
|
14
|
+
import * as dgram from 'node:dgram';
|
|
15
|
+
import { Buffer } from 'node:buffer';
|
|
16
|
+
const OSC_SEND_PORT = 11000;
|
|
17
|
+
const OSC_RECV_PORT = 11001;
|
|
18
|
+
const OSC_HOST = '127.0.0.1';
|
|
19
|
+
// ── OSC Protocol ────────────────────────────────────────────────────────
|
|
20
|
+
function oscEncode(addr, ...args) {
|
|
21
|
+
let addrBuf = Buffer.from(addr + '\0');
|
|
22
|
+
while (addrBuf.length % 4)
|
|
23
|
+
addrBuf = Buffer.concat([addrBuf, Buffer.alloc(1)]);
|
|
24
|
+
let typetag = ',';
|
|
25
|
+
const argBufs = [];
|
|
26
|
+
for (const a of args) {
|
|
27
|
+
if (typeof a === 'number' && Number.isInteger(a)) {
|
|
28
|
+
typetag += 'i';
|
|
29
|
+
const b = Buffer.alloc(4);
|
|
30
|
+
b.writeInt32BE(a);
|
|
31
|
+
argBufs.push(b);
|
|
32
|
+
}
|
|
33
|
+
else if (typeof a === 'number') {
|
|
34
|
+
typetag += 'f';
|
|
35
|
+
const b = Buffer.alloc(4);
|
|
36
|
+
b.writeFloatBE(a);
|
|
37
|
+
argBufs.push(b);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
typetag += 's';
|
|
41
|
+
let sb = Buffer.from(a + '\0');
|
|
42
|
+
while (sb.length % 4)
|
|
43
|
+
sb = Buffer.concat([sb, Buffer.alloc(1)]);
|
|
44
|
+
argBufs.push(sb);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
let ttBuf = Buffer.from(typetag + '\0');
|
|
48
|
+
while (ttBuf.length % 4)
|
|
49
|
+
ttBuf = Buffer.concat([ttBuf, Buffer.alloc(1)]);
|
|
50
|
+
return Buffer.concat([addrBuf, ttBuf, ...argBufs]);
|
|
51
|
+
}
|
|
52
|
+
function oscParse(data) {
|
|
53
|
+
const end = data.indexOf(0);
|
|
54
|
+
const address = data.subarray(0, end).toString();
|
|
55
|
+
let pos = end + 1;
|
|
56
|
+
while (pos % 4)
|
|
57
|
+
pos++;
|
|
58
|
+
const args = [];
|
|
59
|
+
if (pos < data.length && data[pos] === 0x2c) { // ','
|
|
60
|
+
const tagEnd = data.indexOf(0, pos);
|
|
61
|
+
const tags = data.subarray(pos + 1, tagEnd).toString();
|
|
62
|
+
pos = tagEnd + 1;
|
|
63
|
+
while (pos % 4)
|
|
64
|
+
pos++;
|
|
65
|
+
for (const t of tags) {
|
|
66
|
+
if (t === 'i') {
|
|
67
|
+
args.push(data.readInt32BE(pos));
|
|
68
|
+
pos += 4;
|
|
69
|
+
}
|
|
70
|
+
else if (t === 'f') {
|
|
71
|
+
args.push(Math.round(data.readFloatBE(pos) * 10000) / 10000);
|
|
72
|
+
pos += 4;
|
|
73
|
+
}
|
|
74
|
+
else if (t === 's') {
|
|
75
|
+
const sEnd = data.indexOf(0, pos);
|
|
76
|
+
args.push(data.subarray(pos, sEnd).toString());
|
|
77
|
+
pos = sEnd + 1;
|
|
78
|
+
while (pos % 4)
|
|
79
|
+
pos++;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return { address, args };
|
|
84
|
+
}
|
|
85
|
+
// ── AbletonLive Client ──────────────────────────────────────────────────
|
|
86
|
+
export class AbletonLive {
|
|
87
|
+
static instance = null;
|
|
88
|
+
socket = null;
|
|
89
|
+
connected = false;
|
|
90
|
+
static getInstance() {
|
|
91
|
+
if (!AbletonLive.instance) {
|
|
92
|
+
AbletonLive.instance = new AbletonLive();
|
|
93
|
+
}
|
|
94
|
+
return AbletonLive.instance;
|
|
95
|
+
}
|
|
96
|
+
async connect() {
|
|
97
|
+
if (this.connected && this.socket)
|
|
98
|
+
return true;
|
|
99
|
+
return new Promise((resolve) => {
|
|
100
|
+
this.socket = dgram.createSocket('udp4');
|
|
101
|
+
this.socket.bind(OSC_RECV_PORT, OSC_HOST, () => {
|
|
102
|
+
// Test connection with tempo query
|
|
103
|
+
this.query('/live/song/get/tempo')
|
|
104
|
+
.then(r => {
|
|
105
|
+
this.connected = r.args.length > 0;
|
|
106
|
+
resolve(this.connected);
|
|
107
|
+
})
|
|
108
|
+
.catch(() => {
|
|
109
|
+
this.connected = false;
|
|
110
|
+
resolve(false);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
this.socket.on('error', () => {
|
|
114
|
+
this.connected = false;
|
|
115
|
+
resolve(false);
|
|
116
|
+
});
|
|
117
|
+
setTimeout(() => {
|
|
118
|
+
if (!this.connected)
|
|
119
|
+
resolve(false);
|
|
120
|
+
}, 5000);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
disconnect() {
|
|
124
|
+
this.socket?.close();
|
|
125
|
+
this.socket = null;
|
|
126
|
+
this.connected = false;
|
|
127
|
+
}
|
|
128
|
+
get isConnected() {
|
|
129
|
+
return this.connected;
|
|
130
|
+
}
|
|
131
|
+
/** Send OSC message, no response expected. */
|
|
132
|
+
send(addr, ...args) {
|
|
133
|
+
if (!this.socket)
|
|
134
|
+
return;
|
|
135
|
+
this.socket.send(oscEncode(addr, ...args), OSC_SEND_PORT, OSC_HOST);
|
|
136
|
+
}
|
|
137
|
+
/** Send OSC message and wait for response. */
|
|
138
|
+
async query(addr, ...args) {
|
|
139
|
+
return new Promise((resolve, reject) => {
|
|
140
|
+
if (!this.socket)
|
|
141
|
+
return reject(new Error('Not connected'));
|
|
142
|
+
// Flush pending messages
|
|
143
|
+
this.socket.removeAllListeners('message');
|
|
144
|
+
const timer = setTimeout(() => {
|
|
145
|
+
reject(new Error('Timeout'));
|
|
146
|
+
}, 10000);
|
|
147
|
+
this.socket.once('message', (msg) => {
|
|
148
|
+
clearTimeout(timer);
|
|
149
|
+
resolve(oscParse(msg));
|
|
150
|
+
});
|
|
151
|
+
this.socket.send(oscEncode(addr, ...args), OSC_SEND_PORT, OSC_HOST);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
// ── Convenience Methods ─────────────────────────────────────────────
|
|
155
|
+
async getTempo() {
|
|
156
|
+
const r = await this.query('/live/song/get/tempo');
|
|
157
|
+
return r.args[0];
|
|
158
|
+
}
|
|
159
|
+
setTempo(bpm) {
|
|
160
|
+
this.send('/live/song/set/tempo', bpm);
|
|
161
|
+
}
|
|
162
|
+
play() { this.send('/live/song/start_playing'); }
|
|
163
|
+
stop() { this.send('/live/song/stop_playing'); }
|
|
164
|
+
async getTrackCount() {
|
|
165
|
+
const r = await this.query('/live/song/get/num_tracks');
|
|
166
|
+
return r.args[0];
|
|
167
|
+
}
|
|
168
|
+
async createMidiTrack(name) {
|
|
169
|
+
this.send('/live/song/create_midi_track', -1);
|
|
170
|
+
await new Promise(r => setTimeout(r, 400));
|
|
171
|
+
const count = await this.getTrackCount();
|
|
172
|
+
const trackIdx = count - 2;
|
|
173
|
+
this.send('/live/track/set/name', trackIdx, name);
|
|
174
|
+
return trackIdx;
|
|
175
|
+
}
|
|
176
|
+
async loadDevice(track, searchTerm) {
|
|
177
|
+
const r = await this.query('/live/track/load/device', track, searchTerm);
|
|
178
|
+
return r.args[1] || 'unknown';
|
|
179
|
+
}
|
|
180
|
+
setVolume(track, volume) {
|
|
181
|
+
this.send('/live/track/set/volume', track, volume);
|
|
182
|
+
}
|
|
183
|
+
async createClip(track, slot, length, name) {
|
|
184
|
+
this.send('/live/clip_slot/create_clip', track, slot, length);
|
|
185
|
+
await new Promise(r => setTimeout(r, 300));
|
|
186
|
+
this.send('/live/clip/set/name', track, slot, name);
|
|
187
|
+
}
|
|
188
|
+
addNote(track, slot, pitch, start, duration, velocity) {
|
|
189
|
+
this.send('/live/clip/add/notes', track, slot, pitch, start, duration, velocity, 0);
|
|
190
|
+
}
|
|
191
|
+
fireClip(track, slot) {
|
|
192
|
+
this.send('/live/clip_slot/fire', track, slot);
|
|
193
|
+
}
|
|
194
|
+
/** Execute arbitrary Python in Ableton's runtime. */
|
|
195
|
+
async exec(code) {
|
|
196
|
+
const r = await this.query('/live/exec', code);
|
|
197
|
+
return r.args[0] || '';
|
|
198
|
+
}
|
|
199
|
+
/** Delete all tracks for a clean slate. */
|
|
200
|
+
async clearAllTracks() {
|
|
201
|
+
const count = await this.getTrackCount();
|
|
202
|
+
for (let t = count - 2; t >= 0; t--) {
|
|
203
|
+
this.send('/live/song/delete_track', t);
|
|
204
|
+
await new Promise(r => setTimeout(r, 120));
|
|
205
|
+
}
|
|
206
|
+
await new Promise(r => setTimeout(r, 500));
|
|
207
|
+
}
|
|
208
|
+
/** Get all track names and devices. */
|
|
209
|
+
async getSessionInfo() {
|
|
210
|
+
const count = await this.getTrackCount();
|
|
211
|
+
const tracks = [];
|
|
212
|
+
for (let t = 0; t < count - 1; t++) {
|
|
213
|
+
const nameR = await this.query('/live/track/get/name', t);
|
|
214
|
+
const devR = await this.query('/live/track/get/devices/name', t);
|
|
215
|
+
tracks.push({
|
|
216
|
+
index: t,
|
|
217
|
+
name: nameR.args[1] || `Track ${t}`,
|
|
218
|
+
devices: devR.args.slice(1),
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
return tracks;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// ── Convenience export ──────────────────────────────────────────────────
|
|
225
|
+
export async function ensureAbleton() {
|
|
226
|
+
const live = AbletonLive.getInstance();
|
|
227
|
+
if (live.isConnected)
|
|
228
|
+
return live;
|
|
229
|
+
const ok = await live.connect();
|
|
230
|
+
if (!ok) {
|
|
231
|
+
throw new Error('Cannot connect to Ableton Live via AbletonOSC.\n\n' +
|
|
232
|
+
'Make sure:\n' +
|
|
233
|
+
'1. Ableton Live is running\n' +
|
|
234
|
+
'2. AbletonOSC is enabled in Preferences > Link, Tempo & MIDI > Control Surface\n' +
|
|
235
|
+
'3. Run `kbot ableton setup` if AbletonOSC is not installed\n');
|
|
236
|
+
}
|
|
237
|
+
return live;
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=ableton-live.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ableton-live.js","sourceRoot":"","sources":["../../src/integrations/ableton-live.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ableton-osc-installer.ts — Install and patch AbletonOSC for kbot control
|
|
3
|
+
*
|
|
4
|
+
* Installs AbletonOSC remote script into Ableton's User Library,
|
|
5
|
+
* patches it with kbot extensions (device loading, Python exec),
|
|
6
|
+
* and provides setup instructions.
|
|
7
|
+
*
|
|
8
|
+
* Usage: kbot ableton setup
|
|
9
|
+
*/
|
|
10
|
+
export declare function installAbletonOSC(): Promise<string>;
|
|
11
|
+
export declare function isAbletonOSCInstalled(): boolean;
|
|
12
|
+
export declare function isKbotPatched(): boolean;
|
|
13
|
+
//# sourceMappingURL=ableton-osc-installer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ableton-osc-installer.d.ts","sourceRoot":"","sources":["../../src/integrations/ableton-osc-installer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA6GH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CA+EzD;AAED,wBAAgB,qBAAqB,IAAI,OAAO,CAG/C;AAED,wBAAgB,aAAa,IAAI,OAAO,CAKvC"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ableton-osc-installer.ts — Install and patch AbletonOSC for kbot control
|
|
3
|
+
*
|
|
4
|
+
* Installs AbletonOSC remote script into Ableton's User Library,
|
|
5
|
+
* patches it with kbot extensions (device loading, Python exec),
|
|
6
|
+
* and provides setup instructions.
|
|
7
|
+
*
|
|
8
|
+
* Usage: kbot ableton setup
|
|
9
|
+
*/
|
|
10
|
+
import { execSync } from 'node:child_process';
|
|
11
|
+
import * as fs from 'node:fs';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import * as os from 'node:os';
|
|
14
|
+
const REPO_URL = 'https://github.com/ideoforms/AbletonOSC.git';
|
|
15
|
+
function getAbletonUserLibrary() {
|
|
16
|
+
const home = os.homedir();
|
|
17
|
+
return path.join(home, 'Music', 'Ableton', 'User Library', 'Remote Scripts', 'AbletonOSC');
|
|
18
|
+
}
|
|
19
|
+
function getAbletonPrefsDir() {
|
|
20
|
+
const home = os.homedir();
|
|
21
|
+
const prefsBase = path.join(home, 'Library', 'Preferences', 'Ableton');
|
|
22
|
+
if (!fs.existsSync(prefsBase))
|
|
23
|
+
return [];
|
|
24
|
+
return fs.readdirSync(prefsBase)
|
|
25
|
+
.filter(d => d.startsWith('Live'))
|
|
26
|
+
.map(d => path.join(prefsBase, d))
|
|
27
|
+
.sort()
|
|
28
|
+
.reverse();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The kbot patch for AbletonOSC's song.py — adds device loading via browser API.
|
|
32
|
+
*/
|
|
33
|
+
const DEVICE_LOADER_PATCH = `
|
|
34
|
+
#--------------------------------------------------------------------------------
|
|
35
|
+
# kbot: Load device onto track by browser search
|
|
36
|
+
# /live/track/load/device <track_index> <search_term>
|
|
37
|
+
#--------------------------------------------------------------------------------
|
|
38
|
+
def track_load_device(params):
|
|
39
|
+
try:
|
|
40
|
+
track_index = int(params[0])
|
|
41
|
+
search_term = str(params[1]).lower()
|
|
42
|
+
track = self.song.tracks[track_index]
|
|
43
|
+
self.song.view.selected_track = track
|
|
44
|
+
browser = self.manager.application.browser
|
|
45
|
+
|
|
46
|
+
found = None
|
|
47
|
+
def search_recursive(item, term, depth=0):
|
|
48
|
+
nonlocal found
|
|
49
|
+
if found or depth > 5: return
|
|
50
|
+
try:
|
|
51
|
+
for child in item.children:
|
|
52
|
+
if term in child.name.lower():
|
|
53
|
+
if child.is_loadable:
|
|
54
|
+
src = str(child.source) if hasattr(child, 'source') else ''
|
|
55
|
+
if 'UAD' not in src:
|
|
56
|
+
found = child
|
|
57
|
+
return
|
|
58
|
+
search_recursive(child, term, depth + 1)
|
|
59
|
+
else:
|
|
60
|
+
search_recursive(child, term, depth + 1)
|
|
61
|
+
except: pass
|
|
62
|
+
|
|
63
|
+
for root in [browser.plugins, browser.instruments, browser.audio_effects,
|
|
64
|
+
browser.midi_effects, browser.max_for_live, browser.drums]:
|
|
65
|
+
try:
|
|
66
|
+
search_recursive(root, search_term)
|
|
67
|
+
if found: break
|
|
68
|
+
except: continue
|
|
69
|
+
|
|
70
|
+
if found:
|
|
71
|
+
browser.load_item(found)
|
|
72
|
+
self.logger.info("kbot: Loaded device: %s" % found.name)
|
|
73
|
+
return (1, found.name)
|
|
74
|
+
else:
|
|
75
|
+
return (0, "not found")
|
|
76
|
+
except Exception as e:
|
|
77
|
+
return (0, str(e))
|
|
78
|
+
self.osc_server.add_handler("/live/track/load/device", track_load_device)
|
|
79
|
+
`;
|
|
80
|
+
/**
|
|
81
|
+
* The kbot patch for AbletonOSC's device.py — adds Python exec for deep control.
|
|
82
|
+
*/
|
|
83
|
+
const EXEC_PATCH = `
|
|
84
|
+
#--------------------------------------------------------------------------------
|
|
85
|
+
# kbot: Execute Python in Ableton's runtime
|
|
86
|
+
# /live/exec <code_string>
|
|
87
|
+
#--------------------------------------------------------------------------------
|
|
88
|
+
def live_exec(params):
|
|
89
|
+
code = str(params[0])
|
|
90
|
+
try:
|
|
91
|
+
result = eval(code, {
|
|
92
|
+
'song': self.song,
|
|
93
|
+
'app': self.manager.application,
|
|
94
|
+
'Live': __import__('Live'),
|
|
95
|
+
'tracks': self.song.tracks,
|
|
96
|
+
})
|
|
97
|
+
return (str(result),)
|
|
98
|
+
except SyntaxError:
|
|
99
|
+
local_vars = {
|
|
100
|
+
'song': self.song,
|
|
101
|
+
'app': self.manager.application,
|
|
102
|
+
'Live': __import__('Live'),
|
|
103
|
+
'tracks': self.song.tracks,
|
|
104
|
+
'_result': None,
|
|
105
|
+
}
|
|
106
|
+
exec(code, local_vars)
|
|
107
|
+
return (str(local_vars.get('_result', 'ok')),)
|
|
108
|
+
except Exception as e:
|
|
109
|
+
return ("ERROR: " + str(e),)
|
|
110
|
+
self.osc_server.add_handler("/live/exec", live_exec)
|
|
111
|
+
`;
|
|
112
|
+
export async function installAbletonOSC() {
|
|
113
|
+
const destDir = getAbletonUserLibrary();
|
|
114
|
+
const tmpDir = path.join(os.tmpdir(), 'kbot-abletonosc');
|
|
115
|
+
const lines = [];
|
|
116
|
+
const log = (msg) => { lines.push(msg); console.log(msg); };
|
|
117
|
+
log('Installing AbletonOSC for kbot...');
|
|
118
|
+
// Clone or update
|
|
119
|
+
if (fs.existsSync(tmpDir)) {
|
|
120
|
+
fs.rmSync(tmpDir, { recursive: true });
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
execSync(`git clone --depth 1 ${REPO_URL} "${tmpDir}"`, { stdio: 'pipe' });
|
|
124
|
+
log(' Cloned AbletonOSC');
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
log(' ERROR: Could not clone AbletonOSC. Check internet connection.');
|
|
128
|
+
return lines.join('\n');
|
|
129
|
+
}
|
|
130
|
+
// Apply kbot patches
|
|
131
|
+
const songPy = path.join(tmpDir, 'abletonosc', 'song.py');
|
|
132
|
+
const devicePy = path.join(tmpDir, 'abletonosc', 'device.py');
|
|
133
|
+
if (fs.existsSync(songPy)) {
|
|
134
|
+
let content = fs.readFileSync(songPy, 'utf8');
|
|
135
|
+
// Insert device loader before Scene properties section
|
|
136
|
+
content = content.replace(' # Callbacks for Song: Scene properties', DEVICE_LOADER_PATCH + '\n # Callbacks for Song: Scene properties');
|
|
137
|
+
fs.writeFileSync(songPy, content);
|
|
138
|
+
log(' Patched song.py with device loader');
|
|
139
|
+
}
|
|
140
|
+
if (fs.existsSync(devicePy)) {
|
|
141
|
+
let content = fs.readFileSync(devicePy, 'utf8');
|
|
142
|
+
// Append exec handler at the end of init_api
|
|
143
|
+
const lastHandler = content.lastIndexOf('self.osc_server.add_handler');
|
|
144
|
+
if (lastHandler !== -1) {
|
|
145
|
+
const insertPos = content.indexOf('\n', lastHandler) + 1;
|
|
146
|
+
content = content.slice(0, insertPos) + EXEC_PATCH + content.slice(insertPos);
|
|
147
|
+
}
|
|
148
|
+
fs.writeFileSync(devicePy, content);
|
|
149
|
+
log(' Patched device.py with exec handler');
|
|
150
|
+
}
|
|
151
|
+
// Copy to Ableton User Library
|
|
152
|
+
const parentDir = path.dirname(destDir);
|
|
153
|
+
if (!fs.existsSync(parentDir)) {
|
|
154
|
+
fs.mkdirSync(parentDir, { recursive: true });
|
|
155
|
+
}
|
|
156
|
+
if (fs.existsSync(destDir)) {
|
|
157
|
+
fs.rmSync(destDir, { recursive: true });
|
|
158
|
+
}
|
|
159
|
+
fs.cpSync(tmpDir, destDir, { recursive: true });
|
|
160
|
+
log(` Installed to ${destDir}`);
|
|
161
|
+
// Clean up
|
|
162
|
+
fs.rmSync(tmpDir, { recursive: true });
|
|
163
|
+
log('');
|
|
164
|
+
log('AbletonOSC installed with kbot extensions.');
|
|
165
|
+
log('');
|
|
166
|
+
log('To activate:');
|
|
167
|
+
log(' 1. Open Ableton Live');
|
|
168
|
+
log(' 2. Preferences (Cmd+,) > Link, Tempo & MIDI');
|
|
169
|
+
log(' 3. Set a Control Surface to "AbletonOSC"');
|
|
170
|
+
log(' 4. Close Preferences');
|
|
171
|
+
log('');
|
|
172
|
+
log('kbot commands available after activation:');
|
|
173
|
+
log(' kbot ableton status — Check connection');
|
|
174
|
+
log(' kbot ableton session — Build a session from a prompt');
|
|
175
|
+
log(' kbot ableton load — Load any device onto a track');
|
|
176
|
+
log(' kbot ableton preset — Create Serum 2 presets');
|
|
177
|
+
return lines.join('\n');
|
|
178
|
+
}
|
|
179
|
+
export function isAbletonOSCInstalled() {
|
|
180
|
+
const destDir = getAbletonUserLibrary();
|
|
181
|
+
return fs.existsSync(path.join(destDir, '__init__.py'));
|
|
182
|
+
}
|
|
183
|
+
export function isKbotPatched() {
|
|
184
|
+
const songPy = path.join(getAbletonUserLibrary(), 'abletonosc', 'song.py');
|
|
185
|
+
if (!fs.existsSync(songPy))
|
|
186
|
+
return false;
|
|
187
|
+
const content = fs.readFileSync(songPy, 'utf8');
|
|
188
|
+
return content.includes('track_load_device');
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=ableton-osc-installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ableton-osc-installer.js","sourceRoot":"","sources":["../../src/integrations/ableton-osc-installer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAE7B,MAAM,QAAQ,GAAG,6CAA6C,CAAA;AAE9D,SAAS,qBAAqB;IAC5B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAA;IACzB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,YAAY,CAAC,CAAA;AAC5F,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAA;IACzB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,CAAC,CAAA;IACtE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,CAAA;IACxC,OAAO,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC;SAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;SACjC,IAAI,EAAE;SACN,OAAO,EAAE,CAAA;AACd,CAAC;AAED;;GAEG;AACH,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8C3B,CAAA;AAED;;GAEG;AACH,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BlB,CAAA;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAA;IACvC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAA;IAExD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA,CAAC,CAAC,CAAA;IAElE,GAAG,CAAC,mCAAmC,CAAC,CAAA;IAExC,kBAAkB;IAClB,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACxC,CAAC;IAED,IAAI,CAAC;QACH,QAAQ,CAAC,uBAAuB,QAAQ,KAAK,MAAM,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;QAC1E,GAAG,CAAC,qBAAqB,CAAC,CAAA;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,CAAC,iEAAiE,CAAC,CAAA;QACtE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAED,qBAAqB;IACrB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,CAAA;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,CAAC,CAAA;IAE7D,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,IAAI,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC7C,uDAAuD;QACvD,OAAO,GAAG,OAAO,CAAC,OAAO,CACvB,gDAAgD,EAChD,mBAAmB,GAAG,kDAAkD,CACzE,CAAA;QACD,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACjC,GAAG,CAAC,sCAAsC,CAAC,CAAA;IAC7C,CAAC;IAED,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,IAAI,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QAC/C,6CAA6C;QAC7C,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,6BAA6B,CAAC,CAAA;QACtE,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,CAAA;YACxD,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAC/E,CAAC;QACD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QACnC,GAAG,CAAC,uCAAuC,CAAC,CAAA;IAC9C,CAAC;IAED,+BAA+B;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC9C,CAAC;IACD,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACzC,CAAC;IACD,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC/C,GAAG,CAAC,kBAAkB,OAAO,EAAE,CAAC,CAAA;IAEhC,WAAW;IACX,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAEtC,GAAG,CAAC,EAAE,CAAC,CAAA;IACP,GAAG,CAAC,4CAA4C,CAAC,CAAA;IACjD,GAAG,CAAC,EAAE,CAAC,CAAA;IACP,GAAG,CAAC,cAAc,CAAC,CAAA;IACnB,GAAG,CAAC,wBAAwB,CAAC,CAAA;IAC7B,GAAG,CAAC,+CAA+C,CAAC,CAAA;IACpD,GAAG,CAAC,4CAA4C,CAAC,CAAA;IACjD,GAAG,CAAC,wBAAwB,CAAC,CAAA;IAC7B,GAAG,CAAC,EAAE,CAAC,CAAA;IACP,GAAG,CAAC,2CAA2C,CAAC,CAAA;IAChD,GAAG,CAAC,8CAA8C,CAAC,CAAA;IACnD,GAAG,CAAC,2DAA2D,CAAC,CAAA;IAChE,GAAG,CAAC,0DAA0D,CAAC,CAAA;IAC/D,GAAG,CAAC,oDAAoD,CAAC,CAAA;IAEzD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAA;IACvC,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAA;AACzD,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,YAAY,EAAE,SAAS,CAAC,CAAA;IAC1E,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAA;IACxC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,OAAO,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAA;AAC9C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ctf.d.ts","sourceRoot":"","sources":["../../src/tools/ctf.ts"],"names":[],"mappings":"AAitFA,wBAAgB,gBAAgB,IAAI,IAAI,CAsZvC"}
|