Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
115a8a2
Use Corbits Tag for Slack approval workflows
pratikbuilds Jul 31, 2026
35bed53
Remove the unused Slack bridge
pratikbuilds Jul 31, 2026
7df2bbc
Merge main into Slack approval workflow
pratikbuilds Aug 2, 2026
0f9940a
Simplify local workflow step invocation
pratikbuilds Aug 2, 2026
630e380
Merge PR #14 into Slack approval workflow
pratikbuilds Aug 2, 2026
faf1d66
Reuse PR 14 Corbits Tag workspace
pratikbuilds Aug 2, 2026
466be6d
Merge provider selection into Slack approval workflow
pratikbuilds Aug 2, 2026
aa92a4a
Restore provider selection in the approval workflow
pratikbuilds Aug 2, 2026
95d5b18
Merge provider cleanup into Slack approval workflow
pratikbuilds Aug 3, 2026
7bd009c
Remove unnecessary approval workflow test commentary
pratikbuilds Aug 3, 2026
3e0ead8
Add Slack post-to-X workflow
pratikbuilds Aug 3, 2026
f52ee32
Reuse shared Corbits Tag workspace
pratikbuilds Aug 3, 2026
47bb27b
Add Slack community pulse workflow
pratikbuilds Aug 3, 2026
2fe7965
Add Slack Team Grill workflow
pratikbuilds Aug 3, 2026
5a93668
Add Slack fact-check workflow
pratikbuilds Aug 3, 2026
65f2cae
Validate web research responses
pratikbuilds Aug 4, 2026
b55f7c5
Remove unused web research flexibility
pratikbuilds Aug 4, 2026
af00b55
Address Community Pulse review feedback
pratikbuilds Aug 4, 2026
cef0c3f
Prevent stalled Slack approval sessions
pratikbuilds Aug 4, 2026
0a2d4f6
Remove approval workflow tests
pratikbuilds Aug 4, 2026
f6ce690
Use Corbits branding and LGPL license
pratikbuilds Aug 4, 2026
bd05968
Merge remote-tracking branch 'origin/agent/use-corbits-tag-for-slack-…
pratikbuilds Aug 4, 2026
5bdf48e
Merge remote-tracking branch 'upstream/slack-community-pulse-tag-work…
pratikbuilds Aug 4, 2026
13ac339
Use Corbits identity for Community Pulse
pratikbuilds Aug 4, 2026
0c157c8
Use Corbits branding and LGPL license
pratikbuilds Aug 4, 2026
ab9d2c4
Use Corbits branding and LGPL license
pratikbuilds Aug 4, 2026
622801b
Use Corbits branding and LGPL license
pratikbuilds Aug 4, 2026
7511e07
Merge remote-tracking branch 'upstream/slack-community-pulse-tag-work…
pratikbuilds Aug 4, 2026
745a804
Revert "Merge remote-tracking branch 'origin/agent/use-corbits-tag-fo…
pratikbuilds Aug 4, 2026
2bb72bd
Merge updated Team Grill base
pratikbuilds Aug 4, 2026
37c493f
Merge latest post-to-X base
pratikbuilds Aug 4, 2026
a779c4f
Merge commit '37c493f03de92be48a636d862108bfa065c65353' into agent/ad…
pratikbuilds Aug 4, 2026
816fb27
Merge final Team Grill base
pratikbuilds Aug 4, 2026
85fdeac
Merge updated Corbits Slack agent base
pratikbuilds Aug 4, 2026
60f87aa
Reapply "Merge remote-tracking branch 'origin/agent/use-corbits-tag-f…
pratikbuilds Aug 4, 2026
16e5a1e
Merge commit '85fdeaca3906f5523f60404be8bce2923d0e826b' into agent/ad…
pratikbuilds Aug 4, 2026
f457011
Merge final post-to-X base
pratikbuilds Aug 4, 2026
9899c37
Merge commit 'f4570119c71ac3365869d34d3364027a5ef1676e' into agent/ad…
pratikbuilds Aug 4, 2026
a62516a
Merge complete Team Grill base
pratikbuilds Aug 4, 2026
5fcfd46
Scaffold the Slack internal processing package
pratikbuilds Aug 7, 2026
0890ccf
Add call digest types and strict parser
pratikbuilds Aug 7, 2026
13578c7
Define summarize and extract digest workflow
pratikbuilds Aug 7, 2026
bc3f754
Render Slack intake and digest cards
pratikbuilds Aug 7, 2026
dfd0624
Drive transcript intake through Slack sessions
pratikbuilds Aug 7, 2026
b6dd2e3
Mount the Corbits Tag Slack entrypoint
pratikbuilds Aug 7, 2026
b8b0856
Cover digest parsing and session regressions
pratikbuilds Aug 7, 2026
544565f
Document Slack internal processing setup
pratikbuilds Aug 7, 2026
2a98b38
Fix Slack digest workflow data contracts
pratikbuilds Aug 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions starter/slack-approval-flow/.env.example
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
PORT=3001
PUBLIC_BASE_URL=https://your-public-tunnel.example

