What's done here:
- Call releaseLock() on the stdin reader, which immediately cancels any
active reads and prevents new ones.
- Adjust BetterReader to pass releaseLock() on, and handle the input
ending, and expose how much input was read into a buffer if it's
partially filled.
- Add an error message when the one user of read(opt_buffer) gets too
small a buffer.
That last one is readline trying to read 1 byte, and we currently
infinitely loop on that after exiting a process. So this is definitely
not correct but it feels like it's the right direction.
After launching an app, if successful, we connect stdio streams to it,
and wait for it to exit before we return to the prompt.
stdio is implemented as regular AppConnection messages:
- stdin: `{ $: 'stdin', data: Uint8Array }` from phoenix -> child
- stdout: `{ $: 'stdout', data: Uint8Array }` from child -> phoenix
Terminal and Phoenix now communicate with each other using the same
style, instead of 'input' and 'output' messages. This will help with
eventually running subshells.
SIGINT currently is not sent. We also suffer from the same "one more
read from stdin happens after app exits" bug that's in
PathCommandProvider where I copied the stdin code from.
puter.ui.launchApp() returns a Promise that needs to resolve whether the
app uses the Puter SDK or not. Non-SDK apps are tricky because they
don't send a READY message on startup, and we don't know in advance
whether an app will use the SDK or not.
This is a workaround to ensure that launchApp() always resolves. When an
app is closed, if it wasn't using the SDK, we send an artificial
notification that it launched, followed by an extra notification that
it has closed (because the original close notification was sent before
this point). This means any users of launchApp() can await it, and get
an AppConnection, and listen to the close event. They can't otherwise
interact with a non-SDK app because it will have closed already, but we
can improve this in the future without breaking the API.
Apps are not required to use the Puter SDK. If they don't, then we can
still launch them, close them, and listen to their close event, but are
unable to send messages to them.
This also runs the tests for contextlink, which I think we previously
never ran. I don't see any other packages that define an `npm test`
command. Having to manually list all the sub-package test directories in
the top-level package.json is a bit unfortunate, but it works.
For Puter itself we support Node 16.x IIRC, but Phoenix requires at
least 20.x currently.