@brianli/kimaki 0.4.72-brianli.4 → 0.4.72-brianli.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/dist/database.js CHANGED
@@ -3,7 +3,7 @@
3
3
  // API keys, and model preferences in <dataDir>/discord-sessions.db.
4
4
  import { getPrisma, closePrisma } from './db.js';
5
5
  import { getDefaultVerbosity, getDefaultMentionMode } from './config.js';
6
- import { hydrateBotTokenCache, isAuthModeEnabled } from './bot-token.js';
6
+ import { hydrateBotTokenCache } from './bot-token.js';
7
7
  import { createLogger, LogPrefix } from './logger.js';
8
8
  const dbLogger = createLogger(LogPrefix.DB);
9
9
  // Re-export Prisma utilities
@@ -719,9 +719,6 @@ export async function setPartMessagesBatch(partMappings) {
719
719
  * Store a bot token.
720
720
  */
721
721
  export async function setBotToken(appId, token) {
722
- if (isAuthModeEnabled()) {
723
- return;
724
- }
725
722
  const prisma = await getPrisma();
726
723
  await prisma.bot_tokens.upsert({
727
724
  where: { app_id: appId },
package/dist/db.test.js CHANGED
@@ -1,10 +1,17 @@
1
1
  // Tests for Prisma client initialization and schema migration.
2
2
  // Auto-isolated via VITEST guards in config.ts (temp data dir) and db.ts (clears KIMAKI_DB_URL).
3
+ import crypto from 'node:crypto';
3
4
  import { afterAll, describe, expect, test } from 'vitest';
4
5
  import { getPrisma, closePrisma } from './db.js';
5
- import { createPendingWorktree } from './database.js';
6
+ import { createPendingWorktree, setBotToken, setChannelDirectory, } from './database.js';
7
+ const ORIGINAL_GUILD_ID = process.env.KIMAKI_GUILD_ID;
8
+ const ORIGINAL_PRIVATE_KEY = process.env.KIMAKI_PRIVATE_KEY;
9
+ const ORIGINAL_APP_ID = process.env.KIMAKI_APP_ID;
6
10
  afterAll(async () => {
7
11
  await closePrisma();
12
+ process.env.KIMAKI_GUILD_ID = ORIGINAL_GUILD_ID;
13
+ process.env.KIMAKI_PRIVATE_KEY = ORIGINAL_PRIVATE_KEY;
14
+ process.env.KIMAKI_APP_ID = ORIGINAL_APP_ID;
8
15
  });
9
16
  describe('getPrisma', () => {
10
17
  test('creates sqlite file and migrates schema automatically', async () => {
@@ -46,4 +53,36 @@ describe('getPrisma', () => {
46
53
  await prisma.thread_worktrees.delete({ where: { thread_id: threadId } });
47
54
  await prisma.thread_sessions.delete({ where: { thread_id: threadId } });
48
55
  });
56
+ test('auth mode still seeds bot_tokens so channel directory upsert passes foreign key checks', async () => {
57
+ const { privateKey } = crypto.generateKeyPairSync('ed25519');
58
+ const appId = `app-${Date.now()}`;
59
+ const channelId = `channel-${Date.now()}`;
60
+ process.env.KIMAKI_GUILD_ID = '1477130736841658398';
61
+ process.env.KIMAKI_APP_ID = appId;
62
+ process.env.KIMAKI_PRIVATE_KEY = privateKey
63
+ .export({ format: 'pem', type: 'pkcs8' })
64
+ .toString();
65
+ await setBotToken(appId, 'auth-mode-seed-token');
66
+ await setChannelDirectory({
67
+ channelId,
68
+ directory: `./tmp/${channelId}`,
69
+ channelType: 'text',
70
+ appId,
71
+ });
72
+ const prisma = await getPrisma();
73
+ const botRow = await prisma.bot_tokens.findUnique({
74
+ where: { app_id: appId },
75
+ });
76
+ expect(botRow?.app_id).toBe(appId);
77
+ const channelRow = await prisma.channel_directories.findUnique({
78
+ where: { channel_id: channelId },
79
+ });
80
+ expect(channelRow?.app_id).toBe(appId);
81
+ await prisma.channel_directories.deleteMany({
82
+ where: { channel_id: channelId },
83
+ });
84
+ await prisma.bot_tokens.deleteMany({
85
+ where: { app_id: appId },
86
+ });
87
+ });
49
88
  });
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@brianli/kimaki",
3
3
  "module": "index.ts",
4
4
  "type": "module",
5
- "version": "0.4.72-brianli.4",
5
+ "version": "0.4.72-brianli.5",
6
6
  "repository": "https://github.com/remorses/kimaki",
7
7
  "bin": "bin.js",
8
8
  "files": [
@@ -21,9 +21,9 @@
21
21
  "@types/node": "^24.3.0",
22
22
  "prisma": "7.3.0",
23
23
  "tsx": "^4.20.5",
24
- "discord-digital-twin": "^0.0.1",
24
+ "opencode-deterministic-provider": "^0.0.1",
25
25
  "opencode-cached-provider": "^0.0.1",
26
- "opencode-deterministic-provider": "^0.0.1"
26
+ "discord-digital-twin": "^0.0.1"
27
27
  },
28
28
  "dependencies": {
29
29
  "@ai-sdk/google": "^3.0.30",
package/src/database.ts CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { getPrisma, closePrisma } from './db.js'
6
6
  import { getDefaultVerbosity, getDefaultMentionMode } from './config.js'
7
- import { hydrateBotTokenCache, isAuthModeEnabled } from './bot-token.js'
7
+ import { hydrateBotTokenCache } from './bot-token.js'
8
8
  import { createLogger, LogPrefix } from './logger.js'
9
9
 
10
10
  const dbLogger = createLogger(LogPrefix.DB)
@@ -1075,9 +1075,6 @@ export async function setPartMessagesBatch(
1075
1075
  * Store a bot token.
1076
1076
  */
1077
1077
  export async function setBotToken(appId: string, token: string): Promise<void> {
1078
- if (isAuthModeEnabled()) {
1079
- return
1080
- }
1081
1078
  const prisma = await getPrisma()
1082
1079
  await prisma.bot_tokens.upsert({
1083
1080
  where: { app_id: appId },
package/src/db.test.ts CHANGED
@@ -1,12 +1,24 @@
1
1
  // Tests for Prisma client initialization and schema migration.
2
2
  // Auto-isolated via VITEST guards in config.ts (temp data dir) and db.ts (clears KIMAKI_DB_URL).
3
3
 
4
+ import crypto from 'node:crypto'
4
5
  import { afterAll, describe, expect, test } from 'vitest'
5
6
  import { getPrisma, closePrisma } from './db.js'
6
- import { createPendingWorktree } from './database.js'
7
+ import {
8
+ createPendingWorktree,
9
+ setBotToken,
10
+ setChannelDirectory,
11
+ } from './database.js'
12
+
13
+ const ORIGINAL_GUILD_ID = process.env.KIMAKI_GUILD_ID
14
+ const ORIGINAL_PRIVATE_KEY = process.env.KIMAKI_PRIVATE_KEY
15
+ const ORIGINAL_APP_ID = process.env.KIMAKI_APP_ID
7
16
 
8
17
  afterAll(async () => {
9
18
  await closePrisma()
19
+ process.env.KIMAKI_GUILD_ID = ORIGINAL_GUILD_ID
20
+ process.env.KIMAKI_PRIVATE_KEY = ORIGINAL_PRIVATE_KEY
21
+ process.env.KIMAKI_APP_ID = ORIGINAL_APP_ID
10
22
  })
11
23
 
12
24
  describe('getPrisma', () => {
@@ -57,4 +69,42 @@ describe('getPrisma', () => {
57
69
  await prisma.thread_worktrees.delete({ where: { thread_id: threadId } })
58
70
  await prisma.thread_sessions.delete({ where: { thread_id: threadId } })
59
71
  })
72
+
73
+ test('auth mode still seeds bot_tokens so channel directory upsert passes foreign key checks', async () => {
74
+ const { privateKey } = crypto.generateKeyPairSync('ed25519')
75
+ const appId = `app-${Date.now()}`
76
+ const channelId = `channel-${Date.now()}`
77
+
78
+ process.env.KIMAKI_GUILD_ID = '1477130736841658398'
79
+ process.env.KIMAKI_APP_ID = appId
80
+ process.env.KIMAKI_PRIVATE_KEY = privateKey
81
+ .export({ format: 'pem', type: 'pkcs8' })
82
+ .toString()
83
+
84
+ await setBotToken(appId, 'auth-mode-seed-token')
85
+ await setChannelDirectory({
86
+ channelId,
87
+ directory: `./tmp/${channelId}`,
88
+ channelType: 'text',
89
+ appId,
90
+ })
91
+
92
+ const prisma = await getPrisma()
93
+ const botRow = await prisma.bot_tokens.findUnique({
94
+ where: { app_id: appId },
95
+ })
96
+ expect(botRow?.app_id).toBe(appId)
97
+
98
+ const channelRow = await prisma.channel_directories.findUnique({
99
+ where: { channel_id: channelId },
100
+ })
101
+ expect(channelRow?.app_id).toBe(appId)
102
+
103
+ await prisma.channel_directories.deleteMany({
104
+ where: { channel_id: channelId },
105
+ })
106
+ await prisma.bot_tokens.deleteMany({
107
+ where: { app_id: appId },
108
+ })
109
+ })
60
110
  })