@eliya-oss/agent-slack 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/.agents/cli-api.md +295 -0
- package/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +39 -0
- package/assets/terminal.svg +32 -0
- package/dist/adapters/catalog/BundledMethodCatalog.js +53 -0
- package/dist/adapters/http-file-downloader/HttpFileDownloader.js +20 -0
- package/dist/adapters/keychain/KeychainTokenStore.js +152 -0
- package/dist/adapters/live.js +13 -0
- package/dist/adapters/localhost-oauth/NodeLocalhostOAuthFlow.js +160 -0
- package/dist/adapters/profile-file/FileTokenStore.js +67 -0
- package/dist/adapters/slack-sdk/SlackSdkWebApi.js +48 -0
- package/dist/application/auth.js +35 -0
- package/dist/application/commands.js +579 -0
- package/dist/application/execute.js +22 -0
- package/dist/application/payload.js +40 -0
- package/dist/application/services.js +1 -0
- package/dist/application/slack-call.js +62 -0
- package/dist/cli/args.js +70 -0
- package/dist/cli/metadata.js +330 -0
- package/dist/cli/types.js +1 -0
- package/dist/domain/errors.js +68 -0
- package/dist/domain/ids.js +31 -0
- package/dist/domain/slack.js +1 -0
- package/dist/main.js +16 -0
- package/dist/output/envelope.js +60 -0
- package/dist/output/projection.js +55 -0
- package/dist/ports/FileDownloader.js +1 -0
- package/dist/ports/MethodCatalog.js +1 -0
- package/dist/ports/OAuthFlow.js +1 -0
- package/dist/ports/SlackWebApi.js +1 -0
- package/dist/ports/TokenStore.js +1 -0
- package/package.json +63 -0
- package/skills/agent-slack/SKILL.md +35 -0
- package/skills/agent-slack/agents/openai.yaml +4 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { UsageError } from "../domain/errors.js";
|
|
2
|
+
export const projectFields = (value, fields) => {
|
|
3
|
+
if (fields === undefined || fields.trim() === "") {
|
|
4
|
+
return value;
|
|
5
|
+
}
|
|
6
|
+
const paths = fields.split(",").map((field) => field.trim()).filter(Boolean);
|
|
7
|
+
if (paths.length === 0) {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
const projected = {};
|
|
11
|
+
for (const path of paths) {
|
|
12
|
+
assignPath(projected, path, readPath(value, path));
|
|
13
|
+
}
|
|
14
|
+
return projected;
|
|
15
|
+
};
|
|
16
|
+
const readPath = (value, path) => {
|
|
17
|
+
let current = value;
|
|
18
|
+
for (const segment of path.split(".")) {
|
|
19
|
+
if (segment === "") {
|
|
20
|
+
throw new UsageError("--fields paths cannot contain empty segments", { path });
|
|
21
|
+
}
|
|
22
|
+
if (Array.isArray(current)) {
|
|
23
|
+
const index = Number(segment);
|
|
24
|
+
if (!Number.isInteger(index) || index < 0) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
current = current[index];
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (typeof current !== "object" || current === null || !(segment in current)) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
current = current[segment];
|
|
34
|
+
}
|
|
35
|
+
return current;
|
|
36
|
+
};
|
|
37
|
+
const assignPath = (target, path, value) => {
|
|
38
|
+
const segments = path.split(".");
|
|
39
|
+
let current = target;
|
|
40
|
+
for (const segment of segments.slice(0, -1)) {
|
|
41
|
+
const next = current[segment];
|
|
42
|
+
if (typeof next === "object" && next !== null && !Array.isArray(next)) {
|
|
43
|
+
current = next;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const created = {};
|
|
47
|
+
current[segment] = created;
|
|
48
|
+
current = created;
|
|
49
|
+
}
|
|
50
|
+
const last = segments.at(-1);
|
|
51
|
+
if (last === undefined || last === "") {
|
|
52
|
+
throw new UsageError("--fields paths cannot contain empty segments", { path });
|
|
53
|
+
}
|
|
54
|
+
current[last] = value;
|
|
55
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@eliya-oss/agent-slack",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Slack context CLI for AI agents.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"packageManager": "pnpm@11.9.0",
|
|
7
|
+
"bin": {
|
|
8
|
+
"slk": "dist/main.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"assets",
|
|
13
|
+
"skills",
|
|
14
|
+
"README.md",
|
|
15
|
+
"CHANGELOG.md",
|
|
16
|
+
"LICENSE",
|
|
17
|
+
".agents/cli-api.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc -p tsconfig.build.json",
|
|
21
|
+
"check": "pnpm typecheck && pnpm test:coverage && pnpm build",
|
|
22
|
+
"changeset": "changeset",
|
|
23
|
+
"clean": "rm -rf dist coverage",
|
|
24
|
+
"dev": "tsx src/main.ts",
|
|
25
|
+
"prepack": "pnpm build",
|
|
26
|
+
"release:check": "pnpm check && npm pack --dry-run",
|
|
27
|
+
"slk": "tsx src/main.ts",
|
|
28
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"test:coverage": "vitest run --coverage",
|
|
31
|
+
"test:emulate": "vitest run tests/emulate",
|
|
32
|
+
"version-packages": "changeset version"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"slack",
|
|
36
|
+
"cli",
|
|
37
|
+
"agents",
|
|
38
|
+
"effect",
|
|
39
|
+
"oauth"
|
|
40
|
+
],
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@effect/platform-node": "4.0.0-beta.93",
|
|
47
|
+
"@slack/web-api": "7.18.0",
|
|
48
|
+
"effect": "4.0.0-beta.93"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@changesets/cli": "^2.31.0",
|
|
52
|
+
"@effect/vitest": "4.0.0-beta.93",
|
|
53
|
+
"@types/node": "latest",
|
|
54
|
+
"@vitest/coverage-v8": "^4.1.9",
|
|
55
|
+
"emulate": "^0.8.0",
|
|
56
|
+
"tsx": "latest",
|
|
57
|
+
"typescript": "latest",
|
|
58
|
+
"vitest": "latest"
|
|
59
|
+
},
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": ">=22"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-slack
|
|
3
|
+
description: "Use when Codex needs Slack context through the `slk` CLI: authenticate, inspect profiles/scopes, read channels, messages, threads, files, users, search context, or call Slack Web API methods with agent-readable JSON or NDJSON output."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# slk CLI
|
|
7
|
+
|
|
8
|
+
Use `slk` as the Slack context boundary. Prefer read-only commands and preserve Slack's permission model: the CLI can only return data allowed by the active token, scopes, channel membership, workspace policy, and Slack plan.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. Check availability: `slk describe --json`.
|
|
13
|
+
2. Check auth: `slk auth status --json`.
|
|
14
|
+
3. If auth is missing, ask the user to run OAuth or provide a seeded profile; do not invent credentials.
|
|
15
|
+
4. Use specific read commands before raw API calls.
|
|
16
|
+
5. Use `--json` for bounded results and `--format ndjson` for large context streams.
|
|
17
|
+
6. Read structured errors from stderr; do not parse progress text from stdout.
|
|
18
|
+
|
|
19
|
+
## Common Commands
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
slk conversation history C123 --limit 50 --json
|
|
23
|
+
slk thread get --channel C123 --ts 1710000000.000100 --include users,permalinks --json
|
|
24
|
+
slk conversation context C123 --include users,threads,permalinks --format ndjson
|
|
25
|
+
slk file download F123 --out ./artifact.bin --json
|
|
26
|
+
slk user get U123 --json
|
|
27
|
+
slk api call conversations.info --payload '{"channel":"C123"}' --json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Safety
|
|
31
|
+
|
|
32
|
+
- Treat `slk api call` as the escape hatch for missing wrappers.
|
|
33
|
+
- Do not pass write/admin-mutating Slack methods unless the user explicitly asks for mutation and accepts `--allow-write --yes`.
|
|
34
|
+
- Never print token values. `auth status` reports token presence and scopes without secrets.
|
|
35
|
+
- For local repo development, use `pnpm slk -- ...` from the repository root instead of global `slk`.
|