@geminixiang/mikan 1.0.0-beta.95 → 1.0.0-beta.96

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 (137) hide show
  1. package/CHANGELOG.md +427 -388
  2. package/README.md +31 -40
  3. package/dist/adapters/github/bot.js +1 -1
  4. package/dist/adapters/github/bot.js.map +1 -1
  5. package/dist/adapters/github/policy.d.ts +2 -9
  6. package/dist/adapters/github/policy.d.ts.map +1 -1
  7. package/dist/adapters/github/policy.js +18 -26
  8. package/dist/adapters/github/policy.js.map +1 -1
  9. package/dist/adapters/slack/bot.d.ts +2 -4
  10. package/dist/adapters/slack/bot.d.ts.map +1 -1
  11. package/dist/adapters/slack/bot.js +28 -56
  12. package/dist/adapters/slack/bot.js.map +1 -1
  13. package/dist/adapters/slack/socket-agent.d.ts +9 -0
  14. package/dist/adapters/slack/socket-agent.d.ts.map +1 -0
  15. package/dist/adapters/slack/socket-agent.js +17 -0
  16. package/dist/adapters/slack/socket-agent.js.map +1 -0
  17. package/dist/adapters/telegram/bot.d.ts +1 -0
  18. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  19. package/dist/adapters/telegram/bot.js +6 -1
  20. package/dist/adapters/telegram/bot.js.map +1 -1
  21. package/dist/adapters/telegram/types.d.ts +1 -0
  22. package/dist/adapters/telegram/types.d.ts.map +1 -1
  23. package/dist/adapters/telegram/types.js.map +1 -1
  24. package/dist/cli/arg-grammar.d.ts +1 -2
  25. package/dist/cli/arg-grammar.d.ts.map +1 -1
  26. package/dist/cli/arg-grammar.js +2 -17
  27. package/dist/cli/arg-grammar.js.map +1 -1
  28. package/dist/cli/boot.d.ts.map +1 -1
  29. package/dist/cli/boot.js +5 -11
  30. package/dist/cli/boot.js.map +1 -1
  31. package/dist/cli/migrate.d.ts.map +1 -1
  32. package/dist/cli/migrate.js +22 -7
  33. package/dist/cli/migrate.js.map +1 -1
  34. package/dist/cli/office.d.ts.map +1 -1
  35. package/dist/cli/office.js +3 -5
  36. package/dist/cli/office.js.map +1 -1
  37. package/dist/cli/onboard.js +18 -20
  38. package/dist/cli/onboard.js.map +1 -1
  39. package/dist/cli/types.d.ts +1 -2
  40. package/dist/cli/types.d.ts.map +1 -1
  41. package/dist/cli/types.js.map +1 -1
  42. package/dist/env-manifest.d.ts +2 -0
  43. package/dist/env-manifest.d.ts.map +1 -1
  44. package/dist/env-manifest.js +76 -43
  45. package/dist/env-manifest.js.map +1 -1
  46. package/dist/events/index.d.ts +5 -5
  47. package/dist/events/index.d.ts.map +1 -1
  48. package/dist/events/index.js +1 -7
  49. package/dist/events/index.js.map +1 -1
  50. package/dist/file-guards.d.ts +1 -0
  51. package/dist/file-guards.d.ts.map +1 -1
  52. package/dist/file-guards.js +4 -1
  53. package/dist/file-guards.js.map +1 -1
  54. package/dist/harness/execution-resolver.d.ts.map +1 -1
  55. package/dist/harness/execution-resolver.js +1 -7
  56. package/dist/harness/execution-resolver.js.map +1 -1
  57. package/dist/harness/http.d.ts +1 -2
  58. package/dist/harness/http.d.ts.map +1 -1
  59. package/dist/harness/http.js +3 -16
  60. package/dist/harness/http.js.map +1 -1
  61. package/dist/harness/jev.d.ts +2 -1
  62. package/dist/harness/jev.d.ts.map +1 -1
  63. package/dist/harness/jev.js.map +1 -1
  64. package/dist/harness/prompt.d.ts.map +1 -1
  65. package/dist/harness/prompt.js +0 -6
  66. package/dist/harness/prompt.js.map +1 -1
  67. package/dist/harness/session.d.ts +2 -9
  68. package/dist/harness/session.d.ts.map +1 -1
  69. package/dist/harness/session.js +3 -3
  70. package/dist/harness/session.js.map +1 -1
  71. package/dist/harness/tools/event.d.ts +0 -1
  72. package/dist/harness/tools/event.d.ts.map +1 -1
  73. package/dist/harness/tools/event.js +1 -7
  74. package/dist/harness/tools/event.js.map +1 -1
  75. package/dist/harness/types.d.ts +3 -3
  76. package/dist/harness/types.d.ts.map +1 -1
  77. package/dist/harness/types.js.map +1 -1
  78. package/dist/index.d.ts +8 -31
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +3 -15
  81. package/dist/index.js.map +1 -1
  82. package/dist/main.js +26 -36
  83. package/dist/main.js.map +1 -1
  84. package/dist/migrations/index.d.ts +0 -1
  85. package/dist/migrations/index.d.ts.map +1 -1
  86. package/dist/migrations/index.js +4 -4
  87. package/dist/migrations/index.js.map +1 -1
  88. package/dist/migrations/legacy-office-files.d.ts +3 -0
  89. package/dist/migrations/legacy-office-files.d.ts.map +1 -0
  90. package/dist/migrations/legacy-office-files.js +29 -0
  91. package/dist/migrations/legacy-office-files.js.map +1 -0
  92. package/dist/observability/instrument.js +2 -3
  93. package/dist/observability/instrument.js.map +1 -1
  94. package/dist/observability/sentry.js +1 -1
  95. package/dist/observability/sentry.js.map +1 -1
  96. package/dist/office/projection.js +2 -2
  97. package/dist/office/projection.js.map +1 -1
  98. package/dist/sandbox/identity.d.ts +0 -1
  99. package/dist/sandbox/identity.d.ts.map +1 -1
  100. package/dist/sandbox/identity.js +0 -3
  101. package/dist/sandbox/identity.js.map +1 -1
  102. package/dist/sandbox/registry.d.ts +1 -5
  103. package/dist/sandbox/registry.d.ts.map +1 -1
  104. package/dist/sandbox/registry.js +4 -13
  105. package/dist/sandbox/registry.js.map +1 -1
  106. package/dist/sandbox/types.d.ts +1 -5
  107. package/dist/sandbox/types.d.ts.map +1 -1
  108. package/dist/sandbox/types.js.map +1 -1
  109. package/dist/sessions/types.d.ts +1 -1
  110. package/dist/sessions/types.d.ts.map +1 -1
  111. package/dist/sessions/types.js.map +1 -1
  112. package/dist/settings/index.d.ts +56 -2
  113. package/dist/settings/index.d.ts.map +1 -1
  114. package/dist/settings/index.js +57 -37
  115. package/dist/settings/index.js.map +1 -1
  116. package/dist/types.d.ts +1 -25
  117. package/dist/types.d.ts.map +1 -1
  118. package/dist/types.js.map +1 -1
  119. package/dist/vault/index.js +1 -1
  120. package/dist/vault/index.js.map +1 -1
  121. package/package.json +4 -17
  122. package/dist/cli/download.d.ts +0 -2
  123. package/dist/cli/download.d.ts.map +0 -1
  124. package/dist/cli/download.js +0 -84
  125. package/dist/cli/download.js.map +0 -1
  126. package/dist/harness/index.d.ts +0 -20
  127. package/dist/harness/index.d.ts.map +0 -1
  128. package/dist/harness/index.js +0 -14
  129. package/dist/harness/index.js.map +0 -1
  130. package/dist/sandbox/cloudflare.d.ts +0 -17
  131. package/dist/sandbox/cloudflare.d.ts.map +0 -1
  132. package/dist/sandbox/cloudflare.js +0 -142
  133. package/dist/sandbox/cloudflare.js.map +0 -1
  134. package/dist/sandbox/index.d.ts +0 -7
  135. package/dist/sandbox/index.d.ts.map +0 -1
  136. package/dist/sandbox/index.js +0 -6
  137. package/dist/sandbox/index.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -4,701 +4,740 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
