@hasna/recordings 0.1.32 → 0.1.34
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/cli/index.js +29 -23
- package/dist/index.js +5 -5
- package/dist/mcp/index.js +8 -8
- package/dist/storage.js +3 -3
- package/dist/version.d.ts +1 -1
- package/package.json +2 -2
- package/src/native/Recordings/RecordingsLib/RecordingEngine.swift +1 -29
- package/src/native/Recordings/RecordingsTests/OpenAIAPIKeyStoreTests.swift +2 -2
package/dist/cli/index.js
CHANGED
|
@@ -5003,7 +5003,7 @@ var init_pg_migrations = __esm(() => {
|
|
|
5003
5003
|
raw_text TEXT NOT NULL,
|
|
5004
5004
|
processed_text TEXT,
|
|
5005
5005
|
processing_mode TEXT NOT NULL DEFAULT 'raw' CHECK(processing_mode IN ('raw', 'enhanced')),
|
|
5006
|
-
model_used TEXT NOT NULL DEFAULT 'gpt-4o-
|
|
5006
|
+
model_used TEXT NOT NULL DEFAULT 'gpt-4o-transcribe',
|
|
5007
5007
|
enhancement_model TEXT,
|
|
5008
5008
|
duration_ms INTEGER DEFAULT 0,
|
|
5009
5009
|
language TEXT,
|
|
@@ -5098,7 +5098,7 @@ var init_pg_migrate = __esm(() => {
|
|
|
5098
5098
|
var require_package = __commonJS((exports, module) => {
|
|
5099
5099
|
module.exports = {
|
|
5100
5100
|
name: "@hasna/recordings",
|
|
5101
|
-
version: "0.1.
|
|
5101
|
+
version: "0.1.34",
|
|
5102
5102
|
type: "module",
|
|
5103
5103
|
description: "Speech-to-text recording tool with MCP and CLI \u2014 records, transcribes, and optionally enhances text using AI",
|
|
5104
5104
|
repository: {
|
|
@@ -5148,7 +5148,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
5148
5148
|
"LICENSE"
|
|
5149
5149
|
],
|
|
5150
5150
|
dependencies: {
|
|
5151
|
-
"@hasna/events": "^0.1.
|
|
5151
|
+
"@hasna/events": "^0.1.7",
|
|
5152
5152
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
5153
5153
|
chalk: "^5.4.1",
|
|
5154
5154
|
commander: "^13.1.0",
|
|
@@ -5736,9 +5736,15 @@ function print(value, json, text) {
|
|
|
5736
5736
|
else
|
|
5737
5737
|
console.log(text);
|
|
5738
5738
|
}
|
|
5739
|
+
function hasJsonOption(options) {
|
|
5740
|
+
return Boolean(options?.json || options?.opts?.().json || options?.optsWithGlobals?.().json || options?.parent?.opts?.().json || options?.parent?.optsWithGlobals?.().json);
|
|
5741
|
+
}
|
|
5742
|
+
function wantsJson(actionOptions, command) {
|
|
5743
|
+
return hasJsonOption(actionOptions) || hasJsonOption(command);
|
|
5744
|
+
}
|
|
5739
5745
|
function registerWebhookCommands(program, options) {
|
|
5740
5746
|
const webhooks = program.command(options.webhooksCommandName ?? "webhooks").description("Manage Hasna event webhook subscriptions");
|
|
5741
|
-
webhooks.command("add").description("Add or replace a webhook or command subscription").argument("<target>", "Webhook URL or command binary").requiredOption("--id <id>", "Subscription/channel identifier").option("--transport <kind>", "Transport kind: webhook or command", "webhook").option("--name <name>", "Display name").option("--type <pattern>", "Event type filter, e.g. todos.task.*").option("--source <pattern>", "Event source filter").option("--subject <pattern>", "Event subject filter").option("--severity <pattern>", "Event severity filter").option("--secret <secret>", "Webhook HMAC secret").option("--header <name=value...>", "Webhook header", collectValues, []).option("--arg <arg...>", "Command argument", collectValues, []).option("--timeout-ms <ms>", "Transport timeout in milliseconds", parseNumber).option("--retry-attempts <n>", "Maximum delivery attempts", parseNumber).option("--retry-backoff-ms <ms>", "Initial retry backoff in milliseconds", parseNumber).option("--redact <path...>", "Event field path to redact before delivery", collectValues, []).option("--disabled", "Create channel disabled", false).option("-j, --json", "Print JSON output", false).action(async (target, actionOptions) => {
|
|
5747
|
+
webhooks.command("add").description("Add or replace a webhook or command subscription").argument("<target>", "Webhook URL or command binary").requiredOption("--id <id>", "Subscription/channel identifier").option("--transport <kind>", "Transport kind: webhook or command", "webhook").option("--name <name>", "Display name").option("--type <pattern>", "Event type filter, e.g. todos.task.*").option("--source <pattern>", "Event source filter").option("--subject <pattern>", "Event subject filter").option("--severity <pattern>", "Event severity filter").option("--secret <secret>", "Webhook HMAC secret").option("--header <name=value...>", "Webhook header", collectValues, []).option("--arg <arg...>", "Command argument", collectValues, []).option("--timeout-ms <ms>", "Transport timeout in milliseconds", parseNumber).option("--retry-attempts <n>", "Maximum delivery attempts", parseNumber).option("--retry-backoff-ms <ms>", "Initial retry backoff in milliseconds", parseNumber).option("--redact <path...>", "Event field path to redact before delivery", collectValues, []).option("--disabled", "Create channel disabled", false).option("-j, --json", "Print JSON output", false).action(async (target, actionOptions, command) => {
|
|
5742
5748
|
const timestamp = new Date().toISOString();
|
|
5743
5749
|
const channel = {
|
|
5744
5750
|
id: actionOptions.id,
|
|
@@ -5759,11 +5765,11 @@ function registerWebhookCommands(program, options) {
|
|
|
5759
5765
|
throw new Error(`Transport ${actionOptions.transport} is reserved for future use and cannot be added yet`);
|
|
5760
5766
|
}
|
|
5761
5767
|
const saved = await createClient(options).addChannel(channel);
|
|
5762
|
-
print(sanitizeChannelForOutput(saved),
|
|
5768
|
+
print(sanitizeChannelForOutput(saved), wantsJson(actionOptions, command), `Added ${saved.transport} channel ${saved.id}`);
|
|
5763
5769
|
});
|
|
5764
|
-
webhooks.command("list").description("List configured subscriptions").option("-j, --json", "Print JSON output", false).action(async (actionOptions) => {
|
|
5770
|
+
webhooks.command("list").description("List configured subscriptions").option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
|
|
5765
5771
|
const channels = await createClient(options).listChannels();
|
|
5766
|
-
if (actionOptions
|
|
5772
|
+
if (wantsJson(actionOptions, command)) {
|
|
5767
5773
|
console.log(JSON.stringify(sanitizeChannelsForOutput(channels), null, 2));
|
|
5768
5774
|
return;
|
|
5769
5775
|
}
|
|
@@ -5775,11 +5781,11 @@ function registerWebhookCommands(program, options) {
|
|
|
5775
5781
|
console.log(`${channel.id} ${channel.enabled ? "enabled" : "disabled"} ${channel.transport} ${channel.webhook?.url ?? channel.command?.command ?? channel.transport}`);
|
|
5776
5782
|
}
|
|
5777
5783
|
});
|
|
5778
|
-
webhooks.command("remove").description("Remove a subscription").argument("<id>", "Subscription/channel identifier").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions) => {
|
|
5784
|
+
webhooks.command("remove").description("Remove a subscription").argument("<id>", "Subscription/channel identifier").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
|
|
5779
5785
|
const removed = await createClient(options).removeChannel(id);
|
|
5780
|
-
print({ removed },
|
|
5786
|
+
print({ removed }, wantsJson(actionOptions, command), removed ? `Removed ${id}` : `Channel not found: ${id}`);
|
|
5781
5787
|
});
|
|
5782
|
-
webhooks.command("test").description("Send a test event to one subscription").argument("<id>", "Subscription/channel identifier").option("--type <type>", "Event type", "events.test").option("--subject <subject>", "Event subject").option("--message <message>", "Event message", "Hasna events test delivery").option("--data <json>", "Event data JSON object").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions) => {
|
|
5788
|
+
webhooks.command("test").description("Send a test event to one subscription").argument("<id>", "Subscription/channel identifier").option("--type <type>", "Event type", "events.test").option("--subject <subject>", "Event subject").option("--message <message>", "Event message", "Hasna events test delivery").option("--data <json>", "Event data JSON object").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
|
|
5783
5789
|
const result = await createClient(options).testChannel(id, {
|
|
5784
5790
|
source: options.source,
|
|
5785
5791
|
type: actionOptions.type,
|
|
@@ -5787,13 +5793,13 @@ function registerWebhookCommands(program, options) {
|
|
|
5787
5793
|
message: actionOptions.message,
|
|
5788
5794
|
data: parseJsonObject(actionOptions.data, { test: true })
|
|
5789
5795
|
});
|
|
5790
|
-
print(result,
|
|
5796
|
+
print(result, wantsJson(actionOptions, command), `${result.status}: ${result.channelId}`);
|
|
5791
5797
|
});
|
|
5792
5798
|
return webhooks;
|
|
5793
5799
|
}
|
|
5794
5800
|
function registerEventCommands(program, options) {
|
|
5795
5801
|
const events = program.command(options.eventsCommandName ?? "events").description("Emit, list, and replay Hasna events");
|
|
5796
|
-
events.command("emit").description("Emit an event from this app").argument("<type>", "Event type").option("--source <source>", "Event source override").option("--subject <subject>", "Event subject").option("--severity <severity>", "Event severity", "info").option("--message <message>", "Event message").option("--dedupe-key <key>", "Dedupe key").option("--data <json>", "Event data JSON object").option("--metadata <json>", "Event metadata JSON object").option("--no-deliver", "Record without delivering").option("--no-dedupe", "Allow duplicate id/dedupeKey events").option("-j, --json", "Print JSON output", false).action(async (type, actionOptions) => {
|
|
5802
|
+
events.command("emit").description("Emit an event from this app").argument("<type>", "Event type").option("--source <source>", "Event source override").option("--subject <subject>", "Event subject").option("--severity <severity>", "Event severity", "info").option("--message <message>", "Event message").option("--dedupe-key <key>", "Dedupe key").option("--data <json>", "Event data JSON object").option("--metadata <json>", "Event metadata JSON object").option("--no-deliver", "Record without delivering").option("--no-dedupe", "Allow duplicate id/dedupeKey events").option("-j, --json", "Print JSON output", false).action(async (type, actionOptions, command) => {
|
|
5797
5803
|
const result = await createClient(options).emit({
|
|
5798
5804
|
source: actionOptions.source ?? options.source,
|
|
5799
5805
|
type,
|
|
@@ -5804,9 +5810,9 @@ function registerEventCommands(program, options) {
|
|
|
5804
5810
|
data: parseJsonObject(actionOptions.data, {}),
|
|
5805
5811
|
metadata: parseJsonObject(actionOptions.metadata, {})
|
|
5806
5812
|
}, { deliver: actionOptions.deliver, dedupe: actionOptions.dedupe });
|
|
5807
|
-
print(result,
|
|
5813
|
+
print(result, wantsJson(actionOptions, command), `${result.deduped ? "Deduped" : "Emitted"} ${result.event.id} to ${result.deliveries.length} channel(s)`);
|
|
5808
5814
|
});
|
|
5809
|
-
events.command("list").description("List recorded events").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--limit <n>", "Limit results", parseNumber).option("-j, --json", "Print JSON output", false).action(async (actionOptions) => {
|
|
5815
|
+
events.command("list").description("List recorded events").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--limit <n>", "Limit results", parseNumber).option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
|
|
5810
5816
|
let rows = await createClient(options).listEvents();
|
|
5811
5817
|
if (actionOptions.source)
|
|
5812
5818
|
rows = rows.filter((event) => event.source === actionOptions.source);
|
|
@@ -5814,7 +5820,7 @@ function registerEventCommands(program, options) {
|
|
|
5814
5820
|
rows = rows.filter((event) => event.type === actionOptions.type);
|
|
5815
5821
|
if (actionOptions.limit)
|
|
5816
5822
|
rows = rows.slice(-actionOptions.limit);
|
|
5817
|
-
if (actionOptions
|
|
5823
|
+
if (wantsJson(actionOptions, command)) {
|
|
5818
5824
|
console.log(JSON.stringify(rows, null, 2));
|
|
5819
5825
|
return;
|
|
5820
5826
|
}
|
|
@@ -5825,14 +5831,14 @@ function registerEventCommands(program, options) {
|
|
|
5825
5831
|
for (const event of rows)
|
|
5826
5832
|
console.log(`${event.time} ${event.id} ${event.source} ${event.type} ${event.severity}`);
|
|
5827
5833
|
});
|
|
5828
|
-
events.command("replay").description("Replay recorded events").option("--id <id>", "Replay one event id").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--dry-run", "Preview without delivery", false).option("-j, --json", "Print JSON output", false).action(async (actionOptions) => {
|
|
5834
|
+
events.command("replay").description("Replay recorded events").option("--id <id>", "Replay one event id").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--dry-run", "Preview without delivery", false).option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
|
|
5829
5835
|
const result = await createClient(options).replay({
|
|
5830
5836
|
eventId: actionOptions.id,
|
|
5831
5837
|
source: actionOptions.source,
|
|
5832
5838
|
type: actionOptions.type,
|
|
5833
5839
|
dryRun: actionOptions.dryRun
|
|
5834
5840
|
});
|
|
5835
|
-
print(result,
|
|
5841
|
+
print(result, wantsJson(actionOptions, command), `Replayed ${result.events.length} event(s), ${result.deliveries.length} delivery result(s)`);
|
|
5836
5842
|
});
|
|
5837
5843
|
return events;
|
|
5838
5844
|
}
|
|
@@ -5865,7 +5871,7 @@ import { homedir as homedir2 } from "os";
|
|
|
5865
5871
|
var DEFAULT_CONFIG = {
|
|
5866
5872
|
openai_api_key: "",
|
|
5867
5873
|
enhancement_api_key: "",
|
|
5868
|
-
transcription_model: "gpt-4o-
|
|
5874
|
+
transcription_model: "gpt-4o-transcribe",
|
|
5869
5875
|
enhancement_model: "gpt-4o",
|
|
5870
5876
|
language: "en",
|
|
5871
5877
|
audio_format: "wav",
|
|
@@ -6103,7 +6109,7 @@ var MIGRATIONS = [
|
|
|
6103
6109
|
raw_text TEXT NOT NULL,
|
|
6104
6110
|
processed_text TEXT,
|
|
6105
6111
|
processing_mode TEXT NOT NULL DEFAULT 'raw' CHECK(processing_mode IN ('raw', 'enhanced')),
|
|
6106
|
-
model_used TEXT NOT NULL DEFAULT 'gpt-4o-
|
|
6112
|
+
model_used TEXT NOT NULL DEFAULT 'gpt-4o-transcribe',
|
|
6107
6113
|
enhancement_model TEXT,
|
|
6108
6114
|
duration_ms INTEGER DEFAULT 0,
|
|
6109
6115
|
language TEXT,
|
|
@@ -6233,7 +6239,7 @@ function parseRow(row) {
|
|
|
6233
6239
|
raw_text: row["raw_text"],
|
|
6234
6240
|
processed_text: row["processed_text"] || null,
|
|
6235
6241
|
processing_mode: row["processing_mode"] || "raw",
|
|
6236
|
-
model_used: row["model_used"] || "gpt-4o-
|
|
6242
|
+
model_used: row["model_used"] || "gpt-4o-transcribe",
|
|
6237
6243
|
enhancement_model: row["enhancement_model"] || null,
|
|
6238
6244
|
duration_ms: row["duration_ms"] || 0,
|
|
6239
6245
|
language: row["language"] || null,
|
|
@@ -6255,7 +6261,7 @@ function createRecording(input, db) {
|
|
|
6255
6261
|
const tagsJson = JSON.stringify(input.tags || []);
|
|
6256
6262
|
const metadataJson = JSON.stringify(input.metadata || {});
|
|
6257
6263
|
d.query(`INSERT INTO recordings (id, audio_path, raw_text, processed_text, processing_mode, model_used, enhancement_model, duration_ms, language, tags, agent_id, project_id, session_id, goal, role, task_list_id, machine_id, metadata)
|
|
6258
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, input.audio_path || null, input.raw_text, input.processed_text || null, input.processing_mode || "raw", input.model_used || "gpt-4o-
|
|
6264
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, input.audio_path || null, input.raw_text, input.processed_text || null, input.processing_mode || "raw", input.model_used || "gpt-4o-transcribe", input.enhancement_model || null, input.duration_ms || 0, input.language || null, tagsJson, input.agent_id || null, input.project_id || null, input.session_id || null, input.goal || null, input.role || null, input.task_list_id || null, input.machine_id || null, metadataJson);
|
|
6259
6265
|
if (input.tags && input.tags.length > 0) {
|
|
6260
6266
|
const insertTag = d.query("INSERT OR IGNORE INTO recording_tags (recording_id, tag) VALUES (?, ?)");
|
|
6261
6267
|
for (const tag of input.tags) {
|
|
@@ -6762,7 +6768,7 @@ async function processText(rawText, config, systemPrompt) {
|
|
|
6762
6768
|
}
|
|
6763
6769
|
|
|
6764
6770
|
// src/version.ts
|
|
6765
|
-
var VERSION = "0.1.
|
|
6771
|
+
var VERSION = "0.1.33";
|
|
6766
6772
|
|
|
6767
6773
|
// src/cli/storage.ts
|
|
6768
6774
|
import chalk from "chalk";
|
|
@@ -7415,7 +7421,7 @@ program.command("init").description("Initialize .recordings/ in current director
|
|
|
7415
7421
|
mkdirSync3(audioDir, { recursive: true });
|
|
7416
7422
|
if (!existsSync6(configFile)) {
|
|
7417
7423
|
const defaultConf = {
|
|
7418
|
-
transcription_model: "gpt-4o-
|
|
7424
|
+
transcription_model: "gpt-4o-transcribe",
|
|
7419
7425
|
enhancement_model: "gpt-4o",
|
|
7420
7426
|
language: "en",
|
|
7421
7427
|
auto_enhance: true
|
package/dist/index.js
CHANGED
|
@@ -4972,7 +4972,7 @@ import { homedir } from "os";
|
|
|
4972
4972
|
var DEFAULT_CONFIG = {
|
|
4973
4973
|
openai_api_key: "",
|
|
4974
4974
|
enhancement_api_key: "",
|
|
4975
|
-
transcription_model: "gpt-4o-
|
|
4975
|
+
transcription_model: "gpt-4o-transcribe",
|
|
4976
4976
|
enhancement_model: "gpt-4o",
|
|
4977
4977
|
language: "en",
|
|
4978
4978
|
audio_format: "wav",
|
|
@@ -5177,7 +5177,7 @@ var MIGRATIONS = [
|
|
|
5177
5177
|
raw_text TEXT NOT NULL,
|
|
5178
5178
|
processed_text TEXT,
|
|
5179
5179
|
processing_mode TEXT NOT NULL DEFAULT 'raw' CHECK(processing_mode IN ('raw', 'enhanced')),
|
|
5180
|
-
model_used TEXT NOT NULL DEFAULT 'gpt-4o-
|
|
5180
|
+
model_used TEXT NOT NULL DEFAULT 'gpt-4o-transcribe',
|
|
5181
5181
|
enhancement_model TEXT,
|
|
5182
5182
|
duration_ms INTEGER DEFAULT 0,
|
|
5183
5183
|
language TEXT,
|
|
@@ -5460,7 +5460,7 @@ var PG_MIGRATIONS = [
|
|
|
5460
5460
|
raw_text TEXT NOT NULL,
|
|
5461
5461
|
processed_text TEXT,
|
|
5462
5462
|
processing_mode TEXT NOT NULL DEFAULT 'raw' CHECK(processing_mode IN ('raw', 'enhanced')),
|
|
5463
|
-
model_used TEXT NOT NULL DEFAULT 'gpt-4o-
|
|
5463
|
+
model_used TEXT NOT NULL DEFAULT 'gpt-4o-transcribe',
|
|
5464
5464
|
enhancement_model TEXT,
|
|
5465
5465
|
duration_ms INTEGER DEFAULT 0,
|
|
5466
5466
|
language TEXT,
|
|
@@ -5701,7 +5701,7 @@ function parseRow(row) {
|
|
|
5701
5701
|
raw_text: row["raw_text"],
|
|
5702
5702
|
processed_text: row["processed_text"] || null,
|
|
5703
5703
|
processing_mode: row["processing_mode"] || "raw",
|
|
5704
|
-
model_used: row["model_used"] || "gpt-4o-
|
|
5704
|
+
model_used: row["model_used"] || "gpt-4o-transcribe",
|
|
5705
5705
|
enhancement_model: row["enhancement_model"] || null,
|
|
5706
5706
|
duration_ms: row["duration_ms"] || 0,
|
|
5707
5707
|
language: row["language"] || null,
|
|
@@ -5723,7 +5723,7 @@ function createRecording(input, db) {
|
|
|
5723
5723
|
const tagsJson = JSON.stringify(input.tags || []);
|
|
5724
5724
|
const metadataJson = JSON.stringify(input.metadata || {});
|
|
5725
5725
|
d.query(`INSERT INTO recordings (id, audio_path, raw_text, processed_text, processing_mode, model_used, enhancement_model, duration_ms, language, tags, agent_id, project_id, session_id, goal, role, task_list_id, machine_id, metadata)
|
|
5726
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, input.audio_path || null, input.raw_text, input.processed_text || null, input.processing_mode || "raw", input.model_used || "gpt-4o-
|
|
5726
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, input.audio_path || null, input.raw_text, input.processed_text || null, input.processing_mode || "raw", input.model_used || "gpt-4o-transcribe", input.enhancement_model || null, input.duration_ms || 0, input.language || null, tagsJson, input.agent_id || null, input.project_id || null, input.session_id || null, input.goal || null, input.role || null, input.task_list_id || null, input.machine_id || null, metadataJson);
|
|
5727
5727
|
if (input.tags && input.tags.length > 0) {
|
|
5728
5728
|
const insertTag = d.query("INSERT OR IGNORE INTO recording_tags (recording_id, tag) VALUES (?, ?)");
|
|
5729
5729
|
for (const tag of input.tags) {
|
package/dist/mcp/index.js
CHANGED
|
@@ -4920,7 +4920,7 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
4920
4920
|
var require_package = __commonJS((exports, module) => {
|
|
4921
4921
|
module.exports = {
|
|
4922
4922
|
name: "@hasna/recordings",
|
|
4923
|
-
version: "0.1.
|
|
4923
|
+
version: "0.1.34",
|
|
4924
4924
|
type: "module",
|
|
4925
4925
|
description: "Speech-to-text recording tool with MCP and CLI \u2014 records, transcribes, and optionally enhances text using AI",
|
|
4926
4926
|
repository: {
|
|
@@ -4970,7 +4970,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
4970
4970
|
"LICENSE"
|
|
4971
4971
|
],
|
|
4972
4972
|
dependencies: {
|
|
4973
|
-
"@hasna/events": "^0.1.
|
|
4973
|
+
"@hasna/events": "^0.1.7",
|
|
4974
4974
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
4975
4975
|
chalk: "^5.4.1",
|
|
4976
4976
|
commander: "^13.1.0",
|
|
@@ -9021,7 +9021,7 @@ import { homedir } from "os";
|
|
|
9021
9021
|
var DEFAULT_CONFIG = {
|
|
9022
9022
|
openai_api_key: "",
|
|
9023
9023
|
enhancement_api_key: "",
|
|
9024
|
-
transcription_model: "gpt-4o-
|
|
9024
|
+
transcription_model: "gpt-4o-transcribe",
|
|
9025
9025
|
enhancement_model: "gpt-4o",
|
|
9026
9026
|
language: "en",
|
|
9027
9027
|
audio_format: "wav",
|
|
@@ -9259,7 +9259,7 @@ var MIGRATIONS = [
|
|
|
9259
9259
|
raw_text TEXT NOT NULL,
|
|
9260
9260
|
processed_text TEXT,
|
|
9261
9261
|
processing_mode TEXT NOT NULL DEFAULT 'raw' CHECK(processing_mode IN ('raw', 'enhanced')),
|
|
9262
|
-
model_used TEXT NOT NULL DEFAULT 'gpt-4o-
|
|
9262
|
+
model_used TEXT NOT NULL DEFAULT 'gpt-4o-transcribe',
|
|
9263
9263
|
enhancement_model TEXT,
|
|
9264
9264
|
duration_ms INTEGER DEFAULT 0,
|
|
9265
9265
|
language TEXT,
|
|
@@ -9389,7 +9389,7 @@ function parseRow(row) {
|
|
|
9389
9389
|
raw_text: row["raw_text"],
|
|
9390
9390
|
processed_text: row["processed_text"] || null,
|
|
9391
9391
|
processing_mode: row["processing_mode"] || "raw",
|
|
9392
|
-
model_used: row["model_used"] || "gpt-4o-
|
|
9392
|
+
model_used: row["model_used"] || "gpt-4o-transcribe",
|
|
9393
9393
|
enhancement_model: row["enhancement_model"] || null,
|
|
9394
9394
|
duration_ms: row["duration_ms"] || 0,
|
|
9395
9395
|
language: row["language"] || null,
|
|
@@ -9411,7 +9411,7 @@ function createRecording(input, db) {
|
|
|
9411
9411
|
const tagsJson = JSON.stringify(input.tags || []);
|
|
9412
9412
|
const metadataJson = JSON.stringify(input.metadata || {});
|
|
9413
9413
|
d.query(`INSERT INTO recordings (id, audio_path, raw_text, processed_text, processing_mode, model_used, enhancement_model, duration_ms, language, tags, agent_id, project_id, session_id, goal, role, task_list_id, machine_id, metadata)
|
|
9414
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, input.audio_path || null, input.raw_text, input.processed_text || null, input.processing_mode || "raw", input.model_used || "gpt-4o-
|
|
9414
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, input.audio_path || null, input.raw_text, input.processed_text || null, input.processing_mode || "raw", input.model_used || "gpt-4o-transcribe", input.enhancement_model || null, input.duration_ms || 0, input.language || null, tagsJson, input.agent_id || null, input.project_id || null, input.session_id || null, input.goal || null, input.role || null, input.task_list_id || null, input.machine_id || null, metadataJson);
|
|
9415
9415
|
if (input.tags && input.tags.length > 0) {
|
|
9416
9416
|
const insertTag = d.query("INSERT OR IGNORE INTO recording_tags (recording_id, tag) VALUES (?, ?)");
|
|
9417
9417
|
for (const tag of input.tags) {
|
|
@@ -9798,7 +9798,7 @@ async function processText(rawText, config, systemPrompt) {
|
|
|
9798
9798
|
}
|
|
9799
9799
|
|
|
9800
9800
|
// src/version.ts
|
|
9801
|
-
var VERSION = "0.1.
|
|
9801
|
+
var VERSION = "0.1.33";
|
|
9802
9802
|
|
|
9803
9803
|
// src/db/storage-config.ts
|
|
9804
9804
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
@@ -9957,7 +9957,7 @@ var PG_MIGRATIONS = [
|
|
|
9957
9957
|
raw_text TEXT NOT NULL,
|
|
9958
9958
|
processed_text TEXT,
|
|
9959
9959
|
processing_mode TEXT NOT NULL DEFAULT 'raw' CHECK(processing_mode IN ('raw', 'enhanced')),
|
|
9960
|
-
model_used TEXT NOT NULL DEFAULT 'gpt-4o-
|
|
9960
|
+
model_used TEXT NOT NULL DEFAULT 'gpt-4o-transcribe',
|
|
9961
9961
|
enhancement_model TEXT,
|
|
9962
9962
|
duration_ms INTEGER DEFAULT 0,
|
|
9963
9963
|
language TEXT,
|
package/dist/storage.js
CHANGED
|
@@ -5024,7 +5024,7 @@ import { homedir as homedir2 } from "os";
|
|
|
5024
5024
|
var DEFAULT_CONFIG = {
|
|
5025
5025
|
openai_api_key: "",
|
|
5026
5026
|
enhancement_api_key: "",
|
|
5027
|
-
transcription_model: "gpt-4o-
|
|
5027
|
+
transcription_model: "gpt-4o-transcribe",
|
|
5028
5028
|
enhancement_model: "gpt-4o",
|
|
5029
5029
|
language: "en",
|
|
5030
5030
|
audio_format: "wav",
|
|
@@ -5229,7 +5229,7 @@ var MIGRATIONS = [
|
|
|
5229
5229
|
raw_text TEXT NOT NULL,
|
|
5230
5230
|
processed_text TEXT,
|
|
5231
5231
|
processing_mode TEXT NOT NULL DEFAULT 'raw' CHECK(processing_mode IN ('raw', 'enhanced')),
|
|
5232
|
-
model_used TEXT NOT NULL DEFAULT 'gpt-4o-
|
|
5232
|
+
model_used TEXT NOT NULL DEFAULT 'gpt-4o-transcribe',
|
|
5233
5233
|
enhancement_model TEXT,
|
|
5234
5234
|
duration_ms INTEGER DEFAULT 0,
|
|
5235
5235
|
language TEXT,
|
|
@@ -5434,7 +5434,7 @@ var PG_MIGRATIONS = [
|
|
|
5434
5434
|
raw_text TEXT NOT NULL,
|
|
5435
5435
|
processed_text TEXT,
|
|
5436
5436
|
processing_mode TEXT NOT NULL DEFAULT 'raw' CHECK(processing_mode IN ('raw', 'enhanced')),
|
|
5437
|
-
model_used TEXT NOT NULL DEFAULT 'gpt-4o-
|
|
5437
|
+
model_used TEXT NOT NULL DEFAULT 'gpt-4o-transcribe',
|
|
5438
5438
|
enhancement_model TEXT,
|
|
5439
5439
|
duration_ms INTEGER DEFAULT 0,
|
|
5440
5440
|
language TEXT,
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.1.
|
|
1
|
+
export declare const VERSION = "0.1.33";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/recordings",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
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
|
"repository": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"LICENSE"
|
|
51
51
|
],
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@hasna/events": "^0.1.
|
|
53
|
+
"@hasna/events": "^0.1.7",
|
|
54
54
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
55
55
|
"chalk": "^5.4.1",
|
|
56
56
|
"commander": "^13.1.0",
|
|
@@ -520,7 +520,6 @@ public final class RecordingEngine: ObservableObject {
|
|
|
520
520
|
|
|
521
521
|
public func stopAndTranscribe() {
|
|
522
522
|
guard isRecording else { return }
|
|
523
|
-
let stopStartedAt = Date()
|
|
524
523
|
log("stopAndTranscribe")
|
|
525
524
|
|
|
526
525
|
recordingTimer?.invalidate()
|
|
@@ -541,7 +540,6 @@ public final class RecordingEngine: ObservableObject {
|
|
|
541
540
|
let audioPath = activeAudioPath
|
|
542
541
|
let pcmStreamPipe = pcmStreamPipe
|
|
543
542
|
let client = realtimeClient
|
|
544
|
-
let transcriptionLanguage = transcriptionLanguage
|
|
545
543
|
resetRecordingIntent()
|
|
546
544
|
self.pcmStreamPipe = nil
|
|
547
545
|
|
|
@@ -558,37 +556,11 @@ public final class RecordingEngine: ObservableObject {
|
|
|
558
556
|
self.streamingTask = nil
|
|
559
557
|
|
|
560
558
|
let realtimeText = Self.normalizedRealtimeTranscript(streamingResult)
|
|
561
|
-
let fastPathText = Self.realtimeFastPathTranscript(
|
|
562
|
-
realtimeText: streamingResult,
|
|
563
|
-
pcmByteCount: self.recordedPCM.count,
|
|
564
|
-
language: transcriptionLanguage
|
|
565
|
-
)
|
|
566
559
|
|
|
567
560
|
self.liveTranscriptionText = ""
|
|
568
561
|
|
|
569
|
-
if let fastPathText {
|
|
570
|
-
let releaseToTextMS = Int(Date().timeIntervalSince(stopStartedAt) * 1_000)
|
|
571
|
-
let repaired = Self.wasRealtimeTranscriptRepaired(rawText: streamingResult, cleanedText: fastPathText)
|
|
572
|
-
self.log("using realtime fast path chars=\(fastPathText.count) repaired=\(repaired) releaseToTextMs=\(releaseToTextMS)")
|
|
573
|
-
self.isTranscribing = false
|
|
574
|
-
self.finishWithText(
|
|
575
|
-
fastPathText,
|
|
576
|
-
curMode: curMode,
|
|
577
|
-
targetAppBundleIdentifier: targetAppBundleIdentifier,
|
|
578
|
-
targetAppPid: targetAppPid,
|
|
579
|
-
activeProjectId: activeProjectId,
|
|
580
|
-
activeProjectName: activeProjectName
|
|
581
|
-
)
|
|
582
|
-
if let audioPath, !self.recordedPCM.isEmpty {
|
|
583
|
-
Self.saveCapturedWAVInBackground(pcmData: self.recordedPCM, audioPath: audioPath, homePath: self.home)
|
|
584
|
-
}
|
|
585
|
-
self.activeAudioPath = nil
|
|
586
|
-
self.recordedPCM.removeAll(keepingCapacity: true)
|
|
587
|
-
return
|
|
588
|
-
}
|
|
589
|
-
|
|
590
562
|
if let audioPath, self.writeCapturedWAV(to: audioPath) {
|
|
591
|
-
self.log("transcribing captured full audio audioPath=\(audioPath) realtimePreviewChars=\(realtimeText?.count ?? 0)")
|
|
563
|
+
self.log("transcribing captured full audio with quality model audioPath=\(audioPath) realtimePreviewChars=\(realtimeText?.count ?? 0)")
|
|
592
564
|
self.fallbackTranscribe(
|
|
593
565
|
audioPath: audioPath,
|
|
594
566
|
curMode: curMode,
|
|
@@ -119,7 +119,7 @@ struct OpenAIAPIKeyStoreTests {
|
|
|
119
119
|
let home = try makeHome()
|
|
120
120
|
try writeConfig(home: home, [
|
|
121
121
|
"openai_api_key": "old-key",
|
|
122
|
-
"transcription_model": "gpt-4o-
|
|
122
|
+
"transcription_model": "gpt-4o-transcribe",
|
|
123
123
|
])
|
|
124
124
|
|
|
125
125
|
try OpenAIAPIKeyStore.save(key: "sk-rotated", homePath: home.path)
|
|
@@ -131,7 +131,7 @@ struct OpenAIAPIKeyStoreTests {
|
|
|
131
131
|
let data = try Data(contentsOf: configURL)
|
|
132
132
|
let json = try #require(JSONSerialization.jsonObject(with: data) as? [String: Any])
|
|
133
133
|
#expect(json["openai_api_key"] as? String == "sk-rotated")
|
|
134
|
-
#expect(json["transcription_model"] as? String == "gpt-4o-
|
|
134
|
+
#expect(json["transcription_model"] as? String == "gpt-4o-transcribe")
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
@Test("Saving an empty key removes it from config.json")
|