@manifest-network/manifest-agent-core 0.14.0 → 0.16.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/dist/close-lease.d.ts.map +1 -1
- package/dist/close-lease.js +15 -3
- package/dist/close-lease.js.map +1 -1
- package/dist/deploy-app.d.ts +2 -2
- package/dist/deploy-app.d.ts.map +1 -1
- package/dist/deploy-app.js +84 -37
- package/dist/deploy-app.js.map +1 -1
- package/dist/deploy-app.test-d.d.ts +1 -0
- package/dist/deploy-app.test-d.js +11 -0
- package/dist/deploy-app.test-d.js.map +1 -0
- package/dist/guarded-fetch.d.ts +2 -0
- package/dist/guarded-fetch.js +2 -0
- package/dist/index.d.ts +2 -3
- package/dist/index.js +1 -2
- package/dist/internals/cancellation.d.ts +57 -0
- package/dist/internals/cancellation.d.ts.map +1 -0
- package/dist/internals/cancellation.js +79 -0
- package/dist/internals/cancellation.js.map +1 -0
- package/dist/internals/inspect-image.js +1 -1
- package/dist/internals/inspect-image.js.map +1 -1
- package/dist/internals/render-intent-recap.d.ts +13 -11
- package/dist/internals/render-intent-recap.d.ts.map +1 -1
- package/dist/internals/render-intent-recap.js +5 -4
- package/dist/internals/render-intent-recap.js.map +1 -1
- package/dist/internals/spec-normalize.d.ts +34 -28
- package/dist/internals/spec-normalize.d.ts.map +1 -1
- package/dist/internals/spec-normalize.js +28 -22
- package/dist/internals/spec-normalize.js.map +1 -1
- package/dist/manage-domain.d.ts.map +1 -1
- package/dist/manage-domain.js +34 -8
- package/dist/manage-domain.js.map +1 -1
- package/dist/node_modules/@vitest/pretty-format/dist/index.js +888 -0
- package/dist/node_modules/@vitest/pretty-format/dist/index.js.map +1 -0
- package/dist/node_modules/@vitest/runner/dist/chunk-artifact.js +1500 -0
- package/dist/node_modules/@vitest/runner/dist/chunk-artifact.js.map +1 -0
- package/dist/node_modules/@vitest/runner/dist/index.js +1 -0
- package/dist/node_modules/@vitest/runner/dist/utils.js +1 -0
- package/dist/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +82 -0
- package/dist/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js.map +1 -0
- package/dist/node_modules/@vitest/utils/dist/display.js +558 -0
- package/dist/node_modules/@vitest/utils/dist/display.js.map +1 -0
- package/dist/node_modules/@vitest/utils/dist/helpers.js +68 -0
- package/dist/node_modules/@vitest/utils/dist/helpers.js.map +1 -0
- package/dist/node_modules/@vitest/utils/dist/source-map.js +95 -0
- package/dist/node_modules/@vitest/utils/dist/source-map.js.map +1 -0
- package/dist/node_modules/@vitest/utils/dist/timers.js +20 -0
- package/dist/node_modules/@vitest/utils/dist/timers.js.map +1 -0
- package/dist/node_modules/tinyrainbow/dist/index.js +86 -0
- package/dist/node_modules/tinyrainbow/dist/index.js.map +1 -0
- package/dist/node_modules/vite/dist/node/module-runner.js +22 -0
- package/dist/node_modules/vite/dist/node/module-runner.js.map +1 -0
- package/dist/node_modules/vitest/dist/index.js +6 -0
- package/dist/troubleshoot.d.ts.map +1 -1
- package/dist/troubleshoot.js +11 -1
- package/dist/troubleshoot.js.map +1 -1
- package/dist/types.d.ts +30 -51
- package/dist/types.d.ts.map +1 -1
- package/package.json +15 -7
- package/dist/internals/build-fred-input.d.ts +0 -46
- package/dist/internals/build-fred-input.d.ts.map +0 -1
- package/dist/internals/build-fred-input.js +0 -160
- package/dist/internals/build-fred-input.js.map +0 -1
package/dist/troubleshoot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"troubleshoot.js","names":["decodeLeaseState"],"sources":["../src/troubleshoot.ts"],"sourcesContent":["/**\n * Public entry point: produce a markdown-formatted diagnostic report\n * for a given lease.\n *\n * Chain-only (no provider HTTP calls — `TroubleshootOptions` has no\n * `walletProvider` for ADR-036 auth). Composes:\n *\n * - `queryClient.liftedinit.billing.v1.lease({ leaseUuid })` for the\n * authoritative chain-side lease record.\n * - `lease-state.decode` + `isTerminal` to translate the integer\n * state into a canonical `LEASE_STATE_*` name and a\n * guidance-routing terminal/non-terminal classification.\n * - `lease-items.normalizeItem` to surface each item's serviceName\n * and customDomain regardless of snake/camelCase payload shape.\n *\n * The returned `markdown` is plain text with markdown formatting — host\n * surfaces can render it in chat directly or embed in a richer\n * diagnostic UI.\n *\n * **Scope:** chain-only. `TroubleshootOptions` carries no `walletProvider`,\n * so provider-side diagnostics (`appStatus` / `getLeaseProvision` /\n * `getAppLogs`) are out of scope for this function. If the report\n * surfaces a recovery-worthy state (e.g. terminal / drift), the caller\n * composes `closeLease()` separately — agent-core's simple-form\n * `onFailure({ reason })` does not carry recovery options, so the\n * orchestration of \"report → decide → close\" lives at the host surface.\n */\n\nimport {\n ManifestMCPError,\n ManifestMCPErrorCode,\n} from '@manifest-network/manifest-mcp-core';\nimport { normalizeItem } from './internals/lease-items.js';\nimport {\n decode as decodeLeaseState,\n isTerminal,\n} from './internals/lease-state.js';\nimport type {\n LeaseStateName,\n TroubleshootArgs,\n TroubleshootCallbacks,\n TroubleshootOptions,\n TroubleshootReport,\n} from './types.js';\n\nconst UUID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/**\n * Generate a diagnostic markdown report for `args.leaseUuid`.\n *\n * @throws `ManifestMCPError(INVALID_CONFIG)` for args validation.\n * @throws `ManifestMCPError(QUERY_FAILED)` in two cases, both with\n * `onFailure({ reason })` invoked first:\n * - the chain query rejects with a plain `Error` (RPC / transport\n * / decoding failure); or\n * - the chain query succeeds but returns `{ lease: null }` /\n * `undefined` (lease UUID not on-chain — the `billing.v1.lease`\n * no-such-lease response shape).\n * Structured `ManifestMCPError`s raised by the chain client\n * (e.g. `INVALID_CONFIG` from missing rpc/rest url config,\n * `RPC_CONNECTION_FAILED` from connect failure) are re-thrown\n * as-is with their original code, with `onFailure` invoked first.\n */\nexport async function troubleshootDeployment(\n args: TroubleshootArgs,\n callbacks: TroubleshootCallbacks,\n opts: TroubleshootOptions,\n): Promise<TroubleshootReport> {\n validateArgs(args);\n\n let leasePayload: unknown;\n try {\n // Pull `getQueryClient()` INSIDE the try (Copilot review PR #60,\n // comment 3276719462). `getQueryClient()` can throw\n // `INVALID_CONFIG` (neither rpcUrl nor restUrl set) or\n // `RPC_CONNECTION_FAILED` (connect failure). Catching here routes\n // those init-time failures through the same `onFailure` +\n // QUERY_FAILED / structured-passthrough normalization the chain-\n // query failure mode already gets — three modes, one disambiguation.\n const queryClient = await opts.clientManager.getQueryClient();\n const result = await queryClient.liftedinit.billing.v1.lease({\n leaseUuid: args.leaseUuid,\n });\n leasePayload = result.lease;\n } catch (err) {\n // Preserve structured `ManifestMCPError`s from the chain client\n // (Copilot review PR #60, comment 3276172289). Wrapping every\n // failure as `QUERY_FAILED` erases upstream error codes — a real\n // `INVALID_CONFIG` from the chain layer should surface to callers\n // with that code, not be collapsed to a less-specific category.\n // Mirrors the disambiguation `manage-domain.ts:lookupDomain`\n // adopted in commit aaa5cc5. Note: chain-NotFound for\n // `billing.v1.lease({ leaseUuid })` returns `{ lease: null }`\n // (handled below), so errors landing here are genuinely transport\n // or structured failures.\n const reason = `Failed to query lease ${args.leaseUuid}: ${err instanceof Error ? err.message : String(err)}`;\n if (callbacks.onFailure) {\n await callbacks.onFailure({ reason });\n }\n if (err instanceof ManifestMCPError) {\n throw err;\n }\n throw new ManifestMCPError(ManifestMCPErrorCode.QUERY_FAILED, reason);\n }\n\n if (leasePayload === null || leasePayload === undefined) {\n const reason = `Lease ${args.leaseUuid} not found on chain.`;\n if (callbacks.onFailure) {\n await callbacks.onFailure({ reason });\n }\n throw new ManifestMCPError(ManifestMCPErrorCode.QUERY_FAILED, reason);\n }\n\n const markdown = renderReport(args.leaseUuid, leasePayload);\n const report: TroubleshootReport = { markdown };\n callbacks.onComplete?.(report);\n return report;\n}\n\n// --- Helpers --------------------------------------------------------\n\nfunction validateArgs(args: TroubleshootArgs): void {\n if (typeof args.leaseUuid !== 'string' || !args.leaseUuid.match(UUID_RE)) {\n throw new ManifestMCPError(\n ManifestMCPErrorCode.INVALID_CONFIG,\n `troubleshootDeployment: leaseUuid must be a UUID; got \"${args.leaseUuid}\".`,\n );\n }\n}\n\ninterface LeaseShape {\n uuid?: unknown;\n state?: unknown;\n providerUuid?: unknown;\n provider_uuid?: unknown;\n createdAt?: unknown;\n created_at?: unknown;\n closedAt?: unknown;\n closed_at?: unknown;\n items?: unknown;\n}\n\nfunction renderReport(leaseUuid: string, lease: unknown): string {\n const l = (lease ?? {}) as LeaseShape;\n const rawState = l.state;\n const stateName = decodeLeaseState(\n typeof rawState === 'number' || typeof rawState === 'string'\n ? rawState\n : undefined,\n );\n const stateLabel = stateName ?? `UNKNOWN(${String(rawState)})`;\n const providerUuid =\n readString(l.providerUuid) || readString(l.provider_uuid) || '(unknown)';\n const createdAt = readTimestamp(l.createdAt) ?? readTimestamp(l.created_at);\n const closedAt = readTimestamp(l.closedAt) ?? readTimestamp(l.closed_at);\n\n const rawItems = Array.isArray(l.items) ? l.items : [];\n const items = rawItems.map(normalizeItem);\n\n const lines: string[] = [];\n lines.push(`# Lease diagnostic — ${leaseUuid}`);\n lines.push('');\n lines.push('## Chain state');\n lines.push('');\n lines.push(`- **State:** ${stateLabel}`);\n lines.push(`- **Provider:** ${providerUuid}`);\n if (createdAt) lines.push(`- **Created:** ${createdAt}`);\n if (closedAt) lines.push(`- **Closed:** ${closedAt}`);\n lines.push('');\n\n lines.push('## Items');\n lines.push('');\n if (items.length === 0) {\n lines.push('_No items found on this lease._');\n } else {\n for (const item of items) {\n const svc = item.serviceName.length > 0 ? item.serviceName : '(default)';\n const dom =\n item.customDomain.length > 0 ? item.customDomain : '(no custom domain)';\n lines.push(`- **${svc}** → ${dom}`);\n }\n }\n lines.push('');\n\n lines.push('## Guidance');\n lines.push('');\n for (const tip of guidanceFor(stateName)) {\n lines.push(`- ${tip}`);\n }\n\n return lines.join('\\n');\n}\n\nfunction guidanceFor(state: LeaseStateName | undefined): string[] {\n if (state === undefined) {\n return [\n 'Lease state could not be decoded. Re-query in a moment, or check the chain client logs for transport errors.',\n ];\n }\n if (isTerminal(state)) {\n return [\n `Lease is in terminal state \\`${state}\\`. No further provider activity expected.`,\n 'To redeploy, create a new lease via `deployApp`.',\n ];\n }\n switch (state) {\n case 'LEASE_STATE_PENDING':\n return [\n 'Lease is awaiting provider acknowledgement.',\n 'If pending persists for more than a few minutes, the provider may be offline; consider closing and redeploying.',\n ];\n case 'LEASE_STATE_ACTIVE':\n return [\n 'Lease is active on the provider. App-level status / logs require a provider HTTP call with an ADR-036 auth token (out of scope for this chain-only diagnostic).',\n ];\n default:\n return [\n `Lease state is \\`${state}\\`. Review the chain proto for the expected next transition.`,\n ];\n }\n}\n\nfunction readString(value: unknown): string {\n return typeof value === 'string' ? value : '';\n}\n\nfunction readTimestamp(value: unknown): string | undefined {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n return undefined;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"troubleshoot.js","names":["decodeLeaseState"],"sources":["../src/troubleshoot.ts"],"sourcesContent":["/**\n * Public entry point: produce a markdown-formatted diagnostic report\n * for a given lease.\n *\n * Chain-only (no provider HTTP calls — `TroubleshootOptions` has no\n * `walletProvider` for ADR-036 auth). Composes:\n *\n * - `queryClient.liftedinit.billing.v1.lease({ leaseUuid })` for the\n * authoritative chain-side lease record.\n * - `lease-state.decode` + `isTerminal` to translate the integer\n * state into a canonical `LEASE_STATE_*` name and a\n * guidance-routing terminal/non-terminal classification.\n * - `lease-items.normalizeItem` to surface each item's serviceName\n * and customDomain regardless of snake/camelCase payload shape.\n *\n * The returned `markdown` is plain text with markdown formatting — host\n * surfaces can render it in chat directly or embed in a richer\n * diagnostic UI.\n *\n * **Scope:** chain-only. `TroubleshootOptions` carries no `walletProvider`,\n * so provider-side diagnostics (`appStatus` / `getLeaseProvision` /\n * `getAppLogs`) are out of scope for this function. If the report\n * surfaces a recovery-worthy state (e.g. terminal / drift), the caller\n * composes `closeLease()` separately — agent-core's simple-form\n * `onFailure({ reason })` does not carry recovery options, so the\n * orchestration of \"report → decide → close\" lives at the host surface.\n */\n\nimport {\n ManifestMCPError,\n ManifestMCPErrorCode,\n} from '@manifest-network/manifest-mcp-core';\nimport { makeCancellationScope } from './internals/cancellation.js';\nimport { normalizeItem } from './internals/lease-items.js';\nimport {\n decode as decodeLeaseState,\n isTerminal,\n} from './internals/lease-state.js';\nimport type {\n LeaseStateName,\n TroubleshootArgs,\n TroubleshootCallbacks,\n TroubleshootOptions,\n TroubleshootReport,\n} from './types.js';\n\nconst UUID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/**\n * Generate a diagnostic markdown report for `args.leaseUuid`.\n *\n * @throws `ManifestMCPError(INVALID_CONFIG)` for args validation.\n * @throws `ManifestMCPError(QUERY_FAILED)` in two cases, both with\n * `onFailure({ reason })` invoked first:\n * - the chain query rejects with a plain `Error` (RPC / transport\n * / decoding failure); or\n * - the chain query succeeds but returns `{ lease: null }` /\n * `undefined` (lease UUID not on-chain — the `billing.v1.lease`\n * no-such-lease response shape).\n * Structured `ManifestMCPError`s raised by the chain client\n * (e.g. `INVALID_CONFIG` from missing rpc/rest url config,\n * `RPC_CONNECTION_FAILED` from connect failure) are re-thrown\n * as-is with their original code, with `onFailure` invoked first.\n */\nexport async function troubleshootDeployment(\n args: TroubleshootArgs,\n callbacks: TroubleshootCallbacks,\n opts: TroubleshootOptions,\n): Promise<TroubleshootReport> {\n validateArgs(args);\n\n const cx = makeCancellationScope({\n opts,\n onProgress: callbacks.onProgress,\n opLabel: 'Troubleshoot',\n broadcasts: false,\n });\n cx.throwIfCancelled();\n\n let leasePayload: unknown;\n try {\n // Pull `getQueryClient()` INSIDE the try (Copilot review PR #60,\n // comment 3276719462). `getQueryClient()` can throw\n // `INVALID_CONFIG` (neither rpcUrl nor restUrl set) or\n // `RPC_CONNECTION_FAILED` (connect failure). Catching here routes\n // those init-time failures through the same `onFailure` +\n // QUERY_FAILED / structured-passthrough normalization the chain-\n // query failure mode already gets — three modes, one disambiguation.\n const queryClient = await opts.clientManager.getQueryClient();\n const result = await cx.race(\n queryClient.liftedinit.billing.v1.lease({\n leaseUuid: args.leaseUuid,\n }),\n );\n leasePayload = result.lease;\n } catch (err) {\n if (\n err instanceof ManifestMCPError &&\n err.code === ManifestMCPErrorCode.OPERATION_CANCELLED\n ) {\n throw err;\n }\n // Preserve structured `ManifestMCPError`s from the chain client\n // (Copilot review PR #60, comment 3276172289). Wrapping every\n // failure as `QUERY_FAILED` erases upstream error codes — a real\n // `INVALID_CONFIG` from the chain layer should surface to callers\n // with that code, not be collapsed to a less-specific category.\n // Mirrors the disambiguation `manage-domain.ts:lookupDomain`\n // adopted in commit aaa5cc5. Note: chain-NotFound for\n // `billing.v1.lease({ leaseUuid })` returns `{ lease: null }`\n // (handled below), so errors landing here are genuinely transport\n // or structured failures.\n const reason = `Failed to query lease ${args.leaseUuid}: ${err instanceof Error ? err.message : String(err)}`;\n if (callbacks.onFailure) {\n await callbacks.onFailure({ reason });\n }\n if (err instanceof ManifestMCPError) {\n throw err;\n }\n throw new ManifestMCPError(ManifestMCPErrorCode.QUERY_FAILED, reason);\n }\n\n if (leasePayload === null || leasePayload === undefined) {\n const reason = `Lease ${args.leaseUuid} not found on chain.`;\n if (callbacks.onFailure) {\n await callbacks.onFailure({ reason });\n }\n throw new ManifestMCPError(ManifestMCPErrorCode.QUERY_FAILED, reason);\n }\n\n const markdown = renderReport(args.leaseUuid, leasePayload);\n const report: TroubleshootReport = { markdown };\n callbacks.onComplete?.(report);\n return report;\n}\n\n// --- Helpers --------------------------------------------------------\n\nfunction validateArgs(args: TroubleshootArgs): void {\n if (typeof args.leaseUuid !== 'string' || !args.leaseUuid.match(UUID_RE)) {\n throw new ManifestMCPError(\n ManifestMCPErrorCode.INVALID_CONFIG,\n `troubleshootDeployment: leaseUuid must be a UUID; got \"${args.leaseUuid}\".`,\n );\n }\n}\n\ninterface LeaseShape {\n uuid?: unknown;\n state?: unknown;\n providerUuid?: unknown;\n provider_uuid?: unknown;\n createdAt?: unknown;\n created_at?: unknown;\n closedAt?: unknown;\n closed_at?: unknown;\n items?: unknown;\n}\n\nfunction renderReport(leaseUuid: string, lease: unknown): string {\n const l = (lease ?? {}) as LeaseShape;\n const rawState = l.state;\n const stateName = decodeLeaseState(\n typeof rawState === 'number' || typeof rawState === 'string'\n ? rawState\n : undefined,\n );\n const stateLabel = stateName ?? `UNKNOWN(${String(rawState)})`;\n const providerUuid =\n readString(l.providerUuid) || readString(l.provider_uuid) || '(unknown)';\n const createdAt = readTimestamp(l.createdAt) ?? readTimestamp(l.created_at);\n const closedAt = readTimestamp(l.closedAt) ?? readTimestamp(l.closed_at);\n\n const rawItems = Array.isArray(l.items) ? l.items : [];\n const items = rawItems.map(normalizeItem);\n\n const lines: string[] = [];\n lines.push(`# Lease diagnostic — ${leaseUuid}`);\n lines.push('');\n lines.push('## Chain state');\n lines.push('');\n lines.push(`- **State:** ${stateLabel}`);\n lines.push(`- **Provider:** ${providerUuid}`);\n if (createdAt) lines.push(`- **Created:** ${createdAt}`);\n if (closedAt) lines.push(`- **Closed:** ${closedAt}`);\n lines.push('');\n\n lines.push('## Items');\n lines.push('');\n if (items.length === 0) {\n lines.push('_No items found on this lease._');\n } else {\n for (const item of items) {\n const svc = item.serviceName.length > 0 ? item.serviceName : '(default)';\n const dom =\n item.customDomain.length > 0 ? item.customDomain : '(no custom domain)';\n lines.push(`- **${svc}** → ${dom}`);\n }\n }\n lines.push('');\n\n lines.push('## Guidance');\n lines.push('');\n for (const tip of guidanceFor(stateName)) {\n lines.push(`- ${tip}`);\n }\n\n return lines.join('\\n');\n}\n\nfunction guidanceFor(state: LeaseStateName | undefined): string[] {\n if (state === undefined) {\n return [\n 'Lease state could not be decoded. Re-query in a moment, or check the chain client logs for transport errors.',\n ];\n }\n if (isTerminal(state)) {\n return [\n `Lease is in terminal state \\`${state}\\`. No further provider activity expected.`,\n 'To redeploy, create a new lease via `deployApp`.',\n ];\n }\n switch (state) {\n case 'LEASE_STATE_PENDING':\n return [\n 'Lease is awaiting provider acknowledgement.',\n 'If pending persists for more than a few minutes, the provider may be offline; consider closing and redeploying.',\n ];\n case 'LEASE_STATE_ACTIVE':\n return [\n 'Lease is active on the provider. App-level status / logs require a provider HTTP call with an ADR-036 auth token (out of scope for this chain-only diagnostic).',\n ];\n default:\n return [\n `Lease state is \\`${state}\\`. Review the chain proto for the expected next transition.`,\n ];\n }\n}\n\nfunction readString(value: unknown): string {\n return typeof value === 'string' ? value : '';\n}\n\nfunction readTimestamp(value: unknown): string | undefined {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n return undefined;\n}\n"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CosmosClientManager, SkuCandidate, WalletProvider } from "@manifest-network/manifest-mcp-core";
|
|
1
|
+
import { AppDeploySpec, CosmosClientManager, ServiceConfig, SkuCandidate, WalletProvider } from "@manifest-network/manifest-mcp-core";
|
|
2
2
|
|
|
3
3
|
//#region src/types.d.ts
|
|
4
4
|
interface Coin {
|
|
@@ -35,6 +35,19 @@ interface AgentCoreRuntime {
|
|
|
35
35
|
* the optional DenomMap injection (chain-registry-driven humanization).
|
|
36
36
|
*/
|
|
37
37
|
interface DeployAppOptions extends AgentCoreRuntime {
|
|
38
|
+
/**
|
|
39
|
+
* Caller cancellation. Composed with `timeout` via `resolveCallSignal`
|
|
40
|
+
* (core's `CallOptions` convention). Races ONLY the pre-broadcast
|
|
41
|
+
* interactive callbacks (onPlan/onConfirm/onResolveSku) + forwards into
|
|
42
|
+
* fred's `DeployCallOptions.abortSignal`; a post-broadcast abort routes
|
|
43
|
+
* INTO recovery, it never cancels it (ENG-310 / D4).
|
|
44
|
+
*/
|
|
45
|
+
signal?: AbortSignal;
|
|
46
|
+
/**
|
|
47
|
+
* Per-call deadline in ms. Surfaces as a `TimeoutError` (distinct from the
|
|
48
|
+
* caller's `AbortError`), mapped to `OPERATION_CANCELLED` (ENG-310 / D4).
|
|
49
|
+
*/
|
|
50
|
+
timeout?: number;
|
|
38
51
|
/**
|
|
39
52
|
* Wallet provider for ADR-036 auth-token signing.
|
|
40
53
|
*
|
|
@@ -89,6 +102,10 @@ interface DeployAppOptions extends AgentCoreRuntime {
|
|
|
89
102
|
* humanization injection.
|
|
90
103
|
*/
|
|
91
104
|
interface ManageDomainOptions extends AgentCoreRuntime {
|
|
105
|
+
/** Caller cancellation (core `CallOptions` convention; ENG-310 / D4). */
|
|
106
|
+
signal?: AbortSignal;
|
|
107
|
+
/** Per-call deadline in ms (ENG-310 / D4). */
|
|
108
|
+
timeout?: number;
|
|
92
109
|
chainDataFile?: string;
|
|
93
110
|
denomMap?: DenomMap;
|
|
94
111
|
}
|
|
@@ -97,6 +114,10 @@ interface ManageDomainOptions extends AgentCoreRuntime {
|
|
|
97
114
|
* fred → no `walletProvider` required.
|
|
98
115
|
*/
|
|
99
116
|
interface CloseLeaseOptions extends AgentCoreRuntime {
|
|
117
|
+
/** Caller cancellation (core `CallOptions` convention; ENG-310 / D4). */
|
|
118
|
+
signal?: AbortSignal;
|
|
119
|
+
/** Per-call deadline in ms (ENG-310 / D4). */
|
|
120
|
+
timeout?: number;
|
|
100
121
|
chainDataFile?: string;
|
|
101
122
|
denomMap?: DenomMap;
|
|
102
123
|
}
|
|
@@ -105,57 +126,13 @@ interface CloseLeaseOptions extends AgentCoreRuntime {
|
|
|
105
126
|
* broadcast through fred → no `walletProvider` required.
|
|
106
127
|
*/
|
|
107
128
|
interface TroubleshootOptions extends AgentCoreRuntime {
|
|
129
|
+
/** Caller cancellation (core `CallOptions` convention; ENG-310 / D4). */
|
|
130
|
+
signal?: AbortSignal;
|
|
131
|
+
/** Per-call deadline in ms (ENG-310 / D4). */
|
|
132
|
+
timeout?: number;
|
|
108
133
|
chainDataFile?: string;
|
|
109
134
|
denomMap?: DenomMap;
|
|
110
135
|
}
|
|
111
|
-
interface ServiceDef {
|
|
112
|
-
image: string;
|
|
113
|
-
ports?: number[];
|
|
114
|
-
env?: Record<string, string>;
|
|
115
|
-
args?: string[];
|
|
116
|
-
command?: string[];
|
|
117
|
-
}
|
|
118
|
-
interface SingleServiceSpec {
|
|
119
|
-
image: string;
|
|
120
|
-
port?: number | number[];
|
|
121
|
-
env?: Record<string, string>;
|
|
122
|
-
customDomain?: string;
|
|
123
|
-
/**
|
|
124
|
-
* Compute-tier / SKU name selecting the lease item's resources (e.g.
|
|
125
|
-
* `'small'`, `'medium'`). Resolved to an on-chain SKU UUID by
|
|
126
|
-
* `findSkuUuid`, then threaded into SKU selection, fee estimation,
|
|
127
|
-
* readiness, fred's deploy input, and the persisted manifest. Optional;
|
|
128
|
-
* `requestedSize` (`deploy-app.ts`) falls back to `'small'` when absent
|
|
129
|
-
* or empty. ENG-275 promoted this from an undocumented cast-read
|
|
130
|
-
* escape hatch to a first-class typed field so contract-following
|
|
131
|
-
* callers can select a non-default SKU.
|
|
132
|
-
*/
|
|
133
|
-
size?: string;
|
|
134
|
-
/**
|
|
135
|
-
* Optional SKU disambiguator: `provider_uuid` narrows a duplicate
|
|
136
|
-
* `size` name to one provider; `sku_uuid` pins a specific SKU by uuid
|
|
137
|
-
* (bypasses the name). Threaded into `resolveSku`. ENG-296.
|
|
138
|
-
*/
|
|
139
|
-
providerUuid?: string;
|
|
140
|
-
/** See {@link SingleServiceSpec.providerUuid}. Pins a specific SKU by uuid (bypasses the name). ENG-296. */
|
|
141
|
-
skuUuid?: string;
|
|
142
|
-
}
|
|
143
|
-
interface StackSpec {
|
|
144
|
-
services: Record<string, ServiceDef>;
|
|
145
|
-
customDomain?: string;
|
|
146
|
-
serviceName?: string;
|
|
147
|
-
/** SKU tier for the lease items; see {@link SingleServiceSpec.size}. */
|
|
148
|
-
size?: string;
|
|
149
|
-
/**
|
|
150
|
-
* Optional SKU disambiguator: `provider_uuid` narrows a duplicate
|
|
151
|
-
* `size` name to one provider; `sku_uuid` pins a specific SKU by uuid
|
|
152
|
-
* (bypasses the name). Threaded into `resolveSku`. ENG-296.
|
|
153
|
-
*/
|
|
154
|
-
providerUuid?: string;
|
|
155
|
-
/** See {@link StackSpec.providerUuid}. Pins a specific SKU by uuid (bypasses the name). ENG-296. */
|
|
156
|
-
skuUuid?: string;
|
|
157
|
-
}
|
|
158
|
-
type DeploySpec = SingleServiceSpec | StackSpec;
|
|
159
136
|
interface SpecSummary {
|
|
160
137
|
format: 'single' | 'stack';
|
|
161
138
|
serviceCount: number;
|
|
@@ -196,7 +173,7 @@ type PlanEdit = {
|
|
|
196
173
|
env: Record<string, string>;
|
|
197
174
|
} | {
|
|
198
175
|
kind: 'replace_spec';
|
|
199
|
-
spec:
|
|
176
|
+
spec: AppDeploySpec;
|
|
200
177
|
};
|
|
201
178
|
interface DeploymentPlanBlock {
|
|
202
179
|
text: string;
|
|
@@ -247,6 +224,8 @@ type ProgressEvent = {
|
|
|
247
224
|
} | {
|
|
248
225
|
kind: 'sku_ambiguous';
|
|
249
226
|
candidates: SkuCandidate[];
|
|
227
|
+
} | {
|
|
228
|
+
kind: 'cancelled';
|
|
250
229
|
};
|
|
251
230
|
type FailureEnvelope = {
|
|
252
231
|
outcome: 'partially_succeeded';
|
|
@@ -350,5 +329,5 @@ interface CloseLeaseCallbacks {
|
|
|
350
329
|
}) => Promise<void>;
|
|
351
330
|
}
|
|
352
331
|
//#endregion
|
|
353
|
-
export { AgentCoreRuntime, CloseLeaseArgs, CloseLeaseCallbacks, CloseLeaseOptions, CloseLeaseResult, Coin, type CosmosClientManager, DenomLookup, DenomMap, DeployAppCallbacks, DeployAppOptions, DeployResult,
|
|
332
|
+
export { AgentCoreRuntime, type AppDeploySpec, CloseLeaseArgs, CloseLeaseCallbacks, CloseLeaseOptions, CloseLeaseResult, Coin, type CosmosClientManager, DenomLookup, DenomMap, DeployAppCallbacks, DeployAppOptions, DeployResult, DeploymentPlanBlock, FailureEnvelope, FeeEstimate, LeaseStateName, ManageDomainArgs, ManageDomainCallbacks, ManageDomainOptions, ManageDomainResult, Plan, PlanEdit, PlanFees, ProgressEvent, Readiness, ReadinessAction, RecoveryChoice, RecoveryOption, RecoveryOptionId, type ServiceConfig, type SkuCandidate, SpecSummary, TroubleshootArgs, TroubleshootCallbacks, TroubleshootOptions, TroubleshootReport, type WalletProvider };
|
|
354
333
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manifest-network/manifest-agent-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "TypeScript orchestration surface for Manifest agent flows (deploy / manage-domain / troubleshoot / close-lease). Type contract only — see ENG-127.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"sideEffects": false,
|
|
8
9
|
"exports": {
|
|
9
10
|
".": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./guarded-fetch": {
|
|
15
|
+
"types": "./dist/guarded-fetch.d.ts",
|
|
16
|
+
"node": "./dist/guarded-fetch.js",
|
|
17
|
+
"default": null
|
|
12
18
|
}
|
|
13
19
|
},
|
|
14
20
|
"scripts": {
|
|
15
21
|
"build": "tsdown",
|
|
16
22
|
"dev": "tsdown --watch",
|
|
17
23
|
"lint": "tsc --noEmit",
|
|
18
|
-
"test": "vitest run",
|
|
24
|
+
"test": "vitest run --typecheck",
|
|
19
25
|
"test:watch": "vitest"
|
|
20
26
|
},
|
|
21
27
|
"keywords": [
|
|
@@ -42,11 +48,13 @@
|
|
|
42
48
|
"files": [
|
|
43
49
|
"dist"
|
|
44
50
|
],
|
|
45
|
-
"
|
|
46
|
-
"@manifest-network/manifest-mcp-core": "^0.
|
|
47
|
-
"@manifest-network/manifest-mcp-fred": "^0.
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"@manifest-network/manifest-mcp-core": "^0.16.0",
|
|
53
|
+
"@manifest-network/manifest-mcp-fred": "^0.16.0"
|
|
48
54
|
},
|
|
49
55
|
"devDependencies": {
|
|
56
|
+
"@manifest-network/manifest-mcp-core": "0.16.0",
|
|
57
|
+
"@manifest-network/manifest-mcp-fred": "0.16.0",
|
|
50
58
|
"@types/node": "22.19.19",
|
|
51
59
|
"typescript": "5.9.3",
|
|
52
60
|
"vitest": "4.1.8"
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { DeploySpec } from "../types.js";
|
|
2
|
-
import { BuildManifestPreviewInput, DeployAppInput } from "@manifest-network/manifest-mcp-fred";
|
|
3
|
-
|
|
4
|
-
//#region src/internals/build-fred-input.d.ts
|
|
5
|
-
/**
|
|
6
|
-
* Build fred's `BuildManifestPreviewInput` from a typed `DeploySpec`.
|
|
7
|
-
*
|
|
8
|
-
* Stack arm: each `ServiceDef.ports: number[]` is converted to
|
|
9
|
-
* `{<port>/tcp: {}}`. Services without `ports` (or with empty `[]`)
|
|
10
|
-
* omit the `ports` key in the output.
|
|
11
|
-
*
|
|
12
|
-
* Single-service arm: `port: number` and `port: [80]` both produce
|
|
13
|
-
* `port: 80`. Multi-element arrays throw INVALID_CONFIG.
|
|
14
|
-
*
|
|
15
|
-
* Deploy-only fields (`customDomain`, `serviceName`) are deliberately
|
|
16
|
-
* NOT forwarded — the preview path computes only the manifest meta-hash;
|
|
17
|
-
* domain claims happen later in the deploy path.
|
|
18
|
-
*
|
|
19
|
-
* The `size` parameter is accepted for signature parity with
|
|
20
|
-
* `buildFredDeployInput` but is NOT included in the returned object:
|
|
21
|
-
* fred's `BuildManifestPreviewInput` type has no `size` field and
|
|
22
|
-
* `buildManifestPreview` derives no behavior from it. The prior inline
|
|
23
|
-
* builder emitted `size` via an `as unknown as` cast that hid the
|
|
24
|
-
* type-contract violation; this version drops it cleanly.
|
|
25
|
-
*/
|
|
26
|
-
declare function buildManifestPreviewInput(spec: DeploySpec, _size: string): BuildManifestPreviewInput;
|
|
27
|
-
/**
|
|
28
|
-
* Build fred's `DeployAppInput` from a typed `DeploySpec`.
|
|
29
|
-
*
|
|
30
|
-
* Same port-shape conversion as `buildManifestPreviewInput` (so the
|
|
31
|
-
* meta-hash recorded on-chain matches the manifest actually uploaded).
|
|
32
|
-
* Additionally threads `customDomain` (both shapes) and `serviceName`
|
|
33
|
-
* (stack only — single-service leases have no service-name to address).
|
|
34
|
-
*
|
|
35
|
-
* @param pin Optional pre-resolved SKU pin (ENG-258). When supplied, spreads
|
|
36
|
-
* `skuUuid` and `providerUuid` into the output so fred's `deployApp` skips
|
|
37
|
-
* the name-based lookup (uses the `resolved` selector path). Existing
|
|
38
|
-
* 2-arg callers are unaffected — the parameter is optional.
|
|
39
|
-
*/
|
|
40
|
-
declare function buildFredDeployInput(spec: DeploySpec, size: string, pin?: {
|
|
41
|
-
skuUuid: string;
|
|
42
|
-
providerUuid: string;
|
|
43
|
-
}): DeployAppInput;
|
|
44
|
-
//#endregion
|
|
45
|
-
export { buildFredDeployInput, buildManifestPreviewInput };
|
|
46
|
-
//# sourceMappingURL=build-fred-input.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"build-fred-input.d.ts","names":[],"sources":["../../src/internals/build-fred-input.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;iBA6JgB,yBAAA,CACd,IAAA,EAAM,UAAA,EAGN,KAAA,WACC,yBAAyB;;;;;;;;;;;;;;iBAyBZ,oBAAA,CACd,IAAA,EAAM,UAAA,EACN,IAAA,UACA,GAAA;EAAQ,OAAA;EAAiB,YAAA;AAAA,IACxB,cAAkB"}
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { isStackSpec } from "./spec-normalize.js";
|
|
2
|
-
import { ManifestMCPError, ManifestMCPErrorCode } from "@manifest-network/manifest-mcp-core";
|
|
3
|
-
//#region src/internals/build-fred-input.ts
|
|
4
|
-
/**
|
|
5
|
-
* Discriminated-union narrowing builders: typed `DeploySpec` → fred's
|
|
6
|
-
* `BuildManifestPreviewInput` and `DeployAppInput`. ENG-185 sub-PR A, item 2.
|
|
7
|
-
*
|
|
8
|
-
* Replaces the prior inline builders in `deploy-app.ts` (PR-3 commit B) that
|
|
9
|
-
* used `as unknown as <fred-input>` casts and silently truncated
|
|
10
|
-
* `SingleServiceSpec.port` arrays to `port[0]`.
|
|
11
|
-
*
|
|
12
|
-
* Bugs this file kills:
|
|
13
|
-
*
|
|
14
|
-
* (a) Stack `ServiceDef.ports: number[]` (`types.ts:164`) is converted
|
|
15
|
-
* to fred's canonical port-map shape `Record<string, Record<string,
|
|
16
|
-
* never>>` (e.g. `{'80/tcp': {}}`). The prior inline cast passed
|
|
17
|
-
* the raw array straight through, so `buildManifestPreview` and
|
|
18
|
-
* fred's deploy-time builder saw different shapes — the meta-hash
|
|
19
|
-
* recorded on-chain drifted from the manifest actually uploaded.
|
|
20
|
-
*
|
|
21
|
-
* (b) Single-service `SingleServiceSpec.port: number | number[]`
|
|
22
|
-
* (`types.ts:172`) — fred's image-mode input is `port: number`
|
|
23
|
-
* only. The prior inline builders did `port[0]`, silently dropping
|
|
24
|
-
* every other element. We now reject multi-element arrays with
|
|
25
|
-
* `ManifestMCPError(INVALID_CONFIG)` (strategy (a) per the task
|
|
26
|
-
* brief) and point the caller at `StackSpec` for natively
|
|
27
|
-
* multi-port deployments.
|
|
28
|
-
*
|
|
29
|
-
* No `as unknown as` casts. Discriminated narrowing uses the shared
|
|
30
|
-
* `isStackSpec` predicate from `spec-normalize.ts`.
|
|
31
|
-
*/
|
|
32
|
-
/**
|
|
33
|
-
* Convert a `ServiceDef.ports: number[]` to fred's canonical port-map
|
|
34
|
-
* shape. Protocol defaults to `tcp` (the only protocol exposed via the
|
|
35
|
-
* agent-core surface today; UDP is deferred until a caller needs it).
|
|
36
|
-
*/
|
|
37
|
-
function toPortMap(ports) {
|
|
38
|
-
const map = {};
|
|
39
|
-
for (const port of ports) map[`${port}/tcp`] = {};
|
|
40
|
-
return map;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Map a single `ServiceDef` (agent-core spec shape) → fred's
|
|
44
|
-
* `ServiceConfig` shape. Omits optional fields when absent so callers
|
|
45
|
-
* can compare emitted objects with `'foo' in out` checks (rather than
|
|
46
|
-
* `out.foo === undefined`, which a `key: undefined` spread would defeat).
|
|
47
|
-
*/
|
|
48
|
-
function convertServiceDef(svc) {
|
|
49
|
-
const out = { image: svc.image };
|
|
50
|
-
if (svc.ports !== void 0 && svc.ports.length > 0) out.ports = toPortMap(svc.ports);
|
|
51
|
-
if (svc.env !== void 0) out.env = svc.env;
|
|
52
|
-
if (svc.args !== void 0) out.args = [...svc.args];
|
|
53
|
-
if (svc.command !== void 0) out.command = [...svc.command];
|
|
54
|
-
return out;
|
|
55
|
-
}
|
|
56
|
-
function convertStackServices(spec) {
|
|
57
|
-
const out = {};
|
|
58
|
-
for (const [name, svc] of Object.entries(spec.services)) out[name] = convertServiceDef(svc);
|
|
59
|
-
return out;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Narrow `SingleServiceSpec.port: number | number[] | undefined` to
|
|
63
|
-
* fred's single-service `port: number | undefined`.
|
|
64
|
-
*
|
|
65
|
-
* - `undefined` → `undefined`
|
|
66
|
-
* - `80` → `80`
|
|
67
|
-
* - `[80]` → `80` (single-element array convenience)
|
|
68
|
-
* - `[80, 443, …]` → `ManifestMCPError(INVALID_CONFIG)`
|
|
69
|
-
*
|
|
70
|
-
* Strategy (a) per the ENG-185 sub-PR A brief: rejecting multi-element
|
|
71
|
-
* arrays at the builder boundary kills the prior silent `port[0]`
|
|
72
|
-
* truncation. The error message points the caller at the `StackSpec`
|
|
73
|
-
* escape hatch where multi-port routing is natively expressible.
|
|
74
|
-
*/
|
|
75
|
-
function narrowSingleServicePort(port) {
|
|
76
|
-
if (port === void 0) return void 0;
|
|
77
|
-
if (typeof port === "number") return port;
|
|
78
|
-
if (Array.isArray(port)) {
|
|
79
|
-
if (port.length === 0) return void 0;
|
|
80
|
-
if (port.length === 1) return port[0];
|
|
81
|
-
throw new ManifestMCPError(ManifestMCPErrorCode.INVALID_CONFIG, "SingleServiceSpec.port: multi-port single-service is not supported — use a StackSpec with explicit `services.<name>.ports` to expose multiple ports.");
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Build fred's `BuildManifestPreviewInput` from a typed `DeploySpec`.
|
|
86
|
-
*
|
|
87
|
-
* Stack arm: each `ServiceDef.ports: number[]` is converted to
|
|
88
|
-
* `{<port>/tcp: {}}`. Services without `ports` (or with empty `[]`)
|
|
89
|
-
* omit the `ports` key in the output.
|
|
90
|
-
*
|
|
91
|
-
* Single-service arm: `port: number` and `port: [80]` both produce
|
|
92
|
-
* `port: 80`. Multi-element arrays throw INVALID_CONFIG.
|
|
93
|
-
*
|
|
94
|
-
* Deploy-only fields (`customDomain`, `serviceName`) are deliberately
|
|
95
|
-
* NOT forwarded — the preview path computes only the manifest meta-hash;
|
|
96
|
-
* domain claims happen later in the deploy path.
|
|
97
|
-
*
|
|
98
|
-
* The `size` parameter is accepted for signature parity with
|
|
99
|
-
* `buildFredDeployInput` but is NOT included in the returned object:
|
|
100
|
-
* fred's `BuildManifestPreviewInput` type has no `size` field and
|
|
101
|
-
* `buildManifestPreview` derives no behavior from it. The prior inline
|
|
102
|
-
* builder emitted `size` via an `as unknown as` cast that hid the
|
|
103
|
-
* type-contract violation; this version drops it cleanly.
|
|
104
|
-
*/
|
|
105
|
-
function buildManifestPreviewInput(spec, _size) {
|
|
106
|
-
if (isStackSpec(spec)) return { services: convertStackServices(spec) };
|
|
107
|
-
const port = narrowSingleServicePort(spec.port);
|
|
108
|
-
return {
|
|
109
|
-
image: spec.image,
|
|
110
|
-
...port !== void 0 ? { port } : {},
|
|
111
|
-
...spec.env !== void 0 ? { env: spec.env } : {}
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Build fred's `DeployAppInput` from a typed `DeploySpec`.
|
|
116
|
-
*
|
|
117
|
-
* Same port-shape conversion as `buildManifestPreviewInput` (so the
|
|
118
|
-
* meta-hash recorded on-chain matches the manifest actually uploaded).
|
|
119
|
-
* Additionally threads `customDomain` (both shapes) and `serviceName`
|
|
120
|
-
* (stack only — single-service leases have no service-name to address).
|
|
121
|
-
*
|
|
122
|
-
* @param pin Optional pre-resolved SKU pin (ENG-258). When supplied, spreads
|
|
123
|
-
* `skuUuid` and `providerUuid` into the output so fred's `deployApp` skips
|
|
124
|
-
* the name-based lookup (uses the `resolved` selector path). Existing
|
|
125
|
-
* 2-arg callers are unaffected — the parameter is optional.
|
|
126
|
-
*/
|
|
127
|
-
function buildFredDeployInput(spec, size, pin) {
|
|
128
|
-
if (isStackSpec(spec)) {
|
|
129
|
-
const out = {
|
|
130
|
-
size,
|
|
131
|
-
services: convertStackServices(spec),
|
|
132
|
-
...pin ? {
|
|
133
|
-
skuUuid: pin.skuUuid,
|
|
134
|
-
providerUuid: pin.providerUuid
|
|
135
|
-
} : {}
|
|
136
|
-
};
|
|
137
|
-
if (typeof spec.customDomain === "string" && spec.customDomain.length > 0) {
|
|
138
|
-
out.customDomain = spec.customDomain;
|
|
139
|
-
if (typeof spec.serviceName === "string" && spec.serviceName.length > 0) out.serviceName = spec.serviceName;
|
|
140
|
-
}
|
|
141
|
-
return out;
|
|
142
|
-
}
|
|
143
|
-
const port = narrowSingleServicePort(spec.port);
|
|
144
|
-
const out = {
|
|
145
|
-
size,
|
|
146
|
-
image: spec.image,
|
|
147
|
-
...pin ? {
|
|
148
|
-
skuUuid: pin.skuUuid,
|
|
149
|
-
providerUuid: pin.providerUuid
|
|
150
|
-
} : {}
|
|
151
|
-
};
|
|
152
|
-
if (port !== void 0) out.port = port;
|
|
153
|
-
if (spec.env !== void 0) out.env = spec.env;
|
|
154
|
-
if (typeof spec.customDomain === "string" && spec.customDomain.length > 0) out.customDomain = spec.customDomain;
|
|
155
|
-
return out;
|
|
156
|
-
}
|
|
157
|
-
//#endregion
|
|
158
|
-
export { buildFredDeployInput, buildManifestPreviewInput };
|
|
159
|
-
|
|
160
|
-
//# sourceMappingURL=build-fred-input.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"build-fred-input.js","names":[],"sources":["../../src/internals/build-fred-input.ts"],"sourcesContent":["/**\n * Discriminated-union narrowing builders: typed `DeploySpec` → fred's\n * `BuildManifestPreviewInput` and `DeployAppInput`. ENG-185 sub-PR A, item 2.\n *\n * Replaces the prior inline builders in `deploy-app.ts` (PR-3 commit B) that\n * used `as unknown as <fred-input>` casts and silently truncated\n * `SingleServiceSpec.port` arrays to `port[0]`.\n *\n * Bugs this file kills:\n *\n * (a) Stack `ServiceDef.ports: number[]` (`types.ts:164`) is converted\n * to fred's canonical port-map shape `Record<string, Record<string,\n * never>>` (e.g. `{'80/tcp': {}}`). The prior inline cast passed\n * the raw array straight through, so `buildManifestPreview` and\n * fred's deploy-time builder saw different shapes — the meta-hash\n * recorded on-chain drifted from the manifest actually uploaded.\n *\n * (b) Single-service `SingleServiceSpec.port: number | number[]`\n * (`types.ts:172`) — fred's image-mode input is `port: number`\n * only. The prior inline builders did `port[0]`, silently dropping\n * every other element. We now reject multi-element arrays with\n * `ManifestMCPError(INVALID_CONFIG)` (strategy (a) per the task\n * brief) and point the caller at `StackSpec` for natively\n * multi-port deployments.\n *\n * No `as unknown as` casts. Discriminated narrowing uses the shared\n * `isStackSpec` predicate from `spec-normalize.ts`.\n */\n\nimport {\n ManifestMCPError,\n ManifestMCPErrorCode,\n} from '@manifest-network/manifest-mcp-core';\nimport type {\n BuildManifestPreviewInput,\n DeployAppInput as FredDeployAppInput,\n} from '@manifest-network/manifest-mcp-fred';\nimport type { DeploySpec, ServiceDef, StackSpec } from '../types.js';\nimport { isStackSpec } from './spec-normalize.js';\n\n/**\n * Fred's canonical service port-map shape (`{<port>/<protocol>: {}}`).\n * Mirrors `ServiceConfig.ports` and `ManifestPreviewServiceInput.ports`\n * in `packages/fred/src/tools/deployApp.ts` /\n * `packages/fred/src/tools/buildManifestPreview.ts`. The empty `{}`\n * value is required by fred's validator (see\n * `packages/fred/src/manifest.ts`).\n */\ntype FredPortMap = Record<string, Record<string, never>>;\n\n/**\n * Internal shape used to build both preview and deploy service entries.\n * Assignable to both `ManifestPreviewServiceInput` (readonly fields) and\n * fred's `ServiceConfig` (mutable fields) — mutable arrays widen to\n * readonly arrays at the assignment site.\n */\ninterface ConvertedService {\n image: string;\n ports?: FredPortMap;\n env?: Record<string, string>;\n args?: string[];\n command?: string[];\n}\n\n/**\n * Convert a `ServiceDef.ports: number[]` to fred's canonical port-map\n * shape. Protocol defaults to `tcp` (the only protocol exposed via the\n * agent-core surface today; UDP is deferred until a caller needs it).\n */\nfunction toPortMap(ports: readonly number[]): FredPortMap {\n const map: FredPortMap = {};\n for (const port of ports) {\n map[`${port}/tcp`] = {};\n }\n return map;\n}\n\n/**\n * Map a single `ServiceDef` (agent-core spec shape) → fred's\n * `ServiceConfig` shape. Omits optional fields when absent so callers\n * can compare emitted objects with `'foo' in out` checks (rather than\n * `out.foo === undefined`, which a `key: undefined` spread would defeat).\n */\nfunction convertServiceDef(svc: ServiceDef): ConvertedService {\n const out: ConvertedService = { image: svc.image };\n if (svc.ports !== undefined && svc.ports.length > 0) {\n out.ports = toPortMap(svc.ports);\n }\n if (svc.env !== undefined) out.env = svc.env;\n if (svc.args !== undefined) out.args = [...svc.args];\n if (svc.command !== undefined) out.command = [...svc.command];\n return out;\n}\n\nfunction convertStackServices(\n spec: StackSpec,\n): Record<string, ConvertedService> {\n const out: Record<string, ConvertedService> = {};\n for (const [name, svc] of Object.entries(spec.services)) {\n out[name] = convertServiceDef(svc);\n }\n return out;\n}\n\n/**\n * Narrow `SingleServiceSpec.port: number | number[] | undefined` to\n * fred's single-service `port: number | undefined`.\n *\n * - `undefined` → `undefined`\n * - `80` → `80`\n * - `[80]` → `80` (single-element array convenience)\n * - `[80, 443, …]` → `ManifestMCPError(INVALID_CONFIG)`\n *\n * Strategy (a) per the ENG-185 sub-PR A brief: rejecting multi-element\n * arrays at the builder boundary kills the prior silent `port[0]`\n * truncation. The error message points the caller at the `StackSpec`\n * escape hatch where multi-port routing is natively expressible.\n */\nfunction narrowSingleServicePort(\n port: number | number[] | undefined,\n): number | undefined {\n if (port === undefined) return undefined;\n if (typeof port === 'number') return port;\n if (Array.isArray(port)) {\n if (port.length === 0) return undefined;\n if (port.length === 1) return port[0];\n throw new ManifestMCPError(\n ManifestMCPErrorCode.INVALID_CONFIG,\n 'SingleServiceSpec.port: multi-port single-service is not supported — use a StackSpec with explicit `services.<name>.ports` to expose multiple ports.',\n );\n }\n // Unreachable under the typed contract; defensive for `as unknown as`\n // callers that bypass the compile-time guard.\n return undefined;\n}\n\n/**\n * Build fred's `BuildManifestPreviewInput` from a typed `DeploySpec`.\n *\n * Stack arm: each `ServiceDef.ports: number[]` is converted to\n * `{<port>/tcp: {}}`. Services without `ports` (or with empty `[]`)\n * omit the `ports` key in the output.\n *\n * Single-service arm: `port: number` and `port: [80]` both produce\n * `port: 80`. Multi-element arrays throw INVALID_CONFIG.\n *\n * Deploy-only fields (`customDomain`, `serviceName`) are deliberately\n * NOT forwarded — the preview path computes only the manifest meta-hash;\n * domain claims happen later in the deploy path.\n *\n * The `size` parameter is accepted for signature parity with\n * `buildFredDeployInput` but is NOT included in the returned object:\n * fred's `BuildManifestPreviewInput` type has no `size` field and\n * `buildManifestPreview` derives no behavior from it. The prior inline\n * builder emitted `size` via an `as unknown as` cast that hid the\n * type-contract violation; this version drops it cleanly.\n */\nexport function buildManifestPreviewInput(\n spec: DeploySpec,\n // Reserved for signature parity with buildFredDeployInput; not consumed.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _size: string,\n): BuildManifestPreviewInput {\n if (isStackSpec(spec)) {\n return { services: convertStackServices(spec) };\n }\n const port = narrowSingleServicePort(spec.port);\n return {\n image: spec.image,\n ...(port !== undefined ? { port } : {}),\n ...(spec.env !== undefined ? { env: spec.env } : {}),\n };\n}\n\n/**\n * Build fred's `DeployAppInput` from a typed `DeploySpec`.\n *\n * Same port-shape conversion as `buildManifestPreviewInput` (so the\n * meta-hash recorded on-chain matches the manifest actually uploaded).\n * Additionally threads `customDomain` (both shapes) and `serviceName`\n * (stack only — single-service leases have no service-name to address).\n *\n * @param pin Optional pre-resolved SKU pin (ENG-258). When supplied, spreads\n * `skuUuid` and `providerUuid` into the output so fred's `deployApp` skips\n * the name-based lookup (uses the `resolved` selector path). Existing\n * 2-arg callers are unaffected — the parameter is optional.\n */\nexport function buildFredDeployInput(\n spec: DeploySpec,\n size: string,\n pin?: { skuUuid: string; providerUuid: string },\n): FredDeployAppInput {\n if (isStackSpec(spec)) {\n const out: FredDeployAppInput = {\n size,\n services: convertStackServices(spec),\n ...(pin ? { skuUuid: pin.skuUuid, providerUuid: pin.providerUuid } : {}),\n };\n if (typeof spec.customDomain === 'string' && spec.customDomain.length > 0) {\n out.customDomain = spec.customDomain;\n if (typeof spec.serviceName === 'string' && spec.serviceName.length > 0) {\n out.serviceName = spec.serviceName;\n }\n }\n return out;\n }\n const port = narrowSingleServicePort(spec.port);\n const out: FredDeployAppInput = {\n size,\n image: spec.image,\n ...(pin ? { skuUuid: pin.skuUuid, providerUuid: pin.providerUuid } : {}),\n };\n if (port !== undefined) out.port = port;\n if (spec.env !== undefined) out.env = spec.env;\n if (typeof spec.customDomain === 'string' && spec.customDomain.length > 0) {\n out.customDomain = spec.customDomain;\n }\n return out;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqEA,SAAS,UAAU,OAAuC;CACxD,MAAM,MAAmB,CAAC;CAC1B,KAAK,MAAM,QAAQ,OACjB,IAAI,GAAG,KAAK,SAAS,CAAC;CAExB,OAAO;AACT;;;;;;;AAQA,SAAS,kBAAkB,KAAmC;CAC5D,MAAM,MAAwB,EAAE,OAAO,IAAI,MAAM;CACjD,IAAI,IAAI,UAAU,KAAA,KAAa,IAAI,MAAM,SAAS,GAChD,IAAI,QAAQ,UAAU,IAAI,KAAK;CAEjC,IAAI,IAAI,QAAQ,KAAA,GAAW,IAAI,MAAM,IAAI;CACzC,IAAI,IAAI,SAAS,KAAA,GAAW,IAAI,OAAO,CAAC,GAAG,IAAI,IAAI;CACnD,IAAI,IAAI,YAAY,KAAA,GAAW,IAAI,UAAU,CAAC,GAAG,IAAI,OAAO;CAC5D,OAAO;AACT;AAEA,SAAS,qBACP,MACkC;CAClC,MAAM,MAAwC,CAAC;CAC/C,KAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,KAAK,QAAQ,GACpD,IAAI,QAAQ,kBAAkB,GAAG;CAEnC,OAAO;AACT;;;;;;;;;;;;;;;AAgBA,SAAS,wBACP,MACoB;CACpB,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;CAC/B,IAAI,OAAO,SAAS,UAAU,OAAO;CACrC,IAAI,MAAM,QAAQ,IAAI,GAAG;EACvB,IAAI,KAAK,WAAW,GAAG,OAAO,KAAA;EAC9B,IAAI,KAAK,WAAW,GAAG,OAAO,KAAK;EACnC,MAAM,IAAI,iBACR,qBAAqB,gBACrB,sJACF;CACF;AAIF;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,0BACd,MAGA,OAC2B;CAC3B,IAAI,YAAY,IAAI,GAClB,OAAO,EAAE,UAAU,qBAAqB,IAAI,EAAE;CAEhD,MAAM,OAAO,wBAAwB,KAAK,IAAI;CAC9C,OAAO;EACL,OAAO,KAAK;EACZ,GAAI,SAAS,KAAA,IAAY,EAAE,KAAK,IAAI,CAAC;EACrC,GAAI,KAAK,QAAQ,KAAA,IAAY,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;CACpD;AACF;;;;;;;;;;;;;;AAeA,SAAgB,qBACd,MACA,MACA,KACoB;CACpB,IAAI,YAAY,IAAI,GAAG;EACrB,MAAM,MAA0B;GAC9B;GACA,UAAU,qBAAqB,IAAI;GACnC,GAAI,MAAM;IAAE,SAAS,IAAI;IAAS,cAAc,IAAI;GAAa,IAAI,CAAC;EACxE;EACA,IAAI,OAAO,KAAK,iBAAiB,YAAY,KAAK,aAAa,SAAS,GAAG;GACzE,IAAI,eAAe,KAAK;GACxB,IAAI,OAAO,KAAK,gBAAgB,YAAY,KAAK,YAAY,SAAS,GACpE,IAAI,cAAc,KAAK;EAE3B;EACA,OAAO;CACT;CACA,MAAM,OAAO,wBAAwB,KAAK,IAAI;CAC9C,MAAM,MAA0B;EAC9B;EACA,OAAO,KAAK;EACZ,GAAI,MAAM;GAAE,SAAS,IAAI;GAAS,cAAc,IAAI;EAAa,IAAI,CAAC;CACxE;CACA,IAAI,SAAS,KAAA,GAAW,IAAI,OAAO;CACnC,IAAI,KAAK,QAAQ,KAAA,GAAW,IAAI,MAAM,KAAK;CAC3C,IAAI,OAAO,KAAK,iBAAiB,YAAY,KAAK,aAAa,SAAS,GACtE,IAAI,eAAe,KAAK;CAE1B,OAAO;AACT"}
|