@eliya-oss/agent-slack 0.1.7 → 0.1.9
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/.agents/cli-api.md
CHANGED
|
@@ -52,9 +52,10 @@ Auth behavior:
|
|
|
52
52
|
|
|
53
53
|
- Primary setup: `agent-slack auth login` uses the bundled Agent Slack public Client ID, opens Slack in the browser with PKCE, and stores a local Slack profile.
|
|
54
54
|
- Users can also provide an existing Slack bot token with `--token`.
|
|
55
|
-
-
|
|
56
|
-
-
|
|
55
|
+
- Browser login uses Agent Slack's public Slack app.
|
|
56
|
+
- Development and self-hosted OAuth can use Slack app credentials. The **Client ID** and **Client Secret** come from the Slack app's **Basic Information > App Credentials** section.
|
|
57
57
|
- OAuth opens the Slack OAuth URL in the default browser by default. Use `--no-open` to print the URL only, or `--auth-url-out PATH` for headless agents.
|
|
58
|
+
- Distributed Slack apps use an HTTPS relay redirect URI. The relay forwards Slack's `code` and `state` to the local callback.
|
|
58
59
|
- PKCE uses `user_scope=...`; OAuth with app credentials uses `scope=...` for bot scopes.
|
|
59
60
|
- Default local callback: `http://localhost:45454/oauth/slack/callback`.
|
|
60
61
|
- Stores profiles outside the project directory. The default store is `~/.config/agent-slack/profiles.json`; set `AGENT_SLACK_TOKEN_STORE=keychain` on macOS to keep token secrets in Keychain and only profile metadata on disk.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @eliya-oss/agent-slack
|
|
2
2
|
|
|
3
|
+
## 0.1.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Support hosted HTTPS OAuth redirect relays for distributed Slack apps.
|
|
8
|
+
|
|
9
|
+
## 0.1.8
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Keep README auth onboarding focused on browser login and clean up auth help copy.
|
|
14
|
+
|
|
3
15
|
## 0.1.7
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# agent-slack
|
|
4
4
|
|
|
5
5
|
Slack context for AI agents via the `agent-slack` CLI.
|
|
6
6
|
Short alias: `aslk`.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
npm install -g @eliya-oss/agent-slack
|
|
10
|
-
```
|
|
8
|
+
<pre align="center">npm install -g @eliya-oss/agent-slack</pre>
|
|
11
9
|
|
|
12
10
|
<img src="./assets/terminal.webp" alt="Agent Slack terminal screenshot" width="820">
|
|
13
11
|
|
|
@@ -25,28 +23,11 @@ agent-slack api call conversations.info --payload '{"channel":"C123"}' --json
|
|
|
25
23
|
|
|
26
24
|
## Auth
|
|
27
25
|
|
|
28
|
-
Browser login:
|
|
29
|
-
|
|
30
26
|
```bash
|
|
31
27
|
agent-slack auth login
|
|
32
28
|
```
|
|
33
29
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Token setup:
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
agent-slack auth login --token "$SLACK_BOT_TOKEN" --scopes channels:read,channels:history,users:read
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Developer/self-hosted fallback:
|
|
43
|
-
|
|
44
|
-
1. Create a Slack app at <https://api.slack.com/apps>.
|
|
45
|
-
2. Add the needed scopes under **OAuth & Permissions**.
|
|
46
|
-
3. Install it to your workspace and copy the bot token.
|
|
47
|
-
4. Run `agent-slack auth login --token "$SLACK_BOT_TOKEN" --scopes ...`.
|
|
48
|
-
|
|
49
|
-
OAuth with `--client-id` and `--client-secret` is only for development and self-hosted setups.
|
|
30
|
+
Opens Slack in your browser and stores a local profile for future commands.
|
|
50
31
|
|
|
51
32
|
## Skill
|
|
52
33
|
|
|
@@ -63,3 +44,11 @@ Project docs live in `.agents/`.
|
|
|
63
44
|
## License
|
|
64
45
|
|
|
65
46
|
MIT
|
|
47
|
+
|
|
48
|
+
## Sponsors
|
|
49
|
+
|
|
50
|
+
<p align="center">
|
|
51
|
+
<a href="https://github.com/sponsors/Newbie012">
|
|
52
|
+
<img src="https://cdn.jsdelivr.net/gh/newbie012/sponsors/sponsors.svg">
|
|
53
|
+
</a>
|
|
54
|
+
</p>
|
package/assets/terminal.webp
CHANGED
|
Binary file
|
|
@@ -15,10 +15,14 @@ export class NodeLocalhostOAuthFlow {
|
|
|
15
15
|
const redirectHost = env.AGENT_SLACK_OAUTH_REDIRECT_HOST ?? env.SLK_OAUTH_REDIRECT_HOST;
|
|
16
16
|
const redirectPort = env.AGENT_SLACK_OAUTH_REDIRECT_PORT ?? env.SLK_OAUTH_REDIRECT_PORT;
|
|
17
17
|
const redirectPath = env.AGENT_SLACK_OAUTH_REDIRECT_PATH ?? env.SLK_OAUTH_REDIRECT_PATH;
|
|
18
|
+
const slackRedirectUri = env.AGENT_SLACK_OAUTH_REDIRECT_URI ?? env.AGENT_SLACK_OAUTH_PUBLIC_REDIRECT_URI;
|
|
19
|
+
const localCallbackUri = env.AGENT_SLACK_OAUTH_LOCAL_CALLBACK_URI;
|
|
18
20
|
const timeoutMs = env.AGENT_SLACK_OAUTH_TIMEOUT_MS ?? env.SLK_OAUTH_TIMEOUT_MS;
|
|
19
21
|
return new NodeLocalhostOAuthFlow({
|
|
20
22
|
authorizeUrl: env.AGENT_SLACK_OAUTH_AUTHORIZE_URL ?? env.SLK_SLACK_OAUTH_AUTHORIZE_URL ?? (emulatorBaseUrl === undefined ? "https://slack.com/oauth/v2/authorize" : `${emulatorBaseUrl}/oauth/v2/authorize`),
|
|
21
23
|
tokenUrl: env.AGENT_SLACK_OAUTH_ACCESS_URL ?? env.SLK_SLACK_OAUTH_ACCESS_URL ?? (apiBaseUrl === undefined ? "https://slack.com/api/oauth.v2.access" : `${apiBaseUrl.replace(/\/?$/, "/")}oauth.v2.access`),
|
|
24
|
+
...(slackRedirectUri === undefined ? {} : { defaultSlackRedirectUri: slackRedirectUri }),
|
|
25
|
+
...(localCallbackUri === undefined ? {} : { defaultLocalCallbackUri: localCallbackUri }),
|
|
22
26
|
...(redirectHost === undefined ? {} : { defaultRedirectHost: redirectHost }),
|
|
23
27
|
...(redirectPort === undefined ? {} : { defaultRedirectPort: Number(redirectPort) }),
|
|
24
28
|
...(redirectPath === undefined ? {} : { defaultRedirectPath: redirectPath }),
|
|
@@ -30,15 +34,20 @@ export class NodeLocalhostOAuthFlow {
|
|
|
30
34
|
const codeVerifier = input.pkce === true ? randomBytes(32).toString("base64url") : undefined;
|
|
31
35
|
const timeoutMs = input.timeoutMs ?? this.options.defaultTimeoutMs ?? 120_000;
|
|
32
36
|
const server = createServer();
|
|
33
|
-
const
|
|
37
|
+
const slackRedirectUri = input.redirectUri ?? this.options.defaultSlackRedirectUri;
|
|
38
|
+
const localCallbackUri = input.localCallbackUri ??
|
|
39
|
+
this.options.defaultLocalCallbackUri ??
|
|
40
|
+
(slackRedirectUri !== undefined && isLocalCallbackUri(slackRedirectUri) ? slackRedirectUri : undefined);
|
|
41
|
+
const started = await listen(server, localCallbackUri, {
|
|
34
42
|
host: this.options.defaultRedirectHost ?? defaultRedirectHost,
|
|
35
43
|
port: this.options.defaultRedirectPort ?? defaultRedirectPort,
|
|
36
44
|
path: this.options.defaultRedirectPath ?? "/oauth/slack/callback"
|
|
37
45
|
});
|
|
46
|
+
const redirectUri = slackRedirectUri ?? started.redirectUri;
|
|
38
47
|
const authorizationUrl = buildAuthorizationUrl({
|
|
39
48
|
authorizeUrl: this.options.authorizeUrl,
|
|
40
49
|
clientId: input.clientId,
|
|
41
|
-
redirectUri
|
|
50
|
+
redirectUri,
|
|
42
51
|
scopes: input.scopes,
|
|
43
52
|
userScopes: input.userScopes,
|
|
44
53
|
state,
|
|
@@ -85,7 +94,7 @@ export class NodeLocalhostOAuthFlow {
|
|
|
85
94
|
clientId: input.clientId,
|
|
86
95
|
clientSecret: input.clientSecret,
|
|
87
96
|
codeVerifier,
|
|
88
|
-
redirectUri
|
|
97
|
+
redirectUri
|
|
89
98
|
});
|
|
90
99
|
const profile = toAuthProfile(input.profileName, access, input.pkce === true ? "user" : "bot");
|
|
91
100
|
response.writeHead(200, { "content-type": "text/html; charset=utf-8" }).end("<html><body>Slack auth complete. You can close this tab.</body></html>");
|
|
@@ -124,6 +133,13 @@ const listen = (server, redirectUri, fallback) => new Promise((resolve, reject)
|
|
|
124
133
|
});
|
|
125
134
|
const defaultRedirectHost = "localhost";
|
|
126
135
|
const defaultRedirectPort = 45454;
|
|
136
|
+
const isLocalCallbackUri = (value) => {
|
|
137
|
+
const parsed = new URL(value);
|
|
138
|
+
return parsed.protocol === "http:" && (parsed.hostname === "localhost" ||
|
|
139
|
+
parsed.hostname === "127.0.0.1" ||
|
|
140
|
+
parsed.hostname === "[::1]" ||
|
|
141
|
+
parsed.hostname === "::1");
|
|
142
|
+
};
|
|
127
143
|
const buildAuthorizationUrl = (input) => {
|
|
128
144
|
const url = new URL(input.authorizeUrl);
|
|
129
145
|
url.searchParams.set("client_id", input.clientId);
|
package/dist/cli/metadata.js
CHANGED
|
@@ -326,21 +326,20 @@ const renderAuthLoginHelp = () => [
|
|
|
326
326
|
"Browser login",
|
|
327
327
|
" agent-slack auth login",
|
|
328
328
|
"",
|
|
329
|
-
" Opens Slack in the browser
|
|
330
|
-
" The CLI never stores a Slack app secret.",
|
|
329
|
+
" Opens Slack in the browser and stores a local Slack profile.",
|
|
331
330
|
"",
|
|
332
|
-
"
|
|
331
|
+
"Headless setup",
|
|
333
332
|
" agent-slack auth login --token \"$SLACK_BOT_TOKEN\" --scopes channels:read,channels:history,users:read",
|
|
334
333
|
"",
|
|
335
334
|
" Stores an existing bot token as a local Slack profile.",
|
|
336
335
|
"",
|
|
337
|
-
"
|
|
336
|
+
"Development and self-hosted OAuth",
|
|
338
337
|
" agent-slack auth login --oauth --client-id \"$SLACK_CLIENT_ID\" --client-secret \"$SLACK_CLIENT_SECRET\"",
|
|
339
338
|
"",
|
|
340
339
|
"Options",
|
|
341
340
|
" --profile NAME Save as a named profile.",
|
|
342
341
|
" --token TOKEN Store an existing Slack bot token.",
|
|
343
|
-
" --scopes LIST Scopes to request
|
|
342
|
+
" --scopes LIST Scopes to request or record.",
|
|
344
343
|
" --user-scopes LIST User scopes to request during OAuth.",
|
|
345
344
|
" --oauth Use Slack OAuth with app credentials.",
|
|
346
345
|
" --client-id VALUE Override the Slack app Client ID.",
|
|
@@ -350,8 +349,8 @@ const renderAuthLoginHelp = () => [
|
|
|
350
349
|
" --json Emit machine-readable JSON.",
|
|
351
350
|
"",
|
|
352
351
|
"Notes",
|
|
353
|
-
"
|
|
354
|
-
" App credentials are
|
|
352
|
+
" Browser login uses PKCE with Agent Slack's public Slack app.",
|
|
353
|
+
" App credentials are for development and self-hosted setups.",
|
|
355
354
|
""
|
|
356
355
|
].join("\n");
|
|
357
356
|
export const renderCompletion = (shell) => {
|
package/package.json
CHANGED
|
@@ -24,9 +24,9 @@ Browser login:
|
|
|
24
24
|
agent-slack auth login
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Agent Slack opens Slack in the browser
|
|
27
|
+
Agent Slack opens Slack in the browser and stores a local Slack profile.
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Headless setup with an existing bot token:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
agent-slack auth login --token "$SLACK_BOT_TOKEN" --scopes channels:read,channels:history,users:read --json
|
|
@@ -34,7 +34,7 @@ agent-slack auth login --token "$SLACK_BOT_TOKEN" --scopes channels:read,channel
|
|
|
34
34
|
|
|
35
35
|
This stores an existing Slack bot token as a local profile.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Development and self-hosted OAuth:
|
|
38
38
|
|
|
39
39
|
1. Create or open a Slack app at https://api.slack.com/apps.
|
|
40
40
|
2. Go to **OAuth & Permissions**, add the needed bot scopes, install the app to the workspace, and copy the bot token.
|
|
@@ -44,7 +44,7 @@ Developer/self-hosted fallback:
|
|
|
44
44
|
agent-slack auth login --oauth --client-id "$SLACK_CLIENT_ID" --client-secret "$SLACK_CLIENT_SECRET" --json
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
Use Slack app credentials only when the user explicitly asks for development or self-hosted OAuth setup.
|
|
48
48
|
|
|
49
49
|
## Common Commands
|
|
50
50
|
|