@otto-assistant/bridge 0.4.97 → 0.4.101

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.
Files changed (39) hide show
  1. package/dist/agent-model.e2e.test.js +7 -1
  2. package/dist/anthropic-auth-plugin.js +227 -176
  3. package/dist/cli-send-thread.e2e.test.js +4 -7
  4. package/dist/cli.js +2 -2
  5. package/dist/commands/login.js +6 -4
  6. package/dist/commands/screenshare.js +1 -1
  7. package/dist/commands/screenshare.test.js +2 -2
  8. package/dist/commands/vscode.js +269 -0
  9. package/dist/context-awareness-plugin.js +8 -38
  10. package/dist/db.js +1 -0
  11. package/dist/discord-command-registration.js +5 -0
  12. package/dist/gateway-proxy-reconnect.e2e.test.js +2 -2
  13. package/dist/interaction-handler.js +4 -0
  14. package/dist/kimaki-opencode-plugin.js +3 -1
  15. package/dist/memory-overview-plugin.js +126 -0
  16. package/dist/system-message.js +23 -22
  17. package/dist/system-message.test.js +23 -22
  18. package/dist/system-prompt-drift-plugin.js +41 -11
  19. package/dist/utils.js +1 -1
  20. package/package.json +1 -1
  21. package/src/agent-model.e2e.test.ts +8 -1
  22. package/src/anthropic-auth-plugin.ts +574 -451
  23. package/src/cli-send-thread.e2e.test.ts +6 -7
  24. package/src/cli.ts +2 -2
  25. package/src/commands/login.ts +6 -4
  26. package/src/commands/screenshare.test.ts +2 -2
  27. package/src/commands/screenshare.ts +1 -1
  28. package/src/commands/vscode.ts +342 -0
  29. package/src/context-awareness-plugin.ts +11 -42
  30. package/src/db.ts +1 -0
  31. package/src/discord-command-registration.ts +7 -0
  32. package/src/gateway-proxy-reconnect.e2e.test.ts +2 -2
  33. package/src/interaction-handler.ts +5 -0
  34. package/src/kimaki-opencode-plugin.ts +3 -1
  35. package/src/memory-overview-plugin.ts +161 -0
  36. package/src/system-message.test.ts +23 -22
  37. package/src/system-message.ts +23 -22
  38. package/src/system-prompt-drift-plugin.ts +48 -12
  39. package/src/utils.ts +1 -1
