compass-agent 2.0.7 → 2.0.9

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/.env.example ADDED
@@ -0,0 +1,3 @@
1
+ SLACK_APP_TOKEN=xapp-1-...
2
+ SLACK_BOT_TOKEN=xoxb-...
3
+ ALLOWED_USERS=
@@ -3,8 +3,7 @@ name: Publish to npm
3
3
  on:
4
4
  release:
5
5
  types: [published]
6
- push:
7
- branches: [main]
6
+ workflow_dispatch:
8
7
 
9
8
  jobs:
10
9
  publish:
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  Bring workforce of Claude Codes to your Slack workspace. Every thread becomes an isolated coding session — with its own working directory, git worktree, and full access to your local filesystem. Claude runs on your machine, streams responses in real-time, and your whole team can use it simultaneously without conflicts.
8
8
 
9
- ![Agentic task visualization with sub-agents](assets/sub-agent.png)
9
+ ![Agentic task visualization with sub-agents](docs/assets/sub-agent.png)
10
10
 
11
11
  ## Quick start
12
12
 
@@ -45,7 +45,7 @@ Set the working directory for Claude to read/write files.
45
45
 
46
46
  The picker remembers previously used directories. CWD is stored per-thread in SQLite.
47
47
 
48
- ![Working directory set in channel](assets/streaming-feedback.png)
48
+ ![Working directory set in channel](docs/assets/streaming-feedback.png)
49
49
 
50
50
  ### `$teach` — Team knowledge base
51
51
 
@@ -77,7 +77,7 @@ Responses stream token-by-token using Slack's native `chatStream` API, with auto
77
77
 
78
78
  Tool calls are visualized as an agentic timeline — each invocation (file reads, edits, shell commands) appears as a step that progresses from in-progress to complete.
79
79
 
80
- ![Streaming response with planning and sub-agents](assets/planning-streaming.png)
80
+ ![Streaming response with planning and sub-agents](docs/assets/planning-streaming.png)
81
81
 
82
82
  ### Git worktree isolation
83
83
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compass-agent",
3
- "version": "2.0.7",
3
+ "version": "2.0.9",
4
4
  "type": "module",
5
5
  "description": "Bring Claude Code to your Slack workspace — per-thread AI coding sessions with full local filesystem access",
6
6
  "bin": {
package/src/app.ts CHANGED
@@ -33,6 +33,26 @@ if (envFileIdx !== -1 && process.argv[envFileIdx + 1]) {
33
33
  Object.assign(process.env, realEnv);
34
34
  // -----------------------------------------------------------------------------------------
35
35
 
36
+ // --- Required env validation ---
37
+ const requiredEnv = ["SLACK_BOT_TOKEN", "SLACK_APP_TOKEN"] as const;
38
+ const missing = requiredEnv.filter((k) => !process.env[k]);
39
+ if (missing.length > 0) {
40
+ console.error(`ERROR: Missing required environment variable(s): ${missing.join(", ")}`);
41
+ process.exit(1);
42
+ }
43
+
44
+ // Validate CLAUDE_PATH exists
45
+ const claudePath = process.env.CLAUDE_PATH || "claude";
46
+ if (path.isAbsolute(claudePath)) {
47
+ if (!fs.existsSync(claudePath)) {
48
+ console.error(`ERROR: CLAUDE_PATH not found: ${claudePath}`);
49
+ process.exit(1);
50
+ }
51
+ } else if (!Bun.which(claudePath)) {
52
+ console.error(`ERROR: CLAUDE_PATH "${claudePath}" not found in PATH. Set CLAUDE_PATH in .env to the full path of the claude binary.`);
53
+ process.exit(1);
54
+ }
55
+
36
56
  import { App } from "@slack/bolt";
37
57
  import { execFileSync } from "child_process";
38
58
  import {
@@ -219,8 +239,6 @@ app.command("/cwd", async ({ command, ack, client }: any) => {
219
239
  });
220
240
  });
221
241
 
222
- const CLAUDE_PATH = process.env.CLAUDE_PATH || "claude";
223
-
224
242
  // ── Modal submissions ───────────────────────────────────────
225
243
 
226
244
  app.view("cwd_modal", async ({ view, ack, client }: any) => {
@@ -647,25 +665,17 @@ async function processMessage({ channelId, threadTs, messageTs, userText, userId
647
665
  // ── Startup ─────────────────────────────────────────────────
648
666
 
649
667
  (async () => {
650
- // Validate CLAUDE_PATH exists before starting
651
- const claudePath = process.env.CLAUDE_PATH || "claude";
652
- // Check if it's an absolute path that exists, or resolve via Bun.which
653
- if (path.isAbsolute(claudePath)) {
654
- if (!fs.existsSync(claudePath)) {
655
- console.error(`ERROR: CLAUDE_PATH not found: ${claudePath}`);
656
- process.exit(1);
657
- }
658
- } else if (!Bun.which(claudePath)) {
659
- console.error(`ERROR: CLAUDE_PATH "${claudePath}" not found in PATH. Set CLAUDE_PATH in .env to the full path of the claude binary.`);
660
- process.exit(1);
661
- }
662
668
  log(null, `Claude CLI found: ${claudePath}`);
663
669
 
664
- // Register MCP server (idempotent overwrites if already exists)
670
+ // Register MCP server (remove first to ensure it points to latest)
665
671
  try {
666
672
  const mcpServerPath = path.join(import.meta.dir, "mcp", "server.ts");
667
673
  const mcpEnv: Record<string, string | undefined> = { ...process.env };
668
674
  delete mcpEnv.CLAUDECODE; // avoid nested-session check
675
+ const execOpts = { encoding: "utf-8" as const, timeout: 10000, env: mcpEnv as NodeJS.ProcessEnv, stdio: ["pipe", "pipe", "pipe"] as const };
676
+ try {
677
+ execFileSync(claudePath, ["mcp", "remove", "--scope", "user", "compass"], execOpts);
678
+ } catch {}
669
679
  execFileSync(claudePath, [
670
680
  "mcp", "add",
671
681
  "--transport", "stdio",
@@ -673,7 +683,7 @@ async function processMessage({ channelId, threadTs, messageTs, userText, userId
673
683
  "compass",
674
684
  "--",
675
685
  "bun", mcpServerPath,
676
- ], { encoding: "utf-8", timeout: 10000, env: mcpEnv as NodeJS.ProcessEnv, stdio: ["pipe", "pipe", "pipe"] });
686
+ ], execOpts);
677
687
  log(null, `MCP server registered: compass -> ${mcpServerPath}`);
678
688
  } catch (err: any) {
679
689
  logErr(null, `Failed to register MCP server (non-fatal): ${err.message}`);
Binary file
Binary file
Binary file