@geminixiang/mikan 1.0.0-beta.37 → 1.0.0-beta.39

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 (201) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +1 -1
  3. package/dist/adapter.js +1 -1
  4. package/dist/adapter.js.map +1 -1
  5. package/dist/adapters/discord/bot.d.ts +3 -6
  6. package/dist/adapters/discord/bot.d.ts.map +1 -1
  7. package/dist/adapters/discord/bot.js +16 -39
  8. package/dist/adapters/discord/bot.js.map +1 -1
  9. package/dist/adapters/github/bot.d.ts +2 -0
  10. package/dist/adapters/github/bot.d.ts.map +1 -1
  11. package/dist/adapters/github/bot.js +15 -11
  12. package/dist/adapters/github/bot.js.map +1 -1
  13. package/dist/adapters/github/github-ops.d.ts +1 -1
  14. package/dist/adapters/github/github-ops.d.ts.map +1 -1
  15. package/dist/adapters/github/github-ops.js +2 -1
  16. package/dist/adapters/github/github-ops.js.map +1 -1
  17. package/dist/adapters/github/repo.d.ts +2 -1
  18. package/dist/adapters/github/repo.d.ts.map +1 -1
  19. package/dist/adapters/github/repo.js +2 -3
  20. package/dist/adapters/github/repo.js.map +1 -1
  21. package/dist/adapters/github/types.d.ts +1 -1
  22. package/dist/adapters/github/types.d.ts.map +1 -1
  23. package/dist/adapters/github/types.js.map +1 -1
  24. package/dist/adapters/intake.js +1 -1
  25. package/dist/adapters/intake.js.map +1 -1
  26. package/dist/adapters/shared.d.ts +17 -5
  27. package/dist/adapters/shared.d.ts.map +1 -1
  28. package/dist/adapters/shared.js +44 -8
  29. package/dist/adapters/shared.js.map +1 -1
  30. package/dist/adapters/slack/blocks.d.ts +14 -0
  31. package/dist/adapters/slack/blocks.d.ts.map +1 -1
  32. package/dist/adapters/slack/blocks.js +34 -0
  33. package/dist/adapters/slack/blocks.js.map +1 -1
  34. package/dist/adapters/slack/bot.d.ts +19 -6
  35. package/dist/adapters/slack/bot.d.ts.map +1 -1
  36. package/dist/adapters/slack/bot.js +88 -21
  37. package/dist/adapters/slack/bot.js.map +1 -1
  38. package/dist/adapters/slack/types.d.ts +1 -1
  39. package/dist/adapters/slack/types.js.map +1 -1
  40. package/dist/adapters/telegram/bot.d.ts +5 -6
  41. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  42. package/dist/adapters/telegram/bot.js +29 -51
  43. package/dist/adapters/telegram/bot.js.map +1 -1
  44. package/dist/adapters/types.d.ts +19 -1
  45. package/dist/adapters/types.d.ts.map +1 -1
  46. package/dist/adapters/types.js.map +1 -1
  47. package/dist/agent.d.ts +0 -1
  48. package/dist/agent.d.ts.map +1 -1
  49. package/dist/agent.js +79 -101
  50. package/dist/agent.js.map +1 -1
  51. package/dist/cli/ext-dev.d.ts.map +1 -1
  52. package/dist/cli/ext-dev.js +8 -8
  53. package/dist/cli/ext-dev.js.map +1 -1
  54. package/dist/cli/ext.js +3 -3
  55. package/dist/cli/ext.js.map +1 -1
  56. package/dist/cli/office.js +2 -2
  57. package/dist/cli/office.js.map +1 -1
  58. package/dist/commands/auto-reply.d.ts.map +1 -1
  59. package/dist/commands/auto-reply.js +1 -2
  60. package/dist/commands/auto-reply.js.map +1 -1
  61. package/dist/commands/login.js +1 -1
  62. package/dist/commands/login.js.map +1 -1
  63. package/dist/commands/manifest.d.ts.map +1 -1
  64. package/dist/commands/manifest.js +3 -1
  65. package/dist/commands/manifest.js.map +1 -1
  66. package/dist/commands/model.d.ts.map +1 -1
  67. package/dist/commands/model.js +3 -7
  68. package/dist/commands/model.js.map +1 -1
  69. package/dist/commands/sandbox.d.ts.map +1 -1
  70. package/dist/commands/sandbox.js +7 -7
  71. package/dist/commands/sandbox.js.map +1 -1
  72. package/dist/commands/session-view.d.ts.map +1 -1
  73. package/dist/commands/session-view.js +1 -2
  74. package/dist/commands/session-view.js.map +1 -1
  75. package/dist/commands/types.d.ts +2 -1
  76. package/dist/commands/types.d.ts.map +1 -1
  77. package/dist/commands/types.js.map +1 -1
  78. package/dist/config.d.ts +10 -18
  79. package/dist/config.d.ts.map +1 -1
  80. package/dist/config.js +16 -15
  81. package/dist/config.js.map +1 -1
  82. package/dist/execution-resolver.d.ts +4 -6
  83. package/dist/execution-resolver.d.ts.map +1 -1
  84. package/dist/execution-resolver.js +10 -19
  85. package/dist/execution-resolver.js.map +1 -1
  86. package/dist/harness/extensions/loader.js +1 -1
  87. package/dist/harness/extensions/loader.js.map +1 -1
  88. package/dist/harness/skills.d.ts +8 -0
  89. package/dist/harness/skills.d.ts.map +1 -1
  90. package/dist/harness/skills.js +46 -4
  91. package/dist/harness/skills.js.map +1 -1
  92. package/dist/harness/types.d.ts +2 -0
  93. package/dist/harness/types.d.ts.map +1 -1
  94. package/dist/harness/types.js.map +1 -1
  95. package/dist/index.d.ts +2 -0
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +1 -0
  98. package/dist/index.js.map +1 -1
  99. package/dist/main.js +16 -16
  100. package/dist/main.js.map +1 -1
  101. package/dist/{office-address.d.ts → office/address.d.ts} +13 -14
  102. package/dist/office/address.d.ts.map +1 -0
  103. package/dist/{office-address.js → office/address.js} +13 -18
  104. package/dist/office/address.js.map +1 -0
  105. package/dist/office/index.d.ts +11 -0
  106. package/dist/office/index.d.ts.map +1 -0
  107. package/dist/office/index.js +11 -0
  108. package/dist/office/index.js.map +1 -0
  109. package/dist/office/layout.d.ts +20 -0
  110. package/dist/office/layout.d.ts.map +1 -0
  111. package/dist/office/layout.js +88 -0
  112. package/dist/office/layout.js.map +1 -0
  113. package/dist/{office-migration.d.ts → office/migration.d.ts} +3 -3
  114. package/dist/office/migration.d.ts.map +1 -0
  115. package/dist/{office-migration.js → office/migration.js} +8 -12
  116. package/dist/office/migration.js.map +1 -0
  117. package/dist/{office-registry.d.ts → office/registry.d.ts} +18 -24
  118. package/dist/office/registry.d.ts.map +1 -0
  119. package/dist/{office-registry.js → office/registry.js} +22 -83
  120. package/dist/office/registry.js.map +1 -0
  121. package/dist/office/types.d.ts +71 -0
  122. package/dist/office/types.d.ts.map +1 -0
  123. package/dist/office/types.js +2 -0
  124. package/dist/office/types.js.map +1 -0
  125. package/dist/packages/admin.js +5 -5
  126. package/dist/packages/admin.js.map +1 -1
  127. package/dist/packages/inspect.d.ts.map +1 -1
  128. package/dist/packages/inspect.js +3 -8
  129. package/dist/packages/inspect.js.map +1 -1
  130. package/dist/packages/materialize.js +1 -1
  131. package/dist/packages/materialize.js.map +1 -1
  132. package/dist/packages/resolve.js +5 -8
  133. package/dist/packages/resolve.js.map +1 -1
  134. package/dist/packages/types.d.ts +2 -5
  135. package/dist/packages/types.d.ts.map +1 -1
  136. package/dist/packages/types.js.map +1 -1
  137. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  138. package/dist/runtime/conversation-runtime.js +13 -15
  139. package/dist/runtime/conversation-runtime.js.map +1 -1
  140. package/dist/runtime/session-lifecycle.js +1 -1
  141. package/dist/runtime/session-lifecycle.js.map +1 -1
  142. package/dist/runtime/types.d.ts +3 -2
  143. package/dist/runtime/types.d.ts.map +1 -1
  144. package/dist/runtime/types.js.map +1 -1
  145. package/dist/sandbox/identity.js +1 -1
  146. package/dist/sandbox/identity.js.map +1 -1
  147. package/dist/settings-mutation.d.ts +3 -2
  148. package/dist/settings-mutation.d.ts.map +1 -1
  149. package/dist/settings-mutation.js +6 -7
  150. package/dist/settings-mutation.js.map +1 -1
  151. package/dist/tools/generate-image.d.ts +8 -2
  152. package/dist/tools/generate-image.d.ts.map +1 -1
  153. package/dist/tools/generate-image.js +5 -3
  154. package/dist/tools/generate-image.js.map +1 -1
  155. package/dist/tools/index.d.ts +5 -0
  156. package/dist/tools/index.d.ts.map +1 -1
  157. package/dist/tools/index.js +3 -5
  158. package/dist/tools/index.js.map +1 -1
  159. package/dist/trigger.d.ts +1 -1
  160. package/dist/trigger.d.ts.map +1 -1
  161. package/dist/trigger.js +5 -10
  162. package/dist/trigger.js.map +1 -1
  163. package/dist/types.d.ts +3 -22
  164. package/dist/types.d.ts.map +1 -1
  165. package/dist/types.js.map +1 -1
  166. package/dist/vault/index.js +1 -1
  167. package/dist/vault/index.js.map +1 -1
  168. package/dist/vault/injection.d.ts +3 -1
  169. package/dist/vault/injection.d.ts.map +1 -1
  170. package/dist/vault/injection.js +2 -2
  171. package/dist/vault/injection.js.map +1 -1
  172. package/dist/web/admin/portal.d.ts.map +1 -1
  173. package/dist/web/admin/portal.js +67 -80
  174. package/dist/web/admin/portal.js.map +1 -1
  175. package/dist/web/admin/types.d.ts +2 -1
  176. package/dist/web/admin/types.d.ts.map +1 -1
  177. package/dist/web/admin/types.js.map +1 -1
  178. package/dist/web/server.d.ts +1 -1
  179. package/dist/web/server.d.ts.map +1 -1
  180. package/dist/web/server.js +3 -3
  181. package/dist/web/server.js.map +1 -1
  182. package/dist/web/session-view/portal.js +1 -1
  183. package/dist/web/session-view/portal.js.map +1 -1
  184. package/dist/workspace-projection/index.d.ts +2 -4
  185. package/dist/workspace-projection/index.d.ts.map +1 -1
  186. package/dist/workspace-projection/index.js +21 -56
  187. package/dist/workspace-projection/index.js.map +1 -1
  188. package/dist/workspace-projection/types.d.ts +0 -2
  189. package/dist/workspace-projection/types.d.ts.map +1 -1
  190. package/dist/workspace-projection/types.js.map +1 -1
  191. package/package.json +41 -16
  192. package/dist/office-address.d.ts.map +0 -1
  193. package/dist/office-address.js.map +0 -1
  194. package/dist/office-migration.d.ts.map +0 -1
  195. package/dist/office-migration.js.map +0 -1
  196. package/dist/office-registry.d.ts.map +0 -1
  197. package/dist/office-registry.js.map +0 -1
  198. package/dist/store.d.ts +0 -51
  199. package/dist/store.d.ts.map +0 -1
  200. package/dist/store.js +0 -185
  201. package/dist/store.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/adapters/github/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/adapters/github/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/adapters/github/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ConversationEvent } from \"../../adapter.js\";\nimport type { GcpTokenProvider } from \"./gcp-auth.js\";\n\nexport interface GithubEvent extends ConversationEvent {\n type: \"message\" | \"issue\";\n userName?: string;\n}\n\nexport interface GithubBotConfig {\n appId: string;\n /** PEM-encoded GitHub App private key. */\n privateKey: string;\n installationId: string;\n /** `owner/repo` entries to watch; empty = all installation repositories. */\n repos: string[];\n pollIntervalMs: number;\n workingDir: string;\n /**\n * Where the poll watermark state (baseline + seen ids) is persisted. Lives\n * under the host-only state dir: the workspace dir can be mounted into\n * sandboxes, and sandboxed code must not be able to clear dedup state and\n * re-trigger runs.\n */\n syncStatePath: string;\n /**\n * Present when the host has GCP credentials (GOOGLE_APPLICATION_CREDENTIALS):\n * lets github_checks fetch Cloud Build logs. Credentials never enter the\n * sandbox; absent, external-CI checks degrade to guidance text.\n */\n cloudBuild?: {\n tokenProvider: GcpTokenProvider;\n /** Project used when a check's details_url does not name one. */\n projectFallback?: string;\n };\n}\n\nexport interface GcpTokenProviderOptions {\n /** Path to the ADC JSON (usually $GOOGLE_APPLICATION_CREDENTIALS). */\n credentialsPath: string;\n fetchImpl?: typeof fetch;\n}\n\nexport interface CloudBuildLogOptions {\n tokenProvider: GcpTokenProvider;\n project: string;\n buildId: string;\n fetchImpl?: typeof fetch;\n}\n\n/** Persisted per-repo poll watermark (DESIGN.md § Event source). */\ninterface GithubRepoSyncState {\n /** Comments/issues created before this ISO instant never trigger. */\n baseline: string;\n /** Newest updated_at seen; polls fetch from (cursor - overlap). */\n cursor: string;\n seenComments: number[];\n seenIssues: number[];\n /** Optional so state files written before review-comment polling still load. */\n seenReviewComments?: number[];\n}\n\nexport interface GithubSyncState {\n repos: Record<string, GithubRepoSyncState>;\n}\n\nexport interface GithubRepoRef {\n owner: string;\n repo: string;\n}\n\nexport interface GithubConversationRef extends GithubRepoRef {\n number: number;\n}\n\n// ── GitHub REST payload shapes (only the fields mikan reads) ─────────────────\n\ninterface GithubUser {\n login: string;\n type: string;\n}\n\nexport interface GithubIssue {\n id: number;\n number: number;\n title: string;\n body: string | null;\n user: GithubUser;\n created_at: string;\n updated_at: string;\n pull_request?: object;\n /** open | closed */\n state?: string;\n labels?: { name: string }[];\n assignees?: { login: string }[];\n}\n\nexport interface GithubIssueComment {\n id: number;\n body: string;\n user: GithubUser;\n created_at: string;\n updated_at: string;\n /** API URL of the parent issue, e.g. …/repos/o/r/issues/42 */\n issue_url: string;\n}\n\n/** An inline PR review comment (a comment on a diff line). */\nexport interface GithubReviewComment {\n id: number;\n body: string;\n user: GithubUser;\n created_at: string;\n updated_at: string;\n /** API URL of the parent PR, e.g. …/repos/o/r/pulls/42 */\n pull_request_url: string;\n /** File the comment is anchored to. */\n path: string;\n /** Line in the diff's right side; null when the anchor is outdated. */\n line: number | null;\n /** The diff excerpt the comment is anchored to. */\n diff_hunk: string;\n /** Set on replies: the id of the thread's root comment. */\n in_reply_to_id?: number;\n}\n\nexport interface GithubRepository {\n name: string;\n owner: GithubUser;\n}\n\nexport interface GithubRepositoryDetails {\n default_branch: string;\n}\n\nexport interface GithubCollaboratorPermission {\n /** Legacy field: admin | write | read | none (maintain→write, triage→read). */\n permission: string;\n /** Granular assigned role (admin/maintain/write/triage/read or a custom role). */\n role_name?: string;\n}\n\nexport interface GithubPullRequest {\n number: number;\n html_url: string;\n /** head.repo is null when the fork a PR came from was deleted. */\n head?: { ref: string; sha: string; repo?: { full_name?: string } | null };\n base?: { ref: string };\n title?: string;\n body?: string | null;\n /** open | closed */\n state?: string;\n draft?: boolean;\n merged?: boolean;\n mergeable_state?: string;\n changed_files?: number;\n additions?: number;\n deletions?: number;\n user?: GithubUser;\n}\n\n/** One row of GET /pulls/{n}/files. */\nexport interface GithubPullRequestFile {\n filename: string;\n /** added | removed | modified | renamed | … */\n status: string;\n additions: number;\n deletions: number;\n}\n\n/** One submitted review of GET /pulls/{n}/reviews. */\nexport interface GithubPullRequestReview {\n id: number;\n user: GithubUser;\n body: string | null;\n /** APPROVED | CHANGES_REQUESTED | COMMENTED | DISMISSED | PENDING */\n state: string;\n submitted_at?: string;\n}\n\nexport interface GithubCheckRun {\n /** Check-run id; for GitHub Actions this doubles as the job id (log fetch). */\n id: number;\n name: string;\n /** queued | in_progress | completed */\n status: string;\n /** success | failure | neutral | cancelled | skipped | timed_out | action_required | null while running */\n conclusion: string | null;\n html_url: string | null;\n /** The app that reported the check (github-actions vs external CI). */\n app?: { slug?: string } | null;\n /** Whatever the reporting app posted about the run. */\n output?: { title?: string | null; summary?: string | null } | null;\n /** The reporting app's own id for the run; Cloud Build puts the build UUID here. */\n external_id?: string | null;\n /** The reporting app's own results page; Cloud Build encodes the GCP project here. */\n details_url?: string | null;\n}\n\n/** Permission subset requestable on a scoped installation token. */\nexport type GithubTokenPermissions = Partial<\n Record<\"contents\" | \"pull_requests\" | \"issues\", \"read\" | \"write\">\n>;\n\nexport type GithubReactionContent =\n | \"+1\"\n | \"-1\"\n | \"laugh\"\n | \"confused\"\n | \"heart\"\n | \"hooray\"\n | \"rocket\"\n | \"eyes\";\n\nexport interface CloneRepoOptions {\n /** HTTPS remote, e.g. https://github.com/owner/repo.git (no credentials). */\n url: string;\n /** Destination directory (the conversation dir's `repo/`). */\n dir: string;\n /** Ephemeral scoped installation token; used per-invocation, never stored. */\n token: string;\n botLogin: string;\n botEmail: string;\n /** When the conversation is a PR: fetch and check out its head. */\n prNumber?: number;\n /**\n * The PR's head branch name when it lives in this repo (not a fork): the\n * checkout is named after it so committing there + github_pr updates the\n * PR in place. Absent (fork/unknown), the checkout falls back to pr-<n>.\n */\n prHeadBranch?: string;\n}\n\nexport interface PushBranchOptions {\n dir: string;\n branch: string;\n token: string;\n}\n\nexport interface SyncRepoOptions {\n dir: string;\n /** Ephemeral contents:read token; used per-invocation, never stored. */\n token: string;\n /** Explicit branch to fetch; wins over prNumber/defaultBranch. */\n branch?: string;\n /** PR conversations: fetch pull/<n>/head into the local PR checkout. */\n prNumber?: number;\n /** Same-repo PR head name; the local checkout target. Fallback: pr-<n>. */\n prHeadBranch?: string;\n /** Fallback target when neither branch nor prNumber applies. */\n defaultBranch?: string;\n}\n\nexport interface SyncRepoResult {\n /** Local branch the fetch targets (the PR head name, pr-<n>, or the branch). */\n target: string;\n fetchedSha: string;\n /** True when the checkout was moved to the fetched head. */\n updatedCheckout: boolean;\n /** Working tree had uncommitted changes (checkout left alone). */\n dirty: boolean;\n currentBranch: string;\n /** Bot-committed (agent-made) commits on the target that origin lacks. */\n localCommits: number;\n}\n\nexport interface GithubClientOptions {\n appId: string;\n privateKey: string;\n installationId: string;\n /** Override the API root for tests; defaults to https://api.github.com */\n baseUrl?: string;\n fetchImpl?: typeof fetch;\n}\n\n// ── Host-side tool contracts (capability pack, not messaging core) ───────────\n\n/** Arguments for the host-side `github_pr` tool. */\nexport interface GithubPrRequest {\n /** Local branch in the conversation's ./repo clone; must match pi/<name>. */\n branch: string;\n title: string;\n body?: string;\n /** Target branch; defaults to the repository's default branch. */\n base?: string;\n draft?: boolean;\n}\n\nexport interface GithubPrResult {\n number: number;\n url: string;\n /** True when the branch already had an open PR that this push updated. */\n updatedExisting?: boolean;\n}\n\n/** Normalized check-run row for the host-side `github_checks` tool. */\nexport interface GithubCheckSummary {\n /** Check-run id; for GitHub Actions checks it is also the job id for log fetch. */\n id: number;\n name: string;\n /** queued | in_progress | completed */\n status: string;\n /** success | failure | … ; null while the run is still in progress */\n conclusion: string | null;\n url: string | null;\n /** Slug of the reporting app; \"github-actions\" checks have fetchable logs. */\n appSlug: string | null;\n /** The reporting app's own summary of the run, when it posted one. */\n outputSummary: string | null;\n /** The reporting app's run id (Cloud Build: the build UUID). */\n externalId: string | null;\n /** True when this run's log is fetchable via build_id (Cloud Build + GCP creds). */\n buildLogAvailable?: boolean;\n}\n\nexport interface GithubChecksFns {\n getChecks: (branch?: string) => Promise<GithubCheckSummary[]>;\n getJobLog: (jobId: number) => Promise<string>;\n getBuildLog: (buildId: string) => Promise<string>;\n}\n\n/** Arguments for the host-side `github_read` tool. */\nexport interface GithubReadRequest {\n action: \"pr\" | \"pr_files\" | \"pr_reviews\" | \"issue\" | \"comments\" | \"list\";\n /** Issue/PR number; defaults to the conversation's own. */\n number?: number;\n /** list only: open | closed | all (default open). */\n state?: string;\n /** list only: comma-separated label names. */\n labels?: string;\n /** list only: filter by author login. */\n creator?: string;\n}\n\n/** Typed payload of one `github_read` action; the tool renders it. */\nexport type GithubReadResult =\n | { kind: \"pr\"; pr: GithubPullRequest }\n | { kind: \"pr_files\"; files: GithubPullRequestFile[] }\n | { kind: \"pr_reviews\"; reviews: GithubPullRequestReview[]; threads: GithubReviewComment[] }\n | { kind: \"issue\"; issue: GithubIssue }\n | { kind: \"comments\"; comments: GithubIssueComment[] }\n | { kind: \"list\"; issues: GithubIssue[] };\n\n/** Arguments for the host-side `github_issue` tool. Deliberately a closed\n * action set: lock/delete/transfer are not offered at all. */\nexport interface GithubIssueRequest {\n action: \"add_labels\" | \"remove_label\" | \"add_assignees\" | \"remove_assignees\" | \"close\" | \"reopen\";\n /** Issue/PR number; defaults to the conversation's own (triage may target others). */\n number?: number;\n /** add_labels */\n labels?: string[];\n /** remove_label */\n label?: string;\n /** add_assignees / remove_assignees */\n assignees?: string[];\n /** close */\n state_reason?: \"completed\" | \"not_planned\";\n}\n\n/**\n * Host-side GitHub operations for github_* tools. Wired in main.ts over the\n * GitHub bot; tokens stay host-side. Consumed by `createGithubToolPack`.\n */\nexport type GithubSyncFn = (branch?: string) => Promise<string>;\n\nexport type GithubReviewReplyFn = (commentId: number, body: string) => Promise<{ url: string }>;\n\nexport type GithubReadFn = (request: GithubReadRequest) => Promise<GithubReadResult>;\n\nexport type GithubIssueFn = (request: GithubIssueRequest) => Promise<string>;\n\nexport interface PlatformGithubOps {\n /** Push a prepared pi/* branch and open (or update) a pull request. */\n pushAndCreatePr(conversationId: string, request: GithubPrRequest): Promise<GithubPrResult>;\n /** CI check runs for a branch, or for the conversation's PR head when omitted. */\n getChecks(conversationId: string, branch?: string): Promise<GithubCheckSummary[]>;\n /** Log text of one CI job (an Actions check-run id), tail-truncated. */\n getJobLog(conversationId: string, jobId: number): Promise<string>;\n /** Log text of one Cloud Build run (a [build …] uuid), tail-truncated. */\n getBuildLog(conversationId: string, buildId: string): Promise<string>;\n /** Reply inside one inline review thread of the conversation's PR. */\n replyToReviewThread(\n conversationId: string,\n commentId: number,\n body: string,\n ): Promise<{ url: string }>;\n /** Refresh the conversation's ./repo clone; returns a human-readable report. */\n syncRepo(conversationId: string, branch?: string): Promise<string>;\n /** Read PR/issue metadata the clone cannot provide; same repo only. */\n readGithub(conversationId: string, request: GithubReadRequest): Promise<GithubReadResult>;\n /** Label/assignee/state management on this repo's issues; returns a report. */\n manageIssue(conversationId: string, request: GithubIssueRequest): Promise<string>;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/adapters/github/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ConversationEvent } from \"../../adapter.js\";\nimport type { GcpTokenProvider } from \"./gcp-auth.js\";\n\nexport interface GithubEvent extends ConversationEvent {\n type: \"message\" | \"issue\";\n userName?: string;\n}\n\nexport interface GithubBotConfig {\n appId: string;\n /** PEM-encoded GitHub App private key. */\n privateKey: string;\n installationId: string;\n /** `owner/repo` entries to watch; empty = all installation repositories. */\n repos: string[];\n pollIntervalMs: number;\n workspace: import(\"../../office/types.js\").Workspace;\n /**\n * Where the poll watermark state (baseline + seen ids) is persisted. Lives\n * under the host-only state dir: the workspace dir can be mounted into\n * sandboxes, and sandboxed code must not be able to clear dedup state and\n * re-trigger runs.\n */\n syncStatePath: string;\n /**\n * Present when the host has GCP credentials (GOOGLE_APPLICATION_CREDENTIALS):\n * lets github_checks fetch Cloud Build logs. Credentials never enter the\n * sandbox; absent, external-CI checks degrade to guidance text.\n */\n cloudBuild?: {\n tokenProvider: GcpTokenProvider;\n /** Project used when a check's details_url does not name one. */\n projectFallback?: string;\n };\n}\n\nexport interface GcpTokenProviderOptions {\n /** Path to the ADC JSON (usually $GOOGLE_APPLICATION_CREDENTIALS). */\n credentialsPath: string;\n fetchImpl?: typeof fetch;\n}\n\nexport interface CloudBuildLogOptions {\n tokenProvider: GcpTokenProvider;\n project: string;\n buildId: string;\n fetchImpl?: typeof fetch;\n}\n\n/** Persisted per-repo poll watermark (DESIGN.md § Event source). */\ninterface GithubRepoSyncState {\n /** Comments/issues created before this ISO instant never trigger. */\n baseline: string;\n /** Newest updated_at seen; polls fetch from (cursor - overlap). */\n cursor: string;\n seenComments: number[];\n seenIssues: number[];\n /** Optional so state files written before review-comment polling still load. */\n seenReviewComments?: number[];\n}\n\nexport interface GithubSyncState {\n repos: Record<string, GithubRepoSyncState>;\n}\n\nexport interface GithubRepoRef {\n owner: string;\n repo: string;\n}\n\nexport interface GithubConversationRef extends GithubRepoRef {\n number: number;\n}\n\n// ── GitHub REST payload shapes (only the fields mikan reads) ─────────────────\n\ninterface GithubUser {\n login: string;\n type: string;\n}\n\nexport interface GithubIssue {\n id: number;\n number: number;\n title: string;\n body: string | null;\n user: GithubUser;\n created_at: string;\n updated_at: string;\n pull_request?: object;\n /** open | closed */\n state?: string;\n labels?: { name: string }[];\n assignees?: { login: string }[];\n}\n\nexport interface GithubIssueComment {\n id: number;\n body: string;\n user: GithubUser;\n created_at: string;\n updated_at: string;\n /** API URL of the parent issue, e.g. …/repos/o/r/issues/42 */\n issue_url: string;\n}\n\n/** An inline PR review comment (a comment on a diff line). */\nexport interface GithubReviewComment {\n id: number;\n body: string;\n user: GithubUser;\n created_at: string;\n updated_at: string;\n /** API URL of the parent PR, e.g. …/repos/o/r/pulls/42 */\n pull_request_url: string;\n /** File the comment is anchored to. */\n path: string;\n /** Line in the diff's right side; null when the anchor is outdated. */\n line: number | null;\n /** The diff excerpt the comment is anchored to. */\n diff_hunk: string;\n /** Set on replies: the id of the thread's root comment. */\n in_reply_to_id?: number;\n}\n\nexport interface GithubRepository {\n name: string;\n owner: GithubUser;\n}\n\nexport interface GithubRepositoryDetails {\n default_branch: string;\n}\n\nexport interface GithubCollaboratorPermission {\n /** Legacy field: admin | write | read | none (maintain→write, triage→read). */\n permission: string;\n /** Granular assigned role (admin/maintain/write/triage/read or a custom role). */\n role_name?: string;\n}\n\nexport interface GithubPullRequest {\n number: number;\n html_url: string;\n /** head.repo is null when the fork a PR came from was deleted. */\n head?: { ref: string; sha: string; repo?: { full_name?: string } | null };\n base?: { ref: string };\n title?: string;\n body?: string | null;\n /** open | closed */\n state?: string;\n draft?: boolean;\n merged?: boolean;\n mergeable_state?: string;\n changed_files?: number;\n additions?: number;\n deletions?: number;\n user?: GithubUser;\n}\n\n/** One row of GET /pulls/{n}/files. */\nexport interface GithubPullRequestFile {\n filename: string;\n /** added | removed | modified | renamed | … */\n status: string;\n additions: number;\n deletions: number;\n}\n\n/** One submitted review of GET /pulls/{n}/reviews. */\nexport interface GithubPullRequestReview {\n id: number;\n user: GithubUser;\n body: string | null;\n /** APPROVED | CHANGES_REQUESTED | COMMENTED | DISMISSED | PENDING */\n state: string;\n submitted_at?: string;\n}\n\nexport interface GithubCheckRun {\n /** Check-run id; for GitHub Actions this doubles as the job id (log fetch). */\n id: number;\n name: string;\n /** queued | in_progress | completed */\n status: string;\n /** success | failure | neutral | cancelled | skipped | timed_out | action_required | null while running */\n conclusion: string | null;\n html_url: string | null;\n /** The app that reported the check (github-actions vs external CI). */\n app?: { slug?: string } | null;\n /** Whatever the reporting app posted about the run. */\n output?: { title?: string | null; summary?: string | null } | null;\n /** The reporting app's own id for the run; Cloud Build puts the build UUID here. */\n external_id?: string | null;\n /** The reporting app's own results page; Cloud Build encodes the GCP project here. */\n details_url?: string | null;\n}\n\n/** Permission subset requestable on a scoped installation token. */\nexport type GithubTokenPermissions = Partial<\n Record<\"contents\" | \"pull_requests\" | \"issues\", \"read\" | \"write\">\n>;\n\nexport type GithubReactionContent =\n | \"+1\"\n | \"-1\"\n | \"laugh\"\n | \"confused\"\n | \"heart\"\n | \"hooray\"\n | \"rocket\"\n | \"eyes\";\n\nexport interface CloneRepoOptions {\n /** HTTPS remote, e.g. https://github.com/owner/repo.git (no credentials). */\n url: string;\n /** Destination directory (the conversation dir's `repo/`). */\n dir: string;\n /** Ephemeral scoped installation token; used per-invocation, never stored. */\n token: string;\n botLogin: string;\n botEmail: string;\n /** When the conversation is a PR: fetch and check out its head. */\n prNumber?: number;\n /**\n * The PR's head branch name when it lives in this repo (not a fork): the\n * checkout is named after it so committing there + github_pr updates the\n * PR in place. Absent (fork/unknown), the checkout falls back to pr-<n>.\n */\n prHeadBranch?: string;\n}\n\nexport interface PushBranchOptions {\n dir: string;\n branch: string;\n token: string;\n}\n\nexport interface SyncRepoOptions {\n dir: string;\n /** Ephemeral contents:read token; used per-invocation, never stored. */\n token: string;\n /** Explicit branch to fetch; wins over prNumber/defaultBranch. */\n branch?: string;\n /** PR conversations: fetch pull/<n>/head into the local PR checkout. */\n prNumber?: number;\n /** Same-repo PR head name; the local checkout target. Fallback: pr-<n>. */\n prHeadBranch?: string;\n /** Fallback target when neither branch nor prNumber applies. */\n defaultBranch?: string;\n}\n\nexport interface SyncRepoResult {\n /** Local branch the fetch targets (the PR head name, pr-<n>, or the branch). */\n target: string;\n fetchedSha: string;\n /** True when the checkout was moved to the fetched head. */\n updatedCheckout: boolean;\n /** Working tree had uncommitted changes (checkout left alone). */\n dirty: boolean;\n currentBranch: string;\n /** Bot-committed (agent-made) commits on the target that origin lacks. */\n localCommits: number;\n}\n\nexport interface GithubClientOptions {\n appId: string;\n privateKey: string;\n installationId: string;\n /** Override the API root for tests; defaults to https://api.github.com */\n baseUrl?: string;\n fetchImpl?: typeof fetch;\n}\n\n// ── Host-side tool contracts (capability pack, not messaging core) ───────────\n\n/** Arguments for the host-side `github_pr` tool. */\nexport interface GithubPrRequest {\n /** Local branch in the conversation's ./repo clone; must match pi/<name>. */\n branch: string;\n title: string;\n body?: string;\n /** Target branch; defaults to the repository's default branch. */\n base?: string;\n draft?: boolean;\n}\n\nexport interface GithubPrResult {\n number: number;\n url: string;\n /** True when the branch already had an open PR that this push updated. */\n updatedExisting?: boolean;\n}\n\n/** Normalized check-run row for the host-side `github_checks` tool. */\nexport interface GithubCheckSummary {\n /** Check-run id; for GitHub Actions checks it is also the job id for log fetch. */\n id: number;\n name: string;\n /** queued | in_progress | completed */\n status: string;\n /** success | failure | … ; null while the run is still in progress */\n conclusion: string | null;\n url: string | null;\n /** Slug of the reporting app; \"github-actions\" checks have fetchable logs. */\n appSlug: string | null;\n /** The reporting app's own summary of the run, when it posted one. */\n outputSummary: string | null;\n /** The reporting app's run id (Cloud Build: the build UUID). */\n externalId: string | null;\n /** True when this run's log is fetchable via build_id (Cloud Build + GCP creds). */\n buildLogAvailable?: boolean;\n}\n\nexport interface GithubChecksFns {\n getChecks: (branch?: string) => Promise<GithubCheckSummary[]>;\n getJobLog: (jobId: number) => Promise<string>;\n getBuildLog: (buildId: string) => Promise<string>;\n}\n\n/** Arguments for the host-side `github_read` tool. */\nexport interface GithubReadRequest {\n action: \"pr\" | \"pr_files\" | \"pr_reviews\" | \"issue\" | \"comments\" | \"list\";\n /** Issue/PR number; defaults to the conversation's own. */\n number?: number;\n /** list only: open | closed | all (default open). */\n state?: string;\n /** list only: comma-separated label names. */\n labels?: string;\n /** list only: filter by author login. */\n creator?: string;\n}\n\n/** Typed payload of one `github_read` action; the tool renders it. */\nexport type GithubReadResult =\n | { kind: \"pr\"; pr: GithubPullRequest }\n | { kind: \"pr_files\"; files: GithubPullRequestFile[] }\n | { kind: \"pr_reviews\"; reviews: GithubPullRequestReview[]; threads: GithubReviewComment[] }\n | { kind: \"issue\"; issue: GithubIssue }\n | { kind: \"comments\"; comments: GithubIssueComment[] }\n | { kind: \"list\"; issues: GithubIssue[] };\n\n/** Arguments for the host-side `github_issue` tool. Deliberately a closed\n * action set: lock/delete/transfer are not offered at all. */\nexport interface GithubIssueRequest {\n action: \"add_labels\" | \"remove_label\" | \"add_assignees\" | \"remove_assignees\" | \"close\" | \"reopen\";\n /** Issue/PR number; defaults to the conversation's own (triage may target others). */\n number?: number;\n /** add_labels */\n labels?: string[];\n /** remove_label */\n label?: string;\n /** add_assignees / remove_assignees */\n assignees?: string[];\n /** close */\n state_reason?: \"completed\" | \"not_planned\";\n}\n\n/**\n * Host-side GitHub operations for github_* tools. Wired in main.ts over the\n * GitHub bot; tokens stay host-side. Consumed by `createGithubToolPack`.\n */\nexport type GithubSyncFn = (branch?: string) => Promise<string>;\n\nexport type GithubReviewReplyFn = (commentId: number, body: string) => Promise<{ url: string }>;\n\nexport type GithubReadFn = (request: GithubReadRequest) => Promise<GithubReadResult>;\n\nexport type GithubIssueFn = (request: GithubIssueRequest) => Promise<string>;\n\nexport interface PlatformGithubOps {\n /** Push a prepared pi/* branch and open (or update) a pull request. */\n pushAndCreatePr(conversationId: string, request: GithubPrRequest): Promise<GithubPrResult>;\n /** CI check runs for a branch, or for the conversation's PR head when omitted. */\n getChecks(conversationId: string, branch?: string): Promise<GithubCheckSummary[]>;\n /** Log text of one CI job (an Actions check-run id), tail-truncated. */\n getJobLog(conversationId: string, jobId: number): Promise<string>;\n /** Log text of one Cloud Build run (a [build …] uuid), tail-truncated. */\n getBuildLog(conversationId: string, buildId: string): Promise<string>;\n /** Reply inside one inline review thread of the conversation's PR. */\n replyToReviewThread(\n conversationId: string,\n commentId: number,\n body: string,\n ): Promise<{ url: string }>;\n /** Refresh the conversation's ./repo clone; returns a human-readable report. */\n syncRepo(conversationId: string, branch?: string): Promise<string>;\n /** Read PR/issue metadata the clone cannot provide; same repo only. */\n readGithub(conversationId: string, request: GithubReadRequest): Promise<GithubReadResult>;\n /** Label/assignee/state management on this repo's issues; returns a report. */\n manageIssue(conversationId: string, request: GithubIssueRequest): Promise<string>;\n}\n"]}