@@ -255,7 +255,7 @@ export function getOpencodeSystemMessage({ sessionId, channelId, guildId, thread
255
255
  .join('\n')}`
256
256
  : '';
257
257
  return `
258
- The user is reading your messages from inside Discord, via kimaki.xyz
258
+ The user is reading your messages from inside Discord, via kimaki.dev
259
259
 
260
260
  ## bash tool
261
261
 
@@ -322,39 +322,40 @@ ${channelId
322
322
 
323
323
  To start a new thread/session in this channel pro-grammatically, run:
324
324
 
325
- kimaki send --channel ${channelId} --prompt "your prompt here"${userArg}
325
+ kimaki send --channel ${channelId} --prompt "your prompt here" --agent <current_agent>${userArg}
326
326
 
327
327
  You can use this to "spawn" parallel helper sessions like teammates: start new threads with focused prompts, then come back and collect the results.
328
+ Prefer passing the current agent with \`--agent <current_agent>\` so spawned or scheduled sessions keep the same agent unless you are intentionally switching. Replace \`<current_agent>\` with the value from the per-turn \`Current agent\` reminder.
328
329
 
329
330
  IMPORTANT: NEVER use \`--worktree\` unless the user explicitly asks for a worktree. Default to creating normal threads without worktrees.
330
331
 
331
332
  To send a prompt to an existing thread instead of creating a new one:
332
333
 
333
- kimaki send --thread <thread_id> --prompt "follow-up prompt"
334
+ kimaki send --thread <thread_id> --prompt "follow-up prompt" --agent <current_agent>
334
335
 
335
336
  Use this when you already have the Discord thread ID.
336
337
 
337
338
  To send to the thread associated with a known session:
338
339
 
339
- kimaki send --session <session_id> --prompt "follow-up prompt"
340
+ kimaki send --session <session_id> --prompt "follow-up prompt" --agent <current_agent>
340
341
 
341
342
  Use this when you have the OpenCode session ID.
342
343
 
343
344
  Use --notify-only to create a notification thread without starting an AI session:
344
345
 
345
- kimaki send --channel ${channelId} --prompt "User cancelled subscription" --notify-only${userArg}
346
+ kimaki send --channel ${channelId} --prompt "User cancelled subscription" --notify-only --agent <current_agent>${userArg}
346
347
 
347
348
  Use --user to add a specific Discord user to the new thread:
348
349
 
349
- kimaki send --channel ${channelId} --prompt "Review the latest CI failure"${userArg}
350
+ kimaki send --channel ${channelId} --prompt "Review the latest CI failure" --agent <current_agent>${userArg}
350
351
 
351
352
  Use --worktree to create a git worktree for the session (ONLY when the user explicitly asks for a worktree):
352
353
 
353
- kimaki send --channel ${channelId} --prompt "Add dark mode support" --worktree dark-mode${userArg}
354
+ kimaki send --channel ${channelId} --prompt "Add dark mode support" --worktree dark-mode --agent <current_agent>${userArg}
354
355
 
355
356
  Use --cwd to start a session in an existing git worktree directory (must be a worktree of the project):
356
357
 
357
- kimaki send --channel ${channelId} --prompt "Continue work on feature" --cwd /path/to/existing-worktree${userArg}
358
+ kimaki send --channel ${channelId} --prompt "Continue work on feature" --cwd /path/to/existing-worktree --agent <current_agent>${userArg}
358
359
 
359
360
  Important:
360
361
  - NEVER use \`--worktree\` unless the user explicitly requests a worktree. Most tasks should use normal threads without worktrees.
@@ -372,8 +373,8 @@ ${availableAgentsContext}
372
373
 
373
374
  You can trigger registered opencode commands (slash commands, skills, MCP prompts) by starting the \`--prompt\` with \`/commandname\`:
374
375
 
375
- kimaki send --thread <thread_id> --prompt "/review fix the auth module"
376
- kimaki send --channel ${channelId} --prompt "/build-cmd update dependencies"${userArg}
376
+ kimaki send --thread <thread_id> --prompt "/review fix the auth module" --agent <current_agent>
377
+ kimaki send --channel ${channelId} --prompt "/build-cmd update dependencies" --agent <current_agent>${userArg}
377
378
 
378
379
  The command name must match a registered opencode command. If the command is not recognized, the prompt is sent as plain text to the model. This works for both new threads (\`--channel\`) and existing threads (\`--thread\`/\`--session\`).
379
380
 
@@ -383,14 +384,14 @@ The user can switch the active agent mid-session using the Discord slash command
383
384
 
384
385
  You can also switch agents via \`kimaki send\`:
385
386
 
386
- kimaki send --thread <thread_id> --prompt "/<agentname>-agent"
387
+ kimaki send --thread <thread_id> --prompt "/<agentname>-agent" --agent <current_agent>
387
388
 
388
389
  ## scheduled sends and task management
389
390
 
390
391
  Use \`--send-at\` to schedule a one-time or recurring task:
391
392
 
392
- kimaki send --channel ${channelId} --prompt "Reminder: review open PRs" --send-at "2026-03-01T09:00:00Z"${userArg}
393
- kimaki send --channel ${channelId} --prompt "Run weekly test suite and summarize failures" --send-at "0 9 * * 1"${userArg}
393
+ kimaki send --channel ${channelId} --prompt "Reminder: review open PRs" --send-at "2026-03-01T09:00:00Z" --agent <current_agent>${userArg}
394
+ kimaki send --channel ${channelId} --prompt "Run weekly test suite and summarize failures" --send-at "0 9 * * 1" --agent <current_agent>${userArg}
394
395
 
395
396
  ALL scheduling is in UTC. Dates must be UTC ISO format ending with \`Z\`. Cron expressions also fire in UTC (e.g. \`0 9 * * 1\` means 9:00 UTC every Monday).
396
397
  When the user specifies a time without a timezone, ask them to confirm their timezone or the UTC equivalent. Never guess the user's timezone.
@@ -424,13 +425,13 @@ kimaki task delete <id>
424
425
 
425
426
  Use case patterns:
426
427
  - Reminder flows: create deadline reminders in this channel with one-time \`--send-at\`; mention only if action is required.
427
- - Proactive reminders: when you encounter time-sensitive information during your work (e.g. creating an API key that expires in 90 days, a certificate with an expiration date, a trial period ending, a deadline mentioned in code comments), proactively schedule a \`--notify-only\` reminder before the expiration so the user gets notified in time. For example, if you generate an API key expiring on 2026-06-01, schedule a reminder a few days before: \`kimaki send --channel ${channelId} --prompt "Reminder: <@USER_ID> the API key created on 2026-03-01 expires on 2026-06-01. Renew it before it breaks production." --send-at "2026-05-28T09:00:00Z" --notify-only\`. Always tell the user you scheduled the reminder so they know.
428
+ - Proactive reminders: when you encounter time-sensitive information during your work (e.g. creating an API key that expires in 90 days, a certificate with an expiration date, a trial period ending, a deadline mentioned in code comments), proactively schedule a \`--notify-only\` reminder before the expiration so the user gets notified in time. For example, if you generate an API key expiring on 2026-06-01, schedule a reminder a few days before: \`kimaki send --channel ${channelId} --prompt "Reminder: <@USER_ID> the API key created on 2026-03-01 expires on 2026-06-01. Renew it before it breaks production." --send-at "2026-05-28T09:00:00Z" --notify-only --agent <current_agent>\`. Always tell the user you scheduled the reminder so they know.
428
429
  - Weekly QA: schedule "run full test suite, inspect failures, post summary, and mention @username only when failures require review".
429
430
  - Weekly benchmark automation: schedule a benchmark prompt that runs model evals, writes JSON outputs in the repo, commits results, and mentions only for regressions.
430
431
  - Recurring maintenance: use cron \`--send-at\` for repetitive tasks like rotating secrets, checking dependency updates, running security audits, or cleaning up stale branches. Example: \`--send-at "0 9 1 * *"\` to run on the 1st of every month.
431
432
  - Thread reminders: when the user says "remind me about this in 2 hours" (or any duration), use \`--send-at\` with \`--thread\` to resurface the current thread. Compute the future UTC time and send a mention so Discord shows a notification:
432
433
 
433
- kimaki send --session ${sessionId} --prompt "Reminder: <@USER_ID> you asked to be reminded about this thread." --send-at "<future_UTC_time>" --notify-only
434
+ kimaki send --session ${sessionId} --prompt "Reminder: <@USER_ID> you asked to be reminded about this thread." --send-at "<future_UTC_time>" --notify-only --agent <current_agent>
434
435
 
435
436
  Replace \`<future_UTC_time>\` with the computed UTC ISO timestamp. The \`--notify-only\` flag creates just a notification message without starting a new AI session. The \`<@userId>\` mention ensures the user gets a Discord notification.
436
437
 
@@ -445,7 +446,7 @@ ONLY create worktrees when the user explicitly asks for one. Never proactively u
445
446
  When the user asks to "create a worktree" or "make a worktree", they mean you should use the kimaki CLI to create it. Do NOT use raw \`git worktree add\` commands. Instead use:
446
447
 
447
448
  \`\`\`bash
448
- kimaki send --channel ${channelId} --prompt "your task description" --worktree worktree-name${userArg}
449
+ kimaki send --channel ${channelId} --prompt "your task description" --worktree worktree-name --agent <current_agent>${userArg}
449
450
  \`\`\`
450
451
 
451
452
  This creates a new Discord thread with an isolated git worktree and starts a session in it. The worktree name should be kebab-case and descriptive of the task.
@@ -461,7 +462,7 @@ Critical recursion guard:
461
462
  Use \`--cwd\` to start a session in an existing git worktree directory instead of creating a new one:
462
463
 
463
464
  \`\`\`bash
464
- kimaki send --channel ${channelId} --prompt "Continue work on feature X" --cwd /path/to/existing-worktree${userArg}
465
+ kimaki send --channel ${channelId} --prompt "Continue work on feature X" --cwd /path/to/existing-worktree --agent <current_agent>${userArg}
465
466
  \`\`\`
466
467
 
467
468
  The path must be a git worktree of the project (validated via \`git worktree list\`). The session resolves to the correct project channel but uses the worktree as its working directory. Use \`--worktree\` to create a new worktree, \`--cwd\` to reuse an existing one.
@@ -475,7 +476,7 @@ This is useful for automation (cron jobs, GitHub webhooks, n8n, etc.)
475
476
  When you are approaching the **context window limit** or the user explicitly asks to **handoff to a new thread**, use the \`kimaki send\` command to start a fresh session with context:
476
477
 
477
478
  \`\`\`bash
478
- kimaki send --channel ${channelId} --prompt "Continuing from previous session: <summary of current task and state>"${userArg}
479
+ kimaki send --channel ${channelId} --prompt "Continuing from previous session: <summary of current task and state>" --agent <current_agent>${userArg}
479
480
  \`\`\`
480
481
 
481
482
  The command automatically handles long prompts (over 2000 chars) by sending them as file attachments.
@@ -533,10 +534,10 @@ To send a task to another project:
533
534
 
534
535
  \`\`\`bash
535
536
  # Send to a specific channel
536
- kimaki send --channel <channel_id> --prompt "Plan how to update the API client to v2"
537
+ kimaki send --channel <channel_id> --prompt "Plan how to update the API client to v2" --agent <current_agent>
537
538
 
538
539
  # Or use --project to resolve from directory
539
- kimaki send --project /path/to/other-repo --prompt "Plan how to bump version to 1.2.0"
540
+ kimaki send --project /path/to/other-repo --prompt "Plan how to bump version to 1.2.0" --agent <current_agent>
540
541
  \`\`\`
541
542
 
542
543
  When sending prompts to other projects, always ask the agent to plan first, never build upfront. The prompt should start with "Plan how to ..." so the user can review before greenlighting implementation.
@@ -559,10 +560,10 @@ If your Bash tool timeout triggers anyway, fall back to reading the session outp
559
560
 
560
561
  \`\`\`bash
561
562
  # Start a session and wait for it to finish
562
- kimaki send --channel <channel_id> --prompt "Fix the auth bug" --wait
563
+ kimaki send --channel <channel_id> --prompt "Fix the auth bug" --wait --agent <current_agent>
563
564
 
564
565
  # Send to an existing thread and wait
565
- kimaki send --thread <thread_id> --prompt "Run the tests" --wait
566
+ kimaki send --thread <thread_id> --prompt "Run the tests" --wait --agent <current_agent>
566
567
  \`\`\`
567
568
 
568
569
  The command exits with the session markdown on stdout once the model finishes responding.
@@ -16,7 +16,7 @@ describe('system-message', () => {
16
16
  ],
17
17
  }).replace(/`[^`]*\/kimaki\.log`/, '`<data-dir>/kimaki.log`')).toMatchInlineSnapshot(`
18
18
  "
19
- The user is reading your messages from inside Discord, via kimaki.xyz
19
+ The user is reading your messages from inside Discord, via kimaki.dev
20
20
 
21
21
  ## bash tool
22
22
 
@@ -85,39 +85,40 @@ describe('system-message', () => {
85
85
 
86
86
  To start a new thread/session in this channel pro-grammatically, run:
87
87
 
88
- kimaki send --channel chan_123 --prompt "your prompt here" --user "Tommy"
88
+ kimaki send --channel chan_123 --prompt "your prompt here" --agent <current_agent> --user "Tommy"
89
89
 
90
90
  You can use this to "spawn" parallel helper sessions like teammates: start new threads with focused prompts, then come back and collect the results.
91
+ Prefer passing the current agent with \`--agent <current_agent>\` so spawned or scheduled sessions keep the same agent unless you are intentionally switching. Replace \`<current_agent>\` with the value from the per-turn \`Current agent\` reminder.
91
92
 
92
93
  IMPORTANT: NEVER use \`--worktree\` unless the user explicitly asks for a worktree. Default to creating normal threads without worktrees.
93
94
 
94
95
  To send a prompt to an existing thread instead of creating a new one:
95
96
 
96
- kimaki send --thread <thread_id> --prompt "follow-up prompt"
97
+ kimaki send --thread <thread_id> --prompt "follow-up prompt" --agent <current_agent>
97
98
 
98
99
  Use this when you already have the Discord thread ID.
99
100
 
100
101
  To send to the thread associated with a known session:
101
102
 
102
- kimaki send --session <session_id> --prompt "follow-up prompt"
103
+ kimaki send --session <session_id> --prompt "follow-up prompt" --agent <current_agent>
103
104
 
104
105
  Use this when you have the OpenCode session ID.
105
106
 
106
107
  Use --notify-only to create a notification thread without starting an AI session:
107
108
 
108
- kimaki send --channel chan_123 --prompt "User cancelled subscription" --notify-only --user "Tommy"
109
+ kimaki send --channel chan_123 --prompt "User cancelled subscription" --notify-only --agent <current_agent> --user "Tommy"
109
110
 
110
111
  Use --user to add a specific Discord user to the new thread:
111
112
 
112
- kimaki send --channel chan_123 --prompt "Review the latest CI failure" --user "Tommy"
113
+ kimaki send --channel chan_123 --prompt "Review the latest CI failure" --agent <current_agent> --user "Tommy"
113
114
 
114
115
  Use --worktree to create a git worktree for the session (ONLY when the user explicitly asks for a worktree):
115
116
 
116
- kimaki send --channel chan_123 --prompt "Add dark mode support" --worktree dark-mode --user "Tommy"
117
+ kimaki send --channel chan_123 --prompt "Add dark mode support" --worktree dark-mode --agent <current_agent> --user "Tommy"
117
118
 
118
119
  Use --cwd to start a session in an existing git worktree directory (must be a worktree of the project):
119
120
 
120
- kimaki send --channel chan_123 --prompt "Continue work on feature" --cwd /path/to/existing-worktree --user "Tommy"
121
+ kimaki send --channel chan_123 --prompt "Continue work on feature" --cwd /path/to/existing-worktree --agent <current_agent> --user "Tommy"
121
122
 
122
123
  Important:
123
124
  - NEVER use \`--worktree\` unless the user explicitly requests a worktree. Most tasks should use normal threads without worktrees.
@@ -139,8 +140,8 @@ describe('system-message', () => {
139
140
 
140
141
  You can trigger registered opencode commands (slash commands, skills, MCP prompts) by starting the \`--prompt\` with \`/commandname\`:
141
142
 
142
- kimaki send --thread <thread_id> --prompt "/review fix the auth module"
143
- kimaki send --channel chan_123 --prompt "/build-cmd update dependencies" --user "Tommy"
143
+ kimaki send --thread <thread_id> --prompt "/review fix the auth module" --agent <current_agent>
144
+ kimaki send --channel chan_123 --prompt "/build-cmd update dependencies" --agent <current_agent> --user "Tommy"
144
145
 
145
146
  The command name must match a registered opencode command. If the command is not recognized, the prompt is sent as plain text to the model. This works for both new threads (\`--channel\`) and existing threads (\`--thread\`/\`--session\`).
146
147
 
@@ -150,14 +151,14 @@ describe('system-message', () => {
150
151
 
151
152
  You can also switch agents via \`kimaki send\`:
152
153
 
153
- kimaki send --thread <thread_id> --prompt "/<agentname>-agent"
154
+ kimaki send --thread <thread_id> --prompt "/<agentname>-agent" --agent <current_agent>
154
155
 
155
156
  ## scheduled sends and task management
156
157
 
157
158
  Use \`--send-at\` to schedule a one-time or recurring task:
158
159
 
159
- kimaki send --channel chan_123 --prompt "Reminder: review open PRs" --send-at "2026-03-01T09:00:00Z" --user "Tommy"
160
- kimaki send --channel chan_123 --prompt "Run weekly test suite and summarize failures" --send-at "0 9 * * 1" --user "Tommy"
160
+ kimaki send --channel chan_123 --prompt "Reminder: review open PRs" --send-at "2026-03-01T09:00:00Z" --agent <current_agent> --user "Tommy"
161
+ kimaki send --channel chan_123 --prompt "Run weekly test suite and summarize failures" --send-at "0 9 * * 1" --agent <current_agent> --user "Tommy"
161
162
 
162
163
  ALL scheduling is in UTC. Dates must be UTC ISO format ending with \`Z\`. Cron expressions also fire in UTC (e.g. \`0 9 * * 1\` means 9:00 UTC every Monday).
163
164
  When the user specifies a time without a timezone, ask them to confirm their timezone or the UTC equivalent. Never guess the user's timezone.
@@ -191,13 +192,13 @@ describe('system-message', () => {
191
192
 
192
193
  Use case patterns:
193
194
  - Reminder flows: create deadline reminders in this channel with one-time \`--send-at\`; mention only if action is required.
194
- - Proactive reminders: when you encounter time-sensitive information during your work (e.g. creating an API key that expires in 90 days, a certificate with an expiration date, a trial period ending, a deadline mentioned in code comments), proactively schedule a \`--notify-only\` reminder before the expiration so the user gets notified in time. For example, if you generate an API key expiring on 2026-06-01, schedule a reminder a few days before: \`kimaki send --channel chan_123 --prompt "Reminder: <@USER_ID> the API key created on 2026-03-01 expires on 2026-06-01. Renew it before it breaks production." --send-at "2026-05-28T09:00:00Z" --notify-only\`. Always tell the user you scheduled the reminder so they know.
195
+ - Proactive reminders: when you encounter time-sensitive information during your work (e.g. creating an API key that expires in 90 days, a certificate with an expiration date, a trial period ending, a deadline mentioned in code comments), proactively schedule a \`--notify-only\` reminder before the expiration so the user gets notified in time. For example, if you generate an API key expiring on 2026-06-01, schedule a reminder a few days before: \`kimaki send --channel chan_123 --prompt "Reminder: <@USER_ID> the API key created on 2026-03-01 expires on 2026-06-01. Renew it before it breaks production." --send-at "2026-05-28T09:00:00Z" --notify-only --agent <current_agent>\`. Always tell the user you scheduled the reminder so they know.
195
196
  - Weekly QA: schedule "run full test suite, inspect failures, post summary, and mention @username only when failures require review".
196
197
  - Weekly benchmark automation: schedule a benchmark prompt that runs model evals, writes JSON outputs in the repo, commits results, and mentions only for regressions.
197
198
  - Recurring maintenance: use cron \`--send-at\` for repetitive tasks like rotating secrets, checking dependency updates, running security audits, or cleaning up stale branches. Example: \`--send-at "0 9 1 * *"\` to run on the 1st of every month.
198
199
  - Thread reminders: when the user says "remind me about this in 2 hours" (or any duration), use \`--send-at\` with \`--thread\` to resurface the current thread. Compute the future UTC time and send a mention so Discord shows a notification:
199
200
 
200
- kimaki send --session ses_123 --prompt "Reminder: <@USER_ID> you asked to be reminded about this thread." --send-at "<future_UTC_time>" --notify-only
201
+ kimaki send --session ses_123 --prompt "Reminder: <@USER_ID> you asked to be reminded about this thread." --send-at "<future_UTC_time>" --notify-only --agent <current_agent>
201
202
 
202
203
  Replace \`<future_UTC_time>\` with the computed UTC ISO timestamp. The \`--notify-only\` flag creates just a notification message without starting a new AI session. The \`<@userId>\` mention ensures the user gets a Discord notification.
203
204
 
@@ -212,7 +213,7 @@ describe('system-message', () => {
212
213
  When the user asks to "create a worktree" or "make a worktree", they mean you should use the kimaki CLI to create it. Do NOT use raw \`git worktree add\` commands. Instead use:
213
214
 
214
215
  \`\`\`bash
215
- kimaki send --channel chan_123 --prompt "your task description" --worktree worktree-name --user "Tommy"
216
+ kimaki send --channel chan_123 --prompt "your task description" --worktree worktree-name --agent <current_agent> --user "Tommy"
216
217
  \`\`\`
217
218
 
218
219
  This creates a new Discord thread with an isolated git worktree and starts a session in it. The worktree name should be kebab-case and descriptive of the task.
@@ -228,7 +229,7 @@ describe('system-message', () => {
228
229
  Use \`--cwd\` to start a session in an existing git worktree directory instead of creating a new one:
229
230
 
230
231
  \`\`\`bash
231
- kimaki send --channel chan_123 --prompt "Continue work on feature X" --cwd /path/to/existing-worktree --user "Tommy"
232
+ kimaki send --channel chan_123 --prompt "Continue work on feature X" --cwd /path/to/existing-worktree --agent <current_agent> --user "Tommy"
232
233
  \`\`\`
233
234
 
234
235
  The path must be a git worktree of the project (validated via \`git worktree list\`). The session resolves to the correct project channel but uses the worktree as its working directory. Use \`--worktree\` to create a new worktree, \`--cwd\` to reuse an existing one.
@@ -242,7 +243,7 @@ describe('system-message', () => {
242
243
  When you are approaching the **context window limit** or the user explicitly asks to **handoff to a new thread**, use the \`kimaki send\` command to start a fresh session with context:
243
244
 
244
245
  \`\`\`bash
245
- kimaki send --channel chan_123 --prompt "Continuing from previous session: <summary of current task and state>" --user "Tommy"
246
+ kimaki send --channel chan_123 --prompt "Continuing from previous session: <summary of current task and state>" --agent <current_agent> --user "Tommy"
246
247
  \`\`\`
247
248
 
248
249
  The command automatically handles long prompts (over 2000 chars) by sending them as file attachments.
@@ -300,10 +301,10 @@ describe('system-message', () => {
300
301
 
301
302
  \`\`\`bash
302
303
  # Send to a specific channel
303
- kimaki send --channel <channel_id> --prompt "Plan how to update the API client to v2"
304
+ kimaki send --channel <channel_id> --prompt "Plan how to update the API client to v2" --agent <current_agent>
304
305
 
305
306
  # Or use --project to resolve from directory
306
- kimaki send --project /path/to/other-repo --prompt "Plan how to bump version to 1.2.0"
307
+ kimaki send --project /path/to/other-repo --prompt "Plan how to bump version to 1.2.0" --agent <current_agent>
307
308
  \`\`\`
308
309
 
309
310
  When sending prompts to other projects, always ask the agent to plan first, never build upfront. The prompt should start with "Plan how to ..." so the user can review before greenlighting implementation.
@@ -326,10 +327,10 @@ describe('system-message', () => {
326
327
 
327
328
  \`\`\`bash
328
329
  # Start a session and wait for it to finish
329
- kimaki send --channel <channel_id> --prompt "Fix the auth bug" --wait
330
+ kimaki send --channel <channel_id> --prompt "Fix the auth bug" --wait --agent <current_agent>
330
331
 
331
332
  # Send to an existing thread and wait
332
- kimaki send --thread <thread_id> --prompt "Run the tests" --wait
333
+ kimaki send --thread <thread_id> --prompt "Run the tests" --wait --agent <current_agent>
333
334
  \`\`\`
334
335
 
335
336
  The command exits with the session markdown on stdout once the model finishes responding.
@@ -70,7 +70,6 @@ function writeSystemPromptDiffFile({ dataDir, sessionId, beforePrompt, afterProm
70
70
  const timestamp = new Date().toISOString().replaceAll(':', '-');
71
71
  const sessionDir = path.join(getSystemPromptDiffDir({ dataDir }), sessionId);
72
72
  const filePath = path.join(sessionDir, `${timestamp}.diff`);
73
- const latestPromptPath = path.join(sessionDir, `${timestamp}.md`);
74
73
  const fileContent = [
75
74
  `Session: ${sessionId}`,
76
75
  `Created: ${new Date().toISOString()}`,
@@ -88,7 +87,6 @@ function writeSystemPromptDiffFile({ dataDir, sessionId, beforePrompt, afterProm
88
87
  additions: diff.additions,
89
88
  deletions: diff.deletions,
90
89
  filePath,
91
- latestPromptPath,
92
90
  };
93
91
  },
94
92
  catch: (error) => {
@@ -109,6 +107,7 @@ function getOrCreateSessionState({ sessions, sessionId, }) {
109
107
  comparedTurn: 0,
110
108
  previousTurnContext: undefined,
111
109
  currentTurnContext: undefined,
110
+ pendingCompareTimeout: undefined,
112
111
  };
113
112
  sessions.set(sessionId, state);
114
113
  return state;
@@ -162,8 +161,7 @@ async function handleSystemTransform({ input, output, sessions, dataDir, client,
162
161
  message: appendToastSessionMarker({
163
162
  sessionId,
164
163
  message: `system prompt changed since the previous message (+${diffFileResult.additions} / -${diffFileResult.deletions}). ` +
165
- `Diff: \`${abbreviatePath(diffFileResult.filePath)}\`. ` +
166
- `Latest prompt: \`${abbreviatePath(diffFileResult.latestPromptPath)}\``,
164
+ `Diff: \`${abbreviatePath(diffFileResult.filePath)}\`. `
167
165
  }),
