@hasna/recordings 0.1.36 → 0.1.37
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 +43 -0
- package/dist/cli/index.js +14 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +135 -0
- package/dist/mcp/index.js +14 -5
- package/dist/sdk/index.d.ts +16 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +171 -0
- package/dist/sdk/v1.generated.d.ts +150 -0
- package/dist/sdk/v1.generated.d.ts.map +1 -0
- package/dist/server/cloud.d.ts +49 -0
- package/dist/server/cloud.d.ts.map +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +6812 -0
- package/dist/server/openapi.d.ts +614 -0
- package/dist/server/openapi.d.ts.map +1 -0
- package/dist/server/repo.d.ts +34 -0
- package/dist/server/repo.d.ts.map +1 -0
- package/dist/server/serve.d.ts +11 -0
- package/dist/server/serve.d.ts.map +1 -0
- package/dist/server/v1.d.ts +6 -0
- package/dist/server/v1.d.ts.map +1 -0
- package/dist/version.d.ts +1 -1
- package/package.json +13 -4
- package/scripts/generate-sdk.ts +31 -0
- package/scripts/migrate.ts +37 -0
package/README.md
CHANGED
|
@@ -42,6 +42,49 @@ MCP_HTTP=1 MCP_HTTP_PORT=8829 recordings-mcp
|
|
|
42
42
|
|
|
43
43
|
Endpoints: `GET /health` → `{"status":"ok","name":"recordings"}`, MCP at `/mcp`.
|
|
44
44
|
|
|
45
|
+
## HTTP API (`recordings-serve`)
|
|
46
|
+
|
|
47
|
+
`recordings-serve` is the self-hosted HTTP API. In cloud mode it is PURE REMOTE
|
|
48
|
+
(Amendment A1): the process reads/writes the shared cloud Postgres directly with
|
|
49
|
+
API-key auth via [`@hasna/contracts`](https://www.npmjs.com/package/@hasna/contracts).
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
recordings-serve --port 8874 # start the API
|
|
53
|
+
recordings-serve migrate # apply the cloud schema, then exit
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Service surface (unauthenticated): `GET /health`, `GET /ready`, `GET /version`
|
|
57
|
+
(each returns `{status, version, mode}`), and `GET /openapi.json` (the OpenAPI
|
|
58
|
+
3.1 document the SDK is generated from).
|
|
59
|
+
|
|
60
|
+
Versioned API (`/v1/*`, API-key auth via `x-api-key` or `Authorization: Bearer`):
|
|
61
|
+
|
|
62
|
+
| Method | Path | Scope |
|
|
63
|
+
| ------ | ---- | ----- |
|
|
64
|
+
| GET/POST | `/v1/recordings` | `recordings:read` / `recordings:write` |
|
|
65
|
+
| GET/DELETE | `/v1/recordings/:id` | `recordings:read` / `recordings:write` |
|
|
66
|
+
| GET | `/v1/stats` | `recordings:read` |
|
|
67
|
+
| GET/POST | `/v1/agents` · GET `/v1/agents/:id` | `recordings:read` / `recordings:write` |
|
|
68
|
+
| GET/POST | `/v1/projects` · GET `/v1/projects/:id` | `recordings:read` / `recordings:write` |
|
|
69
|
+
|
|
70
|
+
Env: `HASNA_RECORDINGS_DATABASE_URL` (remote Postgres DSN — enables cloud `/v1`)
|
|
71
|
+
and `HASNA_RECORDINGS_API_SIGNING_KEY` (HMAC signing secret for API-key auth).
|
|
72
|
+
|
|
73
|
+
## SDK
|
|
74
|
+
|
|
75
|
+
The typed `/v1` client is generated from the serve OpenAPI document
|
|
76
|
+
(`bun run generate:sdk`):
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { RecordingsV1Client } from "@hasna/recordings/sdk";
|
|
80
|
+
|
|
81
|
+
const client = new RecordingsV1Client({
|
|
82
|
+
baseUrl: process.env.RECORDINGS_API_URL!,
|
|
83
|
+
apiKey: process.env.RECORDINGS_API_KEY!,
|
|
84
|
+
});
|
|
85
|
+
const { recordings } = await client.listRecordings({ limit: 20 });
|
|
86
|
+
```
|
|
87
|
+
|
|
45
88
|
## Storage Sync
|
|
46
89
|
|
|
47
90
|
This package has native local/remote sync. Local data stays in SQLite under
|
package/dist/cli/index.js
CHANGED
|
@@ -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.37",
|
|
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: {
|
|
@@ -5109,7 +5109,8 @@ var require_package = __commonJS((exports, module) => {
|
|
|
5109
5109
|
types: "dist/index.d.ts",
|
|
5110
5110
|
bin: {
|
|
5111
5111
|
recordings: "dist/cli/index.js",
|
|
5112
|
-
"recordings-mcp": "dist/mcp/index.js"
|
|
5112
|
+
"recordings-mcp": "dist/mcp/index.js",
|
|
5113
|
+
"recordings-serve": "dist/server/index.js"
|
|
5113
5114
|
},
|
|
5114
5115
|
exports: {
|
|
5115
5116
|
".": {
|
|
@@ -5119,14 +5120,21 @@ var require_package = __commonJS((exports, module) => {
|
|
|
5119
5120
|
"./storage": {
|
|
5120
5121
|
import: "./dist/storage.js",
|
|
5121
5122
|
types: "./dist/storage.d.ts"
|
|
5123
|
+
},
|
|
5124
|
+
"./sdk": {
|
|
5125
|
+
import: "./dist/sdk/index.js",
|
|
5126
|
+
types: "./dist/sdk/index.d.ts"
|
|
5122
5127
|
}
|
|
5123
5128
|
},
|
|
5124
5129
|
scripts: {
|
|
5125
5130
|
clean: "rm -rf dist",
|
|
5126
|
-
build: "bun run clean && bun run build:cli && bun run build:mcp && bun run build:lib && tsc --emitDeclarationOnly --outDir dist",
|
|
5131
|
+
build: "bun run clean && bun run build:cli && bun run build:mcp && bun run build:serve && bun run build:lib && tsc --emitDeclarationOnly --outDir dist",
|
|
5127
5132
|
"build:cli": "bun build src/cli/index.ts --target=bun --outfile=dist/cli/index.js --external=commander --external=chalk --external=openai",
|
|
5128
5133
|
"build:mcp": "bun build src/mcp/index.ts --target=bun --outfile=dist/mcp/index.js --external=@modelcontextprotocol/sdk --external=openai",
|
|
5129
|
-
"build:
|
|
5134
|
+
"build:serve": "bun build src/server/index.ts --target=bun --outfile=dist/server/index.js --external=@modelcontextprotocol/sdk --external=@hasna/contracts --external=openai --external=pg",
|
|
5135
|
+
"build:lib": "bun build src/index.ts src/storage.ts src/sdk/index.ts --target=bun --outdir=dist --external=openai",
|
|
5136
|
+
"generate:sdk": "bun run scripts/generate-sdk.ts",
|
|
5137
|
+
migrate: "bun run scripts/migrate.ts",
|
|
5130
5138
|
typecheck: "tsc --noEmit",
|
|
5131
5139
|
test: "bun test",
|
|
5132
5140
|
"test:coverage": "bun test --coverage",
|
|
@@ -5150,6 +5158,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
5150
5158
|
"LICENSE"
|
|
5151
5159
|
],
|
|
5152
5160
|
dependencies: {
|
|
5161
|
+
"@hasna/contracts": "0.4.1",
|
|
5153
5162
|
"@hasna/events": "^0.1.11",
|
|
5154
5163
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
5155
5164
|
chalk: "^5.4.1",
|
|
@@ -6991,7 +7000,7 @@ async function processText(rawText, config, systemPrompt) {
|
|
|
6991
7000
|
}
|
|
6992
7001
|
|
|
6993
7002
|
// src/version.ts
|
|
6994
|
-
var VERSION = "0.1.
|
|
7003
|
+
var VERSION = "0.1.37";
|
|
6995
7004
|
|
|
6996
7005
|
// src/cli/storage.ts
|
|
6997
7006
|
import chalk from "chalk";
|
package/dist/index.d.ts
CHANGED
|
@@ -12,4 +12,6 @@ export { loadConfig, getDataDir, ensureDataDir, DEFAULT_CONFIG, } from "./lib/co
|
|
|
12
12
|
export { transcribeAudio, transcribeBuffer, resetClient, } from "./lib/transcriber.js";
|
|
13
13
|
export { needsEnhancement, enhanceText, processText, resetEnhancementClient, } from "./lib/enhancer.js";
|
|
14
14
|
export { startRecording, stopRecording, isRecording, getCurrentFile, checkRecordingDeps, recordDuration, } from "./lib/recorder.js";
|
|
15
|
+
export { RecordingsV1Client, RecordingsV1ApiError, } from "./sdk/index.js";
|
|
16
|
+
export type { RecordingsV1ClientOptions, RecordingsV1Recording, RecordingsV1Agent, RecordingsV1Project, RecordingsV1CreateRecordingInput, RecordingsV1RegisterAgentInput, RecordingsV1RegisterProjectInput, } from "./sdk/index.js";
|
|
15
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,KAAK,EACL,OAAO,EACP,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,WAAW,EACX,aAAa,EACb,aAAa,EACb,SAAS,EACT,SAAS,GACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EACL,sBAAsB,EACtB,+BAA+B,EAC/B,2BAA2B,EAC3B,oCAAoC,EACpC,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,yBAAyB,EACzB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG/E,OAAO,EACL,eAAe,EACf,YAAY,EACZ,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EACL,eAAe,EACf,UAAU,EACV,YAAY,GACb,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,UAAU,EACV,UAAU,EACV,aAAa,EACb,cAAc,GACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,cAAc,EACd,aAAa,EACb,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,cAAc,GACf,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,KAAK,EACL,OAAO,EACP,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,WAAW,EACX,aAAa,EACb,aAAa,EACb,SAAS,EACT,SAAS,GACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EACL,sBAAsB,EACtB,+BAA+B,EAC/B,2BAA2B,EAC3B,oCAAoC,EACpC,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,yBAAyB,EACzB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG/E,OAAO,EACL,eAAe,EACf,YAAY,EACZ,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EACL,eAAe,EACf,UAAU,EACV,YAAY,GACb,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,UAAU,EACV,UAAU,EACV,aAAa,EACb,cAAc,GACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,cAAc,EACd,aAAa,EACb,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,cAAc,GACf,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,yBAAyB,EACzB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,gCAAgC,EAChC,8BAA8B,EAC9B,gCAAgC,GACjC,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4902,6 +4902,139 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
4902
4902
|
});
|
|
4903
4903
|
});
|
|
4904
4904
|
|
|
4905
|
+
// src/sdk/v1.generated.ts
|
|
4906
|
+
class ApiError extends Error {
|
|
4907
|
+
status;
|
|
4908
|
+
body;
|
|
4909
|
+
constructor(status, message, body) {
|
|
4910
|
+
super(message);
|
|
4911
|
+
this.status = status;
|
|
4912
|
+
this.body = body;
|
|
4913
|
+
this.name = "ApiError";
|
|
4914
|
+
}
|
|
4915
|
+
}
|
|
4916
|
+
|
|
4917
|
+
class RecordingsV1Client {
|
|
4918
|
+
baseUrl;
|
|
4919
|
+
apiKey;
|
|
4920
|
+
fetchImpl;
|
|
4921
|
+
baseHeaders;
|
|
4922
|
+
constructor(options) {
|
|
4923
|
+
if (!options.baseUrl)
|
|
4924
|
+
throw new Error("RecordingsV1Client requires a baseUrl.");
|
|
4925
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
4926
|
+
this.apiKey = options.apiKey;
|
|
4927
|
+
this.fetchImpl = options.fetch ?? globalThis.fetch;
|
|
4928
|
+
this.baseHeaders = options.headers ?? {};
|
|
4929
|
+
}
|
|
4930
|
+
async request(method, path, opts) {
|
|
4931
|
+
const url = new URL(this.baseUrl + path);
|
|
4932
|
+
if (opts.query) {
|
|
4933
|
+
for (const [key, value] of Object.entries(opts.query)) {
|
|
4934
|
+
if (value !== undefined && value !== null)
|
|
4935
|
+
url.searchParams.set(key, String(value));
|
|
4936
|
+
}
|
|
4937
|
+
}
|
|
4938
|
+
const headers = { Accept: "application/json", ...this.baseHeaders, ...opts.init?.headers };
|
|
4939
|
+
if (this.apiKey)
|
|
4940
|
+
headers["x-api-key"] = this.apiKey;
|
|
4941
|
+
let payload;
|
|
4942
|
+
if (opts.body !== undefined) {
|
|
4943
|
+
headers["Content-Type"] = "application/json";
|
|
4944
|
+
payload = JSON.stringify(opts.body);
|
|
4945
|
+
}
|
|
4946
|
+
const response = await this.fetchImpl(url.toString(), { ...opts.init, method, headers, body: payload });
|
|
4947
|
+
const text = await response.text();
|
|
4948
|
+
const data = text ? (() => {
|
|
4949
|
+
try {
|
|
4950
|
+
return JSON.parse(text);
|
|
4951
|
+
} catch {
|
|
4952
|
+
return text;
|
|
4953
|
+
}
|
|
4954
|
+
})() : undefined;
|
|
4955
|
+
if (!response.ok) {
|
|
4956
|
+
throw new ApiError(response.status, `${method} ${path} failed: ${response.status}`, data);
|
|
4957
|
+
}
|
|
4958
|
+
return data;
|
|
4959
|
+
}
|
|
4960
|
+
async listAgents(init) {
|
|
4961
|
+
return this.request("GET", `/v1/agents`, {
|
|
4962
|
+
body: undefined,
|
|
4963
|
+
query: undefined,
|
|
4964
|
+
init
|
|
4965
|
+
});
|
|
4966
|
+
}
|
|
4967
|
+
async registerAgent(body, init) {
|
|
4968
|
+
return this.request("POST", `/v1/agents`, {
|
|
4969
|
+
body,
|
|
4970
|
+
query: undefined,
|
|
4971
|
+
init
|
|
4972
|
+
});
|
|
4973
|
+
}
|
|
4974
|
+
async getAgent(id, init) {
|
|
4975
|
+
return this.request("GET", `/v1/agents/${encodeURIComponent(String(id))}`, {
|
|
4976
|
+
body: undefined,
|
|
4977
|
+
query: undefined,
|
|
4978
|
+
init
|
|
4979
|
+
});
|
|
4980
|
+
}
|
|
4981
|
+
async listProjects(init) {
|
|
4982
|
+
return this.request("GET", `/v1/projects`, {
|
|
4983
|
+
body: undefined,
|
|
4984
|
+
query: undefined,
|
|
4985
|
+
init
|
|
4986
|
+
});
|
|
4987
|
+
}
|
|
4988
|
+
async registerProject(body, init) {
|
|
4989
|
+
return this.request("POST", `/v1/projects`, {
|
|
4990
|
+
body,
|
|
4991
|
+
query: undefined,
|
|
4992
|
+
init
|
|
4993
|
+
});
|
|
4994
|
+
}
|
|
4995
|
+
async getProject(id, init) {
|
|
4996
|
+
return this.request("GET", `/v1/projects/${encodeURIComponent(String(id))}`, {
|
|
4997
|
+
body: undefined,
|
|
4998
|
+
query: undefined,
|
|
4999
|
+
init
|
|
5000
|
+
});
|
|
5001
|
+
}
|
|
5002
|
+
async listRecordings(query, init) {
|
|
5003
|
+
return this.request("GET", `/v1/recordings`, {
|
|
5004
|
+
body: undefined,
|
|
5005
|
+
query,
|
|
5006
|
+
init
|
|
5007
|
+
});
|
|
5008
|
+
}
|
|
5009
|
+
async createRecording(body, init) {
|
|
5010
|
+
return this.request("POST", `/v1/recordings`, {
|
|
5011
|
+
body,
|
|
5012
|
+
query: undefined,
|
|
5013
|
+
init
|
|
5014
|
+
});
|
|
5015
|
+
}
|
|
5016
|
+
async getRecording(id, init) {
|
|
5017
|
+
return this.request("GET", `/v1/recordings/${encodeURIComponent(String(id))}`, {
|
|
5018
|
+
body: undefined,
|
|
5019
|
+
query: undefined,
|
|
5020
|
+
init
|
|
5021
|
+
});
|
|
5022
|
+
}
|
|
5023
|
+
async deleteRecording(id, init) {
|
|
5024
|
+
return this.request("DELETE", `/v1/recordings/${encodeURIComponent(String(id))}`, {
|
|
5025
|
+
body: undefined,
|
|
5026
|
+
query: undefined,
|
|
5027
|
+
init
|
|
5028
|
+
});
|
|
5029
|
+
}
|
|
5030
|
+
async getRecordingStats(init) {
|
|
5031
|
+
return this.request("GET", `/v1/stats`, {
|
|
5032
|
+
body: undefined,
|
|
5033
|
+
query: undefined,
|
|
5034
|
+
init
|
|
5035
|
+
});
|
|
5036
|
+
}
|
|
5037
|
+
}
|
|
4905
5038
|
// src/types/index.ts
|
|
4906
5039
|
class RecordingNotFoundError extends Error {
|
|
4907
5040
|
constructor(id) {
|
|
@@ -6334,6 +6467,8 @@ export {
|
|
|
6334
6467
|
STORAGE_TABLES,
|
|
6335
6468
|
STORAGE_MODE_ENV,
|
|
6336
6469
|
STORAGE_DATABASE_ENV,
|
|
6470
|
+
RecordingsV1Client,
|
|
6471
|
+
ApiError as RecordingsV1ApiError,
|
|
6337
6472
|
RecordingNotFoundError,
|
|
6338
6473
|
RecordingError,
|
|
6339
6474
|
RECORDINGS_STORAGE_TABLES,
|
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.37",
|
|
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: {
|
|
@@ -4931,7 +4931,8 @@ var require_package = __commonJS((exports, module) => {
|
|
|
4931
4931
|
types: "dist/index.d.ts",
|
|
4932
4932
|
bin: {
|
|
4933
4933
|
recordings: "dist/cli/index.js",
|
|
4934
|
-
"recordings-mcp": "dist/mcp/index.js"
|
|
4934
|
+
"recordings-mcp": "dist/mcp/index.js",
|
|
4935
|
+
"recordings-serve": "dist/server/index.js"
|
|
4935
4936
|
},
|
|
4936
4937
|
exports: {
|
|
4937
4938
|
".": {
|
|
@@ -4941,14 +4942,21 @@ var require_package = __commonJS((exports, module) => {
|
|
|
4941
4942
|
"./storage": {
|
|
4942
4943
|
import: "./dist/storage.js",
|
|
4943
4944
|
types: "./dist/storage.d.ts"
|
|
4945
|
+
},
|
|
4946
|
+
"./sdk": {
|
|
4947
|
+
import: "./dist/sdk/index.js",
|
|
4948
|
+
types: "./dist/sdk/index.d.ts"
|
|
4944
4949
|
}
|
|
4945
4950
|
},
|
|
4946
4951
|
scripts: {
|
|
4947
4952
|
clean: "rm -rf dist",
|
|
4948
|
-
build: "bun run clean && bun run build:cli && bun run build:mcp && bun run build:lib && tsc --emitDeclarationOnly --outDir dist",
|
|
4953
|
+
build: "bun run clean && bun run build:cli && bun run build:mcp && bun run build:serve && bun run build:lib && tsc --emitDeclarationOnly --outDir dist",
|
|
4949
4954
|
"build:cli": "bun build src/cli/index.ts --target=bun --outfile=dist/cli/index.js --external=commander --external=chalk --external=openai",
|
|
4950
4955
|
"build:mcp": "bun build src/mcp/index.ts --target=bun --outfile=dist/mcp/index.js --external=@modelcontextprotocol/sdk --external=openai",
|
|
4951
|
-
"build:
|
|
4956
|
+
"build:serve": "bun build src/server/index.ts --target=bun --outfile=dist/server/index.js --external=@modelcontextprotocol/sdk --external=@hasna/contracts --external=openai --external=pg",
|
|
4957
|
+
"build:lib": "bun build src/index.ts src/storage.ts src/sdk/index.ts --target=bun --outdir=dist --external=openai",
|
|
4958
|
+
"generate:sdk": "bun run scripts/generate-sdk.ts",
|
|
4959
|
+
migrate: "bun run scripts/migrate.ts",
|
|
4952
4960
|
typecheck: "tsc --noEmit",
|
|
4953
4961
|
test: "bun test",
|
|
4954
4962
|
"test:coverage": "bun test --coverage",
|
|
@@ -4972,6 +4980,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
4972
4980
|
"LICENSE"
|
|
4973
4981
|
],
|
|
4974
4982
|
dependencies: {
|
|
4983
|
+
"@hasna/contracts": "0.4.1",
|
|
4975
4984
|
"@hasna/events": "^0.1.11",
|
|
4976
4985
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
4977
4986
|
chalk: "^5.4.1",
|
|
@@ -9812,7 +9821,7 @@ async function processText(rawText, config, systemPrompt) {
|
|
|
9812
9821
|
}
|
|
9813
9822
|
|
|
9814
9823
|
// src/version.ts
|
|
9815
|
-
var VERSION = "0.1.
|
|
9824
|
+
var VERSION = "0.1.37";
|
|
9816
9825
|
|
|
9817
9826
|
// src/db/storage-config.ts
|
|
9818
9827
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hasna/recordings SDK — typed `/v1` cloud client.
|
|
3
|
+
*
|
|
4
|
+
* Generated from the serve OpenAPI document (src/server/openapi.ts). Regenerate
|
|
5
|
+
* with `bun run generate:sdk`.
|
|
6
|
+
*
|
|
7
|
+
* import { RecordingsV1Client } from "@hasna/recordings/sdk";
|
|
8
|
+
* const client = new RecordingsV1Client({
|
|
9
|
+
* baseUrl: process.env.RECORDINGS_API_URL!,
|
|
10
|
+
* apiKey: process.env.RECORDINGS_API_KEY!,
|
|
11
|
+
* });
|
|
12
|
+
* const { recordings } = await client.listRecordings({ limit: 20 });
|
|
13
|
+
*/
|
|
14
|
+
export { RecordingsV1Client, ApiError as RecordingsV1ApiError, } from "./v1.generated.js";
|
|
15
|
+
export type { RecordingsV1ClientOptions, Recording as RecordingsV1Recording, Agent as RecordingsV1Agent, Project as RecordingsV1Project, CreateRecordingInput as RecordingsV1CreateRecordingInput, RegisterAgentInput as RecordingsV1RegisterAgentInput, RegisterProjectInput as RecordingsV1RegisterProjectInput, } from "./v1.generated.js";
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sdk/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EACL,kBAAkB,EAClB,QAAQ,IAAI,oBAAoB,GACjC,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,yBAAyB,EACzB,SAAS,IAAI,qBAAqB,EAClC,KAAK,IAAI,iBAAiB,EAC1B,OAAO,IAAI,mBAAmB,EAC9B,oBAAoB,IAAI,gCAAgC,EACxD,kBAAkB,IAAI,8BAA8B,EACpD,oBAAoB,IAAI,gCAAgC,GACzD,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
12
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
21
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
22
|
+
for (let key of __getOwnPropNames(mod))
|
|
23
|
+
if (!__hasOwnProp.call(to, key))
|
|
24
|
+
__defProp(to, key, {
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
26
|
+
enumerable: true
|
|
27
|
+
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
30
|
+
return to;
|
|
31
|
+
};
|
|
32
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
33
|
+
var __require = import.meta.require;
|
|
34
|
+
|
|
35
|
+
// src/sdk/v1.generated.ts
|
|
36
|
+
class ApiError extends Error {
|
|
37
|
+
status;
|
|
38
|
+
body;
|
|
39
|
+
constructor(status, message, body) {
|
|
40
|
+
super(message);
|
|
41
|
+
this.status = status;
|
|
42
|
+
this.body = body;
|
|
43
|
+
this.name = "ApiError";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
class RecordingsV1Client {
|
|
48
|
+
baseUrl;
|
|
49
|
+
apiKey;
|
|
50
|
+
fetchImpl;
|
|
51
|
+
baseHeaders;
|
|
52
|
+
constructor(options) {
|
|
53
|
+
if (!options.baseUrl)
|
|
54
|
+
throw new Error("RecordingsV1Client requires a baseUrl.");
|
|
55
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
56
|
+
this.apiKey = options.apiKey;
|
|
57
|
+
this.fetchImpl = options.fetch ?? globalThis.fetch;
|
|
58
|
+
this.baseHeaders = options.headers ?? {};
|
|
59
|
+
}
|
|
60
|
+
async request(method, path, opts) {
|
|
61
|
+
const url = new URL(this.baseUrl + path);
|
|
62
|
+
if (opts.query) {
|
|
63
|
+
for (const [key, value] of Object.entries(opts.query)) {
|
|
64
|
+
if (value !== undefined && value !== null)
|
|
65
|
+
url.searchParams.set(key, String(value));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const headers = { Accept: "application/json", ...this.baseHeaders, ...opts.init?.headers };
|
|
69
|
+
if (this.apiKey)
|
|
70
|
+
headers["x-api-key"] = this.apiKey;
|
|
71
|
+
let payload;
|
|
72
|
+
if (opts.body !== undefined) {
|
|
73
|
+
headers["Content-Type"] = "application/json";
|
|
74
|
+
payload = JSON.stringify(opts.body);
|
|
75
|
+
}
|
|
76
|
+
const response = await this.fetchImpl(url.toString(), { ...opts.init, method, headers, body: payload });
|
|
77
|
+
const text = await response.text();
|
|
78
|
+
const data = text ? (() => {
|
|
79
|
+
try {
|
|
80
|
+
return JSON.parse(text);
|
|
81
|
+
} catch {
|
|
82
|
+
return text;
|
|
83
|
+
}
|
|
84
|
+
})() : undefined;
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
throw new ApiError(response.status, `${method} ${path} failed: ${response.status}`, data);
|
|
87
|
+
}
|
|
88
|
+
return data;
|
|
89
|
+
}
|
|
90
|
+
async listAgents(init) {
|
|
91
|
+
return this.request("GET", `/v1/agents`, {
|
|
92
|
+
body: undefined,
|
|
93
|
+
query: undefined,
|
|
94
|
+
init
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
async registerAgent(body, init) {
|
|
98
|
+
return this.request("POST", `/v1/agents`, {
|
|
99
|
+
body,
|
|
100
|
+
query: undefined,
|
|
101
|
+
init
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
async getAgent(id, init) {
|
|
105
|
+
return this.request("GET", `/v1/agents/${encodeURIComponent(String(id))}`, {
|
|
106
|
+
body: undefined,
|
|
107
|
+
query: undefined,
|
|
108
|
+
init
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
async listProjects(init) {
|
|
112
|
+
return this.request("GET", `/v1/projects`, {
|
|
113
|
+
body: undefined,
|
|
114
|
+
query: undefined,
|
|
115
|
+
init
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
async registerProject(body, init) {
|
|
119
|
+
return this.request("POST", `/v1/projects`, {
|
|
120
|
+
body,
|
|
121
|
+
query: undefined,
|
|
122
|
+
init
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
async getProject(id, init) {
|
|
126
|
+
return this.request("GET", `/v1/projects/${encodeURIComponent(String(id))}`, {
|
|
127
|
+
body: undefined,
|
|
128
|
+
query: undefined,
|
|
129
|
+
init
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
async listRecordings(query, init) {
|
|
133
|
+
return this.request("GET", `/v1/recordings`, {
|
|
134
|
+
body: undefined,
|
|
135
|
+
query,
|
|
136
|
+
init
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
async createRecording(body, init) {
|
|
140
|
+
return this.request("POST", `/v1/recordings`, {
|
|
141
|
+
body,
|
|
142
|
+
query: undefined,
|
|
143
|
+
init
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
async getRecording(id, init) {
|
|
147
|
+
return this.request("GET", `/v1/recordings/${encodeURIComponent(String(id))}`, {
|
|
148
|
+
body: undefined,
|
|
149
|
+
query: undefined,
|
|
150
|
+
init
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
async deleteRecording(id, init) {
|
|
154
|
+
return this.request("DELETE", `/v1/recordings/${encodeURIComponent(String(id))}`, {
|
|
155
|
+
body: undefined,
|
|
156
|
+
query: undefined,
|
|
157
|
+
init
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
async getRecordingStats(init) {
|
|
161
|
+
return this.request("GET", `/v1/stats`, {
|
|
162
|
+
body: undefined,
|
|
163
|
+
query: undefined,
|
|
164
|
+
init
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
export {
|
|
169
|
+
RecordingsV1Client,
|
|
170
|
+
ApiError as RecordingsV1ApiError
|
|
171
|
+
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
export interface Recording {
|
|
2
|
+
"id"?: string;
|
|
3
|
+
"audio_path"?: string | null;
|
|
4
|
+
"raw_text"?: string;
|
|
5
|
+
"processed_text"?: string | null;
|
|
6
|
+
"processing_mode"?: "raw" | "enhanced";
|
|
7
|
+
"model_used"?: string;
|
|
8
|
+
"enhancement_model"?: string | null;
|
|
9
|
+
"duration_ms"?: number;
|
|
10
|
+
"language"?: string | null;
|
|
11
|
+
"tags"?: Array<string>;
|
|
12
|
+
"agent_id"?: string | null;
|
|
13
|
+
"project_id"?: string | null;
|
|
14
|
+
"session_id"?: string | null;
|
|
15
|
+
"goal"?: string | null;
|
|
16
|
+
"role"?: string | null;
|
|
17
|
+
"task_list_id"?: string | null;
|
|
18
|
+
"machine_id"?: string | null;
|
|
19
|
+
"metadata"?: Record<string, unknown>;
|
|
20
|
+
"created_at"?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface Agent {
|
|
23
|
+
"id"?: string;
|
|
24
|
+
"name"?: string;
|
|
25
|
+
"description"?: string | null;
|
|
26
|
+
"role"?: string;
|
|
27
|
+
"metadata"?: Record<string, unknown>;
|
|
28
|
+
"created_at"?: string;
|
|
29
|
+
"last_seen_at"?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface Project {
|
|
32
|
+
"id"?: string;
|
|
33
|
+
"name"?: string;
|
|
34
|
+
"path"?: string;
|
|
35
|
+
"description"?: string | null;
|
|
36
|
+
"created_at"?: string;
|
|
37
|
+
"updated_at"?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface CreateRecordingInput {
|
|
40
|
+
"raw_text": string;
|
|
41
|
+
"audio_path"?: string;
|
|
42
|
+
"processed_text"?: string;
|
|
43
|
+
"processing_mode"?: "raw" | "enhanced";
|
|
44
|
+
"model_used"?: string;
|
|
45
|
+
"enhancement_model"?: string;
|
|
46
|
+
"duration_ms"?: number;
|
|
47
|
+
"language"?: string;
|
|
48
|
+
"tags"?: Array<string>;
|
|
49
|
+
"agent_id"?: string;
|
|
50
|
+
"project_id"?: string;
|
|
51
|
+
"session_id"?: string;
|
|
52
|
+
"goal"?: string;
|
|
53
|
+
"role"?: string;
|
|
54
|
+
"task_list_id"?: string;
|
|
55
|
+
"machine_id"?: string;
|
|
56
|
+
"metadata"?: Record<string, unknown>;
|
|
57
|
+
}
|
|
58
|
+
export interface RegisterAgentInput {
|
|
59
|
+
"name": string;
|
|
60
|
+
"description"?: string;
|
|
61
|
+
"role"?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface RegisterProjectInput {
|
|
64
|
+
"name": string;
|
|
65
|
+
"path": string;
|
|
66
|
+
"description"?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface RecordingsV1ClientOptions {
|
|
69
|
+
/** Base URL, e.g. process.env.APP_API_URL. */
|
|
70
|
+
baseUrl: string;
|
|
71
|
+
/** API key, e.g. process.env.APP_API_KEY. Sent as the 'x-api-key' header. */
|
|
72
|
+
apiKey?: string;
|
|
73
|
+
/** Custom fetch (defaults to global fetch). */
|
|
74
|
+
fetch?: typeof fetch;
|
|
75
|
+
/** Extra headers merged into every request. */
|
|
76
|
+
headers?: Record<string, string>;
|
|
77
|
+
}
|
|
78
|
+
export declare class ApiError extends Error {
|
|
79
|
+
readonly status: number;
|
|
80
|
+
readonly body: unknown;
|
|
81
|
+
constructor(status: number, message: string, body: unknown);
|
|
82
|
+
}
|
|
83
|
+
export declare class RecordingsV1Client {
|
|
84
|
+
private readonly baseUrl;
|
|
85
|
+
private readonly apiKey;
|
|
86
|
+
private readonly fetchImpl;
|
|
87
|
+
private readonly baseHeaders;
|
|
88
|
+
constructor(options: RecordingsV1ClientOptions);
|
|
89
|
+
private request;
|
|
90
|
+
/** List agents */
|
|
91
|
+
listAgents(init?: RequestInit): Promise<{
|
|
92
|
+
"agents"?: Array<Agent>;
|
|
93
|
+
"count"?: number;
|
|
94
|
+
}>;
|
|
95
|
+
/** Register (upsert) an agent */
|
|
96
|
+
registerAgent(body: RegisterAgentInput, init?: RequestInit): Promise<{
|
|
97
|
+
"agent"?: Agent;
|
|
98
|
+
}>;
|
|
99
|
+
/** Get an agent by id or name */
|
|
100
|
+
getAgent(id: string, init?: RequestInit): Promise<{
|
|
101
|
+
"agent"?: Agent;
|
|
102
|
+
}>;
|
|
103
|
+
/** List projects */
|
|
104
|
+
listProjects(init?: RequestInit): Promise<{
|
|
105
|
+
"projects"?: Array<Project>;
|
|
106
|
+
"count"?: number;
|
|
107
|
+
}>;
|
|
108
|
+
/** Register (upsert) a project */
|
|
109
|
+
registerProject(body: RegisterProjectInput, init?: RequestInit): Promise<{
|
|
110
|
+
"project"?: Project;
|
|
111
|
+
}>;
|
|
112
|
+
/** Get a project by id or path */
|
|
113
|
+
getProject(id: string, init?: RequestInit): Promise<{
|
|
114
|
+
"project"?: Project;
|
|
115
|
+
}>;
|
|
116
|
+
/** List recordings */
|
|
117
|
+
listRecordings(query?: {
|
|
118
|
+
"agent_id"?: string;
|
|
119
|
+
"project_id"?: string;
|
|
120
|
+
"session_id"?: string;
|
|
121
|
+
"processing_mode"?: "raw" | "enhanced";
|
|
122
|
+
"search"?: string;
|
|
123
|
+
"limit"?: number;
|
|
124
|
+
"offset"?: number;
|
|
125
|
+
}, init?: RequestInit): Promise<{
|
|
126
|
+
"recordings"?: Array<Recording>;
|
|
127
|
+
"count"?: number;
|
|
128
|
+
}>;
|
|
129
|
+
/** Create a recording */
|
|
130
|
+
createRecording(body: CreateRecordingInput, init?: RequestInit): Promise<{
|
|
131
|
+
"recording"?: Recording;
|
|
132
|
+
}>;
|
|
133
|
+
/** Get a recording by id */
|
|
134
|
+
getRecording(id: string, init?: RequestInit): Promise<{
|
|
135
|
+
"recording"?: Recording;
|
|
136
|
+
}>;
|
|
137
|
+
/** Delete a recording by id */
|
|
138
|
+
deleteRecording(id: string, init?: RequestInit): Promise<{
|
|
139
|
+
"deleted"?: boolean;
|
|
140
|
+
}>;
|
|
141
|
+
/** Aggregate recording statistics */
|
|
142
|
+
getRecordingStats(init?: RequestInit): Promise<{
|
|
143
|
+
"total"?: number;
|
|
144
|
+
"raw"?: number;
|
|
145
|
+
"enhanced"?: number;
|
|
146
|
+
"total_duration_ms"?: number;
|
|
147
|
+
"by_model"?: Record<string, number>;
|
|
148
|
+
}>;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=v1.generated.d.ts.map
|