create-tunnlo 0.1.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.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env node
2
+ import { mkdir, writeFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { createInterface } from 'node:readline';
5
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
6
+ let rlClosed = false;
7
+ rl.on('close', () => { rlClosed = true; });
8
+ function ask(question) {
9
+ return new Promise((resolve) => {
10
+ if (rlClosed)
11
+ return resolve('');
12
+ rl.question(question, (a) => resolve(a.trim()));
13
+ rl.once('close', () => resolve(''));
14
+ });
15
+ }
16
+ async function choose(question, options) {
17
+ console.log(question);
18
+ options.forEach((opt, i) => console.log(` ${i + 1}) ${opt.label}`));
19
+ const answer = await ask(` Choice [1]: `);
20
+ const index = parseInt(answer || '1', 10) - 1;
21
+ return (index >= 0 && index < options.length) ? options[index].value : options[0].value;
22
+ }
23
+ // ── Config generators ──────────────────────────────────────────────────────
24
+ function stdinConfig(model) {
25
+ return `# Tunnlo Pipeline Configuration
26
+ # Docs: https://tunnlo.dev
27
+
28
+ sources:
29
+ - id: stdin-input
30
+ adapter: native/stdin
31
+ config: {}
32
+
33
+ # ─── Alternative: Wireshark / tshark ────────────────────────────────────────
34
+ # To monitor live network traffic instead, replace the source above with:
35
+ #
36
+ # Prerequisite: install tshark — https://www.wireshark.org/download.html
37
+ # macOS: brew install wireshark
38
+ # Ubuntu: sudo apt install tshark
39
+ #
40
+ # sources:
41
+ # - id: network-traffic
42
+ # adapter: native/tshark
43
+ # config:
44
+ # interface: en0 # find yours: ip link (Linux) or networksetup -listallnetworkservices (macOS)
45
+ # capture_filter: tcp # optional BPF filter, e.g. "tcp port 443"
46
+ # output_format: json
47
+ # ────────────────────────────────────────────────────────────────────────────
48
+
49
+ filters:
50
+ - type: rate-limiter
51
+ max_events_per_minute: 30
52
+
53
+ - type: dedup
54
+ window_seconds: 10
55
+ key_fields:
56
+ - payload.data
57
+
58
+ agent:
59
+ runtime: direct-llm
60
+ model: ${model}
61
+ system_prompt: |
62
+ You are a monitoring agent. Analyze incoming events and respond with
63
+ observations, potential issues, and recommended actions.
64
+
65
+ If you want to trigger a webhook action, include a JSON block like:
66
+ \`\`\`json:actions
67
+ [{"type": "webhook", "config": {}, "payload": {"message": "your alert"}}]
68
+ \`\`\`
69
+ token_budget:
70
+ max_per_hour: 50000
71
+ max_per_event: 4000
72
+
73
+ behavior:
74
+ on_llm_unreachable: drop_and_alert
75
+ `;
76
+ }
77
+ function tsharkConfig(model, iface, captureFilter) {
78
+ const filterLine = captureFilter ? ` capture_filter: "${captureFilter}"` : ` # capture_filter: tcp # optional BPF filter, e.g. "tcp port 443"`;
79
+ return `# Tunnlo Pipeline Configuration — Network Monitor
80
+ # Docs: https://tunnlo.dev
81
+ #
82
+ # Prerequisite: tshark must be installed.
83
+ # macOS: brew install wireshark
84
+ # Ubuntu: sudo apt install tshark
85
+ # Windows: install Wireshark from https://www.wireshark.org/download.html
86
+
87
+ sources:
88
+ - id: network-traffic
89
+ adapter: native/tshark
90
+ config:
91
+ interface: ${iface}
92
+ ${filterLine}
93
+ output_format: json
94
+
95
+ filters:
96
+ - type: dedup
97
+ window_seconds: 30
98
+ key_fields:
99
+ - payload.src_ip
100
+ - payload.dst_port
101
+
102
+ - type: rate-limiter
103
+ max_events_per_minute: 20
104
+
105
+ agent:
106
+ runtime: direct-llm
107
+ model: ${model}
108
+ system_prompt: |
109
+ You are a network security analyst monitoring live traffic.
110
+ For each packet event, assess:
111
+ 1. Is this normal traffic or potentially suspicious?
112
+ 2. What kind of activity does this represent?
113
+ 3. Should an alert be raised?
114
+
115
+ If you detect suspicious activity, trigger a webhook alert:
116
+ \`\`\`json:actions
117
+ [{"type": "webhook", "config": {}, "payload": {"severity": "high", "message": "description"}}]
118
+ \`\`\`
119
+ token_budget:
120
+ max_per_hour: 100000
121
+ max_per_event: 4000
122
+
123
+ behavior:
124
+ on_llm_unreachable: drop_and_alert
125
+ `;
126
+ }
127
+ function logConfig(model, logPath) {
128
+ return `# Tunnlo Pipeline Configuration — Log Monitor
129
+ # Docs: https://tunnlo.dev
130
+
131
+ sources:
132
+ - id: log-file
133
+ adapter: native/log-tailer
134
+ config:
135
+ path: ${logPath}
136
+ # poll_interval_ms: 500 # how often to check for new lines
137
+
138
+ filters:
139
+ - type: rate-limiter
140
+ max_events_per_minute: 30
141
+
142
+ - type: dedup
143
+ window_seconds: 10
144
+ key_fields:
145
+ - payload.data
146
+
147
+ agent:
148
+ runtime: direct-llm
149
+ model: ${model}
150
+ system_prompt: |
151
+ You are a log analysis agent. Monitor incoming log lines and identify
152
+ errors, warnings, anomalies, or patterns worth flagging.
153
+ token_budget:
154
+ max_per_hour: 50000
155
+ max_per_event: 4000
156
+
157
+ behavior:
158
+ on_llm_unreachable: drop_and_alert
159
+ `;
160
+ }
161
+ function envExample(model) {
162
+ if (model.startsWith('anthropic/'))
163
+ return 'ANTHROPIC_API_KEY=\n';
164
+ if (model.startsWith('openai/'))
165
+ return 'OPENAI_API_KEY=\n';
166
+ // ollama — no key needed
167
+ return '# Ollama runs locally — no API key required.\n# Make sure ollama is running: ollama serve\n';
168
+ }
169
+ function startInstructions(source, projectName, model) {
170
+ const lines = [
171
+ '',
172
+ `Done! To get started:`,
173
+ '',
174
+ ` cd ${projectName}`,
175
+ ` npm install`,
176
+ ];
177
+ if (!model.startsWith('ollama/')) {
178
+ lines.push(` cp .env.example .env # add your API key`);
179
+ }
180
+ if (source === 'tshark') {
181
+ lines.push('', ' # tshark must be installed:', ' # macOS: brew install wireshark', ' # Ubuntu: sudo apt install tshark');
182
+ }
183
+ lines.push(` npm start`, '');
184
+ return lines.join('\n');
185
+ }
186
+ // ── Main ───────────────────────────────────────────────────────────────────
187
+ async function main() {
188
+ const projectName = process.argv[2];
189
+ if (!projectName) {
190
+ console.log('Usage: npm create tunnlo <project-name>');
191
+ process.exit(1);
192
+ }
193
+ if (!/^[a-zA-Z0-9_-]+$/.test(projectName)) {
194
+ console.error('Error: project name must only contain letters, numbers, hyphens, and underscores.');
195
+ process.exit(1);
196
+ }
197
+ const projectDir = join(process.cwd(), projectName);
198
+ console.log(`\nCreating Tunnlo project: ${projectName}\n`);
199
+ // ── Prompts ──
200
+ const source = await choose('What data source will you use?', [
201
+ { label: 'Standard input (stdin) — pipe data in manually', value: 'stdin' },
202
+ { label: 'Wireshark / tshark — monitor live network traffic', value: 'tshark' },
203
+ { label: 'Log file — tail a log file on disk', value: 'log' },
204
+ ]);
205
+ let iface = 'en0';
206
+ let captureFilter = '';
207
+ let logPath = '/var/log/syslog';
208
+ if (source === 'tshark') {
209
+ iface = await ask(' Network interface (e.g. en0, eth0) [en0]: ') || 'en0';
210
+ captureFilter = await ask(' Capture filter — leave blank for all traffic (e.g. tcp, "tcp port 443") [none]: ');
211
+ }
212
+ else if (source === 'log') {
213
+ logPath = await ask(' Path to log file [/var/log/syslog]: ') || '/var/log/syslog';
214
+ }
215
+ console.log('');
216
+ const model = await choose('Which LLM will you use?', [
217
+ { label: 'Anthropic Claude (requires ANTHROPIC_API_KEY)', value: 'anthropic/claude-sonnet-4-5' },
218
+ { label: 'OpenAI GPT-4o (requires OPENAI_API_KEY)', value: 'openai/gpt-4o' },
219
+ { label: 'Ollama — local models, no API key needed', value: 'ollama/llama3.1:8b' },
220
+ ]);
221
+ rl.close();
222
+ // ── Generate config ──
223
+ let tunnloYaml;
224
+ if (source === 'tshark') {
225
+ tunnloYaml = tsharkConfig(model, iface, captureFilter);
226
+ }
227
+ else if (source === 'log') {
228
+ tunnloYaml = logConfig(model, logPath);
229
+ }
230
+ else {
231
+ tunnloYaml = stdinConfig(model);
232
+ }
233
+ // ── Scaffold files ──
234
+ await mkdir(projectDir, { recursive: true });
235
+ const pkg = {
236
+ name: projectName,
237
+ version: '0.1.0',
238
+ private: true,
239
+ type: 'module',
240
+ scripts: {
241
+ start: 'tunnlo start tunnlo.yaml',
242
+ validate: 'tunnlo validate tunnlo.yaml',
243
+ },
244
+ dependencies: {
245
+ '@tunnlo/cli': '^0.1.0',
246
+ '@tunnlo/core': '^0.1.0',
247
+ '@tunnlo/adapters': '^0.1.0',
248
+ '@tunnlo/filters': '^0.1.0',
249
+ '@tunnlo/bridge-llm': '^0.1.0',
250
+ '@tunnlo/actions': '^0.1.0',
251
+ },
252
+ };
253
+ await writeFile(join(projectDir, 'package.json'), JSON.stringify(pkg, null, 2));
254
+ await writeFile(join(projectDir, 'tunnlo.yaml'), tunnloYaml);
255
+ await writeFile(join(projectDir, '.gitignore'), 'node_modules/\n.env\n.env.*\n');
256
+ await writeFile(join(projectDir, '.env.example'), envExample(model));
257
+ console.log(startInstructions(source, projectName, model));
258
+ }
259
+ main().catch((err) => {
260
+ rl.close();
261
+ console.error('Error:', err.message);
262
+ process.exit(1);
263
+ });
264
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "create-tunnlo",
3
+ "version": "0.1.1",
4
+ "description": "Scaffolding tool for new Tunnlo projects",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "create-tunnlo": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc -b"
12
+ },
13
+ "files": ["dist", "templates"]
14
+ }
@@ -0,0 +1,53 @@
1
+ # Tunnlo Security Monitor Template
2
+ # Monitors network traffic via tshark and sends alerts to LLM
3
+
4
+ sources:
5
+ - id: wireshark-capture
6
+ adapter: native/tshark
7
+ config:
8
+ interface: eth0
9
+ capture_filter: "tcp port 80 or tcp port 443"
10
+ output_format: json
11
+
12
+ filters:
13
+ - type: content-filter
14
+ rules:
15
+ - field: payload.flags
16
+ match: "SYN"
17
+ - field: payload.dst_port
18
+ in: [22, 3389, 445]
19
+ mode: any
20
+
21
+ - type: dedup
22
+ window_seconds: 30
23
+ key_fields:
24
+ - payload.src_ip
25
+ - payload.dst_port
26
+
27
+ - type: rate-limiter
28
+ max_events_per_minute: 20
29
+
30
+ agent:
31
+ runtime: direct-llm
32
+ model: anthropic/claude-sonnet-4-5
33
+ system_prompt: |
34
+ You are a security monitoring agent analyzing network traffic events.
35
+
36
+ For each event, assess:
37
+ 1. Is this normal traffic or potentially suspicious?
38
+ 2. What kind of activity does this represent?
39
+ 3. Should an alert be raised?
40
+
41
+ If you detect suspicious activity, trigger a webhook alert:
42
+ ```json:actions
43
+ [{"type": "webhook", "config": {}, "payload": {"severity": "high", "message": "description"}}]
44
+ ```
45
+ token_budget:
46
+ max_per_hour: 100000
47
+ max_per_event: 4000
48
+ actions:
49
+ - type: webhook
50
+ url: "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
51
+
52
+ behavior:
53
+ on_llm_unreachable: drop_and_alert