@opencomputer/cli 0.2.1 → 0.3.1

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/dist/slack.js ADDED
@@ -0,0 +1,257 @@
1
+ import { spawn } from "node:child_process";
2
+ import { access, mkdir, readFile, rm, writeFile } from "node:fs/promises";
3
+ import { basename, dirname, resolve } from "node:path";
4
+ import { findAgentRoot, readManifest } from "./project.js";
5
+ const OPENCOMPUTER_SLACK_HOOKS = {
6
+ "get-manifest": "node .opencomputer/slack-hook.mjs manifest",
7
+ start: "node .opencomputer/slack-hook.mjs start",
8
+ deploy: "node .opencomputer/slack-hook.mjs deploy",
9
+ };
10
+ const OPENCOMPUTER_SLACK_HOOK_BRIDGE = `#!/usr/bin/env node
11
+ import { spawn } from "node:child_process";
12
+
13
+ const [action, ...extraArgs] = process.argv.slice(2);
14
+ if (!["manifest", "start", "deploy"].includes(action)) {
15
+ process.stderr.write("Unsupported OpenComputer Slack hook\\n");
16
+ process.exit(1);
17
+ }
18
+
19
+ const cliEntry = process.env.OPENCOMPUTER_SLACK_CLI_ENTRY;
20
+ const command = cliEntry
21
+ ? process.env.OPENCOMPUTER_SLACK_NODE_EXECUTABLE || process.execPath
22
+ : process.platform === "win32"
23
+ ? "npx.cmd"
24
+ : "npx";
25
+ const args = cliEntry
26
+ ? [cliEntry, "slack-hook", action, ...extraArgs]
27
+ : [
28
+ "-y",
29
+ "@opencomputer/cli@latest",
30
+ "slack-hook",
31
+ action,
32
+ ...extraArgs,
33
+ ];
34
+ const child = spawn(command, args, { stdio: "inherit", env: process.env });
35
+ for (const signal of ["SIGINT", "SIGTERM"]) {
36
+ process.once(signal, () => child.kill(signal));
37
+ }
38
+ child.once("error", (error) => {
39
+ process.stderr.write(\`opencomputer: \${error.message}\\n\`);
40
+ process.exit(1);
41
+ });
42
+ child.once("exit", (code) => process.exit(code ?? 1));
43
+ `;
44
+ async function exists(path) {
45
+ try {
46
+ await access(path);
47
+ return true;
48
+ }
49
+ catch {
50
+ return false;
51
+ }
52
+ }
53
+ export function localSlackStatePath(root) {
54
+ return resolve(root, ".opencomputer", "channels", "slack.local.json");
55
+ }
56
+ export function remoteSlackStatePath(root) {
57
+ return resolve(root, ".opencomputer", "channels", "slack.remote.json");
58
+ }
59
+ export async function readLocalSlackState(root) {
60
+ try {
61
+ return JSON.parse(await readFile(localSlackStatePath(root), "utf8"));
62
+ }
63
+ catch {
64
+ return undefined;
65
+ }
66
+ }
67
+ export async function readRemoteSlackState(root) {
68
+ try {
69
+ return JSON.parse(await readFile(remoteSlackStatePath(root), "utf8"));
70
+ }
71
+ catch {
72
+ return undefined;
73
+ }
74
+ }
75
+ export async function writeRemoteSlackState(root, state) {
76
+ const path = remoteSlackStatePath(root);
77
+ await mkdir(dirname(path), { recursive: true });
78
+ await writeFile(path, `${JSON.stringify(state, null, 2)}\n`, {
79
+ mode: 0o600,
80
+ });
81
+ }
82
+ export async function clearSlackState(root, mode) {
83
+ await rm(mode === "local"
84
+ ? localSlackStatePath(root)
85
+ : remoteSlackStatePath(root), { force: true });
86
+ }
87
+ export async function ensureSlackHooks(root) {
88
+ const path = resolve(root, ".slack", "hooks.json");
89
+ await mkdir(dirname(path), { recursive: true });
90
+ let existing = {};
91
+ try {
92
+ const parsed = JSON.parse(await readFile(path, "utf8"));
93
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
94
+ existing = parsed;
95
+ }
96
+ }
97
+ catch {
98
+ // A new Slack project does not have hooks yet.
99
+ }
100
+ const hooks = existing.hooks &&
101
+ typeof existing.hooks === "object" &&
102
+ !Array.isArray(existing.hooks)
103
+ ? existing.hooks
104
+ : {};
105
+ const startHook = hooks.start;
106
+ const managed = startHook === undefined ||
107
+ (typeof startHook === "string" &&
108
+ (startHook.includes("@opencomputer/cli") ||
109
+ startHook.includes(".opencomputer/slack-hook.mjs") ||
110
+ startHook.includes("@opencomputer/blue") ||
111
+ startHook.includes(".blue/slack-hook.mjs")));
112
+ if (!managed)
113
+ return;
114
+ const config = existing.config &&
115
+ typeof existing.config === "object" &&
116
+ !Array.isArray(existing.config)
117
+ ? existing.config
118
+ : {};
119
+ await writeFile(path, `${JSON.stringify({
120
+ ...existing,
121
+ hooks: { ...hooks, ...OPENCOMPUTER_SLACK_HOOKS },
122
+ config: { ...config, "sdk-managed-connection-enabled": true },
123
+ }, null, 2)}\n`);
124
+ const bridge = resolve(root, ".opencomputer", "slack-hook.mjs");
125
+ await mkdir(dirname(bridge), { recursive: true });
126
+ await writeFile(bridge, OPENCOMPUTER_SLACK_HOOK_BRIDGE, { mode: 0o755 });
127
+ }
128
+ export async function requireSlackAgentRoot() {
129
+ const root = await findAgentRoot();
130
+ if (!root || !(await exists(resolve(root, "channels", "slack.ts")))) {
131
+ throw new Error("Run `opencomputer channels add slack` inside an agent repository first.");
132
+ }
133
+ await ensureSlackHooks(root);
134
+ return root;
135
+ }
136
+ export async function slackManifest(root, mode) {
137
+ const manifest = await readManifest(root);
138
+ const remote = mode === "remote" ? await readRemoteSlackState(root) : undefined;
139
+ if (mode === "remote" && !remote?.webhookUrl) {
140
+ throw new Error("Run `opencomputer channels connect slack --remote` first.");
141
+ }
142
+ const subscriptions = {
143
+ bot_events: [
144
+ "app_mention",
145
+ "app_context_changed",
146
+ "app_home_opened",
147
+ "message.im",
148
+ ],
149
+ };
150
+ if (remote)
151
+ subscriptions.request_url = remote.webhookUrl;
152
+ return {
153
+ _metadata: { major_version: 1, minor_version: 1 },
154
+ display_information: {
155
+ name: manifest.name || basename(root),
156
+ description: `Run the ${manifest.name} OpenComputer agent from Slack.`,
157
+ background_color: "#0B1220",
158
+ },
159
+ features: {
160
+ agent_view: {
161
+ agent_description: `Work with the ${manifest.name} agent.`,
162
+ suggested_prompts: [
163
+ {
164
+ title: "Get started",
165
+ message: "Tell me what you can help with.",
166
+ },
167
+ ],
168
+ },
169
+ bot_user: {
170
+ display_name: manifest.name,
171
+ always_online: true,
172
+ },
173
+ },
174
+ oauth_config: {
175
+ scopes: {
176
+ bot: [
177
+ "app_mentions:read",
178
+ "assistant:write",
179
+ "chat:write",
180
+ "im:history",
181
+ ],
182
+ },
183
+ },
184
+ settings: {
185
+ event_subscriptions: subscriptions,
186
+ org_deploy_enabled: false,
187
+ socket_mode_enabled: mode === "local",
188
+ token_rotation_enabled: false,
189
+ },
190
+ };
191
+ }
192
+ export async function runSlackCli(root, args, mode) {
193
+ const cliEntry = process.argv[1];
194
+ await new Promise((resolvePromise, reject) => {
195
+ const child = spawn("slack", args, {
196
+ cwd: root,
197
+ stdio: "inherit",
198
+ env: {
199
+ ...process.env,
200
+ ...(cliEntry
201
+ ? {
202
+ OPENCOMPUTER_SLACK_CLI_ENTRY: cliEntry,
203
+ OPENCOMPUTER_SLACK_NODE_EXECUTABLE: process.execPath,
204
+ }
205
+ : {}),
206
+ OPENCOMPUTER_SLACK_MODE: mode,
207
+ },
208
+ });
209
+ child.once("error", (error) => {
210
+ reject(error instanceof Error && "code" in error && error.code === "ENOENT"
211
+ ? new Error("Slack CLI is required. Install it from https://docs.slack.dev/tools/slack-cli/.")
212
+ : error);
213
+ });
214
+ child.once("exit", (code, signal) => {
215
+ if (code === 0)
216
+ resolvePromise();
217
+ else {
218
+ reject(new Error(`Slack CLI exited ${signal ? `with ${signal}` : `with code ${String(code)}`}`));
219
+ }
220
+ });
221
+ });
222
+ }
223
+ export async function captureLocalSlackState(root) {
224
+ const candidates = [
225
+ resolve(root, ".slack", "apps.dev.json"),
226
+ resolve(root, ".slack", "apps.json"),
227
+ ];
228
+ for (const path of candidates) {
229
+ if (!(await exists(path)))
230
+ continue;
231
+ const parsed = JSON.parse(await readFile(path, "utf8"));
232
+ const entries = parsed.apps
233
+ ? Object.values(parsed.apps)
234
+ : Object.values(parsed).filter((entry) => Boolean(entry &&
235
+ typeof entry === "object" &&
236
+ "app_id" in entry &&
237
+ "team_id" in entry));
238
+ const selected = entries.find((entry) => entry.team_domain === parsed.default) ??
239
+ entries[0];
240
+ if (selected?.app_id && selected.team_id) {
241
+ const state = {
242
+ version: 1,
243
+ appId: selected.app_id,
244
+ teamId: selected.team_id,
245
+ teamName: selected.team_domain,
246
+ };
247
+ const output = localSlackStatePath(root);
248
+ await mkdir(dirname(output), { recursive: true });
249
+ await writeFile(output, `${JSON.stringify(state, null, 2)}\n`, {
250
+ mode: 0o600,
251
+ });
252
+ return state;
253
+ }
254
+ }
255
+ throw new Error("Slack CLI did not persist the local app installation.");
256
+ }
257
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../src/slack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,44 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtemp, readFile, rm, stat } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { resolve } from "node:path";
5
+ import test from "node:test";
6
+ import { addSlackChannel, initializeAgentProject, } from "./project.js";
7
+ import { ensureSlackHooks, slackManifest, writeRemoteSlackState, } from "./slack.js";
8
+ const template = {
9
+ id: "research",
10
+ name: "Research agent",
11
+ description: "Research a topic.",
12
+ category: "Insights",
13
+ integrations: [],
14
+ suggestedPrompts: ["Research this topic."],
15
+ };
16
+ test("Slack channel state renders local and remote manifests", async () => {
17
+ const parent = await mkdtemp(resolve(tmpdir(), "opencomputer-slack-"));
18
+ const root = resolve(parent, "research-agent");
19
+ try {
20
+ await initializeAgentProject(template, root);
21
+ await addSlackChannel(root);
22
+ await ensureSlackHooks(root);
23
+ const local = await slackManifest(root, "local");
24
+ assert.equal(local.settings.socket_mode_enabled, true);
25
+ assert.equal((await stat(resolve(root, ".opencomputer", "slack-hook.mjs"))).isFile(), true);
26
+ assert.match(await readFile(resolve(root, ".slack", "hooks.json"), "utf8"), /@opencomputer|opencomputer/);
27
+ await writeRemoteSlackState(root, {
28
+ version: 1,
29
+ connectionId: "channel-1",
30
+ agentId: "research-agent@production",
31
+ webhookUrl: "https://example.com/slack/events",
32
+ apiUrl: "https://example.com",
33
+ });
34
+ const remote = await slackManifest(root, "remote");
35
+ const settings = remote.settings;
36
+ const subscriptions = settings.event_subscriptions;
37
+ assert.equal(settings.socket_mode_enabled, false);
38
+ assert.equal(subscriptions.request_url, "https://example.com/slack/events");
39
+ }
40
+ finally {
41
+ await rm(parent, { recursive: true, force: true });
42
+ }
43
+ });
44
+ //# sourceMappingURL=slack.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.test.js","sourceRoot":"","sources":["../src/slack.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EACL,eAAe,EACf,sBAAsB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAEpB,MAAM,QAAQ,GAAyB;IACrC,EAAE,EAAE,UAAU;IACd,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,mBAAmB;IAChC,QAAQ,EAAE,UAAU;IACpB,YAAY,EAAE,EAAE;IAChB,gBAAgB,EAAE,CAAC,sBAAsB,CAAC;CAC3C,CAAC;AAEF,IAAI,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;IACxE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC7C,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAE7B,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CACT,KAAK,CAAC,QAAoC,CAAC,mBAAmB,EAC/D,IAAI,CACL,CAAC;QACF,MAAM,CAAC,KAAK,CACV,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EACvE,IAAI,CACL,CAAC;QACF,MAAM,CAAC,KAAK,CACV,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,EAC7D,4BAA4B,CAC7B,CAAC;QAEF,MAAM,qBAAqB,CAAC,IAAI,EAAE;YAChC,OAAO,EAAE,CAAC;YACV,YAAY,EAAE,WAAW;YACzB,OAAO,EAAE,2BAA2B;YACpC,UAAU,EAAE,kCAAkC;YAC9C,MAAM,EAAE,qBAAqB;SAC9B,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAmC,CAAC;QAC5D,MAAM,aAAa,GAAG,QAAQ,CAAC,mBAG9B,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CACV,aAAa,CAAC,WAAW,EACzB,kCAAkC,CACnC,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;AACH,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencomputer/cli",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "Build, test, connect, deploy, and share OpenComputer agents as code.",
5
5
  "type": "module",
6
6
  "bin": {