@amerged/ohmyhost-mcp 0.1.28 → 0.1.29

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.
Files changed (32) hide show
  1. package/README.md +1 -1
  2. package/THIRD_PARTY_NOTICES.md +1419 -0
  3. package/dist/{chunk-GIP4M4CK.js → chunk-BWVBJWRR.js} +67 -21
  4. package/dist/index.js +1 -1
  5. package/dist/stdio-main.js +24152 -2353
  6. package/package.json +1 -1
  7. package/src/apps/mcp/package.json +1 -1
  8. package/src/apps/mcp/src/local-client.ts +12 -2
  9. package/src/apps/mcp/src/local-server.ts +333 -4
  10. package/src/apps/product-cli/package.json +4 -2
  11. package/src/apps/product-cli/src/cli.ts +312 -2
  12. package/src/apps/product-cli/src/command.ts +261 -0
  13. package/src/apps/product-cli/src/composition.ts +74 -4
  14. package/src/apps/product-cli/src/index.ts +6 -0
  15. package/src/apps/product-cli/src/product-api.ts +5 -0
  16. package/src/apps/product-cli/src/project-link-store.ts +92 -1
  17. package/src/apps/product-cli/src/runtime-contract.ts +34 -1
  18. package/src/apps/product-cli/src/source-managed-client.ts +189 -0
  19. package/src/apps/product-cli/src/source-publication-store.ts +563 -0
  20. package/src/apps/product-cli/src/source-publisher.ts +195 -0
  21. package/src/apps/product-cli/src/source-workspace.ts +552 -0
  22. package/src/packages/agent-skills/src/generated-skill-resources.ts +18 -8
  23. package/src/packages/contracts/package.json +10 -0
  24. package/src/packages/contracts/src/managed-sources.ts +582 -0
  25. package/src/packages/contracts/src/mcp-source-codec.ts +150 -0
  26. package/src/packages/contracts/src/operation-failure.ts +22 -6
  27. package/src/packages/contracts/src/problem-policy.ts +61 -14
  28. package/src/packages/sdk-ts/package.json +1 -1
  29. package/src/packages/sdk-ts/src/generated/index.ts +92 -0
  30. package/src/packages/sdk-ts/src/generated/sdk.gen.ts +541 -0
  31. package/src/packages/sdk-ts/src/generated/types.gen.ts +911 -4
  32. package/src/packages/workos-auth-contracts/src/tokens.ts +61 -4
