@go-to-k/cdkd 0.296.30 → 0.297.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.
@@ -2,8 +2,8 @@ import { a as runWithStackAwsClients, i as resetAwsClients, o as setAwsClients,
2
2
  import { A as UNRENDERABLE, B as stringifyJsonPayload, D as SAFE_MSG_ALTERED_CHAR, F as displayStackName, I as isPasteableIdent, M as displayAwsMessage, N as displayIdent, O as SECRET_REF_MAX_CODE_POINTS, P as displaySafe, R as plainIdentOr, T as withStackName, V as truncateCodePoints, _ as derivesPatternBName, a as getLogger, f as getLiveRenderer, h as PATTERN_B_RESOURCE_TYPES, j as cutMarker, k as STACK_REF_MAX_CODE_POINTS, l as runStackBuffered, m as PATTERN_B_NAME_PROPERTIES, o as isStdoutReservedForPayload, p as PATTERN_B_NAME_OPTIONS, r as safeStringify, s as reserveStdoutForPayload, t as describeAwsFailure, v as explicitNamePropertyFor, w as withSkipPrefix, y as generateResourceName, z as safeMsg } from "./aws-failure-text-BaWeCWRz.js";
3
3
  import { $n as isAmbiguousOutcomeError, $t as credentialFingerprint, Bn as withheldTargetClause, D as VALUE_NOT_SHOWN, Dn as TIMEOUT_FLAG_RESOURCE_TYPE, E as assertRegionMatch, En as withErrorHandling, Ft as buildLockContentionMessage, G as runDeleteAttempt, Hn as setPasteableVerbFlags, Ht as CUSTOM_RESOURCE_RESPONSE_PREFIX, In as plainOrDescribed, It as forceQuitRecoveryClause, Jt as setPasteableAwsProfile, Kt as producerCoordinateKey, Ln as quotedOrDescribed, Lt as formatLockExpiry, Nn as isInertUnquoted, Nt as UNREPRODUCIBLE_LOCK_CLAUSE, P as remedyLogicalId, Pn as pasteableCommand, Pt as buildForceUnlockCommand, Qt as clientDefaultsFor, Rn as shellBoundedDisplay, Rt as formatLockOperation, Sn as SynthesisError, T as RESOURCE_NOT_FOUND, Tn as normalizeAwsError, Ut as DEFAULT_STATE_PREFIX, Vn as setPasteableRunFlags, Wt as injectiveKey, Xt as ambientClientDefaults, Yt as withPasteableAwsProfile, Z as isAwsCliLiteral, Zt as ambientCredentialConfig, _n as ResourceTimeoutError, ar as isMarkedNonRetryable, bn as StackTerminationProtectionError, cn as IntrinsicResolutionRefusalError, en as AccountIdUnavailableError, ft as logicalIdShown, gn as ProvisioningError, hn as PartialFailureError, in as CrossAccountSecretRefusalError, it as isInterruptedWaitError, jn as commandHole, kn as SHELL_ACTIVE_WHY, ln as LocalInvokeBuildError$1, mn as NestedStackChildDirectDestroyError, mt as resourceTypeShown, n as RESOLVED_PREVIOUS_PRINCIPAL_KEYS, nn as CdkdError, nr as isTransientServerError, nt as endCommandInterruptScope, on as DeployCancelledError, or as isThrottlingError, pn as MalformedProducerRecordRefusalError, qt as producerRecordKey, rr as retryClassificationText, rt as interruptWatchListenerCount, s as readRecordedPrincipals, sn as DynamicReferenceRegionAmbiguousError, sr as markNonRetryable, t as IAM_PRINCIPAL_NAME, tr as isRetryableTransientError, tt as beginCommandInterruptScope, un as LocalStartServiceError, vn as ResourceUpdateNotSupportedError, yn as StackHasActiveImportsError, zn as shellQuote, zt as formatLockOwner } from "./iam-policy-targets-Cz2tPxXk.js";
4
4
  import { n as awsClientDefaults, r as getAssumedRoleCredentials, u as formatAuthority } from "./aws-client-defaults-D0q0z4dG.js";
5
- import { $c as hasOwnKey, $i as previewableOrphanRecords, $s as validateAssetBucketName, $t as orphanDeleteNeedsIdentity, A as noEchoExactEchoLeavesOf, Aa as unpreviewableOrphanRecords, Ac as resolveCaptureObservedState, Ai as hasReadableOutputs, An as maskEventTextWithBoundBags, Ao as carryLogOnlyValues, As as hasUnverifiableParameterRefusal, At as isHandledOrphan, Ba as findReplacedReadersOfRecreateTargets, Bc as MIGRATE_TMP_PREFIX, Bi as malformedOrphanRecordsRefusalMessage, Bn as effectiveDeletionPolicy, Bo as errorCauseChain, Br as producerRegionsFromState, Bs as WorkGraph, Bt as withStackRecords, C as recordRetainedForReadoption, Ca as refuseMalformedState, Cc as Synthesizer, Ci as STATE_RESOURCES_MALFORMED, Cn as collectPublishedOutputNames, Co as noEchoLeavesOf, Cr as deleteIndeterminateGuards, Cs as isNotImplemented, Ct as revertedNestedRowIds, D as withResourceDeadline, Da as repairMalformedResourceEntriesForReadOnly, Dc as loadCdkJson, Di as deployRefusesOrphanRowsReason, Dn as DEFAULT_RESOURCE_WARN_AFTER_MS, Do as readsNoEchoSource, Dr as isWaitAbandonedError, Ds as exportNamesCarriedFrom, Dt as withNestedStackContext, E as serviceTokenBlockingReason, Ea as repairMalformedOutputsForReadOnly, Ec as getLegacyStateBucketName, Ei as accountArgs, En as DEFAULT_RESOURCE_TIMEOUT_MS, Eo as readbackPathFor, Es as describeRegionValueKind, F as isProtectionValueActive, Fc as stateBucketExistenceConfirmed, Fi as malformedExportNamesWarning, Fn as ATOMIC_FINAL_SNAPSHOT_TYPES, Fo as printingCorpusOf, Fr as DiffCalculator, Fs as orphansCarriedFrom, Ft as replayFailedOperations, Ga as renderStatefulReason, Gc as expectedOwnerParam, Gi as malformedOutputsRefusalMessage, Gn as constructPathOf, Go as scrubResourceRecord, Gr as explicitRoleArnOrThrow, Gs as AssetModeResolver, Gt as isReplacementOrphan, Ha as MULTI_REGION_RECREATE_BLOCKED_TYPES, Hc as uploadCfnTemplate, Hi as malformedOrphanRowsKeptWarning, Hn as refusesFinalSnapshot, Ho as maskSecretsInText, Hr as applyRoleArnIfSet, Hs as createAssetRedirectResolver, Ht as recordAfterRollbackUpdate, I as perType, Ia as unwrittenCreateOnlyReplacement, Ic as warnDeprecatedNoPrefixCliFlag, Ii as malformedExportSourceWarning, In as PRE_DELETE_SNAPSHOT_TYPES, Io as recordLogOnlyParameterValue, Ir as INTRINSIC_KEYS, Is as shouldRetainResource, It as replayRollback, Jc as derivePartitionAndUrlSuffix, Ji as malformedResourceEntriesWarning, Jn as RollbackInlinePolicyWriters, Jo as isUncertifiedBaselineMaskPosition, Jr as AWS_CREDENTIAL_ENV_KEYS, Js as ensureAssetStorage, Jt as recheckFailedPlan, Kc as PARTITION_TABLE, Ki as malformedOutputsWarning, Kn as findDestructiveChanges, Ko as DYNAMIC_REFERENCE_TOKEN_SCAN, Kr as isIamRoleArn, Ks as BOOTSTRAP_MARKER_PREFIX, Kt as planFailedOps, L as readProtection, Lc as ssmResolvedValueType, Li as malformedLocalOutputsWarning, Ln as buildFinalSnapshotIdentifier, Lo as recordLogOnlyValue, Lr as IntrinsicFunctionResolver, Ls as AssetPublisher, M as recordedProtectionEvidence, Ma as unreadableResourceEntries, Mc as resolveStateBucketWithDefault, Mi as isReadableOrphanRecord, Mn as secretNamePrintingBag, Mo as hasMaskableValues, Ms as importableOutputs, Mt as loadJournaledOrphans, N as recordedProtectionNote, Na as withheldAccountClause, Nc as resolveStateBucketWithDefaultAndSource, Ni as isReadableResourceEntry, Nn as stateSecretNameNeedles, No as literalSplitDelimitersOf, Ns as isReadableBag, Nt as makeForeignHolderScan, O as noEchoAttributeNamesOf, Oa as repairMalformedResourcePropertiesForReadOnly, Oc as resolveApp, Oi as displayLogicalId, On as completedReplayEntries, Oo as valueAtCoordinate, Os as hasReadableExportSet, Ot as deleteJournaledOrphans, P as PROTECTION_PROPERTY_BY_TYPE, Pa as findActionableSilentDrops, Pc as resolveUseCdkBootstrapAssets, Pi as malformedDriftResourcePropertiesWarning, Pn as extractDeploymentEventError, Po as logOnlyValueCount, Ps as orphansAfterRollback, Pt as sameJournaledOrphans, Qc as defineOwnKey, Qi as malformedStateRefusalMessage, Qn as withCreateTokenLedger, Qo as recordNestedStackParameterExpressions, Qs as readBootstrapMarkerBody, Qt as seedsDeleteFirstGuard, Ra as NO_CC_HANDLERS_REASON, Rc as CFN_TEMPLATE_BODY_LIMIT, Ri as malformedLocalResourceEntriesWarning, Rn as ccRoutedFinalSnapshotError, Ro as shareLogOnlyValues, Rr as poisonRenderedSpellingsCollidingIn, Rs as isSensitiveAttributeName, Rt as destroyStackRecordsView, S as keptForReadoption, Sa as refuseMalformedResourcesForExport, Sc as getDockerImageBySourceHash, Si as STATE_REGION_DIVERGED, Sn as collectDeclaredOutputNames, So as noEchoCoordinatesOf, Sr as UNSPECIFIED_SKIP_REASON, Ss as isAccessDenied, T as findServiceTokenRefusals, Ta as repairMalformedOrphansForReadOnly, Tc as getDefaultStateBucketName, Ti as UNREADABLE_RESOURCES_MAP_ROW, Tn as bindingSkippedOutputs, Tr as deleteSkipReason, Ts as acceptedCreateOnlyDropsOf, Tt as collectNestedChildUnaddressed, Ua as isStatefulRecreateTargetForReplace, Uc as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, Ui as malformedOrphansRefusalMessage, Un as unsupportedFinalSnapshotError, Uo as markSameGenerationBag, Ur as assertFlagRoleArn, Us as loadPublishableAssetManifest, Ut as demoteSupersededOrphans, Va as shownType, Vc as findLargeInlineResources, Vi as malformedOrphanRecordsWarning, Vn as isFinalSnapshotError, Vo as maskSecretsInError, Vr as regionLessSecretName, Vs as buildAssetRedirectMap, Vt as removeProtectionTypeList, Wa as isStatefulRecreateTargetSync, Wc as decodeListingKey, Wi as malformedOrphansWarning, Wn as maskingRetryLogger, Wo as redactSecretsForState, Wr as assertSendableRoleArn, Ws as rewriteTemplateAssetReferences, Wt as isJournaledOrphan, Xc as StageLoadError, Xi as malformedResourcesWarning, Xn as ledgerForStack, Xo as identityKeyFor, Xr as callerEnvCredentials, Xs as isCrossRegionRedirect, Xt as replacementNeverSwapped, Yc as AssemblyReader, Yi as malformedResourcePropertiesWarning, Yo as pathCrossesDottedKey, Yr as applyCallerIdentityCredentials, Ys as getBootstrapMarkerKey, Yt as recordUnderIdIsNotOwn, Zc as processStackMessages, Zi as malformedScrubResourceEntriesRefusalMessage, Zo as inheritNestedStackParameterAssociations, Zr as envCredentialsAreAssumedRole, Zs as parseBootstrapMarker, Zt as resolveReplacementOldType, _ as makeCanonicalizePropertiesFn, _a as refuseMalformedResourcePropertiesForDrift, _c as runDockerStreaming, _n as carriedExportAliasExposure, _o as isMarkedCoordinate, _s as rebuildClientForBucketRegion, _t as displacedPhysicalIdShown, a as findNestedTemplateTreeDefect, aa as refuseMalformedOrphansForDestroy, ac as describeDockerExecFailure, ai as isUnboundTemplateParameter, al as displayAssemblyPath, as as recordNoEchoParameterFreshValue, at as gray, ba as refuseMalformedResourcesForDeploy, bc as stripControlChars, bn as isWholeDynamicReferenceValue, bo as maskWholeValue, br as slowCcOperationTimeoutMs, bs as applyCrossPrefixScan, bt as nestedChildStackName$1, c as renderNestedTemplateTreeDefect, ca as refuseMalformedOutputsForDestroy, cc as finchSecretArgvRefusal, ci as isImpossibleEmptyStoredAttribute, cn as updatePartialReason, co as templateResourceTypes, cs as STATE_SOURCED_BASELINE_RULES, ct as yellow, d as conditionInputsFrom, da as refuseMalformedResourceEntriesForDeploy, dc as isDockerClientEnvKey, di as isNamelessDynamicReferenceError, dn as WITHHELD_NAME_DISPLAY, dr as ccBrokenReason, ds as TEMPLATE_SOURCED_RULES, dt as reachableDivergentParameters, ea as refuseDivergentRecordRegionForDestroy, ec as validateContainerRepoName, el as hasPlainPrototype, en as findNestedStackTypeChanges, es as carriesSecretMask, f as parentSuppliedValues, fa as refuseMalformedResourceEntriesForDestroy, fc as isMalformedEnvKey, fi as keepsSecretReferenceToken, fn as displayTextOrWithheld, fr as isCustomResource, fs as WHOLE_DYNAMIC_REFERENCE_PATTERN, ft as resourcesNamingDeclaredParameter, g as mergeNoChangeOutputs, ga as refuseMalformedResourcePropertiesForDestroy, gc as runDockerForeground, gi as refStateLookupFromResource, gn as secretSafeKeyDisplay, go as canonicalCoordinates, gr as isCustomResourceType$1, gs as S3StateBackend, gt as displacedOpClause, h as keptWholeReasonText, ha as refuseMalformedResourceEntriesForOrphan, hc as redactedDockerCause, hi as isStalePlaceholderArnAttribute, hn as secretBearingStateKeyWarning, ho as TemplateParser, hr as readsNoEchoDeleteValues, hs as isLockInfoExpired, ht as NESTED_PENDING_PARENT_REASON, i as childTemplateLoader, ia as refuseMalformedOrphans, ic as describeDockerCapturedOutput, ii as coerceParameterTypedValue, il as describeFileReadFailure, is as recordNoEchoAttributeValues, it as cyan, j as noEchoParameterNamesOf, ja as unreadableOrphanRecords, jc as resolveSkipPrefix, ji as hasReadableResources, jn as orphanRecordsPrintingBag, jo as createUnionSecretMasker, js as importableOutputKeys, jt as journaledOrphanLines, k as noEchoComparisonForTemplate, ka as repairMalformedResourcesForReadOnly, kc as resolveAutoAssetStorage, ki as hasReadableOrphans, kn as journaledOrphanPrintingBag, ko as liveMatchesUnresolvedTokenFrame, ks as hasReasonlessBaselineRefusal, kt as dropFailedHint, l as templateIdentity, la as refuseMalformedResourceAttributesForOrphan, lc as formatDockerLoginError, li as carriesDynamicReference, ll as resolveBucketRegion, ln as DeploymentEventsReader, lo as describeTypeWithThrottleRetry, lr as CC_BROKEN_REASON, ls as STATE_SOURCED_CROSS_GENERATION_RULES, lt as computeParameterTaint, m as isSecretBearingReferenceString, ma as refuseMalformedResourceEntriesForImportSave, mc as redactDockerArgvValues, mi as cfnRefValueFromPhysicalId, mn as secretBearing, mo as DagBuilder, mr as TemplateNoEchoReresolver, ms as LockManager, mt as planOrphanAdoption, n as IMPLICIT_DELETE_DEPENDENCIES, na as refuseMalformedOrphanRecords, nc as buildDockerImage, nl as ownValue, nn as inheritProducerRegions, ns as recordMaskOnlyValue, nt as createReadOnlyAttributeHealerFactory, o as isAbsoluteAssetPath, oa as refuseMalformedOrphansForOrphan, oc as describeDockerFailure, oi as parameterTypeMayLoseSecretIdentity, ol as renderAssemblyPathEscape, os as recordProvenPublicExpression, ot as green, p as readRecordedConditionVerdicts, pa as refuseMalformedResourceEntriesForImport, pc as partitionSensitiveEnv, pi as AWS_NO_VALUE, pn as exportAliasCollisionScrubWarning, pr as wouldReturnToSdkProvider, ps as isSingleDynamicReferenceToken, pt as makeSiblingClaimReader, qc as canonicalizeRegion, qi as malformedRenderedContainersWarning, qn as formatDestructiveChange, qo as dynamicReferenceTokens, qr as sendableAssumeRoleCommand, qs as assertAssetBucketRegion, qt as planRollback, r as computeImplicitDeleteEdges, ra as refuseMalformedOrphanRecordsForDestroy, rc as resolveDockerContextDirectory, rl as absoluteAssemblyPathEscape, rs as recordMaskOnlyValuesIn, rt as bold, s as listNestedTemplateRows, sa as refuseMalformedOutputs, sc as dockerSpawnEnvWithSensitive, si as getAccountInfo, sl as resolveAssemblyPath, sn as updatePartialMessage, so as prefetchCreateOnlyPropertyPaths, ss as wholeStringLeavesOf, st as red, t as DeployEngine, tc as buildDenyExternalAccessPolicy, tl as nullPrototypeRecord, ts as provenPublicValue, tt as formatResourceLine, u as conditionFingerprint, ua as refuseMalformedResourceEntries, uc as getDockerCmd, ui as carriesFetchableDynamicReference, un as DeploymentEventsStore, uo as withRetry, ur as ProviderRegistry, us as STATE_SOURCED_READBACK_RULES, ut as namesAnyDeclaredParameter, va as refuseMalformedResourcePropertiesForExport, vc as warnFinchArgvExposure, vi as withSharedDrainBudget, vn as exportNameNoEchoParameters, vo as maskAtCoordinates, vr as withPrintingSecrets, vs as CrossPrefixReadError, vt as dropSettledNestedJournals, w as deferredServiceTokenWarning, wa as repairMalformedOrphanRecordsForReadOnly, wc as synthesisStatusMessage, wi as UNREADABLE_ORPHANS_CONTAINER_ROW, wn as isExportAliasCollision, wo as noEchoOutputsComparison, wr as deleteLeftInPlace, ws as splitImportedOps, wt as withNestedRevertRun, xa as refuseMalformedResourcesForDestroy, xc as AssetManifestLoader, xi as JSON_LISTING_HOLE_VALUE, xn as noEchoParameterValueSeed, xo as maskedLeafCoordinatesOf, xs as crossPrefixDeniedWarning, xt as recordDisplacedSkips, ya as refuseMalformedResourcePropertiesForOrphan, yc as escapeRegExp, yi as parameterInputsFor, yn as exportNameSecretExposure, yo as maskReadbackAtCoordinates, yr as CloudControlProvider, ys as CrossPrefixScanCache, za as hasNoCloudControlHandlers, zc as CFN_TEMPLATE_URL_LIMIT, zi as malformedLocalResourcesWarning, zn as createPreDeleteFinalSnapshot, zo as createSecretMasker, zr as classifyReplaySecretRegion, zs as stringifyValue } from "./deploy-engine-BuPc2Dfc.js";
6
- import { t as getCdkdVersion } from "./version-B__YmKBy.js";
5
+ import { $c as derivePartitionAndUrlSuffix, $i as malformedResourceEntriesWarning, $o as isUncertifiedBaselineMaskPosition, $r as AWS_CREDENTIAL_ENV_KEYS, $s as ensureAssetStorage, $t as orphanDeleteNeedsIdentity, A as noEchoExactEchoLeavesOf, Aa as repairMalformedOrphansForReadOnly, Ac as getDefaultStateBucketName, Ai as UNREADABLE_RESOURCES_MAP_ROW, An as maskEventTextWithBoundBags, Ar as deleteSkipReason, As as acceptedCreateOnlyDropsOf, At as isHandledOrphan, Bc as stateBucketExistenceConfirmed, Bi as malformedExportNamesWarning, Bn as ccRoutedFinalSnapshotError, Bo as printingCorpusOf, Br as DiffCalculator, Bs as orphansCarriedFrom, Bt as withStackRecords, C as recordRetainedForReadoption, Ca as refuseMalformedResourcePropertiesForExport, Cc as warnFinchArgvExposure, Ci as withSharedDrainBudget, Cn as collectPublishedOutputNames, Co as maskAtCoordinates, Cr as customResourceResponseExpirationWarning, Cs as CrossPrefixReadError, Ct as revertedNestedRowIds, D as withResourceDeadline, Da as refuseMalformedResourcesForExport, Dc as getDockerImageBySourceHash, Di as STATE_REGION_DIVERGED, Dn as DEFAULT_RESOURCE_WARN_AFTER_MS, Do as noEchoCoordinatesOf, Dr as UNSPECIFIED_SKIP_REASON, Ds as isAccessDenied, Dt as withNestedStackContext, E as serviceTokenBlockingReason, Ea as refuseMalformedResourcesForDestroy, Ec as AssetManifestLoader, Ei as JSON_LISTING_HOLE_VALUE, En as DEFAULT_RESOURCE_TIMEOUT_MS, Eo as maskedLeafCoordinatesOf, Es as crossPrefixDeniedWarning, F as isProtectionValueActive, Fa as unpreviewableOrphanRecords, Fc as resolveCaptureObservedState, Fi as hasReadableOutputs, Fn as storedSecretNameNeedles, Fo as carryLogOnlyValues, Fs as hasUnverifiableParameterRefusal, Ft as replayFailedOperations, Ga as findReplacedReadersOfRecreateTargets, Gc as MIGRATE_TMP_PREFIX, Gi as malformedOrphanRecordsRefusalMessage, Gn as unsupportedFinalSnapshotError, Go as errorCauseChain, Gr as producerRegionsFromState, Gs as WorkGraph, Gt as isReplacementOrphan, Hc as ssmResolvedValueType, Hi as malformedLocalOutputsWarning, Hn as effectiveDeletionPolicy, Ho as recordLogOnlyValue, Hr as IntrinsicFunctionResolver, Hs as AssetPublisher, Ht as recordAfterRollbackUpdate, I as perType, Ia as unreadableOrphanRecords, Ic as resolveSkipPrefix, Ii as hasReadableResources, In as extractDeploymentEventError, Io as createUnionSecretMasker, Is as importableOutputKeys, It as replayRollback, Ja as isStatefulRecreateTargetForReplace, Jc as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, Ji as malformedOrphansRefusalMessage, Jn as findDestructiveChanges, Jo as markSameGenerationBag, Jr as assertFlagRoleArn, Js as loadPublishableAssetManifest, Jt as recheckFailedPlan, Ka as shownType, Kc as findLargeInlineResources, Ki as malformedOrphanRecordsWarning, Kn as maskingRetryLogger, Ko as maskSecretsInError, Kr as regionLessSecretName, Ks as buildAssetRedirectMap, Kt as planFailedOps, L as readProtection, La as unreadableResourceEntries, Lc as resolveStateBucketWithDefault, Li as isReadableOrphanRecord, Ln as ATOMIC_FINAL_SNAPSHOT_TYPES, Lo as hasMaskableValues, Ls as importableOutputs, M as recordedProtectionEvidence, Ma as repairMalformedResourceEntriesForReadOnly, Mc as loadCdkJson, Mi as deployRefusesOrphanRowsReason, Mn as secretNamePrintingBag, Mo as readsNoEchoSource, Mr as isWaitAbandonedError, Ms as exportNamesCarriedFrom, Mt as loadJournaledOrphans, N as recordedProtectionNote, Na as repairMalformedResourcePropertiesForReadOnly, Nc as resolveApp, Ni as displayLogicalId, Nn as secretNamedRecordNeedles, No as valueAtCoordinate, Ns as hasReadableExportSet, Nt as makeForeignHolderScan, O as noEchoAttributeNamesOf, Oa as refuseMalformedState, Oc as Synthesizer, Oi as STATE_RESOURCES_MALFORMED, On as completedReplayEntries, Oo as noEchoLeavesOf, Or as deleteIndeterminateGuards, Os as isNotImplemented, Ot as deleteJournaledOrphans, P as PROTECTION_PROPERTY_BY_TYPE, Pa as repairMalformedResourcesForReadOnly, Pc as resolveAutoAssetStorage, Pi as hasReadableOrphans, Pn as stateSecretNameNeedles, Po as liveMatchesUnresolvedTokenFrame, Ps as hasReasonlessBaselineRefusal, Pt as sameJournaledOrphans, Qc as canonicalizeRegion, Qi as malformedRenderedContainersWarning, Qn as ledgerForStack, Qo as dynamicReferenceTokens, Qr as sendableAssumeRoleCommand, Qs as assertAssetBucketRegion, Qt as seedsDeleteFirstGuard, Ra as withheldAccountClause, Rc as resolveStateBucketWithDefaultAndSource, Ri as isReadableResourceEntry, Rn as PRE_DELETE_SNAPSHOT_TYPES, Ro as literalSplitDelimitersOf, Rs as isReadableBag, Rt as destroyStackRecordsView, S as keptForReadoption, Sa as refuseMalformedResourcePropertiesForDrift, Sc as runDockerStreaming, Sn as collectDeclaredOutputNames, So as isMarkedCoordinate, Sr as applyCustomResourceResponseExpiration, Ss as rebuildClientForBucketRegion, T as findServiceTokenRefusals, Ta as refuseMalformedResourcesForDeploy, Tc as stripControlChars, Tn as bindingSkippedOutputs, To as maskWholeValue, Tr as slowCcOperationTimeoutMs, Ts as applyCrossPrefixScan, Tt as collectNestedChildUnaddressed, Ua as NO_CC_HANDLERS_REASON, Uc as CFN_TEMPLATE_BODY_LIMIT, Ui as malformedLocalResourceEntriesWarning, Un as isFinalSnapshotError, Uo as shareLogOnlyValues, Ur as poisonRenderedSpellingsCollidingIn, Us as isSensitiveAttributeName, Ut as demoteSupersededOrphans, Va as unwrittenCreateOnlyReplacement, Vc as warnDeprecatedNoPrefixCliFlag, Vi as malformedExportSourceWarning, Vn as createPreDeleteFinalSnapshot, Vo as recordLogOnlyParameterValue, Vr as INTRINSIC_KEYS, Vs as shouldRetainResource, Vt as removeProtectionTypeList, Wa as hasNoCloudControlHandlers, Wc as CFN_TEMPLATE_URL_LIMIT, Wi as malformedLocalResourcesWarning, Wn as refusesFinalSnapshot, Wo as createSecretMasker, Wr as classifyReplaySecretRegion, Ws as stringifyValue, Wt as isJournaledOrphan, Xa as renderStatefulReason, Xc as expectedOwnerParam, Xi as malformedOutputsRefusalMessage, Xn as RollbackInlinePolicyWriters, Xo as scrubResourceRecord, Xr as explicitRoleArnOrThrow, Xs as AssetModeResolver, Xt as replacementNeverSwapped, Ya as isStatefulRecreateTargetSync, Yc as decodeListingKey, Yi as malformedOrphansWarning, Yn as formatDestructiveChange, Yo as redactSecretsForState, Yr as assertSendableRoleArn, Ys as rewriteTemplateAssetReferences, Yt as recordUnderIdIsNotOwn, Zc as PARTITION_TABLE, Zi as malformedOutputsWarning, Zo as DYNAMIC_REFERENCE_TOKEN_SCAN, Zr as isIamRoleArn, Zs as BOOTSTRAP_MARKER_PREFIX, Zt as resolveReplacementOldType, _ as makeCanonicalizePropertiesFn, _a as refuseMalformedResourceEntriesForDestroy, _c as isMalformedEnvKey, _i as keepsSecretReferenceToken, _n as carriedExportAliasExposure, _r as readsNoEchoDeleteValues, _s as WHOLE_DYNAMIC_REFERENCE_PATTERN, _t as displacedPhysicalIdShown, a as findNestedTemplateTreeDefect, aa as refuseDivergentRecordRegionForDestroy, ac as validateContainerRepoName, al as hasPlainPrototype, as as carriesSecretMask, at as gray, ba as refuseMalformedResourceEntriesForOrphan, bc as redactedDockerCause, bi as isStalePlaceholderArnAttribute, bn as isWholeDynamicReferenceValue, bo as TemplateParser, br as withPrintingSecrets, bs as isLockInfoExpired, bt as nestedChildStackName$1, c as renderNestedTemplateTreeDefect, ca as refuseMalformedOrphanRecordsForDestroy, cc as resolveDockerContextDirectory, cl as absoluteAssemblyPathEscape, cn as updatePartialReason, cs as recordMaskOnlyValuesIn, ct as yellow, d as conditionInputsFrom, da as refuseMalformedOrphansForOrphan, dc as describeDockerFailure, di as parameterTypeMayLoseSecretIdentity, dl as renderAssemblyPathEscape, dn as WITHHELD_NAME_DISPLAY, dr as CC_BROKEN_REASON, ds as recordProvenPublicExpression, dt as reachableDivergentParameters, ea as malformedResourcePropertiesWarning, ec as getBootstrapMarkerKey, ei as applyCallerIdentityCredentials, el as AssemblyReader, en as findNestedStackTypeChanges, er as withCreateTokenLedger, es as pathCrossesDottedKey, f as parentSuppliedValues, fa as refuseMalformedOutputs, fc as dockerSpawnEnvWithSensitive, fi as getAccountInfo, fl as resolveAssemblyPath, fn as displayTextOrWithheld, fo as prefetchCreateOnlyPropertyPaths, fr as ProviderRegistry, fs as wholeStringLeavesOf, ft as resourcesNamingDeclaredParameter, g as mergeNoChangeOutputs, ga as refuseMalformedResourceEntriesForDeploy, gc as isDockerClientEnvKey, gi as isNamelessDynamicReferenceError, gn as secretSafeKeyDisplay, gr as TemplateNoEchoReresolver, gs as TEMPLATE_SOURCED_RULES, gt as displacedOpClause, h as keptWholeReasonText, ha as refuseMalformedResourceEntries, hc as getDockerCmd, hi as carriesFetchableDynamicReference, hn as secretBearingStateKeyWarning, ho as withRetry, hr as wouldReturnToSdkProvider, hs as STATE_SOURCED_READBACK_RULES, ht as NESTED_PENDING_PARENT_REASON, i as childTemplateLoader, ia as previewableOrphanRecords, ic as validateAssetBucketName, il as hasOwnKey, it as cyan, j as noEchoParameterNamesOf, ja as repairMalformedOutputsForReadOnly, jc as getLegacyStateBucketName, ji as accountArgs, jn as orphanRecordsPrintingBag, jo as readbackPathFor, js as describeRegionValueKind, jt as journaledOrphanLines, k as noEchoComparisonForTemplate, ka as repairMalformedOrphanRecordsForReadOnly, kc as synthesisStatusMessage, ki as UNREADABLE_ORPHANS_CONTAINER_ROW, kn as journaledOrphanPrintingBag, ko as noEchoOutputsComparison, kr as deleteLeftInPlace, ks as splitImportedOps, kt as dropFailedHint, l as templateIdentity, la as refuseMalformedOrphans, lc as describeDockerCapturedOutput, li as coerceParameterTypedValue, ll as describeFileReadFailure, ln as DeploymentEventsReader, ls as recordNoEchoAttributeValues, lt as computeParameterTaint, m as isSecretBearingReferenceString, ma as refuseMalformedResourceAttributesForOrphan, mc as formatDockerLoginError, mi as carriesDynamicReference, ml as resolveBucketRegion, mn as secretBearing, mo as describeTypeWithThrottleRetry, mr as isCustomResource, ms as STATE_SOURCED_CROSS_GENERATION_RULES, mt as planOrphanAdoption, n as IMPLICIT_DELETE_DEPENDENCIES, na as malformedScrubResourceEntriesRefusalMessage, nc as parseBootstrapMarker, ni as envCredentialsAreAssumedRole, nl as processStackMessages, nn as inheritProducerRegions, ns as inheritNestedStackParameterAssociations, nt as createReadOnlyAttributeHealerFactory, o as isAbsoluteAssetPath, oc as buildDenyExternalAccessPolicy, ol as nullPrototypeRecord, os as provenPublicValue, ot as green, p as readRecordedConditionVerdicts, pa as refuseMalformedOutputsForDestroy, pc as finchSecretArgvRefusal, pi as isImpossibleEmptyStoredAttribute, pn as exportAliasCollisionScrubWarning, po as templateResourceTypes, pr as ccBrokenReason, ps as STATE_SOURCED_BASELINE_RULES, pt as makeSiblingClaimReader, qa as MULTI_REGION_RECREATE_BLOCKED_TYPES, qc as uploadCfnTemplate, qi as malformedOrphanRowsKeptWarning, qn as constructPathOf, qo as maskSecretsInText, qr as applyRoleArnIfSet, qs as createAssetRedirectResolver, qt as planRollback, r as computeImplicitDeleteEdges, ra as malformedStateRefusalMessage, rc as readBootstrapMarkerBody, rl as defineOwnKey, rs as recordNestedStackParameterExpressions, rt as bold, s as listNestedTemplateRows, sa as refuseMalformedOrphanRecords, sc as buildDockerImage, sl as ownValue, sn as updatePartialMessage, ss as recordMaskOnlyValue, st as red, t as DeployEngine, ta as malformedResourcesWarning, tc as isCrossRegionRedirect, ti as callerEnvCredentials, tl as StageLoadError, ts as identityKeyFor, tt as formatResourceLine, u as conditionFingerprint, ua as refuseMalformedOrphansForDestroy, uc as describeDockerExecFailure, ui as isUnboundTemplateParameter, ul as displayAssemblyPath, un as DeploymentEventsStore, us as recordNoEchoParameterFreshValue, ut as namesAnyDeclaredParameter, va as refuseMalformedResourceEntriesForImport, vc as partitionSensitiveEnv, vi as AWS_NO_VALUE, vn as exportNameNoEchoParameters, vr as isCustomResourceType$1, vs as isSingleDynamicReferenceToken, vt as dropSettledNestedJournals, w as deferredServiceTokenWarning, wa as refuseMalformedResourcePropertiesForOrphan, wc as escapeRegExp, wi as parameterInputsFor, wn as isExportAliasCollision, wo as maskReadbackAtCoordinates, wr as CloudControlProvider, ws as CrossPrefixScanCache, wt as withNestedRevertRun, xa as refuseMalformedResourcePropertiesForDestroy, xc as runDockerForeground, xi as refStateLookupFromResource, xn as noEchoParameterValueSeed, xo as canonicalCoordinates, xr as CUSTOM_RESOURCE_RESPONSE_LIFECYCLE_RULE_ID, xs as S3StateBackend, xt as recordDisplacedSkips, ya as refuseMalformedResourceEntriesForImportSave, yc as redactDockerArgvValues, yi as cfnRefValueFromPhysicalId, yn as exportNameSecretExposure, yo as DagBuilder, ys as LockManager, za as findActionableSilentDrops, zc as resolveUseCdkBootstrapAssets, zi as malformedDriftResourcePropertiesWarning, zn as buildFinalSnapshotIdentifier, zo as logOnlyValueCount, zs as orphansAfterRollback } from "./deploy-engine-dvf1UDuo.js";
6
+ import { t as getCdkdVersion } from "./version-DE-djeB0.js";
7
7
  import { randomBytes, randomUUID } from "node:crypto";
8
8
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetObjectCommand, HeadBucketCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, NotFound, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutBucketVersioningCommand, PutObjectCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
9
9
  import { GetRoleCommand, GetUserCommand } from "@aws-sdk/client-iam";
@@ -241,7 +241,7 @@ function parsePinCcApiToken(value, previous) {
241
241
  return [...previous ?? [], token];
242
242
  }
243
243
  const pinCcApiOption = new Option("--pin-cc-api <logicalId>", "Keep the named resource (by CloudFormation logical id) on the Cloud Control route in this deploy, declining the automatic return to the SDK Provider that a type-level sdk-coverage exemption would otherwise apply to a resource recorded as provisionedBy: cc-api. Repeatable — pass the flag once per resource. Has no effect on a resource already on the SDK path, and does not override an exemption admitted because Cloud Control cannot manage the type.").argParser(parsePinCcApiToken);
244
- const recreateViaSdkProviderOption = new Option("--recreate-via-sdk-provider <logicalId>", "Destroy + recreate the named resource (by CloudFormation logical id) via cdkd's SDK Provider in this deploy, so a resource currently sticky on provisionedBy: cc-api flips back to provisionedBy: sdk. Used after a #609 backfill release adds SDK coverage for a type the user originally needed CC for (e.g. Lambda LoggingConfig). Repeatable — pass the flag once per resource. Per-resource opt-in. Stateful resource types refuse unless --force-stateful-recreation is ALSO passed.").argParser(parseRecreateViaSdkProviderToken);
244
+ const recreateViaSdkProviderOption = new Option("--recreate-via-sdk-provider <logicalId>", "Destroy + recreate the named resource (by CloudFormation logical id) via cdkd's SDK Provider in this deploy, so a resource currently sticky on provisionedBy: cc-api flips back to provisionedBy: sdk. Used after a release adds SDK coverage for a type the user originally needed CC for (e.g. Lambda LoggingConfig). Repeatable — pass the flag once per resource. Per-resource opt-in. Stateful resource types refuse unless --force-stateful-recreation is ALSO passed.").argParser(parseRecreateViaSdkProviderToken);
245
245
  const forceStatefulRecreationOption = new Option("--force-stateful-recreation", "Confirm a data-losing destroy + recreate of a stateful resource. Required whenever a replacement target is a stateful type on the --recreate-via-cc-api / --recreate-via-sdk-provider pre-flight, with --replace, AND on the paths a plain deploy reaches with no flag: a template immutable-property change, and an in-place update the provisioning layer rejects. Stateful types are databases, filesystems, KMS keys, table / vector storage, source repositories, and more; https://cdkd.dev/cli-deploy-safety/ carries the full list. S3 buckets and log groups are the conditional cases: at pre-flight, a non-empty bucket, or a log group with retention, with log streams, or whose emptiness the probe could not settle; mid-deploy, ANY bucket or log group, because the emptiness probe cannot run there. The two probes differ on failure — the bucket fails open, the log group closed. Destroy + recreate loses ALL data in the resource — no automatic data migration. Full opt-in for CI use: --recreate-via-cc-api '<id>' --force-stateful-recreation --yes.").default(false);
246
246
  const replaceOption = new Option("--replace", "Replace (DELETE + CREATE) a resource whose in-place update is rejected because an immutable property changed and AWS exposes no update API for it (e.g. Lambda LayerVersion content, EFS AccessPoint, ECS TaskDefinition, ApiGatewayV2 immutable fields). Without this flag such a change fails the deploy. Stateful types (RDS / DynamoDB / EFS / any S3 bucket / any Logs log group / etc.) ALSO require --force-stateful-recreation since the replacement is a data-losing DELETE + CREATE — mid-deploy neither emptiness probe can run, so both conditional types count as stateful there.").default(false);
247
247
  const useCdkBootstrapAssetsOption = new Option("--use-cdk-bootstrap-assets", "Publish assets to the CDK bootstrap bucket/repo named by the asset manifest verbatim, skipping the cdkd asset-storage redirection even when this region is opted in via 'cdkd bootstrap'. For apps deployed via both CloudFormation and cdkd during a migration window. Per-app pin: cdk.json context.cdkd.useCdkBootstrapAssets. Also suppresses the legacy-mode 'cdk gc' notice.").default(false);
@@ -867,6 +867,11 @@ async function bootstrapCommand(options) {
867
867
  Policy: JSON.stringify(bucketPolicy)
868
868
  }));
