@hasna/recordings 0.0.3 → 0.1.2

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,6 @@
1
+ import type { RecordingsConfig } from "../types/index.js";
2
+ export declare const DEFAULT_CONFIG: RecordingsConfig;
3
+ export declare function loadConfig(configPath?: string): RecordingsConfig;
4
+ export declare function getDataDir(): string;
5
+ export declare function ensureDataDir(config: RecordingsConfig): void;
6
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,eAAO,MAAM,cAAc,EAAE,gBA0B5B,CAAC;AAEF,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAmEhE;AAgBD,wBAAgB,UAAU,IAAI,MAAM,CAanC;AA0BD,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAU5D"}
@@ -0,0 +1,25 @@
1
+ import type { RecordingsConfig, EnhancementResult } from "../types/index.js";
2
+ export declare function resetEnhancementClient(): void;
3
+ /**
4
+ * Detect if the transcribed text needs AI enhancement.
5
+ *
6
+ * Detection logic:
7
+ * 1. Explicit triggers: "say it better", "rewrite this", etc.
8
+ * 2. Instruction patterns: "write an email saying...", "give instructions to..."
9
+ * 3. Meta-commentary: text that talks ABOUT what to say rather than being the content itself
10
+ */
11
+ export declare function needsEnhancement(text: string, config: RecordingsConfig): {
12
+ needs: boolean;
13
+ reason: string;
14
+ instruction: string;
15
+ };
16
+ export declare function enhanceText(rawText: string, instruction: string, config: RecordingsConfig): Promise<EnhancementResult>;
17
+ /**
18
+ * Full pipeline: detect if enhancement is needed, enhance if so.
19
+ */
20
+ export declare function processText(rawText: string, config: RecordingsConfig): Promise<{
21
+ text: string;
22
+ mode: "raw" | "enhanced";
23
+ enhancement_model: string | null;
24
+ }>;
25
+ //# sourceMappingURL=enhancer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enhancer.d.ts","sourceRoot":"","sources":["../../src/lib/enhancer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AAiB3B,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,gBAAgB,GACvB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAmCzD;AAoBD,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,iBAAiB,CAAC,CAyC5B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,KAAK,GAAG,UAAU,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC,CAkBD"}
@@ -0,0 +1,30 @@
1
+ import type { RecordingsConfig } from "../types/index.js";
2
+ /**
3
+ * Check if sox/rec is available for recording
4
+ */
5
+ export declare function checkRecordingDeps(): Promise<{
6
+ available: boolean;
7
+ tool: string;
8
+ message: string;
9
+ }>;
10
+ /**
11
+ * Start recording audio from microphone
12
+ */
13
+ export declare function startRecording(config: RecordingsConfig): string;
14
+ /**
15
+ * Stop the current recording
16
+ */
17
+ export declare function stopRecording(): string | null;
18
+ /**
19
+ * Check if currently recording
20
+ */
21
+ export declare function isRecording(): boolean;
22
+ /**
23
+ * Get current recording file path
24
+ */
25
+ export declare function getCurrentFile(): string | null;
26
+ /**
27
+ * Record for a specific duration (non-interactive)
28
+ */
29
+ export declare function recordDuration(seconds: number, config: RecordingsConfig): Promise<string>;
30
+ //# sourceMappingURL=recorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/lib/recorder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAM1D;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC;IAClD,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAqDD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CA6B/D;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAa7C;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAE9C;AAwBD;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,MAAM,CAAC,CAgCjB"}
@@ -0,0 +1,5 @@
1
+ import type { RecordingsConfig, TranscriptionResult } from "../types/index.js";
2
+ export declare function resetClient(): void;
3
+ export declare function transcribeAudio(audioPath: string, config: RecordingsConfig): Promise<TranscriptionResult>;
4
+ export declare function transcribeBuffer(buffer: Buffer, filename: string, config: RecordingsConfig): Promise<TranscriptionResult>;
5
+ //# sourceMappingURL=transcriber.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcriber.d.ts","sourceRoot":"","sources":["../../src/lib/transcriber.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAgB/E,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,mBAAmB,CAAC,CAwB9B;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,mBAAmB,CAAC,CA4B9B"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bun
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":""}
package/dist/mcp/index.js CHANGED
@@ -1,13 +1,17 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
3
  var __defProp = Object.defineProperty;
