@eliya-oss/agent-slack 0.1.2 → 0.1.3

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.
@@ -40,6 +40,7 @@ Defaults:
40
40
  agent-slack auth login
41
41
  agent-slack auth login --profile work --scopes channels:read,channels:history --user-scopes search:read.public,search:read.private
42
42
  agent-slack auth login --oauth --client-id CLIENT_ID --client-secret CLIENT_SECRET --auth-url-out /tmp/agent-slack-auth-url
43
+ agent-slack auth login --oauth --client-id CLIENT_ID --client-secret CLIENT_SECRET --no-open
43
44
  agent-slack auth status
44
45
  agent-slack auth scopes
45
46
  agent-slack auth profiles list
@@ -49,6 +50,7 @@ agent-slack auth logout --profile work
49
50
  Auth behavior:
50
51
 
51
52
  - Uses Slack OAuth v2 with a localhost callback.
53
+ - 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 and tests.
52
54
  - Bot scopes go in `scope=...`; user scopes go in `user_scope=...`.
53
55
  - 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.
54
56
  - Supports multiple profiles and workspaces.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @eliya-oss/agent-slack
2
2
 
3
+ ## 0.1.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Open Slack OAuth login in the default browser by default.
8
+
9
+ Headless flows can still use `--auth-url-out PATH` or `--no-open`, and the CLI now reads its displayed version from package metadata so releases stay in sync.
10
+
3
11
  ## 0.1.2
4
12
 
5
13
  ### Patch Changes
package/README.md CHANGED
@@ -23,6 +23,8 @@ agent-slack conversation context C123 --include users,threads,permalinks --forma
23
23
  agent-slack api call conversations.info --payload '{"channel":"C123"}' --json
24
24
  ```
25
25
 
26
+ OAuth login opens Slack in your browser. Use `--no-open` to print the URL.
27
+
26
28
  ## Skill
27
29
 
28
30
  ```bash
@@ -1,4 +1,5 @@
1
1
  import { randomBytes } from "node:crypto";
2
+ import { spawn } from "node:child_process";
2
3
  import { writeFile } from "node:fs/promises";
3
4
  import { createServer } from "node:http";
4
5
  import { PermissionDenied, SlackApiFailed, UsageError } from "../../domain/errors.js";
@@ -41,6 +42,12 @@ export class NodeLocalhostOAuthFlow {
41
42
  if (input.authUrlOut !== undefined) {
42
43
  await writeFile(input.authUrlOut, authorizationUrl, "utf8");
43
44
  }
45
+ else if (input.openBrowser !== false) {
46
+ const opened = await (this.options.openBrowser ?? openSystemBrowser)(authorizationUrl);
47
+ process.stderr.write(opened
48
+ ? `Opening Slack OAuth in your browser.\nIf it did not open, visit:\n${authorizationUrl}\n`
49
+ : `Could not open a browser automatically. Visit this Slack OAuth URL:\n${authorizationUrl}\n`);
50
+ }
44
51
  else {
45
52
  process.stderr.write(`Open this Slack OAuth URL:\n${authorizationUrl}\n`);
46
53
  }
@@ -161,3 +168,24 @@ const splitScopes = (value) => value === undefined || value.trim() === "" ? [] :
161
168
  const closeServer = (server) => {
162
169
  server.close();
163
170
  };
171
+ const openSystemBrowser = (url) => new Promise((resolve) => {
172
+ const command = browserCommand(url);
173
+ const child = spawn(command.file, command.args, {
174
+ detached: true,
175
+ stdio: "ignore"
176
+ });
177
+ child.once("error", () => resolve(false));
178
+ child.once("spawn", () => {
179
+ child.unref();
180
+ resolve(true);
181
+ });
182
+ });
183
+ const browserCommand = (url) => {
184
+ if (process.platform === "darwin") {
185
+ return { file: "open", args: [url] };
186
+ }
187
+ if (process.platform === "win32") {
188
+ return { file: "cmd", args: ["/c", "start", "", url] };
189
+ }
190
+ return { file: "xdg-open", args: [url] };
191
+ };
@@ -210,7 +210,8 @@ const authCommand = async (parsed, services) => {
210
210
  userScopes: splitCsv(flagString(parsed, "user-scopes")),
211
211
  redirectUri: flagString(parsed, "redirect-uri"),
212
212
  authUrlOut: flagString(parsed, "auth-url-out"),
213
- timeoutMs: numberFlag(parsed, "timeout-ms")
213
+ timeoutMs: numberFlag(parsed, "timeout-ms"),
214
+ openBrowser: !flagBoolean(parsed, "no-open")
214
215
  });
215
216
  await services.tokenStore.setProfile(profile);
216
217
  return { method: "auth.login", profile, stdoutValue: sanitizeProfile(profile) };
package/dist/cli/args.js CHANGED
@@ -10,7 +10,8 @@ const booleanFlags = new Set([
10
10
  "yes",
11
11
  "no-cache",
12
12
  "inclusive",
13
- "oauth"
13
+ "oauth",
14
+ "no-open"
14
15
  ]);
15
16
  export const parseArgs = (argv) => {
16
17
  const flags = new Map();
@@ -1,7 +1,10 @@
1
+ import { createRequire } from "node:module";
2
+ const require = createRequire(import.meta.url);
3
+ const packageJson = require("../../package.json");
1
4
  export const PRIMARY_COMMAND_NAME = "agent-slack";
2
5
  export const SHORT_COMMAND_NAME = "aslk";
3
6
  export const COMMAND_NAMES = [PRIMARY_COMMAND_NAME, SHORT_COMMAND_NAME];
4
- export const CLI_VERSION = "0.1.2";
7
+ export const CLI_VERSION = packageJson.version ?? "0.0.0";
5
8
  export const commandMetadata = [
6
9
  {
7
10
  path: ["describe"],
@@ -30,7 +33,7 @@ export const commandMetadata = [
30
33
  {
31
34
  path: ["auth", "login"],
32
35
  summary: "Create a Slack auth profile with OAuth or a seeded token.",
33
- flags: ["--profile", "--oauth", "--client-id", "--client-secret", "--scopes", "--user-scopes", "--redirect-uri", "--auth-url-out", "--timeout-ms", "--token", "--json"],
36
+ flags: ["--profile", "--oauth", "--client-id", "--client-secret", "--scopes", "--user-scopes", "--redirect-uri", "--auth-url-out", "--timeout-ms", "--no-open", "--token", "--json"],
34
37
  safety: "read",
35
38
  output: "profile status",
36
39
  examples: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eliya-oss/agent-slack",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Slack context CLI for AI agents.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.9.0",
@@ -11,7 +11,7 @@ Use `agent-slack` as the Slack context boundary. `aslk` is the short alias. Pref
11
11
 
12
12
  1. Check availability: `agent-slack describe --json`.
13
13
  2. Check auth: `agent-slack auth status --json`.
14
- 3. If auth is missing, ask the user to run OAuth or provide a seeded profile; do not invent credentials.
14
+ 3. If auth is missing, ask the user to run `agent-slack auth login --oauth`; it opens Slack OAuth in the browser by default. For headless flows use `--auth-url-out PATH` or `--no-open`.
15
15
  4. Use specific read commands before raw API calls.
16
16
  5. Use `--json` for bounded results and `--format ndjson` for large context streams.
17
17
  6. Read structured errors from stderr; do not parse progress text from stdout.