Download the PHP package jordandalton/tackle-slack without Composer

On this page you can find all versions of the php package jordandalton/tackle-slack. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package tackle-slack

tackle-slack

Drive a Laravel Tackle coding session from Slack.

Then message the app. Send a task, watch it work, press Yes when it asks before running something destructive.

Why Slack, and not a hosted bot

Outbound only, still. This uses Socket Mode: a WebSocket your machine opens to Slack. No public URL, no tunnel, no hosted process, no port forwarding. A laptop behind NAT can be driven from a phone on the train, because Slack's servers are the relay.

The two other ways to hear from Slack both fail that test. The Events API needs a URL Slack can POST to. Polling conversations.history was rate-limited in 2025 to one call a minute for apps not on the Marketplace, which is not a transport, it is a stall.

And a team already lives there. A session in a channel is one the whole team can watch, and one where the approval a destructive step needs can come from whoever is around — as long as they are on the list.

What it took to build

Almost nothing, and that is the point.

Tackle Remote already separates the agent from the way a human reaches it:

Piece Job Knows about browsers?
SessionLoop Pops the inbox, drives the agent, appends events No
RemoteState inbox / events / question / answers, as files No
RemoteInteraction InteractionPolicy over that protocol No
server/router.php HTTP transport Yes — and only this

So this package adds no new InteractionPolicy and no agent code. It is a pump between that state directory and a channel: drain events out, offer the pending question as buttons, push replies back into the inbox. Every ConfirmAction, every destructive RunArtisan, every MutateDatabase commit routes to Slack automatically, because they already routed through InteractionPolicy.

The only new machinery is a WebSocket client, because a library would have been the package's one dependency for a protocol that fits on two screens.

Security: read this part

Anyone who can message this app can run code on the machine hosting it — and in a channel, that is everyone in the channel.

So allowed_users is not a convenience — it is the entire security model. An unlisted user is not answered, not rate-limited, not asked to authenticate. Their message is dropped before it can reach the agent. An empty allowlist means nobody, and the command refuses to start rather than quietly accepting the workspace.

Your code goes to Slack, and to the channel. The agent will echo file contents, stack traces, and whatever else it reads. In a direct message that is between you and Slack. In a channel it is between you, Slack, and everyone who can read the channel — which is the point of a channel, and also something to decide on purpose. For a client's project, or anything with a compliance boundary, it may simply be a no.

What it does

Install

1. Create the app

Go to api.slack.com/apps → Create New App → From a manifest, pick your workspace, and paste this:

Then:

  1. Install to Workspace, and copy the Bot User OAuth Token (xoxb-…) from OAuth & Permissions into TACKLE_SLACK_BOT_TOKEN.
  2. Under Basic Information → App-Level Tokens, generate one with the connections:write scope and put it (xapp-…) in TACKLE_SLACK_APP_TOKEN.
  3. Invite the app to the channel you want to use (/invite @Tackle), or open a direct message with it.

2. Pair

Find out who is allowed to drive it. Message the app, then:

Say yes and it writes both lines into .env — appending to the user list rather than replacing it, so pairing a second person does not revoke the first, and setting the channel only if nothing has chosen one yet.

--pair only listens and reports. It acts on nothing, so anyone in the workspace can make it print their id — and none of them can make it do anything. The decision stays with you.

Stop any running session first. Slack spreads events across every open Socket Mode connection, so a session running alongside --pair will take turns swallowing your messages with no error anywhere to explain where they went.

3. Start a session

Leave TACKLE_SLACK_CHANNEL unset and the session opens a direct message with the first allowed user.

In your dev script

composer dev runs its processes under concurrently --kill-others, which tears the whole environment down the moment any one of them exits. Use --if-configured so a machine without a Slack setup idles instead of taking the server, queue and Vite with it:

Run on its own without a token it still fails loudly, which is what you want when you meant to start it.

Commands

Slack intercepts anything you type beginning with /, so /clear on its own never reaches anyone. The manifest registers /tackle for that:

/tackle or @Tackle What this is and how to use it
/tackle help Built-in and project commands
/tackle clear Forget the conversation and start fresh
/tackle deploy-check Any command the session has published
/tackle fix the tests Anything else after /tackle is a task
anything else A task for the agent

Restarting the command resumes rather than resets — that is what the "Resumed session" line means. /tackle clear, or a new --session, is what starting over actually looks like.

Files and images are not supported yet; the bot says so rather than ignoring them.

Troubleshooting

Nothing arrives. TACKLE_SLACK_DEBUG=1 traces what the pump is doing — which events it read, whether it posted or edited, and when the socket reconnects.

not_in_channel. The app has to be invited before it can post there: /invite @Tackle.

channel_not_found. TACKLE_SLACK_CHANNEL wants the id (C…, G…, D…), not the name. It is at the bottom of the channel's details pane.

The app ignores you in a channel. It only listens in the one channel it was started for, and only to the users on the list. --pair will tell you what Slack thinks both ids are.

/tackle says "failed with the error dispatch_failed". The session is not running, so nothing acknowledged the command. Start one.

Status

72 tests, against an in-memory Slack — the security model is not something to verify by hand against a live workspace. The WebSocket client has been exercised against a live echo server, including the 64-bit length form and a fragmented read.

Flown against a real workspace on a real project: a task sent from a channel edited a Vue component, narrated what it was doing as it went, and was reverted the same way. The first live run found --pair allowlisting the bot with itself — its own "has joined the channel" event is a message from its own user id — and that is fixed.

Related


All versions of tackle-slack with dependencies

PHP Build Version
Package Version
Requires php Version ^8.3
ext-curl Version *
ext-json Version *
ext-mbstring Version *
ext-openssl Version *
jordandalton/laravel-tackle Version ^1.50
jordandalton/laravel-tackle-remote Version ^0.1.3
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package jordandalton/tackle-slack contains the following files

Loading the files please wait ...