@@ -0,0 +1,195 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ import {
4
+ assertManagedSourceResponse,
5
+ parseManagedSourceRequest,
6
+ type ManagedSourceBlobRequest,
7
+ type ManagedSourceChangesRequest,
8
+ type ManagedSourceFinalizeRequest,
9
+ type ManagedSourceInitializeRequest,
10
+ type ManagedSourceRestoreRequest,
11
+ type ManagedSourceSwitchRequest,
12
+ type ManagedSourceUploadReceipt,
13
+ type ManagedSourceUploadRequest,
14
+ } from "@ohmyhost/contracts/managed-sources";
15
+ import type { Operation } from "@ohmyhost/sdk-ts";
16
+
17
+ import { parseOperation, ResponseContractError } from "./runtime-contract.js";
18
+ import type { SourceSnapshot } from "./source-workspace.js";
19
+
20
+ /** Product operations only. The composition supplies the generated SDK and its current login. */
21
+ export interface ManagedSourceApi {
22
+ getSource(projectId: string): Promise<unknown>;
23
+ initialize(input: {
24
+ projectId: string;
25
+ idempotencyKey: string;
26
+ body: ManagedSourceInitializeRequest;
27
+ }): Promise<Operation>;
28
+ files(input: { projectId: string; commitSha?: string; path?: string }): Promise<unknown>;
29
+ versions(input: {
30
+ projectId: string;
31
+ limit?: number;
32
+ beforeCommitSha?: string;
33
+ }): Promise<unknown>;
34
+ diff(input: { projectId: string; fromCommitSha: string; toCommitSha: string }): Promise<unknown>;
35
+ changes(input: {
36
+ projectId: string;
37
+ idempotencyKey: string;
38
+ body: ManagedSourceChangesRequest;
39
+ }): Promise<Operation>;
40
+ restore(input: {
41
+ projectId: string;
42
+ idempotencyKey: string;
43
+ body: ManagedSourceRestoreRequest;
44
+ }): Promise<Operation>;
45
+ createUpload(input: {
46
+ projectId: string;
47
+ idempotencyKey: string;
48
+ body: ManagedSourceUploadRequest;
49
+ }): Promise<Operation>;
50
+ getUpload(input: { projectId: string; operationId: string }): Promise<ManagedSourceUploadReceipt>;
51
+ putBlob(input: {
52
+ projectId: string;
53
+ operationId: string;
54
+ idempotencyKey: string;
55
+ body: ManagedSourceBlobRequest;
56
+ }): Promise<unknown>;
57
+ commitUpload(input: {
58
+ projectId: string;
59
+ operationId: string;
60
+ idempotencyKey: string;
61
+ body: ManagedSourceFinalizeRequest;
62
+ }): Promise<Operation>;
63
+ switchSource(input: {
64
+ projectId: string;
65
+ idempotencyKey: string;
66
+ body: ManagedSourceSwitchRequest;
67
+ }): Promise<Operation>;
68
+ }
69
+
70
+ export function isSourcePublicationIdempotencyKey(value: unknown): value is string {
71
+ return (
72
+ typeof value === "string" &&
73
+ value.length > 0 &&
74
+ value.length <= 128 &&
75
+ value === value.trim() &&
76
+ !/[^\x20-\xff]/u.test(value) &&
77
+ !/\p{Cc}/u.test(value)
78
+ );
79
+ }
80
+
81
+ /** One stable current-file snapshot is staged and finalized as one source operation. */
82
+ export async function publishSourceSnapshot(input: {
83
+ readonly api: ManagedSourceApi;
84
+ readonly projectId: string;
85
+ readonly request: ManagedSourceUploadRequest;
86
+ readonly snapshot: SourceSnapshot;
87
+ readonly idempotencyKey: string;
88
+ readonly signal: AbortSignal;
89
+ readonly accepted?: (operation: Operation) => Promise<void>;
90
+ readonly rejected?: (error: unknown) => Promise<void>;
91
+ }): Promise<{ readonly operation: Operation; readonly receipt: ManagedSourceUploadReceipt }> {
92
+ if (!isSourcePublicationIdempotencyKey(input.idempotencyKey))
93
+ throw new TypeError("Managed source publication input is invalid");
94
+ parseManagedSourceRequest("upload", input.request);
95
+ const files = input.snapshot.files.map((file) => ({
96
+ path: file.path,
97
+ sha256: file.sha256,
98
+ byte_length: file.byteLength,
99
+ executable: file.executable,
100
+ }));
101
+ const manifest = parseManagedSourceRequest("finalize", {
102
+ files,
103
+ expected_source_generation: input.request.expected_source_generation,
104
+ });
105
+ input.signal.throwIfAborted();
106
+ let accepted: Operation;
107
+ try {
108
+ accepted = await input.api.createUpload({
109
+ projectId: input.projectId,
110
+ body: input.request,
111
+ idempotencyKey: input.idempotencyKey,
112
+ });
113
+ } catch (error) {
114
+ await input.rejected?.(error);
115
+ throw error;
116
+ }
117
+ parseOperation(accepted);
118
+ await input.accepted?.(accepted);
119
+ const receipt = await input.api.getUpload({
120
+ projectId: input.projectId,
121
+ operationId: accepted.id,
122
+ });
123
+ assertManagedSourceResponse("upload", receipt);
124
+ if (
125
+ receipt.operation_id !== accepted.id ||
126
+ receipt.expected_source_generation !== input.request.expected_source_generation ||
127
+ receipt.expected_commit_sha !== input.request.expected_commit_sha
128
+ )
129
+ throw new ResponseContractError();
130
+ // A lost finalize response must be observed under the same operation, never uploaded again.
131
+ if (receipt.state !== "staging") return { operation: accepted, receipt };
132
+ for (const file of input.snapshot.files) {
133
+ input.signal.throwIfAborted();
134
+ const body = parseManagedSourceRequest("blob", {
135
+ path: file.path,
136
+ content_base64: file.contentBase64,
137
+ sha256: file.sha256,
138
+ executable: file.executable,
139
+ });
140
+ const stored = await input.api.putBlob({
141
+ projectId: input.projectId,
142
+ operationId: accepted.id,
143
+ body,
144
+ idempotencyKey: stepKey(input.idempotencyKey, input.snapshot.sha256, file.path),
145
+ });
146
+ assertManagedSourceResponse("blob", stored);
147
+ const value = stored as Record<string, unknown>;
148
+ if (
149
+ value["path"] !== file.path ||
150
+ value["sha256"] !== file.sha256 ||
151
+ value["byte_length"] !== file.byteLength ||
152
+ value["executable"] !== file.executable
153
+ )
154
+ throw new ResponseContractError();
155
+ }
156
+ input.signal.throwIfAborted();
157
+ const idempotencyKey = stepKey(input.idempotencyKey, input.snapshot.sha256, "finalize");
158
+ const operation =
159
+ input.request.mode === "switch"
160
+ ? await input.api.switchSource({
161
+ projectId: input.projectId,
162
+ idempotencyKey,
163
+ body: parseManagedSourceRequest("switch", {
164
+ ...manifest,
165
+ upload_operation_id: accepted.id,
166
+ expected_source_connection_id: input.request.expected_source_connection_id,
167
+ }),
168
+ })
169
+ : await input.api.commitUpload({
170
+ projectId: input.projectId,
171
+ operationId: accepted.id,
172
+ idempotencyKey,
173
+ body: manifest,
174
+ });
175
+ parseOperation(operation);
176
+ if (operation.id !== accepted.id) throw new ResponseContractError();
177
+ const completed = await input.api.getUpload({
178
+ projectId: input.projectId,
179
+ operationId: operation.id,
180
+ });
181
+ assertManagedSourceResponse("upload", completed);
182
+ if (
183
+ completed.operation_id !== operation.id ||
184
+ completed.expected_source_generation !== input.request.expected_source_generation ||
185
+ completed.expected_commit_sha !== input.request.expected_commit_sha
186
+ )
187
+ throw new ResponseContractError();
188
+ return { operation, receipt: completed };
189
+ }
190
+
191
+ function stepKey(key: string, snapshot: string, step: string): string {
192
+ return `source-${createHash("sha256")
193
+ .update(JSON.stringify([key, snapshot, step]))
194
+ .digest("hex")}`;
195
+ }