This may be a useful reference.
betterprogramming.pub/making-a-verlet-physics-engine-in-javascript-1dff066d7bc5
Notable difference to what you’re doing is when limiting the distance between nodes it takes the mass of each node into consideration.
Another thought is to take mass into consideration when applying damping. Something like this:
(X-px)- (1-damping)*(x-px)/mass
For the gravity it looks like what you have is in line with verlet physics. You probably just need to use smaller gravity values.
For collisions it would be a matter of pushing the nodes out of shapes in the closest direction. For circles it’s basically the same as what limits the distance between nodes. For a box it’s a bit more involved.
You asked how to make it change length. Probably by changing the rest length. Adding/removing nodes on the fly seems like an interesting idea too but may take a bit more logic.
As to make it more stable, you need more iterations. It’s trying to solve the limits one at a time so only the last one is perfect. Each iteration brings everything closer. Also the longer the chain is you’ll need more iterations.
So you could limit the speeds of the player and enemy. Or if higher speeds are needed you could move over several smaller steps in a loop with that iteration loop to solve the limits.