Skip to content

feat(messaging,cli): messaging + triggers capability tokens; notify-by-email resolves to user id#1426

Merged
xuyushun441-sys merged 2 commits into
mainfrom
feat/messaging-triggers-capability-tokens
Jun 1, 2026
Merged

feat(messaging,cli): messaging + triggers capability tokens; notify-by-email resolves to user id#1426
xuyushun441-sys merged 2 commits into
mainfrom
feat/messaging-triggers-capability-tokens

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

What

Two related platform improvements that make the notify flow node and auto-firing flows usable from a plain defineStack({ requires: [...] }) — no hand-wired plugin instances.

CLI / runtime — new capability tokens

  • messagingMessagingServicePlugin, so the notify node delivers to a user's inbox channel (sys_inbox_message rows) instead of degrading to a logged no-op.
  • triggersRecordChangeTriggerPlugin (+ ScheduleTriggerPlugin as an extra), so autolaunched / schedule flows actually fire. The automation engine ships the FlowTrigger wiring; these plugins are the concrete triggers. Pair triggers with job for cron/interval schedules.

Mirrored in both the CLI CAPABILITY_PROVIDERS table (serve.ts) and the runtime capability-loader so dev objectstack serve and the cloud artifact kernel resolve them identically. cli/package.json gains the workspace deps so the dynamic imports resolve.

Inbox channel — notify-by-email lands in the right inbox

Flows commonly address recipients by email (e.g. a {record.assignee} field), but sys_inbox_message is keyed by user id. The inbox channel now resolves an email-shaped recipient to its sys_user.id via findOne, with a verbatim fallback when the recipient is not email-shaped, no user matches, or the lookup fails — so a failed resolution can never drop the row. Adds InboxChannelOptions.userObject for the lookup target.

Test

  • pnpm --filter @objectstack/service-messaging test — 24 passing (incl. 5 new resolution cases: resolve, userObject override, non-email verbatim, no-match fallback, lookup-throw fallback).
  • service-messaging + cli + runtime build clean.

Notes / follow-up (separate work)

The Console header bell currently reads sys_notification (ADR-0012 Layer-2 by name, but shipped as a per-user inbox), while the messaging inbox channel writes sys_inbox_message (ADR-0012 Layer-5). Reconciling those two — and the showcase wiring that demonstrates these tokens end-to-end — is intentionally out of scope here and will land separately (needs an ADR decision on which object is the canonical in-app inbox).

🤖 Generated with Claude Code

…olve notify-by-email to user id

Two related platform improvements that make the `notify` flow node and
auto-firing flows usable from a plain `defineStack({ requires: [...] })`,
without hand-wiring plugin instances.

CLI / runtime — new capability tokens
  • `messaging` → MessagingServicePlugin, so the `notify` node delivers to a
    user's inbox channel (sys_inbox_message rows) instead of degrading to a
    logged no-op.
  • `triggers` → RecordChangeTriggerPlugin (+ ScheduleTriggerPlugin extra), so
    autolaunched / schedule flows actually fire. The automation engine ships
    the FlowTrigger wiring; these plugins are the concrete triggers. Pair
    `triggers` with `job` for cron/interval schedules.
  Mirrored in both the CLI CAPABILITY_PROVIDERS table (serve.ts) and the
  runtime capability-loader so dev `objectstack serve` and the cloud
  artifact kernel resolve them identically. CLI package.json gains the
  workspace deps so the dynamic imports resolve.

Inbox channel — notify-by-email lands in the right inbox
  Flows commonly address recipients by email (e.g. a `{record.assignee}`
  field), but sys_inbox_message is keyed by user id. The inbox channel now
  resolves an email-shaped recipient to its sys_user.id via findOne, with a
  verbatim fallback when the recipient is not email-shaped, no user matches,
  or the lookup fails — so a failed resolution can never drop the row.
  Adds InboxChannelOptions.userObject for the lookup target. Fully covered
  by new unit tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 1, 2026 12:36am

Request Review

@github-actions github-actions Bot added dependencies Pull requests that update a dependency file tests size/m and removed dependencies Pull requests that update a dependency file tests labels Jun 1, 2026
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file tests tooling labels Jun 1, 2026
data: IDataEngine,
recipient: string,
): Promise<string> {
if (!EMAIL_SHAPE.test(recipient)) return recipient;
@xuyushun441-sys xuyushun441-sys merged commit 394d34f into main Jun 1, 2026
11 of 13 checks passed
xuyushun441-sys added a commit that referenced this pull request Jun 1, 2026
Activates the showcase's automation chains now that the platform supports
them (capability tokens from #1426; conditional/record-change flows fixed in
#1429):

- requires: ['ui','automation','approvals','messaging','triggers','job'] so
  the notify node delivers and record-change/schedule flows auto-fire.
- Register the `rest` + `slack` connectors for the connector_action node.
  `rest` points at the running server (SHOWCASE_SELF_URL) so its call +
  response are observable with no external dependency.
- Two worked flows: ScheduledDigestFlow (interval schedule → notify → inbox)
  and TaskCompletedRestPingFlow (record-change → rest connector GET /health).
- Fix BudgetApprovalFlow's decision node: branch on edge `condition`
  (`budget > 500000` / `<= 500000`) per the flow spec, instead of the
  unevaluated node-level config + true/false labels — so budgets ≤ $500k
  correctly skip the executive approval step.
- Ambient `process` decl so `pnpm typecheck` stays green without @types/node.

Verified end-to-end in the browser: schedule digest, reassign→notify→inbox
(email→user-id resolved), mark-done→REST/Slack/email, budget→approval with
correct decision routing and approve→resume.

Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants