@opencomputer/blue 0.0.3 → 0.0.5
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 +60 -26
- package/dist/auth/cli-auth.d.ts +1 -0
- package/dist/auth/cli-auth.js +1 -1
- package/dist/auth/cli-auth.js.map +1 -1
- package/dist/channels/slack-api.d.ts +24 -0
- package/dist/channels/slack-api.js +69 -0
- package/dist/channels/slack-api.js.map +1 -0
- package/dist/channels/slack-events.d.ts +8 -0
- package/dist/channels/slack-events.js +48 -0
- package/dist/channels/slack-events.js.map +1 -0
- package/dist/channels/slack-project.d.ts +21 -0
- package/dist/channels/slack-project.js +133 -0
- package/dist/channels/slack-project.js.map +1 -0
- package/dist/cli/index.js +210 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/core/agent.js +63 -6
- package/dist/core/agent.js.map +1 -1
- package/dist/core/artifact.d.ts +1 -0
- package/dist/core/artifact.js +18 -0
- package/dist/core/artifact.js.map +1 -1
- package/dist/dev/local-control-plane.d.ts +2 -0
- package/dist/dev/local-control-plane.js +16 -0
- package/dist/dev/local-control-plane.js.map +1 -1
- package/dist/dev/manager.js +39 -44
- package/dist/dev/manager.js.map +1 -1
- package/dist/landing/agent.d.ts +12 -0
- package/dist/landing/agent.js +122 -0
- package/dist/landing/agent.js.map +1 -0
- package/dist/protocol.d.ts +30 -0
- package/dist/protocol.js.map +1 -1
- package/dist/sdk/client.d.ts +5 -1
- package/dist/sdk/client.js +21 -0
- package/dist/sdk/client.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ control-plane contract:
|
|
|
14
14
|
and hibernating WebSockets;
|
|
15
15
|
- WorkOS device authentication for the hosted CLI;
|
|
16
16
|
- a Blue model gateway that keeps the platform OpenRouter key server-side;
|
|
17
|
+
- native local and deployed Slack apps managed through the Slack CLI;
|
|
17
18
|
- sub-second content-addressed agent artifacts on a generic Lambda MicroVM
|
|
18
19
|
runtime image;
|
|
19
20
|
- an AccountDO registry for agents, immutable deployments, and aliases;
|
|
@@ -131,34 +132,57 @@ package exposes the shorter `blue` binary.
|
|
|
131
132
|
|
|
132
133
|
### Local Slack
|
|
133
134
|
|
|
134
|
-
|
|
135
|
+
Install and authenticate the
|
|
136
|
+
[Slack CLI](https://docs.slack.dev/tools/slack-cli/), then add Slack to an
|
|
137
|
+
agent:
|
|
135
138
|
|
|
136
139
|
```bash
|
|
137
140
|
blue channels add slack
|
|
141
|
+
blue channels connect slack --local
|
|
138
142
|
```
|
|
139
143
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
SLACK_BOT_TOKEN=xoxb-...
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
Restart `blue dev`; it prints `slack: Socket Mode connected`. No request URL or
|
|
148
|
-
tunnel is required. Subscribe the app to `app_mention` and grant
|
|
149
|
-
`app_mentions:read` plus `chat:write`.
|
|
144
|
+
The first command checks in the Slack manifest and Slack CLI hooks. The second
|
|
145
|
+
creates and installs the agent's local Slack app. Start it with `blue dev`;
|
|
146
|
+
Slack CLI supplies its development app and bot tokens to Blue's start hook, and
|
|
147
|
+
Blue connects over Socket Mode. No tunnel or manually copied token is needed.
|
|
150
148
|
|
|
151
149
|
Blue immediately shows Slack's native loading indicator, rotates startup
|
|
152
150
|
messages, and updates the status with reasoning and tool activity. The final
|
|
153
151
|
reply clears the indicator automatically. Each Slack thread maps to one
|
|
154
152
|
persistent local Blue session, with the mapping stored under `.blue/dev/`.
|
|
155
153
|
|
|
156
|
-
The
|
|
157
|
-
|
|
158
|
-
|
|
154
|
+
The non-secret app and workspace identity is recorded in
|
|
155
|
+
`.blue/channels/slack.local.json`. Slack CLI owns the local tokens in its
|
|
156
|
+
credential store; they are not written to the agent's `.env`.
|
|
157
|
+
|
|
158
|
+
### Remote Slack
|
|
159
|
+
|
|
160
|
+
Deploy the same agent, then create its production Slack app:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
blue channels add slack
|
|
164
|
+
blue deploy
|
|
165
|
+
blue channels connect slack --remote
|
|
166
|
+
```
|
|
159
167
|
|
|
160
|
-
|
|
161
|
-
|
|
168
|
+
Blue first reserves a callback for the deployed agent. Slack CLI creates or
|
|
169
|
+
updates the production app from the checked-in manifest, verifies the callback,
|
|
170
|
+
and invokes Blue's deploy hook with the resulting bot token. Blue encrypts that
|
|
171
|
+
token with its platform channel key. It is never written to the repository or
|
|
172
|
+
sent to the agent MicroVM.
|
|
173
|
+
|
|
174
|
+
Invite the resulting app to any channel where it should run, then mention it.
|
|
175
|
+
Direct messages also work. Each Slack thread maps to one persistent remote Blue
|
|
176
|
+
session. Blue resumes that session's MicroVM for later turns, replies as the
|
|
177
|
+
agent's Slack app, and suspends the MicroVM after delivery.
|
|
178
|
+
|
|
179
|
+
Inspect and remove managed connections with:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
blue channels list
|
|
183
|
+
blue channels disconnect slack --local
|
|
184
|
+
blue channels disconnect slack --remote
|
|
185
|
+
```
|
|
162
186
|
|
|
163
187
|
## Hosted Flow
|
|
164
188
|
|
|
@@ -183,8 +207,10 @@ boundary for agents, deployments, and sessions.
|
|
|
183
207
|
|
|
184
208
|
`blue deploy` builds the immutable agent artifact locally, requests a
|
|
185
209
|
platform-owned upload, uploads directly to the returned signed URL, and
|
|
186
|
-
registers the deployment.
|
|
187
|
-
|
|
210
|
+
registers the deployment. It also prints a public agent page with the exact CLI
|
|
211
|
+
and Slack interaction commands. Session create, resume, suspend, and terminate
|
|
212
|
+
call the Blue runtime service. The user machine does not require AWS
|
|
213
|
+
credentials.
|
|
188
214
|
|
|
189
215
|
### Service configuration
|
|
190
216
|
|
|
@@ -193,6 +219,8 @@ The hosted Worker requires:
|
|
|
193
219
|
- `BLUE_WORKOS_CLIENT_ID` and optionally `BLUE_WORKOS_ISSUER` /
|
|
194
220
|
`BLUE_WORKOS_JWKS_URL`;
|
|
195
221
|
- `OPENROUTER_API_KEY` as a Worker secret;
|
|
222
|
+
- `BLUE_CHANNEL_ENCRYPTION_KEY` as a Worker secret containing a base64-encoded
|
|
223
|
+
32-byte random key;
|
|
196
224
|
- `BLUE_RUNTIME_IMAGE_ARN` and `BLUE_RUNTIME_IMAGE_VERSION`;
|
|
197
225
|
- a `DEPLOYMENTS` service binding that returns signed platform artifact
|
|
198
226
|
uploads;
|
|
@@ -211,8 +239,15 @@ npx wrangler secret put BLUE_RUNTIME_IMAGE_ARN \
|
|
|
211
239
|
--config wrangler.production.jsonc
|
|
212
240
|
npx wrangler secret put BLUE_RUNTIME_IMAGE_VERSION \
|
|
213
241
|
--config wrangler.production.jsonc
|
|
242
|
+
npx wrangler secret put BLUE_CHANNEL_ENCRYPTION_KEY \
|
|
243
|
+
--config wrangler.production.jsonc
|
|
214
244
|
```
|
|
215
245
|
|
|
246
|
+
Generate the channel encryption secret with `openssl rand -base64 32`. Every
|
|
247
|
+
remote Slack installation receives a unique callback credential, stored by
|
|
248
|
+
Blue only as a hash. Slack CLI configures that callback automatically from the
|
|
249
|
+
agent manifest.
|
|
250
|
+
|
|
216
251
|
Configure the platform Worker's AWS secrets plus
|
|
217
252
|
`BLUE_AWS_REGION`, `BLUE_ARTIFACT_BUCKET`, `BLUE_EXECUTION_ROLE_ARN`,
|
|
218
253
|
`BLUE_NETWORK_CONNECTOR_ARN`, `BLUE_S3_FILESYSTEM_ID`, and
|
|
@@ -291,11 +326,10 @@ delivery phases are in [PLAN.md](./PLAN.md).
|
|
|
291
326
|
|
|
292
327
|
The standalone local control plane, WorkOS device login, token refresh,
|
|
293
328
|
tenant-isolated Durable Object routing, signed-upload API, runtime lifecycle
|
|
294
|
-
API,
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
remain subsequent milestones.
|
|
329
|
+
API, authenticated OpenRouter proxy, deployed Slack routing, and local/remote
|
|
330
|
+
agent landing pages are implemented.
|
|
331
|
+
|
|
332
|
+
The platform services own AWS credentials, signed S3 uploads, Lambda MicroVM
|
|
333
|
+
calls, and S3 Files access points. Versioned checkpoint replacement,
|
|
334
|
+
permissions, evals, cleanup, and the unified management dashboard remain
|
|
335
|
+
subsequent milestones.
|
package/dist/auth/cli-auth.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export interface BlueCredentials {
|
|
|
22
22
|
updatedAt: string;
|
|
23
23
|
}
|
|
24
24
|
export declare function credentialsPath(): string;
|
|
25
|
+
export declare function openBrowser(url: string): void;
|
|
25
26
|
export declare function readCredentials(): Promise<BlueCredentials | null>;
|
|
26
27
|
export declare function logout(): Promise<boolean>;
|
|
27
28
|
export declare function login(apiUrl?: string): Promise<BlueCredentials>;
|
package/dist/auth/cli-auth.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-auth.js","sourceRoot":"","sources":["../../src/auth/cli-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EACL,KAAK,EACL,KAAK,EACL,QAAQ,EACR,EAAE,EACF,SAAS,GACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,CAAC,MAAM,oBAAoB,GAAG,+BAA+B,CAAC;AAgDpE,SAAS,UAAU;IACjB,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACxD,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,OAAO,CAAC,UAAU,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,KAAK,UAAU,YAAY,CAAI,QAAkB;IAC/C,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IAC/D,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,oCAAoC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,WAAW,IAAI,wBAAwB,SAAS,QAAQ,CAAC,GAAG,EAAE,CAC9H,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC5C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,MAAM,GACV,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;YACvC,CAAC,CAAE,IAAgC;YACnC,CAAC,CAAC,EAAE,CAAC;QACT,MAAM,OAAO,GACX,OAAO,MAAM,CAAC,iBAAiB,KAAK,QAAQ;YAC1C,CAAC,CAAC,MAAM,CAAC,iBAAiB;YAC1B,CAAC,CAAC,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;gBAClC,CAAC,CAAC,MAAM,CAAC,OAAO;gBAChB,CAAC,CAAC,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ;oBAChC,CAAC,CAAC,MAAM,CAAC,KAAK;oBACd,CAAC,CAAC,8BAA8B,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,IAAS,CAAC;AACnB,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"cli-auth.js","sourceRoot":"","sources":["../../src/auth/cli-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { SlackStatus } from "./slack-progress.js";
|
|
2
|
+
export interface SlackInstallation {
|
|
3
|
+
appId: string;
|
|
4
|
+
teamId: string;
|
|
5
|
+
teamName?: string;
|
|
6
|
+
botUserId: string;
|
|
7
|
+
botId: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function resolveSlackInstallation(botToken: string): Promise<SlackInstallation>;
|
|
10
|
+
export declare function postSlackMessage(botToken: string, input: {
|
|
11
|
+
channelId: string;
|
|
12
|
+
threadTimestamp: string;
|
|
13
|
+
text: string;
|
|
14
|
+
}): Promise<string>;
|
|
15
|
+
export declare function updateSlackMessage(botToken: string, input: {
|
|
16
|
+
channelId: string;
|
|
17
|
+
messageTimestamp: string;
|
|
18
|
+
text: string;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
export declare function setSlackThreadStatus(botToken: string, input: {
|
|
21
|
+
channelId: string;
|
|
22
|
+
threadTimestamp: string;
|
|
23
|
+
status: SlackStatus;
|
|
24
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { isRecord } from "../protocol.js";
|
|
2
|
+
const SLACK_API = "https://slack.com/api";
|
|
3
|
+
async function slackRequest(token, method, body) {
|
|
4
|
+
const response = await fetch(`${SLACK_API}/${method}`, {
|
|
5
|
+
method: "POST",
|
|
6
|
+
headers: {
|
|
7
|
+
authorization: `Bearer ${token}`,
|
|
8
|
+
"content-type": "application/json; charset=utf-8",
|
|
9
|
+
},
|
|
10
|
+
body: JSON.stringify(body),
|
|
11
|
+
});
|
|
12
|
+
const result = await response.json().catch(() => null);
|
|
13
|
+
if (!response.ok || !isRecord(result) || result.ok !== true) {
|
|
14
|
+
const message = isRecord(result) && typeof result.error === "string"
|
|
15
|
+
? result.error
|
|
16
|
+
: `HTTP ${String(response.status)}`;
|
|
17
|
+
throw new Error(`Slack ${method} failed: ${message}`);
|
|
18
|
+
}
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
export async function resolveSlackInstallation(botToken) {
|
|
22
|
+
const identity = await slackRequest(botToken, "auth.test", {});
|
|
23
|
+
const teamId = typeof identity.team_id === "string" ? identity.team_id : null;
|
|
24
|
+
const botUserId = typeof identity.user_id === "string" ? identity.user_id : null;
|
|
25
|
+
const botId = typeof identity.bot_id === "string" ? identity.bot_id : null;
|
|
26
|
+
if (!teamId || !botUserId || !botId) {
|
|
27
|
+
throw new Error("Slack auth.test did not return a bot installation");
|
|
28
|
+
}
|
|
29
|
+
const bot = await slackRequest(botToken, "bots.info", { bot: botId });
|
|
30
|
+
const botInfo = isRecord(bot.bot) ? bot.bot : null;
|
|
31
|
+
const appId = botInfo && typeof botInfo.app_id === "string" ? botInfo.app_id : null;
|
|
32
|
+
if (!appId) {
|
|
33
|
+
throw new Error("Slack bots.info did not return an app ID");
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
appId,
|
|
37
|
+
teamId,
|
|
38
|
+
teamName: typeof identity.team === "string" ? identity.team : undefined,
|
|
39
|
+
botUserId,
|
|
40
|
+
botId,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export async function postSlackMessage(botToken, input) {
|
|
44
|
+
const result = await slackRequest(botToken, "chat.postMessage", {
|
|
45
|
+
channel: input.channelId,
|
|
46
|
+
thread_ts: input.threadTimestamp,
|
|
47
|
+
text: input.text.slice(0, 35_000),
|
|
48
|
+
});
|
|
49
|
+
if (typeof result.ts !== "string") {
|
|
50
|
+
throw new Error("Slack chat.postMessage did not return a timestamp");
|
|
51
|
+
}
|
|
52
|
+
return result.ts;
|
|
53
|
+
}
|
|
54
|
+
export async function updateSlackMessage(botToken, input) {
|
|
55
|
+
await slackRequest(botToken, "chat.update", {
|
|
56
|
+
channel: input.channelId,
|
|
57
|
+
ts: input.messageTimestamp,
|
|
58
|
+
text: input.text.slice(0, 35_000),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
export async function setSlackThreadStatus(botToken, input) {
|
|
62
|
+
await slackRequest(botToken, "assistant.threads.setStatus", {
|
|
63
|
+
channel_id: input.channelId,
|
|
64
|
+
thread_ts: input.threadTimestamp,
|
|
65
|
+
status: input.status.status,
|
|
66
|
+
loading_messages: input.status.loadingMessages,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=slack-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack-api.js","sourceRoot":"","sources":["../../src/channels/slack-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function verifySlackSignature(payload: string, headers: Headers, secret: string, now?: number): Promise<boolean>;
|
|
2
|
+
export interface SlackEventCallback {
|
|
3
|
+
id: string;
|
|
4
|
+
appId: string;
|
|
5
|
+
teamId: string;
|
|
6
|
+
data: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export declare function parseSlackEventCallback(value: unknown): SlackEventCallback | null;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { isRecord } from "../protocol.js";
|
|
2
|
+
function bytesToHex(bytes) {
|
|
3
|
+
return [...bytes]
|
|
4
|
+
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
5
|
+
.join("");
|
|
6
|
+
}
|
|
7
|
+
function constantTimeEqual(left, right) {
|
|
8
|
+
const size = Math.max(left.length, right.length);
|
|
9
|
+
let difference = left.length ^ right.length;
|
|
10
|
+
for (let index = 0; index < size; index += 1) {
|
|
11
|
+
difference |=
|
|
12
|
+
(left.charCodeAt(index) || 0) ^ (right.charCodeAt(index) || 0);
|
|
13
|
+
}
|
|
14
|
+
return difference === 0;
|
|
15
|
+
}
|
|
16
|
+
export async function verifySlackSignature(payload, headers, secret, now = Date.now()) {
|
|
17
|
+
const timestamp = headers.get("x-slack-request-timestamp");
|
|
18
|
+
const signature = headers.get("x-slack-signature");
|
|
19
|
+
if (!timestamp || !signature || !signature.startsWith("v0="))
|
|
20
|
+
return false;
|
|
21
|
+
const seconds = Number(timestamp);
|
|
22
|
+
if (!Number.isFinite(seconds) || Math.abs(now - seconds * 1_000) > 300_000) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
26
|
+
const digest = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(`v0:${timestamp}:${payload}`));
|
|
27
|
+
return constantTimeEqual(signature.slice(3), bytesToHex(new Uint8Array(digest)));
|
|
28
|
+
}
|
|
29
|
+
export function parseSlackEventCallback(value) {
|
|
30
|
+
if (!isRecord(value) || value.type !== "event_callback")
|
|
31
|
+
return null;
|
|
32
|
+
if (typeof value.event_id !== "string" ||
|
|
33
|
+
typeof value.api_app_id !== "string" ||
|
|
34
|
+
typeof value.team_id !== "string" ||
|
|
35
|
+
!isRecord(value.event) ||
|
|
36
|
+
(value.event.type !== "message" &&
|
|
37
|
+
value.event.type !== "app_mention") ||
|
|
38
|
+
typeof value.event.channel !== "string") {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
id: value.event_id,
|
|
43
|
+
appId: value.api_app_id,
|
|
44
|
+
teamId: value.team_id,
|
|
45
|
+
data: value.event,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=slack-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack-events.js","sourceRoot":"","sources":["../../src/channels/slack-events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface LocalSlackConnectionState {
|
|
2
|
+
version: 1;
|
|
3
|
+
appId: string;
|
|
4
|
+
teamId: string;
|
|
5
|
+
teamName?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface RemoteSlackConnectionState {
|
|
8
|
+
version: 1;
|
|
9
|
+
connectionId: string;
|
|
10
|
+
agentId: string;
|
|
11
|
+
webhookUrl: string;
|
|
12
|
+
apiUrl: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function slackManifest(name: string, mode: "local" | "remote", webhookUrl?: string): Record<string, unknown>;
|
|
15
|
+
export declare function renderSlackProjectManifest(directory?: string, mode?: "local" | "remote"): Promise<Record<string, unknown>>;
|
|
16
|
+
export declare function localSlackStatePath(root: string): string;
|
|
17
|
+
export declare function remoteSlackStatePath(root: string): string;
|
|
18
|
+
export declare function readLocalSlackState(root: string): Promise<LocalSlackConnectionState | undefined>;
|
|
19
|
+
export declare function readRemoteSlackState(root: string): Promise<RemoteSlackConnectionState | undefined>;
|
|
20
|
+
export declare function writeRemoteSlackState(root: string, state: RemoteSlackConnectionState): Promise<void>;
|
|
21
|
+
export declare function captureLocalSlackState(root: string): Promise<LocalSlackConnectionState>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { access, mkdir, readFile, writeFile, } from "node:fs/promises";
|
|
2
|
+
import { basename, dirname, resolve } from "node:path";
|
|
3
|
+
import { findAgentRoot } from "../core/agent.js";
|
|
4
|
+
async function exists(path) {
|
|
5
|
+
try {
|
|
6
|
+
await access(path);
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function slackManifest(name, mode, webhookUrl) {
|
|
14
|
+
const eventSubscriptions = {
|
|
15
|
+
bot_events: [
|
|
16
|
+
"app_mention",
|
|
17
|
+
"app_context_changed",
|
|
18
|
+
"app_home_opened",
|
|
19
|
+
"message.im",
|
|
20
|
+
],
|
|
21
|
+
};
|
|
22
|
+
if (mode === "remote") {
|
|
23
|
+
if (!webhookUrl) {
|
|
24
|
+
throw new Error("Run `blue channels connect slack --remote` before rendering the production manifest");
|
|
25
|
+
}
|
|
26
|
+
eventSubscriptions.request_url = webhookUrl;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
_metadata: { major_version: 1, minor_version: 1 },
|
|
30
|
+
display_information: {
|
|
31
|
+
name,
|
|
32
|
+
description: `Run the ${name} Blue agent from Slack.`,
|
|
33
|
+
background_color: "#0B1220",
|
|
34
|
+
},
|
|
35
|
+
features: {
|
|
36
|
+
agent_view: {
|
|
37
|
+
agent_description: `Work with the ${name} agent.`,
|
|
38
|
+
suggested_prompts: [
|
|
39
|
+
{
|
|
40
|
+
title: "Get started",
|
|
41
|
+
message: "Inspect the workspace and tell me what you can help with.",
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
bot_user: {
|
|
46
|
+
display_name: name,
|
|
47
|
+
always_online: true,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
oauth_config: {
|
|
51
|
+
scopes: {
|
|
52
|
+
bot: [
|
|
53
|
+
"app_mentions:read",
|
|
54
|
+
"assistant:write",
|
|
55
|
+
"chat:write",
|
|
56
|
+
"im:history",
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
settings: {
|
|
61
|
+
event_subscriptions: eventSubscriptions,
|
|
62
|
+
org_deploy_enabled: false,
|
|
63
|
+
socket_mode_enabled: mode === "local",
|
|
64
|
+
token_rotation_enabled: false,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export async function renderSlackProjectManifest(directory = process.cwd(), mode = process.env.BLUE_SLACK_MODE === "remote" ? "remote" : "local") {
|
|
69
|
+
const root = await findAgentRoot(directory);
|
|
70
|
+
if (!root)
|
|
71
|
+
throw new Error("No Blue agent repository was found");
|
|
72
|
+
const remote = mode === "remote" ? await readRemoteSlackState(root) : undefined;
|
|
73
|
+
return slackManifest(basename(root), mode, remote?.webhookUrl);
|
|
74
|
+
}
|
|
75
|
+
export function localSlackStatePath(root) {
|
|
76
|
+
return resolve(root, ".blue", "channels", "slack.local.json");
|
|
77
|
+
}
|
|
78
|
+
export function remoteSlackStatePath(root) {
|
|
79
|
+
return resolve(root, ".blue", "channels", "slack.remote.json");
|
|
80
|
+
}
|
|
81
|
+
export async function readLocalSlackState(root) {
|
|
82
|
+
try {
|
|
83
|
+
return JSON.parse(await readFile(localSlackStatePath(root), "utf8"));
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export async function readRemoteSlackState(root) {
|
|
90
|
+
try {
|
|
91
|
+
return JSON.parse(await readFile(remoteSlackStatePath(root), "utf8"));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export async function writeRemoteSlackState(root, state) {
|
|
98
|
+
const path = remoteSlackStatePath(root);
|
|
99
|
+
await mkdir(dirname(path), { recursive: true });
|
|
100
|
+
await writeFile(path, `${JSON.stringify(state, null, 2)}\n`, {
|
|
101
|
+
mode: 0o600,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
export async function captureLocalSlackState(root) {
|
|
105
|
+
const candidates = [
|
|
106
|
+
resolve(root, ".slack", "apps.dev.json"),
|
|
107
|
+
resolve(root, ".slack", "apps.json"),
|
|
108
|
+
];
|
|
109
|
+
for (const path of candidates) {
|
|
110
|
+
if (!(await exists(path)))
|
|
111
|
+
continue;
|
|
112
|
+
const parsed = JSON.parse(await readFile(path, "utf8"));
|
|
113
|
+
const entries = Object.values(parsed.apps ?? {});
|
|
114
|
+
const selected = entries.find((entry) => entry.team_domain === parsed.default) ??
|
|
115
|
+
entries[0];
|
|
116
|
+
if (selected?.app_id && selected.team_id) {
|
|
117
|
+
const state = {
|
|
118
|
+
version: 1,
|
|
119
|
+
appId: selected.app_id,
|
|
120
|
+
teamId: selected.team_id,
|
|
121
|
+
teamName: selected.team_domain,
|
|
122
|
+
};
|
|
123
|
+
const output = localSlackStatePath(root);
|
|
124
|
+
await mkdir(dirname(output), { recursive: true });
|
|
125
|
+
await writeFile(output, `${JSON.stringify(state, null, 2)}\n`, {
|
|
126
|
+
mode: 0o600,
|
|
127
|
+
});
|
|
128
|
+
return state;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
throw new Error("Slack CLI did not persist the local app installation");
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=slack-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack-project.js","sourceRoot":"","sources":["../../src/channels/slack-project.ts"],"names":[],"mappings":"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"}
|