@amerged/ohmyhost-mcp 0.1.38 → 0.1.40
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 +1 -1
- package/THIRD_PARTY_NOTICES.md +26 -0
- package/dist/{chunk-Z7AT2PTU.js → chunk-OW4IDEWK.js} +11 -11
- package/dist/index.js +1 -1
- package/dist/licenses/pgcf-bridge-LICENSE +201 -0
- package/dist/licenses/pgcf-bridge-NOTICE +1 -0
- package/dist/stdio-main.js +3847 -32
- package/package.json +1 -1
- package/src/apps/mcp/package.json +1 -1
- package/src/apps/mcp/src/local-client.ts +15 -9
- package/src/apps/mcp/src/local-server.ts +36 -18
- package/src/apps/product-cli/package.json +3 -2
- package/src/apps/product-cli/src/cli.ts +7 -5
- package/src/apps/product-cli/src/command.ts +18 -5
- package/src/apps/product-cli/src/product-api.ts +22 -15
- package/src/apps/product-cli/src/psql-session.ts +54 -19
- package/src/packages/agent-skills/src/generated-skill-resources.ts +10 -10
- package/src/packages/contracts/package.json +5 -0
- package/src/packages/contracts/src/credit-pricing.ts +7 -1
- package/src/packages/contracts/src/database-access.ts +53 -12
- package/src/packages/contracts/src/database-compute.ts +66 -11
- package/src/packages/contracts/src/database-sizes.ts +114 -0
- package/src/packages/contracts/src/framework-admission.ts +1 -1
- package/src/packages/contracts/src/framework-source-rules.ts +1 -1
- package/src/packages/contracts/src/index.ts +1 -1
- package/src/packages/contracts/src/operation-failure.ts +2 -2
- package/src/packages/contracts/src/platform-origins.ts +8 -0
- package/src/packages/contracts/src/problem-policy.ts +16 -2
- package/src/packages/contracts/src/storage-gateway-origin.ts +93 -0
- package/src/packages/postgres-bridge/LICENSE +201 -0
- package/src/packages/postgres-bridge/NOTICE +1 -0
- package/src/packages/postgres-bridge/package.json +26 -0
- package/src/packages/postgres-bridge/src/auth.ts +159 -0
- package/src/packages/postgres-bridge/src/bridge.ts +168 -0
- package/src/packages/postgres-bridge/src/index.ts +2 -0
- package/src/packages/postgres-bridge/src/options.ts +49 -0
- package/src/packages/sdk-ts/package.json +1 -1
- package/src/packages/sdk-ts/src/generated/index.ts +1 -0
- package/src/packages/sdk-ts/src/generated/sdk.gen.ts +9 -8
- package/src/packages/sdk-ts/src/generated/types.gen.ts +91 -24
- package/src/packages/sdk-ts/src/index.ts +1 -0
- package/src/packages/sdk-ts/src/managed-mail-attachment.ts +107 -0
|
@@ -376,9 +376,9 @@ export type PublishedCreditRateCard = {
|
|
|
376
376
|
unit: string;
|
|
377
377
|
units_per_charge: string;
|
|
378
378
|
/**
|
|
379
|
-
* Provider list-cost basis for units_per_charge, in USD micro-units (1000000 equals 1 USD), before shared allowances and discounts.
|
|
379
|
+
* Provider list-cost basis for units_per_charge, in USD micro-units (1000000 equals 1 USD), before shared allowances and discounts. Null for the PGCF RAM tariff means node infrastructure costs are tracked separately and are not allocated to this customer rate; null never means zero cost.
|
|
380
380
|
*/
|
|
381
|
-
provider_cost_micros: string;
|
|
381
|
+
provider_cost_micros: string | null;
|
|
382
382
|
credit_micros: CreditMicros;
|
|
383
383
|
}>;
|
|
384
384
|
};
|
|
@@ -894,13 +894,29 @@ export type ProjectDatabaseAccessRequest = {
|
|
|
894
894
|
label?: string | null;
|
|
895
895
|
};
|
|
896
896
|
|
|
897
|
-
export type ProjectDatabaseAccess =
|
|
897
|
+
export type ProjectDatabaseAccess = (
|
|
898
|
+
| {
|
|
899
|
+
database?: "neondb";
|
|
900
|
+
}
|
|
901
|
+
| {
|
|
902
|
+
database?: unknown;
|
|
903
|
+
}
|
|
904
|
+
) & {
|
|
898
905
|
access_id: Ulid;
|
|
899
906
|
environment: "dev" | "prod";
|
|
900
907
|
mode: "read" | "write";
|
|
901
908
|
role_name: string;
|
|
902
909
|
host: string;
|
|
903
|
-
|
|
910
|
+
/**
|
|
911
|
+
* neondb for a transitional Neon credential; the exact 20-character PGCF database identity for WSS.
|
|
912
|
+
*/
|
|
913
|
+
database: string;
|
|
914
|
+
provider?: "pgcf";
|
|
915
|
+
transport?: "wss";
|
|
916
|
+
/**
|
|
917
|
+
* Verified WSS origin ending in / and matching host. The local bridge adds /v2 and the bound database and user; no public PostgreSQL TCP endpoint.
|
|
918
|
+
*/
|
|
919
|
+
websocket_url?: string;
|
|
904
920
|
label: string | null;
|
|
905
921
|
state: "active" | "expired" | "revoked";
|
|
906
922
|
issued_at: string;
|
|
@@ -909,13 +925,41 @@ export type ProjectDatabaseAccess = {
|
|
|
909
925
|
revocation_reason: "principal" | "expired" | "budget" | "creation_failed" | "data_change" | null;
|
|
910
926
|
};
|
|
911
927
|
|
|
912
|
-
export type ProjectDatabaseAccessCredential =
|
|
928
|
+
export type ProjectDatabaseAccessCredential = (
|
|
929
|
+
| {
|
|
930
|
+
database?: "neondb";
|
|
931
|
+
}
|
|
932
|
+
| {
|
|
933
|
+
database?: unknown;
|
|
934
|
+
}
|
|
935
|
+
) & {
|
|
936
|
+
access_id: Ulid;
|
|
937
|
+
environment: "dev" | "prod";
|
|
938
|
+
mode: "read" | "write";
|
|
939
|
+
role_name: string;
|
|
940
|
+
host: string;
|
|
913
941
|
/**
|
|
914
|
-
*
|
|
942
|
+
* neondb for a transitional Neon credential; the exact 20-character PGCF database identity for WSS.
|
|
943
|
+
*/
|
|
944
|
+
database: string;
|
|
945
|
+
provider?: "pgcf";
|
|
946
|
+
transport?: "wss";
|
|
947
|
+
/**
|
|
948
|
+
* Verified WSS origin ending in / and matching host. The local bridge adds /v2 and the bound database and user; no public PostgreSQL TCP endpoint.
|
|
949
|
+
*/
|
|
950
|
+
websocket_url?: string;
|
|
951
|
+
label: string | null;
|
|
952
|
+
state: "active" | "expired" | "revoked";
|
|
953
|
+
issued_at: string;
|
|
954
|
+
expires_at: string;
|
|
955
|
+
revoked_at: string | null;
|
|
956
|
+
revocation_reason: "principal" | "expired" | "budget" | "creation_failed" | "data_change" | null;
|
|
957
|
+
/**
|
|
958
|
+
* Returned once as credential material. For PGCF this identifies a WSS transport, never direct public TCP. Never place it in command arguments, files, notes or source.
|
|
915
959
|
*/
|
|
916
960
|
connection_uri: string;
|
|
917
961
|
/**
|
|
918
|
-
*
|
|
962
|
+
* For PGCF, a secret-free ohmyhost database psql invocation that obtains and revokes its own session credential. Transitional Neon responses retain their original direct invocation.
|
|
919
963
|
*/
|
|
920
964
|
psql_command: string;
|
|
921
965
|
};
|
|
@@ -1102,7 +1146,7 @@ export type Sha256Digest = string;
|
|
|
1102
1146
|
export type ProjectDataMode = "shared" | "isolated";
|
|
1103
1147
|
|
|
1104
1148
|
/**
|
|
1105
|
-
* Chosen
|
|
1149
|
+
* Chosen at project creation and immutable through customer operations. us (default) or eu places new build resources and, when no storage is already assigned, new file buckets. Existing buckets, source repositories and historical artifacts retain their recorded locations independently of a platform-authorized project-region migration. New PGCF application databases follow the selected project region; existing owner-authorized migrations target US1. Read database compute for the actual database region. storage.jurisdiction must match the project's recorded storage location, or this region when no storage custody exists. Project context reports the authoritative storage jurisdiction. Prices are identical in both project regions.
|
|
1106
1150
|
*/
|
|
1107
1151
|
export type HostingRegion = "us" | "eu";
|
|
1108
1152
|
|
|
@@ -1362,6 +1406,8 @@ export type ProblemDetails = {
|
|
|
1362
1406
|
| "paid_plan_required"
|
|
1363
1407
|
| "project_budget_exceeded"
|
|
1364
1408
|
| "compute_performance_paid_required"
|
|
1409
|
+
| "compute_paid_required"
|
|
1410
|
+
| "compute_storage_shrink_requires_migration"
|
|
1365
1411
|
| "compute_performance_unavailable"
|
|
1366
1412
|
| "database_write_pending"
|
|
1367
1413
|
| "database_access_limit"
|
|
@@ -1486,20 +1532,40 @@ export type DatabaseCompute = {
|
|
|
1486
1532
|
environment: "dev" | "prod";
|
|
1487
1533
|
data_mode: "shared" | "isolated";
|
|
1488
1534
|
observed_at: string;
|
|
1489
|
-
database:
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1535
|
+
database:
|
|
1536
|
+
| null
|
|
1537
|
+
| FixedDatabaseCompute
|
|
1538
|
+
| {
|
|
1539
|
+
min_cu: number;
|
|
1540
|
+
max_cu: number;
|
|
1541
|
+
min_memory_gb: number;
|
|
1542
|
+
max_memory_gb: number;
|
|
1543
|
+
/**
|
|
1544
|
+
* Configured timeout: 0 is provider default; -1 disables suspension.
|
|
1545
|
+
*/
|
|
1546
|
+
suspend_timeout_seconds: number;
|
|
1547
|
+
state: "init" | "active" | "idle";
|
|
1548
|
+
pending_state: "init" | "active" | "idle" | null;
|
|
1549
|
+
disabled: boolean;
|
|
1550
|
+
region: string;
|
|
1551
|
+
};
|
|
1552
|
+
};
|
|
1553
|
+
|
|
1554
|
+
/**
|
|
1555
|
+
* Fixed resources; storage includes engine and WAL overhead. First provisioning is distinct from a sleeping database.
|
|
1556
|
+
*/
|
|
1557
|
+
export type FixedDatabaseCompute = {
|
|
1558
|
+
provider: "pgcf";
|
|
1559
|
+
size_class_id: "r256-s500m" | "r512-s1g" | "r1024-s2g" | "r2048-s4g" | "r4096-s8g";
|
|
1560
|
+
memory_mib: 256 | 512 | 1024 | 2048 | 4096;
|
|
1561
|
+
cpu_millicores: 250 | 500 | 1000 | 2000;
|
|
1562
|
+
storage_mib: 500 | 1024 | 2048 | 4096 | 8192;
|
|
1563
|
+
max_connections: 20 | 40 | 80 | 160 | 200;
|
|
1564
|
+
suspend_timeout_seconds: number;
|
|
1565
|
+
state: "provisioning" | "cold" | "warm" | "suspended" | "error";
|
|
1566
|
+
pending_state: "provisioning" | "cold" | "warm" | "suspended" | "error" | null;
|
|
1567
|
+
disabled: boolean;
|
|
1568
|
+
region: "us" | "eu";
|
|
1503
1569
|
};
|
|
1504
1570
|
|
|
1505
1571
|
export type ProjectContext = {
|
|
@@ -7457,9 +7523,10 @@ export type GetDatabaseComputeResponse =
|
|
|
7457
7523
|
GetDatabaseComputeResponses[keyof GetDatabaseComputeResponses];
|
|
7458
7524
|
|
|
7459
7525
|
export type ChangeDatabaseComputeData = {
|
|
7460
|
-
body: {
|
|
7526
|
+
body: unknown & {
|
|
7461
7527
|
environment: "dev" | "prod";
|
|
7462
|
-
profile
|
|
7528
|
+
profile?: "standard" | "performance";
|
|
7529
|
+
memory_mib?: 256 | 512 | 1024 | 2048 | 4096;
|
|
7463
7530
|
confirm: true;
|
|
7464
7531
|
};
|
|
7465
7532
|
headers: {
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { Client } from "./generated/client/index.js";
|
|
2
|
+
import { getManagedMailAttachment } from "./generated/sdk.gen.js";
|
|
3
|
+
|
|
4
|
+
export interface ManagedMailAttachmentDownload {
|
|
5
|
+
readonly projectId: string;
|
|
6
|
+
readonly environmentId: string;
|
|
7
|
+
readonly messageId: string;
|
|
8
|
+
readonly attachmentId: string;
|
|
9
|
+
readonly signal?: AbortSignal;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type ManagedMailAttachmentResult =
|
|
13
|
+
| Readonly<{ status: "expired" }>
|
|
14
|
+
| Readonly<{ status: "download"; response: Response; body: ReadableStream<Uint8Array> }>;
|
|
15
|
+
|
|
16
|
+
/** Uses the generated authenticated GET without its automatic binary-to-Blob parser. */
|
|
17
|
+
export async function downloadManagedMailAttachment(
|
|
18
|
+
client: Client,
|
|
19
|
+
input: ManagedMailAttachmentDownload,
|
|
20
|
+
): Promise<ManagedMailAttachmentResult> {
|
|
21
|
+
if (
|
|
22
|
+
![input.projectId, input.environmentId, input.messageId].every((id) =>
|
|
23
|
+
/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(id),
|
|
24
|
+
) ||
|
|
25
|
+
!/^[A-Za-z0-9_-]{1,128}$/u.test(input.attachmentId)
|
|
26
|
+
)
|
|
27
|
+
invalid();
|
|
28
|
+
// The generator's return type is fixed to data-only, despite supporting this explicit fields option.
|
|
29
|
+
const result = (await getManagedMailAttachment(
|
|
30
|
+
{
|
|
31
|
+
project_id: input.projectId,
|
|
32
|
+
environment_id: input.environmentId,
|
|
33
|
+
message_id: input.messageId,
|
|
34
|
+
attachment_id: input.attachmentId,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
client,
|
|
38
|
+
parseAs: "stream",
|
|
39
|
+
responseStyle: "fields",
|
|
40
|
+
throwOnError: true,
|
|
41
|
+
signal: input.signal,
|
|
42
|
+
},
|
|
43
|
+
)) as unknown as { response: Response; data: unknown };
|
|
44
|
+
const response = result.response;
|
|
45
|
+
if (
|
|
46
|
+
!(response instanceof Response) ||
|
|
47
|
+
response.status !== 200 ||
|
|
48
|
+
response.body === null ||
|
|
49
|
+
result.data !== response.body
|
|
50
|
+
)
|
|
51
|
+
invalid();
|
|
52
|
+
const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
|
|
53
|
+
if (contentType === "application/octet-stream") {
|
|
54
|
+
return Object.freeze({ status: "download", response, body: response.body });
|
|
55
|
+
}
|
|
56
|
+
if (contentType !== "application/json") {
|
|
57
|
+
void response.body.cancel().catch(ignoreCancellationError);
|
|
58
|
+
invalid();
|
|
59
|
+
}
|
|
60
|
+
const declared = response.headers.get("content-length");
|
|
61
|
+
if (declared !== null && (!/^[0-9]+$/u.test(declared) || Number(declared) > 1024)) {
|
|
62
|
+
void response.body.cancel().catch(ignoreCancellationError);
|
|
63
|
+
invalid();
|
|
64
|
+
}
|
|
65
|
+
const reader = response.body.getReader();
|
|
66
|
+
const bytes = new Uint8Array(1024);
|
|
67
|
+
let length = 0;
|
|
68
|
+
let finished = false;
|
|
69
|
+
try {
|
|
70
|
+
for (;;) {
|
|
71
|
+
const next = await reader.read();
|
|
72
|
+
if (next.done) {
|
|
73
|
+
finished = true;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
if (!(next.value instanceof Uint8Array) || length + next.value.byteLength > bytes.byteLength)
|
|
77
|
+
invalid();
|
|
78
|
+
bytes.set(next.value, length);
|
|
79
|
+
length += next.value.byteLength;
|
|
80
|
+
}
|
|
81
|
+
const value: unknown = JSON.parse(
|
|
82
|
+
new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, length)),
|
|
83
|
+
);
|
|
84
|
+
if (
|
|
85
|
+
typeof value !== "object" ||
|
|
86
|
+
value === null ||
|
|
87
|
+
Array.isArray(value) ||
|
|
88
|
+
Object.keys(value).length !== 1 ||
|
|
89
|
+
(value as Record<string, unknown>)["status"] !== "expired"
|
|
90
|
+
)
|
|
91
|
+
invalid();
|
|
92
|
+
return Object.freeze({ status: "expired" });
|
|
93
|
+
} catch {
|
|
94
|
+
return invalid();
|
|
95
|
+
} finally {
|
|
96
|
+
if (!finished) void reader.cancel().catch(ignoreCancellationError);
|
|
97
|
+
reader.releaseLock();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function invalid(): never {
|
|
102
|
+
throw new Error("Mail attachment response contract invalid");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function ignoreCancellationError(): void {
|
|
106
|
+
// Cleanup cannot replace the response contract failure.
|
|
107
|
+
}
|