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 +3 -0
- package/.github/workflows/publish.yml +1 -2
- package/README.md +3 -3
- package/package.json +1 -1
- package/src/app.ts +26 -16
- package/assets/planning-streaming.png +0 -0
- package/assets/streaming-feedback.png +0 -0
- package/assets/sub-agent.png +0 -0
package/.env.example
ADDED
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
|
-

|
|
9
|
+

|
|
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
|
-

|
|
48
|
+

|
|
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
|
-

|
|
80
|
+

|
|
81
81
|
|
|
82
82
|
### Git worktree isolation
|
|
83
83
|
|
package/package.json
CHANGED
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 (
|
|
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
|
-
],
|
|
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
|
package/assets/sub-agent.png
DELETED
|
Binary file
|