claude-slack-channel-bots 0.16.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,7 +47,7 @@ A single HTTP MCP server that runs several independent Claude Code bots, called
47
47
  ## Prerequisites
48
48
 
49
49
  - [Bun](https://bun.sh) `>= 1.0.21` (agent-director minimum)
50
- - [Claude Code](https://claude.ai/code) 2.1.296 or later for the workers, installed and authenticated: the minimum agent-director states for its exec-form hooks, and the version the fleet runs. A Claude Code too old for exec-form hooks (older than 2.1.139) has its hooks ignored, so every launch stays `pending`. The `claude` on the workers' `PATH` must be Claude Code's native binary or a wrapper that `exec`s it: a launcher or shim that runs Claude Code as a child process makes agent-director ignore every hook (`ad.hook.ignored` with the reason `pid_mismatch`), so every launch stays `pending`.
50
+ - [Claude Code](https://claude.ai/code) 2.1.280 or later for the workers, installed and authenticated: CSCB's supported minimum and the version the fleet runs. A Claude Code too old for exec-form hooks (older than 2.1.139) has its hooks ignored, so every launch stays `pending`. The `claude` on the workers' `PATH` must be Claude Code's native binary or a wrapper that `exec`s it: a launcher or shim that runs Claude Code as a child process makes agent-director ignore every hook (`ad.hook.ignored` with the reason `pid_mismatch`), so every launch stays `pending`.
51
51
  - [`agent-director`](https://github.com/gabemahoney/agent-director) 0.12.0 or later, **installed system-wide** as a prerequisite, like `git` or `docker`. The npm `agent-director` package CSCB depends on is the client only: it finds the system-installed binary at startup and refuses to start when the binary is missing, too old, or unreachable. This release pins the client to `agent-director@0.12.0` and requires the CLI at 0.12.0 or later, installed on the host together with it, and the two are rolled back together; CSCB changes no agent-director code (see "Switching over to agent-director Phase 1" in [Migration](docs/migration.md#migration)). Every agent on the host, with every long-running agent-director process (`agent-director serve` included), is stopped before either binary change (the Phase 1 install, and the rollback's restore of the previous binary) and started again after it. The startup gate refuses a binary below the client's own minimum (`min_binary_version` in the client's `dist/version-floor.json`) or below 0.12.0, and names the required version (see [Startup errors](docs/troubleshooting.md#startup-errors)). To check the install before you start, run `bun run install-check` (see [Checking your agent-director install](docs/agent-director.md#checking-your-agent-director-install)).
52
52
  - [tmux](https://github.com/tmux/tmux) 3.2 or later, with `remain-on-exit` off. agent-director runs it; CSCB starts no tmux process. agent-director does not depend on tmux's `base-index` or `pane-base-index`, so their values don't matter.
53
53
  - Slack workspace admin access (to create and configure one Slack app per persona)
@@ -1,6 +1,6 @@
1
1
  # agent-director
2
2
 
3
- CSCB requires agent-director CLI 0.12.0 or later and pins its TypeScript client to `agent-director@0.12.0`. Workers require Claude Code 2.1.296 or later. Upgrade the CLI with its released installer before upgrading CSCB; see [Migration](migration.md#migration).
3
+ CSCB requires agent-director CLI 0.12.0 or later and pins its TypeScript client to `agent-director@0.12.0`. Workers require Claude Code 2.1.280 or later. Upgrade the CLI with its released installer before upgrading CSCB; see [Migration](migration.md#migration).
4
4
 
5
5
  CSCB runs every bot through [agent-director](https://github.com/gabemahoney/agent-director), installed system-wide. This page covers checking that install, the `install-cscb` skill that walks you through a failed check, and the agent-director settings CSCB reads.
6
6
 
package/docs/migration.md CHANGED
@@ -55,7 +55,7 @@ Do this beforehand, with the old CSCB running and still installed as the global
55
55
  2. **agent-director's version.** Run `agent-director version` in the bot server's launcher environment as the workers' user. Record its version and resolved path. Stage the released 0.12.0 installer and both binaries, and keep the prior install and flags for restoration. A host already on 0.12.0 or later needs no directory migration; verify its `config_dir` and client compatibility before restarting callers.
56
56
  3. **The tmux socket (operator action).** Pin the tmux socket for the bot server's launcher, the host's sweep schedule and the workers. The sweep schedule is whatever runs `agent-director find-missing` on a schedule on your host: a cron entry, a systemd timer or a loop script. Run `tmux display-message -p '#{socket_path}'` from the bot server's launcher, the sweep schedule's environment and a worker's. Confirm that all three print the same path, that it is the pinned path (a `TMUX_TMPDIR` that names a missing path falls back silently to `/tmp`), and that the three share one HOME. A host with no sweep schedule checks the other two, and runs the one step 11 adds in the same environment. Record the result in the switch-over log.
57
57
  4. **tmux.** Confirm tmux 3.2 or later, with `remain-on-exit` off.
58
- 5. **Claude Code.** Run `claude --version` in the bot server's launcher environment (the same user and `PATH` the server launches workers with), and confirm that the workers' Claude Code is 2.1.296 or later: the minimum agent-director states for its exec-form hooks, and the version the fleet runs. On a Claude Code too old for exec-form hooks (older than 2.1.139), each hook prints nothing, agent-director records `ad.hook.ignored` with the reason `no_exec_form`, and every launch stays `pending`. If it is older than 2.1.296, stop here, before anything goes down. In the same environment, run `command -v claude` and confirm that it resolves to Claude Code's native binary or to a wrapper that `exec`s it. A launcher or shim that runs Claude Code as a child process makes agent-director ignore every hook, recording `ad.hook.ignored` with the reason `pid_mismatch`, and every launch stays `pending`; replace such a launcher now.
58
+ 5. **Claude Code.** Run `claude --version` in the bot server's launcher environment (the same user and `PATH` the server launches workers with), and confirm that the workers' Claude Code is 2.1.280 or later: CSCB's supported minimum and the version the fleet runs. On a Claude Code too old for exec-form hooks (older than 2.1.139), each hook prints nothing, agent-director records `ad.hook.ignored` with the reason `no_exec_form`, and every launch stays `pending`. If it is older than 2.1.280, stop here, before anything goes down. In the same environment, run `command -v claude` and confirm that it resolves to Claude Code's native binary or to a wrapper that `exec`s it. A launcher or shim that runs Claude Code as a child process makes agent-director ignore every hook, recording `ad.hook.ignored` with the reason `pid_mismatch`, and every launch stays `pending`; replace such a launcher now.
59
59
  6. **agent-director's timing settings.** Before the AD directory move, read all nine keys of the `[tmux]` table of the existing installation’s `~/.agent-director/config.toml` (an explicit pre-upgrade path exception). If AD is already upgraded, use `~/.config/agent-director/config.toml` instead. A missing file, a missing key or `0` means the default (see [agent-director's timing settings](agent-director.md#agent-directors-timing-settings)). Also read that file’s `[pause] timeout_seconds` (30 s when the file or the key is missing). Record the effective values in the switch-over log. Confirm that the three windows, `pending_grace_seconds`, `stopping_window_seconds` and `starting_session_seconds`, are the values you intend and each is at or above its minimum: `starting_session_seconds` 60, `stopping_window_seconds` 30, and `pending_grace_seconds` the larger of 30 and ⌈(`create_timeout_ms` + `pipe_close_wait_ms`) / 1000⌉ + 20. A `pending_grace_seconds` above 540 s shortens agent-director's SessionStart wait to 540 s. In the same file, read `[defaults] expire_retention_days`: Phase 1 accepts 1 to 106751, and `0` or a missing key gives 31 days. A negative value or one above 106751 makes Phase 1 refuse its whole configuration with `ErrConfigMalformed`, from the install on: every store-backed verb, `serve` and the hooks. Correct such a value now, and record the effective value in the switch-over log.
60
60
  7. **The call timeout.** Always computing from this host's values, confirm that the `agent_director_call_timeout_ms` the persona configuration will carry (staged below; `60000` when it leaves the setting out) exceeds the need: the largest ceiling among the verbs CSCB calls, plus the 15 s margin (15000 ms). Record the computed need in the switch-over log. With Q, A, C, W and E the host's `query_timeout_ms`, `action_timeout_ms`, `create_timeout_ms`, `pipe_close_wait_ms` and `kill_exit_wait_ms`, and B its `sweep_budget_seconds` in ms, the ceilings, in ms, are:
61
61
  - `kill`: the larger of 2Q + 2A + E + 4W and 3Q + 2A + 5W;
@@ -67,8 +67,8 @@ Do this beforehand, with the old CSCB running and still installed as the global
67
67
 
68
68
  `expire` is not among them: CSCB never calls it. [Sizing the agent-director call timeout](agent-director.md#sizing-the-agent-director-call-timeout) works through examples.
69
69
  8. **Leftover sessions.** As the workers' user, on the pinned socket, compare `tmux ls` with `agent-director list`, and record in the switch-over log every `slack_bot_` session that no row names.
70
- 9. **Stage the new release without installing it.** Choose its exact version, record it in the switch-over log and confirm that it is available to install. Write the persona configuration, with `agent_director_call_timeout_ms`, in a separate file, never `config.json`, which the old CSCB reads. Prepare the Slack apps. Nothing is installed over the global package yet, so step 3's `stop --stop-bots` is the old version's own and reads the old, pre-persona `config.json` from the old state directory, `~/.claude/channels/slack`, where the old package keeps it. In the staged file, name each persona's `credentials_file` in that directory too, never under `~/.config/claude-slack-channel-bots` (step 7 says why). Steps 1, 2, 3, 5 and 6 of [Upgrading to personas](#upgrading-to-personas) belong here.
71
- 10. **Copies for rollback.** Keep copies of the pre-persona `config.json`, the crontable, the `/interject` callers (the host crontab's `curl` lines included), `access.json` and the Slack token environment variables the old CSCB uses. The old CSCB keeps `config.json`, the crontable and `access.json` in the old state directory, `~/.claude/channels/slack`: keep the copies outside it, because the first start in step 10 moves that directory. Record the old CSCB's exact version in the switch-over log beside them.
70
+ 9. **Stage the new release without installing it.** Choose its exact version, record it in the switch-over log and confirm that it is available to install. On an existing-persona host (0.11.0 or later), retain the current persona configuration and credentials files, persona keys, `working_directory`, `claude_config_dir`, `resume_enabled` and state paths; check the existing call timeout against item 7. Nothing is installed over the global package yet, so step 3 uses the old package's own stop command against its current files. The rest of this item applies only to a pre-persona host (0.10.x). Write the persona configuration, with `agent_director_call_timeout_ms`, in a separate file, never `config.json`, which the old CSCB reads. Prepare the Slack apps. Nothing is installed over the global package yet, so step 3's `stop --stop-bots` is the old version's own and reads the old, pre-persona `config.json` from the old state directory, `~/.claude/channels/slack`, where the old package keeps it. In the staged file, name each persona's `credentials_file` in that directory too, never under `~/.config/claude-slack-channel-bots` (step 7 says why). Steps 1, 2, 3, 5 and 6 of [Upgrading to personas](#upgrading-to-personas) belong here.
71
+ 10. **Copies for rollback.** On an existing-persona host (0.11.0 or later), back up the current persona `config.json`, credentials files, crontable, `/interject` callers and state files, including `config.json.last-applied` and `retired-keys.json` when present, outside the state directory. Record their current paths for restoration. On a pre-persona host (0.10.x), keep copies of the pre-persona `config.json`, the crontable, the `/interject` callers (the host crontab's `curl` lines included), `access.json` and the Slack token environment variables the old CSCB uses. The old CSCB keeps `config.json`, the crontable and `access.json` in the old state directory, `~/.claude/channels/slack`: keep the copies outside it, because the first start in step 10 moves that directory. Record the old CSCB's exact version in the switch-over log beside them.
72
72
  11. **The orchestrator prompt (operator action).** The shared orchestrator prompt's "ship now" wording may go out any time before the switch-over. The shared orchestrator prompt is the system prompt your orchestrator bots load, for example the file `append_system_prompt_file` names.
73
73
 
74
74
  #### Step 2: Disable CSCB's autostart
@@ -83,7 +83,7 @@ With the old CSCB still installed, run its own stop:
83
83
  claude-slack-channel-bots stop --stop-bots
84
84
  ```
85
85
 
86
- This is the old version's own `stop --stop-bots`, which reads the old, pre-persona `config.json` from the old state directory, `~/.claude/channels/slack`, where the old package keeps it, since nothing new is installed before step 7. An operator arriving from a startup refusal has first reinstalled the previous CSCB (see [Arrived here from a startup refusal?](#arrived-here-from-a-startup-refusal)), so this holds for them too. From here until step 10, no bot server runs.
86
+ On an existing-persona host (0.11.0 or later), this is the old package's own stop command, reading its current persona configuration and state paths. On a pre-persona host (0.10.x), this is the old version's own `stop --stop-bots`, which reads the old, pre-persona `config.json` from the old state directory, `~/.claude/channels/slack`, where the old package keeps it, since nothing new is installed before step 7. An operator arriving from a startup refusal has first reinstalled the previous CSCB (see [Arrived here from a startup refusal?](#arrived-here-from-a-startup-refusal)), so this holds for them too. From here until step 10, no bot server runs.
87
87
 
88
88
  #### Step 4: Wait for the old rows to end
89
89
 
@@ -125,26 +125,26 @@ A leftover that cannot be ended this way means no Phase 1 install: take step 8's
125
125
  ```sh
126
126
  bun install -g claude-slack-channel-bots@<the version recorded in step 1>
127
127
  ```
128
- 2. Put the persona configuration in place as `config.json`, in the old state directory, `~/.claude/channels/slack`, which the new CLI keeps using until the new CSCB's first start.
129
- 3. Write each persona's credentials file with the new CLI (see [`claude-slack-channel-bots credentials`](cli.md#claude-slack-channel-bots-credentials)), into the same directory: each `credentials_file` in the staged configuration names a path there.
130
- 4. Rewrite crontable targets and `/interject` callers to name personas, in the crontable in the same directory.
128
+ 2. On an existing-persona host (0.11.0 or later), retain its current persona configuration and paths. On a pre-persona host (0.10.x), put the persona configuration in place as `config.json`, in the old state directory, `~/.claude/channels/slack`, which the new CLI keeps using until the new CSCB's first start.
129
+ 3. On an existing-persona host, retain its credentials files and paths. On a pre-persona host (0.10.x), write each persona's credentials file with the new CLI (see [`claude-slack-channel-bots credentials`](cli.md#claude-slack-channel-bots-credentials)), into the same directory: each `credentials_file` in the staged configuration names a path there.
130
+ 4. On an existing-persona host, retain the current crontable and `/interject` callers. On a pre-persona host (0.10.x), rewrite crontable targets and `/interject` callers to name personas, in the crontable in the same directory.
131
131
  5. Run the new install check (see [Checking your agent-director install](agent-director.md#checking-your-agent-director-install)). An older CLI is refused by the 0.12.0 client; do not start CSCB until step 8 installs the required CLI.
132
132
 
133
- Steps 4, 7 and 8 of [Upgrading to personas](#upgrading-to-personas) belong here. From this step the new CSCB is deployed but not started.
133
+ On a pre-persona host (0.10.x), steps 4, 7 and 8 of [Upgrading to personas](#upgrading-to-personas) belong here. From this step the new CSCB is deployed but not started.
134
134
 
135
- **Steps 7 and 8, the call-timeout edit included, must not create `~/.config/claude-slack-channel-bots`.** The credentials command makes the directory of a `credentials_file` that is missing, so a path under `~/.config/claude-slack-channel-bots` creates it. The new CSCB's first start moves the old state directory to `~/.config/claude-slack-channel-bots` in one rename when that does not exist; when it exists, the start merges the old directory into it entry by entry, and a file that differs in the two is a conflict that leaves the old directory in place.
135
+ For a host whose state has not yet moved to the current directory, **steps 7 and 8, the call-timeout edit included, must not create `~/.config/claude-slack-channel-bots`.** The credentials command makes the directory of a `credentials_file` that is missing, so a path under `~/.config/claude-slack-channel-bots` creates it. The new CSCB's first start moves the old state directory to `~/.config/claude-slack-channel-bots` in one rename when that does not exist; when it exists, the start merges the old directory into it entry by entry, and a file that differs in the two is a conflict that leaves the old directory in place.
136
136
 
137
137
  #### Step 8: Install agent-director Phase 1
138
138
 
139
139
  1. **The go-ahead (operator action).** Confirm that the go-ahead for this host still stands, and record it in the switch-over log.
140
140
 
141
- **No go.** If there is no go-ahead, there is no Phase 1 install. Reinstall the previous CSCB, the version step 1 recorded, with the `config.json`, crontable, `/interject` callers, `access.json` and Slack token environment variables saved in step 1. Start it on the previous compatible CLI and re-enable its autostart (operator action). Every other agent this step already stopped is started again on the previous compatible CLI by its owner (operator action). The runbook stops there.
141
+ **No go.** If there is no go-ahead, there is no Phase 1 install. Reinstall the previous CSCB, the version step 1 recorded, and restore its version-appropriate files at the paths saved in step 1. On an existing-persona host (0.11.0 or later), restore the persona configuration, credentials files, crontable, `/interject` callers and saved state, including `config.json.last-applied` and `retired-keys.json` when backed up. On a pre-persona host (0.10.x), restore the `config.json`, crontable, `/interject` callers, `access.json` and Slack token environment variables saved in step 1. Start it on the previous compatible CLI and re-enable its autostart (operator action). Every other agent this step already stopped is started again on the previous compatible CLI by its owner (operator action). The runbook stops there.
142
142
  2. **Stop every other agent (operator action).** Otherwise, before the install, disable everything that starts agents and stop every other agent on the host: orchestrators' workers, hand-started sessions and sessions with an `agent-director serve`. Stop every long-running AD process and every caller, including TypeScript clients, before the installer runs. Use the still-installed CLI's `kill` and `find-missing` to reconcile stopped agents, using step 6's version-specific identifiers and flags. Confirm with `agent-director list` that all rows are non-live (`ended` or `missing`), with a read-only `tmux ls` that no agent session is left, and with process checks that all workers, callers, serves and launchers are stopped. Record it in the switch-over log. An unresolved live row or a process that cannot be stopped means "no go": do not run the installer, delete rows or edit SQL to fake a terminal state. No agent may run across the upgrade; the installer enforces this with `ErrAgentsLive`.
143
143
  3. **Back up the store and locate the original install.** Run from a shell agent-director did not start, in the directory the original installer ran in (or the same repository). Before the move, the default store is `~/.agent-director/state.db`. For an external `[store] db_path`, save `state.db`, `state.db-wal` and `state.db-shm` while all callers are stopped; the installer migrates an external store in place and rollback needs that copy. Keep the original installer flags and registrations in the switch-over log.
144
144
  4. **Install released agent-director 0.12.0 with its own installer.** Follow [agent-director's installer instructions](https://github.com/gabemahoney/agent-director/blob/v0.12.0/skills/install-agent-director/SKILL.md). Do not copy binaries by hand or create templates in the new directory first. The installer moves `~/.agent-director` to `~/.config/agent-director`, keeps the original as `~/.agent-director.pre-move-<timestamp>`, migrates the store to schema 9, and migrates config and templates. Preserve that kept directory until rollback is no longer wanted. Fix any manual PATH, hook or MCP entries the installer reports, including entries under other Claude config directories; confirm `agent-director version` reports 0.12.0 or later and the new `config_dir`.
145
145
  5. **Write the `[tmux]` values.** Right after the install, before the restarts that follow and so before the new CSCB starts, write any non-default `[tmux]` values you want into `~/.config/agent-director/config.toml`. A long-running agent-director process reads the file only when it starts.
146
146
  6. **Restart callers (operator action).** Restart every `agent-director serve` process and every caller, including TypeScript clients. Compare process start times to confirm that none is older than the install. Record the version and that result in the switch-over log.
147
- 7. **Check the settings again.** Read the nine timing settings and `[pause] timeout_seconds` again as in step 1, and record the effective values. Confirm them and the call timeout as in step 1; if the need has grown, raise `agent_director_call_timeout_ms` in `config.json` before step 10, in the old state directory's copy (step 7's warning applies). Confirm that `agent-director list` answers without `ErrConfigMalformed`.
147
+ 7. **Check the settings again.** Read the nine timing settings and `[pause] timeout_seconds` again as in step 1, and record the effective values. Confirm them and the call timeout as in step 1; if the need has grown, raise `agent_director_call_timeout_ms` in `config.json` before step 10, in the host's current configuration at its existing path (step 7's warning applies if the state directory has not yet moved). Confirm that `agent-director list` answers without `ErrConfigMalformed`.
148
148
 
149
149
  #### Step 9: Start the other agents again
150
150
 
@@ -154,12 +154,22 @@ Every other agent on the host is started again by its owner (operator action), w
154
154
 
155
155
  1. **The orchestrator prompt's worker cleanup (operator action).** Before the new CSCB starts, change worker cleanup in the shared orchestrator prompt, and in its source copy if you keep one, from row-delete cleanup to "kill, then leave the row". This change goes out in the same deploy as agent-director Phase 1. Kill-then-leave works on 0.10.0 too, so a rollback does not revert it.
156
156
  2. **Start the new CSCB**, then re-enable the host's autostart for CSCB (operator action):
157
+
158
+ On a host already running personas (0.11.0 or later), check each persona before starting:
159
+ ```sh
160
+ agent-director get --instance-id cscb_<key>
161
+ ```
162
+ For a resume, the row must show `state` as `ended` or `missing`, a non-empty `session_id`, and `transcript_status: present`. Keep the persona's key, `working_directory` and `claude_config_dir` unchanged, leave `resume_enabled` enabled, and confirm on the pinned tmux socket that no leftover session has the persona's session name. Record the results in the switch-over log.
163
+
164
+ Start the server:
157
165
  ```sh
158
166
  claude-slack-channel-bots start
159
167
  ```
160
- The first start has no last-applied record yet, so it checks `config.json`, records it and applies it; after that, edits wait until you apply them (see [Reload](reload.md#reload)). Each persona starts fresh once. Pre-persona rows are kept and never resumed.
168
+ On a host switching over from a pre-persona release (0.10.x), the first start has no last-applied record yet, so it checks `config.json`, records it and applies it; after that, edits wait until you apply them (see [Reload](reload.md#reload)). Each persona starts fresh once on that host. Pre-persona rows are kept and never resumed. On a host already running personas (0.11.0 or later), each persona resumes its conversation when the resume conditions above hold.
169
+
170
+ For each persona being resumed, check `server.log` for `spawnForPersona: attempting resume for …`, and record it in the switch-over log. agent-director 0.12.0 resumes only the current session: it no longer falls back to an older session's transcript when the current one is missing.
161
171
 
162
- This start also moves the old state directory: `~/.claude/channels/slack` is renamed to `~/.config/claude-slack-channel-bots`, a symbolic link to it is left at the old name, and the server logs one `[slack] state-migrate: moved the state directory from …` line to `~/.config/claude-slack-channel-bots/server.log`. Edit `config.json` and the other state files through `~/.config/claude-slack-channel-bots` after it.
172
+ A host already using the current state directory keeps that path; with `SLACK_STATE_DIR` set, nothing moves. On a pre-persona host (0.10.x) still using the old default path, this start also moves the old state directory: `~/.claude/channels/slack` is renamed to `~/.config/claude-slack-channel-bots`, a symbolic link to it is left at the old name, and the server logs one `[slack] state-migrate: moved the state directory from …` line to `~/.config/claude-slack-channel-bots/server.log`. Edit `config.json` and the other state files through `~/.config/claude-slack-channel-bots` after it. An existing-persona host still using an earlier default state directory follows the state-directory move described in [Migration](#migration); keep its configuration and credentials paths intact.
163
173
  3. **The post-install check (operator action).** Once every agent has been started again, confirm that `agent-director list --state pending` shows a `launch_started_at` on every row. Record the result in the switch-over log. A row without one is a human's to look at, and the persona whose row it is is held (see "A persona posts a *Held: launch start not recorded* notice" and "How a hold ends" in [Troubleshooting](troubleshooting.md#troubleshooting)).
164
174
 
165
175
  #### Step 11: Schedule the daily expire
@@ -227,9 +237,9 @@ As the workers' user, on the socket switch-over step 1 pinned, run a read-only `
227
237
  - **A leftover whose row is live:** end it with `agent-director kill --instance-id cscb_<key>`, and check its result; on an error, don't delete or respawn. When that `kill` is refused with "not this launch's session", handle it as "Operator actions" describes.
228
238
  - **A finished row's own leftover session:** handle it as "Operator actions" describes.
229
239
  - **An operator action refused inside the stopping window or the starting-session bound:** retry it once the longer of the two has passed. Read all nine timing settings again, as in switch-over step 1, for the two windows' values, and record them in the switch-over log. A plain `kill` never refuses for that reason.
230
- - **A leftover with no row:** handle it as in [switch-over step 5](#step-5-check-for-leftover-sessions), against the previous CSCB's session names (`slack_bot_<name>_<channel>` or `slack_bot_<channel ID>`) instead of the new personas'.
240
+ - **A leftover with no row:** handle it as in [switch-over step 5](#step-5-check-for-leftover-sessions), against the previous CSCB's session names: `slack_bot_<key>` for an existing-persona release (0.11.0 or later); for a pre-persona release (0.10.x), the previous CSCB's session names (`slack_bot_<name>_<channel>` or `slack_bot_<channel ID>`) instead of the new personas'.
231
241
 
232
- Check each result, then run `agent-director find-missing` and switch-over step 5's gone check again. Don't go on while a leftover remains: the previous CSCB's first start deletes every row without a `channel` label.
242
+ Check each result, then run `agent-director find-missing` and switch-over step 5's gone check again. Don't go on while a leftover remains. When rolling back to a pre-persona release (0.10.x), the previous CSCB's first start deletes every row without a `channel` label. This row-deletion warning does not apply when restoring an existing-persona release (0.11.0 or later).
233
243
 
234
244
  #### Step 6: Stop every agent and restore the previous agent-director
235
245
 
@@ -245,13 +255,13 @@ Revert the shared orchestrator prompt's "hold until after" wording that switch-o
245
255
 
246
256
  #### Step 8: Reinstall the previous CSCB
247
257
 
248
- 1. Move aside `config.json.last-applied` and `retired-keys.json` (see [Files beside the config file](reload.md#files-beside-the-config-file)), which are in `~/.config/claude-slack-channel-bots` after the new CSCB's first start.
258
+ 1. Move aside `config.json.last-applied` and `retired-keys.json` from the upgraded run (see [Files beside the config file](reload.md#files-beside-the-config-file)), which are in the host's current state directory after the new CSCB's first start. For rollback to an existing-persona release (0.11.0 or later), restore their switch-over step 1 copies along with the other saved state in item 3; do not discard the previous release's applied configuration or retired-key state.
249
259
  2. Reinstall the previous CSCB, the version switch-over step 1 recorded, or else the version the host ran before, without starting it:
250
260
  ```sh
251
261
  bun install -g claude-slack-channel-bots@<the previous version>
252
262
  ```
253
- 3. Put back what switch-over step 1 saved: the pre-persona `config.json`, the crontable, the `/interject` callers (the host crontab's `curl` lines included), `access.json` and the Slack token environment variables. Put `config.json`, the crontable and `access.json` back in the old state directory, by its old name, `~/.claude/channels/slack`: after the new CSCB's first start that name is a symbolic link to `~/.config/claude-slack-channel-bots`, and the previous CSCB reads its files through the link. Leave the link in place, and do not make a directory at the old name.
254
- 4. Where switch-over step 1's copy of a file is missing, the operator rebuilds the pre-persona file by hand from the persona configuration, reversing the manual conversion in [Upgrading to personas](#upgrading-to-personas). No tooling does this: CSCB ships no conversion tooling in either direction.
263
+ 3. For rollback to an existing-persona release (0.11.0 or later), restore the saved persona configuration, credentials files, crontable, `/interject` callers and state files, including the last-applied and retired-key records when backed up, at the paths recorded in switch-over step 1. Keep the persona keys, `working_directory`, `claude_config_dir` and `resume_enabled` unchanged. For rollback to a pre-persona release (0.10.x), put back what switch-over step 1 saved: the pre-persona `config.json`, the crontable, the `/interject` callers (the host crontab's `curl` lines included), `access.json` and the Slack token environment variables. Put `config.json`, the crontable and `access.json` back in the old state directory, by its old name, `~/.claude/channels/slack`: after the new CSCB's first start that name is a symbolic link to `~/.config/claude-slack-channel-bots`, and the previous CSCB reads its files through the link. Leave the link in place, and do not make a directory at the old name.
264
+ 4. The following manual conversion applies only when rolling back to a pre-persona release (0.10.x). Where switch-over step 1's copy of a file is missing, the operator rebuilds the pre-persona file by hand from the persona configuration, reversing the manual conversion in [Upgrading to personas](#upgrading-to-personas). No tooling does this: CSCB ships no conversion tooling in either direction.
255
265
 
256
266
  #### Step 9: Start the previous CSCB
257
267
 
@@ -17,7 +17,7 @@ These top-level fields apply to the whole server. A confirmed change to one take
17
17
  | `mcp_config_path` | string | `~/.claude/slack-mcp.json` | Path to the MCP config file passed to Claude Code when launching managed sessions. |
18
18
  | `append_system_prompt_file` | string | — | Path to a file appended to every managed session's system prompt via `--append-system-prompt-file`. Missing file silently skipped. See `skills/EXAMPLE_CLAUDE.md` for a template. |
19
19
  | `system_prompt_mode` | string | `"append"` | Controls how `append_system_prompt_file` is applied. `"append"`: the custom prompt file is appended on top of `CLAUDE.md` (default, current behavior). `"none"`: only `CLAUDE.md` is used; `append_system_prompt_file` is ignored even if set. Use `"none"` when the project's `CLAUDE.md` already contains everything the bot needs. |
20
- | `fresh_system_prompt` | boolean | `true` | When `true` (default), every bot launches with `--system-prompt-snapshot off`, so a restarted or resumed bot loads the current system prompt file and `CLAUDE.md` and keeps its conversation, whatever `system_prompt_mode` is. When `false`, the flag is omitted. A change takes effect at the next server start. Needs a Claude Code that has `--system-prompt-snapshot` (confirmed on 2.1.296); on an older one set it to `false`. A bot keeps the launch arguments it was started with on every resume, so a change reaches a bot only when it next starts a new conversation; a `clean_restart` that resumes conversations does not apply it to those bots. |
20
+ | `fresh_system_prompt` | boolean | `true` | When `true` (default), every bot launches with `--system-prompt-snapshot off`, so a restarted or resumed bot loads the current system prompt file and `CLAUDE.md` and keeps its conversation, whatever `system_prompt_mode` is. When `false`, the flag is omitted. A change takes effect at the next server start. Needs a Claude Code that has `--system-prompt-snapshot` (confirmed on 2.1.280); on an older one set it to `false`. A bot keeps the launch arguments it was started with on every resume, so a change reaches a bot only when it next starts a new conversation; a `clean_restart` that resumes conversations does not apply it to those bots. |
21
21
  | `cozempic_prescription` | string | `"standard"` | Cozempic cleaning intensity before resume. Valid values: `gentle`, `standard`, `aggressive`. Has no effect if cozempic is not installed. |
22
22
  | `message_archive_db` | string | — | Path to a SQLite DB where every inbound Slack message is archived in real time. Parent directories are created if missing; schema is initialized on first open. Compatible with the `archive-messages.py` backfill script — both can write concurrently. Each channel's name is looked up through the receiving persona's Slack app, which needs the `channels:read` and `groups:read` bot scopes that the shipped `slack-app-manifest.yml` grants. An app created from an earlier manifest stores the channel ID instead, until both scopes are added and the app is re-installed; the `debug-slack-channel-bots` skill has the steps under "The message archive shows channel IDs". A DM's rows keep the DM's `D…` ID whatever the scopes, as a DM has no name; a group DM's rows keep its ID too. Feature is disabled when absent. |
23
23
  | `claude_config_dir` | string | — | Default Claude on-disk config directory for every persona. When a persona has one (its own or this default), its session launches with `CLAUDE_CONFIG_DIR='<resolved-path>'` so the bot authenticates against a specific account. `~` is expanded and the path is resolved to absolute. A persona's own `claude_config_dir` overrides this value. When neither is set, Claude's own default applies. Must be non-empty when set. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-slack-channel-bots",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
4
4
  "description": "Run several Claude Code personas, each its own Slack app, from one server via Socket Mode",
5
5
  "type": "module",
6
6
  "bin": {