run402-mcp 4.9.0 → 4.10.0
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/package.json +3 -3
- package/schemas/release-spec.v1.json +47 -0
- package/sdk/dist/actions.d.ts +20 -1
- package/sdk/dist/actions.d.ts.map +1 -1
- package/sdk/dist/actions.js.map +1 -1
- package/sdk/dist/node/actions-node.d.ts.map +1 -1
- package/sdk/dist/node/actions-node.js +114 -8
- package/sdk/dist/node/actions-node.js.map +1 -1
- package/sdk/dist/node/deploy-manifest.d.ts +36 -0
- package/sdk/dist/node/deploy-manifest.d.ts.map +1 -1
- package/sdk/dist/node/deploy-manifest.js +112 -3
- package/sdk/dist/node/deploy-manifest.js.map +1 -1
- package/sdk/dist/node/index.d.ts +1 -1
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "run402-mcp",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.10.0",
|
|
4
4
|
"description": "MCP server for Run402 — AI-native Postgres databases with REST API, auth, storage, and row-level security. Pay with x402 USDC micropayments.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"test:sync": "node --test --import tsx sync.test.ts examples/tenant-x402-wallet-stats/example.test.mjs",
|
|
31
31
|
"test:run402-app-schema-drift": "node scripts/check-run402-app-schema-drift.mjs",
|
|
32
32
|
"test:docs": "node scripts/check-typed-config-docs.mjs && npm run check:docs --workspace=@run402/sdk -- --skip-build",
|
|
33
|
-
"test": "npm run build && node --experimental-test-module-mocks --test --import tsx SKILL.test.ts sync.test.ts examples/tenant-x402-wallet-stats/example.test.mjs 'core/src/**/*.test.ts' 'sdk/src/**/*.test.ts' 'src/**/*.test.ts' && node --test cli-core-target.test.mjs && node --experimental-test-module-mocks --test cli-up-argv.test.mjs && node --test cli-output-contract.test.mjs cli-e2e.test.mjs cli-help.test.mjs cli-provision-active.test.mjs cli-typed-config-modes.test.mjs cli-argv.test.mjs cli-conventions-gate.test.mjs cli-env.test.mjs cli-wallets.test.mjs cli-org.test.mjs cli-ci.test.mjs cli-deploy-ci.test.mjs cli-operator-loopback.test.mjs cli/lib/doctor-source-scan.test.mjs cli/lib/errors.test.mjs cli-bootstrap-next-actions.test.mjs && npm run test:docs",
|
|
34
|
-
"test:e2e": "npm run build && node --test cli-core-target.test.mjs && node --test cli-output-contract.test.mjs cli-e2e.test.mjs cli-help.test.mjs cli-provision-active.test.mjs cli-typed-config-modes.test.mjs cli-argv.test.mjs cli-conventions-gate.test.mjs cli-env.test.mjs cli-wallets.test.mjs cli-org.test.mjs cli-ci.test.mjs cli-deploy-ci.test.mjs cli-operator-loopback.test.mjs cli/lib/doctor-source-scan.test.mjs cli/lib/errors.test.mjs cli-bootstrap-next-actions.test.mjs",
|
|
33
|
+
"test": "npm run build && node --experimental-test-module-mocks --test --import tsx SKILL.test.ts sync.test.ts examples/tenant-x402-wallet-stats/example.test.mjs 'core/src/**/*.test.ts' 'sdk/src/**/*.test.ts' 'src/**/*.test.ts' && node --test cli-core-target.test.mjs && node --experimental-test-module-mocks --test cli-up-argv.test.mjs && node --test cli-output-contract.test.mjs cli-e2e.test.mjs cli-help.test.mjs cli-provision-active.test.mjs cli-typed-config-modes.test.mjs cli-argv.test.mjs cli-conventions-gate.test.mjs cli-suggestions-gate.test.mjs cli-env.test.mjs cli-wallets.test.mjs cli-org.test.mjs cli-ci.test.mjs cli-deploy-ci.test.mjs cli-operator-loopback.test.mjs cli/lib/doctor-source-scan.test.mjs cli/lib/errors.test.mjs cli-bootstrap-next-actions.test.mjs && npm run test:docs",
|
|
34
|
+
"test:e2e": "npm run build && node --test cli-core-target.test.mjs && node --test cli-output-contract.test.mjs cli-e2e.test.mjs cli-help.test.mjs cli-provision-active.test.mjs cli-typed-config-modes.test.mjs cli-argv.test.mjs cli-conventions-gate.test.mjs cli-suggestions-gate.test.mjs cli-env.test.mjs cli-wallets.test.mjs cli-org.test.mjs cli-ci.test.mjs cli-deploy-ci.test.mjs cli-operator-loopback.test.mjs cli/lib/doctor-source-scan.test.mjs cli/lib/errors.test.mjs cli-bootstrap-next-actions.test.mjs",
|
|
35
35
|
"test:help": "npm run build && node --test cli-help.test.mjs",
|
|
36
36
|
"test:integration": "node --test --import tsx core/src/siwx-integration.integ.ts",
|
|
37
37
|
"test:integration:full": "node --test --import tsx cli-integration.test.ts",
|
|
@@ -64,6 +64,10 @@
|
|
|
64
64
|
{ "type": "null" },
|
|
65
65
|
{ "$ref": "#/$defs/i18n" }
|
|
66
66
|
]
|
|
67
|
+
},
|
|
68
|
+
"verify": {
|
|
69
|
+
"$ref": "#/$defs/verify",
|
|
70
|
+
"description": "Authoring-only post-apply HTTP verification, run by `run402 up` after a successful apply and rerunnable with `run402 up verify`. Stripped before deploy planning (never part of the wire ReleaseSpec)."
|
|
67
71
|
}
|
|
68
72
|
},
|
|
69
73
|
"anyOf": [
|
|
@@ -638,6 +642,49 @@
|
|
|
638
642
|
"description": "Confirmation token echoed back from a prior plan; required to commit a destructive sync."
|
|
639
643
|
}
|
|
640
644
|
}
|
|
645
|
+
},
|
|
646
|
+
"verify": {
|
|
647
|
+
"type": "object",
|
|
648
|
+
"additionalProperties": false,
|
|
649
|
+
"properties": {
|
|
650
|
+
"http": {
|
|
651
|
+
"type": "array",
|
|
652
|
+
"items": { "$ref": "#/$defs/verifyHttpCheck" }
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
},
|
|
656
|
+
"verifyHttpCheck": {
|
|
657
|
+
"type": "object",
|
|
658
|
+
"additionalProperties": false,
|
|
659
|
+
"required": ["id"],
|
|
660
|
+
"properties": {
|
|
661
|
+
"id": { "type": "string", "minLength": 1 },
|
|
662
|
+
"path": {
|
|
663
|
+
"type": "string",
|
|
664
|
+
"minLength": 1,
|
|
665
|
+
"description": "Request path resolved against the project public origin."
|
|
666
|
+
},
|
|
667
|
+
"url": { "type": "string", "minLength": 1 },
|
|
668
|
+
"expect": {
|
|
669
|
+
"type": "object",
|
|
670
|
+
"additionalProperties": false,
|
|
671
|
+
"required": ["status"],
|
|
672
|
+
"properties": {
|
|
673
|
+
"status": { "type": "integer", "minimum": 100, "maximum": 599 }
|
|
674
|
+
}
|
|
675
|
+
},
|
|
676
|
+
"expected_status": {
|
|
677
|
+
"type": "integer",
|
|
678
|
+
"minimum": 100,
|
|
679
|
+
"maximum": 599,
|
|
680
|
+
"description": "Snake-case alias for expect.status."
|
|
681
|
+
},
|
|
682
|
+
"retries": { "type": "integer", "minimum": 1 }
|
|
683
|
+
},
|
|
684
|
+
"allOf": [
|
|
685
|
+
{ "anyOf": [ { "required": ["path"] }, { "required": ["url"] } ] },
|
|
686
|
+
{ "anyOf": [ { "required": ["expect"] }, { "required": ["expected_status"] } ] }
|
|
687
|
+
]
|
|
641
688
|
}
|
|
642
689
|
}
|
|
643
690
|
}
|
package/sdk/dist/actions.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DeployResult, PlanResponse, ReleaseSpec } from "./namespaces/deploy.types.js";
|
|
2
|
-
import type { Run402AppInstallGraph, Run402AppUpResultEnvelope } from "./app-up.js";
|
|
2
|
+
import type { Run402AppInstallGraph, Run402AppInstallNodeStatus, Run402AppUpResultEnvelope, Run402AppUpVerifyResult } from "./app-up.js";
|
|
3
3
|
import type { ProvisionResult } from "./namespaces/projects.types.js";
|
|
4
4
|
import type { TierName, TierSetResult } from "./namespaces/tier.js";
|
|
5
5
|
import type { Run402ExecutionMode } from "./config.js";
|
|
@@ -133,6 +133,18 @@ export interface Run402ActionResult<T = unknown> {
|
|
|
133
133
|
steps: Run402ActionStep[];
|
|
134
134
|
result?: T;
|
|
135
135
|
}
|
|
136
|
+
/** One post-apply HTTP verification result entry (deploy-manifest `verify.http[]`).
|
|
137
|
+
* Same shape as `Run402AppUpResultEnvelope["verification"]["http"][number]`. */
|
|
138
|
+
export interface Run402UpVerificationHttpEntry {
|
|
139
|
+
id: string;
|
|
140
|
+
status: Run402AppInstallNodeStatus;
|
|
141
|
+
path?: string;
|
|
142
|
+
url?: string;
|
|
143
|
+
expected_status: number;
|
|
144
|
+
actual_status?: number | null;
|
|
145
|
+
propagation_wait_ms?: number;
|
|
146
|
+
diagnostic?: Record<string, unknown>;
|
|
147
|
+
}
|
|
136
148
|
export interface Run402UpResult {
|
|
137
149
|
project_id: string;
|
|
138
150
|
manifest_path: string;
|
|
@@ -142,6 +154,13 @@ export interface Run402UpResult {
|
|
|
142
154
|
spec?: ReleaseSpec;
|
|
143
155
|
plan?: PlanResponse;
|
|
144
156
|
deploy?: DeployResult;
|
|
157
|
+
/** Deploy-manifest `verify.http[]` per-check results (app manifests report
|
|
158
|
+
* the same shape under `app_result.verification.http[]`). */
|
|
159
|
+
verification?: {
|
|
160
|
+
http: Run402UpVerificationHttpEntry[];
|
|
161
|
+
};
|
|
162
|
+
/** Deploy-manifest verify rollup (app manifests: `app_result.verify`). */
|
|
163
|
+
verify?: Run402AppUpVerifyResult;
|
|
145
164
|
}
|
|
146
165
|
export type Run402ProjectsProvisionActionResult = Run402ActionResult<ProvisionResult>;
|
|
147
166
|
export type Run402TierSetActionResult = Run402ActionResult<TierSetResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC5F,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
|
package/sdk/dist/actions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,iBAAiB,EAAE,oBAAoB;IACvC,OAAO,EAAE,UAAU;IACnB,EAAE,EAAE,IAAI;CACA,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions-node.d.ts","sourceRoot":"","sources":["../../src/node/actions-node.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAIV,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EAGb,kCAAkC,EAClC,wBAAwB,EACxB,mBAAmB,EACnB,cAAc,
|
|
1
|
+
{"version":3,"file":"actions-node.d.ts","sourceRoot":"","sources":["../../src/node/actions-node.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAIV,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EAGb,kCAAkC,EAClC,wBAAwB,EACxB,mBAAmB,EACnB,cAAc,EAEf,MAAM,eAAe,CAAC;AAmBvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAS1C,OAAO,KAAK,EAAkB,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,KAAK,EAAY,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGrE,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAmKD;;;GAGG;AACH,qBAAa,WAAY,YAAW,aAAa;;IAE7C,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBADJ,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,kBAAuB;IAG1C,GAAG,CACP,KAAK,EAAE,kCAAkC,EACzC,IAAI,CAAC,EAAE,sBAAsB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACzC,GAAG,CACP,KAAK,EAAE,wBAAwB,EAC/B,IAAI,CAAC,EAAE,sBAAsB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;IACvC,GAAG,CACP,KAAK,EAAE,mBAAmB,EAC1B,IAAI,CAAC,EAAE,sBAAsB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;IAmCxC,EAAE,CACN,KAAK,GAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAM,EAC7C,IAAI,CAAC,EAAE,sBAAsB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;CAs1D/C"}
|
|
@@ -207,6 +207,9 @@ export class NodeActions {
|
|
|
207
207
|
}
|
|
208
208
|
return this.#applyAppManifest(input, manifest, workspaceDir, run, startedAt);
|
|
209
209
|
}
|
|
210
|
+
if (input.verifyOnly) {
|
|
211
|
+
return this.#verifyDeployManifestOnly(input, manifest, workspaceDir, run);
|
|
212
|
+
}
|
|
210
213
|
if (run.executionMode === "check" || run.executionMode === "printSpec") {
|
|
211
214
|
if (!manifest.releaseSpec) {
|
|
212
215
|
throw run.error("Internal error: release manifest did not produce a ReleaseSpec.", "RUN402_ACTION_INTERNAL");
|
|
@@ -275,7 +278,7 @@ export class NodeActions {
|
|
|
275
278
|
});
|
|
276
279
|
}
|
|
277
280
|
run.setState(deployStep, "running");
|
|
278
|
-
await this.#assertLocalProjectKeys(resolved.projectId, run);
|
|
281
|
+
const projectKeys = await this.#assertLocalProjectKeys(resolved.projectId, run);
|
|
279
282
|
const scoped = await this.sdk.project(resolved.projectId);
|
|
280
283
|
const explicitDeployIdempotencyKey = input.idempotencyKey ?? normalized.idempotencyKey ?? manifest.idempotencyKey;
|
|
281
284
|
if (run.executionMode === "plan") {
|
|
@@ -317,11 +320,73 @@ export class NodeActions {
|
|
|
317
320
|
release_id: deploy.release_id,
|
|
318
321
|
operation_id: deploy.operation_id,
|
|
319
322
|
});
|
|
323
|
+
// Deploy-manifest verify.http[] — same propagation-tolerant checks the
|
|
324
|
+
// app-spec path runs, surfaced as `verification.http[]` + `verify` on
|
|
325
|
+
// the up result.
|
|
326
|
+
const verifyChecks = manifest.verify?.http ?? [];
|
|
327
|
+
let verifyBlock = {};
|
|
328
|
+
if (verifyChecks.length > 0) {
|
|
329
|
+
// The deploy result's own urls are the authoritative origin for THIS
|
|
330
|
+
// release (fresh subdomain claims included); the keystore's cached
|
|
331
|
+
// site_url is only a fallback. Resolving from the stale keystore alone
|
|
332
|
+
// produced silent null-origin check failures (2026-07-19 live find).
|
|
333
|
+
const publicOrigin = deploy.urls?.site ?? deploy.urls?.subdomain ?? projectKeys.site_url ?? null;
|
|
334
|
+
const verification = await this.#verifyHttpChecks(verifyChecks, publicOrigin, run, {
|
|
335
|
+
projectId: resolved.projectId,
|
|
336
|
+
claimedHosts: claimedHostsFromRelease(releaseSpec, publicOrigin),
|
|
337
|
+
bindings: deploy.subdomain_bindings ?? [],
|
|
338
|
+
propagationBudgetMs: propagationBudgetMs(input),
|
|
339
|
+
propagationWait: input.propagationWait !== false,
|
|
340
|
+
resolve: (opts) => scoped.apply.resolve(opts),
|
|
341
|
+
});
|
|
342
|
+
verifyBlock = {
|
|
343
|
+
verification: { http: buildVerificationHttpEntries(verifyChecks, verification) },
|
|
344
|
+
verify: appVerifyResult(verification),
|
|
345
|
+
};
|
|
346
|
+
}
|
|
320
347
|
return run.result({
|
|
321
348
|
project_id: resolved.projectId,
|
|
322
349
|
manifest_path: manifest.manifestPath,
|
|
323
350
|
...(resolved.shouldWriteLink ? { workspace_link_path: resolved.linkPath } : {}),
|
|
324
351
|
deploy,
|
|
352
|
+
...verifyBlock,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
async #verifyDeployManifestOnly(input, manifest, workspaceDir, run) {
|
|
356
|
+
const checks = manifest.verify?.http ?? [];
|
|
357
|
+
if (checks.length === 0) {
|
|
358
|
+
throw run.error("Deploy manifest does not define verify.http checks.", "VERIFY_CHECKS_REQUIRED", { manifest_path: manifest.manifestPath });
|
|
359
|
+
}
|
|
360
|
+
const resolved = await this.#resolveProjectForVerify(input, manifest, workspaceDir, run);
|
|
361
|
+
const projectKeys = await this.sdk.projects.keys(resolved.projectId);
|
|
362
|
+
// Keystore site_url first (no network), else the server-authoritative
|
|
363
|
+
// project record — a project provisioned elsewhere has keys without a
|
|
364
|
+
// cached site_url, and path checks need a real origin.
|
|
365
|
+
let publicOrigin = projectKeys.site_url ?? null;
|
|
366
|
+
if (publicOrigin === null) {
|
|
367
|
+
try {
|
|
368
|
+
const detail = await this.sdk.projects.get(resolved.projectId);
|
|
369
|
+
publicOrigin = detail.site_url ?? null;
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
// Fall through with null; the checker reports a per-check
|
|
373
|
+
// missing-origin diagnostic instead of failing silently.
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
const scoped = await this.sdk.project(resolved.projectId);
|
|
377
|
+
const verification = await this.#verifyHttpChecks(checks, publicOrigin, run, {
|
|
378
|
+
projectId: resolved.projectId,
|
|
379
|
+
claimedHosts: new Set(),
|
|
380
|
+
bindings: [],
|
|
381
|
+
propagationBudgetMs: propagationBudgetMs(input),
|
|
382
|
+
propagationWait: input.propagationWait !== false,
|
|
383
|
+
resolve: (opts) => scoped.apply.resolve(opts),
|
|
384
|
+
});
|
|
385
|
+
return run.result({
|
|
386
|
+
project_id: resolved.projectId,
|
|
387
|
+
manifest_path: manifest.manifestPath,
|
|
388
|
+
verification: { http: buildVerificationHttpEntries(checks, verification) },
|
|
389
|
+
verify: appVerifyResult(verification),
|
|
325
390
|
});
|
|
326
391
|
}
|
|
327
392
|
async #discoverAndValidateManifest(input, workspaceDir, source, run) {
|
|
@@ -405,6 +470,7 @@ export class NodeActions {
|
|
|
405
470
|
manifestProjectId: loaded.spec.project === "prj_up_preflight_placeholder"
|
|
406
471
|
? undefined
|
|
407
472
|
: loaded.spec.project,
|
|
473
|
+
...(loaded.verify ? { verify: loaded.verify } : {}),
|
|
408
474
|
};
|
|
409
475
|
}
|
|
410
476
|
async #resolveUpSource(input, run) {
|
|
@@ -518,7 +584,7 @@ export class NodeActions {
|
|
|
518
584
|
const projectKeys = await this.sdk.projects.keys(resolved.projectId);
|
|
519
585
|
const publicOrigin = appPublicOrigin(input, manifest.appSpec) ?? projectKeys.site_url ?? null;
|
|
520
586
|
const scoped = await this.sdk.project(resolved.projectId);
|
|
521
|
-
const verification = await this.#
|
|
587
|
+
const verification = await this.#verifyHttpChecks(manifest.appSpec.verify?.http ?? [], publicOrigin, run, {
|
|
522
588
|
projectId: resolved.projectId,
|
|
523
589
|
claimedHosts: new Set(),
|
|
524
590
|
bindings: [],
|
|
@@ -751,7 +817,7 @@ export class NodeActions {
|
|
|
751
817
|
propagationWait: input.propagationWait !== false,
|
|
752
818
|
resolve: (opts) => scoped.apply.resolve(opts),
|
|
753
819
|
};
|
|
754
|
-
const verification = await this.#
|
|
820
|
+
const verification = await this.#verifyHttpChecks(manifest.appSpec.verify?.http ?? [], publicOrigin, run, verifyContext);
|
|
755
821
|
markAppGraphNodesForVerify(manifest.appGraph, verification);
|
|
756
822
|
const appStatus = verification.ok
|
|
757
823
|
? "succeeded"
|
|
@@ -1092,8 +1158,7 @@ export class NodeActions {
|
|
|
1092
1158
|
run.setState(step, "succeeded", { webhooks });
|
|
1093
1159
|
return webhooks;
|
|
1094
1160
|
}
|
|
1095
|
-
async #
|
|
1096
|
-
const checks = spec.verify?.http ?? [];
|
|
1161
|
+
async #verifyHttpChecks(checks, publicOrigin, run, context) {
|
|
1097
1162
|
const results = new Map();
|
|
1098
1163
|
const diagnostics = [];
|
|
1099
1164
|
const warnings = [];
|
|
@@ -1118,18 +1183,26 @@ export class NodeActions {
|
|
|
1118
1183
|
for (const check of checks) {
|
|
1119
1184
|
const url = check.url ?? (publicOrigin && check.path ? new URL(check.path, publicOrigin).toString() : null);
|
|
1120
1185
|
if (!url) {
|
|
1186
|
+
const message = `HTTP verification ${check.id} needs either url or project public origin + path.`;
|
|
1121
1187
|
results.set(check.id, {
|
|
1122
1188
|
id: check.id,
|
|
1123
1189
|
ok: false,
|
|
1124
1190
|
propagationPending: false,
|
|
1125
1191
|
status: null,
|
|
1126
1192
|
propagationWaitMs: 0,
|
|
1193
|
+
// Surface WHY on the per-check entry itself — an unexplained
|
|
1194
|
+
// `actual_status: null` reads as a mystery network failure.
|
|
1195
|
+
diagnostic: {
|
|
1196
|
+
error: "missing_public_origin",
|
|
1197
|
+
message,
|
|
1198
|
+
hint: "Path checks resolve against the project's public origin. Use an absolute `url` in the check, or deploy/claim a subdomain so the project has a site URL.",
|
|
1199
|
+
},
|
|
1127
1200
|
});
|
|
1128
1201
|
diagnostics.push({
|
|
1129
1202
|
code: "VERIFY_FAILED",
|
|
1130
1203
|
severity: "error",
|
|
1131
1204
|
node_id: `verify.http.${check.id}`,
|
|
1132
|
-
message
|
|
1205
|
+
message,
|
|
1133
1206
|
});
|
|
1134
1207
|
continue;
|
|
1135
1208
|
}
|
|
@@ -1220,7 +1293,18 @@ export class NodeActions {
|
|
|
1220
1293
|
propagationPending: false,
|
|
1221
1294
|
status,
|
|
1222
1295
|
propagationWaitMs: checkPropagationWaitMs,
|
|
1223
|
-
|
|
1296
|
+
// A network-level fetch failure (status null) must carry its error
|
|
1297
|
+
// on the entry, not only in the diagnostics array.
|
|
1298
|
+
...(diagnosis || observed.error
|
|
1299
|
+
? {
|
|
1300
|
+
diagnostic: {
|
|
1301
|
+
...(observed.error ? { error: observed.error } : {}),
|
|
1302
|
+
...(diagnosis
|
|
1303
|
+
? { edge_propagation: diagnosis.edge_propagation ?? null, resolve: diagnosis }
|
|
1304
|
+
: {}),
|
|
1305
|
+
},
|
|
1306
|
+
}
|
|
1307
|
+
: {}),
|
|
1224
1308
|
});
|
|
1225
1309
|
break;
|
|
1226
1310
|
}
|
|
@@ -1622,7 +1706,7 @@ export class NodeActions {
|
|
|
1622
1706
|
}
|
|
1623
1707
|
async #assertLocalProjectKeys(projectId, run) {
|
|
1624
1708
|
try {
|
|
1625
|
-
await this.sdk.projects.keys(projectId);
|
|
1709
|
+
return await this.sdk.projects.keys(projectId);
|
|
1626
1710
|
}
|
|
1627
1711
|
catch (err) {
|
|
1628
1712
|
throw withActionDetails(new LocalError(`Project ${projectId} is selected, but its keys are not available locally. Use a project in the local keystore or provision/link from this machine.`, "resolving project keys for up", {
|
|
@@ -1835,6 +1919,28 @@ function markAppGraphNodesForVerify(graph, verification) {
|
|
|
1835
1919
|
: "failed";
|
|
1836
1920
|
}
|
|
1837
1921
|
}
|
|
1922
|
+
function buildVerificationHttpEntries(checks, verification) {
|
|
1923
|
+
return checks.map((check) => {
|
|
1924
|
+
const actual = verification.results.get(check.id);
|
|
1925
|
+
const status = actual === undefined
|
|
1926
|
+
? "planned"
|
|
1927
|
+
: actual.ok
|
|
1928
|
+
? "succeeded"
|
|
1929
|
+
: actual.propagationPending
|
|
1930
|
+
? "propagation_pending"
|
|
1931
|
+
: "failed";
|
|
1932
|
+
return {
|
|
1933
|
+
id: check.id,
|
|
1934
|
+
status,
|
|
1935
|
+
...(check.path !== undefined ? { path: check.path } : {}),
|
|
1936
|
+
...(check.url !== undefined ? { url: check.url } : {}),
|
|
1937
|
+
expected_status: check.expect.status,
|
|
1938
|
+
...(actual !== undefined ? { actual_status: actual.status } : {}),
|
|
1939
|
+
...(actual !== undefined ? { propagation_wait_ms: actual.propagationWaitMs } : {}),
|
|
1940
|
+
...(actual?.diagnostic ? { diagnostic: actual.diagnostic } : {}),
|
|
1941
|
+
};
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1838
1944
|
function appVerifyResult(verification) {
|
|
1839
1945
|
return {
|
|
1840
1946
|
status: verification.ok
|