The hint by Yuval in his comment is the right one. An approach to writing context-sensitive grammars is to design them like a machine. Send messages over the string. This is very close to writing a linear bounded automaton (or linear space Turing machine). In such a machine the reading/writing head scans over the tape while updating the string. This head (with the machine state) can be modelled by a production, like $ap\to qb$ for "in state $p$ while reading $a$, write $b$ and move left, changing state to $q$", where we assume the state is written to the right of the position of the head.
There are differences. The CSG is more flexible as one can insert letters in the middle of the string, and moreover there can be parallel processes going on at the same time. The latter can be a nuisance when arguing the approach is correct.
Lets see how the messages work in an example:
$L = \{ww\mid w\in\{a,b\}^*, |w|\ge 1 \}$, or squares.
Start with left and right sides of the string with the rule $S\to LR$. As markers and messengers cannot disappear in a CSG they must represent a letter in the final string. This letter can be $a$ or $b$ so we have two rules instead: $S\to L_aR_a\mid L_bR_b$. Now the left marker generates new letters and a messenger that becomes a copy at the other half of the string. $L_\sigma\to L_\sigma aM_a\mid L_\sigma bM_b$. Everywhere in these rules $\sigma,\tau$ may take the values $a,b$.
Messengers move over other letters: $M_\sigma\tau\to \tau M_\sigma$. At the beginning of the second half write the letter: $M_\sigma R_\tau \to R_\tau \sigma$.
We should end the derivation by removing the boundary markers $L_\sigma\to\sigma$, $R_\sigma\to \sigma$. We have a problem when the right marker is gone, while there is still a messenger under way. This can be solved by extra symchronization. However, no terminal string will be generated this way; the drivation is lost, so there is no real problem.
I tried a similar approach here for the language $\{a^ib^jc^{ij} \mid i,j\ge 1\}$. Here a hint for squares (numbers) $\{a^{n^2} \mid n\ge 1\}$. As you see, I practise a lot.
PS. I hope you mean a monotonic grammar rather than a "real" context-sensitive one. Those are harder, but there is a standard (boring) transformation.