@hoverlover/cc-discord 0.1.0 → 0.2.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.
@@ -22,12 +22,13 @@ import { SqliteMemoryStore } from "../memory/providers/sqlite/SqliteMemoryStore.
22
22
 
23
23
  const __dirname = dirname(fileURLToPath(import.meta.url));
24
24
  const ROOT_DIR = process.env.ORCHESTRATOR_DIR || join(__dirname, "..");
25
+ const DATA_DIR = process.env.CC_DISCORD_DATA_DIR || join(process.env.HOME || "", ".cc-discord", "data");
25
26
 
26
27
  const agentId = process.env.AGENT_ID || process.env.CLAUDE_AGENT_ID || "claude";
27
28
  const sessionId =
28
29
  process.env.DISCORD_SESSION_ID || process.env.BROKER_SESSION_ID || process.env.SESSION_ID || "default";
29
30
 
30
- const dbPath = join(ROOT_DIR, "data", "messages.db");
31
+ const dbPath = join(DATA_DIR, "messages.db");
31
32
 
32
33
  const noopLogger = {
33
34
  log() {},
@@ -36,7 +37,7 @@ const noopLogger = {
36
37
  };
37
38
 
38
39
  async function syncRuntimeContext({ hookEvent, hookInput }: { hookEvent: string; hookInput: any }) {
39
- const memoryDbPath = join(ROOT_DIR, "data", "memory.db");
40
+ const memoryDbPath = join(DATA_DIR, "memory.db");
40
41
  const memorySessionKey = buildMemorySessionKey({ sessionId, agentId });
41
42
  const runtimeHint = process.env.CLAUDE_RUNTIME_ID || hookInput?.session_id || hookInput?.sessionId || null;
42
43
 
@@ -71,7 +72,7 @@ async function syncRuntimeContext({ hookEvent, hookInput }: { hookEvent: string;
71
72
  }
72
73
 
73
74
  async function buildMemoryContext({ queryText, runtimeState }: { queryText: string; runtimeState: any }) {
74
- const memoryDbPath = join(ROOT_DIR, "data", "memory.db");
75
+ const memoryDbPath = join(DATA_DIR, "memory.db");
75
76
  const memorySessionKey = buildMemorySessionKey({ sessionId, agentId });
76
77
 
77
78
  let store: SqliteMemoryStore | undefined;
@@ -16,12 +16,13 @@ import { fileURLToPath } from "node:url";
16
16
 
17
17
  const __dirname = dirname(fileURLToPath(import.meta.url));
18
18
  const ROOT_DIR = process.env.ORCHESTRATOR_DIR || join(__dirname, "..");
19
+ const DATA_DIR = process.env.CC_DISCORD_DATA_DIR || join(process.env.HOME || "", ".cc-discord", "data");
19
20
 
20
21
  const agentId = process.env.AGENT_ID || process.env.CLAUDE_AGENT_ID || "claude";
21
22
  const sessionId =
22
23
  process.env.DISCORD_SESSION_ID || process.env.BROKER_SESSION_ID || process.env.SESSION_ID || "default";
23
24
 
24
- const dbPath = join(ROOT_DIR, "data", "messages.db");
25
+ const dbPath = join(DATA_DIR, "messages.db");
25
26
 
26
27
  let hookInput: any;
27
28
  try {
@@ -22,6 +22,7 @@ import { fileURLToPath } from "node:url";
22
22
 
23
23
  const __dirname = dirname(fileURLToPath(import.meta.url));
24
24
  const ROOT_DIR = process.env.ORCHESTRATOR_DIR || join(__dirname, "..");
25
+ const DATA_DIR = process.env.CC_DISCORD_DATA_DIR || join(process.env.HOME || "", ".cc-discord", "data");
25
26
 
26
27
  const agentId = process.env.AGENT_ID || process.env.CLAUDE_AGENT_ID || "claude";
27
28
  const sessionId =
@@ -30,7 +31,7 @@ const traceEnabled = String(process.env.TRACE_THREAD_ENABLED || "true").toLowerC
30
31
  // In channel routing mode, agent_id IS the Discord channel ID
31
32
  const traceChannelId = agentId;
32
33
 
33
- const dbPath = join(ROOT_DIR, "data", "messages.db");
34
+ const dbPath = join(DATA_DIR, "messages.db");
34
35
 
35
36
  const input = await readHookInput();
36
37
  if (!input) process.exit(0);
@@ -5,7 +5,7 @@ import { dirname, join } from "node:path";
5
5
  import { MemoryStore } from "../../core/MemoryStore.ts";
6
6
  import { clamp, MemoryCardTypes, MemoryScopes, nowIso, safeJsonParse, safeJsonStringify } from "../../core/types.ts";
7
7
 
8
- const DEFAULT_DB_PATH = join(process.cwd(), "data", "memory.db");
8
+ const DEFAULT_DB_PATH = join(process.env.CC_DISCORD_DATA_DIR || join(process.env.HOME || "", ".cc-discord", "data"), "memory.db");
9
9
 
10
10
  const SCHEMA_SQL = `
11
11
  CREATE TABLE IF NOT EXISTS memory_sessions (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hoverlover/cc-discord",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Discord <-> Claude Code relay: use your Claude subscription to power per-channel AI bots",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,7 +13,13 @@ set -euo pipefail
13
13
  CHANNEL_ID="${1:?Usage: channel-agent.sh <channel_id> <channel_name>}"
14
14
  CHANNEL_NAME="${2:-channel-$CHANNEL_ID}"
15
15
 
16
- ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
16
+ _SCRIPT="${BASH_SOURCE[0]}"
17
+ while [ -L "$_SCRIPT" ]; do
18
+ _DIR="$(cd "$(dirname "$_SCRIPT")" && pwd)"
19
+ _SCRIPT="$(readlink "$_SCRIPT")"
20
+ [[ "$_SCRIPT" != /* ]] && _SCRIPT="$_DIR/$_SCRIPT"
21
+ done
22
+ ROOT_DIR="$(cd "$(dirname "$_SCRIPT")/.." && pwd)"
17
23
  source "$ROOT_DIR/scripts/load-env.sh"
18
24
 
19
25
  # Load worker env vars (same set as start-orchestrator.sh)
@@ -1,7 +1,13 @@
1
1
  #!/bin/bash
2
2
  set -e
3
3
 
4
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
4
+ _SCRIPT="${BASH_SOURCE[0]}"
5
+ while [ -L "$_SCRIPT" ]; do
6
+ _DIR="$(cd "$(dirname "$_SCRIPT")" && pwd)"
7
+ _SCRIPT="$(readlink "$_SCRIPT")"
8
+ [[ "$_SCRIPT" != /* ]] && _SCRIPT="$_DIR/$_SCRIPT"
9
+ done
10
+ SCRIPT_DIR="$(cd "$(dirname "$_SCRIPT")" && pwd)"
5
11
  ORCHESTRATOR_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
6
12
 
7
13
  TEMPLATE="$ORCHESTRATOR_DIR/.claude/settings.template.json"
@@ -19,7 +19,8 @@ import { dirname, join } from "node:path";
19
19
  import { fileURLToPath } from "node:url";
20
20
 
21
21
  const __dirname = dirname(fileURLToPath(import.meta.url));
22
- const dbPath = process.argv[2] || join(__dirname, "..", "data", "memory.db");
22
+ const defaultDataDir = process.env.CC_DISCORD_DATA_DIR || join(process.env.HOME || "", ".cc-discord", "data");
23
+ const dbPath = process.argv[2] || join(defaultDataDir, "memory.db");
23
24
 
24
25
  console.log(`[migrate] Opening ${dbPath}`);
25
26
  const db = new Database(dbPath);
@@ -17,7 +17,13 @@
17
17
 
18
18
  set -euo pipefail
19
19
 
20
- ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
20
+ _SCRIPT="${BASH_SOURCE[0]}"
21
+ while [ -L "$_SCRIPT" ]; do
22
+ _DIR="$(cd "$(dirname "$_SCRIPT")" && pwd)"
23
+ _SCRIPT="$(readlink "$_SCRIPT")"
24
+ [[ "$_SCRIPT" != /* ]] && _SCRIPT="$_DIR/$_SCRIPT"
25
+ done
26
+ ROOT_DIR="$(cd "$(dirname "$_SCRIPT")/.." && pwd)"
21
27
  source "$ROOT_DIR/scripts/load-env.sh"
22
28
 
23
29
  # Load relay connection env vars
@@ -38,14 +38,15 @@ const TRACE_SESSION_ID = process.env.DISCORD_SESSION_ID || process.env.SESSION_I
38
38
  const TRACE_AGENT_ID = process.env.AGENT_ID || process.env.CLAUDE_AGENT_ID || "claude";
39
39
  const TRACE_CHANNEL_ID = TRACE_AGENT_ID; // In channel routing mode, agent_id IS the channel ID
40
40
  const ORCHESTRATOR_DIR = process.env.ORCHESTRATOR_DIR || "";
41
+ const DATA_DIR = process.env.CC_DISCORD_DATA_DIR || join(process.env.HOME || "", ".cc-discord", "data");
41
42
 
42
43
  let traceDb: InstanceType<typeof DatabaseSync> | null = null;
43
44
 
44
45
  function getTraceDb(): InstanceType<typeof DatabaseSync> | null {
45
- if (!TRACE_ENABLED || !ORCHESTRATOR_DIR) return null;
46
+ if (!TRACE_ENABLED) return null;
46
47
  if (traceDb) return traceDb;
47
48
  try {
48
- const dbPath = join(ORCHESTRATOR_DIR, "data", "messages.db");
49
+ const dbPath = join(DATA_DIR, "messages.db");
49
50
  traceDb = new DatabaseSync(dbPath);
50
51
  traceDb.exec(`
51
52
  CREATE TABLE IF NOT EXISTS trace_events (
@@ -1,7 +1,13 @@
1
1
  #!/bin/bash
2
2
  set -euo pipefail
3
3
 
4
- ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
4
+ _SCRIPT="${BASH_SOURCE[0]}"
5
+ while [ -L "$_SCRIPT" ]; do
6
+ _DIR="$(cd "$(dirname "$_SCRIPT")" && pwd)"
7
+ _SCRIPT="$(readlink "$_SCRIPT")"
8
+ [[ "$_SCRIPT" != /* ]] && _SCRIPT="$_DIR/$_SCRIPT"
9
+ done
10
+ ROOT_DIR="$(cd "$(dirname "$_SCRIPT")/.." && pwd)"
5
11
  source "$ROOT_DIR/scripts/load-env.sh"
6
12
 
7
13
  WORKER_KEYS=(
@@ -1,7 +1,13 @@
1
1
  #!/bin/bash
2
2
  set -e
3
3
 
4
- ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
4
+ _SCRIPT="${BASH_SOURCE[0]}"
5
+ while [ -L "$_SCRIPT" ]; do
6
+ _DIR="$(cd "$(dirname "$_SCRIPT")" && pwd)"
7
+ _SCRIPT="$(readlink "$_SCRIPT")"
8
+ [[ "$_SCRIPT" != /* ]] && _SCRIPT="$_DIR/$_SCRIPT"
9
+ done
10
+ ROOT_DIR="$(cd "$(dirname "$_SCRIPT")/.." && pwd)"
5
11
  source "$ROOT_DIR/scripts/load-env.sh"
6
12
  # Preferred split env file for relay process
7
13
  load_env_file "$ROOT_DIR/.env.relay"
package/scripts/start.sh CHANGED
@@ -22,7 +22,14 @@
22
22
 
23
23
  set -euo pipefail
24
24
 
25
- ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
25
+ # Resolve symlinks so ROOT_DIR is correct when invoked via bunx (which symlinks the bin entry)
26
+ _SCRIPT="${BASH_SOURCE[0]}"
27
+ while [ -L "$_SCRIPT" ]; do
28
+ _DIR="$(cd "$(dirname "$_SCRIPT")" && pwd)"
29
+ _SCRIPT="$(readlink "$_SCRIPT")"
30
+ [[ "$_SCRIPT" != /* ]] && _SCRIPT="$_DIR/$_SCRIPT"
31
+ done
32
+ ROOT_DIR="$(cd "$(dirname "$_SCRIPT")/.." && pwd)"
26
33
 
27
34
  # User config directory (~/.config/cc-discord by default, override with CC_DISCORD_CONFIG_DIR)
28
35
  export CC_DISCORD_CONFIG_DIR="${CC_DISCORD_CONFIG_DIR:-$HOME/.config/cc-discord}"
package/server/config.ts CHANGED
@@ -8,7 +8,9 @@ import { fileURLToPath } from "node:url";
8
8
 
9
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
10
10
  export const ROOT_DIR = join(__dirname, "..");
11
- export const DATA_DIR = join(ROOT_DIR, "data");
11
+ export const DATA_DIR =
12
+ process.env.CC_DISCORD_DATA_DIR ||
13
+ join(process.env.HOME || "", ".cc-discord", "data");
12
14
 
13
15
  // User config directory (~/.config/cc-discord by default, override with CC_DISCORD_CONFIG_DIR)
14
16
  const CONFIG_DIR =
@@ -15,7 +15,8 @@ import { fileURLToPath } from "node:url";
15
15
 
16
16
  const __dirname = dirname(fileURLToPath(import.meta.url));
17
17
  const ROOT_DIR = process.env.ORCHESTRATOR_DIR || join(__dirname, "..");
18
- const dbPath = join(ROOT_DIR, "data", "memory.db");
18
+ const DATA_DIR = process.env.CC_DISCORD_DATA_DIR || join(process.env.HOME || "", ".cc-discord", "data");
19
+ const dbPath = join(DATA_DIR, "memory.db");
19
20
 
20
21
  const args = process.argv.slice(2);
21
22
  let searchTerm: string | null = null;
@@ -29,6 +29,7 @@ import { SqliteMemoryStore } from "../memory/providers/sqlite/SqliteMemoryStore.
29
29
 
30
30
  const __dirname = dirname(fileURLToPath(import.meta.url));
31
31
  const ROOT_DIR = process.env.ORCHESTRATOR_DIR || join(__dirname, "..");
32
+ const DATA_DIR = process.env.CC_DISCORD_DATA_DIR || join(process.env.HOME || "", ".cc-discord", "data");
32
33
 
33
34
  const args = process.argv.slice(2);
34
35
  let agentId = process.env.AGENT_ID || process.env.CLAUDE_AGENT_ID || "claude";
@@ -57,7 +58,7 @@ for (let i = 0; i < args.length; i++) {
57
58
  }
58
59
  }
59
60
 
60
- const dbPath = join(ROOT_DIR, "data", "messages.db");
61
+ const dbPath = join(DATA_DIR, "messages.db");
61
62
  // When agent ID is a numeric channel ID (subagent mode), only match that exact ID.
62
63
  // Otherwise use the legacy multi-target matching.
63
64
  const isChannelAgent = /^\d{15,22}$/.test(agentId);
@@ -166,7 +167,7 @@ process.on("exit", () => {
166
167
  });
167
168
 
168
169
  async function buildMemoryContext(queryText: string): Promise<string> {
169
- const memoryDbPath = join(ROOT_DIR, "data", "memory.db");
170
+ const memoryDbPath = join(DATA_DIR, "memory.db");
170
171
  const memorySessionKey = buildMemorySessionKey({ sessionId, agentId, channelId: channelFilter || undefined });
171
172
  const runtimeHint = process.env.CLAUDE_RUNTIME_ID || null;
172
173