# Keep these secret. Do not commit real values.
# PUBLIC_BASE_URL is a setup convenience, not a runtime input. Use it for
# both Slack request URLs:
# Events API: ${PUBLIC_BASE_URL}/api/tag/slack/webhook
# Interactivity: ${PUBLIC_BASE_URL}/api/tag/slack/webhook

# Slack ingress. Keep these secret. Do not commit real values.
SLACK_SIGNING_SECRET=
SLACK_APP_TOKEN=xapp-...
SLACK_BOT_TOKEN=xoxb-...

# Pick whichever model provider you have configured.
ANTHROPIC_API_KEY=sk-...
# OPENAI_API_KEY=sk-...
# Set one model-provider key. Empty values are ignored.
ANTHROPIC_API_KEY=
OPENAI_API_KEY=
# OPENAI_BASE_URL=
# GOOGLE_API_KEY=
GOOGLE_API_KEY=
# GEMINI_API_KEY=

# Optional overrides.
# INTX_PROVIDER=anthropic
Expand Down
127 changes: 67 additions & 60 deletions starter/slack-approval-flow/README.md
Original file line number Diff line number Diff line change
@@ -1,87 +1,94 @@
# slack-approval-flow

A human-in-the-loop approval workflow driven from Slack:
A human-in-the-loop Interchange workflow driven from Slack through Corbits Tag:

```text
Slack message -> draft -> approval buttons -> approve/reject -> final reply
Slack mention or DM -> draft -> approval card -> approve/reject -> final reply
```

An app mention, DM, or Slack Assistant message starts a run. The draft is
posted back into the thread with Block Kit Approve / Reject buttons.
Approve delivers `run.signal("approve", payload)` and the publish step
executes; Reject calls `run.cancel(...)`. The published result — or the
terminal status if the run ended some other way — lands in the same
thread.
`mountSlackTag` owns Slack signature verification, HTTP webhook routing, and
event normalization. This starter owns the workflow policy and session state:
it posts Chat SDK cards, handles `Button` actions with `onAction`, signals an
approval with `run.signal("approve", payload)`, and cancels a rejection with a
supported Interchange cancellation actor.

This directory is self-contained. Every dependency comes from npm —
`@intx/*` at `0.2.2` and nothing here imports from anywhere else in
this repository. Copy the directory anywhere, `bun install`, and it
runs.
This starter builds on the Corbits Tag dependency introduced by the Slack agent
starter. It uses npm `@intx/*` packages at `0.2.2` and consumes the shared,
pinned Corbits Tag checkout at `../slack-agent/vendor/corbits-tag` as a Bun
workspace. The stacked change does not register or clone a second submodule.

## What's here
## Setup

| Path | Purpose |
| --- | --- |
| `src/cli.ts` | Entry point |
| `src/config.ts` | Slack + provider configuration from the environment |
| `src/adapter.ts` | Routes Slack events and button clicks into the session store |
| `src/session.ts` | The approval lifecycle: one run per Slack thread |
| `src/blocks.ts` | The approval UI — Block Kit payloads for each state |
| `src/workflow.ts` | The workflow itself: `draft -> awaitSignal("approve") -> publish` |
| `src/source.ts` | Provider resolution from the environment |
| `src/slack/` | The Slack transport: connection config, Bolt wiring, event parsing, message helpers, thread session store, generic workflow adapter |
1. Clone the repository with its submodules and install this starter:

