slack-axi 0.1.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/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/bin/slack-axi.d.ts +2 -0
- package/dist/bin/slack-axi.js +4 -0
- package/dist/bin/slack-axi.js.map +1 -0
- package/dist/src/auth/setup.d.ts +39 -0
- package/dist/src/auth/setup.js +119 -0
- package/dist/src/auth/setup.js.map +1 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +66 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/commands/auth.d.ts +2 -0
- package/dist/src/commands/auth.js +192 -0
- package/dist/src/commands/auth.js.map +1 -0
- package/dist/src/commands/cache.d.ts +2 -0
- package/dist/src/commands/cache.js +25 -0
- package/dist/src/commands/cache.js.map +1 -0
- package/dist/src/commands/catchup.d.ts +2 -0
- package/dist/src/commands/catchup.js +171 -0
- package/dist/src/commands/catchup.js.map +1 -0
- package/dist/src/commands/channels.d.ts +6 -0
- package/dist/src/commands/channels.js +147 -0
- package/dist/src/commands/channels.js.map +1 -0
- package/dist/src/commands/cite.d.ts +2 -0
- package/dist/src/commands/cite.js +38 -0
- package/dist/src/commands/cite.js.map +1 -0
- package/dist/src/commands/doctor.d.ts +2 -0
- package/dist/src/commands/doctor.js +46 -0
- package/dist/src/commands/doctor.js.map +1 -0
- package/dist/src/commands/home.d.ts +6 -0
- package/dist/src/commands/home.js +37 -0
- package/dist/src/commands/home.js.map +1 -0
- package/dist/src/commands/read.d.ts +4 -0
- package/dist/src/commands/read.js +178 -0
- package/dist/src/commands/read.js.map +1 -0
- package/dist/src/commands/search.d.ts +2 -0
- package/dist/src/commands/search.js +135 -0
- package/dist/src/commands/search.js.map +1 -0
- package/dist/src/commands/setup.d.ts +2 -0
- package/dist/src/commands/setup.js +21 -0
- package/dist/src/commands/setup.js.map +1 -0
- package/dist/src/commands/write.d.ts +4 -0
- package/dist/src/commands/write.js +148 -0
- package/dist/src/commands/write.js.map +1 -0
- package/dist/src/config.d.ts +71 -0
- package/dist/src/config.js +184 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/flags.d.ts +11 -0
- package/dist/src/flags.js +21 -0
- package/dist/src/flags.js.map +1 -0
- package/dist/src/meta.d.ts +3 -0
- package/dist/src/meta.js +17 -0
- package/dist/src/meta.js.map +1 -0
- package/dist/src/output.d.ts +25 -0
- package/dist/src/output.js +52 -0
- package/dist/src/output.js.map +1 -0
- package/dist/src/session.d.ts +17 -0
- package/dist/src/session.js +25 -0
- package/dist/src/session.js.map +1 -0
- package/dist/src/slack/cache.d.ts +40 -0
- package/dist/src/slack/cache.js +161 -0
- package/dist/src/slack/cache.js.map +1 -0
- package/dist/src/slack/client.d.ts +21 -0
- package/dist/src/slack/client.js +39 -0
- package/dist/src/slack/client.js.map +1 -0
- package/dist/src/slack/errors.d.ts +14 -0
- package/dist/src/slack/errors.js +54 -0
- package/dist/src/slack/errors.js.map +1 -0
- package/dist/src/slack/format.d.ts +8 -0
- package/dist/src/slack/format.js +20 -0
- package/dist/src/slack/format.js.map +1 -0
- package/dist/src/slack/permalink.d.ts +7 -0
- package/dist/src/slack/permalink.js +10 -0
- package/dist/src/slack/permalink.js.map +1 -0
- package/dist/src/slack/resolve.d.ts +22 -0
- package/dist/src/slack/resolve.js +118 -0
- package/dist/src/slack/resolve.js.map +1 -0
- package/dist/src/slack/scopes.d.ts +7 -0
- package/dist/src/slack/scopes.js +23 -0
- package/dist/src/slack/scopes.js.map +1 -0
- package/dist/src/slack/threads.d.ts +24 -0
- package/dist/src/slack/threads.js +63 -0
- package/dist/src/slack/threads.js.map +1 -0
- package/dist/src/slack/time.d.ts +46 -0
- package/dist/src/slack/time.js +156 -0
- package/dist/src/slack/time.js.map +1 -0
- package/dist/src/slack/ts.d.ts +5 -0
- package/dist/src/slack/ts.js +14 -0
- package/dist/src/slack/ts.js.map +1 -0
- package/package.json +41 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jarvus Innovations
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# slack-axi
|
|
2
|
+
|
|
3
|
+
An [AXI](https://github.com/JarvusInnovations) (Agent eXperience Interface) CLI for Slack — built for
|
|
4
|
+
agents to drive over the shell. Read, search, sweep, and safely draft Slack with token-efficient
|
|
5
|
+
[TOON](https://toonformat.dev/) output. It replaces the flaky Slack MCP with a stored long-lived user
|
|
6
|
+
token (no logouts, works headless), human date ranges (no epoch math), threads inlined, and
|
|
7
|
+
ready-to-cite permalinks.
|
|
8
|
+
|
|
9
|
+
## Why
|
|
10
|
+
|
|
11
|
+
The Slack MCP it replaces failed in recurring ways; slack-axi fixes each at the root:
|
|
12
|
+
|
|
13
|
+
| Pain | Fix |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| Constant logouts / breaks headless | long-lived `xoxp` user token, resolvable from env — no session, no daemon |
|
|
16
|
+
| Can't find private channels / group DMs | `channels` lists all conversation types you belong to by default |
|
|
17
|
+
| Wrong-year timestamps | human dates in; the resolved range is **echoed back with explicit year + tz** |
|
|
18
|
+
| Oldest-first / dropped messages | reads paginate to completion with a `complete:` marker; windows tile losslessly |
|
|
19
|
+
| Threads are a second call | thread replies are inlined under their parent |
|
|
20
|
+
| Hand-built permalinks | a compact `ts` handle per row + a stateless `cite` command |
|
|
21
|
+
| name ↔ id friction | `#name`, bare name, or id accepted everywhere |
|
|
22
|
+
|
|
23
|
+
See [`specs/`](specs/) for the full specification and [`specs/motivation.md`](specs/motivation.md) for
|
|
24
|
+
the evidence behind each fix.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
npm install -g slack-axi # or: bun add -g slack-axi
|
|
30
|
+
slack-axi auth setup # guided: create a Slack app from a manifest, then paste the token
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`auth setup` generates an app manifest with all required user-token scopes pre-filled (and token
|
|
34
|
+
rotation disabled), walks you through creating + installing the app, then `auth login --token xoxp-…`.
|
|
35
|
+
Run `slack-axi doctor` to verify auth and scope coverage.
|
|
36
|
+
|
|
37
|
+
## Commands
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
slack-axi # home: active workspace + channel count
|
|
41
|
+
slack-axi channels [--match q] [--type ...] [--all] # discover (all conversation types)
|
|
42
|
+
slack-axi dms # DMs + group DMs
|
|
43
|
+
slack-axi members <channel> # channel members
|
|
44
|
+
slack-axi read <channel> [--since 7d | --from <d> --to <d>] [--threads ...] # the primary verb
|
|
45
|
+
slack-axi thread <channel> <ts> # one thread, fully
|
|
46
|
+
slack-axi search "<query>" [--in #c] [--from @u] [--with @u] [--after <d>] # find a thing
|
|
47
|
+
slack-axi catchup [--since 1d] [--match q] [--in ...] # scoped multi-channel sweep
|
|
48
|
+
slack-axi catchup --every 1w … # plan a month+ catch-up as weekly batches
|
|
49
|
+
slack-axi cite <channel> <ts…> # permalinks + the { channel, ts, permalink } citation shape
|
|
50
|
+
slack-axi react <channel> <ts> :emoji: # reactions:write
|
|
51
|
+
slack-axi draft <channel> "<text>" [--reply <ts>] # prepare a message (does NOT send)
|
|
52
|
+
slack-axi draft send <id> # the explicit, separate step that posts
|
|
53
|
+
slack-axi setup hooks # install the SessionStart ambient-context hook
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Every command supports `--help`. Channel args accept `#name` / name / id. Output is TOON with
|
|
57
|
+
contextual `help[]` next steps; errors are structured with actionable suggestions.
|
|
58
|
+
|
|
59
|
+
### Capabilities
|
|
60
|
+
|
|
61
|
+
Read + **safe-draft**: full read/search/sweep, plus reactions and message *drafts you approve*. Nothing
|
|
62
|
+
posts without an explicit `draft send`.
|
|
63
|
+
|
|
64
|
+
## Development
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
bun install
|
|
68
|
+
bun run build # tsc → dist/
|
|
69
|
+
bun test # vitest (time/window math is unit-tested)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The project is spec-driven — specs in [`specs/`](specs/) are the source of truth; work is tracked as
|
|
73
|
+
plans in [`plans/`](plans/). Requires Node ≥ 20 (built/run with bun; published to run under node).
|
|
74
|
+
|
|
75
|
+
## License
|
|
76
|
+
|
|
77
|
+
MIT © Jarvus Innovations
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack-axi.js","sourceRoot":"","sources":["../../bin/slack-axi.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** Where to start "Create an app from a manifest". */
|
|
2
|
+
export declare const NEW_APP_URL = "https://api.slack.com/apps?new_app=1";
|
|
3
|
+
interface StepState {
|
|
4
|
+
done: boolean;
|
|
5
|
+
at?: string;
|
|
6
|
+
}
|
|
7
|
+
interface SetupState {
|
|
8
|
+
version: number;
|
|
9
|
+
app_name: string;
|
|
10
|
+
steps: {
|
|
11
|
+
app_created: StepState;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export declare function readSetupState(): SetupState;
|
|
15
|
+
export declare function markAppCreated(): void;
|
|
16
|
+
export declare function resetSetup(): void;
|
|
17
|
+
export declare function setAppName(name: string): void;
|
|
18
|
+
export interface SetupProgress {
|
|
19
|
+
appCreated: boolean;
|
|
20
|
+
tokenStored: boolean;
|
|
21
|
+
done: number;
|
|
22
|
+
total: number;
|
|
23
|
+
complete: boolean;
|
|
24
|
+
/** The next incomplete step key, or undefined when complete. */
|
|
25
|
+
next?: "app_created" | "token_stored";
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* token_stored is derived from a successful `auth login` (a stored workspace), never confirmed
|
|
29
|
+
* manually. A stored token is proof the app was created and installed, so it subsumes the
|
|
30
|
+
* app_created waypoint: once a token exists, setup is complete regardless of the manual confirm.
|
|
31
|
+
*/
|
|
32
|
+
export declare function setupProgress(): SetupProgress;
|
|
33
|
+
/** Build a Slack app manifest (YAML) pre-filled with the user-token scopes slack-axi needs. */
|
|
34
|
+
export declare function buildManifest(appName: string): string;
|
|
35
|
+
/** Write the manifest YAML to the config dir; returns its path. */
|
|
36
|
+
export declare function writeManifestFile(appName: string): string;
|
|
37
|
+
/** Write a local setup.html with the new-app link and a copy-paste manifest box; returns its path. */
|
|
38
|
+
export declare function writeSetupHtmlFile(appName: string): string;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { listWorkspaceIds, manifestPath, setupHtmlPath, setupStatePath, } from "../config.js";
|
|
4
|
+
import { REQUIRED_SCOPES } from "../slack/scopes.js";
|
|
5
|
+
/** Where to start "Create an app from a manifest". */
|
|
6
|
+
export const NEW_APP_URL = "https://api.slack.com/apps?new_app=1";
|
|
7
|
+
const DEFAULT_APP_NAME = "slack-axi";
|
|
8
|
+
function defaultState() {
|
|
9
|
+
return { version: 1, app_name: DEFAULT_APP_NAME, steps: { app_created: { done: false } } };
|
|
10
|
+
}
|
|
11
|
+
export function readSetupState() {
|
|
12
|
+
if (!existsSync(setupStatePath()))
|
|
13
|
+
return defaultState();
|
|
14
|
+
try {
|
|
15
|
+
const parsed = JSON.parse(readFileSync(setupStatePath(), "utf-8"));
|
|
16
|
+
return {
|
|
17
|
+
version: parsed.version ?? 1,
|
|
18
|
+
app_name: parsed.app_name ?? DEFAULT_APP_NAME,
|
|
19
|
+
steps: { app_created: parsed.steps?.app_created ?? { done: false } },
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return defaultState();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function writeState(state) {
|
|
27
|
+
mkdirSync(dirname(setupStatePath()), { recursive: true });
|
|
28
|
+
writeFileSync(setupStatePath(), `${JSON.stringify(state, null, 2)}\n`);
|
|
29
|
+
}
|
|
30
|
+
export function markAppCreated() {
|
|
31
|
+
const state = readSetupState();
|
|
32
|
+
state.steps.app_created = { done: true, at: new Date().toISOString() };
|
|
33
|
+
writeState(state);
|
|
34
|
+
}
|
|
35
|
+
export function resetSetup() {
|
|
36
|
+
writeState(defaultState());
|
|
37
|
+
}
|
|
38
|
+
export function setAppName(name) {
|
|
39
|
+
const state = readSetupState();
|
|
40
|
+
state.app_name = name;
|
|
41
|
+
writeState(state);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* token_stored is derived from a successful `auth login` (a stored workspace), never confirmed
|
|
45
|
+
* manually. A stored token is proof the app was created and installed, so it subsumes the
|
|
46
|
+
* app_created waypoint: once a token exists, setup is complete regardless of the manual confirm.
|
|
47
|
+
*/
|
|
48
|
+
export function setupProgress() {
|
|
49
|
+
const appCreated = readSetupState().steps.app_created.done;
|
|
50
|
+
const tokenStored = listWorkspaceIds().length > 0;
|
|
51
|
+
if (tokenStored) {
|
|
52
|
+
return { appCreated: true, tokenStored, done: 2, total: 2, complete: true, next: undefined };
|
|
53
|
+
}
|
|
54
|
+
const done = appCreated ? 1 : 0;
|
|
55
|
+
return { appCreated, tokenStored, done, total: 2, complete: false, next: appCreated ? "token_stored" : "app_created" };
|
|
56
|
+
}
|
|
57
|
+
/** Build a Slack app manifest (YAML) pre-filled with the user-token scopes slack-axi needs. */
|
|
58
|
+
export function buildManifest(appName) {
|
|
59
|
+
const scopeLines = REQUIRED_SCOPES.map((s) => ` - ${s}`).join("\n");
|
|
60
|
+
return `display_information:
|
|
61
|
+
name: ${appName}
|
|
62
|
+
description: Agent-ergonomic Slack CLI — read, search, and draft
|
|
63
|
+
oauth_config:
|
|
64
|
+
scopes:
|
|
65
|
+
user:
|
|
66
|
+
${scopeLines}
|
|
67
|
+
settings:
|
|
68
|
+
org_deploy_enabled: false
|
|
69
|
+
socket_mode_enabled: false
|
|
70
|
+
token_rotation_enabled: false
|
|
71
|
+
`;
|
|
72
|
+
}
|
|
73
|
+
/** Write the manifest YAML to the config dir; returns its path. */
|
|
74
|
+
export function writeManifestFile(appName) {
|
|
75
|
+
const path = manifestPath();
|
|
76
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
77
|
+
writeFileSync(path, buildManifest(appName));
|
|
78
|
+
return path;
|
|
79
|
+
}
|
|
80
|
+
/** Write a local setup.html with the new-app link and a copy-paste manifest box; returns its path. */
|
|
81
|
+
export function writeSetupHtmlFile(appName) {
|
|
82
|
+
const path = setupHtmlPath();
|
|
83
|
+
const manifest = buildManifest(appName);
|
|
84
|
+
const escaped = manifest.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
85
|
+
const html = `<!doctype html>
|
|
86
|
+
<html lang="en">
|
|
87
|
+
<head>
|
|
88
|
+
<meta charset="utf-8">
|
|
89
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
90
|
+
<title>slack-axi setup</title>
|
|
91
|
+
<style>
|
|
92
|
+
body { font: 15px/1.5 system-ui, sans-serif; max-width: 760px; margin: 2rem auto; padding: 0 1rem; }
|
|
93
|
+
ol { padding-left: 1.2rem; } li { margin: 0.6rem 0; }
|
|
94
|
+
a.btn { display: inline-block; background: #4a154b; color: #fff; padding: 0.5rem 0.9rem; border-radius: 6px; text-decoration: none; }
|
|
95
|
+
textarea { width: 100%; height: 22rem; font-family: ui-monospace, monospace; font-size: 13px; }
|
|
96
|
+
code { background: #f2f2f2; padding: 0.1rem 0.3rem; border-radius: 4px; }
|
|
97
|
+
button { font: inherit; padding: 0.35rem 0.7rem; }
|
|
98
|
+
</style>
|
|
99
|
+
</head>
|
|
100
|
+
<body>
|
|
101
|
+
<h1>slack-axi setup</h1>
|
|
102
|
+
<ol>
|
|
103
|
+
<li><a class="btn" href="${NEW_APP_URL}" target="_blank" rel="noopener">Create a Slack app</a> — choose <strong>“From an app manifest”</strong>, pick your workspace.</li>
|
|
104
|
+
<li>Paste this manifest (all user-token scopes pre-filled; token rotation disabled):
|
|
105
|
+
<p><button onclick="navigator.clipboard.writeText(document.getElementById('m').value)">Copy manifest</button></p>
|
|
106
|
+
<textarea id="m" readonly>${escaped}</textarea>
|
|
107
|
+
</li>
|
|
108
|
+
<li>On the app’s <strong>OAuth & Permissions</strong> page, click <strong>Install to Workspace</strong> and authorize.</li>
|
|
109
|
+
<li>Copy the <strong>User OAuth Token</strong> (<code>xoxp-…</code>) and run:<br>
|
|
110
|
+
<code>slack-axi auth login --token xoxp-…</code></li>
|
|
111
|
+
</ol>
|
|
112
|
+
</body>
|
|
113
|
+
</html>
|
|
114
|
+
`;
|
|
115
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
116
|
+
writeFileSync(path, html);
|
|
117
|
+
return path;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/auth/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const TOP_HELP = "usage: slack-axi [command] [args] [flags]\ncommands[14]:\n (none)=home, auth, doctor, channels, dms, members, read, thread, cite, search, catchup, react, draft, setup\nflags[2]:\n --team <id> (per-command), --help, -v/--version\nexamples:\n slack-axi channels --match bid\n slack-axi read #bid-rtd-analytics --since 7d\n slack-axi catchup --from 2026-05-01 --to 2026-06-07 --every 1w --match bid\n slack-axi react #eng <ts> :eyes:\n slack-axi draft #eng \"message\" (then: slack-axi draft send <id>)";
|
|
2
|
+
export declare function main(): Promise<void>;
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { runAxiCli } from "axi-sdk-js";
|
|
2
|
+
import { authCommand, AUTH_HELP } from "./commands/auth.js";
|
|
3
|
+
import { cacheCommand, CACHE_HELP } from "./commands/cache.js";
|
|
4
|
+
import { channelsCommand, CHANNELS_HELP, dmsCommand, DMS_HELP, membersCommand, MEMBERS_HELP, } from "./commands/channels.js";
|
|
5
|
+
import { catchupCommand, CATCHUP_HELP } from "./commands/catchup.js";
|
|
6
|
+
import { citeCommand, CITE_HELP } from "./commands/cite.js";
|
|
7
|
+
import { doctorCommand, DOCTOR_HELP } from "./commands/doctor.js";
|
|
8
|
+
import { homeCommand } from "./commands/home.js";
|
|
9
|
+
import { readCommand, READ_HELP, threadCommand, THREAD_HELP } from "./commands/read.js";
|
|
10
|
+
import { searchCommand, SEARCH_HELP } from "./commands/search.js";
|
|
11
|
+
import { setupCommand, SETUP_HELP } from "./commands/setup.js";
|
|
12
|
+
import { draftCommand, DRAFT_HELP, reactCommand, REACT_HELP } from "./commands/write.js";
|
|
13
|
+
import { DESCRIPTION, readVersion } from "./meta.js";
|
|
14
|
+
export const TOP_HELP = `usage: slack-axi [command] [args] [flags]
|
|
15
|
+
commands[14]:
|
|
16
|
+
(none)=home, auth, doctor, channels, dms, members, read, thread, cite, search, catchup, react, draft, setup
|
|
17
|
+
flags[2]:
|
|
18
|
+
--team <id> (per-command), --help, -v/--version
|
|
19
|
+
examples:
|
|
20
|
+
slack-axi channels --match bid
|
|
21
|
+
slack-axi read #bid-rtd-analytics --since 7d
|
|
22
|
+
slack-axi catchup --from 2026-05-01 --to 2026-06-07 --every 1w --match bid
|
|
23
|
+
slack-axi react #eng <ts> :eyes:
|
|
24
|
+
slack-axi draft #eng "message" (then: slack-axi draft send <id>)`;
|
|
25
|
+
const COMMAND_HELP = {
|
|
26
|
+
auth: AUTH_HELP,
|
|
27
|
+
doctor: DOCTOR_HELP,
|
|
28
|
+
channels: CHANNELS_HELP,
|
|
29
|
+
dms: DMS_HELP,
|
|
30
|
+
members: MEMBERS_HELP,
|
|
31
|
+
cache: CACHE_HELP,
|
|
32
|
+
read: READ_HELP,
|
|
33
|
+
thread: THREAD_HELP,
|
|
34
|
+
cite: CITE_HELP,
|
|
35
|
+
search: SEARCH_HELP,
|
|
36
|
+
catchup: CATCHUP_HELP,
|
|
37
|
+
react: REACT_HELP,
|
|
38
|
+
draft: DRAFT_HELP,
|
|
39
|
+
setup: SETUP_HELP,
|
|
40
|
+
};
|
|
41
|
+
export async function main() {
|
|
42
|
+
await runAxiCli({
|
|
43
|
+
description: DESCRIPTION,
|
|
44
|
+
version: readVersion(),
|
|
45
|
+
topLevelHelp: TOP_HELP,
|
|
46
|
+
home: () => homeCommand(),
|
|
47
|
+
commands: {
|
|
48
|
+
auth: (args) => authCommand(args),
|
|
49
|
+
doctor: (args) => doctorCommand(args),
|
|
50
|
+
channels: (args) => channelsCommand(args),
|
|
51
|
+
dms: (args) => dmsCommand(args),
|
|
52
|
+
members: (args) => membersCommand(args),
|
|
53
|
+
cache: (args) => cacheCommand(args),
|
|
54
|
+
read: (args) => readCommand(args),
|
|
55
|
+
thread: (args) => threadCommand(args),
|
|
56
|
+
cite: (args) => citeCommand(args),
|
|
57
|
+
search: (args) => searchCommand(args),
|
|
58
|
+
catchup: (args) => catchupCommand(args),
|
|
59
|
+
react: (args) => reactCommand(args),
|
|
60
|
+
draft: (args) => draftCommand(args),
|
|
61
|
+
setup: (args) => setupCommand(args),
|
|
62
|
+
},
|
|
63
|
+
getCommandHelp: (command) => COMMAND_HELP[command],
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EACL,eAAe,EACf,aAAa,EACb,UAAU,EACV,QAAQ,EACR,cAAc,EACd,YAAY,GACb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACzF,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAErD,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;qEAU6C,CAAC;AAEtE,MAAM,YAAY,GAA2B;IAC3C,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,WAAW;IACnB,QAAQ,EAAE,aAAa;IACvB,GAAG,EAAE,QAAQ;IACb,OAAO,EAAE,YAAY;IACrB,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,WAAW;IACnB,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,UAAU;CAClB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,SAAS,CAAC;QACd,WAAW,EAAE,WAAW;QACxB,OAAO,EAAE,WAAW,EAAE;QACtB,YAAY,EAAE,QAAQ;QACtB,IAAI,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE;QACzB,QAAQ,EAAE;YACR,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC;YACjC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC;YACrC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC;YACzC,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAC/B,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC;YACvC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;YACnC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC;YACjC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC;YACrC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC;YACjC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC;YACrC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC;YACvC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;YACnC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;YACnC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;SACpC;QACD,cAAc,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC;KACnD,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const AUTH_HELP = "usage: slack-axi auth <subcommand> [flags]\nsubcommands[5]:\n setup Progressive guided setup: create an app from a manifest, then log in\n login --token <xoxp-...> Validate and store a token (derives team/user/scopes)\n workspaces List authenticated workspaces (default marked)\n use <team> Set the default workspace\n revoke <team> Delete a workspace's stored token\nsetup flags[4]:\n --name <name> App display name in the manifest (default: slack-axi)\n --confirm-step <step> Mark a manual step done (step: app_created)\n --show-manifest Also print the manifest YAML inline\n --reset Clear setup state (e.g. to set up another workspace)\nflags[2]:\n --team <id> Target a specific workspace (login/use/revoke)\n --token <xoxp-...> The user token to store (login)\nexamples:\n slack-axi auth setup\n slack-axi auth setup --confirm-step app_created\n slack-axi auth login --token xoxp-...\n slack-axi auth workspaces";
|
|
2
|
+
export declare function authCommand(args: string[]): Promise<string>;
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { AxiError } from "axi-sdk-js";
|
|
2
|
+
import { getDefaultTeam, listWorkspaces, removeWorkspace, setDefaultTeam, writeStoredToken, } from "../config.js";
|
|
3
|
+
import { takeBool, takeFlag } from "../flags.js";
|
|
4
|
+
import { collapseHome, encodeBlock, joinBlocks, renderHelp, renderList } from "../output.js";
|
|
5
|
+
import { buildManifest, markAppCreated, NEW_APP_URL, readSetupState, resetSetup, setAppName, setupProgress, writeManifestFile, writeSetupHtmlFile, } from "../auth/setup.js";
|
|
6
|
+
import { validateToken } from "../slack/client.js";
|
|
7
|
+
import { toAxiError } from "../slack/errors.js";
|
|
8
|
+
import { missingScopes } from "../slack/scopes.js";
|
|
9
|
+
export const AUTH_HELP = `usage: slack-axi auth <subcommand> [flags]
|
|
10
|
+
subcommands[5]:
|
|
11
|
+
setup Progressive guided setup: create an app from a manifest, then log in
|
|
12
|
+
login --token <xoxp-...> Validate and store a token (derives team/user/scopes)
|
|
13
|
+
workspaces List authenticated workspaces (default marked)
|
|
14
|
+
use <team> Set the default workspace
|
|
15
|
+
revoke <team> Delete a workspace's stored token
|
|
16
|
+
setup flags[4]:
|
|
17
|
+
--name <name> App display name in the manifest (default: slack-axi)
|
|
18
|
+
--confirm-step <step> Mark a manual step done (step: app_created)
|
|
19
|
+
--show-manifest Also print the manifest YAML inline
|
|
20
|
+
--reset Clear setup state (e.g. to set up another workspace)
|
|
21
|
+
flags[2]:
|
|
22
|
+
--team <id> Target a specific workspace (login/use/revoke)
|
|
23
|
+
--token <xoxp-...> The user token to store (login)
|
|
24
|
+
examples:
|
|
25
|
+
slack-axi auth setup
|
|
26
|
+
slack-axi auth setup --confirm-step app_created
|
|
27
|
+
slack-axi auth login --token xoxp-...
|
|
28
|
+
slack-axi auth workspaces`;
|
|
29
|
+
export async function authCommand(args) {
|
|
30
|
+
if (args.includes("--help") || args.length === 0)
|
|
31
|
+
return AUTH_HELP;
|
|
32
|
+
const sub = args[0];
|
|
33
|
+
const rest = args.slice(1);
|
|
34
|
+
switch (sub) {
|
|
35
|
+
case "setup":
|
|
36
|
+
return setup(rest);
|
|
37
|
+
case "login":
|
|
38
|
+
return login(rest);
|
|
39
|
+
case "workspaces":
|
|
40
|
+
return workspaces();
|
|
41
|
+
case "use":
|
|
42
|
+
return use(rest);
|
|
43
|
+
case "revoke":
|
|
44
|
+
return revoke(rest);
|
|
45
|
+
default:
|
|
46
|
+
throw new AxiError(`Unknown auth subcommand: ${sub}`, "USAGE", [
|
|
47
|
+
"Subcommands: setup, login, workspaces, use, revoke",
|
|
48
|
+
]);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function setup(args) {
|
|
52
|
+
let rest = args;
|
|
53
|
+
const reset = takeBool(rest, "--reset");
|
|
54
|
+
rest = reset.rest;
|
|
55
|
+
if (reset.present)
|
|
56
|
+
resetSetup();
|
|
57
|
+
const showManifest = takeBool(rest, "--show-manifest");
|
|
58
|
+
rest = showManifest.rest;
|
|
59
|
+
const nameFlag = takeFlag(rest, "--name");
|
|
60
|
+
rest = nameFlag.rest;
|
|
61
|
+
if (nameFlag.value)
|
|
62
|
+
setAppName(nameFlag.value);
|
|
63
|
+
const confirm = takeFlag(rest, "--confirm-step");
|
|
64
|
+
rest = confirm.rest;
|
|
65
|
+
if (confirm.value) {
|
|
66
|
+
if (confirm.value !== "app_created") {
|
|
67
|
+
throw new AxiError(`Unknown setup step: ${confirm.value}`, "USAGE", [
|
|
68
|
+
"The only manual step is `app_created`",
|
|
69
|
+
]);
|
|
70
|
+
}
|
|
71
|
+
markAppCreated();
|
|
72
|
+
}
|
|
73
|
+
// Always refresh the generated artifacts so they reflect the current app name + scopes.
|
|
74
|
+
const appName = readSetupState().app_name;
|
|
75
|
+
const manifestFile = writeManifestFile(appName);
|
|
76
|
+
const htmlFile = writeSetupHtmlFile(appName);
|
|
77
|
+
const progress = setupProgress();
|
|
78
|
+
const head = encodeBlock("setup", {
|
|
79
|
+
progress: `${progress.done} of ${progress.total} steps complete`,
|
|
80
|
+
...(progress.complete ? { status: "complete" } : { next_step: progress.next }),
|
|
81
|
+
});
|
|
82
|
+
let help;
|
|
83
|
+
let blocks = [head];
|
|
84
|
+
if (progress.next === "app_created") {
|
|
85
|
+
blocks.push(encodeBlock("files", { manifest: collapseHome(manifestFile), setup_page: collapseHome(htmlFile) }));
|
|
86
|
+
help = [
|
|
87
|
+
`Open ${collapseHome(htmlFile)} (or ${NEW_APP_URL}) → "From an app manifest" → pick your workspace → paste the manifest from ${collapseHome(manifestFile)}`,
|
|
88
|
+
"Token rotation is disabled in the manifest, so the resulting token won't expire",
|
|
89
|
+
"Once the app exists, run `slack-axi auth setup --confirm-step app_created`",
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
else if (progress.next === "token_stored") {
|
|
93
|
+
help = [
|
|
94
|
+
'On the app\'s "OAuth & Permissions" page, click "Install to Workspace" and authorize',
|
|
95
|
+
"Copy the User OAuth Token (xoxp-...) and run `slack-axi auth login --token xoxp-...`",
|
|
96
|
+
];
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
help = [
|
|
100
|
+
"Run `slack-axi doctor` to verify scopes + read access",
|
|
101
|
+
"To set up another workspace, run `slack-axi auth setup --reset`",
|
|
102
|
+
];
|
|
103
|
+
}
|
|
104
|
+
if (showManifest.present)
|
|
105
|
+
blocks.push(`manifest_yaml: |\n${indent(buildManifest(appName), 2)}`);
|
|
106
|
+
blocks.push(renderHelp(help));
|
|
107
|
+
return joinBlocks(...blocks);
|
|
108
|
+
}
|
|
109
|
+
function indent(text, spaces) {
|
|
110
|
+
const pad = " ".repeat(spaces);
|
|
111
|
+
return text
|
|
112
|
+
.split("\n")
|
|
113
|
+
.map((line) => (line.length > 0 ? pad + line : line))
|
|
114
|
+
.join("\n");
|
|
115
|
+
}
|
|
116
|
+
async function login(args) {
|
|
117
|
+
const { value: token, rest } = takeFlag(args, "--token");
|
|
118
|
+
const { value: teamFlag } = takeFlag(rest, "--team");
|
|
119
|
+
if (!token) {
|
|
120
|
+
throw new AxiError("--token is required", "USAGE", [
|
|
121
|
+
"slack-axi auth login --token xoxp-...",
|
|
122
|
+
"Run `slack-axi auth setup` to obtain a token",
|
|
123
|
+
]);
|
|
124
|
+
}
|
|
125
|
+
let identity;
|
|
126
|
+
try {
|
|
127
|
+
identity = await validateToken(token);
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
throw toAxiError(err, teamFlag ? { team: teamFlag } : {});
|
|
131
|
+
}
|
|
132
|
+
if (teamFlag && teamFlag !== identity.teamId) {
|
|
133
|
+
throw new AxiError(`Token belongs to workspace ${identity.teamId} (${identity.teamName}), not ${teamFlag}`, "TEAM_MISMATCH", ["Re-run without --team, or pass the matching workspace id"]);
|
|
134
|
+
}
|
|
135
|
+
writeStoredToken({
|
|
136
|
+
team_id: identity.teamId,
|
|
137
|
+
team_name: identity.teamName,
|
|
138
|
+
user_id: identity.userId,
|
|
139
|
+
user_name: identity.userName,
|
|
140
|
+
token,
|
|
141
|
+
scopes: identity.scopes,
|
|
142
|
+
obtained_at: new Date().toISOString(),
|
|
143
|
+
});
|
|
144
|
+
const missing = missingScopes(identity.scopes);
|
|
145
|
+
const summary = encodeBlock("authenticated", {
|
|
146
|
+
workspace: `${identity.teamName} (${identity.teamId})`,
|
|
147
|
+
user: identity.userName ? `${identity.userName} (${identity.userId})` : identity.userId,
|
|
148
|
+
scopes: missing.length === 0 ? "all required scopes granted" : `missing ${missing.length}`,
|
|
149
|
+
default: getDefaultTeam() === identity.teamId,
|
|
150
|
+
});
|
|
151
|
+
const help = missing.length > 0
|
|
152
|
+
? renderHelp([`Add missing scopes (${missing.join(", ")}) via \`slack-axi auth setup\`, then re-install + re-login`])
|
|
153
|
+
: "";
|
|
154
|
+
return joinBlocks(summary, help);
|
|
155
|
+
}
|
|
156
|
+
function workspaces() {
|
|
157
|
+
const stored = listWorkspaces();
|
|
158
|
+
if (stored.length === 0) {
|
|
159
|
+
return joinBlocks(encodeBlock("workspaces", "0 workspaces authenticated"), renderHelp(["Run `slack-axi auth setup` to create an app and store a token"]));
|
|
160
|
+
}
|
|
161
|
+
const def = getDefaultTeam();
|
|
162
|
+
const rows = stored.map((w) => ({
|
|
163
|
+
team: w.team_id,
|
|
164
|
+
name: w.team_name,
|
|
165
|
+
user: w.user_name ?? w.user_id,
|
|
166
|
+
default: w.team_id === def,
|
|
167
|
+
}));
|
|
168
|
+
return joinBlocks(renderList("workspaces", rows), renderHelp(["Run `slack-axi auth use <team>` to change the default"]));
|
|
169
|
+
}
|
|
170
|
+
function use(args) {
|
|
171
|
+
const team = args.find((a) => !a.startsWith("-"));
|
|
172
|
+
if (!team)
|
|
173
|
+
throw new AxiError("usage: slack-axi auth use <team>", "USAGE", []);
|
|
174
|
+
const known = listWorkspaces().some((w) => w.team_id === team);
|
|
175
|
+
if (!known) {
|
|
176
|
+
throw new AxiError(`Workspace ${team} is not authenticated`, "TEAM_NOT_FOUND", [
|
|
177
|
+
`Authenticated: ${listWorkspaces().map((w) => w.team_id).join(", ") || "(none)"}`,
|
|
178
|
+
]);
|
|
179
|
+
}
|
|
180
|
+
if (getDefaultTeam() === team)
|
|
181
|
+
return encodeBlock("default", `${team} already default (no-op)`);
|
|
182
|
+
setDefaultTeam(team);
|
|
183
|
+
return encodeBlock("default", team);
|
|
184
|
+
}
|
|
185
|
+
function revoke(args) {
|
|
186
|
+
const team = args.find((a) => !a.startsWith("-"));
|
|
187
|
+
if (!team)
|
|
188
|
+
throw new AxiError("usage: slack-axi auth revoke <team>", "USAGE", []);
|
|
189
|
+
const existed = removeWorkspace(team);
|
|
190
|
+
return encodeBlock("revoked", existed ? team : `${team} (was not stored — no-op)`);
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AxiError } from "axi-sdk-js";
|
|
2
|
+
import { takeFlag } from "../flags.js";
|
|
3
|
+
import { encodeBlock } from "../output.js";
|
|
4
|
+
import { activeSession } from "../session.js";
|
|
5
|
+
import { refreshMemberChannels, refreshUsers } from "../slack/cache.js";
|
|
6
|
+
export const CACHE_HELP = `usage: slack-axi cache refresh [--team <id>]
|
|
7
|
+
Rebuilds the local channel + user caches used for name<->id and user resolution.`;
|
|
8
|
+
export async function cacheCommand(args) {
|
|
9
|
+
if (args.includes("--help") || args.length === 0)
|
|
10
|
+
return CACHE_HELP;
|
|
11
|
+
const sub = args[0];
|
|
12
|
+
const team = takeFlag(args.slice(1), "--team");
|
|
13
|
+
if (sub !== "refresh") {
|
|
14
|
+
throw new AxiError(`Unknown cache subcommand: ${sub}`, "USAGE", ["Only `cache refresh` is supported"]);
|
|
15
|
+
}
|
|
16
|
+
const session = await activeSession({ teamFlag: team.value });
|
|
17
|
+
const channels = await refreshMemberChannels(session);
|
|
18
|
+
await refreshUsers(session);
|
|
19
|
+
return encodeBlock("cache", {
|
|
20
|
+
workspace: `${session.teamName ?? session.teamId} (${session.teamId})`,
|
|
21
|
+
channels: channels.length,
|
|
22
|
+
refreshed: "channels + users",
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/commands/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAExE,MAAM,CAAC,MAAM,UAAU,GAAG;iFACuD,CAAC;AAElF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAc;IAC/C,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC;IACpE,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC/C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,QAAQ,CAAC,6BAA6B,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,mCAAmC,CAAC,CAAC,CAAC;IACzG,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACtD,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,WAAW,CAAC,OAAO,EAAE;QAC1B,SAAS,EAAE,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG;QACtE,QAAQ,EAAE,QAAQ,CAAC,MAAM;QACzB,SAAS,EAAE,kBAAkB;KAC9B,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const CATCHUP_HELP = "usage: slack-axi catchup [flags]\nSweeps a SCOPED set of channels over a time window and returns everything posted \u2014 a multi-channel read.\nSlack has no cross-conversation history endpoint, so this fans out per channel; scope keeps it bounded.\nflags[10]:\n --since <span> Window ending now: 1d, 12h, 90m (default: 1d)\n --from <when> Window start (date / datetime / span); --to end (default now)\n --tz <zone> Timezone (default America/New_York)\n --every <span> PLAN MODE: emit batch windows (e.g. 1w) instead of fetching \u2014 for big catch-ups\n --type <a,b> Conversation types to sweep (default: public,private)\n --match <q> Only channels whose name contains <q>\n --in <c1,c2,...> Explicit channel list (#name/name/id), overrides --type/--match\n --limit-per <n> Max messages per channel (default 50)\n --max-channels <n> Refuse to sweep more than this many (default 40)\n --exclude-bots Drop bot/automation messages\n --cite Add a permalink column\nThreads are not inlined here (kept cheap across many channels); a [+N replies] note marks threads \u2014\nexpand one with `read <channel>` or `thread <channel> <ts>`.\nexamples:\n slack-axi catchup --since 1d --match bid\n slack-axi catchup --from 2026-05-01 --to 2026-06-07 --every 1w --match bid (plan a month, weekly)\n slack-axi catchup --from 2026-06-06T09:00 --in bid-rtd-analytics,transit-lake";
|
|
2
|
+
export declare function catchupCommand(args: string[]): Promise<string>;
|