@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 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
- Add the declarative Slack channel to an agent:
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
- For local development, Socket Mode is the shortest path:
141
-
142
- ```env
143
- SLACK_APP_TOKEN=xapp-...
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 HTTP Events API remains available as a fallback. Set
157
- `SLACK_SIGNING_SECRET` and `SLACK_BOT_TOKEN`, expose the webhook printed by
158
- `blue dev`, and configure it as the Slack app's Events API request URL.
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
- Deployed Slack delivery is not wired yet. The intended Events API route is
161
- agent-specific and owned by the hosted Blue service.
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. Session create, resume, suspend, and terminate call
187
- the Blue runtime service. The user machine does not require AWS credentials.
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, and authenticated OpenRouter proxy are implemented.
295
-
296
- The `DEPLOYMENTS` and `RUNTIMES` platform services still need to be deployed
297
- and bound before `blue deploy` and remote sessions work against
298
- `blue.opencomputer.dev`. Those services own AWS credentials, signed S3 uploads,
299
- Lambda MicroVM calls, and S3 Files access points. Versioned checkpoint
300
- replacement, deployed channels, permissions, evals, cleanup, and the web UI
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.
@@ -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>;
@@ -39,7 +39,7 @@ async function readResponse(response) {
39
39
  }
40
40
  return body;
41
41
  }
42
- function openBrowser(url) {
42
+ export function openBrowser(url) {
43
43
  if (process.env.BLUE_NO_BROWSER === "1")
44
44
  return;
45
45
  const command = process.platform === "darwin"
@@ -1 +1 @@
1
- {"version":3,"file":"cli-auth.js","sourceRoot":"","sources":["../../src/auth/cli-auth.ts"],"names":[],"mappings":"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"}
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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"}