slack-term 1.37.1 → 1.39.0

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
@@ -91,7 +91,7 @@ slack search "deploy" --count 50
91
91
  slack send "#general" "Hello team"
92
92
  # Prints who you're acting as (From: @handle (Uxxxx) — Workspace) + a destination
93
93
  # preview + confirm code; rerun with --code=<code> to actually send. Every gated write
94
- # (send/edit/delete/upload/schedule/channel create/drafts) shows that From: line and
94
+ # (send/edit/delete/upload/schedule/channel create/lists/drafts) shows that From: line and
95
95
  # binds it into the code, so a profile switch mid-flow invalidates it instead of acting
96
96
  # as the wrong account.
97
97
  slack send "#general" "Hello team" --code=<code>
@@ -277,6 +277,59 @@ Notes:
277
277
  are **never** cached — they are exactly the values that change, and Slack's search index
278
278
  already lags. A corrupt or unwritable cache is ignored and the command runs uncached.
279
279
 
280
+ ### pinlog — a pinned status board that keeps a log
281
+
282
+ A **pinlog** is one pinned top-level message that always holds the *current* state
283
+ (HEAD), plus a thread under it with one short reply per change (the log). The HEAD is
284
+ **edited in place, which is silent**; each log reply **notifies**. People who want the
285
+ state read the pin; people who want to know what changed follow the thread. Good for
286
+ anything people come back to: blocker boards, release readiness, incidents — one board
287
+ per topic.
288
+
289
+ ```bash
290
+ slack pinlog ls "#gtm" # boards in a channel (found by their footer)
291
+ slack pinlog get <board> # state + log (--json for one object)
292
+ slack pinlog new "#gtm" "販売ブロッカー\n1. 見積テンプレ — 未" ["why this board exists"]
293
+ slack pinlog set <board> "<the WHOLE new state>" "見積テンプレ: 未 → 済"
294
+ slack pinlog set <board> --file board.md "見積テンプレ: 未 → 済" # state from a file (- = stdin)
295
+ slack pinlog note <board> "まだ法務待ち — 再送済" # reason only, state unchanged
296
+ ```
297
+
298
+ `<board>` is the board's permalink, `#chan:ts`, or the `C…:ts` id `new` prints. There
299
+ are no names and nothing is stored locally: a board *is* its Slack message, so the same
300
+ command works from any machine. Each verb takes only its own kind of target — `new` and
301
+ `ls` a channel, the rest a board — so a pasted channel can never turn an intended update
302
+ into a second board.
303
+
304
+ - Every HEAD ends with a footer, `_Pinlog · 最終更新 2026-10-08 15:10 JST · 更新はスレッドに_`,
305
+ refreshed on each update. `ls` finds boards by it, and `set` **refuses** a message
306
+ without it, so a wrong link cannot overwrite an ordinary message.
307
+ To turn an existing hand-run board into a pinlog on purpose, pass `set --adopt` once.
308
+ - `new`, `set` and `note` use the same two-step `--code` gate as `send`/`edit`, and the
309
+ preview shows the situation, not just your text: `new` lists boards already in the
310
+ channel (usually a sign you meant `set`), and `set` shows the current state next to
311
+ the new one. The `set` code covers the current state, so if someone else changed the
312
+ board after your preview, your code stops matching and you re-read first.
313
+ - **`set` order:** the state edit first, then the reason reply. If the edit fails, **no**
314
+ reason is posted. If the reply fails, the command exits 1, says the state *is* updated,
315
+ and prints the exact retry (`slack pinlog note <board> '…' --code=…`).
316
+ A failure that *may* have landed (network error, Slack `internal_error`/`fatal_error`)
317
+ is reported as `UNKNOWN`, not `NOT posted`, with the `get`/`ls` command to check
318
+ first, because a blind retry would post a second board or a second notifying reply.
319
+ A HEAD over Slack's 40,000-character limit is refused before posting, because Slack
320
+ would truncate the footer.
321
+ - `new` without the pin scope still creates the board: it says `NOT pinned`, prints
322
+ the `slack pinlog pin <board>` command, and exits 0, because retrying `new` would make a
323
+ second board. Pinning needs `pins:write` on the token you act with.
324
+ - `--as-bot` acts as the bot for reads and writes. Slack lets a token edit only its own
325
+ messages, so a board the bot created must be updated `--as-bot`.
326
+ - During quiet hours (JST 23:00–08:00) the preview shows the quiet-hours line, and the
327
+ confirmed run warns that the reply notified. It warns but does not block.
328
+ - Text is posted as-is (plain mrkdwn, no blocks) so the footer reads back verbatim;
329
+ `@handle`s are **not** converted — write `<@U…>` if you need a real mention.
330
+ - Stateless: the only local files are short-lived per-board locks, held while a `set` runs,
331
+ so two writers on one machine cannot interleave.
332
+
280
333
  ### tail — real-time message stream
