@redaksjon/protokoll 1.0.2 → 1.0.7

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,562 @@
1
+ # Smart File Lookup
2
+
3
+ ## Overview
4
+
5
+ Protokoll's MCP tools now support **smart file lookup** for both transcripts and audio files, making them much easier to work with. Instead of requiring full absolute paths, you can now use:
6
+
7
+ - **Filenames**: `"meeting-notes.md"` or `"recording.m4a"`
8
+ - **Partial filenames**: `"2026-01-29"` or `"meeting"`
9
+ - **Absolute paths**: `/full/path/to/file.md` (still supported)
10
+
11
+ The system automatically searches the configured directories and finds the files you're looking for.
12
+
13
+ ## How It Works
14
+
15
+ ### 1. Automatic Directory Discovery
16
+
17
+ When you don't specify a directory, tools use the configured directories from your `.protokoll/config.yaml`:
18
+
19
+ ```yaml
20
+ inputDirectory: ~/recordings # For audio files
21
+ outputDirectory: ~/notes # For transcripts
22
+ processedDirectory: ~/processed # For processed audio
23
+ ```
24
+
25
+ This means you never have to remember or specify paths - the system knows where your files are.
26
+
27
+ ### 2. Intelligent Search
28
+
29
+ When you provide a filename or partial filename, the system:
30
+
31
+ 1. Checks if it's already an absolute path that exists
32
+ 2. If not, searches the output directory recursively
33
+ 3. Matches against filenames and content
34
+ 4. Returns the best match
35
+
36
+ ### 3. Disambiguation
37
+
38
+ If multiple transcripts match your query:
39
+ - **Exact filename match**: Returns that transcript
40
+ - **Multiple matches**: Lists all matches and asks you to be more specific
41
+
42
+ ## Affected Tools
43
+
44
+ ### Transcript Tools
45
+
46
+ All transcript tools now support smart lookup:
47
+
48
+ ### `protokoll_read_transcript`
49
+
50
+ **Before** (required absolute path):
51
+ ```json
52
+ {
53
+ "transcriptPath": "/Users/me/notes/2026/01/2026-01-29-1015-meeting-notes.md"
54
+ }
55
+ ```
56
+
57
+ **After** (filename or partial):
58
+ ```json
59
+ {
60
+ "transcriptPath": "meeting-notes.md"
61
+ }
62
+ ```
63
+
64
+ or
65
+
66
+ ```json
67
+ {
68
+ "transcriptPath": "2026-01-29"
69
+ }
70
+ ```
71
+
72
+ ### `protokoll_edit_transcript`
73
+
74
+ **Before**:
75
+ ```json
76
+ {
77
+ "transcriptPath": "/Users/me/notes/2026/01/2026-01-29-1015-meeting-notes.md",
78
+ "title": "Updated Meeting Notes"
79
+ }
80
+ ```
81
+
82
+ **After**:
83
+ ```json
84
+ {
85
+ "transcriptPath": "meeting-notes",
86
+ "title": "Updated Meeting Notes"
87
+ }
88
+ ```
89
+
90
+ ### `protokoll_combine_transcripts`
91
+
92
+ **Before**:
93
+ ```json
94
+ {
95
+ "transcriptPaths": [
96
+ "/Users/me/notes/2026/01/2026-01-29-1015-meeting-1.md",
97
+ "/Users/me/notes/2026/01/2026-01-29-1030-meeting-2.md"
98
+ ]
99
+ }
100
+ ```
101
+
102
+ **After**:
103
+ ```json
104
+ {
105
+ "transcriptPaths": ["meeting-1", "meeting-2"]
106
+ }
107
+ ```
108
+
109
+ or
110
+
111
+ ```json
112
+ {
113
+ "transcriptPaths": ["2026-01-29-1015", "2026-01-29-1030"]
114
+ }
115
+ ```
116
+
117
+ ### `protokoll_provide_feedback`
118
+
119
+ **Before**:
120
+ ```json
121
+ {
122
+ "transcriptPath": "/Users/me/notes/2026/01/2026-01-29-1015-meeting-notes.md",
123
+ "feedback": "Change 'John' to 'Jon'"
124
+ }
125
+ ```
126
+
127
+ **After**:
128
+ ```json
129
+ {
130
+ "transcriptPath": "meeting-notes",
131
+ "feedback": "Change 'John' to 'Jon'"
132
+ }
133
+ ```
134
+
135
+ ### `protokoll_list_transcripts`
136
+
137
+ Now **directory is optional**:
138
+
139
+ **Before**:
140
+ ```json
141
+ {
142
+ "directory": "/Users/me/notes"
143
+ }
144
+ ```
145
+
146
+ **After** (uses configured output directory):
147
+ ```json
148
+ {}
149
+ ```
150
+
151
+ or with search:
152
+
153
+ ```json
154
+ {
155
+ "search": "meeting"
156
+ }
157
+ ```
158
+
159
+ ### Audio Tools
160
+
161
+ Audio processing tools now support smart lookup:
162
+
163
+ ### `protokoll_process_audio`
164
+
165
+ **Before** (required absolute path):
166
+ ```json
167
+ {
168
+ "audioFile": "/Users/me/recordings/2026-01-29-meeting.m4a"
169
+ }
170
+ ```
171
+
172
+ **After** (filename or partial):
173
+ ```json
174
+ {
175
+ "audioFile": "meeting.m4a"
176
+ }
177
+ ```
178
+
179
+ or
180
+
181
+ ```json
182
+ {
183
+ "audioFile": "2026-01-29"
184
+ }
185
+ ```
186
+
187
+ ### `protokoll_batch_process`
188
+
189
+ Now **directory is optional**:
190
+
191
+ **Before**:
192
+ ```json
193
+ {
194
+ "inputDirectory": "/Users/me/recordings"
195
+ }
196
+ ```
197
+
198
+ **After** (uses configured input directory):
199
+ ```json
200
+ {}
201
+ ```
202
+
203
+ ## Examples
204
+
205
+ ### Transcript Examples
206
+
207
+ #### Example 1: Read Today's Transcript
208
+
209
+ ```typescript
210
+ // Just use today's date
211
+ const result = await client.callTool('protokoll_read_transcript', {
212
+ transcriptPath: '2026-01-29'
213
+ });
214
+ ```
215
+
216
+ #### Example 2: Edit a Transcript by Partial Name
217
+
218
+ ```typescript
219
+ // Find by partial filename
220
+ const result = await client.callTool('protokoll_edit_transcript', {
221
+ transcriptPath: 'standup',
222
+ title: 'Daily Standup - Updated'
223
+ });
224
+ ```
225
+
226
+ #### Example 3: Combine Multiple Transcripts
227
+
228
+ ```typescript
229
+ // Use date patterns to find related transcripts
230
+ const result = await client.callTool('protokoll_combine_transcripts', {
231
+ transcriptPaths: [
232
+ '2026-01-29-morning',
233
+ '2026-01-29-afternoon'
234
+ ],
235
+ title: 'Full Day Notes'
236
+ });
237
+ ```
238
+
239
+ #### Example 4: List Recent Transcripts
240
+
241
+ ```typescript
242
+ // No directory needed - uses config
243
+ const result = await client.callTool('protokoll_list_transcripts', {
244
+ limit: 10,
245
+ sortBy: 'date'
246
+ });
247
+ ```
248
+
249
+ #### Example 5: Search and Edit
250
+
251
+ ```typescript
252
+ // First, search for transcripts
253
+ const list = await client.callTool('protokoll_list_transcripts', {
254
+ search: 'project review'
255
+ });
256
+
257
+ // Then edit using just the filename
258
+ const edit = await client.callTool('protokoll_edit_transcript', {
259
+ transcriptPath: list.transcripts[0].filename,
260
+ projectId: 'new-project'
261
+ });
262
+ ```
263
+
264
+ ### Audio Examples
265
+
266
+ #### Example 6: Process Today's Recording
267
+
268
+ ```typescript
269
+ // Just use today's date or partial filename
270
+ const result = await client.callTool('protokoll_process_audio', {
271
+ audioFile: '2026-01-29'
272
+ });
273
+ ```
274
+
275
+ #### Example 7: Process by Filename
276
+
277
+ ```typescript
278
+ // Use just the filename
279
+ const result = await client.callTool('protokoll_process_audio', {
280
+ audioFile: 'meeting.m4a'
281
+ });
282
+ ```
283
+
284
+ #### Example 8: Batch Process All Audio
285
+
286
+ ```typescript
287
+ // No directory needed - uses configured input directory
288
+ const result = await client.callTool('protokoll_batch_process', {});
289
+ ```
290
+
291
+ #### Example 9: Check Audio Files, Then Process
292
+
293
+ ```typescript
294
+ // First, check what's available using resources
295
+ const audioList = await client.readResource('protokoll://audio/inbound');
296
+ const files = JSON.parse(audioList.text);
297
+
298
+ // Then process a specific file by name
299
+ const result = await client.callTool('protokoll_process_audio', {
300
+ audioFile: files.files[0].filename
301
+ });
302
+ ```
303
+
304
+ ## Error Messages
305
+
306
+ ### No Match Found (Transcripts)
307
+
308
+ ```
309
+ No transcript found matching "xyz" in /Users/me/notes.
310
+ Try using protokoll_list_transcripts to see available transcripts.
311
+ ```
312
+
313
+ **Solution**: Use `protokoll_list_transcripts` to browse available transcripts.
314
+
315
+ ### No Match Found (Audio)
316
+
317
+ ```
318
+ No audio file found matching "xyz" in /Users/me/recordings.
319
+ Try using the protokoll://audio/inbound resource to see available audio files.
320
+ ```
321
+
322
+ **Solution**: Use the `protokoll://audio/inbound` resource to browse available audio files.
323
+
324
+ ### Multiple Matches (Transcripts)
325
+
326
+ ```
327
+ Multiple transcripts match "meeting":
328
+ - 2026-01-29-meeting-notes.md
329
+ - 2026-01-28-meeting-notes.md
330
+ - 2026-01-27-meeting-notes.md
331
+ Please be more specific.
332
+ ```
333
+
334
+ **Solution**: Add more detail to your query (e.g., include the date: `"2026-01-29-meeting"`).
335
+
336
+ ### Multiple Matches (Audio)
337
+
338
+ ```
339
+ Multiple audio files match "recording":
340
+ - 2026-01-29-recording.m4a
341
+ - 2026-01-28-recording.m4a
342
+ Please be more specific.
343
+ ```
344
+
345
+ **Solution**: Add more detail to your query (e.g., include the date or time: `"2026-01-29-recording"`).
346
+
347
+ ## Best Practices
348
+
349
+ ### 1. Use Date Patterns for Recent Work
350
+
351
+ ```typescript
352
+ // Today's files
353
+ transcriptPath: '2026-01-29'
354
+ audioFile: '2026-01-29'
355
+
356
+ // This week's files
357
+ search: '2026-01'
358
+ ```
359
+
360
+ ### 2. Use Descriptive Keywords
361
+
362
+ ```typescript
363
+ // Good - specific
364
+ transcriptPath: 'standup-notes'
365
+ audioFile: 'meeting-recording'
366
+
367
+ // Less specific
368
+ transcriptPath: 'notes'
369
+ audioFile: 'recording'
370
+ ```
371
+
372
+ ### 3. Combine with Resources for Discovery
373
+
374
+ ```typescript
375
+ // For transcripts - discover first
376
+ const list = await client.callTool('protokoll_list_transcripts', {
377
+ search: 'meeting',
378
+ limit: 5
379
+ });
380
+
381
+ // Then use the exact filename
382
+ const transcript = await client.callTool('protokoll_read_transcript', {
383
+ transcriptPath: list.transcripts[0].filename
384
+ });
385
+
386
+ // For audio - use resources
387
+ const audioList = await client.readResource('protokoll://audio/inbound');
388
+ const files = JSON.parse(audioList.text);
389
+
390
+ // Then process by filename
391
+ const result = await client.callTool('protokoll_process_audio', {
392
+ audioFile: files.files[0].filename
393
+ });
394
+ ```
395
+
396
+ ### 4. Override Directory When Needed
397
+
398
+ ```typescript
399
+ // Use a specific directory instead of config
400
+ const transcripts = await client.callTool('protokoll_list_transcripts', {
401
+ directory: '/custom/path/to/transcripts'
402
+ });
403
+
404
+ const batch = await client.callTool('protokoll_batch_process', {
405
+ inputDirectory: '/custom/path/to/audio'
406
+ });
407
+ ```
408
+
409
+ ### 5. Batch Process Without Parameters
410
+
411
+ ```typescript
412
+ // Process all audio in the configured input directory
413
+ const result = await client.callTool('protokoll_batch_process', {});
414
+ ```
415
+
416
+ ## Configuration
417
+
418
+ ### Setting Directories
419
+
420
+ In your `.protokoll/config.yaml`:
421
+
422
+ ```yaml
423
+ inputDirectory: ~/recordings # Where audio files are stored
424
+ outputDirectory: ~/notes # Where transcripts are saved
425
+ processedDirectory: ~/processed # Where processed audio is moved
426
+ outputStructure: month # or 'none', 'year', 'day'
427
+ ```
428
+
429
+ ### Hierarchical Configuration
430
+
431
+ If you have multiple `.protokoll` directories, the closest one takes precedence:
432
+
433
+ ```
434
+ /home/user/
435
+ └── .protokoll/config.yaml
436
+ inputDirectory: ~/recordings
437
+ outputDirectory: ~/notes
438
+
439
+ /home/user/projects/work/
440
+ └── .protokoll/config.yaml
441
+ inputDirectory: ~/work-recordings
442
+ outputDirectory: ~/work-notes
443
+ ```
444
+
445
+ When working in `/home/user/projects/work/`, the system uses:
446
+ - `~/work-recordings` for audio input
447
+ - `~/work-notes` for transcript output
448
+
449
+ ## Technical Details
450
+
451
+ ### Search Algorithm (Transcripts)
452
+
453
+ 1. **Exact path check**: If the input is an absolute path that exists, use it
454
+ 2. **Directory discovery**: Load the configured output directory
455
+ 3. **Search**: Use `protokoll_list_transcripts` with the input as search term
456
+ 4. **Match selection**:
457
+ - 0 matches: Error with helpful message
458
+ - 1 match: Return that transcript
459
+ - Multiple matches: Try exact filename match, otherwise error with list
460
+
461
+ ### Search Algorithm (Audio)
462
+
463
+ 1. **Exact path check**: If the input is an absolute path that exists, use it
464
+ 2. **Directory discovery**: Load the configured input directory
465
+ 3. **File scan**: Read directory and filter by audio extensions
466
+ 4. **Match selection**:
467
+ - Exact filename match
468
+ - Partial filename match
469
+ - Basename match (without extension)
470
+ 5. **Result**:
471
+ - 0 matches: Error with helpful message
472
+ - 1 match: Return that audio file
473
+ - Multiple matches: Error with list of matches
474
+
475
+ ### Performance
476
+
477
+ - Transcript search is recursive and may be slow for very large collections
478
+ - Audio search is single-directory and fast
479
+ - Consider using more specific queries for large directories
480
+ - Results are not cached between tool calls
481
+
482
+ ### Limitations
483
+
484
+ - Requires a valid `.protokoll` context
485
+ - Only searches in configured directories (or specified directories)
486
+ - Partial matches must be unique or include enough detail to disambiguate
487
+ - Audio search only looks in the top-level input directory (not recursive)
488
+
489
+ ## Migration Guide
490
+
491
+ ### For Existing Workflows
492
+
493
+ If you have existing code using absolute paths, it will continue to work. The system detects absolute paths and uses them directly.
494
+
495
+ ### Updating to Use Smart Lookup
496
+
497
+ Replace absolute paths with filenames:
498
+
499
+ **Before (Transcripts)**:
500
+ ```typescript
501
+ const path = '/Users/me/notes/2026/01/2026-01-29-1015-meeting.md';
502
+ await client.callTool('protokoll_read_transcript', { transcriptPath: path });
503
+ ```
504
+
505
+ **After**:
506
+ ```typescript
507
+ await client.callTool('protokoll_read_transcript', {
508
+ transcriptPath: '2026-01-29-meeting'
509
+ });
510
+ ```
511
+
512
+ **Before (Audio)**:
513
+ ```typescript
514
+ const path = '/Users/me/recordings/2026-01-29-meeting.m4a';
515
+ await client.callTool('protokoll_process_audio', { audioFile: path });
516
+ ```
517
+
518
+ **After**:
519
+ ```typescript
520
+ await client.callTool('protokoll_process_audio', {
521
+ audioFile: '2026-01-29-meeting'
522
+ });
523
+ ```
524
+
525
+ ### Handling Ambiguity
526
+
527
+ If you get "multiple matches" errors, add more detail:
528
+
529
+ ```typescript
530
+ // Too vague
531
+ transcriptPath: 'meeting' // ❌ Might match many files
532
+ audioFile: 'recording' // ❌ Might match many files
533
+
534
+ // Better
535
+ transcriptPath: '2026-01-29-meeting' // ✅ More specific
536
+ audioFile: '2026-01-29-recording' // ✅ More specific
537
+
538
+ // Even better
539
+ transcriptPath: '2026-01-29-1015-meeting' // ✅ Very specific
540
+ audioFile: '2026-01-29-1015-recording' // ✅ Very specific
541
+ ```
542
+
543
+ ### Simplifying Batch Operations
544
+
545
+ **Before**:
546
+ ```typescript
547
+ await client.callTool('protokoll_batch_process', {
548
+ inputDirectory: '/Users/me/recordings'
549
+ });
550
+ ```
551
+
552
+ **After**:
553
+ ```typescript
554
+ // Just use empty object - uses config
555
+ await client.callTool('protokoll_batch_process', {});
556
+ ```
557
+
558
+ ## See Also
559
+
560
+ - [MCP Tools Documentation](./MCP_TOOLS.md)
561
+ - [MCP Resources Documentation](./MCP_RESOURCES.md)
562
+ - [Configuration Guide](../README.md#configuration)