7
- once it leaves the 0.x line. While on `0.2.0-beta.*`, breaking changes may land in
8
- any release.
7
+ from 1.0.0 on. The package interface is the root export of `@geminixiang/mikan`; the
8
+ CLI, `settings.json`, `mikan.env`, and the state layout under `~/.mikan` are covered too.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
- ## [1.0.0-beta.95]
12
+ 1.0.0 is the first stable release. It replaces the 0.5.3 runtime, which ran on
13
+ `pi-coding-agent`, with mikan's own harness on `pi-durable` and `pi-ai`, and gives every
14
+ conversation its own office. The 97 `1.0.0-beta.*` prereleases are summarized here; their
15
+ individual notes remain in the [GitHub releases](https://github.com/geminixiang/mikan/releases).
13
16
 
14
- ### Removed
17
+ ### Upgrading from 0.5.3
15
18
 
16
- - `mikan migrate` supports one upgrade, from 0.5.3 to 1.0.0 (ADR 0019). The steps that served only 1.0.0 prerelease installs, `0004-sessions-v3`, `0010-dream-checkpoints`, and `0011-private-office-dirs`, are removed: 0.5.3 session files are imported into `sessions.db` directly and kept under `sessions-v3/` instead of being rewritten to the prerelease v4 format with a `*.v3.bak` copy, which on real data makes the step four times faster and the upgraded state 40% smaller. It no longer rewrites Pi session files stored elsewhere in the workspace. An install that already applied the removed steps has nothing pending. A prerelease install that has not applied them keeps any `dream.json` files and loosely permissioned office state directories: delete the files and run `chmod -R go-rwx <state-dir>/conversations`.
19
+ `mikan migrate` upgrades a 0.5.3 install in place; it is the only supported upgrade path, and
20
+ formats that existed only in 1.0.0 prereleases are not converted. The daemon refuses to start
21
+ while migrations are pending and prints the exact command to run. Follow
22
+ [Upgrading from 0.5.3](https://mikan.geminixiang.com/deployment/#upgrading-from-053) in the
23
+ deployment guide, which lists what migrates, what does not, and what to check afterwards.
17
24
 
18
- ### Changed
25
+ ### Added
19
26
 
20
- - Embedding API: settings and the model list are located through the `Workspace` instead of the `STATE_DIR` environment variable. `loadGlobalSettings`, `updateGlobalSettings`, `resolveSentryDsn`, and `defaultModelsJsonPath` take the state dir, `applyGlobalSettings` takes it after the runtime, `updateSkillPatterns` takes the office and a `"global" | "conversation"` scope, `MikanModels.create` requires `modelsJsonPath`, and `defaultCommandHandlers` requires the model registry. The Admin portal now requires a `workspace`. `--state-dir`, `STATE_DIR`, and `MIKAN_STATE_DIR` still choose the state dir on the command line; mikan no longer writes them back into its own environment.
21
- - Embedding API: `ConversationRuntime` replaces `switchConversationModel` and `refreshConversationEnvironment`, which both only cleared a conversation's cached runners, with one `refreshConversation(address)`. It returns `false` only while the conversation is busy.
27
+ - **Conversation offices.** Each conversation gets its own directory, sandbox runtime, vault,
28
+ settings, sessions, and scheduled events, named by an office key
29
+ (`v1-<platform>-<readable-id>-<hash>`) so two platforms never collide on one raw id. Offices
30
+ are public or private, following the Slack conversation type, and `image:*` sandboxes enforce
31
+ it: a private office sees only itself plus shared knowledge. `mikan office list` prints them.
32
+ - **GitHub adapter.** A regular GitHub account, bound with a fine-grained token and an
33
+ organization webhook, answers mentions, assignments, and review requests; each issue or pull
34
+ request is one conversation.
35
+ - **Durable sessions.** Each office keeps its sessions in one SQLite database (`sessions.db`)
36
+ through `pi-durable`. Sessions survive restarts, a channel's top-level session stays current
37
+ until `/new` with Pi compacting old context, and threads keep their own sessions. The agent's
38
+ `history` tool reads the conversation's earlier sessions.
39
+ - **MCP servers and codemode.** `mcpServers` in `settings.json` connects MCP servers; the agent
40
+ reaches their tools through Pi's codemode and searches large tool lists on demand.
41
+ OpenConnector can provision a per-conversation MCP token.
42
+ - **Subagents.** The agent delegates bounded work, in parallel or as a dependency graph, to
43
+ subagents with role profiles, their own tools, and token, cost, and time budgets.
44
+ - **Admin portal and session viewer.** `/admin` opens a 30-minute portal for model, sandbox
45
+ limits, office visibility, reply mode, MCP servers, and skills; `session` opens a read-only view
46
+ of the current session.
47
+ - **Memory capture.** After each human-triggered run, durable facts go to the office's
48
+ `MEMORY.md`.
49
+ - **Jev.** A small model answers yes/no decisions, such as whether a Slack message addresses the
50
+ bot in `/pi-auto-reply jev` mode, and drives the `jev_browser` tool.
51
+ - **Platform rendering.** Slack answers stream into native markdown and table blocks, with the
52
+ `slack_blockkit` tool for interactive messages; Discord uses Components V2; Telegram uses rich
53
+ formatting. Long answers continue in the thread instead of failing.
54
+ - **CLI.** `mikan onboard` writes `settings.json` and `mikan.env` from a few questions, `mikan env`
55
+ lists every environment variable and which are set, and `mikan migrate` applies state
56
+ migrations with `--dry-run`.
57
+ - **Observability.** Standard OTLP export through the `OTEL_*` variables, alongside Sentry.
58
+
59
+ ### Changed
60
+
61
+ - Node.js 24.15.0 or newer is required.
62
+ - `mikan.env` holds secrets and deployment addresses; `settings.json` holds behavior. The
63
+ Sentry DSN is read only from `SENTRY_DSN`, so a `sentry.dsn` setting is ignored, and the GitHub
64
+ adapter's repositories and trigger rules live under `github` in `settings.json`. At startup the
65
+ daemon logs each environment variable it no longer reads, with what replaces it.
66
+ - State lives in `~/.mikan` only: `settings.json`, `mikan.env`, `models.json`, vaults, and the
67
+ host-only per-conversation directories under `conversations/`. Per-conversation settings,
68
+ sessions, and scheduled events moved out of the workspace, where sandboxes could read them.
69
+ - The workspace argument is optional and defaults to `~/.mikan/workspace`.
70
+ - Inside a sandbox, an office's files are at `/workspace/<office-key>` instead of
71
+ `/workspace/<conversation-id>`. Paths quoted in sessions from before the upgrade point at the
72
+ old location.
73
+ - `image:<image>` provisions one managed container and one vault per office, recreated from the
74
+ current image when missing; `/pi-sandbox boost` raises its limits until it stops.
75
+ - Vault directories use hashed keys instead of raw user and container names.
76
+ - Only `session` and `stop` work without a leading slash; `new`, `model`, and `auto-reply` need
77
+ their slash forms (`/new`, `/pi-new`, …).
78
+ - Auto-reply is Slack-only and takes `on`, `off`, or `jev`. A 0.5.3 channel with auto-reply
79
+ rules replies to every top-level message; the rules are ignored.
80
+ - The link server for the portal and credential links listens on `127.0.0.1` unless
81
+ configured otherwise.
82
+ - The package exports only what an embedder needs: `createConversationRuntime`,
83
+ `createWorkspace`, `createOfficeAddress`, `officeKey`, `createConversationEvent`,
84
+ `createConversationMessage`, `defaultCommandHandlers`, `MikanModels`, and the types they use.
85
+ The `@geminixiang/mikan/harness` and `@geminixiang/mikan/sandbox` entry points are gone.
86
+
87
+ ### Removed
88
+
89
+ - The `pi-coding-agent` runtime and its extension loading; mikan loads no third-party code into
90
+ its process (ADR 0006). Skills in `skills/` directories remain.
91
+ - The `firecracker:*` and `cloudflare:*` sandboxes.
92
+ - `--state-dir` and the `STATE_DIR` / `MIKAN_STATE_DIR` variables, and `--download`.
93
+ - Auto-reply on Discord and Telegram, and auto-reply rules.
94
+ - `SENTRY_ENABLED` (leave `SENTRY_DSN` unset to turn Sentry off) and `HTTP_IDLE_TIMEOUT`
95
+ (outbound HTTP streams time out after five minutes).
96
+ - Provider keys in `~/.pi/mikan/auth.json`; put them in `~/.mikan/mikan.env` or `models.json`.
22
97
 
23
98
  ### Fixed
24
99
 
25
- - A program that embeds mikan with its own `createWorkspace({ stateDir })`, as `deploy/examples/embedder` does, now reads that directory's `settings.json` and `models.json`; it previously used `~/.mikan`'s settings and models while keeping conversations in its own directory.
100
+ - Slack startup and reconnects no longer hang without a log line when Slack accepts the
101
+ connection and never answers; a socket silent for 30 seconds is dropped and retried, and the
102
+ daemon logs `Slack connection lost; reconnecting` and `Slack reconnected after Ns`.
103
+ - Stopping the daemon while it is still connecting to Slack ends in a graceful shutdown.
104
+ - When Telegram ends long polling because the token was revoked (401) or another process polls
105
+ the same bot (409), the daemon logs the reason and exits with code 1 for the process manager
106
+ to restart, instead of running on without receiving messages.
107
+ - A Slack message whose acknowledgement was lost during a reconnect runs once, not twice.
26
108
 
27
- ## [1.0.0-beta.94]
109
+ ## [1.0.0-beta.96]
28
110
 
29
- ### Changed
111
+ The last prerelease before 1.0.0. Installs on 1.0.0-beta.95 run one migration,
112
+ `0012-legacy-office-files`, before the daemon starts.
113
+
114
+ ### Removed
30
115
 
31
- - Pi dependencies (`pi-durable`, `pi-ai`, `pi-agent-core`, `chord`) are pinned to 1.0.2.
116
+ - `--state-dir` and the `STATE_DIR` / `MIKAN_STATE_DIR` variables: state always lives in
117
+ `~/.mikan`, and passing `--state-dir` is an error.
118
+ - The experimental `cloudflare:<sandbox-id>` sandbox with `CLOUDFLARE_SANDBOX_URL` and
119
+ `CLOUDFLARE_SANDBOX_TOKEN`, and `mikan --download`.
120
+ - The `@geminixiang/mikan/harness` and `@geminixiang/mikan/sandbox` entry points and every root
121
+ export an embedder does not need; the root keeps `createConversationRuntime`,
122
+ `createWorkspace`, `createOfficeAddress`, `officeKey`, `createConversationEvent`,
123
+ `createConversationMessage`, `defaultCommandHandlers`, `MikanModels`, and the types they use.
124
+ `MessagingBot` drops the optional `addReaction`, `uploadFile`, `openDirectConversation`,
125
+ `fetchHistory`, and `listUsers`.
126
+ - `SENTRY_ENABLED` and `HTTP_IDLE_TIMEOUT`, and the `sentry.dsn` setting: the DSN comes only from
127
+ `SENTRY_DSN`, and Sentry runs exactly when it is set.
128
+ - The `event` tool's `scope` parameter, and `channelId` in place of `conversationId` in event files.
129
+
130
+ ### Changed
131
+
132
+ - The GitHub adapter's repositories and trigger rules move from `GITHUB_REPOS`,
133
+ `GITHUB_PUBLIC_REPOS`, `GITHUB_USERS`, `GITHUB_MIN_PERMISSION`, `GITHUB_TRIGGERS`, and
134
+ `GITHUB_CAPABILITIES` to the `github` block of `settings.json`, as JSON lists.
135
+ - At startup the daemon logs each `settings.json` key and each environment variable it no longer
136
+ reads, with what replaces it.
137
+ - `mikan onboard` asks fewer questions and lists only the variables it set; `mikan env` folds the
138
+ 19 `OTEL_*` variables into one line and lists every variable mikan reads.
139
+ - `0012-legacy-office-files` removes the `last_prompt.jsonl` and `auto-reply.disabled` files 0.5.3
140
+ left in office directories.
141
+ - `@earendil-works/pi-codemode` and `@earendil-works/pi-mcp` are pinned to 1.0.0.
32
142
 
33
143
  ### Fixed
34
144
 
35
- - Chat-history sync no longer drops a new human message because an earlier message has the same text. Each synced history line keeps its platform message ID, and the message that started a run counts as handled only once Pi has admitted it, so repeated confirmations and identical messages from different people reach the model, including after a session reset or in a forked thread, and a request that failed before admission (for example, missing credentials) stays in history. A history batch and its sync cursor are written in one Pi commit. Previously omitted history is not automatically restored.
36
- - Provider requests are routed to their conversation by Pi's own provider session ID instead of by message-object identity: compaction now counts against its own conversation's budget rather than the most recently started run's, and a request with no matching conversation fails instead of borrowing another conversation's models. Provider prompt caches key on Pi's persisted session ID; conversations without one get it once on their next run.
37
- - The system prompt's channel table no longer lists every channel and direct message the bot belongs to in every conversation: it names only the conversation itself and the public channels whose offices the conversation can read, so the names of private channels and the people who direct-message the bot no longer reach other conversations, as office visibility promises. On a deployment with 279 such conversations the table drops from 8.9k to 6.2k characters.
38
- - The usage summary, the `agent.run.*` metrics, and the run span's usage attributes now count the spend of subagents a run delegates to and of compaction during the run, matching the total the run budget enforces; they previously counted only the main agent's own model calls, so a run whose subagent wrote about 2,000 output tokens reported 21.
145
+ - Slack startup and reconnects give up a connection that stays silent for 30 seconds and retry,
146
+ instead of hanging without a log line; the daemon logs lost connections and reconnection time.
147
+ - Stopping the daemon while it connects to Slack ends in a graceful shutdown instead of
148
+ `Failed to start bot undefined` and exit code 1.
149
+ - When Telegram ends long polling on 401 or 409, the daemon logs why and exits for the process
150
+ manager to restart it, instead of running on without messages.
151
+ - `mikan migrate` refuses to run when the state directory or workspace is not a mikan install,
152
+ instead of recording every step as applied.
153
+ - Office state directories are created with mode `0700`.
154
+ - The startup log reports the HTTP idle timeout actually applied.
155
+ - A Slack App Home Force Stop button without a session key stops nothing.
39
156
 
40
- ## [1.0.0-beta.93]
157
+ ## [0.5.3] - 2026-06-30
41
158
 
42
159
  ### Added
43
160
 
44
- - Skills can be turned off and on per workspace and per conversation with Pi's resource rules: `skills` in the global or conversation settings takes `!glob`, `+path`, and `-path` entries over each skill's directory, every skill stays listed by default, and an excluded skill is left out of the system prompt. The admin portal's Skills pages list every skill the agent loads, including nested ones such as `bundle/vendors/<skill>` that they previously missed, grouped by directory with a filter, and toggle them: the workspace page writes the global entries, and a conversation page cycles a skill between inherited, `+`, and `-` and shows how many skills and characters the prompt lists.
45
-
46
- ## [1.0.0-beta.92]
161
+ - Append a session-view link to event-triggered attribution messages.
162
+ - Show raw cached token counts and cache-hit rate in usage summaries.
47
163
 
48
164
  ### Changed
49
165
 
50
- - Codemode guides the model to discover every tool a task needs in one script and to parse MCP results and emit only the fields the answer needs, because everything a script emits is sent again on every later model call. `searchTools()` and `tool_search` rank with BM25 over names, descriptions, argument schemas, and the MCP server name, splitting camelCase like Pi, so a query such as `OpenConnector` finds `mcp__open-connector__*` tools; the default limit is 8.
166
+ - Use a stable, low-noise usage summary layout with token units and fixed cost breakdowns.
167
+ - Mark the auto-reply command as deprecated.
51
168
 
52
- ## [1.0.0-beta.91]
169
+ ### Fixed
53
170
 
54
- ### Changed
171
+ - Harden state file writes to avoid readers seeing partial state.
172
+ - Reject malformed OAuth configuration during login setup.
55
173
 
56
- - MCP follows Pi's codemode design. MCP tools are reached from `codemode` scripts by default and `tool_search` exists only for servers configured with `"exposure": "deferred"`. A script receives each MCP tool's complete `CallToolResult` (`content`, `structuredContent`, `isError`) instead of the bounded view the model gets, so it can filter large results before they enter the context, and an MCP error resolves with `isError: true` instead of rejecting. The `codemode` description no longer repeats the declarations of tools already declared to the model; each of those tools' descriptions says what a script call resolves to. Server instructions are no longer copied into the system prompt: an `mcp_servers` section lists each server once with the first line of its new optional `description` or its instructions, and scripts read the rest with the new `describeNamespace()`. On a local request these changes cut the tool declarations from 38,274 to 26,538 characters and the codemode description from 14,232 to 2,803.
57
- - A direct MCP call that the server marks `isError` returns an error result instead of throwing, keeping the server's message.
174
+ ### Tests
58
175
 
59
- ## [1.0.0-beta.90]
176
+ - Add unit coverage for utility and tool modules.
177
+ - Expand Slack end-to-end coverage and make CI Slack artifacts more reliable.
60
178
 
61
- ### Changed
179
+ ## [0.5.2] - 2026-06-26
62
180
 
63
- - Run `mikan migrate` before starting this version. It deletes each office's `dream.json`, the checkpoint of the Dream maintenance removed in [ADR 0012](docs/adr/0012-remove-dream.md) that nothing reads, and makes every directory under `<state-dir>/conversations/` readable only by its owner (mode 700); links are not followed.
181
+ ### Added
64
182
 
65
- ### Security
183
+ - Show the top 20 pi sessions by token usage in the admin portal, including channel labels and raw input, output, cache read, cache write, total, and cost columns.
66
184
 
67
- - An office's `events/` directory is created readable only by its owner (mode 700) instead of following the process umask.
185
+ ## [0.5.1] - 2026-06-26
68
186
 
69
- ## [1.0.0-beta.89]
187
+ ### Added
70
188
 
71
- ### Breaking
189
+ - Render markdown as Slack Block Kit.
190
+ - Show live tool progress during agent runs.
72
191
 
73
- - **Pi is upgraded to 1.0, and conversations now run on `@earendil-works/pi-durable`.** Pi 1.0 removed the harness, sessions, compaction, and coding tools from `pi-agent-core`; pi-durable is their first-party successor (see [ADR 0017](docs/adr/0017-pi-durable-harness.md)). Each office now keeps all its sessions in one SQLite storage, `sessions.db` in its State dir (see [ADR 0018](docs/adr/0018-one-durable-storage-per-office.md)); this needs Node 24.15 or later, whose built-in `node:sqlite` prints an experimental warning on load. Run `mikan migrate` before starting this version: it imports each office's v4 session files into that storage, the current main session as the top-level session and earlier main sessions and threads beside it, and moves the office's `sessions/` directory to `sessions-v4/`. An imported session keeps what the model could still see (the newest compaction summary and everything after it), its name, ID, and mikan's bookkeeping; history an earlier compaction had already hidden stays only in the archived files. Every office must be in `office-registry.json`. A tool call that was still running at upgrade is closed with an error result instead of being retried, and a run left unfinished is not resumed.
74
- - `/new` resets the session in place: the model starts from an empty context, and the earlier history stays readable to the `history` tool and the session view instead of moving to a new session file.
75
- - Library API: `createManagedSessionFile`, `createManagedSessionFileAtPath`, `createNewSessionFile`, `extractSessionSuffix`, `extractSessionUuid`, `getThreadSessionFile`, `openManagedSession`, `resolveManagedSessionFile`, `resolveSessionFile`, `tryResolveCurrentSession`, `tryResolveThreadSession`, `isPlatformHistorySession`, `CURRENT_SESSION_VERSION`, `MikanSessionHeader`, and `ChatSyncReport` are removed with session files; `SessionHeader` holds only `id`, `createdAt`, and `parentSessionId`; `registerThreadSession` and `hasMaterializedChatSession` are asynchronous, and `ResolvedSessionScope` no longer has `contextFile`.
76
- - Library API: `SessionEntry` is mikan's own union of `message`, `custom`, and `compaction` entries, with IDs qualified by the session ID; `BranchSummaryEntry`, `CompactionEntry`, and `CustomEntry` are no longer exported. `SessionStore.createHarness` is replaced by `bindHarness`; `appendCustomMessageEntry`, the tree-era `getBranch`, `getLeafId`, `getEntry`, and `isPersisted`, and `SessionEntry.parentId` are removed; `SessionStore.getContextEntries()` returns the entries still in the model's context; and `MikanAgentSession.compactWhenNearLimit`/`cancelIdleCompaction`/`foldExternalUsage` are gone. `HarnessEvent` no longer mirrors pi-agent-core's `AgentEvent`: it drops `agent_start`/`agent_end`/`turn_start`/`turn_end`, replaces `message_update` with `text_delta`, and tool events carry `details` and a `{ content, details }` result. `MikanAgentSession.messages` and `reloadFromSession` are removed: the session keeps no transcript copy, so read the context through `SessionStore`, and a run's own messages through `lastRunMessages`. Harness tools use pi-durable's `execute(args, api, context)`; plain `AgentTool`s are still adapted.
192
+ ## [0.5.0] - 2026-06-25
77
193
 
78
194
  ### Added
79
195
 
80
- - Slack and Discord mark a message with ⏳ when it waits behind a task that is still running, so a queued message no longer looks ignored.
81
- - The agent gets a `history` tool, in every conversation, that lists the conversation's sessions (earlier ones replaced by `/new` and its threads), searches or reads them including tool calls and their output that `log.jsonl` does not keep, and searches the chat log; a query matches entries containing all of its words, and a Chinese or Japanese word also matches when most of its character pairs appear, so `暫時代號` finds `暫時註記:代號`. The system prompt tells the agent to answer from its own context when it can, and to look up a result its context lacks, such as a command's output from another session, instead of guessing or rerunning the command. It never reaches another conversation.
82
- - `SENTRY_TRACES_SAMPLE_RATE` (0 to 1, default 1) sets how many traces go to Sentry when OTLP traces are not configured; an invalid value stops startup.
196
+ - Add the Starlight documentation site with localized docs for English, Japanese, Simplified Chinese, and Traditional Chinese.
197
+ - Add platform adapter guides for Slack, Discord, and Telegram.
198
+ - Add a web agent-events portal for streaming agent events.
83
199
 
84
200
  ### Changed
85
201
 
86
- - A new thread starts from what caused it. A thread under a channel answer, or under the message that triggered it, forks that run, so it carries the run's context up to its end, including tool calls and their output: asked what a command printed, the agent reads it instead of guessing or running it again. Any other thread starts from its root and its own replies, instead of ten earlier top-level messages copied from the chat log. Each run records the message that started it, and the chat log records each run answer with that message and its session.
87
- - Chat history never appears as the agent's own turn: synced messages from other people, other bots, and mikan's notices enter a session as attributed chat lines, and an answer a run posted is left to its own session, so a Discord or Telegram reply answered in another session no longer leaks into the channel session.
88
- - Compaction is Pi's: it runs in the background as the context grows and blocks the next request only near the limit, so mikan no longer starts its own compaction after a reply. Compaction summary requests now count toward a run's LLM-call and token budgets, and a request over the LLM-call budget is never sent.
89
- - A run left unfinished by a crash or restart is aborted before the next message in that conversation instead of answering first.
90
- - A thread session is named after the first line of its root message, cut to 80 characters, instead of the whole message; existing thread sessions take the short name on their next run.
202
+ - Align adapter, runtime, and session naming around conversation terminology for clearer contributor navigation.
203
+ - Update project dependencies and bundled pi packages.
91
204
 
92
205
  ### Fixed
93
206
 
94
- - A one-shot event whose time passed while mikan was restarting or stopped now fires when mikan starts, instead of being deleted without running.
95
- - Tool results that report `isError` reach the model as errors, so a failing codemode script is no longer recorded as a success.
96
- - A run stopped before the model wrote anything no longer stores a made-up aborted answer, and its reply is never taken from the previous run.
97
- - Compaction entries in the session view and subagent parent context show the summary itself, without Pi's wrapper text, and a subagent's parent context keeps the messages Pi retained after compaction.
98
- - A run Pi settles with a model error is recorded as failed instead of completed.
99
- - The usage summary's context size follows Pi's rule, the newest successful answer after the latest compaction, so it no longer reports the pre-compaction size, and it is omitted until a new answer measures it.
207
+ - Preserve custom Starlight theme component overrides.
208
+ - Keep the docs dev server from restarting when settings cleanup runs.
209
+ - Tighten Sentry event sanitization.
100
210
 
101
- ## [1.0.0-beta.88]
211
+ ## [0.4.8] - 2026-06-22
102
212
 
103
- ### Added
104
-
105
- - `tool_search` discovers authorized MCP tools and loads matching schemas for the next model call. MCP connections still start as before, but tools are no longer all declared upfront. Loaded tools survive later prompts and session reopen, subject to current grants. Codemode gains `searchTools()` and omits MCP schemas from its inline description.
106
- - `codemode` runs JavaScript through Pi's official QuickJS sandbox to combine authorized tools and filter results before returning them to the model. Existing direct tools remain available; nested calls honor per-run grants, loop guards and cancellation, and appear in progress and tool-call counts. Sessions without tools stay tool-less.
107
-
108
- ### Fixed
213
+ ### Changed
109
214
 
110
- - Codemode follows Pi's model-facing helper guidance and generates asynchronous global declarations from the same definitions used by the official sandbox. `searchTools` and `describeTool` are explicitly global functions called with `await`; their complete declarations remain available even when the nested tool catalog exceeds its inline budget. Discovery uses Pi-generated tool samples with declared output schemas and its text-result default, so scripts can distinguish JSON text from structured values.
215
+ - Update bundled pi packages to the 0.79.9 line.
111
216
 
112
- ## [1.0.0-beta.87]
217
+ ## [0.4.7] - 2026-06-22
113
218
 
114
219
  ### Fixed
115
220
 
116
- - `mikan migrate` moves the per-thread session directories that early versions left inside `sessions/` to the state directory intact, instead of stopping with `Unexpected entry in sessions directory`. Links inside them are moved as links and never followed.
221
+ - Apply the recent-days and max-messages history window when syncing existing chat sessions so resuming a session no longer replays unbounded older log history.
117
222
 
118
- ## [1.0.0-beta.86]
223
+ ### Changed
119
224
 
120
- ### Breaking
225
+ - Always report a usage summary whenever token usage is available.
121
226
 
122
- - **The GitHub adapter now runs as a bound GitHub account driven by webhooks, and no longer uses a GitHub App or polling.** People mention it with autocomplete, assign it issues and pull requests, and request its review. Set `GITHUB_AGENT_TOKEN` (a fine-grained PAT of that account), `GITHUB_WEBHOOK_SECRET` (an organization or App webhook to `<LINK_URL>/github/webhook`), and `GITHUB_REPOS` (now required: `owner/repo` or `owner/*`); the link server must run. `GITHUB_APP_ID`, `GITHUB_INSTALLATION_ID`, `GITHUB_APP_PRIVATE_KEY`, `GITHUB_APP_PRIVATE_KEY_PATH`, and `GITHUB_POLL_INTERVAL` are removed, `@<app-slug>` no longer triggers, and `<state-dir>/github-sync.json` is no longer read and can be deleted. Deliveries are best effort: events sent while mikan is down are not replayed. See [ADR 0015](docs/adr/0015-github-agent-account-and-webhooks.md) and [Make mikan a GitHub teammate](src/content/docs/github-teammate-guide.md).
123
- - **The GitHub adapter is restricted by default.** It answers only in private repositories listed in `GITHUB_REPOS`, only to people with write permission, and only comments and reads. `GITHUB_CAPABILITIES=triage,push` restores label and assignee management and pull requests; `GITHUB_PUBLIC_REPOS`, `GITHUB_USERS`, `GITHUB_MIN_PERMISSION`, and `GITHUB_TRIGGERS` narrow or widen who can trigger it and how.
124
- - `github_checks` reads GitHub Actions jobs and commit statuses instead of check runs, because fine-grained PATs have no Checks permission. Check runs from third-party CI apps are no longer visible.
125
- - **mikan no longer runs git for GitHub conversations.** Nothing is cloned into `<office>/repo`, and `github_sync` is removed. The agent clones, commits, and pushes inside its sandbox with the sandbox's GitHub credentials, and `github_pr` only opens a pull request for a branch the agent already pushed. What the agent can push is now bounded by that token, the account's repository role, and branch protection instead of mikan's `pi/*` rule; protect the default branch. GitHub conversations now trust `membership`, because only collaborators with write access can trigger them, so they receive `sandbox.defaultSharedVault` and settings-declared MCP servers like Slack conversations.
126
- - **Session files move from `<workspace>/<office-key>/sessions/` to `<state-dir>/conversations/<office-key>/sessions/`, and sandboxes no longer see them.** Run `mikan migrate` before starting this version. The agent searches earlier history in `log.jsonl`, which stays in the office directory. See [ADR 0016](docs/adr/0016-host-sandbox-trust-boundary.md).
127
- - Library API: `officeSessionsDir` and `resolveChannelSessionFile` are removed; use `office.sessionsDir` and `tryResolveCurrentSession(office.sessionsDir)`. `getThreadSessionFile` and `resolveParentSessionForThread` take the sessions directory, and the `ChatHistorySync` options and `registerThreadSession`/`hasMaterializedChatSession` take `office` instead of `conversationDir`.
128
- - `jev_browser` no longer takes a `session` parameter. Each conversation thread has one browser that stays open across calls until `close: true`; a later `url` opens a new tab, and opening past three tabs closes the oldest inactive tabs and reports them in `closedOldTabs`. Model-named sessions each started another Chrome, and a few of them exhausted a 1 GB sandbox until every page load timed out.
227
+ ### Tests
129
228
 
130
- ### Changed
229
+ - Add coverage for capping existing chat history sync to the recent history window.
131
230
 
132
- - Pi is upgraded from 0.87 to 0.99 (`pi-agent-core`, `pi-ai`).
133
- - MCP servers now connect through Pi's `@earendil-works/pi-mcp` client instead of the official `@modelcontextprotocol/sdk`, which is removed along with `zod`. Stdio servers still receive only a minimal inherited environment plus their configured `env`. When an HTTP server rejects the connection, the error now carries the status and the start of the server's response body.
231
+ ## [0.4.6] - 2026-06-18
134
232
 
135
- ### Added
233
+ ### Fixed
136
234
 
137
- - GitHub issue and pull request conversations receive the default OpenConnector runtime token like Slack conversations, named `mikan:github:<conversation-id>`.
235
+ - Store Slack streamed responses as a single finalized bot log entry instead of per-delta fragments.
236
+ - Coalesce legacy Slack bot log fragments when bootstrapping chat sessions so platform history is not filled with partial words.
138
237
 
139
- ### Fixed
238
+ ### Tests
140
239
 
141
- - `models.json` follows `--state-dir` / `STATE_DIR` like `settings.json`; the daemon, `mikan migrate`, and `mikan onboard` no longer read or write `~/.mikan/models.json` for another state directory.
142
- - A daemon adopts at startup only the sandbox containers that mount its own workspace, so two mikan instances sharing one Docker engine no longer stop each other's containers.
143
- - The sandbox image now ships CJK fonts (`fonts-noto-cjk`, about 170 MB). Without them, `jev_browser` screenshots showed Chinese and Japanese text as blank space, and charts drawn in the sandbox could not use Chinese labels.
144
- - Python packages in the sandbox go through uv. The system pip still refuses installs, but its message now names the uv commands to use (`uv run --with <package>`), so the agent recovers after one attempt instead of trying pip, venvs, and apt in turn. The docs no longer claim that `pip install --user` works.
145
- - Creating or updating a periodic event now reports its next three runs in the event's timezone, so the agent no longer computes weekdays itself (it once announced a Monday reminder for a Tuesday). An invalid cron `schedule` or `timezone` is rejected before the event file is written instead of being saved and then skipped by the scheduler.
146
- - `apt-get install` works inside managed sandbox containers again. The containers drop all capabilities, so apt's download sandbox user could not switch groups and every install failed; the image now runs apt downloads as root, and the image smoke test installs a package under the same hardening.
147
- - Asking "好了嗎" at the moment a background task finishes no longer answers "還在處理" right beside the completion notice. Task status now trusts the recorded end of the run over the runtime's still-settling state.
148
- - A Slack message whose acknowledgement was lost during a socket reconnect no longer runs twice. Slack redelivers such events; mikan now recognizes a message or mention it has already taken and ignores the copy. A failed acknowledgement is logged instead of surfacing as an unhandled promise rejection.
149
- - A Slack app that is not an agent app no longer calls `assistant.threads.setSuggestedPrompts` and logs `not_agent_app` every time someone opens its DM; after the first refusal the call is skipped until restart.
150
- - A long Slack answer that outgrew the native stream no longer shows up twice. The partial streamed message is deleted before the full answer is posted, and the notification text sent with it is capped at the 4,000 bytes `chat.update` accepts, so the edit no longer fails with `msg_too_long`.
151
- - A long Slack answer with many headings no longer fails with `invalid_blocks` and an `Error:` line. Slack expands each heading of a markdown block into its own block and rejects a message with more than 50; when an answer would exceed that, its headings are sent as bold lines instead.
152
- - MCP tools ask the model for a progress label like every built-in tool, so the Slack checklist shows a readable step (for example "確認 GitHub 連線") instead of `mcp__server__tool`. The label is not forwarded to the MCP server, and a tool that already has its own `label` argument is left unchanged.
240
+ - Add coverage for coalescing streamed bot history and logging only finalized Slack responses.
153
241
 
154
- ## [1.0.0-beta.85]
242
+ ## [0.4.5] - 2026-06-17
155
243
 
156
- ### Breaking
244
+ ### Added
157
245
 
158
- - **State migrations run only through `mikan migrate`.** The daemon now refuses to start while a migration is pending, and prints the exact command to run. It no longer moves anything at startup or on first read. After installing a new version, run `mikan migrate --sandbox=<the daemon's --sandbox> --dry-run`; if anything is pending, stop the daemon, run the same command without `--dry-run`, then start it. Applied migrations are recorded in `<state-dir>/migrations.json`, and `mikan onboard` marks a new state directory as fully migrated. See [ADR 0014](docs/adr/0014-versioned-state-migrations.md).
159
- - **Removed commands:** `mikan office claim`, `mikan office migrate-openconnector`, `mikan office migrate-events`, `mikan office migrate-door-policy`, `mikan sessions migrate`, and `mikan sandbox status|diff|migrate`. `mikan office list` remains and now prints each office key with its platform and conversation id.
160
- - **Upgrades are supported only from 0.5.3.** Formats that existed only in 1.0.0 prereleases are no longer converted: OpenConnector `open-connector-runtime-token.json` files, door-policy settings, Pi 0.84 session files, `<state-dir>/conversations/<raw-id>` directories, and the hashed legacy vault keys. A prerelease install that already ran those conversions is unaffected.
161
- - **Sandbox containers are disposable.** A managed container has no home volume. When its image or mounts change, it is replaced once it is stopped, and only the workspace and vault mounts carry over. Anything else, including `/root`, installed packages, and caches, starts empty. Existing `mikan-home-*` volumes and `mikan-migrate:*` images are no longer used, and operators may delete them.
162
- - **Host and container vaults use hashed keys only.** The runtime no longer falls back to vault directories named by raw user id (`host`) or `container-<name>` (`container:*`). `mikan migrate` renames them.
163
- - The public API no longer exports `findV3SessionFiles`, `isV3SessionFile`, or `migrateSessionFile`.
246
+ - Rotate shared top-level channel sessions on biweekly Sunday boundaries while keeping thread sessions fixed.
164
247
 
165
248
  ### Changed
166
249
 
167
- - When a scheduled run hits its budget, the stop notice now says how long it ran, how many model and tool calls it made, the slowest steps with their durations, and which step was still running. Slow queries can be found from the notice alone.
250
+ - Bootstrap rotated shared channel sessions from the recent two-week chat log window and prevent older log history from being resynced into the active session.
251
+ - Harden managed Docker sandboxes with dropped capabilities, no-new-privileges, and a PID limit.
168
252
 
169
253
  ### Fixed
170
254
 
171
- - Multi-line error notices in Slack are italicized line by line, because Slack emphasis does not span line breaks.
172
- - Upgrading a 0.5.3 install keeps each conversation's credentials. The old startup migration looked for a vault name that 0.5.3 never wrote, so 0.5.3 conversation vaults were silently left behind; `mikan migrate` moves them to their office keys.
173
- - Upgrading a 0.5.3 install removes its sandbox containers instead of recreating them from snapshots under their old names next to the new ones.
255
+ - Report usage summaries when token usage is available even if provider pricing data is missing.
174
256
 
175
- ## [1.0.0-beta.84]
176
-
177
- ### Performance
257
+ ### Tests
178
258
 
179
- - Shorten the `jev_browser` tool definition from about 7,000 to 2,800 characters sent on every turn: its description and parameters no longer repeat each other or explain rules the tool already enforces with its own error messages.
180
- - List skills in the prompt one line each under their directory instead of an XML block with a full path per skill; a path appears only when a skill's directory differs from its name. A workspace with 68 skills drops from about 31,000 to 22,000 characters of prompt per turn with the same names and descriptions.
259
+ - Add coverage for session rotation, thread bootstrap watermarks, sandbox hardening flags, and usage summaries without cost data.
181
260
 
182
- ## [1.0.0-beta.83]
261
+ ## [0.4.4] - 2026-06-12
183
262
 
184
263
  ### Fixed
185
264
 
186
- - Stop copying each mikan reply back into the session a second time: chat history sync compared the posted reply, which carries the `_Triggered by …_` signature, against the model's unsigned text, missed the match, and appended the signed copy. Context held every answer twice and taught the model to keep writing the signature. Imported bot messages are now compared and stored without the signature, and a posted reply that opens with the tool checklist is matched to the model's answer it ends with.
265
+ - Require exact provider model ID matches when grouping verified admin model availability.
187
266
 
188
- ## [1.0.0-beta.82]
189
-
190
- ### Changed
191
-
192
- - mikan reacts `saluting_face` (eyes on GitHub) itself when a run starts its first work tool, instead of the model spending a separate round on the reaction; the model's `react` tool is left for background checks with nothing to report.
193
- - mikan owns the `_Triggered by …_` signature on chat responses and replaces any signature line the model wrote, so user messages no longer carry a per-turn attribution instruction. The model is still asked to sign GitHub text it writes itself.
194
- - The model reads the current time from each message's send time instead of running `date`.
195
-
196
- ## [1.0.0-beta.81]
267
+ ## [0.4.3] - 2026-06-12
197
268
 
198
269
  ### Added
199
270
 
200
- - Stream every run of a session live in Session View: a run started from Slack or another chat platform now appears on an open page as it happens (user message, tool results, the streaming answer), then the timeline reloads. Page-sent messages use the same stream; thinking text and errors appear after the timeline reloads.
201
- - Guard tool loops: repeating the same tool call with identical arguments earns a notice from the third call, is blocked from the fifth, and stops the run at the tenth; short repeating cycles of calls also earn a notice.
202
- - Compact a session in the background after a successful run when its context nears the compaction threshold, so the next message does not wait for compaction.
203
-
204
- ### Fixed
205
-
206
- - Undo Slack's HTML escaping on incoming text: the model and the office log saw `&amp;&amp;`, `&lt;`, and `&gt;` where the user typed `&&`, `<`, and `>`.
207
- - Keep the tool checklist visible while the final answer streams; it used to disappear until the answer finished.
208
- - Stop an open Session View page from holding shutdown open; open live streams now close after a five-second grace, so a restart no longer waits for the process manager's kill timeout.
209
- - Report a GitHub API request that returns an empty body where a resource is required with its method, path, and status, instead of failing later on a null value.
210
-
211
- ### Security
212
-
213
- - **Breaking (deploy):** The link server (Admin, Session View, and credential links) now listens on `127.0.0.1` even when `LINK_URL` is set; it used to listen on every interface, so portal tokens could travel in plain HTTP straight to `LINK_PORT` around the TLS reverse proxy. A reverse proxy on the same host (`reverse_proxy 127.0.0.1:8181`) keeps working unchanged. Set the new `LINK_HOST` (for example `0.0.0.0`) when the proxy runs on another host or in a separate network namespace.
271
+ - Group admin model selectors by verified availability for OpenAI and Anthropic keys.
272
+ - Log the active provider and model when each agent run starts to simplify server-side debugging.
214
273
 
215
- ## [1.0.0-beta.80]
274
+ ## [0.4.2] - 2026-06-11
216
275
 
217
276
  ### Fixed
218
277
 
219
- - Post no Slack usage summary for a `[SILENT]` response: the reply and its thread were deleted, so the summary for a quiet recurring event landed at the top level of the channel on every run.
220
- - Stop warning `Could not remove snapshot image mikan-migrate:...` for every migrated container on each startup; the startup sweep now leaves a snapshot alone while its container still runs from it, and still reclaims snapshots no container uses.
278
+ - Resolve custom providers through pi's model registry so conversation settings can select models from `models.json`.
279
+ - Resolve attached file paths from the sandbox runtime workspace so image sandboxes upload generated files from the correct host path.
221
280
 
222
- ## [1.0.0-beta.79]
281
+ ## [0.4.1] - 2026-06-08
223
282
 
224
283
  ### Changed
225
284
 
226
- - Load the Discord adapter and `discord.js` only when Discord is active, saving about 38 MB of memory and 90 ms of startup in processes that do not run Discord.
227
- - Use pi's `typebox` 1.3.27 for tool and settings schemas instead of the incompatible `@sinclair/typebox` 0.34; platform tool packs now share pi's `AgentTool` schema types. Schema validation errors retain field paths but use typebox 1's wording.
228
- - **Breaking (SDK):** `new ChatHistorySync()` now requires `{ isCommandText }`, so sessions no longer import the command inventory from the adapters. Pass the newly exported `isCommandText` to keep filtering command messages out of synced history.
229
-
230
- ### Security
231
-
232
- - Only send the Slack bot token to `https://*.slack.com` file URLs, and stream incoming attachments to disk with a 100 MiB limit instead of buffering whole files in memory; a download over the limit is rejected, not retried, and leaves no partial file.
285
+ - Update bundled pi packages to the 0.78.1 line.
233
286
 
234
287
  ### Fixed
235
288
 
236
- - Reject missing sandbox helper executables as ordinary `ENOENT` errors instead of emitting an unhandled child-process error.
237
- - Accept `thinking: max` in subagent profiles; they kept their own level list without `max`, while settings and `/pi-model` accepted it.
238
- - Spill oversized MCP JSON results as indented JSON so `read` and `grep` can inspect them; the compact single-line spill exceeded `read`'s per-line limit.
239
- - Record a Discord channel without a name (such as a DM) under its channel id instead of a `null` name.
289
+ - Stream Slack responses with delta-only appends to avoid duplicated message segments and streaming state conflicts.
290
+ - Include Slack streaming recipient metadata so threaded streamed replies work in Slack E2E and production workspaces.
240
291
 
241
292
  ### Tests
242
293
 
243
- - Type-check tests, E2E code, and the embedder example in pre-commit and CI, and remove every `any` and double assertion from tests.
244
- - Run tests in random order and print the seed, so order-dependent tests fail visibly and can be reproduced.
294
+ - Add Slack streaming E2E coverage for delta appends without duplicate text.
245
295
 
246
- ## [1.0.0-beta.78]
296
+ ## [0.4.0] - 2026-06-07
247
297
 
248
298
  ### Added
249
299
 
250
- - Capture durable knowledge after each settled human run: Jev gates the exchange, and the conversation's model adds or updates stamped lines under `## Captured knowledge` in the conversation `MEMORY.md`; configured secrets are redacted from captured entries (ADR 0011).
251
- - Give each new managed image container a per-office home volume (`mikan-home-<key>`) at `/root`. A stopped container whose image or mounts are stale is recreated from the current image with the same volume, so `/root` survives image upgrades; running containers are never interrupted (ADR 0009).
252
- - Add `mikan sandbox status|diff|migrate` to inspect managed containers and move legacy containers onto a home volume with the daemon stopped.
300
+ - Add streamed response deltas across adapters so replies can update progressively.
301
+ - Add Slack reply mode configuration in the admin portal.
302
+ - Add event tool CRUD support for listing, reading, updating, and deleting scheduled events, with conversation-scoped listing by default and explicit all-event listing.
253
303
 
254
304
  ### Changed
255
305
 
256
- - Bound MCP tool results like `bash`: JSON is re-serialized compactly, oversized results become a structural digest (keys, counts, and pagination kept) within Pi's 50KB/2000-line limit, and the full result is spilled to `.mikan/mcp-output/` in the runtime workspace. `structuredContent` is used when `content` is empty, binary resources are no longer inlined, error text is bounded, and MCP results pass through secret redaction.
257
- - Shared top-level channel sessions no longer rotate every two weeks; they stay current until `/new`, and Pi's automatic compaction bounds the model context (ADR 0010).
258
- - The sandbox image installs its runtime outside `/root` and is published only with mikan releases.
259
- - Document the Vault as the store for development credentials that sandbox programs read directly; OpenConnector is the path for third-party service access (ADR 0013).
306
+ - Reorganize source modules and centralize shared type definitions for clearer contributor navigation.
307
+ - Centralize adapter conversation intake and reduce wrapper indirection across runtime, adapters, commands, config, and web modules.
308
+ - Attribute agent Sentry traces with platform and conversation context for clearer operator debugging.
260
309
 
261
- ### Removed
310
+ ### Fixed
262
311
 
263
- - Remove scheduled Dream memory maintenance. Conversation `MEMORY.md` is written only by the agent and by post-run memory capture; existing `dream.json` checkpoints are no longer read (ADR 0012).
312
+ - Persist global settings overrides correctly.
313
+ - Warn when invalid custom OAuth service definitions are skipped instead of silently dropping them.
264
314
 
265
- ## [1.0.0-beta.77]
315
+ ## [0.4.0-beta.0]
266
316
 
267
317
  ### Added
268
318
 
269
- - Provision the standard sandbox image with Node.js 24, Chromium, ffmpeg, pinned `agent-browser` 0.38.1, and a checksummed Google Workspace CLI so `jev_browser` and capture workflows work without runtime installation and current-page recording preserves hydrated browser state.
319
+ - Add streamed response deltas across adapters so replies can update progressively.
320
+ - Add Slack reply mode configuration in the admin portal.
321
+ - Add event tool CRUD support for listing, reading, updating, and deleting scheduled events, with conversation-scoped listing by default and explicit all-event listing.
270
322
 
271
323
  ### Changed
272
324
 
273
- - Run every `jev_browser` command through the conversation-authorized sandbox executor, preserve native snapshots, refs, frames, tabs, screenshots, HAR, and recording, serialize calls per runner, and make named-session continuity and close-only operations explicit.
274
- - Bound autonomous browser failures and repeated action cycles, refresh current page evidence before reporting completion, and refuse to silently resurrect an explicitly closed named session as `about:blank`.
275
- - Delegate persisted session behavior to public Pi session and harness APIs instead of maintaining duplicate storage semantics.
325
+ - Reorganize source modules and centralize shared type definitions for clearer contributor navigation.
326
+ - Centralize adapter conversation intake and reduce wrapper indirection across runtime, adapters, commands, config, and web modules.
276
327
 
277
328
  ### Fixed
278
329
 
279
- - Log LLM cancellation reasons and Pi run ids only while provider transport is active, avoiding false abort logs during authentication, payload hooks, retry waits, tool execution, or after structural requests finish.
280
-
281
- ### Security
282
-
283
- - Harden state and credential ownership by preserving explicit vault mount targets outside secret directories, rejecting migration collisions, keeping private file writes atomic, and deriving session operations from authorized conversation identities.
330
+ - Persist global settings overrides correctly.
284
331
 
285
- ## [1.0.0-beta.76]
332
+ ## [0.3.2] - 2026-06-02
286
333
 
287
- ### Changed
334
+ ### Fixed
288
335
 
289
- - Update `@earendil-works/pi-agent-core` and `@earendil-works/pi-ai` to 0.87.0, including their aligned telemetry and harness dependencies.
336
+ - Preserve trigger attribution in streamed agent responses so tool-written GitHub comments include the triggering user.
290
337
 
291
- ## [1.0.0-beta.75]
338
+ ## [0.3.1] - 2026-06-02
292
339
 
293
340
  ### Added
294
341
 
295
- - `jev_browser` agent tool: drives a real Chrome browser toward a natural-language goal, deciding each step (click, type, select, scroll, wait) itself using a Jev decision per step against ref-indexed accessibility snapshots — the same architecture as [`browser-use/jev-ultrafast`](https://github.com/browser-use/jev-ultrafast). A `commands` mode forwards raw [`agent-browser`](https://github.com/vercel-labs/agent-browser) CLI argument arrays directly, covering screenshot, video recording, HAR capture, cookies, and any other agent-browser capability beyond the click/type/select loop. A named `session` spans multiple calls against the same browser (start a recording, run a goal, stop the recording, screenshot the result) and stays open by default; every result reports `browserContinuity` in plain language so a caller can tell whether the browser it just used was actually the same one a prior call left open. Tool progress lines are prefixed `jev_browser ·`, matching the existing `jev ·` treatment. Requires the `agent-browser` CLI installed on the host (not a mikan dependency); host sandbox only.
296
- - Jev decision cost (from the `jev` tool, `jev_browser`'s decision loop, Slack auto-reply gating, and task-intent classification) is now reported to Sentry/OpenTelemetry as `agent.jev.cost`, `agent.jev.duration`, and `agent.jev.calls`, tagged by which feature made the call. Previously this spend was invisible next to the primary chat model's per-run cost — it only ever appeared inside a tool call's raw JSON text.
297
-
298
- ### Changed
342
+ - Add Slack Block Kit response support and document Block Kit implementation lessons.
299
343
 
300
- - Every agent tool now requires the `label` parameter the system prompt already promises for every tool call, so its progress line always shows a real description instead of silently falling back to the raw tool name.
344
+ ### Fixed
301
345
 
302
- ## [1.0.0-beta.74]
346
+ - Require explicit mentions before Slack thread replies trigger the bot.
303
347
 
304
- ### Security
348
+ ### Tests
305
349
 
306
- - Host sandbox tool output (bash, read, and every other agent tool) is now scrubbed of any configured secret env var's value before it reaches the model or the durable session transcript. Host sandbox mode does not isolate environment variables, so a command like `echo $OPENROUTER_API_KEY` previously returned the key in plain text with no defense beyond the model choosing not to repeat it; it is now replaced with a `[SECRET:VAR_NAME]` placeholder using mikan's existing secret env var inventory.
350
+ - Enforce phase-one strict checks and unused export checks.
307
351
 
308
- ### Fixed
352
+ ## [0.3.0] - 2026-06-01
309
353
 
310
- - Stop and shutdown-restart notices ("Stopping…", "Stopped.", the restart notice) are now recorded in the conversation's `log.jsonl`, matching every other agent reply. Previously these control messages reached the platform but left no trace in the human-readable history the agent (and operators) grep, so a stopped run looked, on later review, like it had never been interrupted.
354
+ ### Added
311
355
 
312
- ## [1.0.0-beta.73]
356
+ - Add source directory README guides for contributors navigating adapters, commands, runtime, sessions, sandbox, tools, login, admin, and session-view code.
313
357
 
314
358
  ### Changed
315
359
 
316
- - Admin: redesigned the page around a persistent icon sidebar and a single active settings pane (Claude/ChatGPT settings-app style), replacing the pill-tab-plus-accordion layout. Conversation and workspace scope each get their own rail; every pane shares one quiet header (title, one-line description, actions) instead of a stack of bordered cards. Widened the page from 960px to 1180px so the sidebar-plus-pane layout has room to breathe.
317
-
318
- ## [1.0.0-beta.72]
360
+ - Centralize chat session bootstrapping through `ChatSessionManager` so Slack top-level and thread sessions share the same log-based history sync path.
361
+ - Rename Slack branch/fork terminology to thread/anchor terminology across the adapter, session viewer, and documentation.
362
+ - Model session-view related sessions as parent/thread relationships, including fixed-path thread sessions without legacy parent metadata.
363
+ - Remove legacy thread fork and snapshot helpers from session storage.
319
364
 
320
- ### Added
365
+ ### Fixed
321
366
 
322
- - Admin: the Skills panel (conversation and global) can now create, edit, and delete skills directly, not just list and preview them. Saving writes `SKILL.md` straight into the workspace skills tree the harness loader reads, so a new or edited skill is available on the conversation's next turn.
367
+ - Anchor session-view thread links on the root turn instead of earlier bootstrapped context messages.
323
368
 
324
- ## [1.0.0-beta.71]
369
+ ## [0.3.0-beta.0]
325
370
 
326
371
  ### Changed
327
372
 
328
- - Built-in subagents now use the full 100-turn / $10 allowance, and the model-facing `subagent` tool can only request a larger token allowance instead of accidentally shrinking turn, cost, or duration budgets (for example, to $0.30).
373
+ - Centralize chat session bootstrapping through `ChatSessionManager` so Slack top-level and thread sessions share the same log-based history sync path.
374
+ - Rename Slack branch/fork terminology to thread/anchor terminology across the adapter, session viewer, and documentation.
375
+ - Model session-view related sessions as parent/thread relationships, including fixed-path thread sessions without legacy parent metadata.
376
+ - Remove legacy thread fork and snapshot helpers from session storage.
329
377
 
330
378
  ### Fixed
331
379
 
332
- - Shared-memory guidance now keeps personal, project-specific, and tool-specific knowledge in its proper scope, prevents memory from overriding system mechanisms, and removes the obsolete shared `SYSTEM.md` environment log.
333
- - Console usage summaries now show cache-read tokens alongside fresh input tokens.
334
- - Sandbox provisioning no longer logs `Container … already running` on every readiness check; creation, restart, drift, and failure messages remain visible.
380
+ - Anchor session-view thread links on the root turn instead of earlier bootstrapped context messages.
335
381
 
336
- ## [1.0.0-beta.70]
382
+ ## [0.2.4] - 2026-06-01
337
383
 
338
384
  ### Fixed
339
385
 
340
- - Sandbox: a container migrated to the office-key mount layout (or recreated after its mount configuration drifted) no longer re-migrates on every subsequent restart. The one-time bridging snapshot image is now removed once the new container is confirmed up, instead of being kept forever on the mistaken assumption that the container would eventually run from the base image again. In production this had pinned dozens of containers to increasingly stale snapshots and left their images unreclaimed, consuming disk space on every restart.
341
-
342
- ## [1.0.0-beta.69]
343
-
344
- ### Changed
345
-
346
- - `harness/jev.ts` is now backed by [`@geminixiang/jev`](https://github.com/geminixiang/jev), a standalone SDK shaped like pi-ai (providers own auth, a model catalog, and a wire implementation) instead of a hand-rolled OpenRouter fetch client. `evaluateWithJev`'s signature, types, and error classes are unchanged, so the auto-reply gate, DM task-intent classification, and the `jev` tool are unaffected. The swap adds request retries and timeouts, neither of which existed before, and a path to other Jev backends (TypeSafe, Vercel AI Gateway, Cloudflare Workers AI) without touching call sites.
386
+ - Make Slack bot-rooted thread session seeds loadable by storing platform-history assistant metadata.
347
387
 
348
- ## [1.0.0-beta.68]
388
+ ## [0.2.3] - 2026-06-01
349
389
 
350
390
  ### Added
351
391
 
352
- - `jev` agent tool: the model can now call Jev directly with a `state` (text or JSON) and any number of boolean / choice / score `questions`, mirroring the decisions API one-to-one — structured instructions and criteria, per-option probabilities, confidence, and score legends all pass through. Available to the main agent and to the `worker`, `software-engineer`, `data-scientist`, and `summarizer` subagent profiles. A missing `OPENROUTER_API_KEY` is reported as a tool error so the model judges for itself.
353
- - Slack: DM messages in a task thread (and top-level DMs while a task is running) are classified by Jev as `status`, `steer`, or `request` before spending a model turn. Status questions are answered from recorded task state; steering is delivered into the running task; anything else starts a normal run. The regex status matcher remains as the fallback.
354
- - `task_status` reports `queued` for tasks that were admitted but have not started executing yet.
392
+ - Add a sandbox resource limit tool for checking and temporarily updating managed sandbox CPU and memory limits.
355
393
 
356
- ### Changed
394
+ ### Fixed
357
395
 
358
- - `harness/jev.ts` accepts structured JSON for state, instructions, and criteria, and returns `confidence` and `legend` on choice / score answers.
359
- - Jev auto-reply and task-intent state renders `<@U…>` mentions as `@Name` (the bot as `@mikan`) so Jev can tell a message addressed to someone else from one addressed to mikan.
360
- - Tool progress lines for `jev` calls are prefixed with `jev ·` so users can see which steps came from a calibrated judgment.
396
+ - Isolate Slack sessions rooted at bot messages so thread replies do not inherit unrelated channel history.
361
397
 
362
- ## [1.0.0-beta.67]
398
+ ## [0.2.2] - 2026-05-30
363
399
 
364
- ### Changed
365
-
366
- - Slack: unaddressed thread replies in shared channels now pass through the same `/pi-auto-reply` gate as top-level messages instead of being dropped unconditionally. In `jev` mode, Jev scores the message together with its surrounding scope (the channel's recent top-level messages, or the thread's messages plus whether mikan has already replied there), so bare follow-ups like "then roll it back" are judged in context. `off` still requires a mention; `on` now admits thread replies too.
367
- - Deploy docs: `/pi-auto-reply` slash command description lists `on | off | jev`.
400
+ ### Added
368
401
 
369
- ## [1.0.0-beta.66]
402
+ - Add `/admin` portal with token-protected access via `/admin` and `/pi-admin` commands.
403
+ - Add admin APIs and UI for conversation settings, global settings, workspace preview, skills, events, session links, and login/vault links.
404
+ - Add model selection in the admin portal using `ModelRegistry.getAvailable()` instead of free-text fields.
405
+ - Share portal shell chrome across admin, session-view, and login/vault pages.
406
+ - Document admin, login, and session token boundaries in `docs/portal-auth-model.md`.
370
407
 
371
- ### Added
408
+ ### Changed
372
409
 
373
- - `/pi-auto-reply` gains a third state, `jev`: alongside manual `on`/`off`, a Slack channel can now delegate the "does this unaddressed message address mikan" decision to Jev (`typesafe/jev`), a fast typed-decision model, on a per-message basis. Any evaluation failure (including a missing `OPENROUTER_API_KEY`) fails closed to "not addressed" so a misconfiguration cannot make the bot noisy in a shared channel.
374
- - `harness/jev.ts`: a standalone `evaluateWithJev` client for Jev, reached through OpenRouter's `/api/alpha/decisions` REST API using the same `OPENROUTER_API_KEY` pi-ai's `openrouter` chat provider reads. Jev returns typed decisions (boolean probability, choice, score) instead of generated text, so it is a plain function call sites use directly rather than a selectable chat provider in `models.ts`'s catalog.
375
- - Jev-mode auto-reply decisions (channel, probability, addressed, truncated message text) are logged at info level for observability.
410
+ - Normalize slash-command feedback into muted compact summaries.
411
+ - Align desktop layout widths across all portal surfaces.
376
412
 
377
- ## [1.0.0-beta.65]
413
+ ## [0.2.1] - 2026-05-27
378
414
 
379
415
  ### Added
380
416
 
381
- - Slack: when a run resolves to exactly one completed subagent profile with a known persona, the final answer posts as a fresh message under that profile's own username/icon (`Data Scientist`, `Software Engineer`, `DevOps Engineer`, `Account Manager`, `Business Development`, `Creative Producer`, `Ad Operations Specialist`) instead of mikan's own identity. Mixed-profile or partially-failed runs keep mikan's identity, since `chat.update`/`chat.appendStream` cannot carry a Slack identity and there is no single "who answered this" to attribute.
382
- - The `react` tool (add an emoji reaction to the triggering message) is now documented in the system prompt with two unconditional triggers tied to `start_task`'s existing bar: react before starting any multi-step investigation, change/test, or long wait, and react instead of writing "nothing to report" on a periodic/background check with nothing to report.
383
- - Discord and Telegram now wire the `react` tool into their responders (previously Slack/GitHub-only despite the tool being granted everywhere); a shared short-name-to-Unicode translation covers what the prompt recommends for platforms whose reaction API takes a Unicode character rather than a name.
384
- - `creative-producer` subagent profile gains the `generate_image` tool grant, matching its image-deliverable description.
417
+ - Add expanded command, configuration, deployment, development, session, and skill documentation.
418
+ - Add README hero and architecture diagrams.
419
+ - Add project agent development rules and Karpathy coding guidelines.
385
420
 
386
421
  ### Changed
387
422
 
388
- - Built-in subagent profile `maxTokens` raised from 100,000 to 1,000,000: the old cap was a common budget-exceeded trip for ordinary investigative tasks (e.g. a repo-wide architecture review), not just runaway loops.
389
- - The `analysis-only` subagent profile is renamed `summarizer`: it is a DAG synthesis node over upstream dependency output, not a mid-task advisor.
390
- - Office data policy for non-Slack platforms is now an explicit rule (ADR 0008): only Slack conversations can be public, and Telegram/Discord/GitHub offices always resolve to private rather than falling through an "unknown" branch by omission.
391
- - The Admin office visibility card now states the effective outcome in plain words instead of the internal policy model; public Slack channels get one "Hide the files in this channel from other offices" checkbox, other conversation kinds show the fixed Hidden state with no control.
392
- - `settings.json` ownership (schema, scope merge, readers, writers, one-time migrations) is gathered under `src/settings/`.
423
+ - Simplify the README overview and clarify sandbox runtime architecture documentation.
424
+ - Simplify file guards and retry helpers.
393
425
 
394
- ### Docs and maintenance
426
+ ### Fixed
395
427
 
396
- - Describe mikan as an organization-wide, per-conversation-isolated agent.
397
- - Move the three remaining top-level source files into their owning modules (`adapters/messages.ts`, `adapters/index.ts`, `cli/process-lifecycle.ts`); pure move, no behavior change.
428
+ - Retry attachment downloads.
429
+ - Skip retry sleep on the final attempt and clarify retry naming.
398
430
 
399
- ## [1.0.0-beta.64]
431
+ ## [0.2.0] - 2026-05-23
400
432
 
401
433
  ### Changed
402
434
 
403
- - The retired door-policy keys (`sandbox.image.workspaceMount`, `sandbox.workspace`) are dropped at load time and no longer appear in the resolved sandbox settings or the Admin office view.
435
+ - Renamed the project, CLI, npm package, GitHub repository, documentation, release skill, and sandbox image references to mikan.
436
+ - Changed platform credentials to unprefixed env vars (`SLACK_APP_TOKEN`, `SLACK_BOT_TOKEN`, `TELEGRAM_BOT_TOKEN`, `DISCORD_BOT_TOKEN`) while keeping `MIKAN_*` aliases as fallbacks.
437
+ - Changed runtime env vars such as `LINK_URL`, `LINK_PORT`, `STATE_DIR`, OAuth scope overrides, and Cloudflare sandbox settings to prefer unprefixed names with `MIKAN_*` fallbacks.
438
+ - Raised the minimum supported Node.js version to `>=22.19.0`.
439
+ - Updated internal variable, function, type, Docker label, sandbox image, and generated resource names to use mikan naming.
440
+ - Added manual dispatch support to the CI workflow.
404
441
 
405
- ### Added
406
-
407
- - `mikan office migrate-door-policy` removes the retired keys from the global and every registered office settings file, preserving all other settings and leaving files without them untouched. Only an explicit shared-support `private` visibility is carried into `office.visibility`; `full`, `isolated`, and legacy `private` are removed without deriving any grant.
408
-
409
- ## [1.0.0-beta.63]
442
+ ## [0.2.0-beta.25] - 2026-05-23
410
443
 
411
444
  ### Changed
412
445
 
413
- - Office data policy is now a single **visibility** derived from the Slack conversation type (ADR 0008): public channels are public offices; private channels, DMs, group DMs, externally shared channels, and unknown kinds are private. Every office receives the same projection — its own directory read-write, every other public office read-only under `/workspace/public/<office key>`, and shared `MEMORY.md`/`skills/` read-write for public offices or read-only for private ones. Nothing mounts the workspace root.
414
- - The five-way door policy (`isolated`, `trusted/shared-support`, `trusted/full`, …) is retired. Legacy settings still parse but no longer change the projection; offices that still declare `full` are reported once per process. The Admin "door policy" control and `/pi-sandbox door` are replaced by one switch that can narrow a public channel to private (`/pi-sandbox visibility <private|default>`); nothing can widen beyond what Slack allows.
415
- - Backends without a managed projection (`host`, `container:*`, `cloudflare:*`) now serve private offices with a one-time logged warning instead of refusing, since they are trusted deployments by definition.
446
+ - Grouped session modules under a single directory.
447
+ - Centralized command parsing across adapters.
448
+ - Removed explicit `any` usage across the type surface.
449
+ - Cleaned unused dependencies.
416
450
 
417
- ### Added
451
+ ### Tests
418
452
 
419
- - The Slack adapter records channel kinds for every registered office from the channel list loaded at startup, so offices created before kinds were recorded keep their public status without waiting for a new message.
453
+ - CI now enforces coverage thresholds.
454
+
455
+ ## [0.2.0-beta.24]
420
456
 
421
457
  ### Fixed
422
458
 
423
- - Recreating a sandbox container after a visibility change removes empty `/workspace/public/<key>` mountpoints that `docker commit` carried over from the previous mount set.
459
+ - Session history writes now emit valid assistant messages.
424
460
 
425
- ## [1.0.0-beta.62]
461
+ ## [0.2.0-beta.23]
426
462
 
427
- ### Changed
463
+ ### Fixed
428
464
 
429
- - Scheduled events now live in host-only per-office state (`<state dir>/conversations/<office key>/events/`) and are never mounted into a sandbox. The `event` tool and the Admin portal are the only writers, both confined to the current office; `create` never overwrites, deleting a record cancels its timer or cron immediately, and the Slack App Home lists only the opener's DM office schedules. The filesystem watcher is gone: hand-edited records take effect on the next start.
430
- - OpenConnector is an ordinary MCP server with a deployment default. When a Slack conversation has not declared `open-connector`, mikan mints that conversation's runtime token with `OPENCONNECTOR_ADMIN_TOKEN` and saves a normal `mcpServers` entry in its settings; conversations may override it with a self-hosted server or disable it like any other MCP entry. The loader no longer fills `connectionName`; connection selection belongs to OpenConnector.
465
+ - Refresh stale channel history before forking a thread.
466
+ - Separate history seeds from live sessions to prevent cross-contamination.
467
+ - Materialize channel history when the first thread is created.
431
468
 
432
469
  ### Added
433
470
 
434
- - `mikan office migrate-events` moves legacy `<workspace>/events/*.json` records into the owning office's state and reports records it cannot attribute.
435
- - `mikan office migrate-openconnector` converts legacy `open-connector-runtime-token.json` files into conversation MCP entries.
471
+ - Scripts to migrate session history and repair orphan thread sessions.
472
+
473
+ ## [0.2.0-beta.22]
436
474
 
437
475
  ### Fixed
438
476
 
439
- - The agent `event` tool can no longer list, read, update, or delete another office's events, and `scope=all` is rejected.
477
+ - Slack: fork bot response threads from the channel session so replies inherit context.
478
+ - Vault: preserve failures when the default shared vault cannot be applied.
440
479
 
441
- ### Docs and maintenance
480
+ ## [0.2.0-beta.21]
442
481
 
443
- - Redraw the architecture diagram as a single rounded page and refresh the README image.
444
- - Support local Slack E2E runs, capture intake and session markers on failure, and schedule E2E events through the `event` tool instead of writing files.
445
- - Record the Office isolation policy, storage inventory, and OpenConnector history audit under `docs/`.
482
+ ### Added
483
+
484
+ - Vault: seed new sandboxes from a shared profile (`sandbox.defaultSharedVault`).
446
485
 
447
- ## [1.0.0-beta.61]
486
+ ## [0.2.0-beta.20]
448
487
 
449
488
  ### Added
450
489
 
451
- - Ground Slack DM progress replies in runtime/v4 task observations; common task-thread status queries no longer steer work, and ordinary followups do not repeat completion mentions.
452
- - Slack DM task handoff: independent task threads keep the main conversation free, with text steering in active task threads and continuation after stopping.
490
+ - Sentry: report user-facing failures.
491
+ - Auto-reply: surface configured rules in the status command.
453
492
 
454
493
  ### Fixed
455
494
 
456
- - Keep thread stop acknowledgements in the source thread, including shared-channel unmentioned stop controls.
457
- - Notify Slack DM task requesters with a fresh in-thread mention after normal completion.
458
- - Finalize stop acknowledgements that arrive after the cancelled run has already settled.
459
- - Propagate final response delivery failures so rejected updates do not trigger completion notifications.
460
- - Honor stop during runner preparation and keep older active tasks visible in status queries.
461
- - Report task admission, asynchronous startup, and status inspection failures through the existing Sentry/OTLP observability path.
495
+ - Slack: anchor event-fork sessions correctly (#61).
496
+ - Slack: keep session ephemerals scoped to threads.
497
+ - Agent: require history search before answering unknown replies.
498
+ - Agent: keep quiet tool errors out of chat.
462
499
 
463
500
  ### Changed
464
501
 
465
- - Publish the already built and verified npm package without rerunning build and repository setup lifecycle scripts.
466
- - Keep the documented and CI coverage commands as stable entry points while maintaining their shared Vitest invocation in one place.
467
- - Validate debug Session View selections from their path and header, leaving full parsing to consumers that load session content instead of inspecting the same file twice.
502
+ - Removed cloud-logging config — log to stdout/stderr and route via your process manager.
468
503
 
469
- ## [1.0.0-beta.60]
504
+ ## [0.2.0-beta.19]
470
505
 
471
506
  ### Fixed
472
507
 
473
- - Separate CJK-adjacent bold dollar amounts for Slack's Markdown parser while preserving code and link destinations.
474
- - Validate Session View selections through read-only inspection so active and repeatedly selected historical sessions do not conflict with writer ownership or appear corrupted.
508
+ - Sandbox: bootstrap `gh` git credentials inside managed containers.
475
509
 
476
- ## [1.0.0-beta.59]
510
+ ## [0.2.0-beta.18]
477
511
 
478
512
  ### Fixed
479
513
 
480
- - Keep Slack's working indicator in its own paragraph so progressive heading and table updates can replace existing rich-text messages without `block_mismatch`.
481
- - Pace failed progressive redraws as well as successful ones, retaining accumulated text for recovery instead of retrying on every delta.
482
-
483
- ### Changed
484
-
485
- - Use Commander for CLI option parsing, subcommand validation, and generated help.
486
- - Guide interactive onboarding with arrow-key selections, masked credentials, and a final confirmation before saving. Cancel without writing settings.
487
- - Refuse custom-provider onboarding when models.json already exists, without printing credentials or writing partial settings.
514
+ - Sandbox: update memory swap when applying CPU/memory limits.
515
+ - Slack: preserve long replies posted in threads.
488
516
 
489
- ## [1.0.0-beta.58]
517
+ ## [0.2.0-beta.17]
490
518
 
491
519
  ### Added
492
520
 
493
- - Restore Slack `/pi-auto-reply on|off` with the original per-conversation marker files, without judge models or rules.
494
- - Expose the admin portal command on Discord and Telegram.
521
+ - Sentry: store env values and write a `sentry-cli` config for richer error reports.
495
522
 
496
523
  ### Changed
497
524
 
498
- - Collapse conversation sections in the Admin portal, load their data only when opened, remember their open state, and open Vault and Session View links in new tabs.
525
+ - Bumped `@earendil-works/pi-*` packages.
499
526
 
500
- ## [1.0.0-beta.57]
527
+ ## [0.2.0-beta.16]
501
528
 
502
- ### Changed
503
-
504
- - Export raw platform conversation, channel, session, thread, message, and user identifiers so Sentry traces can be mapped directly back to their source while continuing to exclude human-readable names and conversation or tool content.
505
-
506
- ### Removed
529
+ ### Performance
507
530
 
508
- - Remove telemetry identifier hashing and the `TELEMETRY_HASH_KEY` deployment setting.
531
+ - Slack: unblock startup while backfill is running.
509
532
 
510
- ## [1.0.0-beta.56]
533
+ ## [0.2.0-beta.15]
511
534
 
512
535
  ### Added
513
536
 
514
- - Add content-free agent diagnostics for actual model IDs, token and cost totals, first-token latency, context utilization, message and attachment counts, payload sizes, tool categories and status, and retry, compaction, and budget summaries.
537
+ - Config: validate JSON files with TypeBox schemas.
538
+ - Agent: attribute the trigger (mention/direct/auto-reply/…) in responses.
515
539
 
516
- ### Security
540
+ ## [0.2.0-beta.14]
517
541
 
518
- - Replace raw conversation, session, message, thread, and user telemetry identifiers with stable opaque values, support deployment-specific HMACs through `TELEMETRY_HASH_KEY`, and stop sending usernames to Sentry.
542
+ ### Fixed
519
543
 
520
- ## [1.0.0-beta.55]
544
+ - Login: refresh the sandbox after copying a shared profile.
521
545
 
522
- ### Added
546
+ ### Changed
523
547
 
524
- - Export explicitly configured, content-free traces and metrics over standard OTLP HTTP/protobuf, including GenAI and OpenInference attribution for Arize Phoenix. Sentry remains available for sanitized issues and legacy metric fallback without duplicate spans; zero configuration remains network-free.
525
- - Add a guided Admin dialog for configuring MCP servers, with structured fields or pasted standard `mcpServers` JSON and card-based installed-server management.
548
+ - Simplified command dispatch, token stores, and re-exports (#60).
526
549
 
527
- ### Changed
550
+ ## [0.2.0-beta.13]
528
551
 
529
- - Delegate the agent run loop, retries, compaction, persistence, cancellation, and the native `read`, `write`, `edit`, and `bash` tools to Pi's `AgentHarness` and execution-tool implementations. mikan retains budgets, platform presentation, authorization, and sandbox-backed execution routing.
530
- - Upgrade `pi-agent-core` and `pi-ai` to 0.85.1, including GPT-6 Astra catalog entries and the 30-minute prompt-cache TTL for GPT-5.6+ Responses models.
531
- - Consolidate harness, office, session, sandbox, web-adapter, and shared-command ownership without changing the published root exports.
552
+ ### Added
532
553
 
533
- ### Removed
554
+ - Login: gcloud OAuth support.
534
555
 
535
- - Remove managed skill packages and their Admin/package materialization surfaces. Workspace and conversation skills remain supported.
536
- - Remove the auto-reply judge, command, configuration, and UI; explicit platform triggers remain supported.
537
- - Remove the unused `/api/agent-events/stream` SSE mirror, its token setting, and supporting event types. The authenticated session viewer continues to use `/session/stream`.
556
+ ## [0.2.0-beta.12]
538
557
 
539
558
  ### Fixed
540
559
 
541
- - Preserve Pi's native optional tool schemas, require an explicit authorized execution environment for native file/shell tools, and keep container working directories inside the guest instead of applying them to the host Docker process.
560
+ - Auto-reply: persist the resolved session key.
542
561
 
543
- ## [1.0.0-beta.54]
562
+ ## [0.2.0-beta.11]
544
563
 
545
- ### Changed
546
-
547
- - Admin portal: MCP servers are added by pasting the server's standard `mcpServers` JSON (Claude Desktop / Cursor shape), stored as-is; the old name / target / `KEY=value` form is gone. Every add and preset install is followed by a real connection check, and the response shows the tool count or the server's own error; a per-server **Test** button re-checks an installed entry. Query-string values in listed URLs are redacted. stdio entries now run their command on the host at save time.
564
+ ### Fixed
548
565
 
549
- ## [1.0.0-beta.53]
566
+ - Login: make Slack login ephemeral and refresh vault mounts after credentials change.
550
567
 
551
568
  ### Changed
552
569
 
553
- - Graceful shutdown drains in-flight runs for up to five minutes (was 30 seconds) after stopping intake; runs still open at the deadline are aborted and their conversations receive a restart notice instead of silence. The pm2 template `kill_timeout` is now six minutes; update your `ecosystem.config.cjs` to match. Shutdown failures now log every nested step error.
570
+ - Sandbox: update base image and tags.
571
+
572
+ ## [0.2.0-beta.10]
554
573
 
555
574
  ### Added
556
575
 
557
- - Send the run user (id and username) with Sentry events instead of stripping it, so Conversations show who sent each message; email and IP stay dropped.
558
- - Set the Sentry conversation id to the session key on every agent run so Agent Monitoring groups gen_ai spans per thread.
559
- - Report subagent outcomes to Sentry from the subagent tool: `agent.subagent.runs` / `agent.subagent.duration` metrics and a lifecycle breadcrumb for every status; a Sentry error under `error_domain=subagent` for `failed` and `invalid_output` (fingerprinted by error class) and for launch failures. `budget_exceeded`, `timeout`, `cancelled`, and `skipped` stay metrics-only. Reports carry run metrics, never task text or labels.
576
+ - Auto-reply: channel trigger rules and a configurable judge model (`llm.autoReply`).
577
+ - Slack: native E2E smoke workflow under `e2e/`.
560
578
 
561
- ## [1.0.0-beta.52]
579
+ ### Fixed
562
580
 
563
- ### Removed
581
+ - Auto-reply: use mom-compatible marker files; judge policy never throws and always logs.
582
+ - Events: validate one-shot times before scheduling; simplify fresh follow-up sessions.
564
583
 
565
- - Remove the subagent `requiredTools` / `required_tools` mechanism: the post-run "every listed tool was invoked" check was a proxy for evidence that never held and failed only after the budget was spent. Callers that want evidence can read `toolCallCounts`.
584
+ ### Changed
566
585
 
567
- ## [1.0.0-beta.51]
586
+ - Onboard: default model is `claude-sonnet-4-6`.
587
+ - Separated runtime and control-plane paths.
568
588
 
569
- ### Fixed
589
+ ## [0.2.0-beta.9]
570
590
 
571
- - Drop `requiredTools` from built-in subagent profiles; requiring both `read` and `bash` discarded finished answers from tasks that needed only one of them.
572
- - Keep a caller's `requiredTools` when the request also names a profile.
573
- - Stop dropping the retained assistant message when an overflow retry rebuilds context from the store.
591
+ ### Added
574
592
 
575
- ### Changed
593
+ - Session view: floating composer and per-message copy button.
594
+ - Docker sandbox: add `rg` and `fd` to the image.
576
595
 
577
- - Read mikan session metadata through Pi's `session.getValue` in `open`/`inspect`; compare `fstat` fields instead of hashing the file for pending-session materialization.
596
+ ### Fixed
578
597
 
579
- ## [1.0.0-beta.50]
598
+ - Session view: ignore Enter during IME composition; preserve code-block contrast.
580
599
 
581
- ### Fixed
600
+ ## [0.2.0-beta.8]
582
601
 
583
- - Tolerate byte-identical duplicate Dream session files while rejecting divergent same-ID files.
602
+ ### Added
584
603
 
585
- ## [1.0.0-beta.49]
604
+ - Login: shared vault profiles.
605
+ - Session view: improved interactive chat console.
606
+ - Slack: harden socket connection and label the platform in the connect log.
607
+ - Agent: `ThinkingLevel` type on session parameters.
586
608
 
587
609
  ### Changed
588
610
 
589
- - Configure OpenConnector only at startup with `OPENCONNECTOR_ENDPOINT` and `OPENCONNECTOR_ADMIN_TOKEN`; ignore settings overrides of the reserved server, and reduce the Admin MCP Marketplace to the Metabase preset.
611
+ - Sandbox: store the image workspace mount in settings.
612
+ - Dropped `vault.json` metadata — directories are the only source of truth.
613
+ - Refactored agent runner orchestration into smaller modules.
590
614
 
591
- ## [1.0.0-beta.48]
615
+ ### Removed
616
+
617
+ - `UserBindingStore` and `bindings.json` plumbing.
618
+ - Log-to-session backfill.
619
+
620
+ ## [0.2.0-beta.7]
592
621
 
593
622
  ### Added
594
623
 
595
- - Add an offline session migration for Pi 0.84-generation v4 JSONL files, with verified atomic replacement and preserved `*.pi-084.bak` originals.
624
+ - Sandbox: temporary `boost` command for one-off CPU/memory bumps.
625
+ - Slack: mute command summaries.
596
626
 
597
627
  ### Changed
598
628
 
599
- - Upgrade `pi-agent-core` and `pi-ai` to 0.85.0 and persist sessions with the current `v: 4`, `storageVersion: 1` schema.
600
- - Extend `mikan sessions migrate` to convert both legacy mikan v3 and Pi 0.84-generation v4 sessions while the daemon is stopped.
629
+ - Migrated `pi-*` packages to the `@earendil-works/` namespace.
601
630
 
602
- ## [1.0.0-beta.47]
631
+ ### Fixed
632
+
633
+ - Slack: log messages from external apps; hide bash tool diagnostics.
634
+ - Session: ignore history written before a reset.
635
+ - Agent: clarify runtime workspace paths in the system prompt.
636
+
637
+ ## [0.2.0-beta.6]
603
638
 
604
639
  ### Added
605
640
 
606
- - Integrate OpenConnector as a host-side MCP gateway: Slack Conversation offices receive scoped runtime identities, while provider OAuth connections remain in the gateway and execution audit stays attributable to the originating conversation.
607
- - Preserve operating guidance supplied during MCP initialization and present it to the agent with explicit system-prompt and user-intent boundaries.
608
- - Add automatic selection of a sole OpenConnector provider connection when an action omits `connectionName`; retain explicit selection when multiple accounts exist.
641
+ - Commands: conversation model switch (`/pi-model …`) with `:thinking` shorthand.
642
+ - Config: onboarding flow for global settings (`mikan --onboard`).
643
+ - Docs: PM2 ecosystem config and production deploy guide.
609
644
 
610
645
  ### Changed
611
646
 
612
- - Gate MCP tools by the platform trust model and enforce the untrusted package boundary.
613
- - Make platform shutdown cleanup bounded and strengthen runner/session lifecycle rollback handling.
647
+ - Config: nest settings schema; align chat platform commands.
614
648
 
615
649
  ### Fixed
616
650
 
617
- - Isolate Slack DM and thread E2E context and bound event-delivery waits.
651
+ - Slack: strip only the bot's own mention from message text.
618
652
 
619
- ### Tests
653
+ ## [0.2.0-beta.5]
654
+
655
+ ### Added
620
656
 
621
- - Add coverage for OpenConnector token provisioning, MCP instruction propagation, connection selection, trust gating, lifecycle cleanup, and Slack isolation.
657
+ - Sandbox: Cloudflare sandbox bridge (experimental).
658
+ - Tests: unit coverage for `CommandRegistry` and command handlers.
622
659
 
623
- ## [1.0.0-beta.46]
660
+ ### Changed
624
661
 
625
- ### Added
662
+ - Env: renamed `MOM_*` env vars to `MIKAN_*` (breaking).
663
+ - Vault: conversation vault directories are now the source of truth; dropped platform prefix from the conversation vault key.
664
+ - Config: `--state-dir` is the single source for settings.
665
+ - Tightened command/runtime types and added a `postPrivate` capability.
626
666
 
627
- - Add an interactive `mikan onboard` wizard that configures one chat adapter, an LLM provider, and the sandbox, writing private environment and settings files while retaining non-interactive template generation.
628
- - Derive shared workspace visibility from platform channel privacy: Slack public channels can update shared memory, private channels receive it read-only, and DMs, external channels, unknown kinds, and other platforms stay isolated unless explicitly overridden.
629
- - Schedule Dream maintenance for Conversation-office memory with durable evidence checkpoints.
630
- - Add an Admin MCP Marketplace with reviewed GitHub, Context7, Playwright, Sequential Thinking, and Metabase presets; Metabase installations accept an instance endpoint and API key.
667
+ ## [0.2.0-beta.4]
631
668
 
632
669
  ### Changed
633
670
 
634
- - Remove the executable extension system and its CLI/chat management surfaces; packages remain the supported path for deploying read-only skills.
635
- - Remove the harness `auth.json` credential store; configure provider credentials through environment variables, onboarding, or the conversation vault.
636
- - Remove Gondolin, Firecracker, and GitHub Cloud Build log integrations from the supported runtime surface.
637
- - Fail closed when a sandbox backend cannot enforce an isolated office or read-only shared workspace memory; use `image:*` or explicitly select a trusted read-write projection.
638
- - Consolidate runtime, session, adapter, web, and configuration ownership to reduce duplicate lifecycle and parsing rules.
671
+ - Hardened core writes; unified adapter retry and log helpers.
672
+ - Eliminated duplication across adapters, vault, and Slack command factories (#53).
673
+ - Session forks now anchor to raw split points.
674
+ - Adapter-specific stop logic stays in adapters.
639
675
 
640
676
  ### Fixed
641
677
 
642
- - Preserve streamed UTF-8 output when host sandbox chunks split multi-byte characters.
643
- - Re-aim migrated session lanes at the nearest surviving ancestor when the newest v3 entry contains facts but no v4 message.
678
+ - Slack: tighten thread reply triggers.
644
679
 
645
- ### Tests
680
+ ## [0.2.0-beta.3]
646
681
 
647
- - Move CI action runtimes to Node 24 and strengthen runtime, presenter, workspace-projection, MCP marketplace, and session migration coverage.
682
+ ### Added
648
683
 
649
- ## [1.0.0-beta.45]
684
+ - Session view: Slack-aware session viewer with branching (#51).
685
+ - Login: built-in credential presets and a redesigned credential portal.
686
+ - Sandbox: image-mode container CPU/memory limits (#50), bridge network isolation, `ffmpeg` in the tools image.
650
687
 
651
688
  ### Fixed
652
689
 
653
- - Session migration now collapses crash-duplicated v3 lines (a retried append writing the same header and entry twice) the way the v3 reader did, instead of failing v4 verification on the duplicate id. Found rehearsing the migration against 5,446 production session files; after the fix all migrate and reopen cleanly.
690
+ - Discord: normalize thread sessions; queue follow-up messages; persistent channel sessions; hide usage summary by default.
691
+ - Events: restore Slack synthetic notifications (#52).
692
+ - Attachments: wait for downloads before the agent accesses them.
654
693
 
655
- ## [1.0.0-beta.44]
694
+ ## [0.2.0-beta.2]
656
695
 
657
696
  ### Added
658
697
 
659
- - Connect MCP (Model Context Protocol) servers via `mcpServers` settings and expose their tools to the agent as `mcp__<server>__<tool>`; stdio and streamable-HTTP transports, per-server failures isolated, credentials held host-side in server config out of the model's reach.
660
- - Manage MCP servers from the admin portal: per-conversation and global panels with add, enable/disable, and remove; credential values are redacted to key names in the UI.
661
- - Migrate sessions to pi's v4 format with a `mikan sessions migrate` CLI; pi upgraded to 0.84.3.
662
- - Extensions can declare required host capabilities in `package.json` (`mikan.requires`); activation checks them before importing the module and `mikan ext validate` reports them.
698
+ - Per-user vault system for actor-scoped credential isolation (#24).
699
+ - Managed image sandbox (`--sandbox=image:<image>`) (#47).
700
+ - Login flow wired into the runtime; credential onboarding server (#32, #34).
701
+ - Slack: `/pi-new` and `/pi-login` DM commands.
702
+ - Events: actor-aware scheduling tool (#36, #39).
663
703
 
664
704
  ### Changed
665
705
 
666
- - Split the agent module into five authority modules (catalog, prompt, runner, subagent-runner, types); the runtime now owns session rotation decisions and per-event chat-history sync.
667
- - Derive all platform command registration and routing from the single command manifest.
668
- - Adopt pi-ai's retryable-error classifier instead of a local copy.
669
- - Conversation runtimes are keyed by office key, fixing cross-conversation runner reuse after ID changes.
706
+ - Internal contracts unified around "conversation" naming across adapter, store, config, log, and UI layers (#38, #41, #42, #43, #44, #46).
670
707
 
671
708
  ### Fixed
672
709
 
673
- - Session files enforce single-writer ownership, surviving inode reuse and stale writer claims.
674
- - Failed extension activations roll back cleanly; duplicate tool names are rejected.
675
- - Slack slash commands in threads carry the thread session key instead of falling back to the top-level session.
676
- - GitHub first-contact stop no longer creates participation state.
677
- - Subagent deadlines are enforced by a single wall-clock timer; `before_agent_start` hooks run before auth and pre-turn compaction.
678
- - Sandbox container removal failures no longer clear ownership, preventing orphaned containers.
679
- - Run outcomes settle from the final message and run state is released on throw.
710
+ - Telegram: handle bare `stop` in shared chats; escape unsupported HTML entities.
711
+ - Slack: queue follow-up messages per session.
680
712
 
681
- ## [1.0.0-beta.43]
713
+ ## [0.2.0-beta.1]
682
714
 
683
715
  ### Added
684
716
 
685
- - Add an optional authenticated GitHub webhook endpoint that wakes polling immediately for lower-latency issue and pull-request handling.
686
- - Add a machine-readable architecture index and generated system architecture documentation for repository-wide module boundaries and flows.
717
+ - File-backed credential vault (#31) and per-user vault routing (#33).
718
+ - OAuth: GitHub redirect flow, scope parity with `gh` CLI, gcloud OAuth.
719
+ - Sandbox: separate `stateDir` from `workspaceDir` to keep secrets out of sandboxes.
687
720
 
688
- ### Changed
721
+ ### Security
689
722
 
690
- - Run manual and automatic Session Dreams in the background while preserving session rotation and conversation maintenance boundaries.
723
+ - Hardened vault writes, file permissions, and login flow.
724
+ - Stopped leaking secrets in `docker exec` args.
725
+ - Enforced vault sandbox isolation policy.
691
726
 
692
- ### Fixed
727
+ ### Changed
693
728
 
694
- - Wait for final Slack thread responses in isolation coverage instead of accepting provisional native-stream text.
729
+ - Renamed `docker` sandbox mode to `container` (breaking).
730
+ - Replaced `DockerProvisioner` with `DockerContainerManager` + idle stop.
695
731
 
696
- ### Tests
732
+ ## [0.2.0-beta.0]
697
733
 
698
- - Add regression coverage for GitHub webhook authentication and dispatch, background Session Dream lifecycle behavior, and final Slack stream settlement.
734
+ ### Added
699
735
 
700
- ## [1.0.0-beta.42]
736
+ - Sentry integration for error monitoring, tracing, and metrics (#21).
737
+ - Persistent session management with in-thread replies (#18).
738
+ - Telegram: native slash commands; private-chat session fix (#15).
739
+ - `pi-coding-agent` extension loading (#12).
701
740
 
702
- ### Changed
741
+ ## Earlier releases
703
742
 
704
- [Showing lines 1-614 of 1985 (50.0KB limit). Use offset=615 to continue.]
743
+ For releases prior to `0.2.0-beta.0` (i.e. the `0.1.x` line), see the [git tag history](https://github.com/geminixiang/mikan/tags).