The Comonad concept represents context-sensitive computations and data.
Formally, the Comonad concept is dual to the Monad concept. But unless you're a mathematician, you don't care about that and it's fine. So intuitively, a Comonad represents context sensitive values and computations. First, Comonads make it possible to extract context-sensitive values from their context with extract. In contrast, Monads make it possible to wrap raw values into a given context with lift (from Applicative).
Secondly, Comonads make it possible to apply context-sensitive values to functions accepting those, and to return the result as a context-sensitive value using extend. In contrast, Monads make it possible to apply a monadic value to a function accepting a normal value and returning a monadic value, and to return the result as a monadic value (with chain).
Finally, Comonads make it possible to wrap a context-sensitive value into an extra layer of context using duplicate, while Monads make it possible to take a value with an extra layer of context and to strip it with flatten.
Whereas lift, chain and flatten from Applicative and Monad have signatures
\begin{align*} \mathtt{lift}_M &: T \to M(T) \\ \mathtt{chain} &: M(T) \times (T \to M(U)) \to M(U) \\ \mathtt{flatten} &: M(M(T)) \to M(T) \end{align*}
extract, extend and duplicate from Comonad have signatures
\begin{align*} \mathtt{extract} &: W(T) \to T \\ \mathtt{extend} &: W(T) \times (W(T) \to U) \to W(U) \\ \mathtt{duplicate} &: W(T) \to W(W(T)) \end{align*}
Notice how the "arrows" are reversed. This symmetry is essentially what we mean by Comonad being the dual of Monad.
extract and (extend or duplicate) satisfying the laws below. A Comonad must also be a Functor.
For all Comonads w, the following laws must be satisfied:
Functor, hence the requirement that a Comonad also is a Functor.