@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.
- package/README.md +1 -1
- package/THIRD_PARTY_NOTICES.md +1419 -0
- package/dist/{chunk-GIP4M4CK.js → chunk-BWVBJWRR.js} +67 -21
- package/dist/index.js +1 -1
- package/dist/stdio-main.js +24152 -2353
- package/package.json +1 -1
- package/src/apps/mcp/package.json +1 -1
- package/src/apps/mcp/src/local-client.ts +12 -2
- package/src/apps/mcp/src/local-server.ts +333 -4
- package/src/apps/product-cli/package.json +4 -2
- package/src/apps/product-cli/src/cli.ts +312 -2
- package/src/apps/product-cli/src/command.ts +261 -0
- package/src/apps/product-cli/src/composition.ts +74 -4
- package/src/apps/product-cli/src/index.ts +6 -0
- package/src/apps/product-cli/src/product-api.ts +5 -0
- package/src/apps/product-cli/src/project-link-store.ts +92 -1
- package/src/apps/product-cli/src/runtime-contract.ts +34 -1
- package/src/apps/product-cli/src/source-managed-client.ts +189 -0
- package/src/apps/product-cli/src/source-publication-store.ts +563 -0
- package/src/apps/product-cli/src/source-publisher.ts +195 -0
- package/src/apps/product-cli/src/source-workspace.ts +552 -0
- package/src/packages/agent-skills/src/generated-skill-resources.ts +18 -8
- package/src/packages/contracts/package.json +10 -0
- package/src/packages/contracts/src/managed-sources.ts +582 -0
- package/src/packages/contracts/src/mcp-source-codec.ts +150 -0
- package/src/packages/contracts/src/operation-failure.ts +22 -6
- package/src/packages/contracts/src/problem-policy.ts +61 -14
- package/src/packages/sdk-ts/package.json +1 -1
- package/src/packages/sdk-ts/src/generated/index.ts +92 -0
- package/src/packages/sdk-ts/src/generated/sdk.gen.ts +541 -0
- package/src/packages/sdk-ts/src/generated/types.gen.ts +911 -4
- package/src/packages/workos-auth-contracts/src/tokens.ts +61 -4
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
import { open } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import {
|
|
4
|
+
assertManagedSourceResponse,
|
|
5
|
+
type ManagedProjectSource,
|
|
6
|
+
} from "@ohmyhost/contracts/managed-sources";
|
|
7
|
+
import {
|
|
8
|
+
createSourceSnapshot,
|
|
9
|
+
inspectSourceWorkspace,
|
|
10
|
+
SourceWorkspaceError,
|
|
11
|
+
type SourceWorkspace,
|
|
12
|
+
} from "./source-workspace.js";
|
|
13
|
+
import { publishSourceSnapshot } from "./source-publisher.js";
|
|
14
|
+
import {
|
|
15
|
+
prepareLocalSourcePublication,
|
|
16
|
+
completeLocalSourcePublication,
|
|
17
|
+
inspectLocalSourcePublications,
|
|
18
|
+
LocalSourcePublicationError,
|
|
19
|
+
type LocalSourceMetadataDirectory,
|
|
20
|
+
} from "./source-publication-store.js";
|
|
21
|
+
import { readProjectLinks } from "./project-link-store.js";
|
|
2
22
|
import {
|
|
3
23
|
parseProjectDatabaseWrite,
|
|
4
24
|
assertProjectDatabaseWriteReceipt,
|
|
@@ -94,6 +114,7 @@ import {
|
|
|
94
114
|
parseOperationEvent,
|
|
95
115
|
parseProjectPage,
|
|
96
116
|
parseProjectStatus,
|
|
117
|
+
parseProjectSourceBinding,
|
|
97
118
|
parseProjectDatabaseQuery,
|
|
98
119
|
parsePaidDomain,
|
|
99
120
|
parsePaidDomainPlan,
|
|
@@ -212,6 +233,11 @@ export class PublicResponseTooLargeError extends Error {
|
|
|
212
233
|
}
|
|
213
234
|
|
|
214
235
|
export interface ProductCliDependencies {
|
|
236
|
+
readonly sourceDirectory?: string;
|
|
237
|
+
readonly sourceMetadataDirectory?: LocalSourceMetadataDirectory;
|
|
238
|
+
readonly sourceWorkspace?: () => Promise<SourceWorkspace>;
|
|
239
|
+
readonly linkedSourceProvider?: "github" | "managed";
|
|
240
|
+
readonly linkedProjectId?: string;
|
|
215
241
|
readonly apiToken?: string;
|
|
216
242
|
readonly commandPrefix: string;
|
|
217
243
|
/** One credential store for a run without saved logins; a chosen saved login uses its own. */
|
|
@@ -234,11 +260,15 @@ export interface ProductCliDependencies {
|
|
|
234
260
|
* keeping product mutation capabilities out of login.
|
|
235
261
|
*/
|
|
236
262
|
readonly accountProfile: (accessToken: () => Promise<string>) => Promise<PublicAccount>;
|
|
237
|
-
/** Optional onboarding guidance
|
|
263
|
+
/** Optional onboarding guidance uses only these narrow read-only SDK queries. */
|
|
238
264
|
readonly githubConnectionStatus?: (
|
|
239
265
|
accessToken: () => Promise<string>,
|
|
240
266
|
organizationId: string,
|
|
241
267
|
) => ReturnType<ProductApi["getGithubConnection"]>;
|
|
268
|
+
readonly projectSourceStatus?: (
|
|
269
|
+
accessToken: () => Promise<string>,
|
|
270
|
+
projectId: string,
|
|
271
|
+
) => Promise<unknown>;
|
|
242
272
|
readonly projectLinkStore: ProjectLinkStore;
|
|
243
273
|
readonly productApiOrigin: string;
|
|
244
274
|
readonly tokenRevoker: TokenRevoker;
|
|
@@ -389,6 +419,24 @@ const HELP_USAGE = Object.freeze({
|
|
|
389
419
|
"source auto-deploy set":
|
|
390
420
|
"ohmyhost source auto-deploy set --project ULID --branch BRANCH --enabled true|false --idempotency-key KEY --json",
|
|
391
421
|
"source auto-deploy status": "ohmyhost source auto-deploy status --project ULID --json",
|
|
422
|
+
"source inspect":
|
|
423
|
+
"ohmyhost source inspect [--directory PATH] --json (read local source and sanitized GitHub context without sign-in)",
|
|
424
|
+
"source status": "ohmyhost source status --project ULID --json",
|
|
425
|
+
"source files": "ohmyhost source files --project ULID [--commit SHA] --json",
|
|
426
|
+
"source file": "ohmyhost source file --project ULID --path PATH [--commit SHA] --json",
|
|
427
|
+
"source versions":
|
|
428
|
+
"ohmyhost source versions --project ULID [--limit 1..100] [--before SHA] --json",
|
|
429
|
+
"source diff": "ohmyhost source diff --project ULID --from SHA --to SHA --json",
|
|
430
|
+
"source upload":
|
|
431
|
+
"ohmyhost source upload --project ULID --operation ULID --json (observe the same upload after uncertainty)",
|
|
432
|
+
"source publish":
|
|
433
|
+
"ohmyhost source publish --project ULID --mode initialize|commit|switch [--directory PATH] --expected-source-generation N [--expected-source-connection ULID] [--expected-commit SHA] --message TEXT --idempotency-key KEY [--wait] --json (current files, no history import; one managed commit)",
|
|
434
|
+
"source publish complete":
|
|
435
|
+
"ohmyhost source publish complete --project ULID [--directory PATH] [--operation ULID] --json (confirm the recorded publication and save this directory's own committed base)",
|
|
436
|
+
"source initialize":
|
|
437
|
+
"ohmyhost source initialize --project ULID --template empty|vite-react --expected-source-generation N --idempotency-key KEY [--wait] --json",
|
|
438
|
+
"source restore":
|
|
439
|
+
"ohmyhost source restore --project ULID --expected-source-generation N --expected-commit SHA --restore-commit SHA --message TEXT --idempotency-key KEY [--wait] --json (restore as a new version; publication is separate)",
|
|
392
440
|
"domain cloudflare authorize":
|
|
393
441
|
"ohmyhost domain cloudflare authorize --project ULID --zone ZONE --idempotency-key KEY --json",
|
|
394
442
|
"domain cloudflare status": "ohmyhost domain cloudflare status --project ULID --json",
|
|
@@ -608,6 +656,24 @@ export class ProductCli {
|
|
|
608
656
|
if (command.kind === "help" || command.kind === "version")
|
|
609
657
|
return cliMetadataResult(command.kind, command.kind === "help" ? command.topic : undefined);
|
|
610
658
|
if (command.kind === "init") throw new ProviderCapabilityBlockedError();
|
|
659
|
+
if (command.kind === "source-inspect")
|
|
660
|
+
return success(name, {
|
|
661
|
+
status: "inspected",
|
|
662
|
+
workspace: await inspectSourceWorkspace(
|
|
663
|
+
resolve(this.dependencies.sourceDirectory ?? process.cwd(), command.directory),
|
|
664
|
+
),
|
|
665
|
+
pending_publications: await inspectLocalSourcePublications(
|
|
666
|
+
resolve(this.dependencies.sourceDirectory ?? process.cwd(), command.directory),
|
|
667
|
+
),
|
|
668
|
+
});
|
|
669
|
+
if (
|
|
670
|
+
command.kind === "source-read" ||
|
|
671
|
+
command.kind === "source-publish" ||
|
|
672
|
+
command.kind === "source-initialize" ||
|
|
673
|
+
command.kind === "source-restore" ||
|
|
674
|
+
command.kind === "source-complete"
|
|
675
|
+
)
|
|
676
|
+
return await this.managedSource(command, signal);
|
|
611
677
|
if (
|
|
612
678
|
this.dependencies.apiToken !== undefined &&
|
|
613
679
|
(command.kind === "organization-create" ||
|
|
@@ -1083,12 +1149,31 @@ export class ProductCli {
|
|
|
1083
1149
|
}
|
|
1084
1150
|
|
|
1085
1151
|
private async githubNextAction(
|
|
1086
|
-
api: Pick<ProductApi, "getGithubConnection"
|
|
1152
|
+
api: Pick<ProductApi, "getGithubConnection"> & {
|
|
1153
|
+
readonly managedSource?: Pick<NonNullable<ProductApi["managedSource"]>, "getSource">;
|
|
1154
|
+
},
|
|
1087
1155
|
organizationId: string,
|
|
1088
1156
|
): Promise<Readonly<Record<string, string>>> {
|
|
1089
1157
|
// Optional onboarding guidance must not turn a completed login into failure when
|
|
1090
1158
|
// a scoped key cannot read source connections or the status endpoint is unavailable.
|
|
1091
1159
|
try {
|
|
1160
|
+
let provider = this.dependencies.linkedSourceProvider;
|
|
1161
|
+
if (this.dependencies.linkedProjectId !== undefined) {
|
|
1162
|
+
if (api.managedSource === undefined) return {};
|
|
1163
|
+
const binding = await api.managedSource.getSource(this.dependencies.linkedProjectId);
|
|
1164
|
+
if (binding !== null) parseProjectSourceBinding(binding);
|
|
1165
|
+
provider =
|
|
1166
|
+
binding === null ? undefined : (binding as { provider: "github" | "managed" }).provider;
|
|
1167
|
+
}
|
|
1168
|
+
if (provider === "managed") return {};
|
|
1169
|
+
if (provider !== "github" && this.dependencies.sourceWorkspace !== undefined) {
|
|
1170
|
+
const workspace = await this.dependencies.sourceWorkspace();
|
|
1171
|
+
if (!workspace.git?.remotes.some((remote) => remote.githubRepository !== null))
|
|
1172
|
+
return {
|
|
1173
|
+
next_action:
|
|
1174
|
+
"Ask once whether to deploy directly with ohmyho.st storing the versions or set up GitHub for this project. Inspect current source first; a missing GitHub connection does not require GitHub.",
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1092
1177
|
const github = parseGithubOrganizationConnectionStatus(
|
|
1093
1178
|
await api.getGithubConnection(organizationId),
|
|
1094
1179
|
);
|
|
@@ -1347,6 +1432,7 @@ export class ProductCli {
|
|
|
1347
1432
|
}
|
|
1348
1433
|
this.#profile = profile;
|
|
1349
1434
|
const readGithubConnection = this.dependencies.githubConnectionStatus;
|
|
1435
|
+
const readProjectSource = this.dependencies.projectSourceStatus;
|
|
1350
1436
|
if (organization !== null)
|
|
1351
1437
|
return success("login", {
|
|
1352
1438
|
status: "authenticated",
|
|
@@ -1356,6 +1442,17 @@ export class ProductCli {
|
|
|
1356
1442
|
? {}
|
|
1357
1443
|
: await this.githubNextAction(
|
|
1358
1444
|
{
|
|
1445
|
+
...(readProjectSource === undefined
|
|
1446
|
+
? {}
|
|
1447
|
+
: {
|
|
1448
|
+
managedSource: {
|
|
1449
|
+
getSource: (selectedProjectId) =>
|
|
1450
|
+
readProjectSource(
|
|
1451
|
+
async () => credential.accessToken,
|
|
1452
|
+
selectedProjectId,
|
|
1453
|
+
),
|
|
1454
|
+
},
|
|
1455
|
+
}),
|
|
1359
1456
|
getGithubConnection: (selectedOrganizationId) =>
|
|
1360
1457
|
readGithubConnection(
|
|
1361
1458
|
async () => credential.accessToken,
|
|
@@ -1844,6 +1941,7 @@ export class ProductCli {
|
|
|
1844
1941
|
if (
|
|
1845
1942
|
project.project_id !== command.projectId ||
|
|
1846
1943
|
source === null ||
|
|
1944
|
+
source.provider !== "github" ||
|
|
1847
1945
|
source.status !== "ready" ||
|
|
1848
1946
|
source.repository_full_name.toLowerCase() !==
|
|
1849
1947
|
`${command.repositoryOwner}/${command.repositoryName}`.toLowerCase()
|
|
@@ -1866,6 +1964,201 @@ export class ProductCli {
|
|
|
1866
1964
|
return success("link", { status: "completed", operation, organization_id: organizationId });
|
|
1867
1965
|
}
|
|
1868
1966
|
|
|
1967
|
+
private async managedSource(
|
|
1968
|
+
command: Extract<
|
|
1969
|
+
ProductCliCommand,
|
|
1970
|
+
{
|
|
1971
|
+
kind:
|
|
1972
|
+
| "source-read"
|
|
1973
|
+
| "source-publish"
|
|
1974
|
+
| "source-initialize"
|
|
1975
|
+
| "source-restore"
|
|
1976
|
+
| "source-complete";
|
|
1977
|
+
}
|
|
1978
|
+
>,
|
|
1979
|
+
signal: AbortSignal,
|
|
1980
|
+
): Promise<CliResult> {
|
|
1981
|
+
const api = await this.authenticatedApi(command.credentialStore, signal);
|
|
1982
|
+
const source = api.managedSource;
|
|
1983
|
+
if (source === undefined) throw new ProviderCapabilityBlockedError();
|
|
1984
|
+
const name = parsedCommandName(command);
|
|
1985
|
+
if (command.kind === "source-complete") {
|
|
1986
|
+
const completed = await completeLocalSourcePublication({
|
|
1987
|
+
api: source,
|
|
1988
|
+
getOperation: (id) => api.getOperation(id),
|
|
1989
|
+
directory: resolve(this.dependencies.sourceDirectory ?? process.cwd(), command.directory),
|
|
1990
|
+
metadataDirectory: this.dependencies.sourceMetadataDirectory,
|
|
1991
|
+
apiOrigin: this.dependencies.productApiOrigin,
|
|
1992
|
+
identity: await api.getCurrentIdentity(),
|
|
1993
|
+
projectId: command.projectId,
|
|
1994
|
+
operationId: command.operationId,
|
|
1995
|
+
});
|
|
1996
|
+
return success(name, completed);
|
|
1997
|
+
}
|
|
1998
|
+
if (command.kind === "source-read") {
|
|
1999
|
+
const result =
|
|
2000
|
+
command.action === "status"
|
|
2001
|
+
? await source.getSource(command.projectId)
|
|
2002
|
+
: command.action === "files" || command.action === "file"
|
|
2003
|
+
? await source.files({
|
|
2004
|
+
projectId: command.projectId,
|
|
2005
|
+
commitSha: command.commitSha,
|
|
2006
|
+
path: command.path,
|
|
2007
|
+
})
|
|
2008
|
+
: command.action === "versions"
|
|
2009
|
+
? await source.versions({
|
|
2010
|
+
projectId: command.projectId,
|
|
2011
|
+
limit: command.limit,
|
|
2012
|
+
beforeCommitSha: command.beforeCommitSha,
|
|
2013
|
+
})
|
|
2014
|
+
: command.action === "diff"
|
|
2015
|
+
? await source.diff({
|
|
2016
|
+
projectId: command.projectId,
|
|
2017
|
+
fromCommitSha: String(command.fromCommitSha),
|
|
2018
|
+
toCommitSha: String(command.toCommitSha),
|
|
2019
|
+
})
|
|
2020
|
+
: await source.getUpload({
|
|
2021
|
+
projectId: command.projectId,
|
|
2022
|
+
operationId: String(command.operationId),
|
|
2023
|
+
});
|
|
2024
|
+
if (command.action === "status") {
|
|
2025
|
+
if (result !== null) parseProjectSourceBinding(result);
|
|
2026
|
+
} else
|
|
2027
|
+
assertManagedSourceResponse(command.action === "file" ? "files" : command.action, result);
|
|
2028
|
+
return success(name, { status: "succeeded", source: result, context: this.context() });
|
|
2029
|
+
}
|
|
2030
|
+
let operation: ReturnType<typeof parseOperation>;
|
|
2031
|
+
let receipt: unknown;
|
|
2032
|
+
let snapshot: { sha256: string; total_bytes: number; files: number } | undefined;
|
|
2033
|
+
if (command.kind === "source-publish") {
|
|
2034
|
+
const directory = resolve(
|
|
2035
|
+
this.dependencies.sourceDirectory ?? process.cwd(),
|
|
2036
|
+
command.directory,
|
|
2037
|
+
);
|
|
2038
|
+
const captured = await createSourceSnapshot({
|
|
2039
|
+
directory,
|
|
2040
|
+
});
|
|
2041
|
+
const prepared = await prepareLocalSourcePublication({
|
|
2042
|
+
directory,
|
|
2043
|
+
metadataDirectory: this.dependencies.sourceMetadataDirectory,
|
|
2044
|
+
apiOrigin: this.dependencies.productApiOrigin,
|
|
2045
|
+
identity: await api.getCurrentIdentity(),
|
|
2046
|
+
projectId: command.projectId,
|
|
2047
|
+
request: command.request,
|
|
2048
|
+
explicitExpectedCommit: command.explicitExpectedCommit,
|
|
2049
|
+
snapshotSha256: captured.sha256,
|
|
2050
|
+
idempotencyKey: command.idempotencyKey,
|
|
2051
|
+
});
|
|
2052
|
+
const published = await publishSourceSnapshot({
|
|
2053
|
+
api: source,
|
|
2054
|
+
projectId: command.projectId,
|
|
2055
|
+
request: prepared.request,
|
|
2056
|
+
snapshot: captured,
|
|
2057
|
+
idempotencyKey: command.idempotencyKey,
|
|
2058
|
+
signal,
|
|
2059
|
+
accepted: prepared.accepted,
|
|
2060
|
+
rejected: prepared.rejected,
|
|
2061
|
+
});
|
|
2062
|
+
operation = parseOperation(published.operation);
|
|
2063
|
+
receipt = published.receipt;
|
|
2064
|
+
snapshot = {
|
|
2065
|
+
sha256: captured.sha256,
|
|
2066
|
+
total_bytes: captured.totalBytes,
|
|
2067
|
+
files: captured.files.length,
|
|
2068
|
+
};
|
|
2069
|
+
} else
|
|
2070
|
+
operation = parseOperation(
|
|
2071
|
+
command.kind === "source-initialize"
|
|
2072
|
+
? await source.initialize({
|
|
2073
|
+
projectId: command.projectId,
|
|
2074
|
+
body: command.request,
|
|
2075
|
+
idempotencyKey: command.idempotencyKey,
|
|
2076
|
+
})
|
|
2077
|
+
: await source.restore({
|
|
2078
|
+
projectId: command.projectId,
|
|
2079
|
+
body: command.request,
|
|
2080
|
+
idempotencyKey: command.idempotencyKey,
|
|
2081
|
+
}),
|
|
2082
|
+
);
|
|
2083
|
+
if (command.wait) operation = await this.waitForOperation(api, operation, signal);
|
|
2084
|
+
if (operation.state === "succeeded" && command.kind === "source-publish") {
|
|
2085
|
+
const completed = await completeLocalSourcePublication({
|
|
2086
|
+
api: source,
|
|
2087
|
+
getOperation: (id) => api.getOperation(id),
|
|
2088
|
+
directory: resolve(this.dependencies.sourceDirectory ?? process.cwd(), command.directory),
|
|
2089
|
+
metadataDirectory: this.dependencies.sourceMetadataDirectory,
|
|
2090
|
+
apiOrigin: this.dependencies.productApiOrigin,
|
|
2091
|
+
identity: await api.getCurrentIdentity(),
|
|
2092
|
+
projectId: command.projectId,
|
|
2093
|
+
operationId: operation.id,
|
|
2094
|
+
});
|
|
2095
|
+
receipt = completed.receipt;
|
|
2096
|
+
} else if (operation.state === "succeeded") {
|
|
2097
|
+
const current = await source.getSource(command.projectId);
|
|
2098
|
+
parseProjectSourceBinding(current);
|
|
2099
|
+
if (
|
|
2100
|
+
current === null ||
|
|
2101
|
+
typeof current !== "object" ||
|
|
2102
|
+
!("provider" in current) ||
|
|
2103
|
+
current.provider !== "managed"
|
|
2104
|
+
)
|
|
2105
|
+
throw new ResponseContractError();
|
|
2106
|
+
const managed = current as ManagedProjectSource;
|
|
2107
|
+
const expectedGeneration =
|
|
2108
|
+
command.kind === "source-initialize" ||
|
|
2109
|
+
(command.kind === "source-publish" && command.request.mode !== "commit")
|
|
2110
|
+
? command.request.expected_source_generation + 1
|
|
2111
|
+
: command.request.expected_source_generation;
|
|
2112
|
+
if (managed.source_generation !== expectedGeneration || managed.status !== "ready")
|
|
2113
|
+
throw new ResponseContractError();
|
|
2114
|
+
const [organizationId, ...others] = parseCurrentIdentity(
|
|
2115
|
+
await api.getCurrentIdentity(),
|
|
2116
|
+
).organization_ids;
|
|
2117
|
+
if (organizationId === undefined || others.length > 0) throw new ResponseContractError();
|
|
2118
|
+
const prior = (
|
|
2119
|
+
await readProjectLinks(
|
|
2120
|
+
join(
|
|
2121
|
+
this.dependencies.sourceDirectory ?? process.cwd(),
|
|
2122
|
+
this.dependencies.sourceMetadataDirectory ?? ".ohmyhost",
|
|
2123
|
+
),
|
|
2124
|
+
this.dependencies.productApiOrigin,
|
|
2125
|
+
)
|
|
2126
|
+
).links.find(
|
|
2127
|
+
(link) => link.organization_id === organizationId && link.project_id === command.projectId,
|
|
2128
|
+
);
|
|
2129
|
+
const confirmed =
|
|
2130
|
+
prior?.version === 3 &&
|
|
2131
|
+
prior.source.provider === "managed" &&
|
|
2132
|
+
prior.source.source_connection_id === managed.source_connection_id &&
|
|
2133
|
+
prior.source.source_generation === managed.source_generation
|
|
2134
|
+
? prior.source.last_confirmed_commit_sha
|
|
2135
|
+
: null;
|
|
2136
|
+
await this.dependencies.projectLinkStore.save({
|
|
2137
|
+
version: 3,
|
|
2138
|
+
api_origin: this.dependencies.productApiOrigin,
|
|
2139
|
+
organization_id: organizationId,
|
|
2140
|
+
project_id: command.projectId,
|
|
2141
|
+
source: {
|
|
2142
|
+
provider: "managed",
|
|
2143
|
+
source_connection_id: managed.source_connection_id,
|
|
2144
|
+
source_generation: managed.source_generation,
|
|
2145
|
+
namespace: managed.namespace,
|
|
2146
|
+
repository_name: managed.repository_name,
|
|
2147
|
+
branch: "main",
|
|
2148
|
+
last_confirmed_commit_sha: confirmed,
|
|
2149
|
+
},
|
|
2150
|
+
});
|
|
2151
|
+
}
|
|
2152
|
+
return success(name, {
|
|
2153
|
+
status: command.wait ? "completed" : "accepted",
|
|
2154
|
+
operation,
|
|
2155
|
+
...(receipt === undefined ? {} : { receipt }),
|
|
2156
|
+
...(snapshot === undefined ? {} : { snapshot }),
|
|
2157
|
+
next_action:
|
|
2158
|
+
"Read the resulting commit_sha, then plan and deploy that exact version. Publication is a separate action.",
|
|
2159
|
+
});
|
|
2160
|
+
}
|
|
2161
|
+
|
|
1869
2162
|
private async configureAutoDeploy(
|
|
1870
2163
|
command: Extract<ProductCliCommand, { kind: "source-auto-deploy-set" }>,
|
|
1871
2164
|
signal: AbortSignal,
|
|
@@ -2512,6 +2805,17 @@ const classifyFailure = (
|
|
|
2512
2805
|
signal: AbortSignal,
|
|
2513
2806
|
actingAs?: Readonly<Record<string, unknown>>,
|
|
2514
2807
|
): CliResult => {
|
|
2808
|
+
if (error instanceof LocalSourcePublicationError)
|
|
2809
|
+
return failure(
|
|
2810
|
+
command,
|
|
2811
|
+
2,
|
|
2812
|
+
error.code,
|
|
2813
|
+
error.code === "source_publication_pending",
|
|
2814
|
+
error.message,
|
|
2815
|
+
error.operation,
|
|
2816
|
+
);
|
|
2817
|
+
if (error instanceof SourceWorkspaceError)
|
|
2818
|
+
return failure(command, 2, error.code, error.code === "source_snapshot_changed", error.message);
|
|
2515
2819
|
if (signal.aborted || isCancellation(error)) {
|
|
2516
2820
|
return failure(
|
|
2517
2821
|
command,
|
|
@@ -2743,6 +3047,12 @@ const failure = (
|
|
|
2743
3047
|
};
|
|
2744
3048
|
|
|
2745
3049
|
const parsedCommandName = (command: ProductCliCommand): CommandLabel => {
|
|
3050
|
+
if (command.kind === "source-inspect") return "source inspect";
|
|
3051
|
+
if (command.kind === "source-publish") return "source publish";
|
|
3052
|
+
if (command.kind === "source-complete") return "source publish complete";
|
|
3053
|
+
if (command.kind === "source-initialize") return "source initialize";
|
|
3054
|
+
if (command.kind === "source-restore") return "source restore";
|
|
3055
|
+
if (command.kind === "source-read") return `source ${command.action}`;
|
|
2746
3056
|
if (command.kind === "export-create") return "export create";
|
|
2747
3057
|
if (command.kind === "export-get") return "export get";
|
|
2748
3058
|
if (command.kind === "token-create") return "token create";
|