4
+ var __returnValue = (v) => v;
5
+ function __exportSetter(name, newValue) {
6
+ this[name] = __returnValue.bind(null, newValue);
7
+ }
4
8
  var __export = (target, all) => {
5
9
  for (var name in all)
6
10
  __defProp(target, name, {
7
11
  get: all[name],
8
12
  enumerable: true,
9
13
  configurable: true,
10
- set: (newValue) => all[name] = () => newValue
14
+ set: __exportSetter.bind(all, name)
11
15
  });
12
16
  };
13
17
  var __require = import.meta.require;
@@ -4878,5 +4882,31 @@ server.tool("list_projects", "List registered projects.", {}, async () => {
4878
4882
  return errorResult(e);
4879
4883
  }
4880
4884
  });
4885
+ var _agentReg = new Map;
4886
+ server.tool("register_agent", "Register this agent session. Returns agent_id for use in heartbeat/set_focus.", { name: exports_external.string(), session_id: exports_external.string().optional() }, async (a) => {
4887
+ const existing = [..._agentReg.values()].find((x) => x.name === a.name);
4888
+ if (existing) {
4889
+ existing.last_seen_at = new Date().toISOString();
4890
+ return { content: [{ type: "text", text: JSON.stringify(existing) }] };
4891
+ }
4892
+ const id = Math.random().toString(36).slice(2, 10);
4893
+ const ag = { id, name: a.name, last_seen_at: new Date().toISOString() };
4894
+ _agentReg.set(id, ag);
4895
+ return { content: [{ type: "text", text: JSON.stringify(ag) }] };
4896
+ });
4897
+ server.tool("heartbeat", "Update last_seen_at to signal agent is active.", { agent_id: exports_external.string() }, async (a) => {
4898
+ const ag = _agentReg.get(a.agent_id);
4899
+ if (!ag)
4900
+ return { content: [{ type: "text", text: `Agent not found: ${a.agent_id}` }], isError: true };
4901
+ ag.last_seen_at = new Date().toISOString();
4902
+ return { content: [{ type: "text", text: `\u2665 ${ag.name} \u2014 active` }] };
4903
+ });
4904
+ server.tool("set_focus", "Set active project context for this agent session.", { agent_id: exports_external.string(), project_id: exports_external.string().optional() }, async (a) => {
4905
+ const ag = _agentReg.get(a.agent_id);
4906
+ if (!ag)
4907
+ return { content: [{ type: "text", text: `Agent not found: ${a.agent_id}` }], isError: true };
4908
+ ag.project_id = a.project_id;
4909
+ return { content: [{ type: "text", text: a.project_id ? `Focus: ${a.project_id}` : "Focus cleared" }] };
4910
+ });
4881
4911
  var transport = new StdioServerTransport;
4882
4912
  await server.connect(transport);
@@ -0,0 +1,103 @@
1
+ export interface Recording {
2
+ id: string;
3
+ audio_path: string | null;
4
+ raw_text: string;
5
+ processed_text: string | null;
6
+ processing_mode: ProcessingMode;
7
+ model_used: string;
8
+ enhancement_model: string | null;
9
+ duration_ms: number;
10
+ language: string | null;
11
+ tags: string[];
12
+ agent_id: string | null;
13
+ project_id: string | null;
14
+ session_id: string | null;
15
+ metadata: Record<string, unknown>;
16
+ created_at: string;
17
+ }
18
+ export type ProcessingMode = "raw" | "enhanced";
19
+ export interface CreateRecordingInput {
20
+ audio_path?: string;
21
+ raw_text: string;
22
+ processed_text?: string;
23
+ processing_mode?: ProcessingMode;
24
+ model_used?: string;
25
+ enhancement_model?: string;
26
+ duration_ms?: number;
27
+ language?: string;
28
+ tags?: string[];
29
+ agent_id?: string;
30
+ project_id?: string;
31
+ session_id?: string;
32
+ metadata?: Record<string, unknown>;
33
+ }
34
+ export interface RecordingFilter {
35
+ agent_id?: string;
36
+ project_id?: string;
37
+ session_id?: string;
38
+ processing_mode?: ProcessingMode;
39
+ tags?: string[];
40
+ search?: string;
41
+ since?: string;
42
+ until?: string;
43
+ limit?: number;
44
+ offset?: number;
45
+ }
46
+ export interface Agent {
47
+ id: string;
48
+ name: string;
49
+ description: string | null;
50
+ role: string;
51
+ metadata: Record<string, unknown>;
52
+ created_at: string;
53
+ last_seen_at: string;
54
+ }
55
+ export interface Project {
56
+ id: string;
57
+ name: string;
58
+ path: string;
59
+ description: string | null;
60
+ created_at: string;
61
+ updated_at: string;
62
+ }
63
+ export interface RecordingsConfig {
64
+ openai_api_key: string;
65
+ enhancement_api_key: string;
66
+ transcription_model: string;
67
+ enhancement_model: string;
68
+ language: string;
69
+ audio_format: "wav" | "mp3" | "m4a" | "webm";
70
+ sample_rate: number;
71
+ record_command: string;
72
+ hotkey: string;
73
+ auto_enhance: boolean;
74
+ enhance_triggers: string[];
75
+ db_path: string;
76
+ audio_dir: string;
77
+ max_recording_seconds: number;
78
+ }
79
+ export interface TranscriptionResult {
80
+ text: string;
81
+ duration_ms: number;
82
+ model: string;
83
+ language: string | null;
84
+ }
85
+ export interface EnhancementResult {
86
+ original: string;
87
+ enhanced: string;
88
+ model: string;
89
+ reasoning: string | null;
90
+ }
91
+ export declare class RecordingNotFoundError extends Error {
92
+ constructor(id: string);
93
+ }
94
+ export declare class RecordingError extends Error {
95
+ constructor(message: string);
96
+ }
97
+ export declare class TranscriptionError extends Error {
98
+ constructor(message: string);
99
+ }
100
+ export declare class EnhancementError extends Error {
101
+ constructor(message: string);
102
+ }
103
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/recordings",
3
- "version": "0.0.3",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "description": "Speech-to-text recording tool with MCP and CLI — records, transcribes, and optionally enhances text using AI",
6
6
  "main": "dist/index.js",