281
334
 
282
335
  `slack tail` polls a channel every 3 seconds (configurable via `--interval`) and
package/SKILL.md CHANGED
@@ -120,7 +120,7 @@ plus `[as bot]` under `--as-bot`) and the resolved destination (`→ ... — THR
120
120
  `→ ... — NEW top-level message`); verify both before re-running with `--code`.
121
121
 
122
122
  **Every** gated write opens its preview with that same `From:` line — `send`, `edit`,
123
- `delete`, `upload`, `schedule send`, `schedule rm`, `channel create`, `drafts edit`,
123
+ `delete`, `upload`, `schedule send`, `schedule rm`, `channel create`, `lists create/add/set/share`, `drafts edit`,
124
124
  `drafts delete` — and the identity is part of the confirm hash: switching
125
125
  profile/token between preview and confirm invalidates the code instead of acting as
126
126
  someone else. It matters most on `schedule send`, where the message goes out later,
@@ -202,6 +202,22 @@ slack sent --cwd . --json # everything posted from this repo,
202
202
  Read-only and token-free. `SLACK_TERM_ATTRIBUTION=off` disables both the log and the
203
203
  metadata; `SLACK_TERM_AGENT_SESSION` / `_CLI` / `_PID` override what is detected.
204
204
 
205
+ ### pinlog — a pinned board: HEAD = current state, thread = log
206
+
207
+ ```bash
208
+ slack pinlog ls "#chan" # boards in a channel
209
+ slack pinlog get <board> # state + log
210
+ slack pinlog new "#chan" --file board.md "<why>" --as-bot # → board id C…:ts; pins it
211
+ slack pinlog set <board> --file board.md "<what changed>" --as-bot
212
+ slack pinlog note <board> "<progress, state unchanged>" --as-bot
213
+ ```
214
+
215
+ `<board>` = permalink, `#chan:ts` or `C…:ts` — no names, nothing local. The state is edited
216
+ in place (silent); `set` and `note` each post ONE thread reply (notifies). Always pass the
217
+ WHOLE new state, keep it true, and post only for real changes. Writes need `--code` (preview
218
+ first). If the edit fails, no reply is posted; if the reply fails, the command prints the
219
+ `note` retry. A board the bot created must be changed `--as-bot`.
220
+
205
221
  ### todo — tasks as reactions
206
222
 
207
223
  A task is any message carrying the marker reaction 📌 `:pushpin:`. Progress lives in a
@@ -280,6 +296,7 @@ Under **User Token Scopes**:
280
296
  - `users:read` — resolve display names
281
297
  - `chat:write` — send messages
282
298
  - `reactions:write` — add/remove reactions (`react`)
299
+ - `pins:write` — pin a board (`pinlog new` / `pinlog pin`)
283
300
 
284
301
  > **Token-type gotcha:** the CLI uses the **user token** (`xoxp-`) by default, so scopes
285
302
  > must be under **User Token Scopes**. Adding `reactions:write` only to *Bot* Token Scopes