@@ -33,7 +33,7 @@ export async function processMessageIntake(options) {
33
33
  return "magic-word";
34
34
  }
35
35
  const triggerResult = options.isAutoReplyCandidate
36
- ? await evaluateAutoReplyPolicy({ event: options.eventBase, workingDir: options.workingDir })
36
+ ? await evaluateAutoReplyPolicy({ event: options.eventBase, office: options.office })
37
37
  : { trigger: true, reason: "addressed" };
38
38
  if (!triggerResult.trigger) {
39
39
  options.log?.({ ...options.logEntryBase, attachments: [] });
@@ -1 +1 @@
1
- {"version":3,"file":"intake.js","sourceRoot":"","sources":["../../src/adapters/intake.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qCAAqC,EACrC,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG7E;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACjE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAqC;IAErC,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACvD,IAAI,OAAO,CAAC,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAC/C,qCAAqC,CACnC,OAAO,CAAC,SAAS,CAAC,UAAU,EAC5B,OAAO,CAAC,SAAS,CAAC,cAAc,CACjC,CAAC;IACJ,CAAC;IACD,IAAI,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,MAAM,EAAE,CAAC;QAChF,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5D,MAAM,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,oBAAoB;QAChD,CAAC,CAAC,MAAM,uBAAuB,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;QAC7F,CAAC,CAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAY,CAAC;IAEtD,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5D,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,SAAS,YAAY,CAAC,WAAsB;QAC1C,MAAM,KAAK,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,WAAW,EAAY,CAAC;QAC9D,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,UAAU,iBAAiB;QAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC;QACpF,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;QACpF,MAAM,OAAO,CAAC,GAAG,CAAC,WAAW,CAC3B,OAAO,CAAC,SAAS,CAAC,cAAc,EAChC,oBAAoB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAC3C,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,QAAQ,CAAC,KAAa;QAC7B,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC7C,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,OAAO,CAAC,wBAAwB,EAAE,CAAC;QACrC,wEAAwE;QACxE,kDAAkD;QAClD,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YAC3C,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAC/D,IAAI,OAAO,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,iBAAiB,EAAE,CAAC;gBAAE,OAAO;YAC3E,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,iBAAiB,EAAE,CAAC;QAAE,OAAO,eAAe,CAAC;IAC3F,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IACzD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,mBAAmB,CAChC,OAAqC;IAErC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACvD,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;IAClC,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,CAAC;IAChD,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC;IAExC,IAAI,MAAM,GAAG,iBAAiB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IACjE,IAAI,CAAC,MAAM,IAAI,qBAAqB,CAAC,SAAS,CAAC,aAAa,EAAE,UAAU,EAAE,cAAc,CAAC,EAAE,CAAC;QAC1F,MAAM,GAAG,2BAA2B,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IACjD,CAAC;SAAM,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;QAC/B,MAAM,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAC5B,aAA+C,EAC/C,UAA8B,EAC9B,cAAsB;IAEtB,IAAI,aAAa,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,aAAa,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC5C,2EAA2E;IAC3E,4EAA4E;IAC5E,OAAO,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,cAAc,CAAC;AACnE,CAAC","sourcesContent":["import {\n assertSessionKeyBelongsToConversation,\n assertConversationId,\n} from \"../sessions/session-key.js\";\nimport type { ConversationEvent } from \"../adapter.js\";\nimport { formatAlreadyWorking, formatNothingRunning } from \"../platform-messages.js\";\nimport { evaluateAutoReplyPolicy } from \"../trigger.js\";\nimport { resolveOnlyScopedStopTarget, resolveStopTarget } from \"./shared.js\";\nimport type { MessageIntakeOptions, MessageIntakeOutcome } from \"./types.js\";\n\n/**\n * Recognize a magic word: a highest-priority chat control phrase that bypasses\n * trigger policy and queueing (see CONTEXT.md). One grammar for every\n * platform: optional leading slash, optional `@botname` suffix, any case.\n */\nexport function matchMagicWord(text: string): \"stop\" | null {\n return /^\\/?stop(?:@\\w+)?$/i.test(text.trim()) ? \"stop\" : null;\n}\n\n/**\n * Shared message ingress pipeline for platform adapters.\n *\n * Platform adapters normalize SDK events; this module owns the ordering for\n * messages that may start an agent run:\n *\n * magic word → trigger policy → attachments → log → busy policy → queue → dispatch\n *\n * Magic words are matched before the trigger gate — `stop` must never wait on\n * an auto-reply judgment or queue behind a running agent turn. Adapters state\n * platform policy as data (`magicWord`, `busyPolicy`) instead of callbacks.\n */\nexport async function processMessageIntake<TEvent extends ConversationEvent>(\n options: MessageIntakeOptions<TEvent>,\n): Promise<MessageIntakeOutcome> {\n assertConversationId(options.eventBase.conversationId);\n if (options.eventBase.sessionKey !== undefined) {\n assertSessionKeyBelongsToConversation(\n options.eventBase.sessionKey,\n options.eventBase.conversationId,\n );\n }\n if (matchMagicWord(options.magicWord.text ?? options.eventBase.text) === \"stop\") {\n options.log?.({ ...options.logEntryBase, attachments: [] });\n await handleStopMagicWord(options);\n return \"magic-word\";\n }\n\n const triggerResult = options.isAutoReplyCandidate\n ? await evaluateAutoReplyPolicy({ event: options.eventBase, workingDir: options.workingDir })\n : ({ trigger: true, reason: \"addressed\" } as const);\n\n if (!triggerResult.trigger) {\n options.log?.({ ...options.logEntryBase, attachments: [] });\n return \"not-triggered\";\n }\n\n function prepareEvent(attachments: unknown[]): TEvent {\n const event = { ...options.eventBase, attachments } as TEvent;\n options.log?.({ ...options.logEntryBase, attachments });\n return event;\n }\n\n async function rejectedWhileBusy(): Promise<boolean> {\n const sessionKey = options.eventBase.sessionKey ?? options.eventBase.conversationId;\n if (!options.handler.isRunning(options.eventBase.address, sessionKey)) return false;\n await options.bot.postMessage(\n options.eventBase.conversationId,\n formatAlreadyWorking(options.bot, \"/stop\"),\n );\n return true;\n }\n\n function dispatch(event: TEvent): Promise<void> {\n const context = options.createContext(event);\n return options.handler.handleEvent(event, options.bot, context);\n }\n\n if (options.deferAttachmentsUntilRun) {\n // Busy rejection happens inside the queued work here, so the outcome is\n // already \"enqueued\" by the time it is evaluated.\n options.enqueue(options.queueKey, async () => {\n const event = prepareEvent(await options.processAttachments());\n if (options.busyPolicy === \"reject\" && (await rejectedWhileBusy())) return;\n return dispatch(event);\n });\n return \"enqueued\";\n }\n\n const event = prepareEvent(await options.processAttachments());\n if (options.busyPolicy === \"reject\" && (await rejectedWhileBusy())) return \"rejected-busy\";\n options.enqueue(options.queueKey, () => dispatch(event));\n return \"enqueued\";\n}\n\n/**\n * Resolve and stop the session a magic-word `stop` targets. When nothing is\n * running, reply only if the message addressed the bot — an unaddressed\n * \"stop\" in a busy channel should never make the bot pipe up.\n */\nasync function handleStopMagicWord<TEvent extends ConversationEvent>(\n options: MessageIntakeOptions<TEvent>,\n): Promise<void> {\n const { handler, bot, eventBase, magicWord } = options;\n const address = eventBase.address;\n const conversationId = eventBase.conversationId;\n const sessionKey = eventBase.sessionKey;\n\n let target = resolveStopTarget({ handler, address, sessionKey });\n if (!target && widensToScopedSession(magicWord.scopeFallback, sessionKey, conversationId)) {\n target = resolveOnlyScopedStopTarget(handler, address);\n }\n\n if (target) {\n await handler.handleStop(address, target, bot);\n } else if (magicWord.addressed) {\n await bot.postMessage(conversationId, formatNothingRunning(bot));\n }\n}\n\nfunction widensToScopedSession(\n scopeFallback: \"top-level\" | \"always\" | \"never\",\n sessionKey: string | undefined,\n conversationId: string,\n): boolean {\n if (scopeFallback === \"never\") return false;\n if (scopeFallback === \"always\") return true;\n // \"top-level\": only a message aimed at the persistent conversation session\n // may widen to the single running scoped session; thread messages stay put.\n return sessionKey === undefined || sessionKey === conversationId;\n}\n"]}
1
+ {"version":3,"file":"intake.js","sourceRoot":"","sources":["../../src/adapters/intake.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n assertSessionKeyBelongsToConversation,\n assertConversationId,\n} from \"../sessions/session-key.js\";\nimport type { ConversationEvent } from \"../adapter.js\";\nimport { formatAlreadyWorking, formatNothingRunning } from \"../platform-messages.js\";\nimport { evaluateAutoReplyPolicy } from \"../trigger.js\";\nimport { resolveOnlyScopedStopTarget, resolveStopTarget } from \"./shared.js\";\nimport type { MessageIntakeOptions, MessageIntakeOutcome } from \"./types.js\";\n\n/**\n * Recognize a magic word: a highest-priority chat control phrase that bypasses\n * trigger policy and queueing (see CONTEXT.md). One grammar for every\n * platform: optional leading slash, optional `@botname` suffix, any case.\n */\nexport function matchMagicWord(text: string): \"stop\" | null {\n return /^\\/?stop(?:@\\w+)?$/i.test(text.trim()) ? \"stop\" : null;\n}\n\n/**\n * Shared message ingress pipeline for platform adapters.\n *\n * Platform adapters normalize SDK events; this module owns the ordering for\n * messages that may start an agent run:\n *\n * magic word → trigger policy → attachments → log → busy policy → queue → dispatch\n *\n * Magic words are matched before the trigger gate — `stop` must never wait on\n * an auto-reply judgment or queue behind a running agent turn. Adapters state\n * platform policy as data (`magicWord`, `busyPolicy`) instead of callbacks.\n */\nexport async function processMessageIntake<TEvent extends ConversationEvent>(\n options: MessageIntakeOptions<TEvent>,\n): Promise<MessageIntakeOutcome> {\n assertConversationId(options.eventBase.conversationId);\n if (options.eventBase.sessionKey !== undefined) {\n assertSessionKeyBelongsToConversation(\n options.eventBase.sessionKey,\n options.eventBase.conversationId,\n );\n }\n if (matchMagicWord(options.magicWord.text ?? options.eventBase.text) === \"stop\") {\n options.log?.({ ...options.logEntryBase, attachments: [] });\n await handleStopMagicWord(options);\n return \"magic-word\";\n }\n\n const triggerResult = options.isAutoReplyCandidate\n ? await evaluateAutoReplyPolicy({ event: options.eventBase, office: options.office })\n : ({ trigger: true, reason: \"addressed\" } as const);\n\n if (!triggerResult.trigger) {\n options.log?.({ ...options.logEntryBase, attachments: [] });\n return \"not-triggered\";\n }\n\n function prepareEvent(attachments: unknown[]): TEvent {\n const event = { ...options.eventBase, attachments } as TEvent;\n options.log?.({ ...options.logEntryBase, attachments });\n return event;\n }\n\n async function rejectedWhileBusy(): Promise<boolean> {\n const sessionKey = options.eventBase.sessionKey ?? options.eventBase.conversationId;\n if (!options.handler.isRunning(options.eventBase.address, sessionKey)) return false;\n await options.bot.postMessage(\n options.eventBase.conversationId,\n formatAlreadyWorking(options.bot, \"/stop\"),\n );\n return true;\n }\n\n function dispatch(event: TEvent): Promise<void> {\n const context = options.createContext(event);\n return options.handler.handleEvent(event, options.bot, context);\n }\n\n if (options.deferAttachmentsUntilRun) {\n // Busy rejection happens inside the queued work here, so the outcome is\n // already \"enqueued\" by the time it is evaluated.\n options.enqueue(options.queueKey, async () => {\n const event = prepareEvent(await options.processAttachments());\n if (options.busyPolicy === \"reject\" && (await rejectedWhileBusy())) return;\n return dispatch(event);\n });\n return \"enqueued\";\n }\n\n const event = prepareEvent(await options.processAttachments());\n if (options.busyPolicy === \"reject\" && (await rejectedWhileBusy())) return \"rejected-busy\";\n options.enqueue(options.queueKey, () => dispatch(event));\n return \"enqueued\";\n}\n\n/**\n * Resolve and stop the session a magic-word `stop` targets. When nothing is\n * running, reply only if the message addressed the bot — an unaddressed\n * \"stop\" in a busy channel should never make the bot pipe up.\n */\nasync function handleStopMagicWord<TEvent extends ConversationEvent>(\n options: MessageIntakeOptions<TEvent>,\n): Promise<void> {\n const { handler, bot, eventBase, magicWord } = options;\n const address = eventBase.address;\n const conversationId = eventBase.conversationId;\n const sessionKey = eventBase.sessionKey;\n\n let target = resolveStopTarget({ handler, address, sessionKey });\n if (!target && widensToScopedSession(magicWord.scopeFallback, sessionKey, conversationId)) {\n target = resolveOnlyScopedStopTarget(handler, address);\n }\n\n if (target) {\n await handler.handleStop(address, target, bot);\n } else if (magicWord.addressed) {\n await bot.postMessage(conversationId, formatNothingRunning(bot));\n }\n}\n\nfunction widensToScopedSession(\n scopeFallback: \"top-level\" | \"always\" | \"never\",\n sessionKey: string | undefined,\n conversationId: string,\n): boolean {\n if (scopeFallback === \"never\") return false;\n if (scopeFallback === \"always\") return true;\n // \"top-level\": only a message aimed at the persistent conversation session\n // may widen to the single running scoped session; thread messages stay put.\n return sessionKey === undefined || sessionKey === conversationId;\n}\n"]}
@@ -7,8 +7,9 @@
7
7
  * markup wrappers — so it lives here once.
8
8
  */
9
9
  import type { MessagingEventHandler, OfficeAddress } from "../adapter.js";
10
- export type { ChatResponseErrorContext, ChatResponseErrorOperation, ChatResponseErrorReporter, ResolveStopTargetInput, RetryOptions, } from "./types.js";
11
- import type { ChatResponseErrorContext, ChatResponseErrorReporter, RetryOptions, ResolveStopTargetInput } from "./types.js";
10
+ import { type Office } from "../office/index.js";
11
+ export type { ChatResponseErrorContext, ChatResponseErrorOperation, ChatResponseErrorReporter, IncomingAttachment, ResolveStopTargetInput, RetryOptions, SavedAttachments, } from "./types.js";
12
+ import type { ChatResponseErrorContext, ChatResponseErrorReporter, IncomingAttachment, RetryOptions, ResolveStopTargetInput, SavedAttachments } from "./types.js";
12
13
  export declare function createChatResponseErrorReporter(resolve: () => Omit<ChatResponseErrorContext, "operation" | "extra">): ChatResponseErrorReporter;
13
14
  export declare class MessagingEventQueue {
14
15
  private readonly name;
@@ -35,12 +36,23 @@ export declare function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions):
35
36
  export declare function splitText(text: string, limit: number, formatContinuation: (partNum: number) => string): string[];
36
37
  /**
37
38
  * Append a JSON-serializable entry to the office's `log.jsonl`,
38
- * creating the directory on first use. This is the single write path every
39
+ * materializing the office on first use. This is the single write path every
39
40
  * adapter uses for human-readable message history.
40
41
  */
41
- export declare function appendChannelLog(workingDir: string, address: OfficeAddress, entry: object): void;
42
+ export declare function appendChannelLog(office: Office, entry: object): void;
43
+ /**
44
+ * Save incoming platform files under the office's attachments directory.
45
+ *
46
+ * The one owner of the attachment convention: sanitized
47
+ * `<timestamp>_<name>` filenames, the `<office key>/attachments/<file>`
48
+ * workspace-relative localPath the agent reads, and office materialization
49
+ * before the first write. Download mechanics and failure policy stay with
50
+ * the adapter — failures come back in `failed` for the caller to throw or
51
+ * warn about, matching its platform's behavior.
52
+ */
53
+ export declare function saveIncomingAttachments(office: Office, items: readonly IncomingAttachment[]): Promise<SavedAttachments>;
42
54
  /** Convenience for appending the bot's own outbound message. */
43
- export declare function appendBotResponseLog(workingDir: string, address: OfficeAddress, text: string, ts: string, threadTs?: string, extraFields?: Record<string, unknown>): void;
55
+ export declare function appendBotResponseLog(office: Office, text: string, ts: string, threadTs?: string, extraFields?: Record<string, unknown>): void;
44
56
  /**
45
57
  * Pick which session key a `/stop` should target without applying any
46
58
  * platform-specific fallback policy. Order:
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAK1E,YAAY,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACtB,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EACzB,YAAY,EACZ,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,IAAI,CAAC,wBAAwB,EAAE,WAAW,GAAG,OAAO,CAAC,GACnE,yBAAyB,CAI3B;AA0BD,qBAAa,mBAAmB;IAIlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,UAAU,CAAS;IAE3B,YAA6B,IAAI,GAAE,MAAW,EAAI;IAElD,OAAO,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAGvC;IAED,IAAI,IAAI,MAAM,CAEb;YAEa,WAAW;CAe1B;AAID;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAwBvF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAC9C,MAAM,EAAE,CAeV;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAGhG;AAED,gEAAgE;AAChE,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACxC,IAAI,CAWN;AAID;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,GAAG,IAAI,CAM9E;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,aAAa,GACrB,MAAM,GAAG,IAAI,CAQf;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAsBhF;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpF"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG7D,YAAY,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,EACzB,kBAAkB,EAClB,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EACzB,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,EACtB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,IAAI,CAAC,wBAAwB,EAAE,WAAW,GAAG,OAAO,CAAC,GACnE,yBAAyB,CAI3B;AA0BD,qBAAa,mBAAmB;IAIlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,UAAU,CAAS;IAE3B,YAA6B,IAAI,GAAE,MAAW,EAAI;IAElD,OAAO,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAGvC;IAED,IAAI,IAAI,MAAM,CAEb;YAEa,WAAW;CAe1B;AAID;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAwBvF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAC9C,MAAM,EAAE,CAeV;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAGpE;AAED;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,kBAAkB,EAAE,GACnC,OAAO,CAAC,gBAAgB,CAAC,CA2B3B;AAED,gEAAgE;AAChE,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACxC,IAAI,CAWN;AAID;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,GAAG,IAAI,CAM9E;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,aAAa,GACrB,MAAM,GAAG,IAAI,CAQf;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAsBhF;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpF"}
@@ -9,8 +9,7 @@
9
9
  import { appendFileSync } from "fs";
10
10
  import { mkdir, writeFile } from "fs/promises";
11
11
  import { dirname, join } from "path";
12
- import { sameOffice } from "../office-address.js";
13
- import { ensureOfficeDir } from "../office-registry.js";
12
+ import { sameOffice } from "../office/index.js";
14
13
  import * as log from "../log.js";
15
14
  import { reportUserFacingError } from "../observability/sentry.js";
16
15
  export function createChatResponseErrorReporter(resolve) {
@@ -122,16 +121,53 @@ export function splitText(text, limit, formatContinuation) {
122
121
  }
123
122
  /**
124
123
  * Append a JSON-serializable entry to the office's `log.jsonl`,
125
- * creating the directory on first use. This is the single write path every
124
+ * materializing the office on first use. This is the single write path every
126
125
  * adapter uses for human-readable message history.
127
126
  */
128
- export function appendChannelLog(workingDir, address, entry) {
129
- const dir = ensureOfficeDir(workingDir, address);
130
- appendFileSync(join(dir, "log.jsonl"), `${JSON.stringify(entry)}\n`);
127
+ export function appendChannelLog(office, entry) {
128
+ office.ensure();
129
+ appendFileSync(office.logPath, `${JSON.stringify(entry)}\n`);
130
+ }
131
+ /**
132
+ * Save incoming platform files under the office's attachments directory.
133
+ *
134
+ * The one owner of the attachment convention: sanitized
135
+ * `<timestamp>_<name>` filenames, the `<office key>/attachments/<file>`
136
+ * workspace-relative localPath the agent reads, and office materialization
137
+ * before the first write. Download mechanics and failure policy stay with
138
+ * the adapter — failures come back in `failed` for the caller to throw or
139
+ * warn about, matching its platform's behavior.
140
+ */
141
+ export async function saveIncomingAttachments(office, items) {
142
+ if (items.length === 0)
143
+ return { saved: [], failed: [] };
144
+ // Attachment downloads can be the office's first write; materialize (and
145
+ // register) it before composing office-relative attachment paths.
146
+ office.ensure();
147
+ await mkdir(office.attachmentsDir, { recursive: true });
148
+ // Results keep the caller's item order regardless of download completion
149
+ // order — platform message logs list attachments as the platform sent them.
150
+ const results = await Promise.all(items.map(async (item) => {
151
+ const sanitized = item.name.replace(/[^a-zA-Z0-9._-]/g, "_");
152
+ const filename = `${item.timestampMs ?? Date.now()}_${sanitized}`;
153
+ try {
154
+ await item.download(join(office.attachmentsDir, filename));
155
+ return {
156
+ saved: { original: item.name, localPath: `${office.key}/attachments/${filename}` },
157
+ };
158
+ }
159
+ catch (error) {
160
+ return { failed: { name: item.name, error } };
161
+ }
162
+ }));
163
+ return {
164
+ saved: results.flatMap((result) => (result.saved ? [result.saved] : [])),
165
+ failed: results.flatMap((result) => (result.failed ? [result.failed] : [])),
166
+ };
131
167
  }
132
168
  /** Convenience for appending the bot's own outbound message. */
133
- export function appendBotResponseLog(workingDir, address, text, ts, threadTs, extraFields = {}) {
134
- appendChannelLog(workingDir, address, {
169
+ export function appendBotResponseLog(office, text, ts, threadTs, extraFields = {}) {
170
+ appendChannelLog(office, {
135
171
  date: new Date().toISOString(),
136
172
  ts,
137
173
  ...(threadTs ? { threadTs } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Helpers shared across platform adapters.\n *\n * The agent runner is platform-agnostic: it hands strings and structured tool\n * results to each adapter, which decides how to split, format, and route them.\n * The split/normalize logic itself doesn't differ across platforms — only the\n * markup wrappers — so it lives here once.\n */\n\nimport { appendFileSync } from \"fs\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport { dirname, join } from \"path\";\nimport type { MessagingEventHandler, OfficeAddress } from \"../adapter.js\";\nimport { sameOffice } from \"../office-address.js\";\nimport { ensureOfficeDir } from \"../office-registry.js\";\nimport * as log from \"../log.js\";\nimport { reportUserFacingError } from \"../observability/sentry.js\";\nexport type {\n ChatResponseErrorContext,\n ChatResponseErrorOperation,\n ChatResponseErrorReporter,\n ResolveStopTargetInput,\n RetryOptions,\n} from \"./types.js\";\nimport type {\n ChatResponseErrorContext,\n ChatResponseErrorReporter,\n RetryOptions,\n ResolveStopTargetInput,\n} from \"./types.js\";\n\nexport function createChatResponseErrorReporter(\n resolve: () => Omit<ChatResponseErrorContext, \"operation\" | \"extra\">,\n): ChatResponseErrorReporter {\n return (err, operation, extra) => {\n reportChatResponseError(err, { ...resolve(), operation, extra });\n };\n}\n\nfunction reportChatResponseError(err: unknown, context: ChatResponseErrorContext): void {\n reportUserFacingError(err, {\n domain: \"chat_platform\",\n surface: \"chat_response\",\n operation: context.operation,\n severity: context.operation === \"set_working\" ? \"warning\" : \"error\",\n platform: context.platform,\n context: {\n conversationId: context.conversationId,\n channelId: context.channelId,\n chatId: context.chatId,\n messageId: context.messageId,\n sessionKey: context.sessionKey,\n responseMessageId: context.responseMessageId,\n threadTs: context.threadTs,\n replyTargetId: context.replyTargetId,\n replyToId: context.replyToId,\n conversationKind: context.conversationKind,\n isThreaded: context.isThreaded,\n ...context.extra,\n },\n });\n}\n\nexport class MessagingEventQueue {\n private queue: Array<() => Promise<void>> = [];\n private processing = false;\n\n constructor(private readonly name: string = \"\") {}\n\n enqueue(work: () => Promise<void>): void {\n this.queue.push(work);\n this.processNext();\n }\n\n size(): number {\n return this.queue.length;\n }\n\n private async processNext(): Promise<void> {\n if (this.processing || this.queue.length === 0) return;\n this.processing = true;\n const work = this.queue.shift()!;\n try {\n await work();\n } catch (err) {\n log.logWarning(\n `${this.name ? this.name + \" \" : \"\"}queue error`,\n err instanceof Error ? err.message : String(err),\n );\n }\n this.processing = false;\n this.processNext();\n }\n}\n\n// RetryOptions is defined in ./types.ts and re-exported from the top of this file.\n\n/**\n * Run `fn` and retry with exponential backoff when its error matches\n * `isRateLimited`. Other errors propagate immediately. Each platform supplies\n * its own predicate so we don't have to know every SDK's error shape here.\n */\nexport async function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions): Promise<T> {\n const maxAttempts = opts.maxAttempts ?? 3;\n const baseDelayMs = opts.baseDelayMs ?? 1000;\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n\n const isLastAttempt = attempt === maxAttempts - 1;\n if (isLastAttempt || !opts.isRateLimited(lastError)) {\n throw lastError;\n }\n\n const delay = baseDelayMs * Math.pow(2, attempt);\n log.logWarning(\n `Retrying after error in ${delay}ms (attempt ${attempt + 1}/${maxAttempts}): ${lastError.message}`,\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n throw lastError;\n}\n\n/**\n * Split `text` into chunks no larger than `limit`, appending a continuation\n * marker (e.g. `_(continued 1)_`) at the end of every part except the last.\n *\n * Each adapter passes its own `formatContinuation` so the marker uses the\n * platform's italic / emphasis convention.\n */\nexport function splitText(\n text: string,\n limit: number,\n formatContinuation: (partNum: number) => string,\n): string[] {\n if (text.length <= limit) return [text];\n const parts: string[] = [];\n let remaining = text;\n let partNum = 1;\n while (remaining.length > 0) {\n const suffixReserve = formatContinuation(partNum).length + 8;\n const chunkLimit = Math.max(1, limit - suffixReserve);\n const chunk = remaining.slice(0, chunkLimit);\n remaining = remaining.slice(chunkLimit);\n const suffix = remaining.length > 0 ? `\\n${formatContinuation(partNum)}` : \"\";\n parts.push(chunk + suffix);\n partNum++;\n }\n return parts;\n}\n\n/**\n * Append a JSON-serializable entry to the office's `log.jsonl`,\n * creating the directory on first use. This is the single write path every\n * adapter uses for human-readable message history.\n */\nexport function appendChannelLog(workingDir: string, address: OfficeAddress, entry: object): void {\n const dir = ensureOfficeDir(workingDir, address);\n appendFileSync(join(dir, \"log.jsonl\"), `${JSON.stringify(entry)}\\n`);\n}\n\n/** Convenience for appending the bot's own outbound message. */\nexport function appendBotResponseLog(\n workingDir: string,\n address: OfficeAddress,\n text: string,\n ts: string,\n threadTs?: string,\n extraFields: Record<string, unknown> = {},\n): void {\n appendChannelLog(workingDir, address, {\n date: new Date().toISOString(),\n ts,\n ...(threadTs ? { threadTs } : {}),\n user: \"bot\",\n text,\n attachments: [],\n isMessagingBot: true,\n ...extraFields,\n });\n}\n\n// ResolveStopTargetInput is defined in ./types.ts and re-exported from the top of this file.\n\n/**\n * Pick which session key a `/stop` should target without applying any\n * platform-specific fallback policy. Order:\n * 1. The provided sessionKey, if running.\n * 2. The bare conversationId, if running.\n */\nexport function resolveStopTarget(input: ResolveStopTargetInput): string | null {\n const { handler, address, sessionKey } = input;\n\n if (sessionKey && handler.isRunning(address, sessionKey)) return sessionKey;\n if (handler.isRunning(address, address.conversationId)) return address.conversationId;\n return null;\n}\n\n/**\n * Return the single running scoped session for this office, or null when there\n * are zero or multiple matches. Another platform's identically named\n * conversation is a different office and is never a stop target.\n */\nexport function resolveOnlyScopedStopTarget(\n handler: MessagingEventHandler,\n address: OfficeAddress,\n): string | null {\n const runningScopes = handler\n .getRunningSessions()\n .filter((session) => sameOffice(session.address, address))\n .map((session) => session.sessionKey)\n .filter((key) => key.startsWith(`${address.conversationId}:`));\n\n return runningScopes.length === 1 ? runningScopes[0] : null;\n}\n\n/**\n * Render tool-call args for human display. Drops `label` (already in the\n * heading) and folds `path` + `offset`/`limit` into a single `path:start-end`\n * line. Pure data normalization with no platform-specific markup.\n */\nexport function formatToolArgs(args: Record<string, unknown> | undefined): string {\n if (!args) return \"\";\n const lines: string[] = [];\n\n for (const [key, value] of Object.entries(args)) {\n if (key === \"label\" || key === \"offset\" || key === \"limit\") continue;\n\n if (key === \"path\" && typeof value === \"string\") {\n const offset = args.offset as number | undefined;\n const limit = args.limit as number | undefined;\n lines.push(\n offset !== undefined && limit !== undefined\n ? `${value}:${offset}-${offset + limit}`\n : value,\n );\n continue;\n }\n\n lines.push(typeof value === \"string\" ? value : JSON.stringify(value));\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Fetch `url` and write the response body to `destPath`, creating parent\n * directories as needed. Throws on non-2xx responses or write failures.\n */\nexport async function downloadUrlToFile(url: string, destPath: string): Promise<void> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n const buffer = await response.arrayBuffer();\n await mkdir(dirname(destPath), { recursive: true });\n await writeFile(destPath, Buffer.from(buffer));\n}\n"]}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAErC,OAAO,EAAE,UAAU,EAAe,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAmBnE,MAAM,UAAU,+BAA+B,CAC7C,OAAoE;IAEpE,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE;QAC/B,uBAAuB,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,GAAY,EAAE,OAAiC;IAC9E,qBAAqB,CAAC,GAAG,EAAE;QACzB,MAAM,EAAE,eAAe;QACvB,OAAO,EAAE,eAAe;QACxB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,QAAQ,EAAE,OAAO,CAAC,SAAS,KAAK,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;QACnE,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,OAAO,EAAE;YACP,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;YAC5C,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;YAC1C,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,GAAG,OAAO,CAAC,KAAK;SACjB;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,OAAO,mBAAmB;IAI9B,YAA6B,IAAI,GAAW,EAAE;QAAjB,SAAI,GAAJ,IAAI,CAAa;QAHtC,UAAK,GAA+B,EAAE,CAAC;QACvC,eAAU,GAAG,KAAK,CAAC;IAEsB,CAAC;IAElD,OAAO,CAAC,IAAyB;QAC/B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,WAAW;QACvB,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACvD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,UAAU,CACZ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,aAAa,EAChD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACjD,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;CACF;AAED,mFAAmF;AAEnF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,EAAoB,EAAE,IAAkB;IACzE,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC;IAC7C,IAAI,SAA4B,CAAC;IAEjC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAEhE,MAAM,aAAa,GAAG,OAAO,KAAK,WAAW,GAAG,CAAC,CAAC;YAClD,IAAI,aAAa,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;gBACpD,MAAM,SAAS,CAAC;YAClB,CAAC;YAED,MAAM,KAAK,GAAG,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACjD,GAAG,CAAC,UAAU,CACZ,2BAA2B,KAAK,eAAe,OAAO,GAAG,CAAC,IAAI,WAAW,MAAM,SAAS,CAAC,OAAO,EAAE,CACnG,CAAC;YACF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IACD,MAAM,SAAS,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACvB,IAAY,EACZ,KAAa,EACb,kBAA+C;IAE/C,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,SAAS,GAAG,IAAI,CAAC;IACrB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,aAAa,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,aAAa,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAC7C,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,KAAa;IAC5D,MAAM,CAAC,MAAM,EAAE,CAAC;IAChB,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAc,EACd,KAAoC;IAEpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACzD,yEAAyE;IACzE,kEAAkE;IAClE,MAAM,CAAC,MAAM,EAAE,CAAC;IAChB,MAAM,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExD,yEAAyE;IACzE,4EAA4E;IAC5E,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,SAAS,EAAE,CAAC;QAClE,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;YAC3D,OAAO;gBACL,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,GAAG,gBAAgB,QAAQ,EAAE,EAAE;aACnF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IACF,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KAC5E,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,oBAAoB,CAClC,MAAc,EACd,IAAY,EACZ,EAAU,EACV,QAAiB,EACjB,WAAW,GAA4B,EAAE;IAEzC,gBAAgB,CAAC,MAAM,EAAE;QACvB,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC9B,EAAE;QACF,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjC,IAAI,EAAE,KAAK;QACX,IAAI;QACJ,WAAW,EAAE,EAAE;QACf,cAAc,EAAE,IAAI;QACpB,GAAG,WAAW;KACf,CAAC,CAAC;AACL,CAAC;AAED,6FAA6F;AAE7F;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAE/C,IAAI,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IAC5E,IAAI,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC;QAAE,OAAO,OAAO,CAAC,cAAc,CAAC;IACtF,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACzC,OAA8B,EAC9B,OAAsB;IAEtB,MAAM,aAAa,GAAG,OAAO;SAC1B,kBAAkB,EAAE;SACpB,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;SACzD,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC;SACpC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;IAEjE,OAAO,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAyC;IACtE,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,OAAO;YAAE,SAAS;QAErE,IAAI,GAAG,KAAK,MAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAChD,MAAM,MAAM,GAAG,IAAI,CAAC,MAA4B,CAAC;YACjD,MAAM,KAAK,GAAG,IAAI,CAAC,KAA2B,CAAC;YAC/C,KAAK,CAAC,IAAI,CACR,MAAM,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;gBACzC,CAAC,CAAC,GAAG,KAAK,IAAI,MAAM,IAAI,MAAM,GAAG,KAAK,EAAE;gBACxC,CAAC,CAAC,KAAK,CACV,CAAC;YACF,SAAS;QACX,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAW,EAAE,QAAgB;IACnE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AACjD,CAAC","sourcesContent":["/**\n * Helpers shared across platform adapters.\n *\n * The agent runner is platform-agnostic: it hands strings and structured tool\n * results to each adapter, which decides how to split, format, and route them.\n * The split/normalize logic itself doesn't differ across platforms — only the\n * markup wrappers — so it lives here once.\n */\n\nimport { appendFileSync } from \"fs\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport { dirname, join } from \"path\";\nimport type { MessagingEventHandler, OfficeAddress } from \"../adapter.js\";\nimport { sameOffice, type Office } from \"../office/index.js\";\nimport * as log from \"../log.js\";\nimport { reportUserFacingError } from \"../observability/sentry.js\";\nexport type {\n ChatResponseErrorContext,\n ChatResponseErrorOperation,\n ChatResponseErrorReporter,\n IncomingAttachment,\n ResolveStopTargetInput,\n RetryOptions,\n SavedAttachments,\n} from \"./types.js\";\nimport type {\n ChatResponseErrorContext,\n ChatResponseErrorReporter,\n IncomingAttachment,\n RetryOptions,\n ResolveStopTargetInput,\n SavedAttachments,\n} from \"./types.js\";\n\nexport function createChatResponseErrorReporter(\n resolve: () => Omit<ChatResponseErrorContext, \"operation\" | \"extra\">,\n): ChatResponseErrorReporter {\n return (err, operation, extra) => {\n reportChatResponseError(err, { ...resolve(), operation, extra });\n };\n}\n\nfunction reportChatResponseError(err: unknown, context: ChatResponseErrorContext): void {\n reportUserFacingError(err, {\n domain: \"chat_platform\",\n surface: \"chat_response\",\n operation: context.operation,\n severity: context.operation === \"set_working\" ? \"warning\" : \"error\",\n platform: context.platform,\n context: {\n conversationId: context.conversationId,\n channelId: context.channelId,\n chatId: context.chatId,\n messageId: context.messageId,\n sessionKey: context.sessionKey,\n responseMessageId: context.responseMessageId,\n threadTs: context.threadTs,\n replyTargetId: context.replyTargetId,\n replyToId: context.replyToId,\n conversationKind: context.conversationKind,\n isThreaded: context.isThreaded,\n ...context.extra,\n },\n });\n}\n\nexport class MessagingEventQueue {\n private queue: Array<() => Promise<void>> = [];\n private processing = false;\n\n constructor(private readonly name: string = \"\") {}\n\n enqueue(work: () => Promise<void>): void {\n this.queue.push(work);\n this.processNext();\n }\n\n size(): number {\n return this.queue.length;\n }\n\n private async processNext(): Promise<void> {\n if (this.processing || this.queue.length === 0) return;\n this.processing = true;\n const work = this.queue.shift()!;\n try {\n await work();\n } catch (err) {\n log.logWarning(\n `${this.name ? this.name + \" \" : \"\"}queue error`,\n err instanceof Error ? err.message : String(err),\n );\n }\n this.processing = false;\n this.processNext();\n }\n}\n\n// RetryOptions is defined in ./types.ts and re-exported from the top of this file.\n\n/**\n * Run `fn` and retry with exponential backoff when its error matches\n * `isRateLimited`. Other errors propagate immediately. Each platform supplies\n * its own predicate so we don't have to know every SDK's error shape here.\n */\nexport async function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions): Promise<T> {\n const maxAttempts = opts.maxAttempts ?? 3;\n const baseDelayMs = opts.baseDelayMs ?? 1000;\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n\n const isLastAttempt = attempt === maxAttempts - 1;\n if (isLastAttempt || !opts.isRateLimited(lastError)) {\n throw lastError;\n }\n\n const delay = baseDelayMs * Math.pow(2, attempt);\n log.logWarning(\n `Retrying after error in ${delay}ms (attempt ${attempt + 1}/${maxAttempts}): ${lastError.message}`,\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n throw lastError;\n}\n\n/**\n * Split `text` into chunks no larger than `limit`, appending a continuation\n * marker (e.g. `_(continued 1)_`) at the end of every part except the last.\n *\n * Each adapter passes its own `formatContinuation` so the marker uses the\n * platform's italic / emphasis convention.\n */\nexport function splitText(\n text: string,\n limit: number,\n formatContinuation: (partNum: number) => string,\n): string[] {\n if (text.length <= limit) return [text];\n const parts: string[] = [];\n let remaining = text;\n let partNum = 1;\n while (remaining.length > 0) {\n const suffixReserve = formatContinuation(partNum).length + 8;\n const chunkLimit = Math.max(1, limit - suffixReserve);\n const chunk = remaining.slice(0, chunkLimit);\n remaining = remaining.slice(chunkLimit);\n const suffix = remaining.length > 0 ? `\\n${formatContinuation(partNum)}` : \"\";\n parts.push(chunk + suffix);\n partNum++;\n }\n return parts;\n}\n\n/**\n * Append a JSON-serializable entry to the office's `log.jsonl`,\n * materializing the office on first use. This is the single write path every\n * adapter uses for human-readable message history.\n */\nexport function appendChannelLog(office: Office, entry: object): void {\n office.ensure();\n appendFileSync(office.logPath, `${JSON.stringify(entry)}\\n`);\n}\n\n/**\n * Save incoming platform files under the office's attachments directory.\n *\n * The one owner of the attachment convention: sanitized\n * `<timestamp>_<name>` filenames, the `<office key>/attachments/<file>`\n * workspace-relative localPath the agent reads, and office materialization\n * before the first write. Download mechanics and failure policy stay with\n * the adapter — failures come back in `failed` for the caller to throw or\n * warn about, matching its platform's behavior.\n */\nexport async function saveIncomingAttachments(\n office: Office,\n items: readonly IncomingAttachment[],\n): Promise<SavedAttachments> {\n if (items.length === 0) return { saved: [], failed: [] };\n // Attachment downloads can be the office's first write; materialize (and\n // register) it before composing office-relative attachment paths.\n office.ensure();\n await mkdir(office.attachmentsDir, { recursive: true });\n\n // Results keep the caller's item order regardless of download completion\n // order — platform message logs list attachments as the platform sent them.\n const results = await Promise.all(\n items.map(async (item) => {\n const sanitized = item.name.replace(/[^a-zA-Z0-9._-]/g, \"_\");\n const filename = `${item.timestampMs ?? Date.now()}_${sanitized}`;\n try {\n await item.download(join(office.attachmentsDir, filename));\n return {\n saved: { original: item.name, localPath: `${office.key}/attachments/${filename}` },\n };\n } catch (error) {\n return { failed: { name: item.name, error } };\n }\n }),\n );\n return {\n saved: results.flatMap((result) => (result.saved ? [result.saved] : [])),\n failed: results.flatMap((result) => (result.failed ? [result.failed] : [])),\n };\n}\n\n/** Convenience for appending the bot's own outbound message. */\nexport function appendBotResponseLog(\n office: Office,\n text: string,\n ts: string,\n threadTs?: string,\n extraFields: Record<string, unknown> = {},\n): void {\n appendChannelLog(office, {\n date: new Date().toISOString(),\n ts,\n ...(threadTs ? { threadTs } : {}),\n user: \"bot\",\n text,\n attachments: [],\n isMessagingBot: true,\n ...extraFields,\n });\n}\n\n// ResolveStopTargetInput is defined in ./types.ts and re-exported from the top of this file.\n\n/**\n * Pick which session key a `/stop` should target without applying any\n * platform-specific fallback policy. Order:\n * 1. The provided sessionKey, if running.\n * 2. The bare conversationId, if running.\n */\nexport function resolveStopTarget(input: ResolveStopTargetInput): string | null {\n const { handler, address, sessionKey } = input;\n\n if (sessionKey && handler.isRunning(address, sessionKey)) return sessionKey;\n if (handler.isRunning(address, address.conversationId)) return address.conversationId;\n return null;\n}\n\n/**\n * Return the single running scoped session for this office, or null when there\n * are zero or multiple matches. Another platform's identically named\n * conversation is a different office and is never a stop target.\n */\nexport function resolveOnlyScopedStopTarget(\n handler: MessagingEventHandler,\n address: OfficeAddress,\n): string | null {\n const runningScopes = handler\n .getRunningSessions()\n .filter((session) => sameOffice(session.address, address))\n .map((session) => session.sessionKey)\n .filter((key) => key.startsWith(`${address.conversationId}:`));\n\n return runningScopes.length === 1 ? runningScopes[0] : null;\n}\n\n/**\n * Render tool-call args for human display. Drops `label` (already in the\n * heading) and folds `path` + `offset`/`limit` into a single `path:start-end`\n * line. Pure data normalization with no platform-specific markup.\n */\nexport function formatToolArgs(args: Record<string, unknown> | undefined): string {\n if (!args) return \"\";\n const lines: string[] = [];\n\n for (const [key, value] of Object.entries(args)) {\n if (key === \"label\" || key === \"offset\" || key === \"limit\") continue;\n\n if (key === \"path\" && typeof value === \"string\") {\n const offset = args.offset as number | undefined;\n const limit = args.limit as number | undefined;\n lines.push(\n offset !== undefined && limit !== undefined\n ? `${value}:${offset}-${offset + limit}`\n : value,\n );\n continue;\n }\n\n lines.push(typeof value === \"string\" ? value : JSON.stringify(value));\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Fetch `url` and write the response body to `destPath`, creating parent\n * directories as needed. Throws on non-2xx responses or write failures.\n */\nexport async function downloadUrlToFile(url: string, destPath: string): Promise<void> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n const buffer = await response.arrayBuffer();\n await mkdir(dirname(destPath), { recursive: true });\n await writeFile(destPath, Buffer.from(buffer));\n}\n"]}
@@ -1,4 +1,18 @@
1
1
  import type { KnownBlock } from "@slack/types";
2
+ /**
3
+ * Resolve response-source mentions to Slack's native form.
4
+ *
5
+ * The response source is platform-neutral: the model writes `<@userName>`
6
+ * from the prompt's Users table, and the adapter owns the conversion to
7
+ * `<@U…>` — Slack only links and notifies on the raw user id. Lookup covers
8
+ * userName and displayName case-insensitively; native-id mentions pass
9
+ * through, and unknown names stay verbatim rather than guessing.
10
+ */
11
+ export declare function resolveSlackMentions(source: string, users: Iterable<{
12
+ id: string;
13
+ userName: string;
14
+ displayName: string;
15
+ }>): string;
2
16
  export declare function renderSlackBlocks(source: string): {
3
17
  text: string;
4
18
  blocks: KnownBlock[];
@@ -1 +1 @@
1
- {"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/blocks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA+I/C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,EAAE,CAAA;CAAE,CAmCxF"}
1
+ {"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/blocks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAyB/C;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,GACrE,MAAM,CAiBR;AA4HD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,EAAE,CAAA;CAAE,CAmCxF"}
@@ -14,6 +14,40 @@ const LEGACY_MRKDWN_LINK_PATTERN = /<(https?:\/\/[^<>|\s]+)\|([^<>\n]+)>/g;
14
14
  function convertLegacyMrkdwnLinks(source) {
15
15
  return source.replace(LEGACY_MRKDWN_LINK_PATTERN, "[$2]($1)");
16
16
  }
17
+ // Slack user/bot-user ids: U/W prefix. Already-native mentions pass through.
18
+ const SLACK_USER_ID_PATTERN = /^[UW][A-Z0-9]{2,}$/;
19
+ const MENTION_PATTERN = /<@([^<>\n]+)>/g;
20
+ /**
21
+ * Resolve response-source mentions to Slack's native form.
22
+ *
23
+ * The response source is platform-neutral: the model writes `<@userName>`
24
+ * from the prompt's Users table, and the adapter owns the conversion to
25
+ * `<@U…>` — Slack only links and notifies on the raw user id. Lookup covers
26
+ * userName and displayName case-insensitively; native-id mentions pass
27
+ * through, and unknown names stay verbatim rather than guessing.
28
+ */
29
+ export function resolveSlackMentions(source, users) {
30
+ if (!source.includes("<@"))
31
+ return source;
32
+ const list = [...users];
33
+ const byName = new Map();
34
+ for (const user of list) {
35
+ if (user.userName)
36
+ byName.set(user.userName.toLowerCase(), user.id);
37
+ }
38
+ // Display names never shadow a userName held by someone else.
39
+ for (const user of list) {
40
+ const display = user.displayName?.toLowerCase();
41
+ if (display && !byName.has(display))
42
+ byName.set(display, user.id);
43
+ }
44
+ return source.replace(MENTION_PATTERN, (mention, name) => {
45
+ if (SLACK_USER_ID_PATTERN.test(name))
46
+ return mention;
47
+ const id = byName.get(name.trim().replace(/^@/, "").toLowerCase());
48
+ return id ? `<@${id}>` : mention;
49
+ });
50
+ }
17
51
  function normalizeMarkdownTables(source) {
18
52
  return source
19
53
  .split("\n")
@@ -1 +1 @@
1
- {"version":3,"file":"blocks.js","sourceRoot":"","sources":["../../../src/adapters/slack/blocks.ts"],"names":[],"mappings":"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","sourcesContent":["import MarkdownIt from \"markdown-it\";\nimport type Token from \"markdown-it/lib/token.mjs\";\nimport type { KnownBlock } from \"@slack/types\";\n\n// Parser is used only to locate tables and derive plain-text fallback.\n// Prose is never re-serialized from tokens: it is sliced verbatim from the\n// source and handed to Slack as a native `markdown` block, so Slack owns\n// all prose rendering (same renderer as the markdown_text streaming API).\nconst markdown = new MarkdownIt({ html: false });\n\nconst MAX_BLOCKS = 50;\n// Slack rejects messages whose markdown block text exceeds 12k (msg_too_long).\nconst MARKDOWN_TEXT_LIMIT = 12000;\nconst FIELD_TEXT_LIMIT = 2000;\n\n// Legacy Slack-style links (<url|label>) predate the standard-GFM response\n// source contract; system producers may still emit them.\nconst LEGACY_MRKDWN_LINK_PATTERN = /<(https?:\\/\\/[^<>|\\s]+)\\|([^<>\\n]+)>/g;\n\nfunction convertLegacyMrkdwnLinks(source: string): string {\n return source.replace(LEGACY_MRKDWN_LINK_PATTERN, \"[$2]($1)\");\n}\n\nfunction normalizeMarkdownTables(source: string): string {\n return source\n .split(\"\\n\")\n .map((line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"|\") || !trimmed.endsWith(\"|\")) return line;\n if (!/^[|+\\-:\\s]+$/.test(trimmed) || !trimmed.includes(\"+\")) return line;\n return line.replaceAll(\"+\", \"|\");\n })\n .join(\"\\n\");\n}\n\nfunction inlinePlainText(tokens: Token[] | null | undefined): string {\n if (!tokens) return \"\";\n let text = \"\";\n for (const token of tokens) {\n if (token.type === \"text\" || token.type === \"code_inline\") text += token.content;\n else if (token.type === \"softbreak\" || token.type === \"hardbreak\") text += \"\\n\";\n else if (token.children) text += inlinePlainText(token.children);\n }\n return text;\n}\n\nfunction buildTableBlock(headers: string[], rows: string[][]): KnownBlock {\n const hasIndex = headers[0] === \"#\";\n const tableHeaders = hasIndex ? headers : [\"#\", ...headers];\n const tableRows = hasIndex\n ? rows\n : rows.map((row, rowNumber) => [String(rowNumber + 1)].concat(row));\n return {\n type: \"table\",\n rows: [tableHeaders, ...tableRows].map((row) =>\n row.map((cell) => ({ type: \"raw_text\", text: (cell || \" \").slice(0, FIELD_TEXT_LIMIT) })),\n ),\n column_settings: tableHeaders.map(() => ({ is_wrapped: true })),\n } as KnownBlock;\n}\n\ninterface ParsedTable {\n block: KnownBlock;\n fallback: string;\n startLine: number;\n endLine: number;\n}\n\nfunction parseTable(tokens: Token[], index: number): { table: ParsedTable; next: number } | null {\n const open = tokens[index];\n if (open?.type !== \"table_open\" || !open.map) return null;\n\n const headers: string[] = [];\n const rows: string[][] = [];\n let currentRow: string[] | null = null;\n let inHead = false;\n let i = index + 1;\n\n for (; i < tokens.length && tokens[i].type !== \"table_close\"; i++) {\n const token = tokens[i];\n if (token.type === \"thead_open\") inHead = true;\n else if (token.type === \"thead_close\") inHead = false;\n else if (token.type === \"tr_open\") currentRow = [];\n else if (token.type === \"tr_close\" && currentRow) {\n if (inHead) headers.push(...currentRow);\n else rows.push(currentRow);\n currentRow = null;\n } else if (token.type === \"inline\" && currentRow) {\n currentRow.push(inlinePlainText(token.children) || token.content);\n }\n }\n\n if (!headers.length || !rows.length) return null;\n\n const fallback = [headers.join(\" | \"), ...rows.map((row) => row.join(\" | \"))].join(\"\\n\");\n const endLine = tokens[i]?.map?.[1] ?? open.map[1];\n return {\n table: {\n block: buildTableBlock(headers, rows),\n fallback,\n startLine: open.map[0],\n endLine,\n },\n next: i,\n };\n}\n\n/** Split prose into chunks under the markdown block limit, preferring\n * paragraph boundaries, then line boundaries, then a hard slice. */\nfunction splitProse(text: string): string[] {\n if (text.length <= MARKDOWN_TEXT_LIMIT) return [text];\n const chunks: string[] = [];\n let rest = text;\n while (rest.length > MARKDOWN_TEXT_LIMIT) {\n const window = rest.slice(0, MARKDOWN_TEXT_LIMIT);\n let cut = window.lastIndexOf(\"\\n\\n\");\n if (cut <= 0) cut = window.lastIndexOf(\"\\n\");\n if (cut <= 0) cut = MARKDOWN_TEXT_LIMIT;\n chunks.push(rest.slice(0, cut));\n rest = rest.slice(cut);\n }\n if (rest.trim()) chunks.push(rest);\n return chunks;\n}\n\nfunction pushMarkdown(blocks: KnownBlock[], prose: string): void {\n const trimmed = prose.trim();\n if (!trimmed) return;\n for (const chunk of splitProse(trimmed)) {\n if (blocks.length >= MAX_BLOCKS) return;\n const text = chunk.trim();\n if (text) blocks.push({ type: \"markdown\", text } as KnownBlock);\n }\n}\n\nfunction plainTextFallback(tokens: Token[]): string {\n const parts: string[] = [];\n for (const token of tokens) {\n if (token.type === \"inline\") parts.push(inlinePlainText(token.children) || token.content);\n else if (token.type === \"fence\" || token.type === \"code_block\")\n parts.push(token.content.trimEnd());\n }\n return parts.filter(Boolean).join(\"\\n\");\n}\n\nexport function renderSlackBlocks(source: string): { text: string; blocks: KnownBlock[] } {\n const normalized = normalizeMarkdownTables(convertLegacyMrkdwnLinks(source));\n const tokens = markdown.parse(normalized, {});\n const lines = normalized.split(\"\\n\");\n\n const tables: ParsedTable[] = [];\n for (let i = 0; i < tokens.length; i++) {\n const parsed = parseTable(tokens, i);\n if (parsed) {\n tables.push(parsed.table);\n i = parsed.next;\n }\n }\n\n const blocks: KnownBlock[] = [];\n const fallback: string[] = [];\n let cursor = 0;\n for (const table of tables) {\n const prose = lines.slice(cursor, table.startLine).join(\"\\n\");\n pushMarkdown(blocks, prose);\n if (prose.trim()) fallback.push(plainTextFallback(markdown.parse(prose, {})));\n if (blocks.length < MAX_BLOCKS) {\n blocks.push(table.block);\n fallback.push(table.fallback);\n }\n cursor = table.endLine;\n }\n const trailingProse = lines.slice(cursor).join(\"\\n\");\n pushMarkdown(blocks, trailingProse);\n if (trailingProse.trim()) fallback.push(plainTextFallback(markdown.parse(trailingProse, {})));\n\n return {\n text: fallback.filter(Boolean).join(\"\\n\\n\") || normalized,\n blocks,\n };\n}\n"]}
1
+ {"version":3,"file":"blocks.js","sourceRoot":"","sources":["../../../src/adapters/slack/blocks.ts"],"names":[],"mappings":"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","sourcesContent":["import MarkdownIt from \"markdown-it\";\nimport type Token from \"markdown-it/lib/token.mjs\";\nimport type { KnownBlock } from \"@slack/types\";\n\n// Parser is used only to locate tables and derive plain-text fallback.\n// Prose is never re-serialized from tokens: it is sliced verbatim from the\n// source and handed to Slack as a native `markdown` block, so Slack owns\n// all prose rendering (same renderer as the markdown_text streaming API).\nconst markdown = new MarkdownIt({ html: false });\n\nconst MAX_BLOCKS = 50;\n// Slack rejects messages whose markdown block text exceeds 12k (msg_too_long).\nconst MARKDOWN_TEXT_LIMIT = 12000;\nconst FIELD_TEXT_LIMIT = 2000;\n\n// Legacy Slack-style links (<url|label>) predate the standard-GFM response\n// source contract; system producers may still emit them.\nconst LEGACY_MRKDWN_LINK_PATTERN = /<(https?:\\/\\/[^<>|\\s]+)\\|([^<>\\n]+)>/g;\n\nfunction convertLegacyMrkdwnLinks(source: string): string {\n return source.replace(LEGACY_MRKDWN_LINK_PATTERN, \"[$2]($1)\");\n}\n\n// Slack user/bot-user ids: U/W prefix. Already-native mentions pass through.\nconst SLACK_USER_ID_PATTERN = /^[UW][A-Z0-9]{2,}$/;\nconst MENTION_PATTERN = /<@([^<>\\n]+)>/g;\n\n/**\n * Resolve response-source mentions to Slack's native form.\n *\n * The response source is platform-neutral: the model writes `<@userName>`\n * from the prompt's Users table, and the adapter owns the conversion to\n * `<@U…>` — Slack only links and notifies on the raw user id. Lookup covers\n * userName and displayName case-insensitively; native-id mentions pass\n * through, and unknown names stay verbatim rather than guessing.\n */\nexport function resolveSlackMentions(\n source: string,\n users: Iterable<{ id: string; userName: string; displayName: string }>,\n): string {\n if (!source.includes(\"<@\")) return source;\n const list = [...users];\n const byName = new Map<string, string>();\n for (const user of list) {\n if (user.userName) byName.set(user.userName.toLowerCase(), user.id);\n }\n // Display names never shadow a userName held by someone else.\n for (const user of list) {\n const display = user.displayName?.toLowerCase();\n if (display && !byName.has(display)) byName.set(display, user.id);\n }\n return source.replace(MENTION_PATTERN, (mention, name: string) => {\n if (SLACK_USER_ID_PATTERN.test(name)) return mention;\n const id = byName.get(name.trim().replace(/^@/, \"\").toLowerCase());\n return id ? `<@${id}>` : mention;\n });\n}\n\nfunction normalizeMarkdownTables(source: string): string {\n return source\n .split(\"\\n\")\n .map((line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"|\") || !trimmed.endsWith(\"|\")) return line;\n if (!/^[|+\\-:\\s]+$/.test(trimmed) || !trimmed.includes(\"+\")) return line;\n return line.replaceAll(\"+\", \"|\");\n })\n .join(\"\\n\");\n}\n\nfunction inlinePlainText(tokens: Token[] | null | undefined): string {\n if (!tokens) return \"\";\n let text = \"\";\n for (const token of tokens) {\n if (token.type === \"text\" || token.type === \"code_inline\") text += token.content;\n else if (token.type === \"softbreak\" || token.type === \"hardbreak\") text += \"\\n\";\n else if (token.children) text += inlinePlainText(token.children);\n }\n return text;\n}\n\nfunction buildTableBlock(headers: string[], rows: string[][]): KnownBlock {\n const hasIndex = headers[0] === \"#\";\n const tableHeaders = hasIndex ? headers : [\"#\", ...headers];\n const tableRows = hasIndex\n ? rows\n : rows.map((row, rowNumber) => [String(rowNumber + 1)].concat(row));\n return {\n type: \"table\",\n rows: [tableHeaders, ...tableRows].map((row) =>\n row.map((cell) => ({ type: \"raw_text\", text: (cell || \" \").slice(0, FIELD_TEXT_LIMIT) })),\n ),\n column_settings: tableHeaders.map(() => ({ is_wrapped: true })),\n } as KnownBlock;\n}\n\ninterface ParsedTable {\n block: KnownBlock;\n fallback: string;\n startLine: number;\n endLine: number;\n}\n\nfunction parseTable(tokens: Token[], index: number): { table: ParsedTable; next: number } | null {\n const open = tokens[index];\n if (open?.type !== \"table_open\" || !open.map) return null;\n\n const headers: string[] = [];\n const rows: string[][] = [];\n let currentRow: string[] | null = null;\n let inHead = false;\n let i = index + 1;\n\n for (; i < tokens.length && tokens[i].type !== \"table_close\"; i++) {\n const token = tokens[i];\n if (token.type === \"thead_open\") inHead = true;\n else if (token.type === \"thead_close\") inHead = false;\n else if (token.type === \"tr_open\") currentRow = [];\n else if (token.type === \"tr_close\" && currentRow) {\n if (inHead) headers.push(...currentRow);\n else rows.push(currentRow);\n currentRow = null;\n } else if (token.type === \"inline\" && currentRow) {\n currentRow.push(inlinePlainText(token.children) || token.content);\n }\n }\n\n if (!headers.length || !rows.length) return null;\n\n const fallback = [headers.join(\" | \"), ...rows.map((row) => row.join(\" | \"))].join(\"\\n\");\n const endLine = tokens[i]?.map?.[1] ?? open.map[1];\n return {\n table: {\n block: buildTableBlock(headers, rows),\n fallback,\n startLine: open.map[0],\n endLine,\n },\n next: i,\n };\n}\n\n/** Split prose into chunks under the markdown block limit, preferring\n * paragraph boundaries, then line boundaries, then a hard slice. */\nfunction splitProse(text: string): string[] {\n if (text.length <= MARKDOWN_TEXT_LIMIT) return [text];\n const chunks: string[] = [];\n let rest = text;\n while (rest.length > MARKDOWN_TEXT_LIMIT) {\n const window = rest.slice(0, MARKDOWN_TEXT_LIMIT);\n let cut = window.lastIndexOf(\"\\n\\n\");\n if (cut <= 0) cut = window.lastIndexOf(\"\\n\");\n if (cut <= 0) cut = MARKDOWN_TEXT_LIMIT;\n chunks.push(rest.slice(0, cut));\n rest = rest.slice(cut);\n }\n if (rest.trim()) chunks.push(rest);\n return chunks;\n}\n\nfunction pushMarkdown(blocks: KnownBlock[], prose: string): void {\n const trimmed = prose.trim();\n if (!trimmed) return;\n for (const chunk of splitProse(trimmed)) {\n if (blocks.length >= MAX_BLOCKS) return;\n const text = chunk.trim();\n if (text) blocks.push({ type: \"markdown\", text } as KnownBlock);\n }\n}\n\nfunction plainTextFallback(tokens: Token[]): string {\n const parts: string[] = [];\n for (const token of tokens) {\n if (token.type === \"inline\") parts.push(inlinePlainText(token.children) || token.content);\n else if (token.type === \"fence\" || token.type === \"code_block\")\n parts.push(token.content.trimEnd());\n }\n return parts.filter(Boolean).join(\"\\n\");\n}\n\nexport function renderSlackBlocks(source: string): { text: string; blocks: KnownBlock[] } {\n const normalized = normalizeMarkdownTables(convertLegacyMrkdwnLinks(source));\n const tokens = markdown.parse(normalized, {});\n const lines = normalized.split(\"\\n\");\n\n const tables: ParsedTable[] = [];\n for (let i = 0; i < tokens.length; i++) {\n const parsed = parseTable(tokens, i);\n if (parsed) {\n tables.push(parsed.table);\n i = parsed.next;\n }\n }\n\n const blocks: KnownBlock[] = [];\n const fallback: string[] = [];\n let cursor = 0;\n for (const table of tables) {\n const prose = lines.slice(cursor, table.startLine).join(\"\\n\");\n pushMarkdown(blocks, prose);\n if (prose.trim()) fallback.push(plainTextFallback(markdown.parse(prose, {})));\n if (blocks.length < MAX_BLOCKS) {\n blocks.push(table.block);\n fallback.push(table.fallback);\n }\n cursor = table.endLine;\n }\n const trailingProse = lines.slice(cursor).join(\"\\n\");\n pushMarkdown(blocks, trailingProse);\n if (trailingProse.trim()) fallback.push(plainTextFallback(markdown.parse(trailingProse, {})));\n\n return {\n text: fallback.filter(Boolean).join(\"\\n\\n\") || normalized,\n blocks,\n };\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { type MessagingBot, type ConversationEvent, type MessagingEventHandler, type MessagingInfo } from "../../adapter.js";
2
+ import { type Workspace } from "../../office/index.js";
2
3
  import type { EventsWatcher } from "../../events.js";
3
- import type { ChannelStore } from "../../store.js";
4
4
  import type { SlackChannel, SlackUser } from "./types.js";
5
5
  /**
6
6
  * Build a Slack context block whose text is capped at the mrkdwn limit.
@@ -12,8 +12,8 @@ export declare class SlackMessagingBot implements MessagingBot {
12
12
  private socketClient;
13
13
  private webClient;
14
14
  private handler;
15
- private workingDir;
16
- private store;
15
+ private workspace;
16
+ private botToken;
17
17
  private botUserId;
18
18
  private botId;
19
19
  private teamId;
@@ -23,15 +23,14 @@ export declare class SlackMessagingBot implements MessagingBot {
23
23
  private channels;
24
24
  private queues;
25
25
  private eventsWatcher;
26
- /** Host office dir for a Slack conversation (see officeDirName). */
26
+ /** Host office dir for a Slack conversation. */
27
27
  private conversationDir;
28
28
  private resolveReplyMode;
29
29
  private createContext;
30
30
  constructor(handler: MessagingEventHandler, config: {
31
31
  appToken: string;
32
32
  botToken: string;
33
- workingDir: string;
34
- store: ChannelStore;
33
+ workspace: Workspace;
35
34
  });
36
35
  setEventsWatcher(watcher: EventsWatcher): void;
37
36
  start(): Promise<void>;
@@ -40,6 +39,12 @@ export declare class SlackMessagingBot implements MessagingBot {
40
39
  getAllUsers(): SlackUser[];
41
40
  getAllChannels(): SlackChannel[];
42
41
  private stripOwnMention;
42
+ /**
43
+ * Response-source `<@userName>` mentions become native `<@U…>` here — the
44
+ * one conversion every outgoing response path funnels through. Slack only
45
+ * links and notifies on raw user ids.
46
+ */
47
+ private resolveMentions;
43
48
  postMessage(channel: string, text: string): Promise<string>;
44
49
  addReaction(channel: string, messageTs: string, emoji: string): Promise<void>;
45
50
  postEphemeral(channel: string, user: string, text: string, threadTs?: string): Promise<void>;
@@ -92,6 +97,14 @@ export declare class SlackMessagingBot implements MessagingBot {
92
97
  private handleAppHomeOpened;
93
98
  private handleBlockAction;
94
99
  private handleSlackInteraction;
100
+ /**
101
+ * Download Slack message files into the office's attachments directory.
102
+ * The Slack contract is all-or-error: any failed download throws after the
103
+ * successful ones are on disk, so callers still log the message text.
104
+ */
105
+ private processAttachments;
106
+ /** Authorized download with retry; Slack file URLs require the bot token. */
107
+ private downloadSlackFile;
95
108
  /**
96
109
  * Log a user message to log.jsonl after attachments are ready.
97
110
  */