## Setup
```bash
git clone --recurse-submodules https://github.com/corbitsdev/examples.git
cd examples/starter/slack-approval-flow
bun install
cp .env.example .env
```

```bash
cd starter/slack-approval-flow
bun install
cp .env.example .env
```
If the repository is already cloned, initialize the shared Corbits Tag
submodule from the repository root:

Fill in:
```bash
git submodule update --init --recursive starter/slack-agent/vendor/corbits-tag
```

```bash
SLACK_SIGNING_SECRET=...
SLACK_APP_TOKEN=xapp-...
SLACK_BOT_TOKEN=xoxb-...
ANTHROPIC_API_KEY=...
```
2. Expose port `3001` through an HTTPS tunnel. Replace both
`https://your-public-tunnel.example` placeholders in
[`manifest.slack.json`](./manifest.slack.json) with the tunnel's HTTPS URL.
Both request URLs must end in `/api/tag/slack/webhook`.

3. Create a Slack app from the edited manifest and install it in the workspace.

4. Populate `.env` with `SLACK_SIGNING_SECRET`, `SLACK_BOT_TOKEN`, and one
provider key: `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, or `GOOGLE_API_KEY`.

Import [`manifest.slack.json`](./manifest.slack.json) in Slack, enable
Socket Mode, install (or reinstall) the app, then:
5. Start the HTTP server:

```bash
bun run start
```bash
bun run start
```

6. In Slack's app settings, verify that both Event Subscriptions and
Interactivity accept the same HTTPS webhook URL.

The server listens on:

```text
POST /api/tag/slack/webhook
```

Socket Mode needs no public tunnel. Without it, point Slack Event
Subscriptions, Slash Commands, and Interactivity at
`https://your-public-tunnel.example/slack/events` and leave
`SLACK_APP_TOKEN` unset.
## Use it

## Using it
Mention the bot in a channel or send it a DM:

```text
@interchange-workflow write a short launch note for the approval workflow demo
Open the Slack Assistant pane and ask interchange-workflow for an approval draft
@corbits-workflow write a short launch note for the approval workflow demo
```

Step context is written under `tmp/slack-approval-flow/`; delete that
directory for a fresh start.
The bot posts the draft with Approve and Reject buttons. Approval resumes the
workflow and publishes the result in the same Slack thread; rejection cancels
the run.

## Providers
Step context is written under `tmp/slack-approval-flow/`. Delete that directory
for a fresh start. Type-check with `bun run typecheck`.

Use whichever provider key you have: `ANTHROPIC_API_KEY`,
`OPENAI_API_KEY`, or `GOOGLE_API_KEY`. Set `INTX_PROVIDER` and
`INTX_MODEL` to force a provider or model. See
[`src/source.ts`](./src/source.ts).
## Providers

Type-check with `bun run typecheck`.
Set one of `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, or `GOOGLE_API_KEY`.
[`src/source.ts`](./src/source.ts) selects the configured provider and also
supports `GEMINI_API_KEY` plus OpenAI-compatible endpoints through
`OPENAI_BASE_URL`. Use `INTX_PROVIDER` and `INTX_MODEL` to select explicitly.

## A note on duplication
## Files

`src/slack/`, `src/workflow.ts` and `src/source.ts` are duplicated with
the other starters rather than shared. That is on purpose: a starter is
only useful if you can copy the one directory you are reading and have
working code. Do not factor these back into a common package.
| Path | Purpose |
| --- | --- |
| `src/cli.ts` | HTTP server, Corbits Tag mount, and Chat SDK action registration |
| `src/session.ts` | Consumer-owned approval lifecycle and run state |
| `src/cards.ts` | Chat SDK cards and buttons |
| `src/workflow.ts` | `draft -> awaitSignal("approve") -> publish` workflow |
| `src/source.ts` | Provider selection from environment variables |
| `../slack-agent/vendor/corbits-tag` | Shared pinned Corbits Tag workspace introduced by the base change |
Loading