168
166
  },
169
167
  });
@@ -193,13 +191,41 @@ const systemPromptDriftPlugin = async ({ client, directory }) => {
193
191
  'experimental.chat.system.transform': async (input, output) => {
194
192
  const result = await errore.tryAsync({
195
193
  try: async () => {
196
- await handleSystemTransform({
197
- input,
198
- output,
199
- sessions,
200
- dataDir,
201
- client,
202
- });
194
+ const sessionId = input.sessionID;
195
+ if (!sessionId) {
196
+ return;
197
+ }
198
+ const state = getOrCreateSessionState({ sessions, sessionId });
199
+ if (state.pendingCompareTimeout) {
200
+ clearTimeout(state.pendingCompareTimeout);
201
+ }
202
+ // Delay one tick so other system-transform hooks can finish mutating
203
+ // output.system before we snapshot it for drift detection.
204
+ state.pendingCompareTimeout = setTimeout(() => {
205
+ state.pendingCompareTimeout = undefined;
206
+ void errore.tryAsync({
207
+ try: async () => {
208
+ await handleSystemTransform({
209
+ input,
210
+ output,
211
+ sessions,
212
+ dataDir,
213
+ client,
214
+ });
215
+ },
216
+ catch: (error) => {
217
+ return new Error('system prompt drift transform hook failed', {
218
+ cause: error,
219
+ });
220
+ },
221
+ }).then((delayedResult) => {
222
+ if (!(delayedResult instanceof Error)) {
223
+ return;
224
+ }
225
+ logger.warn(`[system-prompt-drift-plugin] ${formatPluginErrorWithStack(delayedResult)}`);
226
+ void notifyError(delayedResult, 'system prompt drift plugin transform hook failed');
227
+ });
228
+ }, 0);
203
229
  },
204
230
  catch: (error) => {
205
231
  return new Error('system prompt drift transform hook failed', {
@@ -222,6 +248,10 @@ const systemPromptDriftPlugin = async ({ client, directory }) => {
222
248
  if (!deletedSessionId) {
223
249
  return;
224
250
  }
251
+ const state = sessions.get(deletedSessionId);
252
+ if (state?.pendingCompareTimeout) {
253
+ clearTimeout(state.pendingCompareTimeout);
254
+ }
225
255
  sessions.delete(deletedSessionId);
226
256
  },
227
257
  catch: (error) => {
package/dist/utils.js CHANGED
@@ -50,7 +50,7 @@ export function generateBotInstallUrl({ clientId, permissions = [
50
50
  return url.toString();
51
51
  }
52
52
  export const KIMAKI_GATEWAY_APP_ID = process.env.KIMAKI_GATEWAY_APP_ID || '1477605701202481173';
53
- export const KIMAKI_WEBSITE_URL = process.env.KIMAKI_WEBSITE_URL || 'https://kimaki.xyz';
53
+ export const KIMAKI_WEBSITE_URL = process.env.KIMAKI_WEBSITE_URL || 'https://kimaki.dev';
54
54
  export function generateDiscordInstallUrlForBot({ appId, mode, clientId, clientSecret, gatewayCallbackUrl, reachableUrl, }) {
55
55
  if (mode !== 'gateway') {
56
56
  return generateBotInstallUrl({ clientId: appId });
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@otto-assistant/bridge",
3
3
  "module": "index.ts",
4
4
  "type": "module",
5
- "version": "0.4.97",
5
+ "version": "0.4.101",
6
6
  "scripts": {
7
7
  "dev": "tsx src/bin.ts",
8
8
  "prepublishOnly": "pnpm generate && pnpm tsc",
@@ -542,7 +542,14 @@ describe('agent model resolution', () => {
542
542
  afterAuthorId: discord.botUserId,
543
543
  })
544
544
 
545
- expect(await discord.thread(thread.id).text()).toMatchInlineSnapshot(`
545
+ const threadText = (await discord.thread(thread.id).text())
546
+ .split('\n')
547
+ .filter((line) => {
548
+ return !line.startsWith('⬦ info: Context cache discarded:')
549
+ })
550
+ .join('\n')
551
+
552
+ expect(threadText).toMatchInlineSnapshot(`
546
553
  "--- from: user (agent-model-tester)
547
554
  first message in thread
548
555
  Reply with exactly: reply-context-check