@amerged/ohmyhost-mcp 0.1.20 → 0.1.21
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/dist/{chunk-NESQZ3BS.js → chunk-4WY7AAPR.js} +9 -9
- package/dist/index.js +1 -1
- package/dist/stdio-main.js +123 -9
- package/package.json +1 -1
- package/src/apps/mcp/local-client.ts +33 -0
- package/src/apps/mcp/local-server.ts +41 -2
- package/src/apps/product-cli/cli.ts +33 -0
- package/src/apps/product-cli/command.ts +52 -0
- package/src/apps/product-cli/index.ts +2 -0
- package/src/apps/product-cli/product-api.ts +28 -0
- package/src/apps/product-cli/runtime-contract.ts +48 -3
- package/src/packages/agent-skills/generated-skill-resources.ts +8 -8
- package/src/packages/contracts/operation-failure.ts +3 -3
- package/src/packages/sdk-ts/generated/index.ts +21 -0
- package/src/packages/sdk-ts/generated/sdk.gen.ts +142 -0
- package/src/packages/sdk-ts/generated/types.gen.ts +200 -2
package/dist/stdio-main.js
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
serverIdentityOf,
|
|
27
27
|
setNegotiatedProtocolVersion,
|
|
28
28
|
validateEnvelopeMeta
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-4WY7AAPR.js";
|
|
30
30
|
|
|
31
31
|
// node_modules/.pnpm/@modelcontextprotocol+server@2.0.0/node_modules/@modelcontextprotocol/server/dist/stdio.mjs
|
|
32
32
|
var StdioServerTransport = class {
|
|
@@ -516,7 +516,7 @@ function toError(value) {
|
|
|
516
516
|
var failures = {
|
|
517
517
|
operation_abandoned: [
|
|
518
518
|
"The operation stopped renewing its execution lease and was ended.",
|
|
519
|
-
"Inspect project status and
|
|
519
|
+
"Inspect project status and, when this operation names a deployment_id, its diagnostics with 'ohmyhost deployment logs --project PROJECT_ULID --deployment DEPLOYMENT_ULID --follow --json' or MCP deployment_logs before creating a fresh plan. Keep this operation ID; the expired execution cannot resume."
|
|
520
520
|
],
|
|
521
521
|
database_write_rejected: [
|
|
522
522
|
"The database rejected this write; it was not committed.",
|
|
@@ -580,7 +580,7 @@ var failures = {
|
|
|
580
580
|
],
|
|
581
581
|
build_failed: [
|
|
582
582
|
"The build did not produce a verified deployable artifact.",
|
|
583
|
-
"
|
|
583
|
+
"Read the BUILD_FAILED diagnostic of this operation's deployment_id with 'ohmyhost deployment logs --project PROJECT_ULID --deployment DEPLOYMENT_ULID --follow --json' or MCP deployment_logs; its excerpt is the tail of the install and build output. Correct that failure and verify the commands for the admitted commit before planning a new deployment."
|
|
584
584
|
],
|
|
585
585
|
insufficient_organization_credits: [
|
|
586
586
|
"The organization does not have sufficient available credits for this operation.",
|
|
@@ -596,7 +596,7 @@ var failures = {
|
|
|
596
596
|
],
|
|
597
597
|
runtime_candidate_failed: [
|
|
598
598
|
"The deployed candidate failed its runtime checks.",
|
|
599
|
-
"
|
|
599
|
+
"Read the HEALTH_CHECK_FAILED diagnostic of this operation's deployment_id with 'ohmyhost deployment logs --project PROJECT_ULID --deployment DEPLOYMENT_ULID --follow --json' or MCP deployment_logs. Its route must answer 2xx to a cookieless GET without a redirect; status_code and, for owners, excerpt show what it answered. Fix that, often a missing secret or a redirect, then plan a new deployment."
|
|
600
600
|
],
|
|
601
601
|
runtime_candidate_rejected: [
|
|
602
602
|
"The runtime rejected the built Worker script.",
|
|
@@ -799,7 +799,7 @@ function exact2(v, keys) {
|
|
|
799
799
|
// apps/product-cli/package.json
|
|
800
800
|
var package_default = {
|
|
801
801
|
name: "@ohmyhost/product-cli",
|
|
802
|
-
version: "0.1.
|
|
802
|
+
version: "0.1.21",
|
|
803
803
|
private: true,
|
|
804
804
|
ohmyhost: {
|
|
805
805
|
deployment: "production",
|
|
@@ -2168,6 +2168,11 @@ var PROBLEM_POLICY = {
|
|
|
2168
2168
|
retryable: false,
|
|
2169
2169
|
action: "Finish database provisioning, then request the export again. No backup was accepted."
|
|
2170
2170
|
},
|
|
2171
|
+
powered_by_flag_required: {
|
|
2172
|
+
status: 409,
|
|
2173
|
+
retryable: false,
|
|
2174
|
+
action: "Keep the flag on, remove the custom domain with 'ohmyhost domain paid delete', or buy Paid, then switch the flag off."
|
|
2175
|
+
},
|
|
2171
2176
|
rate_limited: { status: 429, retryable: true, action: "Retry after the server delay." },
|
|
2172
2177
|
insufficient_organization_credits: {
|
|
2173
2178
|
status: 402,
|
|
@@ -2182,7 +2187,7 @@ var PROBLEM_POLICY = {
|
|
|
2182
2187
|
paid_plan_required: {
|
|
2183
2188
|
status: 402,
|
|
2184
2189
|
retryable: false,
|
|
2185
|
-
action: "Ask the organization Owner to activate Paid through billing checkout, then retry. Top-ups and signup credits do not activate Paid."
|
|
2190
|
+
action: "Ask the organization Owner to activate Paid through billing checkout, then retry. Top-ups and signup credits do not activate Paid. For a website domain alone, a Free workspace may instead show the powered-by flag on the project."
|
|
2186
2191
|
},
|
|
2187
2192
|
interactive_login_required: {
|
|
2188
2193
|
status: 403,
|
|
@@ -2290,6 +2295,18 @@ var parseDevAccessState = (value) => {
|
|
|
2290
2295
|
throw new ResponseContractError();
|
|
2291
2296
|
return input;
|
|
2292
2297
|
};
|
|
2298
|
+
var parsePoweredByFlag = (value) => {
|
|
2299
|
+
const input = exactRecord2(value, ["project_id", "enabled", "enabled_at"]);
|
|
2300
|
+
if (!isUlid(input["project_id"]) || typeof input["enabled"] !== "boolean" || (input["enabled"] ? !isIsoInstant(input["enabled_at"]) : input["enabled_at"] !== null))
|
|
2301
|
+
throw new ResponseContractError();
|
|
2302
|
+
return input;
|
|
2303
|
+
};
|
|
2304
|
+
var parseOrganizationReferral = (value) => {
|
|
2305
|
+
const input = exactRecord2(value, ["organization_id", "referral_url"]);
|
|
2306
|
+
if (!isUlid(input["organization_id"]) || input["referral_url"] !== `https://ohmyho.st/?r=ref-${String(input["organization_id"]).toLowerCase()}`)
|
|
2307
|
+
throw new ResponseContractError();
|
|
2308
|
+
return input;
|
|
2309
|
+
};
|
|
2293
2310
|
var parseDevAccessTicket = (value) => {
|
|
2294
2311
|
const input = exactRecord2(value, [
|
|
2295
2312
|
"ticket_id",
|
|
@@ -2381,6 +2398,7 @@ var parseSafeProblem = (value) => {
|
|
|
2381
2398
|
var parseOperation = (value) => {
|
|
2382
2399
|
const input = exactRecord2(value, [
|
|
2383
2400
|
"blocking_operation_id",
|
|
2401
|
+
"deployment_id",
|
|
2384
2402
|
"id",
|
|
2385
2403
|
"state",
|
|
2386
2404
|
"created_at",
|
|
@@ -2396,7 +2414,8 @@ var parseOperation = (value) => {
|
|
|
2396
2414
|
const updatedAt = input["updated_at"];
|
|
2397
2415
|
const result = input["result"];
|
|
2398
2416
|
const blockingOperationId = input["blocking_operation_id"];
|
|
2399
|
-
|
|
2417
|
+
const deploymentId = input["deployment_id"];
|
|
2418
|
+
if (blockingOperationId !== void 0 && (state !== "queued" || !isUlid(blockingOperationId) || blockingOperationId === id3) || deploymentId !== void 0 && !isUlid(deploymentId))
|
|
2400
2419
|
throw new ResponseContractError();
|
|
2401
2420
|
if (!isUlid(id3) || !isOperationState(state) || !isIsoInstant(createdAt) || !isIsoInstant(updatedAt) || result !== void 0 && !isRecord2(result)) {
|
|
2402
2421
|
throw new ResponseContractError();
|
|
@@ -2443,6 +2462,7 @@ var parseOperation = (value) => {
|
|
|
2443
2462
|
created_at: createdAt,
|
|
2444
2463
|
updated_at: updatedAt,
|
|
2445
2464
|
...blockingOperationId === void 0 ? {} : { blocking_operation_id: blockingOperationId },
|
|
2465
|
+
...deploymentId === void 0 ? {} : { deployment_id: deploymentId },
|
|
2446
2466
|
...progress === void 0 ? {} : { progress },
|
|
2447
2467
|
...result === void 0 ? {} : { result },
|
|
2448
2468
|
...error === void 0 ? {} : { error },
|
|
@@ -2597,6 +2617,7 @@ var HELP_USAGE = Object.freeze({
|
|
|
2597
2617
|
"export create": "ohmyhost export create --project ULID --idempotency-key KEY --stdin --json (password on stdin only; one accepted SQL ZIP per project per 24 hours)",
|
|
2598
2618
|
"export get": "ohmyhost export get EXPORT_ULID --project ULID --json (poll the original job; signed ZIP download lasts 24 hours)",
|
|
2599
2619
|
"credits account": "ohmyhost credits account --organization ULID --json",
|
|
2620
|
+
"referral link": "ohmyhost referral link --organization ULID --json (the workspace's link to share; a new user who signs up through it starts with a free Paid month and 1,000 credits, and their first payment gives this workspace the same)",
|
|
2600
2621
|
"credits balance": "ohmyhost credits balance --organization ULID --json",
|
|
2601
2622
|
"billing recharge get": "ohmyhost billing recharge get --organization ULID --json",
|
|
2602
2623
|
"billing recharge set": "ohmyhost billing recharge set --organization ULID --enabled true|false --monthly-limit-minor CENTS --revision N --idempotency-key KEY [--consent off_session_v1] --json (explicit Owner consent required before enabling)",
|
|
@@ -2626,6 +2647,8 @@ var HELP_USAGE = Object.freeze({
|
|
|
2626
2647
|
"project dev-share rotate": "ohmyhost project dev-share rotate --project ULID --idempotency-key KEY --yes --json",
|
|
2627
2648
|
"project dev-share revoke": "ohmyhost project dev-share revoke --project ULID --idempotency-key KEY --yes --json",
|
|
2628
2649
|
"project dev-access mode": "ohmyhost project dev-access mode --project ULID --mode protected|public --idempotency-key KEY --yes --json",
|
|
2650
|
+
"project flag status": "ohmyhost project flag status --project ULID --json",
|
|
2651
|
+
"project flag set": "ohmyhost project flag set --project ULID --enabled true|false --idempotency-key KEY --json (shows the small Powered by ohmyho.st flag on the production site; while it shows, a Free workspace may connect its own domain without the domain fee and each Paid period adds 250 credits)",
|
|
2629
2652
|
"project handle check": "ohmyhost project handle check --handle HANDLE --json (is this address free? answers with a reason and free alternatives; the address becomes HANDLE.check.omh.st)",
|
|
2630
2653
|
"project handle set": "ohmyhost project handle set --project ULID --handle HANDLE --if-match ETAG --idempotency-key KEY --json (moves the project to a free address; the old one stops working and anyone may claim it)",
|
|
2631
2654
|
"database compute set": "ohmyhost database compute set --project ULID --environment dev|prod --profile standard|performance --idempotency-key KEY --yes [--wait] --json\n standard: Free 0.25 CU/1 GB/60s idle, Paid 0.5 CU/2 GB/60s idle. performance: Paid 1 CU/4 GB/300s idle, 2.5x database compute credits per equal active minute; longer idle time also consumes credits.",
|
|
@@ -3567,6 +3590,23 @@ var getGithubOrganizationConnection = (parameters, options) => {
|
|
|
3567
3590
|
...params
|
|
3568
3591
|
});
|
|
3569
3592
|
};
|
|
3593
|
+
var getOrganizationReferral = (parameters, options) => {
|
|
3594
|
+
const params = buildClientParams([parameters], [
|
|
3595
|
+
{
|
|
3596
|
+
args: [
|
|
3597
|
+
{ in: "headers", key: "X-Request-Id" },
|
|
3598
|
+
{ in: "path", key: "organization_id" }
|
|
3599
|
+
]
|
|
3600
|
+
}
|
|
3601
|
+
]);
|
|
3602
|
+
return (options?.client ?? client).get({
|
|
3603
|
+
responseStyle: "data",
|
|
3604
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
3605
|
+
url: "/v1/organizations/{organization_id}/referral",
|
|
3606
|
+
...options,
|
|
3607
|
+
...params
|
|
3608
|
+
});
|
|
3609
|
+
};
|
|
3570
3610
|
var getOrganizationAccount = (parameters, options) => {
|
|
3571
3611
|
const params = buildClientParams([parameters], [{ args: [{ in: "path", key: "organization_id" }] }]);
|
|
3572
3612
|
return (options?.client ?? client).get({
|
|
@@ -4171,6 +4211,47 @@ var setProjectDevAccessMode = (parameters, options) => {
|
|
|
4171
4211
|
}
|
|
4172
4212
|
});
|
|
4173
4213
|
};
|
|
4214
|
+
var getProjectPoweredByFlag = (parameters, options) => {
|
|
4215
|
+
const params = buildClientParams([parameters], [
|
|
4216
|
+
{
|
|
4217
|
+
args: [
|
|
4218
|
+
{ in: "headers", key: "X-Request-Id" },
|
|
4219
|
+
{ in: "path", key: "project_id" }
|
|
4220
|
+
]
|
|
4221
|
+
}
|
|
4222
|
+
]);
|
|
4223
|
+
return (options?.client ?? client).get({
|
|
4224
|
+
responseStyle: "data",
|
|
4225
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
4226
|
+
url: "/v1/projects/{project_id}/powered-by-flag",
|
|
4227
|
+
...options,
|
|
4228
|
+
...params
|
|
4229
|
+
});
|
|
4230
|
+
};
|
|
4231
|
+
var setProjectPoweredByFlag = (parameters, options) => {
|
|
4232
|
+
const params = buildClientParams([parameters], [
|
|
4233
|
+
{
|
|
4234
|
+
args: [
|
|
4235
|
+
{ in: "headers", key: "X-Request-Id" },
|
|
4236
|
+
{ in: "headers", key: "Idempotency-Key" },
|
|
4237
|
+
{ in: "path", key: "project_id" },
|
|
4238
|
+
{ key: "setPoweredByFlagRequest", map: "body" }
|
|
4239
|
+
]
|
|
4240
|
+
}
|
|
4241
|
+
]);
|
|
4242
|
+
return (options?.client ?? client).put({
|
|
4243
|
+
responseStyle: "data",
|
|
4244
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
4245
|
+
url: "/v1/projects/{project_id}/powered-by-flag",
|
|
4246
|
+
...options,
|
|
4247
|
+
...params,
|
|
4248
|
+
headers: {
|
|
4249
|
+
"Content-Type": "application/json",
|
|
4250
|
+
...options?.headers,
|
|
4251
|
+
...params.headers
|
|
4252
|
+
}
|
|
4253
|
+
});
|
|
4254
|
+
};
|
|
4174
4255
|
var createProjectDevAccessTicket = (parameters, options) => {
|
|
4175
4256
|
const params = buildClientParams([parameters], [
|
|
4176
4257
|
{
|
|
@@ -5429,6 +5510,9 @@ var GeneratedSdkProductApi = class {
|
|
|
5429
5510
|
async getAccountProfile() {
|
|
5430
5511
|
return parseAccountProfile(await getAccountProfile({ client: this.#client }));
|
|
5431
5512
|
}
|
|
5513
|
+
getOrganizationReferral(organizationId) {
|
|
5514
|
+
return getOrganizationReferral({ organization_id: organizationId }, { client: this.#client });
|
|
5515
|
+
}
|
|
5432
5516
|
getOrganizationAccount(organizationId) {
|
|
5433
5517
|
return getOrganizationAccount({ organization_id: organizationId }, { client: this.#client });
|
|
5434
5518
|
}
|
|
@@ -5602,6 +5686,16 @@ var GeneratedSdkProductApi = class {
|
|
|
5602
5686
|
setDevAccessModeRequest: { mode }
|
|
5603
5687
|
}, { client: this.#client });
|
|
5604
5688
|
}
|
|
5689
|
+
async getPoweredByFlag(projectId) {
|
|
5690
|
+
return getProjectPoweredByFlag({ project_id: projectId }, { client: this.#client });
|
|
5691
|
+
}
|
|
5692
|
+
async setPoweredByFlag(projectId, enabled, idempotencyKey2) {
|
|
5693
|
+
return setProjectPoweredByFlag({
|
|
5694
|
+
project_id: projectId,
|
|
5695
|
+
"Idempotency-Key": idempotencyKey2,
|
|
5696
|
+
setPoweredByFlagRequest: { enabled }
|
|
5697
|
+
}, { client: this.#client });
|
|
5698
|
+
}
|
|
5605
5699
|
async createDevAccessTicket(projectId) {
|
|
5606
5700
|
return createProjectDevAccessTicket({ project_id: projectId }, { client: this.#client });
|
|
5607
5701
|
}
|
|
@@ -6361,6 +6455,9 @@ var GeneratedSdkLocalMcpClient = class {
|
|
|
6361
6455
|
assertOrganizationAccount(account);
|
|
6362
6456
|
return account;
|
|
6363
6457
|
}
|
|
6458
|
+
async getOrganizationReferral(organizationId) {
|
|
6459
|
+
return parseOrganizationReferral(await getOrganizationReferral({ organization_id: organizationId }, { client: this.#client }));
|
|
6460
|
+
}
|
|
6364
6461
|
getOrganizationCredits(organizationId) {
|
|
6365
6462
|
return getOrganizationCredits({ organization_id: organizationId }, { client: this.#client });
|
|
6366
6463
|
}
|
|
@@ -6489,6 +6586,16 @@ var GeneratedSdkLocalMcpClient = class {
|
|
|
6489
6586
|
setDevAccessModeRequest: { mode: input.mode }
|
|
6490
6587
|
}, { client: this.#client }));
|
|
6491
6588
|
}
|
|
6589
|
+
async getPoweredByFlag(projectId) {
|
|
6590
|
+
return parsePoweredByFlag(await getProjectPoweredByFlag({ project_id: projectId }, { client: this.#client }));
|
|
6591
|
+
}
|
|
6592
|
+
async setPoweredByFlag(input) {
|
|
6593
|
+
return parsePoweredByFlag(await setProjectPoweredByFlag({
|
|
6594
|
+
project_id: input.projectId,
|
|
6595
|
+
"Idempotency-Key": input.idempotencyKey,
|
|
6596
|
+
setPoweredByFlagRequest: { enabled: input.enabled }
|
|
6597
|
+
}, { client: this.#client }));
|
|
6598
|
+
}
|
|
6492
6599
|
async rotateDevShareLink(input) {
|
|
6493
6600
|
return parseDevAccessState(await rotateProjectDevShareLink({ project_id: input.projectId, "Idempotency-Key": input.idempotencyKey }, { client: this.#client }));
|
|
6494
6601
|
}
|
|
@@ -6894,6 +7001,7 @@ function createLocalOhmyhostMcpServer(dependencies) {
|
|
|
6894
7001
|
...input.cursor ? { cursor: input.cursor } : {}
|
|
6895
7002
|
}));
|
|
6896
7003
|
registerProductTool(server, dependencies, "organization_account_get", "Owner-only: read the effective Free/Paid plan, its Stripe or granted source, available expiring Free credits and purchased credits that never expire, reservations and next expiry. Granted Paid features do not imply a Stripe subscription or extra monthly Paid allowance. This read grants no access or credits.", external_exports.object({ organization_id: identifier2 }), (client2, input) => client2.getOrganizationAccount(input.organization_id));
|
|
7004
|
+
registerProductTool(server, dependencies, "referral_link_get", "Read the workspace's referral link to share. A new user whose first workspace comes from it starts with a free Paid month and 1,000 credits; that workspace's first payment gives this workspace the same. Any member may read it.", external_exports.object({ organization_id: identifier2 }), (client2, input) => client2.getOrganizationReferral(input.organization_id));
|
|
6897
7005
|
registerProductTool(server, dependencies, "organization_credits_get", "Read the owner's shared organization credit pool, seven-day grace_started_at/grace_expires_at and published rate_cards. Existing services/domains are not immediately shut down at zero credit; an explicit project stop budget is separate. One credit is 1000000 microcredits. Each rate states credit_micros for units_per_charge; publication alone does not enable billing. active_meters identifies billed sources; provider outages and platform overrun are not customer debt. Works at zero credit.", external_exports.object({ organization_id: identifier2 }), (client2, input) => client2.getOrganizationCredits(input.organization_id));
|
|
6898
7006
|
registerProductTool(server, dependencies, "project_budget_get", "Read the owner's project UTC-month budget, measured usage and open reservations. A budget never allocates a second wallet.", external_exports.object({ project_id: identifier2 }), (client2, input) => client2.getProjectCreditBudget(input.project_id));
|
|
6899
7007
|
registerProductTool(server, dependencies, "project_budget_set", "Set an owner's optional monthly project budget in microcredits (1000000 = one credit). continue is the default and uses the org pool after the threshold; stop blocks new billable work. null clears the budget and requires continue. Changing it never resets usage or adds credits. Replay the same key after uncertainty; read the budget again for current usage.", external_exports.object({
|
|
@@ -7095,6 +7203,12 @@ function createLocalOhmyhostMcpServer(dependencies) {
|
|
|
7095
7203
|
mode: input.mode,
|
|
7096
7204
|
idempotencyKey: input.idempotency_key
|
|
7097
7205
|
}), destructiveAnnotations());
|
|
7206
|
+
registerProductTool(server, dependencies, "powered_by_flag_get", 'Read whether the production site shows the opt-in "Powered by ohmyho.st" flag.', external_exports.object({ project_id: identifier2 }), (client2, input) => client2.getPoweredByFlag(input.project_id));
|
|
7207
|
+
registerProductTool(server, dependencies, "powered_by_flag_set", `Owner only, ask the human first: show or hide a small "Powered by ohmyho.st" flag on the right edge of the production site. While it is on, a Free workspace may connect its own domain to this project free of the domain fee, and each Paid period adds 250 credits. Hiding it is refused while a Free workspace's domain depends on it. Replay the same key and value after uncertainty to get the first answer without switching again; every new switch needs a new key.`, external_exports.object({ project_id: identifier2, enabled: external_exports.boolean(), idempotency_key: idempotencyKey }), (client2, input) => client2.setPoweredByFlag({
|
|
7208
|
+
projectId: input.project_id,
|
|
7209
|
+
enabled: input.enabled,
|
|
7210
|
+
idempotencyKey: input.idempotency_key
|
|
7211
|
+
}), mutationAnnotations());
|
|
7098
7212
|
registerProductTool(server, dependencies, "project_dev_share_link_rotate", "Owner only: replace the persistent Dev link and immediately revoke old links and sessions. Repeat the same key after uncertainty.", external_exports.object({ project_id: identifier2, idempotency_key: idempotencyKey }), (client2, input) => client2.rotateDevShareLink({
|
|
7099
7213
|
projectId: input.project_id,
|
|
7100
7214
|
idempotencyKey: input.idempotency_key
|
|
@@ -7145,7 +7259,7 @@ function createLocalOhmyhostMcpServer(dependencies) {
|
|
|
7145
7259
|
...input.limit === void 0 ? {} : { limit: input.limit }
|
|
7146
7260
|
}));
|
|
7147
7261
|
registerProductTool(server, dependencies, "deployment_get", "Get one deployment", external_exports.object({ project_id: identifier2, deployment_id: identifier2 }), (client2, input) => client2.getDeployment({ projectId: input.project_id, deploymentId: input.deployment_id }));
|
|
7148
|
-
registerProductTool(server, dependencies, "deployment_logs", "List the newest normalized diagnostics of one deployment (build, control, runtime and function failures with catalog codes). A BUILD_FAILED item carries excerpt: the sanitized tail of the customer's own install/build output, newest lines last, with excerpt_truncated when earlier output was omitted. Read
|
|
7262
|
+
registerProductTool(server, dependencies, "deployment_logs", "List the newest normalized diagnostics of one deployment (build, control, runtime and function failures with catalog codes). A failed operation_get names the deployment as deployment_id. A BUILD_FAILED item carries excerpt: the sanitized tail of the customer's own install/build output, newest lines last, with excerpt_truncated when earlier output was omitted. A HEALTH_CHECK_FAILED item carries the probed route and status_code and, only for a project owner, excerpt: the head (at most 4096 characters, control characters removed, never a header) of what the app answered. The probe is a cookieless GET that follows no redirect, 5 s per try and up to four tries, so a 3xx or an empty 503 is unhealthy too. Read the item before changing source; scheduled runs are in function_runs_list, not here.", external_exports.object({
|
|
7149
7263
|
project_id: identifier2,
|
|
7150
7264
|
deployment_id: identifier2,
|
|
7151
7265
|
limit: external_exports.number().int().min(1).max(100).default(100)
|
|
@@ -7154,7 +7268,7 @@ function createLocalOhmyhostMcpServer(dependencies) {
|
|
|
7154
7268
|
deploymentId: input.deployment_id,
|
|
7155
7269
|
limit: input.limit
|
|
7156
7270
|
}));
|
|
7157
|
-
registerProductTool(server, dependencies, "operation_get", "Get durable operation status and current deployment progress/reconciliation guidance. Follow progress.phase and progress.suggested_action. waiting_for_mail requires mail_domain_status now for the current verification issue and DNS records; publishing means the build completed but runtime preparation/publication is unfinished. Poll this operation after progress.next_poll_after_seconds. A queued/running operation with reconciliation.state=required needs one confirmed operation_reconcile using the same operation; pending means poll this operation after 60 seconds. Never infer deployment success from a completed reconciliation attempt or start another build to recover it.", external_exports.object({ operation_id: identifier2 }), (client2, input) => client2.getOperation(input.operation_id));
|
|
7271
|
+
registerProductTool(server, dependencies, "operation_get", "Get durable operation status and current deployment progress/reconciliation guidance. Follow progress.phase and progress.suggested_action. waiting_for_mail requires mail_domain_status now for the current verification issue and DNS records; publishing means the build completed but runtime preparation/publication is unfinished. Poll this operation after progress.next_poll_after_seconds. A queued/running operation with reconciliation.state=required needs one confirmed operation_reconcile using the same operation; pending means poll this operation after 60 seconds. Never infer deployment success from a completed reconciliation attempt or start another build to recover it. A deploy, promotion or rollback names its deployment_id in every state; when state is failed, read that deployment with deployment_logs and follow error.suggested_action before changing source.", external_exports.object({ operation_id: identifier2 }), (client2, input) => client2.getOperation(input.operation_id));
|
|
7158
7272
|
registerProductTool(server, dependencies, "operation_logs", "Read available operation events for at most ten seconds, stopping earlier at max_events or a terminal event. This is a bounded snapshot, not a wait for deployment completion. Use operation_get for current progress and keep the same operation. Stream failures are errors, not empty logs.", external_exports.object({
|
|
7159
7273
|
operation_id: identifier2,
|
|
7160
7274
|
max_events: external_exports.number().int().min(1).max(100).default(50)
|
package/package.json
CHANGED
|
@@ -26,6 +26,8 @@ import {
|
|
|
26
26
|
createProjectDevAccessTicket,
|
|
27
27
|
ensureProjectDevShareLink,
|
|
28
28
|
setProjectDevAccessMode,
|
|
29
|
+
getProjectPoweredByFlag,
|
|
30
|
+
setProjectPoweredByFlag,
|
|
29
31
|
rotateProjectDevShareLink,
|
|
30
32
|
revokeProjectDevShareLink,
|
|
31
33
|
createCloudflareDnsAuthorization,
|
|
@@ -52,6 +54,7 @@ import {
|
|
|
52
54
|
deletePaidProjectDomain,
|
|
53
55
|
getOrganizationCredits,
|
|
54
56
|
getOrganizationAccount,
|
|
57
|
+
getOrganizationReferral,
|
|
55
58
|
getOrganizationCreditUsage,
|
|
56
59
|
getProjectCreditBudget,
|
|
57
60
|
setProjectCreditBudget,
|
|
@@ -93,6 +96,8 @@ import {
|
|
|
93
96
|
streamOperationEvents,
|
|
94
97
|
type DevAccessTicket,
|
|
95
98
|
type DevAccessState,
|
|
99
|
+
type PoweredByFlag,
|
|
100
|
+
type OrganizationReferral,
|
|
96
101
|
type CloudflareDnsAuthorization,
|
|
97
102
|
type CloudflareDnsAuthorizationStatus,
|
|
98
103
|
type OhMyHostClient,
|
|
@@ -113,6 +118,8 @@ import {
|
|
|
113
118
|
ProductApiAuthenticationError,
|
|
114
119
|
parseDevAccessTicket,
|
|
115
120
|
parseDevAccessState,
|
|
121
|
+
parsePoweredByFlag,
|
|
122
|
+
parseOrganizationReferral,
|
|
116
123
|
parseCloudflareDnsAuthorization,
|
|
117
124
|
parseCloudflareDnsAuthorizationStatus,
|
|
118
125
|
parsePaidDomain,
|
|
@@ -419,6 +426,11 @@ export class GeneratedSdkLocalMcpClient implements LocalMcpProductClient {
|
|
|
419
426
|
assertOrganizationAccount(account);
|
|
420
427
|
return account;
|
|
421
428
|
}
|
|
429
|
+
public async getOrganizationReferral(organizationId: string): Promise<OrganizationReferral> {
|
|
430
|
+
return parseOrganizationReferral(
|
|
431
|
+
await getOrganizationReferral({ organization_id: organizationId }, { client: this.#client }),
|
|
432
|
+
);
|
|
433
|
+
}
|
|
422
434
|
public getOrganizationCredits(organizationId: string) {
|
|
423
435
|
return getOrganizationCredits({ organization_id: organizationId }, { client: this.#client });
|
|
424
436
|
}
|
|
@@ -606,6 +618,27 @@ export class GeneratedSdkLocalMcpClient implements LocalMcpProductClient {
|
|
|
606
618
|
),
|
|
607
619
|
);
|
|
608
620
|
}
|
|
621
|
+
public async getPoweredByFlag(projectId: string): Promise<PoweredByFlag> {
|
|
622
|
+
return parsePoweredByFlag(
|
|
623
|
+
await getProjectPoweredByFlag({ project_id: projectId }, { client: this.#client }),
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
public async setPoweredByFlag(input: {
|
|
627
|
+
projectId: string;
|
|
628
|
+
enabled: boolean;
|
|
629
|
+
idempotencyKey: string;
|
|
630
|
+
}): Promise<PoweredByFlag> {
|
|
631
|
+
return parsePoweredByFlag(
|
|
632
|
+
await setProjectPoweredByFlag(
|
|
633
|
+
{
|
|
634
|
+
project_id: input.projectId,
|
|
635
|
+
"Idempotency-Key": input.idempotencyKey,
|
|
636
|
+
setPoweredByFlagRequest: { enabled: input.enabled },
|
|
637
|
+
},
|
|
638
|
+
{ client: this.#client },
|
|
639
|
+
),
|
|
640
|
+
);
|
|
641
|
+
}
|
|
609
642
|
public async rotateDevShareLink(input: {
|
|
610
643
|
projectId: string;
|
|
611
644
|
idempotencyKey: string;
|
|
@@ -70,6 +70,12 @@ export interface LocalMcpProductClient {
|
|
|
70
70
|
projectId: string;
|
|
71
71
|
idempotencyKey: string;
|
|
72
72
|
}): Promise<import("@ohmyhost/sdk-ts").DevAccessState>;
|
|
73
|
+
getPoweredByFlag(projectId: string): Promise<import("@ohmyhost/sdk-ts").PoweredByFlag>;
|
|
74
|
+
setPoweredByFlag(input: {
|
|
75
|
+
projectId: string;
|
|
76
|
+
enabled: boolean;
|
|
77
|
+
idempotencyKey: string;
|
|
78
|
+
}): Promise<import("@ohmyhost/sdk-ts").PoweredByFlag>;
|
|
73
79
|
revokeDevShareLink(input: {
|
|
74
80
|
projectId: string;
|
|
75
81
|
idempotencyKey: string;
|
|
@@ -156,6 +162,9 @@ export interface LocalMcpProductClient {
|
|
|
156
162
|
getOrganizationAccount(
|
|
157
163
|
organizationId: string,
|
|
158
164
|
): Promise<import("@ohmyhost/sdk-ts").OrganizationAccount>;
|
|
165
|
+
getOrganizationReferral(
|
|
166
|
+
organizationId: string,
|
|
167
|
+
): Promise<import("@ohmyhost/sdk-ts").OrganizationReferral>;
|
|
159
168
|
getOrganizationCredits(
|
|
160
169
|
organizationId: string,
|
|
161
170
|
): Promise<import("@ohmyhost/sdk-ts").OrganizationCredits>;
|
|
@@ -706,6 +715,14 @@ export function createLocalOhmyhostMcpServer(dependencies: LocalOhmyhostMcpDepen
|
|
|
706
715
|
z.object({ organization_id: identifier }),
|
|
707
716
|
(client, input) => client.getOrganizationAccount(input.organization_id),
|
|
708
717
|
);
|
|
718
|
+
registerProductTool(
|
|
719
|
+
server,
|
|
720
|
+
dependencies,
|
|
721
|
+
"referral_link_get",
|
|
722
|
+
"Read the workspace's referral link to share. A new user whose first workspace comes from it starts with a free Paid month and 1,000 credits; that workspace's first payment gives this workspace the same. Any member may read it.",
|
|
723
|
+
z.object({ organization_id: identifier }),
|
|
724
|
+
(client, input) => client.getOrganizationReferral(input.organization_id),
|
|
725
|
+
);
|
|
709
726
|
registerProductTool(
|
|
710
727
|
server,
|
|
711
728
|
dependencies,
|
|
@@ -1163,6 +1180,28 @@ export function createLocalOhmyhostMcpServer(dependencies: LocalOhmyhostMcpDepen
|
|
|
1163
1180
|
}),
|
|
1164
1181
|
destructiveAnnotations(),
|
|
1165
1182
|
);
|
|
1183
|
+
registerProductTool(
|
|
1184
|
+
server,
|
|
1185
|
+
dependencies,
|
|
1186
|
+
"powered_by_flag_get",
|
|
1187
|
+
'Read whether the production site shows the opt-in "Powered by ohmyho.st" flag.',
|
|
1188
|
+
z.object({ project_id: identifier }),
|
|
1189
|
+
(client, input) => client.getPoweredByFlag(input.project_id),
|
|
1190
|
+
);
|
|
1191
|
+
registerProductTool(
|
|
1192
|
+
server,
|
|
1193
|
+
dependencies,
|
|
1194
|
+
"powered_by_flag_set",
|
|
1195
|
+
'Owner only, ask the human first: show or hide a small "Powered by ohmyho.st" flag on the right edge of the production site. While it is on, a Free workspace may connect its own domain to this project free of the domain fee, and each Paid period adds 250 credits. Hiding it is refused while a Free workspace\'s domain depends on it. Replay the same key and value after uncertainty to get the first answer without switching again; every new switch needs a new key.',
|
|
1196
|
+
z.object({ project_id: identifier, enabled: z.boolean(), idempotency_key: idempotencyKey }),
|
|
1197
|
+
(client, input) =>
|
|
1198
|
+
client.setPoweredByFlag({
|
|
1199
|
+
projectId: input.project_id,
|
|
1200
|
+
enabled: input.enabled,
|
|
1201
|
+
idempotencyKey: input.idempotency_key,
|
|
1202
|
+
}),
|
|
1203
|
+
mutationAnnotations(),
|
|
1204
|
+
);
|
|
1166
1205
|
registerProductTool(
|
|
1167
1206
|
server,
|
|
1168
1207
|
dependencies,
|
|
@@ -1308,7 +1347,7 @@ export function createLocalOhmyhostMcpServer(dependencies: LocalOhmyhostMcpDepen
|
|
|
1308
1347
|
server,
|
|
1309
1348
|
dependencies,
|
|
1310
1349
|
"deployment_logs",
|
|
1311
|
-
"List the newest normalized diagnostics of one deployment (build, control, runtime and function failures with catalog codes). A BUILD_FAILED item carries excerpt: the sanitized tail of the customer's own install/build output, newest lines last, with excerpt_truncated when earlier output was omitted. Read
|
|
1350
|
+
"List the newest normalized diagnostics of one deployment (build, control, runtime and function failures with catalog codes). A failed operation_get names the deployment as deployment_id. A BUILD_FAILED item carries excerpt: the sanitized tail of the customer's own install/build output, newest lines last, with excerpt_truncated when earlier output was omitted. A HEALTH_CHECK_FAILED item carries the probed route and status_code and, only for a project owner, excerpt: the head (at most 4096 characters, control characters removed, never a header) of what the app answered. The probe is a cookieless GET that follows no redirect, 5 s per try and up to four tries, so a 3xx or an empty 503 is unhealthy too. Read the item before changing source; scheduled runs are in function_runs_list, not here.",
|
|
1312
1351
|
z.object({
|
|
1313
1352
|
project_id: identifier,
|
|
1314
1353
|
deployment_id: identifier,
|
|
@@ -1325,7 +1364,7 @@ export function createLocalOhmyhostMcpServer(dependencies: LocalOhmyhostMcpDepen
|
|
|
1325
1364
|
server,
|
|
1326
1365
|
dependencies,
|
|
1327
1366
|
"operation_get",
|
|
1328
|
-
"Get durable operation status and current deployment progress/reconciliation guidance. Follow progress.phase and progress.suggested_action. waiting_for_mail requires mail_domain_status now for the current verification issue and DNS records; publishing means the build completed but runtime preparation/publication is unfinished. Poll this operation after progress.next_poll_after_seconds. A queued/running operation with reconciliation.state=required needs one confirmed operation_reconcile using the same operation; pending means poll this operation after 60 seconds. Never infer deployment success from a completed reconciliation attempt or start another build to recover it.",
|
|
1367
|
+
"Get durable operation status and current deployment progress/reconciliation guidance. Follow progress.phase and progress.suggested_action. waiting_for_mail requires mail_domain_status now for the current verification issue and DNS records; publishing means the build completed but runtime preparation/publication is unfinished. Poll this operation after progress.next_poll_after_seconds. A queued/running operation with reconciliation.state=required needs one confirmed operation_reconcile using the same operation; pending means poll this operation after 60 seconds. Never infer deployment success from a completed reconciliation attempt or start another build to recover it. A deploy, promotion or rollback names its deployment_id in every state; when state is failed, read that deployment with deployment_logs and follow error.suggested_action before changing source.",
|
|
1329
1368
|
z.object({ operation_id: identifier }),
|
|
1330
1369
|
(client, input) => client.getOperation(input.operation_id),
|
|
1331
1370
|
);
|
|
@@ -80,6 +80,8 @@ import {
|
|
|
80
80
|
parseProjectCreditBudget,
|
|
81
81
|
parseDevAccessTicket,
|
|
82
82
|
parseDevAccessState,
|
|
83
|
+
parsePoweredByFlag,
|
|
84
|
+
parseOrganizationReferral,
|
|
83
85
|
parseGuardedActionPlan,
|
|
84
86
|
parseEnvironmentSecret,
|
|
85
87
|
parseEnvironmentSecretDeletion,
|
|
@@ -304,6 +306,8 @@ const HELP_USAGE = Object.freeze({
|
|
|
304
306
|
"export get":
|
|
305
307
|
"ohmyhost export get EXPORT_ULID --project ULID --json (poll the original job; signed ZIP download lasts 24 hours)",
|
|
306
308
|
"credits account": "ohmyhost credits account --organization ULID --json",
|
|
309
|
+
"referral link":
|
|
310
|
+
"ohmyhost referral link --organization ULID --json (the workspace's link to share; a new user who signs up through it starts with a free Paid month and 1,000 credits, and their first payment gives this workspace the same)",
|
|
307
311
|
"credits balance": "ohmyhost credits balance --organization ULID --json",
|
|
308
312
|
"billing recharge get": "ohmyhost billing recharge get --organization ULID --json",
|
|
309
313
|
"billing recharge set":
|
|
@@ -350,6 +354,9 @@ const HELP_USAGE = Object.freeze({
|
|
|
350
354
|
"ohmyhost project dev-share revoke --project ULID --idempotency-key KEY --yes --json",
|
|
351
355
|
"project dev-access mode":
|
|
352
356
|
"ohmyhost project dev-access mode --project ULID --mode protected|public --idempotency-key KEY --yes --json",
|
|
357
|
+
"project flag status": "ohmyhost project flag status --project ULID --json",
|
|
358
|
+
"project flag set":
|
|
359
|
+
"ohmyhost project flag set --project ULID --enabled true|false --idempotency-key KEY --json (shows the small Powered by ohmyho.st flag on the production site; while it shows, a Free workspace may connect its own domain without the domain fee and each Paid period adds 250 credits)",
|
|
353
360
|
"project handle check":
|
|
354
361
|
"ohmyhost project handle check --handle HANDLE --json (is this address free? answers with a reason and free alternatives; the address becomes HANDLE.check.omh.st)",
|
|
355
362
|
"project handle set":
|
|
@@ -619,6 +626,13 @@ export class ProductCli {
|
|
|
619
626
|
}
|
|
620
627
|
return success(name, { status: "succeeded", billing: result });
|
|
621
628
|
}
|
|
629
|
+
if (command.kind === "referral-link") {
|
|
630
|
+
const api = await this.authenticatedApi(command.credentialStore, signal);
|
|
631
|
+
const referral = parseOrganizationReferral(
|
|
632
|
+
await api.getOrganizationReferral(command.organizationId),
|
|
633
|
+
);
|
|
634
|
+
return success("referral link", { status: "succeeded", referral });
|
|
635
|
+
}
|
|
622
636
|
if (command.kind === "credits-account") {
|
|
623
637
|
const api = await this.authenticatedApi(command.credentialStore, signal);
|
|
624
638
|
const account = await api.getOrganizationAccount(command.organizationId);
|
|
@@ -809,6 +823,22 @@ export class ProductCli {
|
|
|
809
823
|
if (command.kind === "project-status") return await this.getProjectStatus(command, signal);
|
|
810
824
|
if (command.kind === "project-dev-access-create")
|
|
811
825
|
return await this.createDevAccessTicket(command, signal);
|
|
826
|
+
if (command.kind === "project-flag-status" || command.kind === "project-flag-set") {
|
|
827
|
+
const api = await this.authenticatedApi(command.credentialStore, signal);
|
|
828
|
+
const flag = parsePoweredByFlag(
|
|
829
|
+
command.kind === "project-flag-status"
|
|
830
|
+
? await api.getPoweredByFlag(command.projectId)
|
|
831
|
+
: await api.setPoweredByFlag(
|
|
832
|
+
command.projectId,
|
|
833
|
+
command.enabled,
|
|
834
|
+
command.idempotencyKey,
|
|
835
|
+
),
|
|
836
|
+
);
|
|
837
|
+
return success(
|
|
838
|
+
command.kind === "project-flag-status" ? "project flag status" : "project flag set",
|
|
839
|
+
{ status: "succeeded", flag },
|
|
840
|
+
);
|
|
841
|
+
}
|
|
812
842
|
if (
|
|
813
843
|
command.kind === "project-dev-share-link" ||
|
|
814
844
|
command.kind === "project-dev-share-rotate" ||
|
|
@@ -2450,6 +2480,7 @@ const parsedCommandName = (command: ProductCliCommand): CommandLabel => {
|
|
|
2450
2480
|
if (command.kind === "billing-status") return "billing status";
|
|
2451
2481
|
if (command.kind === "billing-portal") return "billing portal";
|
|
2452
2482
|
if (command.kind === "credits-account") return "credits account";
|
|
2483
|
+
if (command.kind === "referral-link") return "referral link";
|
|
2453
2484
|
if (command.kind === "credits-balance") return "credits balance";
|
|
2454
2485
|
if (command.kind === "credits-usage") return "credits usage";
|
|
2455
2486
|
if (command.kind === "budget-get") return "budget get";
|
|
@@ -2475,6 +2506,8 @@ const parsedCommandName = (command: ProductCliCommand): CommandLabel => {
|
|
|
2475
2506
|
if (command.kind === "project-dev-share-rotate") return "project dev-share rotate";
|
|
2476
2507
|
if (command.kind === "project-dev-share-revoke") return "project dev-share revoke";
|
|
2477
2508
|
if (command.kind === "project-dev-access-mode-set") return "project dev-access mode";
|
|
2509
|
+
if (command.kind === "project-flag-status") return "project flag status";
|
|
2510
|
+
if (command.kind === "project-flag-set") return "project flag set";
|
|
2478
2511
|
if (command.kind === "project-handle-check") return "project handle check";
|
|
2479
2512
|
if (command.kind === "project-handle-set") return "project handle set";
|
|
2480
2513
|
if (command.kind === "database-write") return "database write";
|
|
@@ -127,6 +127,11 @@ export type ProductCliCommand =
|
|
|
127
127
|
readonly organizationId: string;
|
|
128
128
|
readonly credentialStore: "native";
|
|
129
129
|
}
|
|
130
|
+
| {
|
|
131
|
+
readonly kind: "referral-link";
|
|
132
|
+
readonly organizationId: string;
|
|
133
|
+
readonly credentialStore: "native";
|
|
134
|
+
}
|
|
130
135
|
| {
|
|
131
136
|
readonly kind: "credits-balance";
|
|
132
137
|
readonly organizationId: string;
|
|
@@ -256,6 +261,18 @@ export type ProductCliCommand =
|
|
|
256
261
|
readonly projectId: string;
|
|
257
262
|
readonly credentialStore: "native";
|
|
258
263
|
}
|
|
264
|
+
| {
|
|
265
|
+
readonly kind: "project-flag-status";
|
|
266
|
+
readonly projectId: string;
|
|
267
|
+
readonly credentialStore: "native";
|
|
268
|
+
}
|
|
269
|
+
| {
|
|
270
|
+
readonly kind: "project-flag-set";
|
|
271
|
+
readonly projectId: string;
|
|
272
|
+
readonly enabled: boolean;
|
|
273
|
+
readonly idempotencyKey: string;
|
|
274
|
+
readonly credentialStore: "native";
|
|
275
|
+
}
|
|
259
276
|
| {
|
|
260
277
|
readonly kind: "database-write";
|
|
261
278
|
readonly projectId: string;
|
|
@@ -549,6 +566,7 @@ export type RecognizedCommandLabel =
|
|
|
549
566
|
| "version"
|
|
550
567
|
| "whoami"
|
|
551
568
|
| "credits account"
|
|
569
|
+
| "referral link"
|
|
552
570
|
| "credits balance"
|
|
553
571
|
| "credits usage"
|
|
554
572
|
| "budget get"
|
|
@@ -577,6 +595,8 @@ export type RecognizedCommandLabel =
|
|
|
577
595
|
| "project dev-share rotate"
|
|
578
596
|
| "project dev-share revoke"
|
|
579
597
|
| "project dev-access mode"
|
|
598
|
+
| "project flag status"
|
|
599
|
+
| "project flag set"
|
|
580
600
|
| "project handle check"
|
|
581
601
|
| "project handle set"
|
|
582
602
|
| "database write"
|
|
@@ -656,6 +676,7 @@ export const recognizedCommandLabel = (argv: readonly string[]): RecognizedComma
|
|
|
656
676
|
if (value === "github" && values[0] === "status") return "github status";
|
|
657
677
|
if (value === "operation" && values[0] === "get") return "operation get";
|
|
658
678
|
if (value === "credits" && values[0] === "account") return "credits account";
|
|
679
|
+
if (value === "referral" && values[0] === "link") return "referral link";
|
|
659
680
|
if (value === "credits" && values[0] === "balance") return "credits balance";
|
|
660
681
|
if (value === "billing" && values[0] === "recharge" && values[1] === "get")
|
|
661
682
|
return "billing recharge get";
|
|
@@ -701,6 +722,10 @@ export const recognizedCommandLabel = (argv: readonly string[]): RecognizedComma
|
|
|
701
722
|
return "project dev-access mode";
|
|
702
723
|
if (value === "project" && values[0] === "dev-access" && values[1] === "create")
|
|
703
724
|
return "project dev-access create";
|
|
725
|
+
if (value === "project" && values[0] === "flag" && values[1] === "status")
|
|
726
|
+
return "project flag status";
|
|
727
|
+
if (value === "project" && values[0] === "flag" && values[1] === "set")
|
|
728
|
+
return "project flag set";
|
|
704
729
|
if (value === "database" && values[0] === "compute" && values[1] === "set")
|
|
705
730
|
return "database compute set";
|
|
706
731
|
if (value === "database" && values[0] === "compute" && values[1] === "get")
|
|
@@ -1080,6 +1105,12 @@ export const parseProductCliCommand = (argv: readonly string[]): ProductCliComma
|
|
|
1080
1105
|
const options = parseOptions(values, ["--organization"]);
|
|
1081
1106
|
return { kind: "credits-account", organizationId: options["--organization"], credentialStore };
|
|
1082
1107
|
}
|
|
1108
|
+
if (first === "referral" && values[0] === "link") {
|
|
1109
|
+
values.shift();
|
|
1110
|
+
if (yes || wait || follow || stdin) throw new InvalidCommandError();
|
|
1111
|
+
const options = parseOptions(values, ["--organization"]);
|
|
1112
|
+
return { kind: "referral-link", organizationId: options["--organization"], credentialStore };
|
|
1113
|
+
}
|
|
1083
1114
|
if (first === "credits" && values.shift() === "balance") {
|
|
1084
1115
|
if (yes || wait || follow || stdin) throw new InvalidCommandError();
|
|
1085
1116
|
const options = parseOptions(values, ["--organization"]);
|
|
@@ -1266,6 +1297,27 @@ export const parseProductCliCommand = (argv: readonly string[]): ProductCliComma
|
|
|
1266
1297
|
credentialStore,
|
|
1267
1298
|
};
|
|
1268
1299
|
}
|
|
1300
|
+
if (subcommand === "flag") {
|
|
1301
|
+
const action = values.shift();
|
|
1302
|
+
if (yes || wait || follow || stdin) throw new InvalidCommandError();
|
|
1303
|
+
if (action === "status") {
|
|
1304
|
+
const options = parseOptions(values, ["--project"]);
|
|
1305
|
+
return { kind: "project-flag-status", projectId: options["--project"], credentialStore };
|
|
1306
|
+
}
|
|
1307
|
+
if (action === "set") {
|
|
1308
|
+
const options = parseOptions(values, ["--project", "--enabled", "--idempotency-key"]);
|
|
1309
|
+
if (options["--enabled"] !== "true" && options["--enabled"] !== "false")
|
|
1310
|
+
throw new InvalidCommandError();
|
|
1311
|
+
return {
|
|
1312
|
+
kind: "project-flag-set",
|
|
1313
|
+
projectId: options["--project"],
|
|
1314
|
+
enabled: options["--enabled"] === "true",
|
|
1315
|
+
idempotencyKey: options["--idempotency-key"],
|
|
1316
|
+
credentialStore,
|
|
1317
|
+
};
|
|
1318
|
+
}
|
|
1319
|
+
throw new InvalidCommandError();
|
|
1320
|
+
}
|
|
1269
1321
|
if (subcommand === "dev-access" && values.shift() === "create") {
|
|
1270
1322
|
if (yes || wait || follow || stdin) throw new InvalidCommandError();
|
|
1271
1323
|
const options = parseOptions(values, ["--project"]);
|