Skip to content

feat(messages): hold a conversation with the bots from the terminal - #164

Merged
arthware-dev merged 5 commits into
mainfrom
feat/drive-tool
Sep 27, 2026
Merged

arthware-dev merged 5 commits into
mainfrom
feat/drive-tool

Conversation

@arthware-dev

Copy link
Copy Markdown
Contributor

Summary

  • stack <stacklet> <command> --json prints what the command returns; before, the answer was dropped and --json reached the command as an argument (send ... --json posted "... --json").
  • stack messages can hold a conversation with the bots: send --reply-to, react, and read --after/--from/--wait, so the archivist's answer to one message can be awaited from the terminal.
  • tests/driver/driver operates an instance from its own surfaces only (the CLI and the chat), here or on another Mac over ssh: say, speak and send as a family member, read and await answers, run ./stack, answer the installer's prompts with a transcript and asciinema recording, and open web UIs in Playwright. README in tests/driver/.

Rebase merge: four commits, each its own changelog line.

A stacklet command returns a dict, and the plugin contract says the
framework renders it. It never did: on success the dict was dropped,
and `--json` was passed on to the command as an argument, so
`stack messages send room "hi" --json` posted "hi --json" and printed
nothing, not even the event id it had sent.

With `--json` the returned dict is now printed as JSON on stdout,
anything the command prints for people goes to stderr, and the flag no
longer reaches the command. Without `--json` nothing changes.
An admin or an agent checking a bot had no way to answer one message,
react to it, or read the bot's answer to the message just sent: `send`
did not say what it posted, and `read` showed the whole room.

- `stack messages send ... --reply-to <event-id>` answers one message
  without starting a thread, and `send` prints the id of what it posted.
- `stack messages react <room> <event-id> <emoji> [--as <user>]` reacts
  as the system account or a family member.
- `stack messages read` takes `--after <event-id>`, `--from <user>` and
  `--wait <seconds>`, so it can wait for the archivist's answer to one
  message; with `--json` each message names its thread or the message
  it answers.
Trying something on a real instance meant hand-written Matrix calls and
ssh one-liners in every session. `tests/driver/driver` acts as a family
member (say, voice, send, react), reads and awaits what the bots
answered, runs `./stack` as the admin, answers an interactive command
such as the installer prompt by prompt with a transcript and an
asciinema recording, and opens a stacklet's web UI in Playwright,
signed in to Element, on this Mac or another over ssh.

It uses only the stack's own surfaces, the CLI and the chat through
`stack messages`; what it adds is the target, text turned into speech,
copying a file to the instance, and the event ids between steps.
Reviews of larger changes went into reverse-engineering long functions
that mixed parsing, deciding and I/O. The engineer guide now lists eight
structural rules, after Robert C. Martin's Clean Code, that new and
touched code follows, and the pr skill checks a diff against them before
a PR is opened. Existing code is left for its own day.
`driver cycle curator` and `driver cycle nightly` run the work the
curator otherwise does on a timer (pages after a filing, the nightly
sweep) through `stack memory sync --pages` and `stack memory nightly`,
and log it as a CYCLE line, apart from what family members do.
@arthware-dev
arthware-dev merged commit 7625d63 into main Sep 27, 2026
1 check passed
@arthware-dev
arthware-dev deleted the feat/drive-tool branch September 27, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant