@geminixiang/mikan 1.0.0-beta.57 → 1.0.0-beta.59

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 (50) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +2 -1
  3. package/dist/adapters/commands/admin.d.ts.map +1 -1
  4. package/dist/adapters/commands/admin.js +7 -1
  5. package/dist/adapters/commands/admin.js.map +1 -1
  6. package/dist/adapters/commands/auto-reply.d.ts +5 -0
  7. package/dist/adapters/commands/auto-reply.d.ts.map +1 -0
  8. package/dist/adapters/commands/auto-reply.js +38 -0
  9. package/dist/adapters/commands/auto-reply.js.map +1 -0
  10. package/dist/adapters/commands/manifest.d.ts.map +1 -1
  11. package/dist/adapters/commands/manifest.js +15 -0
  12. package/dist/adapters/commands/manifest.js.map +1 -1
  13. package/dist/adapters/commands/registry.d.ts.map +1 -1
  14. package/dist/adapters/commands/registry.js +2 -0
  15. package/dist/adapters/commands/registry.js.map +1 -1
  16. package/dist/adapters/progressive-renderer.d.ts.map +1 -1
  17. package/dist/adapters/progressive-renderer.js +8 -2
  18. package/dist/adapters/progressive-renderer.js.map +1 -1
  19. package/dist/adapters/slack/bot.d.ts.map +1 -1
  20. package/dist/adapters/slack/bot.js +8 -8
  21. package/dist/adapters/slack/bot.js.map +1 -1
  22. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  23. package/dist/adapters/slack/response-lifecycle.js +4 -1
  24. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  25. package/dist/adapters/web/admin/portal.js +155 -85
  26. package/dist/adapters/web/admin/portal.js.map +1 -1
  27. package/dist/cli/arg-grammar.d.ts +7 -45
  28. package/dist/cli/arg-grammar.d.ts.map +1 -1
  29. package/dist/cli/arg-grammar.js +38 -80
  30. package/dist/cli/arg-grammar.js.map +1 -1
  31. package/dist/cli/boot.d.ts.map +1 -1
  32. package/dist/cli/boot.js +34 -47
  33. package/dist/cli/boot.js.map +1 -1
  34. package/dist/cli/office.d.ts.map +1 -1
  35. package/dist/cli/office.js +30 -21
  36. package/dist/cli/office.js.map +1 -1
  37. package/dist/cli/onboard.d.ts.map +1 -1
  38. package/dist/cli/onboard.js +35 -51
  39. package/dist/cli/onboard.js.map +1 -1
  40. package/dist/cli/sessions.d.ts.map +1 -1
  41. package/dist/cli/sessions.js +24 -16
  42. package/dist/cli/sessions.js.map +1 -1
  43. package/dist/cli/types.d.ts +2 -0
  44. package/dist/cli/types.d.ts.map +1 -1
  45. package/dist/cli/types.js.map +1 -1
  46. package/dist/config.d.ts +2 -0
  47. package/dist/config.d.ts.map +1 -1
  48. package/dist/config.js +20 -1
  49. package/dist/config.js.map +1 -1
  50. package/package.json +3 -1
package/CHANGELOG.md CHANGED
@@ -9,6 +9,30 @@ any release.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [1.0.0-beta.59]
13
+
14
+ ### Fixed
15
+
16
+ - Keep Slack's working indicator in its own paragraph so progressive heading and table updates can replace existing rich-text messages without `block_mismatch`.
17
+ - Pace failed progressive redraws as well as successful ones, retaining accumulated text for recovery instead of retrying on every delta.
18
+
19
+ ### Changed
20
+
21
+ - Use Commander for CLI option parsing, subcommand validation, and generated help.
22
+ - Guide interactive onboarding with arrow-key selections, masked credentials, and a final confirmation before saving. Cancel without writing settings.
23
+ - Refuse custom-provider onboarding when models.json already exists, without printing credentials or writing partial settings.
24
+
25
+ ## [1.0.0-beta.58]
26
+
27
+ ### Added
28
+
29
+ - Restore Slack `/pi-auto-reply on|off` with the original per-conversation marker files, without judge models or rules.
30
+ - Expose the admin portal command on Discord and Telegram.
31
+
32
+ ### Changed
33
+
34
+ - 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.
35
+
12
36
  ## [1.0.0-beta.57]
13
37
 
14
38
  ### Changed
package/README.md CHANGED
@@ -140,6 +140,7 @@ For routing, mounts, vault behavior, managed container details, and Cloudflare n
140
140
  | `/new` / `/pi-new` | Reset the current session |
141
141
  | `/model` / `/pi-model provider/model[:thinking]` | Switch the LLM for the current conversation |
142
142
  | `/sandbox` / `/pi-sandbox [boost\|door …]` | Show sandbox status, boost limits, or set the office door policy |
143
+ | `/pi-auto-reply <on\|off>` | Toggle mention-free replies for the current Slack channel |
143
144
  | `/admin` / `/pi-admin` | Open the admin portal |
144
145
  | `stop` / `/stop` | Stop the current run (works on every platform) |
145
146
 
@@ -224,4 +225,4 @@ PRs welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) for dev setup, commit sty
224
225
 
225
226
  MIT — see [LICENSE](LICENSE).
226
227
 
227
- Auto-reply has been retired. Existing `auto-reply` / `auto-reply.disabled` marker files and `llm.autoReply` / `autoReply` settings no longer take effect; reading configuration does not delete these files.
228
+ Slack auto-reply uses the conversation's `auto-reply` / `auto-reply.disabled` marker files. File contents are ignored: only the on/off marker name matters; rules and `llm.autoReply` judge-model settings remain retired.
@@ -1 +1 @@
1
- {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../../src/adapters/commands/admin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjE,qBAAa,mBAAoB,YAAW,cAAc;IAClD,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAuBzD;CACF"}
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../../src/adapters/commands/admin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjE,qBAAa,mBAAoB,YAAW,cAAc;IAClD,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CA8BzD;CACF"}
@@ -1,10 +1,16 @@
1
1
  import { slashForms, matchCommand } from "./manifest.js";
2
- import { portalNotConfiguredLines, replySummaryPrivately } from "./utils.js";
2
+ import { portalNotConfiguredLines, replySummary, replySummaryPrivately } from "./utils.js";
3
3
  const ADMIN_COMMANDS = slashForms("admin");
4
4
  export class AdminCommandHandler {
5
5
  async tryHandle(context) {
6
6
  if (!matchCommand(context.commandText, ADMIN_COMMANDS, { stripMention: true }))
7
7
  return false;
8
+ if (!context.privateConversation && !context.bot.postPrivate) {
9
+ await replySummary(context, "Admin", [
10
+ "For privacy, open a direct conversation with mikan and run `/admin` there.",
11
+ ]);
12
+ return true;
13
+ }
8
14
  if (!context.services.portalBaseUrl) {
9
15
  await replySummaryPrivately(context, "Admin", portalNotConfiguredLines("Admin portal"));
10
16
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../src/adapters/commands/admin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAE7E,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;AAE3C,MAAM,OAAO,mBAAmB;IAC9B,KAAK,CAAC,SAAS,CAAC,OAAuB;QACrC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,cAAc,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QAE7F,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;YACpC,MAAM,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC;YACxF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG;aAC7B,gBAAgB,EAAE;aAClB,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;QAC5D,MAAM,gBAAgB,GAAG,YAAY,EAAE,QAAQ,IAAI,YAAY,EAAE,WAAW,CAAC;QAE7E,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC;YACpD,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClD,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,aAAa,gBAAgB,KAAK,CAAC,KAAK,EAAE,CAAC;QAC3E,MAAM,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { slashForms, matchCommand } from \"./manifest.js\";\nimport type { CommandContext, CommandHandler } from \"./types.js\";\nimport { portalNotConfiguredLines, replySummaryPrivately } from \"./utils.js\";\n\nconst ADMIN_COMMANDS = slashForms(\"admin\");\n\nexport class AdminCommandHandler implements CommandHandler {\n async tryHandle(context: CommandContext): Promise<boolean> {\n if (!matchCommand(context.commandText, ADMIN_COMMANDS, { stripMention: true })) return false;\n\n if (!context.services.portalBaseUrl) {\n await replySummaryPrivately(context, \"Admin\", portalNotConfiguredLines(\"Admin portal\"));\n return true;\n }\n\n const platformUser = context.bot\n .getMessagingInfo()\n .users.find((user) => user.id === context.platformUserId);\n const platformUserName = platformUser?.userName || platformUser?.displayName;\n\n const token = context.services.adminTokenStore.create({\n platform: context.platform,\n platformUserId: context.platformUserId,\n conversationId: context.conversationId,\n ...(platformUserName ? { platformUserName } : {}),\n });\n\n const url = `${context.services.portalBaseUrl}/admin?token=${token.token}`;\n await replySummaryPrivately(context, \"Admin\", [url, \"Expires: 30 minutes\"]);\n return true;\n }\n}\n"]}
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../src/adapters/commands/admin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAE3F,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;AAE3C,MAAM,OAAO,mBAAmB;IAC9B,KAAK,CAAC,SAAS,CAAC,OAAuB;QACrC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,cAAc,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QAE7F,IAAI,CAAC,OAAO,CAAC,mBAAmB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;YAC7D,MAAM,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE;gBACnC,4EAA4E;aAC7E,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;YACpC,MAAM,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC;YACxF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG;aAC7B,gBAAgB,EAAE;aAClB,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;QAC5D,MAAM,gBAAgB,GAAG,YAAY,EAAE,QAAQ,IAAI,YAAY,EAAE,WAAW,CAAC;QAE7E,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC;YACpD,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClD,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,aAAa,gBAAgB,KAAK,CAAC,KAAK,EAAE,CAAC;QAC3E,MAAM,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { slashForms, matchCommand } from \"./manifest.js\";\nimport type { CommandContext, CommandHandler } from \"./types.js\";\nimport { portalNotConfiguredLines, replySummary, replySummaryPrivately } from \"./utils.js\";\n\nconst ADMIN_COMMANDS = slashForms(\"admin\");\n\nexport class AdminCommandHandler implements CommandHandler {\n async tryHandle(context: CommandContext): Promise<boolean> {\n if (!matchCommand(context.commandText, ADMIN_COMMANDS, { stripMention: true })) return false;\n\n if (!context.privateConversation && !context.bot.postPrivate) {\n await replySummary(context, \"Admin\", [\n \"For privacy, open a direct conversation with mikan and run `/admin` there.\",\n ]);\n return true;\n }\n\n if (!context.services.portalBaseUrl) {\n await replySummaryPrivately(context, \"Admin\", portalNotConfiguredLines(\"Admin portal\"));\n return true;\n }\n\n const platformUser = context.bot\n .getMessagingInfo()\n .users.find((user) => user.id === context.platformUserId);\n const platformUserName = platformUser?.userName || platformUser?.displayName;\n\n const token = context.services.adminTokenStore.create({\n platform: context.platform,\n platformUserId: context.platformUserId,\n conversationId: context.conversationId,\n ...(platformUserName ? { platformUserName } : {}),\n });\n\n const url = `${context.services.portalBaseUrl}/admin?token=${token.token}`;\n await replySummaryPrivately(context, \"Admin\", [url, \"Expires: 30 minutes\"]);\n return true;\n }\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import type { CommandContext, CommandHandler } from "./types.js";
2
+ export declare class AutoReplyCommandHandler implements CommandHandler {
3
+ tryHandle(context: CommandContext): Promise<boolean>;
4
+ }
5
+ //# sourceMappingURL=auto-reply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-reply.d.ts","sourceRoot":"","sources":["../../../src/adapters/commands/auto-reply.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjE,qBAAa,uBAAwB,YAAW,cAAc;IACtD,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAiCzD;CACF"}
@@ -0,0 +1,38 @@
1
+ import { setSlackConversationAutoReply, slackConversationAutoReplyEnabled } from "../../config.js";
2
+ import { slashForms, matchCommand } from "./manifest.js";
3
+ import { replySummary } from "./utils.js";
4
+ const AUTO_REPLY_COMMANDS = slashForms("autoreply");
5
+ export class AutoReplyCommandHandler {
6
+ async tryHandle(context) {
7
+ const matched = matchCommand(context.commandText, AUTO_REPLY_COMMANDS);
8
+ if (!matched)
9
+ return false;
10
+ if (context.platform !== "slack") {
11
+ await replySummary(context, "Auto-reply", [
12
+ "Auto-reply is currently available on Slack only.",
13
+ ]);
14
+ return true;
15
+ }
16
+ if (context.privateConversation) {
17
+ await replySummary(context, "Auto-reply", [
18
+ "Auto-reply only applies to shared channels. Direct messages already reply automatically.",
19
+ ]);
20
+ return true;
21
+ }
22
+ const value = matched.args[0]?.toLowerCase();
23
+ if ((value !== "on" && value !== "off") || matched.args.length !== 1) {
24
+ await replySummary(context, "Auto-reply", ["Usage: `/pi-auto-reply <on|off>`"]);
25
+ return true;
26
+ }
27
+ const office = context.services.workspace.office(context.address);
28
+ setSlackConversationAutoReply(office, value === "on");
29
+ const enabled = slackConversationAutoReplyEnabled(office);
30
+ await replySummary(context, "Auto-reply", [
31
+ enabled
32
+ ? "Enabled. New messages in this channel will trigger mikan without a mention."
33
+ : "Disabled. New messages in this channel must address mikan explicitly.",
34
+ ]);
35
+ return true;
36
+ }
37
+ }
38
+ //# sourceMappingURL=auto-reply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-reply.js","sourceRoot":"","sources":["../../../src/adapters/commands/auto-reply.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,iCAAiC,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,mBAAmB,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;AAEpD,MAAM,OAAO,uBAAuB;IAClC,KAAK,CAAC,SAAS,CAAC,OAAuB;QACrC,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;QACvE,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAE3B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACjC,MAAM,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE;gBACxC,kDAAkD;aACnD,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;YAChC,MAAM,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE;gBACxC,0FAA0F;aAC3F,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;QAC7C,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrE,MAAM,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE,CAAC,kCAAkC,CAAC,CAAC,CAAC;YAChF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClE,6BAA6B,CAAC,MAAM,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,iCAAiC,CAAC,MAAM,CAAC,CAAC;QAC1D,MAAM,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE;YACxC,OAAO;gBACL,CAAC,CAAC,6EAA6E;gBAC/E,CAAC,CAAC,uEAAuE;SAC5E,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import { setSlackConversationAutoReply, slackConversationAutoReplyEnabled } from \"../../config.js\";\nimport { slashForms, matchCommand } from \"./manifest.js\";\nimport type { CommandContext, CommandHandler } from \"./types.js\";\nimport { replySummary } from \"./utils.js\";\n\nconst AUTO_REPLY_COMMANDS = slashForms(\"autoreply\");\n\nexport class AutoReplyCommandHandler implements CommandHandler {\n async tryHandle(context: CommandContext): Promise<boolean> {\n const matched = matchCommand(context.commandText, AUTO_REPLY_COMMANDS);\n if (!matched) return false;\n\n if (context.platform !== \"slack\") {\n await replySummary(context, \"Auto-reply\", [\n \"Auto-reply is currently available on Slack only.\",\n ]);\n return true;\n }\n\n if (context.privateConversation) {\n await replySummary(context, \"Auto-reply\", [\n \"Auto-reply only applies to shared channels. Direct messages already reply automatically.\",\n ]);\n return true;\n }\n\n const value = matched.args[0]?.toLowerCase();\n if ((value !== \"on\" && value !== \"off\") || matched.args.length !== 1) {\n await replySummary(context, \"Auto-reply\", [\"Usage: `/pi-auto-reply <on|off>`\"]);\n return true;\n }\n\n const office = context.services.workspace.office(context.address);\n setSlackConversationAutoReply(office, value === \"on\");\n const enabled = slackConversationAutoReplyEnabled(office);\n await replySummary(context, \"Auto-reply\", [\n enabled\n ? \"Enabled. New messages in this channel will trigger mikan without a mention.\"\n : \"Disabled. New messages in this channel must address mikan explicitly.\",\n ]);\n return true;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/adapters/commands/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAExE,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,EAAE,SAAS,oBAAoB,EAyE3D,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAIvE;AAED,4FAA4F;AAC5F,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAM1D;AAED,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAG5D;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,IAAI;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EAAE,CAKhF;AAED,wBAAgB,YAAY,CAAC,OAAO,SAAS,MAAM,EACjD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GACnC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAQ7C;AAkBD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/adapters/commands/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAExE,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,EAAE,SAAS,oBAAoB,EAwF3D,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAIvE;AAED,4FAA4F;AAC5F,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAM1D;AAED,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAG5D;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,IAAI;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EAAE,CAKhF;AAED,wBAAgB,YAAY,CAAC,OAAO,SAAS,MAAM,EACjD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GACnC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAQ7C;AAkBD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD"}
@@ -65,6 +65,18 @@ export const COMMAND_MANIFEST = [
65
65
  telegramMenu: { description: "Show or boost sandbox limits" },
66
66
  telegramCommand: true,
67
67
  },
68
+ {
69
+ name: "autoreply",
70
+ aliases: ["auto-reply"],
71
+ description: "Enable or disable replies without mentions",
72
+ arg: {
73
+ name: "state",
74
+ description: "on or off",
75
+ required: true,
76
+ },
77
+ slackCommand: "/pi-auto-reply",
78
+ slackRoute: { includeText: true },
79
+ },
68
80
  {
69
81
  name: "stop",
70
82
  description: "Stop the current conversation",
@@ -86,6 +98,9 @@ export const COMMAND_MANIFEST = [
86
98
  description: "Open the admin portal",
87
99
  slackCommand: "/pi-admin",
88
100
  slackRoute: { thread: true },
101
+ discord: true,
102
+ telegramMenu: {},
103
+ telegramCommand: true,
89
104
  },
90
105
  ];
91
106
  export function commandManifestEntry(name) {
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/adapters/commands/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Platform-agnostic command manifest — the single inventory that platform\n * adapters derive their native slash-command registration and routing from,\n * and that `isCommandText` and the handler grammars mirror.\n *\n * Adding a command means adding a manifest entry plus a handler in this\n * directory; adapters pick up registration and routing from the entry instead\n * of hand-restating the inventory (where a missed spot used to mean a silent\n * no-response).\n *\n * Per CONTEXT.md, slash commands are a minimal chat control surface: detailed\n * or infrequent settings belong in Admin, and bare commands are limited to\n * `session`. `stop` is listed for platform registration/UI only — it is a\n * magic word owned by conversation intake, not a command handler.\n */\n\nimport type { CommandManifestEntry } from \"./types.js\";\n\nexport type { CommandManifestEntry, SlackSlashRoute } from \"./types.js\";\n\n/** Entry order is the Telegram command-menu order. */\nexport const COMMAND_MANIFEST: readonly CommandManifestEntry[] = [\n {\n name: \"login\",\n description: \"Store credentials in your private vault\",\n slackCommand: \"/pi-login\",\n slackRoute: { includeText: true, privateCommand: true },\n discord: true,\n telegramMenu: {},\n },\n {\n name: \"session\",\n description: \"Open the current session in the web viewer\",\n bare: true,\n slackCommand: \"/pi-session\",\n slackRoute: { thread: true },\n discord: true,\n telegramMenu: {},\n },\n {\n name: \"model\",\n description: \"Switch this conversation's LLM model\",\n arg: {\n name: \"model\",\n description: \"provider/model[:thinking], e.g. anthropic/claude-sonnet-4-6:off\",\n required: false,\n },\n slackCommand: \"/pi-model\",\n slackRoute: { includeText: true },\n discord: true,\n telegramMenu: {},\n },\n {\n name: \"sandbox\",\n description: \"Show sandbox status or boost limits\",\n arg: {\n name: \"action\",\n // Discord caps option descriptions at 100 characters (registration\n // fails otherwise); commands.test.ts enforces the budget.\n // The `door` action still works but is deliberately undocumented: the\n // workspace posture follows the platform's own channel visibility\n // automatically, and overriding it is an admin escape hatch, not a\n // user-facing feature.\n description: \"'boost' temporarily applies the configured boost limits\",\n required: false,\n },\n slackCommand: \"/pi-sandbox\",\n slackRoute: { includeText: true },\n discord: true,\n telegramMenu: { description: \"Show or boost sandbox limits\" },\n telegramCommand: true,\n },\n {\n name: \"stop\",\n description: \"Stop the current conversation\",\n magicWord: true,\n discord: true,\n telegramMenu: { description: \"Stop ongoing conversation\" },\n },\n {\n name: \"new\",\n description: \"Reset conversation history and start fresh\",\n slackCommand: \"/pi-new\",\n slackRoute: {},\n discord: true,\n telegramMenu: {},\n telegramCommand: true,\n },\n {\n name: \"admin\",\n description: \"Open the admin portal\",\n slackCommand: \"/pi-admin\",\n slackRoute: { thread: true },\n },\n];\n\nexport function commandManifestEntry(name: string): CommandManifestEntry {\n const entry = COMMAND_MANIFEST.find((candidate) => candidate.name === name);\n if (!entry) throw new Error(`Unknown command in manifest: ${name}`);\n return entry;\n}\n\n/** Slash spellings of a command: `/<name>` and `/pi-<name>` for the name and each alias. */\nexport function slashForms(name: string): readonly string[] {\n const entry = commandManifestEntry(name);\n return [entry.name, ...(entry.aliases ?? [])].flatMap((spelling) => [\n `/${spelling}`,\n `/pi-${spelling}`,\n ]);\n}\n\n/** Every accepted spelling: the bare name (when the command is bare) plus slash forms. */\nexport function commandForms(name: string): readonly string[] {\n const entry = commandManifestEntry(name);\n return [...(entry.bare ? [entry.name] : []), ...slashForms(name)];\n}\n\n/** Telegram `setMyCommands` payload (menu registration; routing is separate). */\nexport function telegramCommandMenu(): { command: string; description: string }[] {\n return COMMAND_MANIFEST.filter((entry) => entry.telegramMenu).map((entry) => ({\n command: entry.name,\n description: entry.telegramMenu?.description ?? entry.description,\n }));\n}\n\nexport function matchCommand<Command extends string>(\n text: string,\n aliases: readonly Command[],\n options?: { stripMention?: boolean },\n): { command: Command; args: string[] } | null {\n const tokens = text.trim().split(/\\s+/).filter(Boolean);\n const first = tokens[0];\n if (first === undefined) return null;\n\n const token = options?.stripMention ? first.replace(/@\\w+$/i, \"\") : first;\n const command = token.toLowerCase() as Command;\n return aliases.includes(command) ? { command, args: tokens.slice(1) } : null;\n}\n\n/**\n * Chat-command text recognition, derived from the command manifest so the\n * inventory has a single source of truth. Session resume uses it to keep\n * command messages out of replayed history.\n *\n * The `pi-[\\w-]+` alternative is a catch-all for platform-prefixed command\n * names (including ones a platform registers but this build no longer\n * handles), independent of the manifest.\n */\nconst COMMAND_NAMES = COMMAND_MANIFEST.flatMap((entry) => [entry.name].concat(entry.aliases ?? []));\n\nconst COMMAND_TEXT_PATTERN = new RegExp(\n `^\\\\/(?:pi-[\\\\w-]+|${COMMAND_NAMES.join(\"|\")})(?:@\\\\w+)?(?:\\\\s|$)`,\n \"i\",\n);\n\nexport function isCommandText(text: string): boolean {\n return COMMAND_TEXT_PATTERN.test(text.trim());\n}\n"]}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/adapters/commands/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Platform-agnostic command manifest — the single inventory that platform\n * adapters derive their native slash-command registration and routing from,\n * and that `isCommandText` and the handler grammars mirror.\n *\n * Adding a command means adding a manifest entry plus a handler in this\n * directory; adapters pick up registration and routing from the entry instead\n * of hand-restating the inventory (where a missed spot used to mean a silent\n * no-response).\n *\n * Per CONTEXT.md, slash commands are a minimal chat control surface: detailed\n * or infrequent settings belong in Admin, and bare commands are limited to\n * `session`. `stop` is listed for platform registration/UI only — it is a\n * magic word owned by conversation intake, not a command handler.\n */\n\nimport type { CommandManifestEntry } from \"./types.js\";\n\nexport type { CommandManifestEntry, SlackSlashRoute } from \"./types.js\";\n\n/** Entry order is the Telegram command-menu order. */\nexport const COMMAND_MANIFEST: readonly CommandManifestEntry[] = [\n {\n name: \"login\",\n description: \"Store credentials in your private vault\",\n slackCommand: \"/pi-login\",\n slackRoute: { includeText: true, privateCommand: true },\n discord: true,\n telegramMenu: {},\n },\n {\n name: \"session\",\n description: \"Open the current session in the web viewer\",\n bare: true,\n slackCommand: \"/pi-session\",\n slackRoute: { thread: true },\n discord: true,\n telegramMenu: {},\n },\n {\n name: \"model\",\n description: \"Switch this conversation's LLM model\",\n arg: {\n name: \"model\",\n description: \"provider/model[:thinking], e.g. anthropic/claude-sonnet-4-6:off\",\n required: false,\n },\n slackCommand: \"/pi-model\",\n slackRoute: { includeText: true },\n discord: true,\n telegramMenu: {},\n },\n {\n name: \"sandbox\",\n description: \"Show sandbox status or boost limits\",\n arg: {\n name: \"action\",\n // Discord caps option descriptions at 100 characters (registration\n // fails otherwise); commands.test.ts enforces the budget.\n // The `door` action still works but is deliberately undocumented: the\n // workspace posture follows the platform's own channel visibility\n // automatically, and overriding it is an admin escape hatch, not a\n // user-facing feature.\n description: \"'boost' temporarily applies the configured boost limits\",\n required: false,\n },\n slackCommand: \"/pi-sandbox\",\n slackRoute: { includeText: true },\n discord: true,\n telegramMenu: { description: \"Show or boost sandbox limits\" },\n telegramCommand: true,\n },\n {\n name: \"autoreply\",\n aliases: [\"auto-reply\"],\n description: \"Enable or disable replies without mentions\",\n arg: {\n name: \"state\",\n description: \"on or off\",\n required: true,\n },\n slackCommand: \"/pi-auto-reply\",\n slackRoute: { includeText: true },\n },\n {\n name: \"stop\",\n description: \"Stop the current conversation\",\n magicWord: true,\n discord: true,\n telegramMenu: { description: \"Stop ongoing conversation\" },\n },\n {\n name: \"new\",\n description: \"Reset conversation history and start fresh\",\n slackCommand: \"/pi-new\",\n slackRoute: {},\n discord: true,\n telegramMenu: {},\n telegramCommand: true,\n },\n {\n name: \"admin\",\n description: \"Open the admin portal\",\n slackCommand: \"/pi-admin\",\n slackRoute: { thread: true },\n discord: true,\n telegramMenu: {},\n telegramCommand: true,\n },\n];\n\nexport function commandManifestEntry(name: string): CommandManifestEntry {\n const entry = COMMAND_MANIFEST.find((candidate) => candidate.name === name);\n if (!entry) throw new Error(`Unknown command in manifest: ${name}`);\n return entry;\n}\n\n/** Slash spellings of a command: `/<name>` and `/pi-<name>` for the name and each alias. */\nexport function slashForms(name: string): readonly string[] {\n const entry = commandManifestEntry(name);\n return [entry.name, ...(entry.aliases ?? [])].flatMap((spelling) => [\n `/${spelling}`,\n `/pi-${spelling}`,\n ]);\n}\n\n/** Every accepted spelling: the bare name (when the command is bare) plus slash forms. */\nexport function commandForms(name: string): readonly string[] {\n const entry = commandManifestEntry(name);\n return [...(entry.bare ? [entry.name] : []), ...slashForms(name)];\n}\n\n/** Telegram `setMyCommands` payload (menu registration; routing is separate). */\nexport function telegramCommandMenu(): { command: string; description: string }[] {\n return COMMAND_MANIFEST.filter((entry) => entry.telegramMenu).map((entry) => ({\n command: entry.name,\n description: entry.telegramMenu?.description ?? entry.description,\n }));\n}\n\nexport function matchCommand<Command extends string>(\n text: string,\n aliases: readonly Command[],\n options?: { stripMention?: boolean },\n): { command: Command; args: string[] } | null {\n const tokens = text.trim().split(/\\s+/).filter(Boolean);\n const first = tokens[0];\n if (first === undefined) return null;\n\n const token = options?.stripMention ? first.replace(/@\\w+$/i, \"\") : first;\n const command = token.toLowerCase() as Command;\n return aliases.includes(command) ? { command, args: tokens.slice(1) } : null;\n}\n\n/**\n * Chat-command text recognition, derived from the command manifest so the\n * inventory has a single source of truth. Session resume uses it to keep\n * command messages out of replayed history.\n *\n * The `pi-[\\w-]+` alternative is a catch-all for platform-prefixed command\n * names (including ones a platform registers but this build no longer\n * handles), independent of the manifest.\n */\nconst COMMAND_NAMES = COMMAND_MANIFEST.flatMap((entry) => [entry.name].concat(entry.aliases ?? []));\n\nconst COMMAND_TEXT_PATTERN = new RegExp(\n `^\\\\/(?:pi-[\\\\w-]+|${COMMAND_NAMES.join(\"|\")})(?:@\\\\w+)?(?:\\\\s|$)`,\n \"i\",\n);\n\nexport function isCommandText(text: string): boolean {\n return COMMAND_TEXT_PATTERN.test(text.trim());\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/adapters/commands/registry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAkBhF,wBAAgB,sBAAsB,CACpC,aAAa,GAAE,aAAoC,GAClD,cAAc,EAAE,CAUlB;AAED,gFAAgF;AAChF,wBAAsB,eAAe,CACnC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC,CAKlB"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/adapters/commands/registry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAmBhF,wBAAgB,sBAAsB,CACpC,aAAa,GAAE,aAAoC,GAClD,cAAc,EAAE,CAUlB;AAED,gFAAgF;AAChF,wBAAsB,eAAe,CACnC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC,CAKlB"}
@@ -1,5 +1,6 @@
1
1
  import { MikanModels } from "../../harness/index.js";
2
2
  import { AdminCommandHandler } from "./admin.js";
3
+ import { AutoReplyCommandHandler } from "./auto-reply.js";
3
4
  import { LoginCommandHandler } from "./login.js";
4
5
  import { COMMAND_MANIFEST } from "./manifest.js";
5
6
  import { ModelCommandHandler } from "./model.js";
@@ -15,6 +16,7 @@ import { SessionViewCommandHandler } from "./session-view.js";
15
16
  */
16
17
  const HANDLER_FACTORIES = {
17
18
  admin: () => new AdminCommandHandler(),
19
+ autoreply: () => new AutoReplyCommandHandler(),
18
20
  login: () => new LoginCommandHandler(),
19
21
  session: () => new SessionViewCommandHandler(),
20
22
  model: (modelRegistry) => new ModelCommandHandler(modelRegistry),
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/adapters/commands/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAG9D;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAqE;IAC1F,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,mBAAmB,EAAE;IACtC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,mBAAmB,EAAE;IACtC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,yBAAyB,EAAE;IAC9C,KAAK,EAAE,CAAC,aAAa,EAAE,EAAE,CAAC,IAAI,mBAAmB,CAAC,aAAa,CAAC;IAChE,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,qBAAqB,EAAE;IAC1C,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,iBAAiB,EAAE;CACnC,CAAC;AAEF,MAAM,UAAU,sBAAsB,CACpC,aAAa,GAAkB,WAAW,CAAC,MAAM,EAAE;IAEnD,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACxE,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,2BAA2B,KAAK,CAAC,IAAI,kDAAkD,CACxF,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAmC,EACnC,OAAuB;IAEvB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;IACpD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import { MikanModels } from \"../../harness/index.js\";\nimport { AdminCommandHandler } from \"./admin.js\";\nimport { LoginCommandHandler } from \"./login.js\";\nimport { COMMAND_MANIFEST } from \"./manifest.js\";\nimport { ModelCommandHandler } from \"./model.js\";\nimport { NewCommandHandler } from \"./new.js\";\nimport { SandboxCommandHandler } from \"./sandbox.js\";\nimport { SessionViewCommandHandler } from \"./session-view.js\";\nimport type { CommandContext, CommandHandler, ModelRegistry } from \"./types.js\";\n\n/**\n * Handler factory per manifest command name. The manifest is the inventory\n * authority; this map only binds each entry to its implementation, and\n * `defaultCommandHandlers` verifies the binding is complete so a manifest\n * entry without a handler fails at construction instead of dispatching into\n * silence. Magic-word entries (routed by conversation intake) are exempt.\n */\nconst HANDLER_FACTORIES: Record<string, (modelRegistry: ModelRegistry) => CommandHandler> = {\n admin: () => new AdminCommandHandler(),\n login: () => new LoginCommandHandler(),\n session: () => new SessionViewCommandHandler(),\n model: (modelRegistry) => new ModelCommandHandler(modelRegistry),\n sandbox: () => new SandboxCommandHandler(),\n new: () => new NewCommandHandler(),\n};\n\nexport function defaultCommandHandlers(\n modelRegistry: ModelRegistry = MikanModels.create(),\n): CommandHandler[] {\n return COMMAND_MANIFEST.filter((entry) => !entry.magicWord).map((entry) => {\n const factory = HANDLER_FACTORIES[entry.name];\n if (!factory) {\n throw new Error(\n `Command manifest entry \"${entry.name}\" has no handler factory in commands/registry.ts`,\n );\n }\n return factory(modelRegistry);\n });\n}\n\n/** Run handlers in order, returning true as soon as one accepts the command. */\nexport async function dispatchCommand(\n handlers: readonly CommandHandler[],\n context: CommandContext,\n): Promise<boolean> {\n for (const handler of handlers) {\n if (await handler.tryHandle(context)) return true;\n }\n return false;\n}\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/adapters/commands/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAG9D;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAqE;IAC1F,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,mBAAmB,EAAE;IACtC,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,uBAAuB,EAAE;IAC9C,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,mBAAmB,EAAE;IACtC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,yBAAyB,EAAE;IAC9C,KAAK,EAAE,CAAC,aAAa,EAAE,EAAE,CAAC,IAAI,mBAAmB,CAAC,aAAa,CAAC;IAChE,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,qBAAqB,EAAE;IAC1C,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,iBAAiB,EAAE;CACnC,CAAC;AAEF,MAAM,UAAU,sBAAsB,CACpC,aAAa,GAAkB,WAAW,CAAC,MAAM,EAAE;IAEnD,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACxE,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,2BAA2B,KAAK,CAAC,IAAI,kDAAkD,CACxF,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAmC,EACnC,OAAuB;IAEvB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;IACpD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import { MikanModels } from \"../../harness/index.js\";\nimport { AdminCommandHandler } from \"./admin.js\";\nimport { AutoReplyCommandHandler } from \"./auto-reply.js\";\nimport { LoginCommandHandler } from \"./login.js\";\nimport { COMMAND_MANIFEST } from \"./manifest.js\";\nimport { ModelCommandHandler } from \"./model.js\";\nimport { NewCommandHandler } from \"./new.js\";\nimport { SandboxCommandHandler } from \"./sandbox.js\";\nimport { SessionViewCommandHandler } from \"./session-view.js\";\nimport type { CommandContext, CommandHandler, ModelRegistry } from \"./types.js\";\n\n/**\n * Handler factory per manifest command name. The manifest is the inventory\n * authority; this map only binds each entry to its implementation, and\n * `defaultCommandHandlers` verifies the binding is complete so a manifest\n * entry without a handler fails at construction instead of dispatching into\n * silence. Magic-word entries (routed by conversation intake) are exempt.\n */\nconst HANDLER_FACTORIES: Record<string, (modelRegistry: ModelRegistry) => CommandHandler> = {\n admin: () => new AdminCommandHandler(),\n autoreply: () => new AutoReplyCommandHandler(),\n login: () => new LoginCommandHandler(),\n session: () => new SessionViewCommandHandler(),\n model: (modelRegistry) => new ModelCommandHandler(modelRegistry),\n sandbox: () => new SandboxCommandHandler(),\n new: () => new NewCommandHandler(),\n};\n\nexport function defaultCommandHandlers(\n modelRegistry: ModelRegistry = MikanModels.create(),\n): CommandHandler[] {\n return COMMAND_MANIFEST.filter((entry) => !entry.magicWord).map((entry) => {\n const factory = HANDLER_FACTORIES[entry.name];\n if (!factory) {\n throw new Error(\n `Command manifest entry \"${entry.name}\" has no handler factory in commands/registry.ts`,\n );\n }\n return factory(modelRegistry);\n });\n}\n\n/** Run handlers in order, returning true as soon as one accepts the command. */\nexport async function dispatchCommand(\n handlers: readonly CommandHandler[],\n context: CommandContext,\n): Promise<boolean> {\n for (const handler of handlers) {\n if (await handler.tryHandle(context)) return true;\n }\n return false;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"progressive-renderer.d.ts","sourceRoot":"","sources":["../../src/adapters/progressive-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EAEtB,MAAM,eAAe,CAAC;AAQvB,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAE9D,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CASvE;AAqhBD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,2BAA2B,GAAG;IAChF,SAAS,EAAE,qBAAqB,CAAC;CAClC,CAEA"}
1
+ {"version":3,"file":"progressive-renderer.d.ts","sourceRoot":"","sources":["../../src/adapters/progressive-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EAEtB,MAAM,eAAe,CAAC;AAQvB,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAE9D,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CASvE;AA0hBD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,2BAA2B,GAAG;IAChF,SAAS,EAAE,qBAAqB,CAAC;CAClC,CAEA"}
@@ -264,8 +264,14 @@ class ProgressiveRenderer {
264
264
  if (this.state.lastFlushAt === 0 ||
265
265
  (elapsed >= this.flushIntervalMs && this.state.pendingChars > 0)) {
266
266
  this.state.pendingChars = 0;
267
- this.state.source = await this.renderDelta(this.state.source);
268
- this.state.lastFlushAt = this.now();
267
+ try {
268
+ this.state.source = await this.renderDelta(this.state.source);
269
+ }
270
+ finally {
271
+ // A rejected edit still spent an API call. Pace subsequent deltas
272
+ // from its completion too, retaining source for the next attempt.
273
+ this.state.lastFlushAt = this.now();
274
+ }
269
275
  }
270
276
  }, () => ({ textLength: delta.length, accumulatedLength: this.state.source.length }));
271
277
  }
@@ -1 +1 @@
1
- {"version":3,"file":"progressive-renderer.js","sourceRoot":"","sources":["../../src/adapters/progressive-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ChatToolResult,\n ConversationResponder,\n SubagentProgressSnapshot,\n} from \"../adapter.js\";\nimport * as log from \"../log.js\";\nimport {\n createChatResponseErrorReporter,\n formatToolArgs,\n splitText,\n type ChatResponseErrorOperation,\n} from \"./shared.js\";\nimport type { ProgressiveRendererPlatform } from \"./types.js\";\n\nexport function formatMarkdownToolResult(result: ChatToolResult): string {\n const argsFormatted = formatToolArgs(result.args);\n const duration = (result.durationMs / 1000).toFixed(1);\n let text = `**${result.isError ? \"Error\" : \"Done\"} ${result.toolName}**`;\n if (result.label) text += `: ${result.label}`;\n text += ` (${duration}s)\\n`;\n if (argsFormatted) text += `\\`\\`\\`\\n${argsFormatted}\\n\\`\\`\\`\\n`;\n text += `**Result:**\\n\\`\\`\\`\\n${result.result}\\n\\`\\`\\``;\n return text;\n}\n\ninterface RendererState {\n responseId: string | null;\n source: string;\n working: boolean;\n streamActive: boolean;\n streamUnavailable: boolean;\n streamedSource: string;\n pendingChars: number;\n lastFlushAt: number;\n resetDelta: boolean;\n typingInterval: ReturnType<typeof setInterval> | null;\n typingFailureWarned: boolean;\n extraIds: Array<string | number>;\n /**\n * Messages holding the overflow of a response too long for one message,\n * in order. Reused across redraws — see `postSplit`.\n */\n continuationIds: Array<string | number>;\n}\n\n/**\n * Floor on how often a streaming response redraws.\n *\n * Every platform meters edits per channel — Slack's is the tightest at roughly\n * fifty a minute — and a redraw sends the whole message, so the cost is the\n * number of calls, not their size. One second keeps a long answer inside that\n * budget while still reading as live.\n *\n * This is a floor, not a target: the interval is measured from when the last\n * redraw *finished*, so a platform that slows down under load slows the redraw\n * rate with it instead of queueing work it cannot deliver.\n */\nconst DEFAULT_FLUSH_INTERVAL_MS = 1000;\n\nclass ProgressiveRenderer {\n readonly responder: ConversationResponder;\n private readonly state: RendererState;\n private readonly sanitize: (text: string) => string;\n private readonly reportResponseError;\n private readonly now = Date.now;\n private readonly flushIntervalMs: number;\n private queueTail = Promise.resolve();\n\n constructor(private readonly platform: ProgressiveRendererPlatform) {\n this.state = {\n responseId: platform.initialResponseId ?? null,\n source: \"\",\n working: true,\n streamActive: false,\n streamUnavailable: false,\n streamedSource: \"\",\n pendingChars: 0,\n lastFlushAt: 0,\n resetDelta: false,\n typingInterval: null,\n typingFailureWarned: false,\n extraIds: [],\n continuationIds: [],\n };\n this.sanitize = platform.sanitize ?? ((text: string) => text);\n this.reportResponseError = platform.responseErrorContext\n ? createChatResponseErrorReporter(() => platform.responseErrorContext!(this.state.responseId))\n : undefined;\n this.flushIntervalMs = platform.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;\n this.responder = this.createResponder();\n }\n\n private createResponder(): ConversationResponder {\n return {\n respond: (text) => this.respond(text),\n appendResponseDelta:\n this.platform.supportsDeltas || this.platform.stream\n ? (delta) => this.appendDelta(delta)\n : undefined,\n finishResponse:\n this.platform.supportsDeltas || this.platform.stream\n ? (finalText) => this.finishResponse(finalText)\n : undefined,\n replaceResponse: (text, options) => this.replaceResponse(text, options),\n replaceSubagentProgress: this.platform.formatSubagentProgress\n ? (progress, finalText) => this.replaceSubagentProgress(progress, finalText)\n : undefined,\n respondDiagnostic: (text, options) => this.respondDiagnostic(text, options),\n respondToolResult: (result) => this.respondToolResult(result),\n setTyping: (isTyping) => this.setTyping(isTyping),\n setWorking: (working) => this.setWorking(working),\n uploadFile: (filePath, title) => this.uploadFile(filePath, title),\n ...(this.platform.react ? { react: this.platform.react } : {}),\n deleteResponse: () => this.deleteResponse(),\n };\n }\n\n private stopTyping(): void {\n if (this.state.typingInterval !== null) {\n clearInterval(this.state.typingInterval);\n this.state.typingInterval = null;\n }\n }\n\n private provisional(text: string, working: boolean): string {\n if (this.platform.formatProvisional) return this.platform.formatProvisional(text, working);\n return working && this.platform.workingIndicator ? text + this.platform.workingIndicator : text;\n }\n\n private split(text: string): string[] {\n return splitText(text, this.platform.maxLength, this.platform.formatContinuation);\n }\n\n private async postOrUpdate(text: string): Promise<void> {\n if (this.state.responseId !== null) {\n await this.platform.update(this.state.responseId, text);\n return;\n }\n if (this.platform.typing?.stopOnSend) this.stopTyping();\n this.state.responseId = await this.platform.post(text);\n }\n\n private async postSplit(text: string): Promise<void> {\n const [head = text, ...tail] = this.split(text);\n await this.postOrUpdate(head);\n for (const [index, part] of tail.entries()) {\n const existing = this.state.continuationIds[index];\n if (existing !== undefined) {\n await this.platform.update(String(existing), part);\n continue;\n }\n if (this.platform.typing?.stopOnSend) this.stopTyping();\n const id = await this.platform.postExtra(part, this.state.responseId);\n if (id !== undefined && id !== null) this.state.continuationIds[index] = id;\n }\n }\n\n private async postExtra(text: string): Promise<void> {\n if (this.platform.typing?.stopOnSend) this.stopTyping();\n await this.platform.postExtra(text, this.state.responseId);\n }\n\n private async stopNativeStream(): Promise<void> {\n if (!this.state.streamActive || this.state.responseId === null || !this.platform.stream) return;\n const streamId = this.state.responseId;\n this.state.streamActive = false;\n this.state.streamedSource = \"\";\n await this.platform.stream.stop(streamId);\n }\n\n private async abandonNativeStream(): Promise<void> {\n if (!this.platform.stream || this.state.responseId === null) return;\n const streamId = this.state.responseId;\n this.state.streamActive = false;\n this.state.streamedSource = \"\";\n await this.platform.stream.stop(streamId).catch(() => undefined);\n if (this.state.responseId === streamId) this.state.responseId = null;\n }\n\n private async renderRaw(\n text: string,\n operation: \"render\" | \"replace\",\n options?: { createOverflowLink?: () => string },\n canonicalText = text,\n ): Promise<string> {\n try {\n await this.postSplit(text);\n return canonicalText;\n } catch (err) {\n if (!this.platform.handleTooLong) throw err;\n if (this.platform.isTooLongError && !this.platform.isTooLongError(err)) throw err;\n const fallback = await this.platform.handleTooLong({\n text: canonicalText,\n operation,\n options,\n responseId: this.state.responseId,\n write: (fallbackText) => this.postSplit(fallbackText),\n getResponseId: () => this.state.responseId,\n });\n return fallback.text;\n }\n }\n\n private async renderDelta(text: string): Promise<string> {\n if (this.state.working && !text.trim()) return text;\n const prepared = this.platform.prepareSource?.(text, this.state.working) ?? text;\n const stream = this.platform.stream;\n const display = this.provisional(prepared, this.state.working);\n if (!stream || this.state.streamUnavailable) {\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n if (this.state.responseId !== null && !this.state.streamActive) {\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n if (\n this.state.responseId !== null &&\n this.state.streamActive &&\n !prepared.startsWith(this.state.streamedSource)\n ) {\n await this.abandonNativeStream();\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n\n try {\n if (this.state.responseId !== null) {\n const delta = prepared.slice(this.state.streamedSource.length);\n if (delta && delta.length >= (stream.minDeltaChars ?? 0)) {\n await stream.append(this.state.responseId, delta);\n this.state.streamedSource = prepared;\n }\n return prepared;\n }\n this.state.responseId = await stream.start(prepared);\n this.state.streamActive = true;\n this.state.streamedSource = prepared;\n return prepared;\n } catch (err) {\n this.state.streamUnavailable = true;\n log.logWarning(\n \"Native response streaming unavailable; falling back to message updates\",\n err instanceof Error ? err.message : String(err),\n );\n await this.abandonNativeStream();\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n }\n\n private async renderFinal(text: string): Promise<string> {\n const stream = this.platform.stream;\n if (stream && this.state.streamActive && this.state.responseId !== null) {\n let streamed = false;\n try {\n if (text.startsWith(this.state.streamedSource)) {\n const delta = text.slice(this.state.streamedSource.length);\n if (delta) await stream.append(this.state.responseId, delta);\n await stream.stop(this.state.responseId);\n streamed = true;\n }\n } catch (err) {\n this.state.streamUnavailable = true;\n log.logWarning(\n \"Native response streaming unavailable; falling back to message updates\",\n err instanceof Error ? err.message : String(err),\n );\n }\n this.state.streamActive = false;\n this.state.streamedSource = \"\";\n if (streamed) {\n if (this.platform.needsCanonicalRender?.(text)) await this.renderRaw(text, \"render\");\n return text;\n }\n await this.abandonNativeStream();\n }\n if (this.state.responseId !== null || text) return this.renderRaw(text, \"render\");\n return text;\n }\n\n private async run(\n label: string,\n operation: ChatResponseErrorOperation,\n work: () => Promise<void>,\n extra: () => Record<string, unknown>,\n ): Promise<void> {\n const operationPromise = this.queueTail.then(work);\n const handled = operationPromise.catch(async (err) => {\n const message = err instanceof Error ? err.message : String(err);\n log.logWarning(`${this.platform.label} ${label} error`, message);\n this.reportResponseError?.(err, operation, extra());\n if (this.platform.notifySendFailure) {\n try {\n await this.platform.notifySendFailure(message);\n } catch {\n // A secondary notification must not poison the response queue.\n }\n }\n });\n this.queueTail = handled.catch(() => undefined);\n return handled;\n }\n\n private async appendDelta(delta: string): Promise<void> {\n await this.run(\n \"appendResponseDelta\",\n \"respond\",\n async () => {\n if (!delta) return;\n if (this.state.resetDelta) {\n this.state.source = \"\";\n this.state.pendingChars = 0;\n this.state.resetDelta = false;\n }\n const sanitized = this.sanitize(delta);\n this.state.source += sanitized;\n this.state.pendingChars += sanitized.length;\n const elapsed = this.now() - this.state.lastFlushAt;\n if (\n this.state.lastFlushAt === 0 ||\n (elapsed >= this.flushIntervalMs && this.state.pendingChars > 0)\n ) {\n this.state.pendingChars = 0;\n this.state.source = await this.renderDelta(this.state.source);\n this.state.lastFlushAt = this.now();\n }\n },\n () => ({ textLength: delta.length, accumulatedLength: this.state.source.length }),\n );\n }\n\n private async respond(text: string): Promise<void> {\n await this.run(\n \"respond\",\n \"respond\",\n async () => {\n const sanitized = this.sanitize(text);\n this.state.source = this.state.source ? `${this.state.source}\\n${sanitized}` : sanitized;\n this.state.pendingChars = 0;\n this.state.source = await this.renderDelta(this.state.source);\n if (this.state.responseId !== null && this.platform.logIntermediateResponses) {\n this.platform.logBotResponse?.(text, this.state.responseId);\n }\n },\n () => ({\n phase: this.state.responseId ? \"update\" : \"initial_post\",\n textLength: text.length,\n accumulatedLength: this.state.source.length,\n }),\n );\n }\n\n private async finishResponse(finalText?: string): Promise<void> {\n await this.run(\n \"finishResponse\",\n \"set_working\",\n async () => {\n if (finalText !== undefined) this.state.source = this.sanitize(finalText);\n this.state.resetDelta = false;\n this.state.pendingChars = 0;\n this.stopTyping();\n this.state.working = false;\n this.state.source = await this.renderFinal(this.state.source);\n if (this.state.responseId !== null) {\n this.platform.logBotResponse?.(this.state.source, this.state.responseId);\n }\n await this.platform.onFinish?.(this.state.source, this.state.responseId);\n },\n () => ({ finalTextLength: finalText?.length }),\n );\n }\n\n private async replaceResponse(\n text: string,\n options?: { createOverflowLink?: () => string },\n ): Promise<void> {\n await this.run(\n \"replaceResponse\",\n \"replace_response\",\n async () => {\n this.state.source = this.sanitize(text);\n this.state.pendingChars = 0;\n this.state.resetDelta = true;\n if (this.state.streamActive) await this.stopNativeStream();\n if (this.state.working && !this.state.source.trim()) return;\n const prepared =\n this.platform.prepareSource?.(this.state.source, this.state.working) ?? this.state.source;\n this.state.source = await this.renderRaw(\n this.provisional(prepared, this.state.working),\n \"replace\",\n options,\n prepared,\n );\n },\n () => ({ textLength: text.length, hadExistingResponse: Boolean(this.state.responseId) }),\n );\n }\n\n private async replaceSubagentProgress(\n progress: SubagentProgressSnapshot,\n finalText?: string,\n ): Promise<void> {\n const dashboard = this.platform.formatSubagentProgress!(progress);\n await this.responder.replaceResponse(finalText ? `${dashboard}\\n\\n${finalText}` : dashboard);\n }\n\n private async respondDiagnostic(\n text: string,\n options: { style?: \"muted\" | \"error\" } = {},\n ): Promise<void> {\n await this.run(\n \"respondDiagnostic\",\n \"respond_diagnostic\",\n async () => {\n const ids = this.platform.postDiagnostic\n ? await this.platform.postDiagnostic(text, options, this.state.responseId)\n : await this.postDefaultDiagnostic(text, options);\n this.state.extraIds.push(...ids);\n },\n () => ({ textLength: text.length, style: options.style }),\n );\n }\n\n private async respondToolResult(result: ChatToolResult): Promise<void> {\n await this.responder.respondDiagnostic(this.platform.formatToolResult(result));\n }\n\n private async setTyping(isTyping: boolean): Promise<void> {\n await this.run(\n \"setTyping\",\n \"set_working\",\n async () => {\n if (this.platform.setTyping) {\n await this.platform.setTyping(isTyping, this.state.responseId);\n return;\n }\n const typing = this.platform.typing;\n if (!typing) return;\n const onTypingError = (err: unknown): void => {\n if (this.state.typingFailureWarned) return;\n this.state.typingFailureWarned = true;\n log.logWarning(\n `${this.platform.label} sendTyping failed (further occurrences suppressed for this session)`,\n err instanceof Error ? err.message : String(err),\n );\n };\n if (isTyping && this.state.typingInterval === null) {\n typing.send().catch(onTypingError);\n this.state.typingInterval = setInterval(() => {\n typing.send().catch(onTypingError);\n }, typing.intervalMs);\n } else if (!isTyping) {\n this.stopTyping();\n }\n },\n () => ({ working: isTyping }),\n );\n }\n\n private async setWorking(working: boolean): Promise<void> {\n await this.run(\n \"setWorking\",\n \"set_working\",\n async () => {\n this.state.working = working;\n if (!working) this.stopTyping();\n await this.platform.onWorkingChanged?.(working, this.state.responseId);\n if (\n this.state.responseId === null ||\n (!this.platform.workingIndicator && !this.platform.stream)\n ) {\n return;\n }\n if (working && !this.state.source.trim()) return;\n if (this.state.streamActive && !working) {\n await this.stopNativeStream();\n return;\n }\n if (this.state.responseId !== null) {\n this.state.source = await this.renderRaw(\n this.provisional(this.state.source, working),\n \"render\",\n undefined,\n this.state.source,\n );\n }\n },\n () => ({ working }),\n );\n }\n\n private async uploadFile(filePath: string, title?: string): Promise<void> {\n if (this.platform.uploadFile) {\n await this.platform.uploadFile(filePath, title);\n return;\n }\n const note = this.platform.uploadFallbackNote?.(title ?? filePath);\n if (note === undefined) return;\n await this.run(\n \"uploadFile\",\n \"respond_diagnostic\",\n () => this.postExtra(note),\n () => ({ filePath }),\n );\n }\n\n private async deleteResponse(): Promise<void> {\n await this.run(\n \"deleteResponse\",\n \"respond\",\n async () => {\n this.stopTyping();\n if (this.state.streamActive) await this.stopNativeStream().catch(() => undefined);\n for (const id of [...this.state.extraIds, ...this.state.continuationIds]) {\n try {\n await this.platform.deleteExtra?.(id);\n } catch {\n // Deleting diagnostics is best effort.\n }\n }\n this.state.extraIds = [];\n this.state.continuationIds = [];\n if (this.state.responseId !== null) {\n try {\n await this.platform.delete?.(this.state.responseId);\n } catch {\n // Deleting the main response is best effort.\n }\n }\n this.state.responseId = null;\n this.state.source = \"\";\n this.state.streamUnavailable = false;\n this.state.streamedSource = \"\";\n this.state.streamActive = false;\n this.state.resetDelta = false;\n this.state.working = true;\n },\n () => ({}),\n );\n }\n\n private async postDefaultDiagnostic(\n text: string,\n options: { style?: \"muted\" | \"error\" },\n ): Promise<Array<string | number>> {\n const prefix = options.style === \"error\" ? this.platform.errorPrefix : \"\";\n const ids: Array<string | number> = [];\n for (const part of this.split(this.sanitize(`${prefix}${text}`))) {\n const id = await this.platform.postExtra(part, this.state.responseId);\n if (typeof id === \"string\" || typeof id === \"number\") ids.push(id);\n }\n return ids;\n }\n}\n\nexport function createProgressiveRenderer(platform: ProgressiveRendererPlatform): {\n responder: ConversationResponder;\n} {\n return { responder: new ProgressiveRenderer(platform).responder };\n}\n"]}
1
+ {"version":3,"file":"progressive-renderer.js","sourceRoot":"","sources":["../../src/adapters/progressive-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ChatToolResult,\n ConversationResponder,\n SubagentProgressSnapshot,\n} from \"../adapter.js\";\nimport * as log from \"../log.js\";\nimport {\n createChatResponseErrorReporter,\n formatToolArgs,\n splitText,\n type ChatResponseErrorOperation,\n} from \"./shared.js\";\nimport type { ProgressiveRendererPlatform } from \"./types.js\";\n\nexport function formatMarkdownToolResult(result: ChatToolResult): string {\n const argsFormatted = formatToolArgs(result.args);\n const duration = (result.durationMs / 1000).toFixed(1);\n let text = `**${result.isError ? \"Error\" : \"Done\"} ${result.toolName}**`;\n if (result.label) text += `: ${result.label}`;\n text += ` (${duration}s)\\n`;\n if (argsFormatted) text += `\\`\\`\\`\\n${argsFormatted}\\n\\`\\`\\`\\n`;\n text += `**Result:**\\n\\`\\`\\`\\n${result.result}\\n\\`\\`\\``;\n return text;\n}\n\ninterface RendererState {\n responseId: string | null;\n source: string;\n working: boolean;\n streamActive: boolean;\n streamUnavailable: boolean;\n streamedSource: string;\n pendingChars: number;\n lastFlushAt: number;\n resetDelta: boolean;\n typingInterval: ReturnType<typeof setInterval> | null;\n typingFailureWarned: boolean;\n extraIds: Array<string | number>;\n /**\n * Messages holding the overflow of a response too long for one message,\n * in order. Reused across redraws — see `postSplit`.\n */\n continuationIds: Array<string | number>;\n}\n\n/**\n * Floor on how often a streaming response redraws.\n *\n * Every platform meters edits per channel — Slack's is the tightest at roughly\n * fifty a minute — and a redraw sends the whole message, so the cost is the\n * number of calls, not their size. One second keeps a long answer inside that\n * budget while still reading as live.\n *\n * This is a floor, not a target: the interval is measured from when the last\n * redraw *finished*, so a platform that slows down under load slows the redraw\n * rate with it instead of queueing work it cannot deliver.\n */\nconst DEFAULT_FLUSH_INTERVAL_MS = 1000;\n\nclass ProgressiveRenderer {\n readonly responder: ConversationResponder;\n private readonly state: RendererState;\n private readonly sanitize: (text: string) => string;\n private readonly reportResponseError;\n private readonly now = Date.now;\n private readonly flushIntervalMs: number;\n private queueTail = Promise.resolve();\n\n constructor(private readonly platform: ProgressiveRendererPlatform) {\n this.state = {\n responseId: platform.initialResponseId ?? null,\n source: \"\",\n working: true,\n streamActive: false,\n streamUnavailable: false,\n streamedSource: \"\",\n pendingChars: 0,\n lastFlushAt: 0,\n resetDelta: false,\n typingInterval: null,\n typingFailureWarned: false,\n extraIds: [],\n continuationIds: [],\n };\n this.sanitize = platform.sanitize ?? ((text: string) => text);\n this.reportResponseError = platform.responseErrorContext\n ? createChatResponseErrorReporter(() => platform.responseErrorContext!(this.state.responseId))\n : undefined;\n this.flushIntervalMs = platform.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;\n this.responder = this.createResponder();\n }\n\n private createResponder(): ConversationResponder {\n return {\n respond: (text) => this.respond(text),\n appendResponseDelta:\n this.platform.supportsDeltas || this.platform.stream\n ? (delta) => this.appendDelta(delta)\n : undefined,\n finishResponse:\n this.platform.supportsDeltas || this.platform.stream\n ? (finalText) => this.finishResponse(finalText)\n : undefined,\n replaceResponse: (text, options) => this.replaceResponse(text, options),\n replaceSubagentProgress: this.platform.formatSubagentProgress\n ? (progress, finalText) => this.replaceSubagentProgress(progress, finalText)\n : undefined,\n respondDiagnostic: (text, options) => this.respondDiagnostic(text, options),\n respondToolResult: (result) => this.respondToolResult(result),\n setTyping: (isTyping) => this.setTyping(isTyping),\n setWorking: (working) => this.setWorking(working),\n uploadFile: (filePath, title) => this.uploadFile(filePath, title),\n ...(this.platform.react ? { react: this.platform.react } : {}),\n deleteResponse: () => this.deleteResponse(),\n };\n }\n\n private stopTyping(): void {\n if (this.state.typingInterval !== null) {\n clearInterval(this.state.typingInterval);\n this.state.typingInterval = null;\n }\n }\n\n private provisional(text: string, working: boolean): string {\n if (this.platform.formatProvisional) return this.platform.formatProvisional(text, working);\n return working && this.platform.workingIndicator ? text + this.platform.workingIndicator : text;\n }\n\n private split(text: string): string[] {\n return splitText(text, this.platform.maxLength, this.platform.formatContinuation);\n }\n\n private async postOrUpdate(text: string): Promise<void> {\n if (this.state.responseId !== null) {\n await this.platform.update(this.state.responseId, text);\n return;\n }\n if (this.platform.typing?.stopOnSend) this.stopTyping();\n this.state.responseId = await this.platform.post(text);\n }\n\n private async postSplit(text: string): Promise<void> {\n const [head = text, ...tail] = this.split(text);\n await this.postOrUpdate(head);\n for (const [index, part] of tail.entries()) {\n const existing = this.state.continuationIds[index];\n if (existing !== undefined) {\n await this.platform.update(String(existing), part);\n continue;\n }\n if (this.platform.typing?.stopOnSend) this.stopTyping();\n const id = await this.platform.postExtra(part, this.state.responseId);\n if (id !== undefined && id !== null) this.state.continuationIds[index] = id;\n }\n }\n\n private async postExtra(text: string): Promise<void> {\n if (this.platform.typing?.stopOnSend) this.stopTyping();\n await this.platform.postExtra(text, this.state.responseId);\n }\n\n private async stopNativeStream(): Promise<void> {\n if (!this.state.streamActive || this.state.responseId === null || !this.platform.stream) return;\n const streamId = this.state.responseId;\n this.state.streamActive = false;\n this.state.streamedSource = \"\";\n await this.platform.stream.stop(streamId);\n }\n\n private async abandonNativeStream(): Promise<void> {\n if (!this.platform.stream || this.state.responseId === null) return;\n const streamId = this.state.responseId;\n this.state.streamActive = false;\n this.state.streamedSource = \"\";\n await this.platform.stream.stop(streamId).catch(() => undefined);\n if (this.state.responseId === streamId) this.state.responseId = null;\n }\n\n private async renderRaw(\n text: string,\n operation: \"render\" | \"replace\",\n options?: { createOverflowLink?: () => string },\n canonicalText = text,\n ): Promise<string> {\n try {\n await this.postSplit(text);\n return canonicalText;\n } catch (err) {\n if (!this.platform.handleTooLong) throw err;\n if (this.platform.isTooLongError && !this.platform.isTooLongError(err)) throw err;\n const fallback = await this.platform.handleTooLong({\n text: canonicalText,\n operation,\n options,\n responseId: this.state.responseId,\n write: (fallbackText) => this.postSplit(fallbackText),\n getResponseId: () => this.state.responseId,\n });\n return fallback.text;\n }\n }\n\n private async renderDelta(text: string): Promise<string> {\n if (this.state.working && !text.trim()) return text;\n const prepared = this.platform.prepareSource?.(text, this.state.working) ?? text;\n const stream = this.platform.stream;\n const display = this.provisional(prepared, this.state.working);\n if (!stream || this.state.streamUnavailable) {\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n if (this.state.responseId !== null && !this.state.streamActive) {\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n if (\n this.state.responseId !== null &&\n this.state.streamActive &&\n !prepared.startsWith(this.state.streamedSource)\n ) {\n await this.abandonNativeStream();\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n\n try {\n if (this.state.responseId !== null) {\n const delta = prepared.slice(this.state.streamedSource.length);\n if (delta && delta.length >= (stream.minDeltaChars ?? 0)) {\n await stream.append(this.state.responseId, delta);\n this.state.streamedSource = prepared;\n }\n return prepared;\n }\n this.state.responseId = await stream.start(prepared);\n this.state.streamActive = true;\n this.state.streamedSource = prepared;\n return prepared;\n } catch (err) {\n this.state.streamUnavailable = true;\n log.logWarning(\n \"Native response streaming unavailable; falling back to message updates\",\n err instanceof Error ? err.message : String(err),\n );\n await this.abandonNativeStream();\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n }\n\n private async renderFinal(text: string): Promise<string> {\n const stream = this.platform.stream;\n if (stream && this.state.streamActive && this.state.responseId !== null) {\n let streamed = false;\n try {\n if (text.startsWith(this.state.streamedSource)) {\n const delta = text.slice(this.state.streamedSource.length);\n if (delta) await stream.append(this.state.responseId, delta);\n await stream.stop(this.state.responseId);\n streamed = true;\n }\n } catch (err) {\n this.state.streamUnavailable = true;\n log.logWarning(\n \"Native response streaming unavailable; falling back to message updates\",\n err instanceof Error ? err.message : String(err),\n );\n }\n this.state.streamActive = false;\n this.state.streamedSource = \"\";\n if (streamed) {\n if (this.platform.needsCanonicalRender?.(text)) await this.renderRaw(text, \"render\");\n return text;\n }\n await this.abandonNativeStream();\n }\n if (this.state.responseId !== null || text) return this.renderRaw(text, \"render\");\n return text;\n }\n\n private async run(\n label: string,\n operation: ChatResponseErrorOperation,\n work: () => Promise<void>,\n extra: () => Record<string, unknown>,\n ): Promise<void> {\n const operationPromise = this.queueTail.then(work);\n const handled = operationPromise.catch(async (err) => {\n const message = err instanceof Error ? err.message : String(err);\n log.logWarning(`${this.platform.label} ${label} error`, message);\n this.reportResponseError?.(err, operation, extra());\n if (this.platform.notifySendFailure) {\n try {\n await this.platform.notifySendFailure(message);\n } catch {\n // A secondary notification must not poison the response queue.\n }\n }\n });\n this.queueTail = handled.catch(() => undefined);\n return handled;\n }\n\n private async appendDelta(delta: string): Promise<void> {\n await this.run(\n \"appendResponseDelta\",\n \"respond\",\n async () => {\n if (!delta) return;\n if (this.state.resetDelta) {\n this.state.source = \"\";\n this.state.pendingChars = 0;\n this.state.resetDelta = false;\n }\n const sanitized = this.sanitize(delta);\n this.state.source += sanitized;\n this.state.pendingChars += sanitized.length;\n const elapsed = this.now() - this.state.lastFlushAt;\n if (\n this.state.lastFlushAt === 0 ||\n (elapsed >= this.flushIntervalMs && this.state.pendingChars > 0)\n ) {\n this.state.pendingChars = 0;\n try {\n this.state.source = await this.renderDelta(this.state.source);\n } finally {\n // A rejected edit still spent an API call. Pace subsequent deltas\n // from its completion too, retaining source for the next attempt.\n this.state.lastFlushAt = this.now();\n }\n }\n },\n () => ({ textLength: delta.length, accumulatedLength: this.state.source.length }),\n );\n }\n\n private async respond(text: string): Promise<void> {\n await this.run(\n \"respond\",\n \"respond\",\n async () => {\n const sanitized = this.sanitize(text);\n this.state.source = this.state.source ? `${this.state.source}\\n${sanitized}` : sanitized;\n this.state.pendingChars = 0;\n this.state.source = await this.renderDelta(this.state.source);\n if (this.state.responseId !== null && this.platform.logIntermediateResponses) {\n this.platform.logBotResponse?.(text, this.state.responseId);\n }\n },\n () => ({\n phase: this.state.responseId ? \"update\" : \"initial_post\",\n textLength: text.length,\n accumulatedLength: this.state.source.length,\n }),\n );\n }\n\n private async finishResponse(finalText?: string): Promise<void> {\n await this.run(\n \"finishResponse\",\n \"set_working\",\n async () => {\n if (finalText !== undefined) this.state.source = this.sanitize(finalText);\n this.state.resetDelta = false;\n this.state.pendingChars = 0;\n this.stopTyping();\n this.state.working = false;\n this.state.source = await this.renderFinal(this.state.source);\n if (this.state.responseId !== null) {\n this.platform.logBotResponse?.(this.state.source, this.state.responseId);\n }\n await this.platform.onFinish?.(this.state.source, this.state.responseId);\n },\n () => ({ finalTextLength: finalText?.length }),\n );\n }\n\n private async replaceResponse(\n text: string,\n options?: { createOverflowLink?: () => string },\n ): Promise<void> {\n await this.run(\n \"replaceResponse\",\n \"replace_response\",\n async () => {\n this.state.source = this.sanitize(text);\n this.state.pendingChars = 0;\n this.state.resetDelta = true;\n if (this.state.streamActive) await this.stopNativeStream();\n if (this.state.working && !this.state.source.trim()) return;\n const prepared =\n this.platform.prepareSource?.(this.state.source, this.state.working) ?? this.state.source;\n this.state.source = await this.renderRaw(\n this.provisional(prepared, this.state.working),\n \"replace\",\n options,\n prepared,\n );\n },\n () => ({ textLength: text.length, hadExistingResponse: Boolean(this.state.responseId) }),\n );\n }\n\n private async replaceSubagentProgress(\n progress: SubagentProgressSnapshot,\n finalText?: string,\n ): Promise<void> {\n const dashboard = this.platform.formatSubagentProgress!(progress);\n await this.responder.replaceResponse(finalText ? `${dashboard}\\n\\n${finalText}` : dashboard);\n }\n\n private async respondDiagnostic(\n text: string,\n options: { style?: \"muted\" | \"error\" } = {},\n ): Promise<void> {\n await this.run(\n \"respondDiagnostic\",\n \"respond_diagnostic\",\n async () => {\n const ids = this.platform.postDiagnostic\n ? await this.platform.postDiagnostic(text, options, this.state.responseId)\n : await this.postDefaultDiagnostic(text, options);\n this.state.extraIds.push(...ids);\n },\n () => ({ textLength: text.length, style: options.style }),\n );\n }\n\n private async respondToolResult(result: ChatToolResult): Promise<void> {\n await this.responder.respondDiagnostic(this.platform.formatToolResult(result));\n }\n\n private async setTyping(isTyping: boolean): Promise<void> {\n await this.run(\n \"setTyping\",\n \"set_working\",\n async () => {\n if (this.platform.setTyping) {\n await this.platform.setTyping(isTyping, this.state.responseId);\n return;\n }\n const typing = this.platform.typing;\n if (!typing) return;\n const onTypingError = (err: unknown): void => {\n if (this.state.typingFailureWarned) return;\n this.state.typingFailureWarned = true;\n log.logWarning(\n `${this.platform.label} sendTyping failed (further occurrences suppressed for this session)`,\n err instanceof Error ? err.message : String(err),\n );\n };\n if (isTyping && this.state.typingInterval === null) {\n typing.send().catch(onTypingError);\n this.state.typingInterval = setInterval(() => {\n typing.send().catch(onTypingError);\n }, typing.intervalMs);\n } else if (!isTyping) {\n this.stopTyping();\n }\n },\n () => ({ working: isTyping }),\n );\n }\n\n private async setWorking(working: boolean): Promise<void> {\n await this.run(\n \"setWorking\",\n \"set_working\",\n async () => {\n this.state.working = working;\n if (!working) this.stopTyping();\n await this.platform.onWorkingChanged?.(working, this.state.responseId);\n if (\n this.state.responseId === null ||\n (!this.platform.workingIndicator && !this.platform.stream)\n ) {\n return;\n }\n if (working && !this.state.source.trim()) return;\n if (this.state.streamActive && !working) {\n await this.stopNativeStream();\n return;\n }\n if (this.state.responseId !== null) {\n this.state.source = await this.renderRaw(\n this.provisional(this.state.source, working),\n \"render\",\n undefined,\n this.state.source,\n );\n }\n },\n () => ({ working }),\n );\n }\n\n private async uploadFile(filePath: string, title?: string): Promise<void> {\n if (this.platform.uploadFile) {\n await this.platform.uploadFile(filePath, title);\n return;\n }\n const note = this.platform.uploadFallbackNote?.(title ?? filePath);\n if (note === undefined) return;\n await this.run(\n \"uploadFile\",\n \"respond_diagnostic\",\n () => this.postExtra(note),\n () => ({ filePath }),\n );\n }\n\n private async deleteResponse(): Promise<void> {\n await this.run(\n \"deleteResponse\",\n \"respond\",\n async () => {\n this.stopTyping();\n if (this.state.streamActive) await this.stopNativeStream().catch(() => undefined);\n for (const id of [...this.state.extraIds, ...this.state.continuationIds]) {\n try {\n await this.platform.deleteExtra?.(id);\n } catch {\n // Deleting diagnostics is best effort.\n }\n }\n this.state.extraIds = [];\n this.state.continuationIds = [];\n if (this.state.responseId !== null) {\n try {\n await this.platform.delete?.(this.state.responseId);\n } catch {\n // Deleting the main response is best effort.\n }\n }\n this.state.responseId = null;\n this.state.source = \"\";\n this.state.streamUnavailable = false;\n this.state.streamedSource = \"\";\n this.state.streamActive = false;\n this.state.resetDelta = false;\n this.state.working = true;\n },\n () => ({}),\n );\n }\n\n private async postDefaultDiagnostic(\n text: string,\n options: { style?: \"muted\" | \"error\" },\n ): Promise<Array<string | number>> {\n const prefix = options.style === \"error\" ? this.platform.errorPrefix : \"\";\n const ids: Array<string | number> = [];\n for (const part of this.split(this.sanitize(`${prefix}${text}`))) {\n const id = await this.platform.postExtra(part, this.state.responseId);\n if (typeof id === \"string\" || typeof id === \"number\") ids.push(id);\n }\n return ids;\n }\n}\n\nexport function createProgressiveRenderer(platform: ProgressiveRendererPlatform): {\n responder: ConversationResponder;\n} {\n return { responder: new ProgressiveRenderer(platform).responder };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/bot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/bot.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ import { basename, join } from "node:path";
6
6
  import { createConversationEvent, createConversationMessage, } from "../../adapter.js";
7
7
  import { createOfficeAddress } from "../../office/index.js";
8
8
  import { COMMAND_MANIFEST } from "../commands/manifest.js";
9
- import { resolveConversationSettings } from "../../config.js";
9
+ import { slackConversationAutoReplyEnabled, resolveConversationSettings } from "../../config.js";
10
10
  import * as log from "../../log.js";
11
11
  import { isRecord, readTextFileIfExists } from "../../file-guards.js";
12
12
  import { PRODUCT_NAME, formatForceStopped } from "../../platform-messages.js";
@@ -760,7 +760,10 @@ export class SlackMessagingBot {
760
760
  return processMessageIntake({
761
761
  eventBase: options.event,
762
762
  addressed: options.addressed,
763
- magicWord: { addressed: options.addressed, scopeFallback: "top-level" },
763
+ magicWord: {
764
+ addressed: options.magicWordAddressed ?? options.addressed,
765
+ scopeFallback: "top-level",
766
+ },
764
767
  busyPolicy: "queue",
765
768
  logEntryBase: {},
766
769
  processAttachments: () => options.attachmentsPromise,
@@ -1187,17 +1190,14 @@ export class SlackMessagingBot {
1187
1190
  return;
1188
1191
  }
1189
1192
  const activeSessionKey = slackEvent.sessionKey ?? resolveSlackSessionKey(e.channel, e.thread_ts);
1190
- // Auto-reply top-level channel messages start with no sessionKey because
1191
- // they are only candidates until the policy allows them. Persist the
1192
- // resolved key on the event; otherwise the runtime fallback treats the
1193
- // message ts as a thread session (`channel:ts`) instead of the persistent
1194
- // top-level channel session.
1195
1193
  slackEvent.sessionKey = activeSessionKey;
1194
+ const autoReply = !isDM && slackConversationAutoReplyEnabled(this.workspace.office(slackEvent.address));
1196
1195
  const intake = this.processSlackMessageIntake({
1197
1196
  event: slackEvent,
1198
1197
  attachmentsPromise,
1199
1198
  queueKey: this.resolveQueueKey(e.channel, activeSessionKey),
1200
- addressed: isDM,
1199
+ addressed: isDM || autoReply,
1200
+ magicWordAddressed: isDM,
1201
1201
  });
1202
1202
  ack();
1203
1203
  await intake;