package/src/cli/index.ts CHANGED
@@ -34,7 +34,7 @@ program
34
34
  .description(
35
35
  "Speech-to-text recording tool — record, transcribe, and enhance with AI"
36
36
  )
37
- .version("0.0.1")
37
+ .version("0.0.3")
38
38
  .option("--json", "Output as JSON")
39
39
  .option("--agent <name>", "Agent name or ID")
40
40
  .option("--project <name>", "Project name or ID")
package/src/mcp/index.ts CHANGED
@@ -401,5 +401,46 @@ server.tool(
401
401
 
402
402
  // ── Start Server ────────────────────────────────────────────────────────────
403
403
 
404
+
405
+ const _agentReg = new Map<string, { id: string; name: string; last_seen_at: string }>();
406
+
407
+ server.tool(
408
+ "register_agent",
409
+ "Register this agent session. Returns agent_id for use in heartbeat/set_focus.",
410
+ { name: z.string(), session_id: z.string().optional() },
411
+ async (a: { name: string; session_id?: string }) => {
412
+ const existing = [..._agentReg.values()].find(x => x.name === a.name);
413
+ if (existing) { existing.last_seen_at = new Date().toISOString(); return { content: [{ type: "text" as const, text: JSON.stringify(existing) }] }; }
414
+ const id = Math.random().toString(36).slice(2, 10);
415
+ const ag = { id, name: a.name, last_seen_at: new Date().toISOString() };
416
+ _agentReg.set(id, ag);
417
+ return { content: [{ type: "text" as const, text: JSON.stringify(ag) }] };
418
+ }
419
+ );
420
+
421
+ server.tool(
422
+ "heartbeat",
423
+ "Update last_seen_at to signal agent is active.",
424
+ { agent_id: z.string() },
425
+ async (a: { agent_id: string }) => {
426
+ const ag = _agentReg.get(a.agent_id);
427
+ if (!ag) return { content: [{ type: "text" as const, text: `Agent not found: ${a.agent_id}` }], isError: true };
428
+ ag.last_seen_at = new Date().toISOString();
429
+ return { content: [{ type: "text" as const, text: `♥ ${ag.name} — active` }] };
430
+ }
431
+ );
432
+
433
+ server.tool(
434
+ "set_focus",
435
+ "Set active project context for this agent session.",
436
+ { agent_id: z.string(), project_id: z.string().optional() },
437
+ async (a: { agent_id: string; project_id?: string }) => {
438
+ const ag = _agentReg.get(a.agent_id);
439
+ if (!ag) return { content: [{ type: "text" as const, text: `Agent not found: ${a.agent_id}` }], isError: true };
440
+ (ag as any).project_id = a.project_id;
441
+ return { content: [{ type: "text" as const, text: a.project_id ? `Focus: ${a.project_id}` : "Focus cleared" }] };
442
+ }
443
+ );
444
+
404
445
  const transport = new StdioServerTransport();
405
446
  await server.connect(transport);
@@ -1 +0,0 @@
1
- {"sessionId":"26ed30ef-ff55-4957-91cc-40a82f829ca0","pid":85889,"acquiredAt":1773261929948}