869
869
  logger.info("✓ Set bucket policy (deny external access)");
870
+ logger.debug("Setting custom-resource response lifecycle rule...");
871
+ const lifecycle = await applyCustomResourceResponseExpiration(stateBucketS3, bucketName, { expectedBucketOwner: accountId });
872
+ if (lifecycle.status === "failed" || lifecycle.status === "refused") logger.warn(customResourceResponseExpirationWarning(bucketName, lifecycle));
873
+ else if (lifecycle.status === "added") logger.info(safeMsg`✓ Set lifecycle rule (expire ${CUSTOM_RESOURCE_RESPONSE_PREFIX}/ responses after ${1} day)`);
874
+ else logger.info(safeMsg`✓ Lifecycle rule ${CUSTOM_RESOURCE_RESPONSE_LIFECYCLE_RULE_ID} already present (left unchanged)`);
870
875
  }
871
876
  let assetStorage;
872
877
  if (options.assets) {
@@ -921,7 +926,7 @@ async function bootstrapCommand(options) {
921
926
  }
922
927
  }
923
928
  function createBootstrapCommand() {
924
- const cmd = new Command("bootstrap").description("Bootstrap cdkd by creating the S3 state bucket plus cdkd-owned asset storage (asset bucket + container-asset ECR repo) for the region. With --destroy, tear down the region's asset storage instead (issue #1010).").option("--state-bucket <bucket>", "Name of S3 bucket to create for state storage (default: cdkd-state-{accountId})").option("--force", "Create: force reconfiguration of an existing bucket. Destroy: delete the asset storage even when deployed stacks still reference it", false).option("--no-assets", "Skip cdkd asset storage (asset bucket / ECR repo / marker) — deploys keep publishing assets to the CDK bootstrap bucket/repo").option("--asset-bucket <name>", "Custom name for the cdkd asset bucket (default: cdkd-assets-{accountId}-{region}). Written into the bootstrap marker; re-bootstrapping a region with a different name is refused").option("--container-repo <name>", "Custom name for the container-asset ECR repository (default: cdkd-container-assets-{accountId}-{region}). Written into the bootstrap marker; re-bootstrapping a region with a different name is refused").option("--destroy", "Tear down the region's cdkd asset storage (empty + delete the asset bucket, force-delete the container-asset ECR repo, then delete the bootstrap marker last). The state bucket is kept unless --include-state-bucket is also passed", false).option("--include-state-bucket", "With --destroy: also delete the S3 state bucket. Refused while any stack state exists or any other region is still opted in to asset storage", false).addOption(new Option("--region <region>", "AWS region to bootstrap, or to tear down with --destroy (defaults to AWS_REGION env, else us-east-1)")).action(withErrorHandling(async (options) => {
929
+ const cmd = new Command("bootstrap").description("Bootstrap cdkd by creating the S3 state bucket plus cdkd-owned asset storage (asset bucket + container-asset ECR repo) for the region. With --destroy, tear down the region's asset storage instead.").option("--state-bucket <bucket>", "Name of S3 bucket to create for state storage (default: cdkd-state-{accountId})").option("--force", "Create: force reconfiguration of an existing bucket. Destroy: delete the asset storage even when deployed stacks still reference it", false).option("--no-assets", "Skip cdkd asset storage (asset bucket / ECR repo / marker) — deploys keep publishing assets to the CDK bootstrap bucket/repo").option("--asset-bucket <name>", "Custom name for the cdkd asset bucket (default: cdkd-assets-{accountId}-{region}). Written into the bootstrap marker; re-bootstrapping a region with a different name is refused").option("--container-repo <name>", "Custom name for the container-asset ECR repository (default: cdkd-container-assets-{accountId}-{region}). Written into the bootstrap marker; re-bootstrapping a region with a different name is refused").option("--destroy", "Tear down the region's cdkd asset storage (empty + delete the asset bucket, force-delete the container-asset ECR repo, then delete the bootstrap marker last). The state bucket is kept unless --include-state-bucket is also passed", false).option("--include-state-bucket", "With --destroy: also delete the S3 state bucket. Refused while any stack state exists or any other region is still opted in to asset storage", false).addOption(new Option("--region <region>", "AWS region to bootstrap, or to tear down with --destroy (defaults to AWS_REGION env, else us-east-1)")).action(withErrorHandling(async (options) => {
925
930
  if (options.destroy) {
926
931
  if (options.assetBucket !== void 0 || options.containerRepo !== void 0) throw new CdkdError("--asset-bucket / --container-repo cannot be combined with --destroy. The teardown reads the region's asset storage names from the bootstrap marker.", "INVALID_OPTIONS");
927
932
  if (!options.assets) throw new CdkdError("--no-assets cannot be combined with --destroy. The teardown scope is the asset storage itself; use --include-state-bucket to also delete the state bucket.", "INVALID_OPTIONS");
@@ -1506,7 +1511,7 @@ function renderRecreateTargetsErrors(validation) {
1506
1511
  if (lines.length > 0) lines.push("");
1507
1512
  lines.push(`${FLAG_UMBRELLA} named ${validation.missingFromState.length} logical id(s) the template declares but cdkd state has no record of:`);
1508
1513
  for (const id of validation.missingFromState) lines.push(` - ${id}`);
1509
- lines.push(" These are fresh CREATEs on the next deploy — recreate has nothing to destroy first. Remove the flag for these resources; the auto-route via Cloud Control (#614) handles fresh deploys for silent-drop properties, and SDK Provider is the default for everything else.");
1514
+ lines.push(" These are fresh CREATEs on the next deploy — recreate has nothing to destroy first. Remove the flag for these resources; the auto-route via Cloud Control handles fresh deploys for silent-drop properties, and SDK Provider is the default for everything else.");
1510
1515
  }
1511
1516
  if (validation.ambiguousIntent.length > 0) {
1512
1517
  if (lines.length > 0) lines.push("");
@@ -2404,7 +2409,7 @@ function collectCrossStackRefs(node, onRef) {
2404
2409
  //#region src/provisioning/register-providers.ts
2405
2410
  let providerClasses;
2406
2411
  function loadProviderClasses() {
2407
- providerClasses ??= import("./provider-classes-DmZ0J68L.js");
2412
+ providerClasses ??= import("./provider-classes-uUFRfL9s.js");
2408
2413
  return providerClasses;
2409
2414
  }
2410
2415
  function registerAllProviders(registry, classes) {
@@ -4401,7 +4406,7 @@ function deployRefusesPropertiesReason(logicalIds) {
4401
4406
  return `${logicalIds.length} resource record(s) hold a 'properties' map that cannot be read. This preview repaired them to empty; 'cdkd deploy' refuses the record instead, so the deploy this previews will not start.`;
4402
4407
  }
4403
4408
  function nestedStackTypeChangeReason(tc) {
4404
- return `${displayIdent(tc.logicalId)}: Type changes from ${displayIdent(tc.currentType)} to ${displayIdent(tc.desiredType)}. cdkd does not replace a resource into or out of ${NESTED_STACK_RESOURCE_TYPE} (issue #2668); give the new resource a different logical id, or remove it in one deploy and add its replacement in the next.`;
4409
+ return `${displayIdent(tc.logicalId)}: Type changes from ${displayIdent(tc.currentType)} to ${displayIdent(tc.desiredType)}. cdkd does not replace a resource into or out of ${NESTED_STACK_RESOURCE_TYPE}; give the new resource a different logical id, or remove it in one deploy and add its replacement in the next.`;
4405
4410
  }
4406
4411
  function findUnwrittenCreateOnlyRefusals(changes, stateResources) {
4407
4412
  const reasons = [];
@@ -4782,6 +4787,9 @@ async function computeStackDiff(currentState, template, region, stackName, state
4782
4787
  recordLogOnlyParameterValue(diffSecrets, mergedParameters[name]);
4783
4788
  recordLogOnlyParameterValue(splitPieces, mergedParameters[name], splitDelimiters);
4784
4789
  }
4790
+ const noEchoJudge = new Map(diffSecrets);
4791
+ carryLogOnlyValues(diffSecrets, noEchoJudge);
4792
+ const stateNames = storedSecretNameNeedles(currentState.resources ?? {}, noEchoJudge, /* @__PURE__ */ new Map(), currentState.outputs);
4785
4793
  const outputsPassSecrets = /* @__PURE__ */ new Map();
4786
4794
  const printing = createDiffPrintingMasker([
4787
4795
  diffSecrets,
@@ -4790,6 +4798,7 @@ async function computeStackDiff(currentState, template, region, stackName, state
4790
4798
  ], [
4791
4799
  splitPieces,
4792
4800
  derivedNames,
4801
+ stateNames,
4793
4802
  ...inheritedDerivedNames ? [inheritedDerivedNames] : []
4794
4803
  ]);
4795
4804
  const maskForLog = printing.mask;
@@ -4846,6 +4855,7 @@ async function computeStackDiff(currentState, template, region, stackName, state
4846
4855
  logger.warn(malformedResourcePropertiesWarning(stackName, region, tornAdopted, options.refusalRecovery));
4847
4856
  deployRefusals.push(deployRefusesPropertiesReason(tornAdopted));
4848
4857
  }
4858
+ storedSecretNameNeedles(stateForDiff.resources, noEchoJudge, stateNames, currentState.outputs);
4849
4859
  }
4850
4860
  const alreadyReported = new Set(reportedByTheAdoptedPropertiesArm);
4851
4861
  const previewedRowsTheDeployRefuses = readableOrphans.filter((record) => !isReadableOrphanRecord(record)).map((record) => record.logicalId).filter((logicalId) => !alreadyReported.has(logicalId));
@@ -4996,6 +5006,7 @@ async function computeStackDiff(currentState, template, region, stackName, state
4996
5006
  effectiveTemplate,
4997
5007
  printingSecrets,
4998
5008
  derivedNames: diffPrintingSecrets([derivedNames, inheritedDerivedNames]),
5009
+ secretNamedRecords: secretNamedRecordNeedles(stateForDiff.resources, noEchoJudge),
4999
5010
  resolvedParameters: mergedParameters,
5000
5011
  conditions,
5001
5012
  knownConditions: conditions === void 0 ? void 0 : Object.fromEntries(Object.entries(conditions).filter(([name]) => !stillUnknown.includes(name))),
@@ -5234,7 +5245,7 @@ async function buildDiffTree(args) {
5234
5245
  } finally {
5235
5246
  createOnlyPrefetch.cancel();
5236
5247
  }
5237
- const { changes, outputChanges, adoptedOrphans, adoptedRecords, blocking, unreadableOrphans, deployRefusals: adoptedDeployRefusals, effectiveTemplate, printingSecrets, derivedNames: nodeDerivedNames, resolvedParameters, conditions, knownConditions, trust } = stackDiff;
5248
+ const { changes, outputChanges, adoptedOrphans, adoptedRecords, blocking, unreadableOrphans, deployRefusals: adoptedDeployRefusals, effectiveTemplate, printingSecrets, derivedNames: nodeDerivedNames, secretNamedRecords: nodeStateNames, resolvedParameters, conditions, knownConditions, trust } = stackDiff;
5238
5249
  const stateAfterAdoption = Object.keys(adoptedRecords).length > 0 ? {
5239
5250
  ...state,
5240
5251
  resources: {
@@ -5285,7 +5296,11 @@ async function buildDiffTree(args) {
5285
5296
  ]), void 0, stateAfterAdoption.resources);
5286
5297
  const rowDerivedNames = /* @__PURE__ */ new Map();
5287
5298
  const childParameters = await resolveChildStackParameters(resource, effectiveTemplate, stateAfterAdoption, region, stackName, stateBackend, resolvedParameters, conditions, cfnFallback, printingSecrets, attributeHealer, childUnresolvedParameters, trust, rowDerivedNames);
5288
- const childDerivedNames = diffPrintingSecrets([inheritedDerivedNames, rowDerivedNames]);
5299
+ const childDerivedNames = diffPrintingSecrets([
5300
+ inheritedDerivedNames,
5301
+ rowDerivedNames,
5302
+ nodeStateNames
5303
+ ]);
5289
5304
  const buildChild = () => buildDiffTree({
5290
5305
  stackName: childStackName,
5291
5306
  displayName: childStackName,
@@ -5320,7 +5335,7 @@ async function buildDiffTree(args) {
5320
5335
  for (const [logicalId, resource] of Object.entries(state.resources ?? {})) {
5321
5336
  if (resource.resourceType !== "AWS::CloudFormation::Stack") continue;
5322
5337
  if (templateChildIds.has(logicalId)) continue;
5323
- node.children.push(await buildDeletedSubtree(`${stackName}~${logicalId}`, region, stateBackend, diffCalculator, secretBearingAbove, printingSecrets, refusalRecovery, diffPrintingSecrets([nodeDerivedNames, stateDerivedNames(state.resources ?? {})])));
5338
+ node.children.push(await buildDeletedSubtree(`${stackName}~${logicalId}`, region, stateBackend, diffCalculator, secretBearingAbove, printingSecrets, refusalRecovery, diffPrintingSecrets([nodeDerivedNames, nodeStateNames])));
5324
5339
  }
5325
5340
  return node;
5326
5341
  }
@@ -5355,10 +5370,7 @@ async function buildDeletedSubtree(stackName, region, stateBackend, diffCalculat
5355
5370
  return node;
5356
5371
  }
5357
5372
  function stateDerivedNames(resources) {
5358
- const bag = /* @__PURE__ */ new Map();
5359
- const needlesOf = stateSecretNameNeedles(resources);
5360
- for (const logicalId of Object.keys(resources)) for (const needle of needlesOf(logicalId) ?? []) recordLogOnlyValue(bag, needle);
5361
- return bag;
5373
+ return secretNamedRecordNeedles(resources, void 0);
5362
5374
  }
5363
5375
  const EMPTY_ALLOW_SET = /* @__PURE__ */ new Set();
5364
5376
  function diffReplaces(change, record) {
@@ -5468,7 +5480,7 @@ function diffTreeToJson(node) {
5468
5480
  children: node.children.map(diffTreeToJson)
5469
5481
  };
5470
5482
  }
5471
- function isIntrinsic(value) {
5483
+ function isIntrinsic$1(value) {
5472
5484
  if (value === null || value === void 0 || typeof value !== "object" || Array.isArray(value)) return false;
5473
5485
  const keys = Object.keys(value);
5474
5486
  return keys.length === 1 && INTRINSIC_KEYS.has(keys[0]);
@@ -5476,12 +5488,12 @@ function isIntrinsic(value) {
5476
5488
  function stripUnchangedValues(value, other) {
5477
5489
  if (value === null || value === void 0 || typeof value !== "object") return value;
5478
5490
  if (Array.isArray(value)) return value;
5479
- if (isIntrinsic(value)) return void 0;
5480
- if (isIntrinsic(other)) return void 0;
5491
+ if (isIntrinsic$1(value)) return void 0;
5492
+ if (isIntrinsic$1(other)) return void 0;
5481
5493
  return value;
5482
5494
  }
5483
5495
  function isPlainNonIntrinsicObject(value) {
5484
- return typeof value === "object" && value !== null && !Array.isArray(value) && !isIntrinsic(value);
5496
+ return typeof value === "object" && value !== null && !Array.isArray(value) && !isIntrinsic$1(value);
5485
5497
  }
5486
5498
  function stripUnchangedValuePair(oldValue, newValue) {
5487
5499
  if (!isPlainNonIntrinsicObject(oldValue) || !isPlainNonIntrinsicObject(newValue)) return [stripUnchangedValues(oldValue, newValue), stripUnchangedValues(newValue, oldValue)];
@@ -5491,7 +5503,7 @@ function stripUnchangedValuePair(oldValue, newValue) {
5491
5503
  for (const key of keys) {
5492
5504
  const o = oldValue[key];
5493
5505
  const n = newValue[key];
5494
- if (isIntrinsic(o) || isIntrinsic(n)) continue;
5506
+ if (isIntrinsic$1(o) || isIntrinsic$1(n)) continue;
5495
5507
  if (JSON.stringify(o) === JSON.stringify(n)) continue;
5496
5508
  if (isPlainNonIntrinsicObject(o) && isPlainNonIntrinsicObject(n)) {
5497
5509
  const [fo, fn] = stripUnchangedValuePair(o, n);
@@ -5506,7 +5518,7 @@ function stripUnchangedValuePair(oldValue, newValue) {
5506
5518
  return [oldResult, newResult];
5507
5519
  }
5508
5520
  function renderDiffValue(own, filtered, indent, isNewSide) {
5509
- if (isIntrinsic(own)) {
5521
+ if (isIntrinsic$1(own)) {
5510
5522
  const suffix = isNewSide ? " (known after deploy)" : "";
5511
5523
  return `${JSON.stringify(own)}${suffix}`;
5512
5524
  }
@@ -8775,9 +8787,10 @@ function stripWalk(value) {
8775
8787
 
8776
8788
  //#endregion
8777
8789
  //#region src/cli/commands/refused-baseline-remedy.ts
8790
+ const ACCEPT_REFUSED_REMEDY = "Once the deployed template no longer reads a parameter at this resource, cdkd state refresh-observed '<stack>' --accept-refused '<logicalId>' --template '<file>' records a baseline on your assertion that AWS holds no secret the template does not spell as a dynamic reference.";
8778
8791
  function refusedBaselineRemedy(record) {
8779
- if (hasUnverifiableParameterRefusal(record)) return "Deploying a change does NOT clear this refusal: the resource reads a template parameter whose deployed value cdkd could not prove, so only a deploy that replaces the resource, or a re-import while a CloudFormation stack can prove that value, restores a baseline.";
8780
- if (hasReasonlessBaselineRefusal(record)) return "This refusal was recorded without a reason this cdkd recognizes: a deploy that actually CHANGES this resource restores a baseline unless the resource reads a template parameter, and then only a deploy that replaces the resource, or a re-import while a CloudFormation stack can prove the parameter's deployed value, does.";
8792
+ if (hasUnverifiableParameterRefusal(record)) return "Deploying a change does NOT clear this refusal: the resource reads a template parameter whose deployed value cdkd could not prove, so only a deploy that replaces the resource, or a re-import while a CloudFormation stack can prove that value, restores a baseline. " + ACCEPT_REFUSED_REMEDY;
8793
+ if (hasReasonlessBaselineRefusal(record)) return "This refusal was recorded without a reason this cdkd recognizes: a deploy that actually CHANGES this resource restores a baseline unless the resource reads a template parameter, and then only a deploy that replaces the resource, or a re-import while a CloudFormation stack can prove the parameter's deployed value, does. " + ACCEPT_REFUSED_REMEDY;
8781
8794
  }
8782
8795
 
8783
8796
  //#endregion
@@ -10743,7 +10756,7 @@ function printRevertPlan(reports, out, recovery) {
10743
10756
  ...accountArgs(recovery)
10744
10757
  ]) : void 0;
10745
10758
  const refreshAccountNote = refresh === void 0 ? "" : withheldAccountClause(recovery, "the command below prints").trimEnd();
10746
- out.write(" The template does not declare these, so cdkd cannot tell an AWS-authored value from an out-of-band change and will not reset either (issue #1626). " + (refresh === void 0 ? "Re-deploy if you want them reverted too; this record's identity cannot be named safely in a command, so none is offered.\n" : `Populate observedProperties with the command below, or re-deploy, if you want them reverted too.${refreshAccountNote === "" ? "" : ` ${refreshAccountNote}`}\n`));
10759
+ out.write(" The template does not declare these, so cdkd cannot tell an AWS-authored value from an out-of-band change and will not reset either. " + (refresh === void 0 ? "Re-deploy if you want them reverted too; this record's identity cannot be named safely in a command, so none is offered.\n" : `Populate observedProperties with the command below, or re-deploy, if you want them reverted too.${refreshAccountNote === "" ? "" : ` ${refreshAccountNote}`}\n`));
10747
10760
  if (refresh !== void 0) out.write(` Populate with: ${refresh.command}\n`);
10748
10761
  }
10749
10762
  }
@@ -12283,7 +12296,7 @@ async function destroyCommand(stackArgs, options) {
12283
12296
  }
12284
12297
  }
12285
12298
  function createDestroyCommand() {
12286
- const cmd = new Command("destroy").description("Destroy all resources in the stack").argument("[stacks...]", "Stack name(s) to destroy. Accepts CDK display paths (e.g. 'MyStage/Api') with wildcards ('MyStage/*', '**'), or exact physical CloudFormation names (e.g. 'MyStage-Api').").option("--all", "Destroy every top-level stack (top-level only; Stage stacks: '**')", false).option("--purge-events", `After a clean destroy, also delete the stack's deployment-event history (issue #808 store), purging every earlier version under the stack's deployments/ prefix on a versioned state bucket too unless a warning says otherwise. By default events survive destroy as post-mortem context. Skipped when the destroy fails or is interrupted (those events aid the retry). Equivalent for an already-destroyed stack: cdkd events prune ${commandHole("stack")} --all.`, false).action(withErrorHandling(destroyCommand));
12299
+ const cmd = new Command("destroy").description("Destroy all resources in the stack").argument("[stacks...]", "Stack name(s) to destroy. Accepts CDK display paths (e.g. 'MyStage/Api') with wildcards ('MyStage/*', '**'), or exact physical CloudFormation names (e.g. 'MyStage-Api').").option("--all", "Destroy every top-level stack (top-level only; Stage stacks: '**')", false).option("--purge-events", `After a clean destroy, also delete the stack's deployment-event history, purging every earlier version under the stack's deployments/ prefix on a versioned state bucket too unless a warning says otherwise. By default events survive destroy as post-mortem context. Skipped when the destroy fails or is interrupted (those events aid the retry). Equivalent for an already-destroyed stack: cdkd events prune ${commandHole("stack")} --all.`, false).action(withErrorHandling(destroyCommand));
12287
12300
  [
12288
12301
  ...commonOptions,
12289
12302
  ...appOptions,
@@ -15263,7 +15276,7 @@ async function cachedTypeSchemaInfo(resourceType, cfnClient, cache) {
15263
15276
  function typeIsImportUnsupported(entry) {
15264
15277
  return entry.importSupport === "unsupported";
15265
15278
  }
15266
- const CFN_IMPORT_REFUSED_DESPITE_REGISTRY = /* @__PURE__ */ new Map([["AWS::AppSync::GraphQLApi", "measured in us-east-1 on 2026-09-18: the registry schema declares a read handler and FULLY_MUTABLE, yet CreateChangeSet --change-set-type IMPORT rejected the type"]]);
15279
+ const CFN_IMPORT_REFUSED_DESPITE_REGISTRY = /* @__PURE__ */ new Map([["AWS::AppSync::GraphQLApi", "measured against AWS: the registry schema declares a read handler and FULLY_MUTABLE, yet CreateChangeSet --change-set-type IMPORT rejected the type"]]);
15267
15280
  function cfnRefusesImportDespiteRegistry(resourceType) {
15268
15281
  return CFN_IMPORT_REFUSED_DESPITE_REGISTRY.get(resourceType);
15269
15282
  }
@@ -16142,7 +16155,7 @@ async function runPerStackImportLoop(args) {
16142
16155
  if (!options.yes) {
16143
16156
  const phase2Note = totalPhase2Creates > 0 ? ` Phase 2 will CREATE ${totalPhase2Creates} non-importable resource(s) across the tree.` : "";
16144
16157
  const recreateNote = totalRecreate > 0 ? ` cdkd will also DELETE ${totalRecreate} AWS resource(s) between phases so CFn can re-CREATE them in phase 2 (brief unavailability window — see the plan above for the affected resources, and for any marked as not confirmed to be re-created).` : "";
16145
- if (!await confirmPrompt$2(`Create ${perStackPlans.length} CloudFormation stack(s) by importing the cdkd nested-stack tree rooted at ${quotedOrNotShown(rootStackName)} (${quotedRegion(rootRegion)}) — leaf-first, per-stack IMPORT loop (#464 design §4.3).` + phase2Note + recreateNote + (totalRecreate > 0 ? ` All other AWS resources are unchanged.` : ` AWS resources are unchanged.`) + ` cdkd state for every adopted stack will be deleted on success.`)) {
16158
+ if (!await confirmPrompt$2(`Create ${perStackPlans.length} CloudFormation stack(s) by importing the cdkd nested-stack tree rooted at ${quotedOrNotShown(rootStackName)} (${quotedRegion(rootRegion)}) — leaf-first, per-stack IMPORT loop.` + phase2Note + recreateNote + (totalRecreate > 0 ? ` All other AWS resources are unchanged.` : ` AWS resources are unchanged.`) + ` cdkd state for every adopted stack will be deleted on success.`)) {
16146
16159
  logger.info("Migration cancelled. cdkd state and CloudFormation are unchanged.");
16147
16160
  return {
16148
16161
  outcome: "cancelled",
@@ -16530,6 +16543,250 @@ function spacedAccountClause(recovery, where) {
16530
16543
  return clause === "" ? "" : ` ${clause}`;
16531
16544
  }
16532
16545
 
16546
+ //#endregion
16547
+ //#region src/cli/commands/state-refresh-observed.ts
16548
+ function collectAcceptRefused(value, previous) {
16549
+ if (value === "") throw new InvalidArgumentError("--accept-refused takes one logical id.");
16550
+ return [...previous ?? [], value];
16551
+ }
16552
+ function readAcceptRefusedTemplate(path) {
16553
+ const shown = displayIdent(path, { maxCodePoints: STACK_REF_MAX_CODE_POINTS });
16554
+ let raw;
16555
+ try {
16556
+ raw = readFileSync(path, "utf-8");
16557
+ } catch (err) {
16558
+ throw new Error(`Failed to read the --template file ${shown}: ${fsReadErrorCause(err)}`);
16559
+ }
16560
+ let parsed;
16561
+ try {
16562
+ parsed = parseCfnTemplateWithFormat(raw).template;
16563
+ } catch {
16564
+ parsed = void 0;
16565
+ }
16566
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error(`The --template file ${shown} is not a valid CloudFormation template (JSON or YAML).`);
16567
+ return parsed;
16568
+ }
16569
+ function judgeAcceptRefused(record, logicalId, template, stack) {
16570
+ const id = displayIdent(logicalId);
16571
+ if (record === void 0) return {
16572
+ ok: false,
16573
+ reason: `The stack's state record has no resource ${id}.`
16574
+ };
16575
+ if (record.observedBaselineRefused !== true) return {
16576
+ ok: false,
16577
+ reason: `${id} carries no observed-baseline refusal, so there is nothing to accept. Run 'cdkd state refresh-observed' without --accept-refused to refresh it.`
16578
+ };
16579
+ const reason = record.observedBaselineRefusalReason;
16580
+ if (reason === "incomplete-resolution") return {
16581
+ ok: false,
16582
+ reason: `The refusal on ${id} is not over a template parameter, and --accept-refused overrides only that class. A deploy that actually CHANGES the resource restores its baseline.`
16583
+ };
16584
+ const legacy = reason !== "unverifiable-parameter";
16585
+ const verdict = resourcesNamingDeclaredParameter(template);
16586
+ if (verdict.failedClosed !== void 0) return {
16587
+ ok: false,
16588
+ reason: `The template's parameter dependence could not be judged (${verdict.failedClosed}), so the refusal on ${id} cannot be accepted.`
16589
+ };
16590
+ const resources = template["Resources"];
16591
+ const definition = Object.hasOwn(resources, logicalId) ? resources[logicalId] : void 0;
16592
+ if (definition === null || typeof definition !== "object" || Array.isArray(definition)) return {
16593
+ ok: false,
16594
+ reason: `The template defines no resource ${id}. Pass the template this stack was last deployed from (for a nested stack, the child's own template).`
16595
+ };
16596
+ if (definition["Type"] !== record.resourceType) return {
16597
+ ok: false,
16598
+ reason: `The template's ${id} is not the resource type the state record holds, so the template does not describe this resource.`
16599
+ };
16600
+ if (verdict(logicalId)) return {
16601
+ ok: false,
16602
+ reason: `In this template ${id} still depends on a template parameter, and cdkd binds a parameter's Default, which is not what AWS may hold. Make the template spell the value as a dynamic reference (or a literal), deploy it, then run this again.`
16603
+ };
16604
+ const shape = matchesDeployedShape(definition["Properties"] ?? {}, record.properties, stack);
16605
+ if (shape === "unprovable") return {
16606
+ ok: false,
16607
+ reason: `The template defines ${id} with a function cdkd cannot work out from the state records (only Ref, Fn::GetAtt, Fn::Join, Fn::Sub and Fn::Select of what the stack records), so cdkd cannot prove the template was deployed to the resource. A deploy does not change that; replacing the resource clears the refusal.`
16608
+ };
16609
+ if (shape === "differs") return {
16610
+ ok: false,
16611
+ reason: `The state record of ${id} does not hold what this template defines for it, so cdkd cannot prove the template was deployed to the resource. Pass the template it was last deployed from, or deploy this one and run this again. If cdkd records this resource with fewer properties than the template sets (one it does not send), a deploy does not change that, and replacing the resource clears the refusal.`
16612
+ };
16613
+ const hit = parameterDefaultInProperties(template, record.properties);
16614
+ if (hit !== void 0) return {
16615
+ ok: false,
16616
+ reason: `A recorded property of ${id} holds the Default of the template parameter ${displayIdent(hit)}, so the record may still hold the placeholder the refusal distrusted. If the template no longer uses the parameter there, deploy it and run this again. If the value only coincides with that Default, change or remove the parameter's Default and deploy, or replace the resource.`
16617
+ };
16618
+ return {
16619
+ ok: true,
16620
+ legacy
16621
+ };
16622
+ }
16623
+ const ACCOUNT = Symbol("account");
16624
+ const MISSING = Symbol("missing");
16625
+ function matchesDeployedShape(node, recorded, stack) {
16626
+ let differs = false;
16627
+ let unprovable = false;
16628
+ const pending = [[node, recorded]];
16629
+ while (pending.length > 0) {
16630
+ const [t, r] = pending.pop();
16631
+ if (t === null || typeof t !== "object") {
16632
+ if (t !== r) differs = true;
16633
+ } else if (Array.isArray(t)) {
16634
+ if (!Array.isArray(r) || r.length !== t.length) differs = true;
16635
+ else t.forEach((item, i) => pending.push([item, r[i]]));
16636
+ } else if (isIntrinsic(t)) {
16637
+ const parts = evaluate(t, stack);
16638
+ if (parts === void 0) {
16639
+ unprovable = true;
16640
+ continue;
16641
+ }
16642
+ if (parts === MISSING) {
16643
+ differs = true;
16644
+ continue;
16645
+ }
16646
+ const text = typeof r === "string" ? r : typeof r === "number" ? String(r) : void 0;
16647
+ if (text === void 0 || !partsPattern(parts).test(text)) differs = true;
16648
+ } else if (r === null || typeof r !== "object" || Array.isArray(r)) differs = true;
16649
+ else {
16650
+ const tKeys = Object.keys(t).sort();
16651
+ const rKeys = Object.keys(r).sort();
16652
+ if (tKeys.length !== rKeys.length || tKeys.some((k, i) => k !== rKeys[i])) differs = true;
16653
+ for (const k of tKeys) {
16654
+ if (!Object.hasOwn(r, k)) continue;
16655
+ pending.push([t[k], r[k]]);
16656
+ }
16657
+ }
16658
+ }
16659
+ return unprovable ? "unprovable" : differs ? "differs" : "match";
16660
+ }
16661
+ function isIntrinsic(node) {
16662
+ const keys = Object.keys(node);
16663
+ return keys.length === 1 && (keys[0] === "Ref" || keys[0].startsWith("Fn::"));
16664
+ }
16665
+ function partsPattern(parts) {
16666
+ const body = parts.map((p) => p === ACCOUNT ? "[0-9]{12}" : p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
16667
+ return new RegExp(`^${body}$`);
16668
+ }
16669
+ function evaluate(node, stack) {
16670
+ if (typeof node === "string") return [node];
16671
+ if (typeof node === "number" && Number.isFinite(node)) return [String(node)];
16672
+ if (node === null || typeof node !== "object" || Array.isArray(node) || !isIntrinsic(node)) return;
16673
+ const [fn, arg] = Object.entries(node)[0];
16674
+ switch (fn) {
16675
+ case "Ref": return typeof arg === "string" ? reference(arg, stack) : void 0;
16676
+ case "Fn::GetAtt": {
16677
+ const pair = typeof arg === "string" ? arg.includes(".") ? [arg.slice(0, arg.indexOf(".")), arg.slice(arg.indexOf(".") + 1)] : void 0 : arg;
16678
+ if (!Array.isArray(pair) || pair.length !== 2) return void 0;
16679
+ const [target, attribute] = pair;
16680
+ return typeof target === "string" && typeof attribute === "string" ? attributeOf(target, attribute, stack) : void 0;
16681
+ }
16682
+ case "Fn::Join": {
16683
+ if (!Array.isArray(arg) || arg.length !== 2) return void 0;
16684
+ const [delimiter, list] = arg;
16685
+ if (typeof delimiter !== "string" || !Array.isArray(list)) return void 0;
16686
+ const out = [];
16687
+ let missing = false;
16688
+ for (let i = 0; i < list.length; i++) {
16689
+ const parts = evaluate(list[i], stack);
16690
+ if (parts === void 0) return void 0;
16691
+ if (i > 0 && delimiter !== "") out.push(delimiter);
16692
+ if (parts === MISSING) missing = true;
16693
+ else out.push(...parts);
16694
+ }
16695
+ return missing ? MISSING : out;
16696
+ }
16697
+ case "Fn::Select": {
16698
+ if (!Array.isArray(arg) || arg.length !== 2) return void 0;
16699
+ const [index, list] = arg;
16700
+ const i = typeof index === "number" ? index : typeof index === "string" ? Number(index) : NaN;
16701
+ if (!Number.isInteger(i) || !Array.isArray(list) || i < 0 || i >= list.length) return;
16702
+ return evaluate(list[i], stack);
16703
+ }
16704
+ case "Fn::Sub": {
16705
+ const [text, vars] = Array.isArray(arg) ? arg : [arg, {}];
16706
+ if (typeof text !== "string" || vars === null || typeof vars !== "object" || Array.isArray(vars)) return;
16707
+ const out = [];
16708
+ let missing = false;
16709
+ let last = 0;
16710
+ for (const m of text.matchAll(/\$\{([^}]*)\}/g)) {
16711
+ out.push(text.slice(last, m.index));
16712
+ last = m.index + m[0].length;
16713
+ const name = m[1];
16714
+ if (name.startsWith("!")) {
16715
+ out.push(`\${${name.slice(1)}}`);
16716
+ continue;
16717
+ }
16718
+ const parts = Object.hasOwn(vars, name) ? evaluate(vars[name], stack) : name.includes(".") ? attributeOf(name.slice(0, name.indexOf(".")), name.slice(name.indexOf(".") + 1), stack) : reference(name, stack);
16719
+ if (parts === void 0) return void 0;
16720
+ if (parts === MISSING) missing = true;
16721
+ else out.push(...parts);
16722
+ }
16723
+ out.push(text.slice(last));
16724
+ return missing ? MISSING : out;
16725
+ }
16726
+ default: return;
16727
+ }
16728
+ }
16729
+ function reference(name, stack) {
16730
+ switch (name) {
16731
+ case "AWS::Region": return [stack.region];
16732
+ case "AWS::Partition": return [derivePartitionAndUrlSuffix(stack.region).partition];
16733
+ case "AWS::URLSuffix": return [derivePartitionAndUrlSuffix(stack.region).urlSuffix];
16734
+ case "AWS::AccountId": return [ACCOUNT];
16735
+ case "AWS::StackName": return [stack.stackName];
16736
+ }
16737
+ if (name.startsWith("AWS::")) return void 0;
16738
+ if (!Object.hasOwn(stack.resources, name)) return MISSING;
16739
+ const physicalId = stack.resources[name]?.physicalId;
16740
+ return typeof physicalId === "string" ? [physicalId] : void 0;
16741
+ }
16742
+ function attributeOf(target, attribute, stack) {
16743
+ if (!Object.hasOwn(stack.resources, target)) return MISSING;
16744
+ const attributes = stack.resources[target]?.attributes;
16745
+ if (attributes === null || typeof attributes !== "object") return MISSING;
16746
+ if (!Object.hasOwn(attributes, attribute)) return MISSING;
16747
+ const value = attributes[attribute];
16748
+ if (typeof value === "string") return [value];
16749
+ if (typeof value === "number" && Number.isFinite(value)) return [String(value)];
16750
+ }
16751
+ const DEFAULT_SUBSTRING_MIN_LENGTH = 4;
16752
+ function parameterDefaultInProperties(template, properties) {
16753
+ const parameters = template["Parameters"];
16754
+ if (parameters === null || typeof parameters !== "object" || Array.isArray(parameters)) return;
16755
+ const needles = /* @__PURE__ */ new Map();
16756
+ for (const [name, decl] of Object.entries(parameters)) {
16757
+ if (decl === null || typeof decl !== "object") continue;
16758
+ const raw = decl["Default"];
16759
+ let text;
16760
+ if (typeof raw === "string") text = raw;
16761
+ else if (typeof raw === "number" && Number.isFinite(raw)) text = String(raw);
16762
+ if (text === void 0 || text === "") continue;
16763
+ if (!needles.has(text)) needles.set(text, name);
16764
+ const type = decl["Type"];
16765
+ if (typeof type === "string" && (type === "CommaDelimitedList" || type.startsWith("List<"))) for (const item of text.split(",")) {
16766
+ const trimmed = item.trim();
16767
+ if (trimmed !== "" && !needles.has(trimmed)) needles.set(trimmed, name);
16768
+ }
16769
+ }
16770
+ if (needles.size === 0) return void 0;
16771
+ const pending = [properties];
16772
+ while (pending.length > 0) {
16773
+ const value = pending.pop();
16774
+ if (typeof value === "string" || typeof value === "number" && Number.isFinite(value)) {
16775
+ const text = String(value);
16776
+ const exact = needles.get(text);
16777
+ if (exact !== void 0) return exact;
16778
+ for (const [needle, name] of needles) if (needle.length >= DEFAULT_SUBSTRING_MIN_LENGTH && text.includes(needle)) return name;
16779
+ } else if (Array.isArray(value)) pending.push(...value);
16780
+ else if (value !== null && typeof value === "object") pending.push(...Object.values(value));
16781
+ }
16782
+ }
16783
+ function acceptRefusedAssertion(logicalId, resourceType, stackRef, legacy) {
16784
+ return `Accepting the refused observed baseline of ${displayIdent(logicalId)} (${displayIdent(resourceType)}) in ${stackRef}. ` + (legacy ? "The refusal was recorded without a reason this cdkd recognizes, and is treated as one over a template parameter whose deployed value cdkd could not prove. " : "cdkd refused it because the resource reads a template parameter whose deployed value it could not prove. ") + "By accepting you assert that this template is deployed, and that AWS holds NO secret at any position of this resource that the template does not spell as a dynamic reference ({{resolve:...}}): whatever AWS holds there now is written to state.json as the drift baseline, in plaintext. A deploy does not resend a value the record already holds, so a literal there need not be what AWS holds.";
16785
+ }
16786
+ async function confirmAcceptRefused(assertion) {
16787
+ return confirmOrRefuse(`${assertion}\nAccept it?`, { refusal: "The cdkd state refresh-observed --accept-refused confirmation prompt cannot run in a non-interactive environment. Pass -y / --yes to make the assertion, or run the command from a real terminal." });
16788
+ }
16789
+
16533
16790
  //#endregion
16534
16791
  //#region src/cli/commands/state.ts
16535
16792
  const STATE_READ_FAILED_REASON = "state record could not be read; run `cdkd state show` for the error";
@@ -17102,7 +17359,7 @@ function treeToShowJson(node) {
17102
17359
  };
17103
17360
  }
17104
17361
  function createStateShowCommand() {
17105
- const cmd = new Command("show").description("Show the full cdkd state record for a stack (metadata, outputs, resources)").argument("<stack>", "Stack name (physical CloudFormation name)").option("--json", "Output the raw state and lock as JSON", false).option("--show-nested", "Recursively show every nested-stack child under the target stack (issue #555 A4)", false).addOption(stackRegionOption$1()).action(withErrorHandling(stateShowCommand));
17362
+ const cmd = new Command("show").description("Show the full cdkd state record for a stack (metadata, outputs, resources)").argument("<stack>", "Stack name (physical CloudFormation name)").option("--json", "Output the raw state and lock as JSON", false).option("--show-nested", "Recursively show every nested-stack child under the target stack", false).addOption(stackRegionOption$1()).action(withErrorHandling(stateShowCommand));
17106
17363
  [...commonOptions, ...stateOptions].forEach((opt) => cmd.addOption(opt));
17107
17364
  cmd.addOption(deprecatedRegionOption);
17108
17365
  return cmd;
@@ -17698,6 +17955,17 @@ async function stateRefreshObservedCommand(stackArgs, options) {
17698
17955
  const providerClasses = await loadProviderClasses();
17699
17956
  const logger = getLogger();
17700
17957
  if (options.verbose) logger.setLevel("debug");
17958
+ let accept;
17959
+ if (options.acceptRefused !== void 0) {
17960
+ if (options.acceptRefused.length !== 1) throw new Error("--accept-refused takes exactly one logical id per run.");
17961
+ if (options.all || stackArgs.length !== 1) throw new Error("--accept-refused applies to one resource of ONE stack: pass a single stack name, not --all.");
17962
+ if (options.template === void 0) throw new Error("--accept-refused requires --template <file>: the synthesized template this stack was last deployed from.");
17963
+ accept = {
17964
+ logicalId: options.acceptRefused[0],
17965
+ template: readAcceptRefusedTemplate(options.template),
17966
+ yes: options.yes ?? false
17967
+ };
17968
+ } else if (options.template !== void 0) throw new Error("--template is used only with --accept-refused.");
17701
17969
  if (!options.all && stackArgs.length === 0) throw new Error(`Stack name is required. Usage: cdkd state refresh-observed ${commandHole("stacks...")} | --all`);
17702
17970
  const setup = await setupStateBackend(options);
17703
17971
  const stackRegionScopes = /* @__PURE__ */ new Map();
@@ -17746,7 +18014,7 @@ async function stateRefreshObservedCommand(stackArgs, options) {
17746
18014
  refuseMalformedState(loaded.state, target.stackName, target.region, lockRecovery);
17747
18015
  refuseMalformedResourceEntries(loaded.state, target.stackName, target.region, lockRecovery);
17748
18016
  }
17749
- if (!options.yes && !options.dryRun) {
18017
+ if (!options.yes && !options.dryRun && accept === void 0) {
17750
18018
  const targetList = targets.map(describedStackRef).join(", ");
17751
18019
  if (targets.some(refIsDescribed)) logger.info(STATE_LIST_POINTER);
17752
18020
  if (!await confirmRefresh(`Refresh observedProperties for ${targets.length} stack(s) (${targetList})?`)) {
@@ -17777,7 +18045,8 @@ async function stateRefreshObservedCommand(stackArgs, options) {
17777
18045
  const counts = await runWithStackAwsClients(scope.clients, () => refreshObservedForStack(target.stackName, targetRegion, setup.stateBackend, setup.lockManager, scope.registry, {
17778
18046
  dryRun: options.dryRun ?? false,
17779
18047
  logger,
17780
- lockRecovery
18048
+ lockRecovery,
18049
+ ...accept && { accept }
17781
18050
  }));
17782
18051
  totalRefreshed += counts.refreshed;
17783
18052
  totalUnsupported += counts.unsupported;
@@ -17820,7 +18089,7 @@ async function warnOnLiveForeignLock(lockManager, stackName, region, logger) {
17820
18089
  } catch {}
17821
18090
  }
17822
18091
  async function refreshObservedForStack(stackName, region, stateBackend, lockManager, providerRegistry, opts) {
17823
- const { logger, lockRecovery } = opts;
18092
+ const { logger, lockRecovery, accept } = opts;
17824
18093
  const ref = formatStackRefSafe({
17825
18094
  stackName,
17826
18095
  region
@@ -17830,7 +18099,33 @@ async function refreshObservedForStack(stackName, region, stateBackend, lockMana
17830
18099
  const { state, etag, migrationPending } = result;
17831
18100
  refuseMalformedState(state, stackName, region, lockRecovery);
17832
18101
  refuseMalformedResourceEntries(state, stackName, region, lockRecovery);
17833
- const entries = Object.entries(state.resources);
18102
+ let entries = Object.entries(state.resources);
18103
+ const acceptId = accept?.logicalId;
18104
+ if (accept !== void 0) {
18105
+ const record = Object.hasOwn(state.resources, accept.logicalId) ? state.resources[accept.logicalId] : void 0;
18106
+ const verdict = judgeAcceptRefused(record, accept.logicalId, accept.template, {
18107
+ stackName,
18108
+ region,
18109
+ resources: state.resources
18110
+ });
18111
+ if (!verdict.ok) throw new Error(safeMsg`${ref}: ${verdict.reason}`);
18112
+ entries = [[accept.logicalId, record]];
18113
+ if (!opts.dryRun) {
18114
+ const assertion = acceptRefusedAssertion(accept.logicalId, record.resourceType, ref, verdict.legacy);
18115
+ if (accept.yes) logger.warn(safeMsg`${assertion} (asserted with --yes)`);
18116
+ else if (!await confirmAcceptRefused(assertion)) {
18117
+ logger.info("Aborted.");
18118
+ return {
18119
+ refreshed: 0,
18120
+ unsupported: 0,
18121
+ failed: 0,
18122
+ notFound: 0,
18123
+ refusedBaseline: 0,
18124
+ refusedSticky: 0
18125
+ };
18126
+ }
18127
+ }
18128
+ }
17834
18129
  if (entries.length === 0) {
17835
18130
  logger.info(safeMsg`✓ ${ref}: no resources in state, skipping`);
17836
18131
  return {
@@ -17847,8 +18142,8 @@ async function refreshObservedForStack(stackName, region, stateBackend, lockMana
17847
18142
  let wouldUnsupported = 0;
17848
18143
  let wouldRefuse = 0;
17849
18144
  let wouldRefuseSticky = 0;
17850
- for (const [, resource] of entries) {
17851
- if (resource.observedBaselineRefused === true) {
18145
+ for (const [logicalId, resource] of entries) {
18146
+ if (resource.observedBaselineRefused === true && logicalId !== acceptId) {
17852
18147
  wouldRefuse++;
17853
18148
  if (refusedBaselineRemedy(resource) !== void 0) wouldRefuseSticky++;
17854
18149
  continue;
@@ -17866,6 +18161,7 @@ async function refreshObservedForStack(stackName, region, stateBackend, lockMana
17866
18161
  if (provider.readCurrentState) wouldRefresh++;
17867
18162
  else wouldUnsupported++;
17868
18163
  }
18164
+ if (accept !== void 0 && wouldRefresh === 0) throw new Error(safeMsg`${ref}: cdkd cannot read ${displayIdent(accept.logicalId)} back from AWS, so no ` + `baseline can be captured and its refusal stands.`);
17869
18165
  logger.info(safeMsg`Plan ${ref}: ${wouldRefresh} resource(s) would be refreshed, ${wouldUnsupported} unsupported` + (wouldRefuse > 0 ? safeMsg`, ${wouldRefuse} refused (import baseline refusal)` : ""));
17870
18166
  return {
17871
18167
  refreshed: wouldRefresh,
@@ -17893,7 +18189,7 @@ async function refreshObservedForStack(stackName, region, stateBackend, lockMana
17893
18189
  const publicSsmProver = new PublicSsmProver(region, () => driftProducerRegionEvidence(state, stackName, region, stateBackend), logger);
17894
18190
  await withStackName(stackName, async () => {
17895
18191
  const tasks = entries.map(async ([logicalId, resource]) => {
17896
- if (resource.observedBaselineRefused === true) {
18192
+ if (resource.observedBaselineRefused === true && logicalId !== acceptId) {
17897
18193
  refusedBaseline++;
17898
18194
  if (refusedBaselineRemedy(resource) !== void 0) refusedSticky++;
17899
18195
  return;
@@ -17928,6 +18224,10 @@ async function refreshObservedForStack(stackName, region, stateBackend, lockMana
17928
18224
  return;
17929
18225
  }
17930
18226
  resource.observedProperties = redactSecretsForState(maskReadbackAtCoordinates(observed, resource.properties ?? {}, [...maskedLeafCoordinatesOf(resource.properties ?? {}), ...noEchoLeavesOf(resource) ?? []]), await publicSsmProver.proofBagFor(resource.properties ?? {}), resource.properties ?? {}, STATE_SOURCED_BASELINE_RULES);
18227
+ if (logicalId === acceptId) {
18228
+ delete resource.observedBaselineRefused;
18229
+ delete resource.observedBaselineRefusalReason;
18230
+ }
17931
18231
  refreshed++;
17932
18232
  } catch (err) {
17933
18233
  failed++;
@@ -17936,12 +18236,24 @@ async function refreshObservedForStack(stackName, region, stateBackend, lockMana
17936
18236
  });
17937
18237
  await Promise.all(tasks);
17938
18238
  });
18239
+ if (accept !== void 0 && refreshed === 0) {
18240
+ if (unsupported > 0) throw new Error(safeMsg`${ref}: cdkd cannot read ${displayIdent(accept.logicalId)} back from AWS, so no ` + `baseline was captured and its refusal stands.`);
18241
+ return {
18242
+ refreshed,
18243
+ unsupported,
18244
+ failed,
18245
+ notFound,
18246
+ refusedBaseline,
18247
+ refusedSticky
18248
+ };
18249
+ }
17939
18250
  state.lastModified = Date.now();
17940
18251
  if (refreshed > 0) delete state.skippedOutputs;
17941
18252
  const saveOptions = { expectedEtag: etag };
17942
18253
  if (migrationPending) saveOptions.migrateLegacy = true;
17943
18254
  await stateBackend.saveState(stackName, region, state, saveOptions);
17944
18255
  logger.info(safeMsg`✓ ${ref}: ` + safeMsg`${refreshed} refreshed, ${unsupported} unsupported, ${failed} failed` + (notFound > 0 ? safeMsg`, ${notFound} not found in AWS` : "") + (refusedBaseline > 0 ? safeMsg`, ${refusedBaseline} refused (import baseline refusal)` : ""));
18256
+ if (accept !== void 0) logger.info(safeMsg`Accepted: the observed-baseline refusal on ${displayIdent(accept.logicalId)} was cleared ` + `and a baseline was captured.`);
17945
18257
  return {
17946
18258
  refreshed,
17947
18259
  unsupported,
@@ -17966,7 +18278,7 @@ async function confirmRefresh(prompt) {
17966
18278
  return confirmOrRefuse(prompt, { refusal: "The cdkd state refresh-observed confirmation prompt cannot run in a non-interactive environment. Pass -y / --yes to confirm the refresh, or run the command from a real terminal." });
17967
18279
  }
17968
18280
  function createStateRefreshObservedCommand() {
17969
- const cmd = new Command("refresh-observed").description("Refresh observedProperties for every resource in a stack by calling provider.readCurrentState — populates the drift baseline for stacks deployed before state schema v3, without redeploying. Run cdkd scrub first on state written by a pre-GHSA binary: the readback is redacted by POSITION against the record, so a record whose own properties still hold plaintext has nothing to redact from.").argument("[stacks...]", "Stack name(s) to refresh (physical CloudFormation names)").option("--all", "Refresh every stack in the state bucket", false).option("--dry-run", "Print the per-stack refresh count without writing state", false).addOption(stackRegionOption$1()).action(withErrorHandling(stateRefreshObservedCommand));
18281
+ const cmd = new Command("refresh-observed").description("Refresh observedProperties for every resource in a stack by calling provider.readCurrentState — populates the drift baseline for stacks deployed before state schema v3, without redeploying. Run cdkd scrub first on state written by a pre-GHSA binary: the readback is redacted by POSITION against the record, so a record whose own properties still hold plaintext has nothing to redact from.").argument("[stacks...]", "Stack name(s) to refresh (physical CloudFormation names)").option("--all", "Refresh every stack in the state bucket", false).option("--dry-run", "Print the per-stack refresh count without writing state", false).option("--accept-refused <logicalId>", "Clear the observed-baseline refusal on ONE resource and capture its baseline, asserting that AWS holds no secret the template does not spell as a dynamic reference. Requires --template and a single stack; prompts unless -y / --yes", collectAcceptRefused).option("--template <file>", "With --accept-refused: the synthesized template (JSON or YAML) this stack was last deployed from").addOption(stackRegionOption$1()).action(withErrorHandling(stateRefreshObservedCommand));
17970
18282
  [...commonOptions, ...stateOptions].forEach((opt) => cmd.addOption(opt));
17971
18283
  cmd.addOption(deprecatedRegionOption);
17972
18284
  return cmd;
@@ -18661,7 +18973,7 @@ async function eventsCommand(stackName, options) {
18661
18973
  async function resolveEventsRegion(reader, stackName, explicitRegion) {
18662
18974
  if (explicitRegion) return canonicalizeRegion(explicitRegion);
18663
18975
  const regions = await reader.listRegions(stackName);
18664
- if (regions.length === 0) throw new CdkdError(`No deployment-event history found for stack ${displayStackName(stackName)}. Events are recorded by cdkd's deploy and destroy commands (issue #808); a stack deployed by an older cdkd version has none.\nIf its history was deleted earlier, the prune subcommand with --all and --stack-region still purges the earlier versions left on a versioned state bucket, unless a warning says otherwise.`, "EVENTS_NOT_FOUND");
18976
+ if (regions.length === 0) throw new CdkdError(`No deployment-event history found for stack ${displayStackName(stackName)}. Events are recorded by cdkd's deploy and destroy commands; a stack deployed by an older cdkd version has none.\nIf its history was deleted earlier, the prune subcommand with --all and --stack-region still purges the earlier versions left on a versioned state bucket, unless a warning says otherwise.`, "EVENTS_NOT_FOUND");
18665
18977
  if (regions.length > 1) {
18666
18978
  const named = regions.filter((r) => isPasteableIdent(r));
18667
18979
  const unnamed = regions.length - named.length;
@@ -18807,7 +19119,7 @@ function colorizeEventType(eventType) {
18807
19119
  return cyan(token);
18808
19120
  }
18809
19121
  function createEventsCommand() {
18810
- const cmd = new Command("events").description("Read back structured deployment events (cdkd's DescribeStackEvents equivalent, issue #808)").argument("<stack>", "Stack name (physical CloudFormation name)").option("--run <runId>", "Read a single run's full event stream instead of the run listing").option("--stack-region <region>", "Disambiguate a stack with event history in multiple regions", parseStackRegion).option("--json", "Output as JSON", false).option("--format <format>", "Output format ('json' is equivalent to --json)").action(withErrorHandling((stack, options) => {
19122
+ const cmd = new Command("events").description("Read back structured deployment events (cdkd's DescribeStackEvents equivalent)").argument("<stack>", "Stack name (physical CloudFormation name)").option("--run <runId>", "Read a single run's full event stream instead of the run listing").option("--stack-region <region>", "Disambiguate a stack with event history in multiple regions", parseStackRegion).option("--json", "Output as JSON", false).option("--format <format>", "Output format ('json' is equivalent to --json)").action(withErrorHandling((stack, options) => {
18811
19123
  return eventsCommand(stack, {
18812
19124
  ...options,
18813
19125
  json: options.json === true || options.format === "json"
@@ -21207,7 +21519,7 @@ function cannotLeaveUnbound(profile) {
21207
21519
  return !(profile || process.env["AWS_PROFILE"]);
21208
21520
  }
21209
21521
  function cfnProviderRefusal(drift) {
21210
- return `--from-cfn-stack cannot run under --role-arn with this cdk-local version: it has ${drift.join(", ")}, so cdkd cannot make it read the stack with your own credentials instead of the role's. Pass --profile <name> (your own profile), or use the cdk-local version this cdkd release ships with (go-to-k/cdkd#3240).`;
21522
+ return `--from-cfn-stack cannot run under --role-arn with this cdk-local version: it has ${drift.join(", ")}, so cdkd cannot make it read the stack with your own credentials instead of the role's. Pass --profile <name> (your own profile), or use the cdk-local version this cdkd release ships with.`;
21211
21523
  }
21212
21524
  const CFN_PROVIDER_CLIENT_GETTERS = [
21213
21525
  "getClient",
@@ -21357,7 +21669,7 @@ function engineRoleExposureWarning(commandName, channels, fromCfnStackChannel, i
21357
21669
  const envProfileSet = !!input.envProfile;
21358
21670
  const open = envProfileSet ? all.filter((c) => c.flagOnly) : all;
21359
21671
  if (open.length === 0) return void 0;
21360
- return `cdkd local ${commandName}: --role-arn ${envProfileSet ? "is set, and the exported AWS_PROFILE does not cover what follows (only the --profile flag does)" : "is set and no profile is selected"}, so the local emulation engine resolves these AS THE ROLE and hands them to your local code: ${open.map((c) => c.what).join("; ")}. Pass --profile <name> with your own profile to keep them on your identity, or do not pass a role whose permissions you would not give the code in the container. Tracked as go-to-k/cdkd#3240 (upstream go-to-k/cdk-local#783).`;
21672
+ return `cdkd local ${commandName}: --role-arn ${envProfileSet ? "is set, and the exported AWS_PROFILE does not cover what follows (only the --profile flag does)" : "is set and no profile is selected"}, so the local emulation engine resolves these AS THE ROLE and hands them to your local code: ${open.map((c) => c.what).join("; ")}. Pass --profile <name> with your own profile to keep them on your identity, or do not pass a role whose permissions you would not give the code in the container.`;
21361
21673
  }
21362
21674
 
21363
21675
  //#endregion
@@ -24949,7 +25261,7 @@ function resolveMtlsConfig(options) {
24949
25261
  });
24950
25262
  }
24951
25263
  function createLocalStartApiCommand() {
24952
- const startApi = new Command("start-api").description("Run a long-running local HTTP server that maps API Gateway routes (REST v1, HTTP API, Function URL) to Lambda invocations against the AWS Lambda Runtime Interface Emulator (Docker required). Supports Lambda TOKEN/REQUEST authorizers, Cognito User Pool / HTTP v2 JWT authorizers, and AWS_IAM auth (REST v1 `AuthorizationType: AWS_IAM` and Function URL `AuthType: AWS_IAM` — SigV4 signature verification only; IAM policy evaluation is NOT emulated; see https://cdkd.dev/local-start-api/#aws-iam-authorization). When JWKS is unreachable, JWT authorizers fall back to pass-through (every token accepted) with a warn line — local dev fallback. VPC-config Lambdas run locally and surface a warn line at startup; their containers do NOT get attached to the deployed VPC subnets, so calls to private RDS / ElastiCache will fail.").argument("[target]", "Optional API filter. Accepts the bare CDK logical id ('MyHttpApi'; single-stack apps only), stack-qualified logical id ('MyStack:MyHttpApi'), full CDK Construct path ('MyStack/MyHttpApi/Resource'), or an ancestor Construct path that prefix-matches ('MyStack/MyHttpApi'). When omitted, every discovered API gets its own server. Mirrors `cdkd local invoke` / `cdkd local run-task` target syntax.").addOption(new Option("--port <port>", "HTTP server port (default: auto-allocate)").default("0")).addOption(new Option("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option("--stack <name>", "Stack to start (single-stack apps auto-detect)")).addOption(new Option("--warm", "Pre-start one container per Lambda at server boot").default(false)).addOption(new Option("--per-lambda-concurrency <n>", "Pool size cap per Lambda (default 2, max 4)").default("2")).addOption(new Option("--no-pull", "Skip docker pull (cached image)")).addOption(new Option("--container-host <host>", "IP the host uses to bind/probe the RIE port (must be a numeric IP — `docker run -p <ip>:<port>:8080` rejects hostnames). Defaults to 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--debug-port-base <port>", "Reserve a contiguous --debug-port range (one per Lambda)")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--assume-role <arn-or-pair>", "Assume the Lambda's execution role and forward STS-issued temp creds. Two forms: (1) `--assume-role <arn>` sets a single global default ARN used for every routed Lambda; (2) `--assume-role <LogicalId>=<arn>` (repeatable) is a per-Lambda override (wins over the global default and over --assume-role-auto for the named Lambda). Pair with --assume-role-auto to auto-resolve every other Lambda. Precedence: per-Lambda > (--assume-role-auto OR global default) > unset (developer creds passed through).").argParser((raw, prev) => parseAssumeRoleToken(raw, prev))).addOption(new Option("--assume-role-auto", "Auto-resolve EACH routed Lambda's own execution role per-Lambda (literal ARN / Fn::GetAtt against template / --from-cfn-stack state). Slower boot — one STS call per Lambda — but the right shape when each Lambda's deployed role differs. Mutually exclusive with `--assume-role <arn>` (global default); errors at boot. Compatible with `--assume-role <LogicalId>=<arn>` per-Lambda overrides — the map wins for named Lambdas, auto-resolve handles the rest.").default(false)).addOption(new Option("--watch", "Hot-reload: watch the CDK app source tree and re-synth + re-discover routes on a source edit (cdk.out / node_modules / .git excluded; honors cdk.json watch.include / watch.exclude). Off by default; the server keeps the previous version serving when synth fails mid-reload.").default(false)).addOption(new Option("--stage <name>", "Select an API Gateway Stage by its 'StageName'. Default: the first Stage attached to each API. Drives BOTH event.stageVariables and requestContext.stage, for REST v1 and HTTP API v2 alike: when a route's API has a matching templated Stage, the selected StageName is threaded into requestContext.stage. An HTTP API v2 route reports '$default' only when its API carries no AWS::ApiGatewayV2::Stage in the template — that is v2's auto-deployed stage, not a limit on what this flag can select (AWS's CreateStage accepts named stages on v2 too). An API with no Stage matching the selected name is warned about at start-up and its routes get stageVariables: null.")).addOption(new Option("--api <id>", "DEPRECATED — use the positional <target> argument instead. Same accepted forms (bare logical id, stack-qualified, Construct path, ancestor prefix). Will be removed in a future major release.")).addOption(new Option("--layer-role-arn <arn>", "Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN entry in Properties.Layers (issue #448). Use only when the dev credentials cannot read the layer — typically cross-account layers. AWS-published public layers (e.g. Lambda Powertools) are readable from every account and need no role.")).addOption(new Option("--from-state", "Read cdkd S3 state for every routed stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::Join (and AWS pseudo parameters) in Lambda env vars with the deployed physical IDs / attributes. Off by default — pre-PR warn-and-drop semantics are preserved. Turn on for stacks already deployed via cdkd deploy. Mirrors `cdkd local invoke --from-state` / `cdkd local run-task --from-state`. Re-runs against fresh state on every hot-reload firing (--watch).").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in Lambda env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the cdkd stack name per routed stack; pass an explicit value when a single CFn stack should serve every routed stack. Mutually exclusive with --from-state. Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-state when the same stack name has state in multiple regions, and with --from-cfn-stack as the CFn client region (cdkd does not have a separate --cfn-stack-region flag).").argParser(parseStackRegion)).addOption(new Option("--mtls-truststore <path>", "PEM-encoded CA bundle for client-certificate verification (mutual TLS). When set, the local server switches from HTTP to HTTPS and the TLS handshake rejects clients whose certificate doesn't chain to one of these CAs. Verified certs are surfaced on the Lambda event under requestContext.identity.clientCert (REST v1) / requestContext.authentication.clientCert (HTTP API v2). Must be set together with --mtls-cert + --mtls-key; partial flag sets are rejected. Generate a CA + server + client cert for local dev: openssl req -x509 -newkey rsa:2048 -nodes -keyout ca-key.pem -out ca.pem -subj \"/CN=cdkd-local-ca\" -days 365; openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-csr.pem -subj \"/CN=localhost\"; openssl x509 -req -in server-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 365; openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-csr.pem -subj \"/CN=client\"; openssl x509 -req -in client-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 365; curl --cacert ca.pem --cert client-cert.pem --key client-key.pem https://localhost:<port>/...")).addOption(new Option("--mtls-cert <path>", "PEM-encoded server certificate for mutual TLS. Self-signed is fine for local dev. Must be set together with --mtls-truststore + --mtls-key.")).addOption(new Option("--mtls-key <path>", "PEM-encoded server private key matching --mtls-cert. Must be set together with --mtls-truststore + --mtls-cert.")).addOption(new Option("--strict-sigv4", "Opt-in: enforce strict AWS_IAM SigV4 verification. When set, requests whose signature cannot be cryptographically verified (foreign access-key-id, OR no local AWS credentials configured) are denied. DEFAULT off — warn-and-pass with a placeholder principalId, matching cdk-local's `cdkl start-api`. Enable this when you want local parity with the deployed API Gateway's signature enforcement.").default(false)).action(withErrorHandling(localStartApiCommand));
25264
+ const startApi = new Command("start-api").description("Run a long-running local HTTP server that maps API Gateway routes (REST v1, HTTP API, Function URL) to Lambda invocations against the AWS Lambda Runtime Interface Emulator (Docker required). Supports Lambda TOKEN/REQUEST authorizers, Cognito User Pool / HTTP v2 JWT authorizers, and AWS_IAM auth (REST v1 `AuthorizationType: AWS_IAM` and Function URL `AuthType: AWS_IAM` — SigV4 signature verification only; IAM policy evaluation is NOT emulated; see https://cdkd.dev/local-start-api/#aws-iam-authorization). When JWKS is unreachable, JWT authorizers fall back to pass-through (every token accepted) with a warn line — local dev fallback. VPC-config Lambdas run locally and surface a warn line at startup; their containers do NOT get attached to the deployed VPC subnets, so calls to private RDS / ElastiCache will fail.").argument("[target]", "Optional API filter. Accepts the bare CDK logical id ('MyHttpApi'; single-stack apps only), stack-qualified logical id ('MyStack:MyHttpApi'), full CDK Construct path ('MyStack/MyHttpApi/Resource'), or an ancestor Construct path that prefix-matches ('MyStack/MyHttpApi'). When omitted, every discovered API gets its own server. Mirrors `cdkd local invoke` / `cdkd local run-task` target syntax.").addOption(new Option("--port <port>", "HTTP server port (default: auto-allocate)").default("0")).addOption(new Option("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option("--stack <name>", "Stack to start (single-stack apps auto-detect)")).addOption(new Option("--warm", "Pre-start one container per Lambda at server boot").default(false)).addOption(new Option("--per-lambda-concurrency <n>", "Pool size cap per Lambda (default 2, max 4)").default("2")).addOption(new Option("--no-pull", "Skip docker pull (cached image)")).addOption(new Option("--container-host <host>", "IP the host uses to bind/probe the RIE port (must be a numeric IP — `docker run -p <ip>:<port>:8080` rejects hostnames). Defaults to 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--debug-port-base <port>", "Reserve a contiguous --debug-port range (one per Lambda)")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--assume-role <arn-or-pair>", "Assume the Lambda's execution role and forward STS-issued temp creds. Two forms: (1) `--assume-role <arn>` sets a single global default ARN used for every routed Lambda; (2) `--assume-role <LogicalId>=<arn>` (repeatable) is a per-Lambda override (wins over the global default and over --assume-role-auto for the named Lambda). Pair with --assume-role-auto to auto-resolve every other Lambda. Precedence: per-Lambda > (--assume-role-auto OR global default) > unset (developer creds passed through).").argParser((raw, prev) => parseAssumeRoleToken(raw, prev))).addOption(new Option("--assume-role-auto", "Auto-resolve EACH routed Lambda's own execution role per-Lambda (literal ARN / Fn::GetAtt against template / --from-cfn-stack state). Slower boot — one STS call per Lambda — but the right shape when each Lambda's deployed role differs. Mutually exclusive with `--assume-role <arn>` (global default); errors at boot. Compatible with `--assume-role <LogicalId>=<arn>` per-Lambda overrides — the map wins for named Lambdas, auto-resolve handles the rest.").default(false)).addOption(new Option("--watch", "Hot-reload: watch the CDK app source tree and re-synth + re-discover routes on a source edit (cdk.out / node_modules / .git excluded; honors cdk.json watch.include / watch.exclude). Off by default; the server keeps the previous version serving when synth fails mid-reload.").default(false)).addOption(new Option("--stage <name>", "Select an API Gateway Stage by its 'StageName'. Default: the first Stage attached to each API. Drives BOTH event.stageVariables and requestContext.stage, for REST v1 and HTTP API v2 alike: when a route's API has a matching templated Stage, the selected StageName is threaded into requestContext.stage. An HTTP API v2 route reports '$default' only when its API carries no AWS::ApiGatewayV2::Stage in the template — that is v2's auto-deployed stage, not a limit on what this flag can select (AWS's CreateStage accepts named stages on v2 too). An API with no Stage matching the selected name is warned about at start-up and its routes get stageVariables: null.")).addOption(new Option("--api <id>", "DEPRECATED — use the positional <target> argument instead. Same accepted forms (bare logical id, stack-qualified, Construct path, ancestor prefix). Will be removed in a future major release.")).addOption(new Option("--layer-role-arn <arn>", "Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN entry in Properties.Layers. Use only when the dev credentials cannot read the layer — typically cross-account layers. AWS-published public layers (e.g. Lambda Powertools) are readable from every account and need no role.")).addOption(new Option("--from-state", "Read cdkd S3 state for every routed stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::Join (and AWS pseudo parameters) in Lambda env vars with the deployed physical IDs / attributes. Off by default — pre-PR warn-and-drop semantics are preserved. Turn on for stacks already deployed via cdkd deploy. Mirrors `cdkd local invoke --from-state` / `cdkd local run-task --from-state`. Re-runs against fresh state on every hot-reload firing (--watch).").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in Lambda env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the cdkd stack name per routed stack; pass an explicit value when a single CFn stack should serve every routed stack. Mutually exclusive with --from-state. Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-state when the same stack name has state in multiple regions, and with --from-cfn-stack as the CFn client region (cdkd does not have a separate --cfn-stack-region flag).").argParser(parseStackRegion)).addOption(new Option("--mtls-truststore <path>", "PEM-encoded CA bundle for client-certificate verification (mutual TLS). When set, the local server switches from HTTP to HTTPS and the TLS handshake rejects clients whose certificate doesn't chain to one of these CAs. Verified certs are surfaced on the Lambda event under requestContext.identity.clientCert (REST v1) / requestContext.authentication.clientCert (HTTP API v2). Must be set together with --mtls-cert + --mtls-key; partial flag sets are rejected. Generate a CA + server + client cert for local dev: openssl req -x509 -newkey rsa:2048 -nodes -keyout ca-key.pem -out ca.pem -subj \"/CN=cdkd-local-ca\" -days 365; openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-csr.pem -subj \"/CN=localhost\"; openssl x509 -req -in server-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 365; openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-csr.pem -subj \"/CN=client\"; openssl x509 -req -in client-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 365; curl --cacert ca.pem --cert client-cert.pem --key client-key.pem https://localhost:<port>/...")).addOption(new Option("--mtls-cert <path>", "PEM-encoded server certificate for mutual TLS. Self-signed is fine for local dev. Must be set together with --mtls-truststore + --mtls-key.")).addOption(new Option("--mtls-key <path>", "PEM-encoded server private key matching --mtls-cert. Must be set together with --mtls-truststore + --mtls-cert.")).addOption(new Option("--strict-sigv4", "Opt-in: enforce strict AWS_IAM SigV4 verification. When set, requests whose signature cannot be cryptographically verified (foreign access-key-id, OR no local AWS credentials configured) are denied. DEFAULT off — warn-and-pass with a placeholder principalId, matching cdk-local's `cdkl start-api`. Enable this when you want local parity with the deployed API Gateway's signature enforcement.").default(false)).action(withErrorHandling(localStartApiCommand));
24953
25265
  [
24954
25266
  ...commonOptions,
24955
25267
  ...appOptions,
@@ -26235,7 +26547,7 @@ function buildRunEcsTaskOptions(options, channels, extra = {}) {
26235
26547
  return runOpts;
26236
26548
  }
26237
26549
  function createLocalRunTaskCommand() {
26238
- const cmd = new Command("run-task").description("Run an AWS::ECS::TaskDefinition locally — pulls/builds images, sets up a per-task docker network with the AWS-published metadata-endpoints sidecar, and starts every container in dependsOn order. Target accepts a CDK display path (MyStack/MyService/TaskDef) or stack-qualified logical ID (MyStack:MyServiceTaskDefXYZ1234). Single-stack apps may omit the stack prefix.").argument("<target>", "CDK display path or stack-qualified logical ID of the AWS::ECS::TaskDefinition to run").addOption(new Option("--cluster <name>", "Cluster name surfaced to ECS_CONTAINER_METADATA_URI_V4 and used as the docker network prefix").default("cdkd-local")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"ContainerName\":{\"KEY\":\"VALUE\"}, \"Parameters\":{}})")).addOption(new Option("--container-host <ip>", "Host IP to bind published container ports to. Must be a numeric IP (Docker rejects hostnames here)").default("127.0.0.1")).addOption(new Option("--assume-task-role [arn]", "Assume the task definition's TaskRoleArn (or the supplied ARN) and forward STS-issued temp credentials via the metadata sidecar so containers run with the deployed function role. Bare flag uses the template's TaskRoleArn; pass an explicit ARN to override.")).addOption(new Option("--no-pull", "Skip docker pull for every container image and the metadata sidecar")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries (#455). Issues sts:AssumeRole via the default credential chain and uses the temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the caller does not have direct cross-account access to the target repository. A same-account pull in ANY region does not need this flag: the ECR client is built for the image URI's own region, so crossing a region costs nothing extra (issue #2536).")).addOption(new Option("--platform <platform>", "Force docker --platform (linux/amd64 or linux/arm64). Default: inferred from task RuntimePlatform.CpuArchitecture")).addOption(new Option("--keep-running", "Don't docker rm -f the user containers on task exit (network + sidecar are still torn down). Use when you want to docker exec into a stopped container for post-mortems.").default(false)).addOption(new Option("--detach", "Start the containers in the background and exit (skip log streaming + auto teardown). Useful in CI smoke tests; caller manages container lifecycle.").default(false)).addOption(new Option("--from-state", "Read cdkd S3 state for the target stack and substitute Fn::Sub / Fn::GetAtt references to same-stack AWS::ECR::Repository resources with the deployed URI. Off by default — only the AWS pseudo-parameter tier (${AWS::AccountId} / ${AWS::Region}) is resolved without this flag.").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in container env vars / secrets / image URIs with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the cdkd stack name; pass an explicit value when the CFn stack name differs. Mutually exclusive with --from-state. Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-state when the same stack name has state in multiple regions, and with --from-cfn-stack as the CFn client region (cdkd does not have a separate --cfn-stack-region flag).").argParser(parseStackRegion)).action(withErrorHandling(localRunTaskCommand));
26550
+ const cmd = new Command("run-task").description("Run an AWS::ECS::TaskDefinition locally — pulls/builds images, sets up a per-task docker network with the AWS-published metadata-endpoints sidecar, and starts every container in dependsOn order. Target accepts a CDK display path (MyStack/MyService/TaskDef) or stack-qualified logical ID (MyStack:MyServiceTaskDefXYZ1234). Single-stack apps may omit the stack prefix.").argument("<target>", "CDK display path or stack-qualified logical ID of the AWS::ECS::TaskDefinition to run").addOption(new Option("--cluster <name>", "Cluster name surfaced to ECS_CONTAINER_METADATA_URI_V4 and used as the docker network prefix").default("cdkd-local")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"ContainerName\":{\"KEY\":\"VALUE\"}, \"Parameters\":{}})")).addOption(new Option("--container-host <ip>", "Host IP to bind published container ports to. Must be a numeric IP (Docker rejects hostnames here)").default("127.0.0.1")).addOption(new Option("--assume-task-role [arn]", "Assume the task definition's TaskRoleArn (or the supplied ARN) and forward STS-issued temp credentials via the metadata sidecar so containers run with the deployed function role. Bare flag uses the template's TaskRoleArn; pass an explicit ARN to override.")).addOption(new Option("--no-pull", "Skip docker pull for every container image and the metadata sidecar")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries. Issues sts:AssumeRole via the default credential chain and uses the temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the caller does not have direct cross-account access to the target repository. A same-account pull in ANY region does not need this flag: the ECR client is built for the image URI's own region, so crossing a region costs nothing extra.")).addOption(new Option("--platform <platform>", "Force docker --platform (linux/amd64 or linux/arm64). Default: inferred from task RuntimePlatform.CpuArchitecture")).addOption(new Option("--keep-running", "Don't docker rm -f the user containers on task exit (network + sidecar are still torn down). Use when you want to docker exec into a stopped container for post-mortems.").default(false)).addOption(new Option("--detach", "Start the containers in the background and exit (skip log streaming + auto teardown). Useful in CI smoke tests; caller manages container lifecycle.").default(false)).addOption(new Option("--from-state", "Read cdkd S3 state for the target stack and substitute Fn::Sub / Fn::GetAtt references to same-stack AWS::ECR::Repository resources with the deployed URI. Off by default — only the AWS pseudo-parameter tier (${AWS::AccountId} / ${AWS::Region}) is resolved without this flag.").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in container env vars / secrets / image URIs with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the cdkd stack name; pass an explicit value when the CFn stack name differs. Mutually exclusive with --from-state. Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-state when the same stack name has state in multiple regions, and with --from-cfn-stack as the CFn client region (cdkd does not have a separate --cfn-stack-region flag).").argParser(parseStackRegion)).action(withErrorHandling(localRunTaskCommand));
26239
26551
  [
26240
26552
  ...commonOptions,
26241
26553
  ...appOptions,
@@ -26263,7 +26575,7 @@ function serviceStrategy() {
26263
26575
  };
26264
26576
  }
26265
26577
  function createLocalStartServiceCommand() {
26266
- const cmd = new Command("start-service").description("Run one or more AWS::ECS::Service resources locally as a long-running emulator. Spins up DesiredCount task replicas per service (clamped by --max-tasks) using the same per-task docker network + metadata sidecar pattern as `cdkd local run-task`, then keeps each replica running and restarts it on exit per --restart-policy. ^C tears every replica + sidecar + network down. Each <target> accepts a CDK display path (MyStack/MyService) or stack-qualified logical ID (MyStack:MyServiceXYZ); single-stack apps may omit the stack prefix. When two or more <target>s are supplied, every service is booted into a shared Cloud Map / Service Connect registry so peer services discover each other via docker --add-host overlay (Issue #460). Omit <targets> in an interactive terminal to multi-select the ECS services from a list.").argument("[targets...]", "One or more CDK display paths or stack-qualified logical IDs of the AWS::ECS::Service resources to run (omit to multi-select interactively in a TTY)").addOption(new Option("--from-state", "Read cdkd's S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::ImportValue / Fn::GetStackOutput intrinsics in container images, environment variables, secrets, role ARNs, and volumes. Mutually exclusive with --from-cfn-stack.").default(false)).addOption(new Option("--state-bucket <bucket>", "S3 bucket for --from-state. Falls back to CDKD_STATE_BUCKET env or cdk.json context.cdkd.stateBucket.")).addOption(new Option("--state-prefix <prefix>", "S3 key prefix for --from-state state files.").default("cdkd")).action(withErrorHandling(async (targets, options) => {
26578
+ const cmd = new Command("start-service").description("Run one or more AWS::ECS::Service resources locally as a long-running emulator. Spins up DesiredCount task replicas per service (clamped by --max-tasks) using the same per-task docker network + metadata sidecar pattern as `cdkd local run-task`, then keeps each replica running and restarts it on exit per --restart-policy. ^C tears every replica + sidecar + network down. Each <target> accepts a CDK display path (MyStack/MyService) or stack-qualified logical ID (MyStack:MyServiceXYZ); single-stack apps may omit the stack prefix. When two or more <target>s are supplied, every service is booted into a shared Cloud Map / Service Connect registry so peer services discover each other via docker --add-host overlay. Omit <targets> in an interactive terminal to multi-select the ECS services from a list.").argument("[targets...]", "One or more CDK display paths or stack-qualified logical IDs of the AWS::ECS::Service resources to run (omit to multi-select interactively in a TTY)").addOption(new Option("--from-state", "Read cdkd's S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::ImportValue / Fn::GetStackOutput intrinsics in container images, environment variables, secrets, role ARNs, and volumes. Mutually exclusive with --from-cfn-stack.").default(false)).addOption(new Option("--state-bucket <bucket>", "S3 bucket for --from-state. Falls back to CDKD_STATE_BUCKET env or cdk.json context.cdkd.stateBucket.")).addOption(new Option("--state-prefix <prefix>", "S3 key prefix for --from-state state files.").default("cdkd")).action(withErrorHandling(async (targets, options) => {
26267
26579
  await runEcsServiceEmulator(targets, options, serviceStrategy(), cdkdExtraStateProviders);
26268
26580
  }));
26269
26581
  addStartServiceSpecificOptions(cmd);
@@ -27451,7 +27763,7 @@ function readEnvOverridesFile$1(filePath) {
27451
27763
  return parsed;
27452
27764
  }
27453
27765
  function createLocalInvokeAgentCoreCommand() {
27454
- const cmd = new Command("invoke-agentcore").description("Run a Bedrock AgentCore Runtime container locally and invoke it once over its protocol contract: HTTP (POST /invocations + GET /ping on 8080) or MCP (POST /mcp Streamable HTTP on 8000). Resolves the AWS::BedrockAgentCore::Runtime, pulls/builds its container, injects env vars + AWS credentials, and prints the response. For an MCP runtime, runs the session handshake then sends one JSON-RPC request (tools/list by default, or the method/params from --event). Target accepts a CDK display path (MyStack/MyAgent) or stack-qualified logical ID (MyStack:MyAgentRuntime1234). Single-stack apps may omit the stack prefix. Omit <target> in an interactive terminal to pick from a list. Supports the container artifact and the CodeConfiguration managed-runtime artifact (fromCodeAsset, built from source) on the HTTP + MCP protocols; the agent calls real AWS for managed services.").argument("[target]", "CDK display path or stack-qualified logical ID of the AgentCore Runtime to invoke (omit to pick interactively in a TTY)").addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}})")).addOption(new Option("--session-id <id>", "AgentCore runtime session id header value (default: a random UUID)")).addOption(new Option("--ws", "Stream over the HTTP-protocol agent's bidirectional /ws WebSocket endpoint (on 8080) instead of POST /invocations: send --event as the first frame and print every received frame to stdout until the agent closes. When stdin is a TTY, auto-enters a REPL — each typed line is sent as a follow-up text frame until Ctrl-D / agent close; pipe from /dev/null to force one-shot in a TTY. Ignored for an MCP runtime.").default(false)).addOption(new Option("--watch", "Re-synth and reload the agent container on CDK source changes (follows cdk-local #270). Supported on the HTTP / AGUI protocols, both the --ws session AND the default one-shot POST /invocations (the reload re-runs the single shot). An interpreted-language source edit inside a CodeConfiguration source tree takes a soft-reload fast path (docker cp + docker restart, no rebuild); Dockerfile / compiled-source / asset-hash-changed / ambiguous edits force a full rebuild. For MCP / A2A runtimes --watch is a no-op WARN and the single shot proceeds.").default(false)).addOption(new Option("--bearer-token <jwt>", "Bearer JWT to present when the runtime declares a customJwtAuthorizer. Verified against the runtime OIDC discovery URL (signature / issuer / expiry / audience) before the container starts, then forwarded to /invocations as Authorization: Bearer <jwt>.")).addOption(new Option("--no-verify-auth", "Skip inbound JWT verification even when the runtime declares a customJwtAuthorizer (local-dev escape hatch). A --bearer-token, if given, is still forwarded.")).addOption(new Option("--sigv4", "Sign the /invocations POST with AWS SigV4 (service bedrock-agentcore) using the resolved credentials, matching the cloud default when the runtime declares no customJwtAuthorizer. Opt-in: default unsigned. Mutually exclusive with --bearer-token; ignored on a JWT-protected runtime.").default(false)).addOption(new Option("--platform <platform>", "docker --platform for the agent container (linux/amd64 or linux/arm64)").choices(["linux/amd64", "linux/arm64"]).default("linux/arm64")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for the local-build path")).addOption(new Option("--no-build", "Skip docker build on the local-asset path (use the previously-built tag). No-op for the ECR / registry pull paths.")).addOption(new Option("--container-host <host>", "Host to bind the agent port to").default("127.0.0.1")).addOption(new Option("--timeout <ms>", "Per-request timeout in milliseconds. Applied to POST /invocations, POST /mcp, and the /ws open-to-close window. Raise this for long-running agent calls that exceed the default.").default(12e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role [arn]", "Assume the runtime's execution role and forward STS-issued temp credentials to the container so the agent runs with the deployed role. Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) uses the runtime's RoleArn when it is a literal ARN; (3) `--no-assume-role` opts out. Off by default — the developer's shell credentials are forwarded unchanged.")).addOption(new Option("--no-assume-role", "Explicitly opt out of assuming the runtime's execution role: forward your ambient AWS credentials (or the --profile overlay) unchanged even when --from-state / --from-cfn-stack is set.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries. A same-account pull in ANY region does not need this flag: the ECR client is built for the image URI's own region, so crossing a region costs nothing extra (issue #2536).")).addOption(new Option("--from-state", "Load cdkd's S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::ImportValue in env vars with the deployed physical IDs / cross-stack exports. Mutually exclusive with --from-cfn-stack.").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. For CDK apps deployed via the upstream CDK CLI. Bare form uses the resolved stack name; pass an explicit value when the CFn stack name differs. Mutually exclusive with --from-state.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.").argParser(parseStackRegion)).action(withErrorHandling(async (target, options) => {
27766
+ const cmd = new Command("invoke-agentcore").description("Run a Bedrock AgentCore Runtime container locally and invoke it once over its protocol contract: HTTP (POST /invocations + GET /ping on 8080) or MCP (POST /mcp Streamable HTTP on 8000). Resolves the AWS::BedrockAgentCore::Runtime, pulls/builds its container, injects env vars + AWS credentials, and prints the response. For an MCP runtime, runs the session handshake then sends one JSON-RPC request (tools/list by default, or the method/params from --event). Target accepts a CDK display path (MyStack/MyAgent) or stack-qualified logical ID (MyStack:MyAgentRuntime1234). Single-stack apps may omit the stack prefix. Omit <target> in an interactive terminal to pick from a list. Supports the container artifact and the CodeConfiguration managed-runtime artifact (fromCodeAsset, built from source) on the HTTP + MCP protocols; the agent calls real AWS for managed services.").argument("[target]", "CDK display path or stack-qualified logical ID of the AgentCore Runtime to invoke (omit to pick interactively in a TTY)").addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}})")).addOption(new Option("--session-id <id>", "AgentCore runtime session id header value (default: a random UUID)")).addOption(new Option("--ws", "Stream over the HTTP-protocol agent's bidirectional /ws WebSocket endpoint (on 8080) instead of POST /invocations: send --event as the first frame and print every received frame to stdout until the agent closes. When stdin is a TTY, auto-enters a REPL — each typed line is sent as a follow-up text frame until Ctrl-D / agent close; pipe from /dev/null to force one-shot in a TTY. Ignored for an MCP runtime.").default(false)).addOption(new Option("--watch", "Re-synth and reload the agent container on CDK source changes. Supported on the HTTP / AGUI protocols, both the --ws session AND the default one-shot POST /invocations (the reload re-runs the single shot). An interpreted-language source edit inside a CodeConfiguration source tree takes a soft-reload fast path (docker cp + docker restart, no rebuild); Dockerfile / compiled-source / asset-hash-changed / ambiguous edits force a full rebuild. For MCP / A2A runtimes --watch is a no-op WARN and the single shot proceeds.").default(false)).addOption(new Option("--bearer-token <jwt>", "Bearer JWT to present when the runtime declares a customJwtAuthorizer. Verified against the runtime OIDC discovery URL (signature / issuer / expiry / audience) before the container starts, then forwarded to /invocations as Authorization: Bearer <jwt>.")).addOption(new Option("--no-verify-auth", "Skip inbound JWT verification even when the runtime declares a customJwtAuthorizer (local-dev escape hatch). A --bearer-token, if given, is still forwarded.")).addOption(new Option("--sigv4", "Sign the /invocations POST with AWS SigV4 (service bedrock-agentcore) using the resolved credentials, matching the cloud default when the runtime declares no customJwtAuthorizer. Opt-in: default unsigned. Mutually exclusive with --bearer-token; ignored on a JWT-protected runtime.").default(false)).addOption(new Option("--platform <platform>", "docker --platform for the agent container (linux/amd64 or linux/arm64)").choices(["linux/amd64", "linux/arm64"]).default("linux/arm64")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for the local-build path")).addOption(new Option("--no-build", "Skip docker build on the local-asset path (use the previously-built tag). No-op for the ECR / registry pull paths.")).addOption(new Option("--container-host <host>", "Host to bind the agent port to").default("127.0.0.1")).addOption(new Option("--timeout <ms>", "Per-request timeout in milliseconds. Applied to POST /invocations, POST /mcp, and the /ws open-to-close window. Raise this for long-running agent calls that exceed the default.").default(12e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role [arn]", "Assume the runtime's execution role and forward STS-issued temp credentials to the container so the agent runs with the deployed role. Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) uses the runtime's RoleArn when it is a literal ARN; (3) `--no-assume-role` opts out. Off by default — the developer's shell credentials are forwarded unchanged.")).addOption(new Option("--no-assume-role", "Explicitly opt out of assuming the runtime's execution role: forward your ambient AWS credentials (or the --profile overlay) unchanged even when --from-state / --from-cfn-stack is set.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries. A same-account pull in ANY region does not need this flag: the ECR client is built for the image URI's own region, so crossing a region costs nothing extra.")).addOption(new Option("--from-state", "Load cdkd's S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::ImportValue in env vars with the deployed physical IDs / cross-stack exports. Mutually exclusive with --from-cfn-stack.").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. For CDK apps deployed via the upstream CDK CLI. Bare form uses the resolved stack name; pass an explicit value when the CFn stack name differs. Mutually exclusive with --from-state.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.").argParser(parseStackRegion)).action(withErrorHandling(async (target, options) => {
27455
27767
  await localInvokeAgentCoreCommand(target, options);
27456
27768
  }));
27457
27769
  [
@@ -27509,7 +27821,7 @@ function warnUnresolvedLambdaTargetEnv(strategy, options) {
27509
27821
  const ecsNote = resolved.boots.length > 0 ? "The ECS service targets behind this ALB DO honor --from-state. " : "";
27510
27822
  return {
27511
27823
  ...resolved,
27512
- warnings: [...resolved.warnings, `--from-state does not reach the container environment of this ALB's Lambda target group(s): ${lambdaIds.map((id) => plainOrDescribed(id, "logical id")).join(", ")}. Their Environment.Variables keep any Ref / Fn::GetAtt / Fn::Sub / Fn::ImportValue intrinsics unresolved, and each is then dropped with its own warning. ` + ecsNote + "The only state source the Lambda path reads is --from-cfn-stack '<name>', which REPLACES --from-state (the two are mutually exclusive) and reaches both target kinds on a CloudFormation-deployed stack; otherwise override the affected variables with --env-vars. Tracked as go-to-k/cdkd#2602 (upstream go-to-k/cdk-local#707)."]
27824
+ warnings: [...resolved.warnings, `--from-state does not reach the container environment of this ALB's Lambda target group(s): ${lambdaIds.map((id) => plainOrDescribed(id, "logical id")).join(", ")}. Their Environment.Variables keep any Ref / Fn::GetAtt / Fn::Sub / Fn::ImportValue intrinsics unresolved, and each is then dropped with its own warning. ` + ecsNote + "The only state source the Lambda path reads is --from-cfn-stack '<name>', which REPLACES --from-state (the two are mutually exclusive) and reaches both target kinds on a CloudFormation-deployed stack; otherwise override the affected variables with --env-vars."]
27513
27825
  };
27514
27826
  }
27515
27827
  };
@@ -27518,7 +27830,7 @@ function buildAlbEmulatorStrategy(options) {
27518
27830
  return warnUnresolvedLambdaTargetEnv(albStrategy(options), options);
27519
27831
  }
27520
27832
  function createLocalStartAlbCommand() {
27521
- const cmd = new Command("start-alb").description("Run an Application Load Balancer locally: name the ALB, and cdk-local boots the ECS service(s) behind its listeners and stands up a local front-door on each listener port that round-robins across the running replicas and routes its listener rules across the backing services — a stable host endpoint, like behind a real load balancer. The symmetric ALB counterpart of `start-api`. Each <target> accepts a CDK display path (MyStack/MyAlb) or stack-qualified logical ID; single-stack apps may omit the stack prefix. Supports HTTP and HTTPS listeners — by default a cloud-HTTPS listener is served over plain HTTP locally (with X-Forwarded-Proto: https preserved). Pass --tls (or --tls-cert / --tls-key) to terminate TLS locally with a self-signed or user-supplied cert. All six ALB rule-condition fields are honored (path-pattern / host-header / http-header / http-request-method / query-string / source-ip); forward (single and weighted), redirect, and fixed-response actions; and ECS or Lambda targets (a Lambda target group is invoked locally via the Lambda RIE). authenticate-cognito / authenticate-oidc actions enforce a local Bearer-JWT check (or AWSELBAuthSessionCookie pass-through) against the same JWKS / OIDC discovery URL the deployed ALB would; use --bearer-token '<jwt>' to inject a default token or --no-verify-auth to disable the guard. Omit <targets> in an interactive terminal to multi-select the load balancers from a list.").argument("[targets...]", "One or more CDK display paths or stack-qualified logical IDs of the AWS::ElasticLoadBalancingV2::LoadBalancer resources to run (omit to multi-select interactively in a TTY)").addOption(new Option("--from-state", "Read cdkd's S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::ImportValue / Fn::GetStackOutput intrinsics in container images, environment variables, secrets, role ARNs, and volumes of the ECS services behind the ALB. Does NOT reach a Lambda target group's container environment (upstream go-to-k/cdk-local#707; a boot warning names the affected functions) — use --from-cfn-stack for those. Mutually exclusive with --from-cfn-stack.").default(false)).addOption(new Option("--state-bucket <bucket>", "S3 bucket for --from-state. Falls back to CDKD_STATE_BUCKET env or cdk.json context.cdkd.stateBucket.")).addOption(new Option("--state-prefix <prefix>", "S3 key prefix for --from-state state files.").default("cdkd")).action(withErrorHandling(async (targets, options) => {
27833
+ const cmd = new Command("start-alb").description("Run an Application Load Balancer locally: name the ALB, and cdk-local boots the ECS service(s) behind its listeners and stands up a local front-door on each listener port that round-robins across the running replicas and routes its listener rules across the backing services — a stable host endpoint, like behind a real load balancer. The symmetric ALB counterpart of `start-api`. Each <target> accepts a CDK display path (MyStack/MyAlb) or stack-qualified logical ID; single-stack apps may omit the stack prefix. Supports HTTP and HTTPS listeners — by default a cloud-HTTPS listener is served over plain HTTP locally (with X-Forwarded-Proto: https preserved). Pass --tls (or --tls-cert / --tls-key) to terminate TLS locally with a self-signed or user-supplied cert. All six ALB rule-condition fields are honored (path-pattern / host-header / http-header / http-request-method / query-string / source-ip); forward (single and weighted), redirect, and fixed-response actions; and ECS or Lambda targets (a Lambda target group is invoked locally via the Lambda RIE). authenticate-cognito / authenticate-oidc actions enforce a local Bearer-JWT check (or AWSELBAuthSessionCookie pass-through) against the same JWKS / OIDC discovery URL the deployed ALB would; use --bearer-token '<jwt>' to inject a default token or --no-verify-auth to disable the guard. Omit <targets> in an interactive terminal to multi-select the load balancers from a list.").argument("[targets...]", "One or more CDK display paths or stack-qualified logical IDs of the AWS::ElasticLoadBalancingV2::LoadBalancer resources to run (omit to multi-select interactively in a TTY)").addOption(new Option("--from-state", "Read cdkd's S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::ImportValue / Fn::GetStackOutput intrinsics in container images, environment variables, secrets, role ARNs, and volumes of the ECS services behind the ALB. Does NOT reach a Lambda target group's container environment (a boot warning names the affected functions) — use --from-cfn-stack for those. Mutually exclusive with --from-cfn-stack.").default(false)).addOption(new Option("--state-bucket <bucket>", "S3 bucket for --from-state. Falls back to CDKD_STATE_BUCKET env or cdk.json context.cdkd.stateBucket.")).addOption(new Option("--state-prefix <prefix>", "S3 key prefix for --from-state state files.").default("cdkd")).action(withErrorHandling(async (targets, options) => {
27522
27834
  await runEcsServiceEmulator(targets, options, buildAlbEmulatorStrategy(options), cdkdExtraStateProviders);
27523
27835
  }));
27524
27836
  addAlbSpecificOptions(cmd);
@@ -27538,7 +27850,7 @@ function createLocalStartCloudFrontCommand$1() {
27538
27850
  embedConfig: getEmbedConfig(),
27539
27851
  extraStateProviders: cdkdExtraStateProviders
27540
27852
  });
27541
- cmd.addOption(new Option("--from-state", "[not supported on start-cloudfront] Read cdkd's S3 state for the target stack. Refused at startup: the CloudFront emulator consults a state source only under --from-cfn-stack (go-to-k/cdkd#2528, upstream go-to-k/cdk-local#699). Use --from-cfn-stack instead.").default(false));
27853
+ cmd.addOption(new Option("--from-state", "[not supported on start-cloudfront] Read cdkd's S3 state for the target stack. Refused at startup: the CloudFront emulator consults a state source only under --from-cfn-stack. Use --from-cfn-stack instead.").default(false));
27542
27854
  cmd.addOption(new Option("--state-bucket <bucket>", "[not supported on start-cloudfront] S3 bucket for --from-state. Refused at startup with --from-state."));
27543
27855
  cmd.addOption(new Option("--state-prefix <prefix>", "[not supported on start-cloudfront] S3 key prefix for --from-state state files. Refused at startup with --from-state.").default("cdkd"));
27544
27856
  cmd.addOption(new Option("--no-assume-role", "Explicitly opt out of assuming the deployed execution role: forward your ambient AWS credentials (or the --profile overlay) unchanged, and suppress the \"re-run with --assume-role\" hint that omitting the flag prints when deployed state is loaded."));
@@ -27554,7 +27866,7 @@ function refuseUnwiredCdkdStateFlags(cmd) {
27554
27866
  if (options.stateBucket !== void 0) passed.push("--state-bucket");
27555
27867
  if (actionCommand.getOptionValueSource("statePrefix") === "cli") passed.push("--state-prefix");
27556
27868
  if (passed.length === 0) return;
27557
- actionCommand.error(`error: ${passed.join(" / ")} ${passed.length === 1 ? "is" : "are"} not supported by \`cdkd local start-cloudfront\`. The CloudFront emulator resolves its deployed-S3 origins, its cf.kvs() bindings and its Function URL / Lambda@Edge containers' environment through cdk-local, which consults a state source only under --from-cfn-stack. DROP the flag(s) above, then use --from-cfn-stack '<name>' for a CloudFormation-deployed stack, or --origin '<originId>'='<dir>' to serve an origin from a local directory. Adding --from-cfn-stack while leaving these on hits this same refusal. Tracked as go-to-k/cdkd#2528 (upstream go-to-k/cdk-local#699).`, { code: "cdkd.startCloudFrontStateFlagUnsupported" });
27869
+ actionCommand.error(`error: ${passed.join(" / ")} ${passed.length === 1 ? "is" : "are"} not supported by \`cdkd local start-cloudfront\`. The CloudFront emulator resolves its deployed-S3 origins, its cf.kvs() bindings and its Function URL / Lambda@Edge containers' environment through cdk-local, which consults a state source only under --from-cfn-stack. DROP the flag(s) above, then use --from-cfn-stack '<name>' for a CloudFormation-deployed stack, or --origin '<originId>'='<dir>' to serve an origin from a local directory. Adding --from-cfn-stack while leaving these on hits this same refusal.`, { code: "cdkd.startCloudFrontStateFlagUnsupported" });
27558
27870
  });
27559
27871
  }
27560
27872
 
@@ -28208,7 +28520,7 @@ function pickReferencedLogicalId(intrinsic) {
28208
28520
  function createLocalCommand() {
28209
28521
  setEmbedConfig(CDKD_EMBED_CONFIG);
28210
28522
  const local = new Command("local").description("Local execution of Lambda functions (RIE) and ECS task definitions (Docker required)");
28211
- const invoke = new Command("invoke").description("Run a Lambda function locally in a Docker container (RIE-backed). Target accepts a CDK display path (MyStack/MyApi/Handler) or stack-qualified logical ID (MyStack:MyApiHandler1234ABCD). Single-stack apps may omit the stack prefix.").argument("<target>", "CDK display path or stack-qualified logical ID of the Lambda to invoke").addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}})")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for IMAGE local-build path; `docker build` does not pull base layers by default")).addOption(new Option("--no-build", "Skip docker build on the IMAGE local-build path (use the previously-built tag). Requires the deterministic tag to already be in the local registry; errors with an actionable message when missing. No-op for ZIP Lambdas and the IMAGE ECR-pull path. Compatible with --no-pull.")).addOption(new Option("--debug-port <port>", "Node --inspect-brk port (default: off)")).addOption(new Option("--container-host <host>", "Host to bind the RIE port to").default("127.0.0.1")).addOption(new Option("--assume-role [arn]", "Assume the Lambda's deployed execution role and forward STS-issued temp credentials to the container so the handler runs with the deployed function's narrow permissions (closes the \"developer admin / function narrow\" skew). Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) auto-resolves the function's execution role ARN from cdkd state (requires --from-state); (3) `--no-assume-role` explicitly opts out (forces dev creds even with --from-state). Off by default — when omitted, the developer's shell credentials are forwarded unchanged (SAM-compatible default). STS failures degrade to a warn + dev-creds fallback.")).addOption(new Option("--no-assume-role", "Explicitly opt out of assuming the deployed execution role: forward your ambient AWS credentials (or the --profile overlay) even when --from-state is set, and suppress the \"run with --assume-role\" hint. Distinct from omitting the flag, which still prints that hint.")).addOption(new Option("--layer-role-arn <arn>", "Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN entry in Properties.Layers (issue #448). Use only when the dev credentials cannot read the layer — typically cross-account layers. AWS-published public layers (e.g. Lambda Powertools) are readable from every account and need no role.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries (#455). Issues sts:AssumeRole via the default credential chain and uses the temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the caller does not have direct cross-account access to the target repository. A same-account pull in ANY region does not need this flag: the ECR client is built for the image URI's own region, so crossing a region costs nothing extra (issue #2536).")).addOption(new Option("--from-state", "Read cdkd S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub in env vars with the deployed physical IDs / attributes. Off by default — keep PR 1 warn-and-drop semantics; turn on for stacks already deployed via cdkd deploy.").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the cdkd stack name; pass an explicit value when CFn stack name differs. Mutually exclusive with --from-state. Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-state when the same stack name has state in multiple regions, and with --from-cfn-stack as the CFn client region (cdkd does not have a separate --cfn-stack-region flag).").argParser(parseStackRegion)).action(withErrorHandling(localInvokeCommand));
28523
+ const invoke = new Command("invoke").description("Run a Lambda function locally in a Docker container (RIE-backed). Target accepts a CDK display path (MyStack/MyApi/Handler) or stack-qualified logical ID (MyStack:MyApiHandler1234ABCD). Single-stack apps may omit the stack prefix.").argument("<target>", "CDK display path or stack-qualified logical ID of the Lambda to invoke").addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}})")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for IMAGE local-build path; `docker build` does not pull base layers by default")).addOption(new Option("--no-build", "Skip docker build on the IMAGE local-build path (use the previously-built tag). Requires the deterministic tag to already be in the local registry; errors with an actionable message when missing. No-op for ZIP Lambdas and the IMAGE ECR-pull path. Compatible with --no-pull.")).addOption(new Option("--debug-port <port>", "Node --inspect-brk port (default: off)")).addOption(new Option("--container-host <host>", "Host to bind the RIE port to").default("127.0.0.1")).addOption(new Option("--assume-role [arn]", "Assume the Lambda's deployed execution role and forward STS-issued temp credentials to the container so the handler runs with the deployed function's narrow permissions (closes the \"developer admin / function narrow\" skew). Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) auto-resolves the function's execution role ARN from cdkd state (requires --from-state); (3) `--no-assume-role` explicitly opts out (forces dev creds even with --from-state). Off by default — when omitted, the developer's shell credentials are forwarded unchanged (SAM-compatible default). STS failures degrade to a warn + dev-creds fallback.")).addOption(new Option("--no-assume-role", "Explicitly opt out of assuming the deployed execution role: forward your ambient AWS credentials (or the --profile overlay) even when --from-state is set, and suppress the \"run with --assume-role\" hint. Distinct from omitting the flag, which still prints that hint.")).addOption(new Option("--layer-role-arn <arn>", "Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN entry in Properties.Layers. Use only when the dev credentials cannot read the layer — typically cross-account layers. AWS-published public layers (e.g. Lambda Powertools) are readable from every account and need no role.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries. Issues sts:AssumeRole via the default credential chain and uses the temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the caller does not have direct cross-account access to the target repository. A same-account pull in ANY region does not need this flag: the ECR client is built for the image URI's own region, so crossing a region costs nothing extra.")).addOption(new Option("--from-state", "Read cdkd S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub in env vars with the deployed physical IDs / attributes. Off by default — keep PR 1 warn-and-drop semantics; turn on for stacks already deployed via cdkd deploy.").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the cdkd stack name; pass an explicit value when CFn stack name differs. Mutually exclusive with --from-state. Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-state when the same stack name has state in multiple regions, and with --from-cfn-stack as the CFn client region (cdkd does not have a separate --cfn-stack-region flag).").argParser(parseStackRegion)).action(withErrorHandling(localInvokeCommand));
28212
28524
  [
28213
28525
  ...commonOptions,
28214
28526
  ...appOptions,
@@ -28282,4 +28594,4 @@ function collectVerbFlags(program) {
28282
28594
 
28283
28595
  //#endregion
28284
28596
  export { canonicalizeIpProtocolValue as a, buildProgram, resolveSecretDerivedPrincipals as i, runDestroyForStack as n, resolvedResourceTimeoutMs as o, isResolvableSecretPrincipalList as r, canonicalizeIpv4Cidr as t };
28285
- //# sourceMappingURL=program-CIxuz2zX.js.map
28597
+ //# sourceMappingURL=program-NRnM6vPK.js.map