claude-code-swarm 0.3.7 → 0.3.9

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 (1357) hide show
  1. package/.claude/settings.json +1 -0
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/CLAUDE.md +44 -1
  5. package/package.json +5 -5
  6. package/scripts/bootstrap-bg.mjs +31 -0
  7. package/scripts/bootstrap.mjs +30 -4
  8. package/scripts/dev-link.mjs +179 -0
  9. package/scripts/map-hook.mjs +35 -44
  10. package/scripts/map-sidecar.mjs +163 -28
  11. package/src/__tests__/bootstrap.test.mjs +227 -237
  12. package/src/__tests__/config.test.mjs +275 -1
  13. package/src/__tests__/e2e-reconnection.test.mjs +537 -0
  14. package/src/__tests__/helpers.mjs +6 -0
  15. package/src/__tests__/index.test.mjs +4 -0
  16. package/src/__tests__/log.test.mjs +510 -0
  17. package/src/__tests__/map-connection.test.mjs +7 -0
  18. package/src/__tests__/paths.test.mjs +1 -1
  19. package/src/bootstrap.mjs +129 -94
  20. package/src/config.mjs +36 -9
  21. package/src/index.mjs +4 -0
  22. package/src/log.mjs +152 -0
  23. package/src/map-connection.mjs +40 -9
  24. package/src/mesh-connection.mjs +8 -12
  25. package/src/opentasks-client.mjs +5 -2
  26. package/src/paths.mjs +11 -8
  27. package/src/roles.mjs +4 -3
  28. package/src/sessionlog.mjs +38 -2
  29. package/src/sidecar-client.mjs +13 -2
  30. package/src/sidecar-server.mjs +16 -26
  31. package/src/skilltree-client.mjs +4 -1
  32. package/src/swarmkit-resolver.mjs +17 -1
  33. package/src/template.mjs +4 -1
  34. package/vitest.config.mjs +4 -0
  35. package/references/agent-inbox/CLAUDE.md +0 -151
  36. package/references/agent-inbox/README.md +0 -238
  37. package/references/agent-inbox/docs/CLAUDE-CODE-SWARM-PROPOSAL.md +0 -137
  38. package/references/agent-inbox/docs/DESIGN.md +0 -1156
  39. package/references/agent-inbox/hooks/inbox-hook.mjs +0 -119
  40. package/references/agent-inbox/hooks/register-hook.mjs +0 -69
  41. package/references/agent-inbox/package-lock.json +0 -3347
  42. package/references/agent-inbox/package.json +0 -58
  43. package/references/agent-inbox/rules/agent-inbox.md +0 -78
  44. package/references/agent-inbox/src/federation/address.ts +0 -61
  45. package/references/agent-inbox/src/federation/connection-manager.ts +0 -573
  46. package/references/agent-inbox/src/federation/delivery-queue.ts +0 -222
  47. package/references/agent-inbox/src/federation/index.ts +0 -6
  48. package/references/agent-inbox/src/federation/routing-engine.ts +0 -188
  49. package/references/agent-inbox/src/federation/trust.ts +0 -71
  50. package/references/agent-inbox/src/index.ts +0 -404
  51. package/references/agent-inbox/src/ipc/ipc-server.ts +0 -265
  52. package/references/agent-inbox/src/jsonrpc/mail-server.ts +0 -382
  53. package/references/agent-inbox/src/map/map-client.ts +0 -414
  54. package/references/agent-inbox/src/mcp/mcp-proxy.ts +0 -326
  55. package/references/agent-inbox/src/mcp/mcp-server.ts +0 -272
  56. package/references/agent-inbox/src/mesh/delivery-bridge.ts +0 -110
  57. package/references/agent-inbox/src/mesh/mesh-connector.ts +0 -41
  58. package/references/agent-inbox/src/mesh/mesh-transport.ts +0 -157
  59. package/references/agent-inbox/src/mesh/type-mapper.ts +0 -239
  60. package/references/agent-inbox/src/push/notifier.ts +0 -233
  61. package/references/agent-inbox/src/registry/warm-registry.ts +0 -255
  62. package/references/agent-inbox/src/router/message-router.ts +0 -175
  63. package/references/agent-inbox/src/storage/interface.ts +0 -48
  64. package/references/agent-inbox/src/storage/memory.ts +0 -145
  65. package/references/agent-inbox/src/storage/sqlite.ts +0 -671
  66. package/references/agent-inbox/src/traceability/traceability.ts +0 -183
  67. package/references/agent-inbox/src/types.ts +0 -329
  68. package/references/agent-inbox/test/federation/address.test.ts +0 -101
  69. package/references/agent-inbox/test/federation/connection-manager.test.ts +0 -546
  70. package/references/agent-inbox/test/federation/delivery-queue.test.ts +0 -159
  71. package/references/agent-inbox/test/federation/integration.test.ts +0 -857
  72. package/references/agent-inbox/test/federation/routing-engine.test.ts +0 -117
  73. package/references/agent-inbox/test/federation/sdk-integration.test.ts +0 -744
  74. package/references/agent-inbox/test/federation/trust.test.ts +0 -89
  75. package/references/agent-inbox/test/ipc-jsonrpc.test.ts +0 -113
  76. package/references/agent-inbox/test/ipc-new-commands.test.ts +0 -200
  77. package/references/agent-inbox/test/ipc-server.test.ts +0 -197
  78. package/references/agent-inbox/test/mail-server.test.ts +0 -285
  79. package/references/agent-inbox/test/map-client.test.ts +0 -408
  80. package/references/agent-inbox/test/mcp-proxy.test.ts +0 -191
  81. package/references/agent-inbox/test/mesh/delivery-bridge.test.ts +0 -178
  82. package/references/agent-inbox/test/mesh/e2e-mesh.test.ts +0 -527
  83. package/references/agent-inbox/test/mesh/e2e-real-meshpeer.test.ts +0 -629
  84. package/references/agent-inbox/test/mesh/federation-mesh.test.ts +0 -269
  85. package/references/agent-inbox/test/mesh/mesh-connector.test.ts +0 -66
  86. package/references/agent-inbox/test/mesh/mesh-transport.test.ts +0 -191
  87. package/references/agent-inbox/test/mesh/meshpeer-integration.test.ts +0 -442
  88. package/references/agent-inbox/test/mesh/mock-mesh.ts +0 -125
  89. package/references/agent-inbox/test/mesh/mock-meshpeer.ts +0 -266
  90. package/references/agent-inbox/test/mesh/type-mapper.test.ts +0 -226
  91. package/references/agent-inbox/test/message-router.test.ts +0 -184
  92. package/references/agent-inbox/test/push-notifier.test.ts +0 -139
  93. package/references/agent-inbox/test/registry/warm-registry.test.ts +0 -171
  94. package/references/agent-inbox/test/sqlite-prefix.test.ts +0 -192
  95. package/references/agent-inbox/test/sqlite-storage.test.ts +0 -243
  96. package/references/agent-inbox/test/storage.test.ts +0 -196
  97. package/references/agent-inbox/test/traceability.test.ts +0 -123
  98. package/references/agent-inbox/test/wake.test.ts +0 -330
  99. package/references/agent-inbox/tsconfig.json +0 -20
  100. package/references/agent-inbox/tsup.config.ts +0 -10
  101. package/references/agent-inbox/vitest.config.ts +0 -8
  102. package/references/minimem/.claude/settings.json +0 -7
  103. package/references/minimem/.sudocode/issues.jsonl +0 -18
  104. package/references/minimem/.sudocode/specs.jsonl +0 -1
  105. package/references/minimem/CLAUDE.md +0 -329
  106. package/references/minimem/README.md +0 -565
  107. package/references/minimem/claude-plugin/.claude-plugin/plugin.json +0 -10
  108. package/references/minimem/claude-plugin/.mcp.json +0 -7
  109. package/references/minimem/claude-plugin/README.md +0 -158
  110. package/references/minimem/claude-plugin/commands/recall.md +0 -47
  111. package/references/minimem/claude-plugin/commands/remember.md +0 -41
  112. package/references/minimem/claude-plugin/hooks/__tests__/hooks.test.ts +0 -272
  113. package/references/minimem/claude-plugin/hooks/hooks.json +0 -27
  114. package/references/minimem/claude-plugin/hooks/session-end.sh +0 -86
  115. package/references/minimem/claude-plugin/hooks/session-start.sh +0 -85
  116. package/references/minimem/claude-plugin/skills/memory/SKILL.md +0 -108
  117. package/references/minimem/media/banner.png +0 -0
  118. package/references/minimem/package-lock.json +0 -5373
  119. package/references/minimem/package.json +0 -76
  120. package/references/minimem/scripts/postbuild.js +0 -49
  121. package/references/minimem/src/__tests__/edge-cases.test.ts +0 -371
  122. package/references/minimem/src/__tests__/errors.test.ts +0 -265
  123. package/references/minimem/src/__tests__/helpers.ts +0 -199
  124. package/references/minimem/src/__tests__/internal.test.ts +0 -407
  125. package/references/minimem/src/__tests__/knowledge-frontmatter.test.ts +0 -148
  126. package/references/minimem/src/__tests__/knowledge.test.ts +0 -148
  127. package/references/minimem/src/__tests__/minimem.integration.test.ts +0 -1127
  128. package/references/minimem/src/__tests__/session.test.ts +0 -190
  129. package/references/minimem/src/cli/__tests__/commands.test.ts +0 -760
  130. package/references/minimem/src/cli/__tests__/contained-layout.test.ts +0 -286
  131. package/references/minimem/src/cli/commands/__tests__/conflicts.test.ts +0 -141
  132. package/references/minimem/src/cli/commands/append.ts +0 -76
  133. package/references/minimem/src/cli/commands/config.ts +0 -262
  134. package/references/minimem/src/cli/commands/conflicts.ts +0 -415
  135. package/references/minimem/src/cli/commands/daemon.ts +0 -169
  136. package/references/minimem/src/cli/commands/index.ts +0 -12
  137. package/references/minimem/src/cli/commands/init.ts +0 -166
  138. package/references/minimem/src/cli/commands/mcp.ts +0 -221
  139. package/references/minimem/src/cli/commands/push-pull.ts +0 -213
  140. package/references/minimem/src/cli/commands/search.ts +0 -223
  141. package/references/minimem/src/cli/commands/status.ts +0 -84
  142. package/references/minimem/src/cli/commands/store.ts +0 -189
  143. package/references/minimem/src/cli/commands/sync-init.ts +0 -290
  144. package/references/minimem/src/cli/commands/sync.ts +0 -70
  145. package/references/minimem/src/cli/commands/upsert.ts +0 -197
  146. package/references/minimem/src/cli/config.ts +0 -611
  147. package/references/minimem/src/cli/index.ts +0 -299
  148. package/references/minimem/src/cli/shared.ts +0 -189
  149. package/references/minimem/src/cli/sync/__tests__/central.test.ts +0 -152
  150. package/references/minimem/src/cli/sync/__tests__/conflicts.test.ts +0 -209
  151. package/references/minimem/src/cli/sync/__tests__/daemon.test.ts +0 -118
  152. package/references/minimem/src/cli/sync/__tests__/detection.test.ts +0 -207
  153. package/references/minimem/src/cli/sync/__tests__/integration.test.ts +0 -476
  154. package/references/minimem/src/cli/sync/__tests__/registry.test.ts +0 -363
  155. package/references/minimem/src/cli/sync/__tests__/state.test.ts +0 -255
  156. package/references/minimem/src/cli/sync/__tests__/validation.test.ts +0 -193
  157. package/references/minimem/src/cli/sync/__tests__/watcher.test.ts +0 -178
  158. package/references/minimem/src/cli/sync/central.ts +0 -292
  159. package/references/minimem/src/cli/sync/conflicts.ts +0 -205
  160. package/references/minimem/src/cli/sync/daemon.ts +0 -407
  161. package/references/minimem/src/cli/sync/detection.ts +0 -138
  162. package/references/minimem/src/cli/sync/index.ts +0 -107
  163. package/references/minimem/src/cli/sync/operations.ts +0 -373
  164. package/references/minimem/src/cli/sync/registry.ts +0 -279
  165. package/references/minimem/src/cli/sync/state.ts +0 -358
  166. package/references/minimem/src/cli/sync/validation.ts +0 -206
  167. package/references/minimem/src/cli/sync/watcher.ts +0 -237
  168. package/references/minimem/src/cli/version.ts +0 -34
  169. package/references/minimem/src/core/index.ts +0 -9
  170. package/references/minimem/src/core/indexer.ts +0 -628
  171. package/references/minimem/src/core/searcher.ts +0 -221
  172. package/references/minimem/src/db/schema.ts +0 -183
  173. package/references/minimem/src/db/sqlite-vec.ts +0 -24
  174. package/references/minimem/src/embeddings/__tests__/embeddings.test.ts +0 -431
  175. package/references/minimem/src/embeddings/batch-gemini.ts +0 -392
  176. package/references/minimem/src/embeddings/batch-openai.ts +0 -409
  177. package/references/minimem/src/embeddings/embeddings.ts +0 -434
  178. package/references/minimem/src/index.ts +0 -132
  179. package/references/minimem/src/internal.ts +0 -299
  180. package/references/minimem/src/minimem.ts +0 -1291
  181. package/references/minimem/src/search/__tests__/hybrid.test.ts +0 -247
  182. package/references/minimem/src/search/graph.ts +0 -234
  183. package/references/minimem/src/search/hybrid.ts +0 -151
  184. package/references/minimem/src/search/search.ts +0 -256
  185. package/references/minimem/src/server/__tests__/mcp.test.ts +0 -347
  186. package/references/minimem/src/server/__tests__/tools.test.ts +0 -364
  187. package/references/minimem/src/server/mcp.ts +0 -326
  188. package/references/minimem/src/server/tools.ts +0 -720
  189. package/references/minimem/src/session.ts +0 -460
  190. package/references/minimem/src/store/__tests__/manifest.test.ts +0 -177
  191. package/references/minimem/src/store/__tests__/materialize.test.ts +0 -52
  192. package/references/minimem/src/store/__tests__/store-graph.test.ts +0 -228
  193. package/references/minimem/src/store/index.ts +0 -27
  194. package/references/minimem/src/store/manifest.ts +0 -203
  195. package/references/minimem/src/store/materialize.ts +0 -185
  196. package/references/minimem/src/store/store-graph.ts +0 -252
  197. package/references/minimem/tsconfig.json +0 -19
  198. package/references/minimem/tsup.config.ts +0 -26
  199. package/references/minimem/vitest.config.ts +0 -29
  200. package/references/multi-agent-protocol/.sudocode/issues.jsonl +0 -120
  201. package/references/multi-agent-protocol/.sudocode/specs.jsonl +0 -15
  202. package/references/multi-agent-protocol/LICENSE +0 -21
  203. package/references/multi-agent-protocol/README.md +0 -113
  204. package/references/multi-agent-protocol/docs/00-design-specification.md +0 -496
  205. package/references/multi-agent-protocol/docs/01-open-questions.md +0 -1050
  206. package/references/multi-agent-protocol/docs/02-wire-protocol.md +0 -296
  207. package/references/multi-agent-protocol/docs/03-streaming-semantics.md +0 -252
  208. package/references/multi-agent-protocol/docs/04-error-handling.md +0 -231
  209. package/references/multi-agent-protocol/docs/05-connection-model.md +0 -244
  210. package/references/multi-agent-protocol/docs/06-visibility-permissions.md +0 -243
  211. package/references/multi-agent-protocol/docs/07-federation.md +0 -335
  212. package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +0 -253
  213. package/references/multi-agent-protocol/docs/09-authentication.md +0 -748
  214. package/references/multi-agent-protocol/docs/10-environment-awareness.md +0 -242
  215. package/references/multi-agent-protocol/docs/10-mail-protocol.md +0 -553
  216. package/references/multi-agent-protocol/docs/11-anp-inspired-improvements.md +0 -1079
  217. package/references/multi-agent-protocol/docs/11-trajectory-protocol.md +0 -292
  218. package/references/multi-agent-protocol/docs/12-anp-implementation-plan.md +0 -641
  219. package/references/multi-agent-protocol/docs/agent-iam-integration.md +0 -877
  220. package/references/multi-agent-protocol/docs/agentic-mesh-integration-draft.md +0 -459
  221. package/references/multi-agent-protocol/docs/git-transport-draft.md +0 -251
  222. package/references/multi-agent-protocol/docs-site/Gemfile +0 -22
  223. package/references/multi-agent-protocol/docs-site/README.md +0 -82
  224. package/references/multi-agent-protocol/docs-site/_config.yml +0 -91
  225. package/references/multi-agent-protocol/docs-site/_includes/head_custom.html +0 -20
  226. package/references/multi-agent-protocol/docs-site/_sass/color_schemes/map.scss +0 -42
  227. package/references/multi-agent-protocol/docs-site/_sass/custom/custom.scss +0 -34
  228. package/references/multi-agent-protocol/docs-site/examples/full-integration.md +0 -510
  229. package/references/multi-agent-protocol/docs-site/examples/index.md +0 -138
  230. package/references/multi-agent-protocol/docs-site/examples/simple-chat.md +0 -282
  231. package/references/multi-agent-protocol/docs-site/examples/task-queue.md +0 -399
  232. package/references/multi-agent-protocol/docs-site/getting-started/index.md +0 -98
  233. package/references/multi-agent-protocol/docs-site/getting-started/installation.md +0 -219
  234. package/references/multi-agent-protocol/docs-site/getting-started/overview.md +0 -172
  235. package/references/multi-agent-protocol/docs-site/getting-started/quickstart.md +0 -237
  236. package/references/multi-agent-protocol/docs-site/index.md +0 -136
  237. package/references/multi-agent-protocol/docs-site/protocol/authentication.md +0 -391
  238. package/references/multi-agent-protocol/docs-site/protocol/connection-model.md +0 -376
  239. package/references/multi-agent-protocol/docs-site/protocol/design.md +0 -284
  240. package/references/multi-agent-protocol/docs-site/protocol/error-handling.md +0 -312
  241. package/references/multi-agent-protocol/docs-site/protocol/federation.md +0 -449
  242. package/references/multi-agent-protocol/docs-site/protocol/index.md +0 -129
  243. package/references/multi-agent-protocol/docs-site/protocol/permissions.md +0 -398
  244. package/references/multi-agent-protocol/docs-site/protocol/streaming.md +0 -353
  245. package/references/multi-agent-protocol/docs-site/protocol/wire-protocol.md +0 -369
  246. package/references/multi-agent-protocol/docs-site/sdk/api/agent.md +0 -357
  247. package/references/multi-agent-protocol/docs-site/sdk/api/client.md +0 -380
  248. package/references/multi-agent-protocol/docs-site/sdk/api/index.md +0 -62
  249. package/references/multi-agent-protocol/docs-site/sdk/api/server.md +0 -453
  250. package/references/multi-agent-protocol/docs-site/sdk/api/types.md +0 -468
  251. package/references/multi-agent-protocol/docs-site/sdk/guides/agent.md +0 -375
  252. package/references/multi-agent-protocol/docs-site/sdk/guides/authentication.md +0 -405
  253. package/references/multi-agent-protocol/docs-site/sdk/guides/client.md +0 -352
  254. package/references/multi-agent-protocol/docs-site/sdk/guides/index.md +0 -89
  255. package/references/multi-agent-protocol/docs-site/sdk/guides/server.md +0 -360
  256. package/references/multi-agent-protocol/docs-site/sdk/guides/testing.md +0 -446
  257. package/references/multi-agent-protocol/docs-site/sdk/guides/transports.md +0 -363
  258. package/references/multi-agent-protocol/docs-site/sdk/index.md +0 -206
  259. package/references/multi-agent-protocol/package-lock.json +0 -4230
  260. package/references/multi-agent-protocol/package.json +0 -56
  261. package/references/multi-agent-protocol/schema/meta.json +0 -584
  262. package/references/multi-agent-protocol/schema/schema.json +0 -3067
  263. package/references/openhive/.claude/settings.json +0 -6
  264. package/references/openhive/.dockerignore +0 -54
  265. package/references/openhive/.github/workflows/docker.yml +0 -52
  266. package/references/openhive/.sudocode/issues.jsonl +0 -24
  267. package/references/openhive/.sudocode/specs.jsonl +0 -4
  268. package/references/openhive/CLAUDE.md +0 -88
  269. package/references/openhive/Dockerfile +0 -105
  270. package/references/openhive/README.md +0 -745
  271. package/references/openhive/bin/openhive.js +0 -6
  272. package/references/openhive/cloudbuild.yaml +0 -80
  273. package/references/openhive/deploy/cloud-run.sh +0 -106
  274. package/references/openhive/deploy/openhive.env.example +0 -80
  275. package/references/openhive/deploy/openhive.service +0 -91
  276. package/references/openhive/docker-compose.yml +0 -67
  277. package/references/openhive/docker-entrypoint.sh +0 -117
  278. package/references/openhive/docs/API_MIGRATION.md +0 -176
  279. package/references/openhive/docs/DEPLOYMENT.md +0 -847
  280. package/references/openhive/docs/DESIGN_v1.md +0 -489
  281. package/references/openhive/docs/DESIGN_v2.md +0 -564
  282. package/references/openhive/docs/HEADSCALE_HOSTING_SPEC.md +0 -513
  283. package/references/openhive/docs/HIVE_SYNC_DESIGN.md +0 -2362
  284. package/references/openhive/docs/HIVE_SYNC_IMPLEMENTATION_PLAN.md +0 -1169
  285. package/references/openhive/docs/HOSTING.md +0 -601
  286. package/references/openhive/docs/IMPLEMENTATION_PLAN.md +0 -428
  287. package/references/openhive/docs/LOCAL_SETUP.md +0 -506
  288. package/references/openhive/docs/MACRO_AGENT_ATLAS_EXTENSION.md +0 -351
  289. package/references/openhive/docs/MEMORY_BANK_SYNC_SPEC.md +0 -909
  290. package/references/openhive/docs/PLAN_v1.md +0 -471
  291. package/references/openhive/docs/PLAN_v2.md +0 -623
  292. package/references/openhive/docs/WEBSOCKET.md +0 -267
  293. package/references/openhive/docs/openswarm-bootstrap-token-spec.md +0 -240
  294. package/references/openhive/ecosystem.config.cjs +0 -76
  295. package/references/openhive/fly.toml +0 -63
  296. package/references/openhive/package-lock.json +0 -17640
  297. package/references/openhive/package.json +0 -128
  298. package/references/openhive/packages/openhive-types/package-lock.json +0 -1473
  299. package/references/openhive/packages/openhive-types/package.json +0 -42
  300. package/references/openhive/packages/openhive-types/src/index.ts +0 -36
  301. package/references/openhive/packages/openhive-types/src/map-coordination.ts +0 -92
  302. package/references/openhive/packages/openhive-types/src/map-session-sync.ts +0 -50
  303. package/references/openhive/packages/openhive-types/src/map-sync.ts +0 -68
  304. package/references/openhive/packages/openhive-types/tsconfig.json +0 -15
  305. package/references/openhive/packages/openhive-types/tsconfig.tsbuildinfo +0 -1
  306. package/references/openhive/packages/openhive-types/tsup.config.ts +0 -12
  307. package/references/openhive/railway.json +0 -13
  308. package/references/openhive/railway.toml +0 -24
  309. package/references/openhive/render.yaml +0 -51
  310. package/references/openhive/src/__tests__/auth.test.ts +0 -148
  311. package/references/openhive/src/__tests__/bridge/credentials.test.ts +0 -65
  312. package/references/openhive/src/__tests__/bridge/dal.test.ts +0 -279
  313. package/references/openhive/src/__tests__/bridge/inbound.test.ts +0 -349
  314. package/references/openhive/src/__tests__/bridge/manager.test.ts +0 -419
  315. package/references/openhive/src/__tests__/bridge/mentions.test.ts +0 -83
  316. package/references/openhive/src/__tests__/bridge/outbound.test.ts +0 -209
  317. package/references/openhive/src/__tests__/bridge/slack-adapter.test.ts +0 -276
  318. package/references/openhive/src/__tests__/cli.test.ts +0 -342
  319. package/references/openhive/src/__tests__/config.test.ts +0 -205
  320. package/references/openhive/src/__tests__/coordination/coordination.test.ts +0 -1072
  321. package/references/openhive/src/__tests__/coordination/cross-instance.test.ts +0 -540
  322. package/references/openhive/src/__tests__/coordination/e2e.test.ts +0 -780
  323. package/references/openhive/src/__tests__/data-dir.test.ts +0 -332
  324. package/references/openhive/src/__tests__/db.test.ts +0 -258
  325. package/references/openhive/src/__tests__/discovery.test.ts +0 -288
  326. package/references/openhive/src/__tests__/events/dal.test.ts +0 -371
  327. package/references/openhive/src/__tests__/events/dispatch.test.ts +0 -202
  328. package/references/openhive/src/__tests__/events/e2e.test.ts +0 -528
  329. package/references/openhive/src/__tests__/events/normalizers.test.ts +0 -263
  330. package/references/openhive/src/__tests__/events/router.test.ts +0 -314
  331. package/references/openhive/src/__tests__/events/routes.test.ts +0 -407
  332. package/references/openhive/src/__tests__/follows.test.ts +0 -328
  333. package/references/openhive/src/__tests__/helpers/test-dirs.ts +0 -44
  334. package/references/openhive/src/__tests__/ingest-keys.test.ts +0 -925
  335. package/references/openhive/src/__tests__/map/sync-client-content.test.ts +0 -288
  336. package/references/openhive/src/__tests__/map/sync-client.test.ts +0 -500
  337. package/references/openhive/src/__tests__/map/sync-listener.test.ts +0 -504
  338. package/references/openhive/src/__tests__/middleware/hostname-guard.test.ts +0 -73
  339. package/references/openhive/src/__tests__/migrations.test.ts +0 -260
  340. package/references/openhive/src/__tests__/opentasks/client.test.ts +0 -497
  341. package/references/openhive/src/__tests__/opentasks/discovery.test.ts +0 -283
  342. package/references/openhive/src/__tests__/opentasks/e2e.test.ts +0 -767
  343. package/references/openhive/src/__tests__/routes/agents.test.ts +0 -417
  344. package/references/openhive/src/__tests__/routes/opentasks-content.test.ts +0 -493
  345. package/references/openhive/src/__tests__/routes/resource-content.test.ts +0 -1741
  346. package/references/openhive/src/__tests__/sessions/adapters.test.ts +0 -524
  347. package/references/openhive/src/__tests__/sessions/routes.test.ts +0 -1053
  348. package/references/openhive/src/__tests__/sessions/storage.test.ts +0 -545
  349. package/references/openhive/src/__tests__/sessions/trajectory-checkpoints.test.ts +0 -349
  350. package/references/openhive/src/__tests__/sessions/trajectory-routes.test.ts +0 -290
  351. package/references/openhive/src/__tests__/swarm/config.test.ts +0 -125
  352. package/references/openhive/src/__tests__/swarm/credentials.test.ts +0 -254
  353. package/references/openhive/src/__tests__/swarm/dal.test.ts +0 -290
  354. package/references/openhive/src/__tests__/swarm/e2e.test.ts +0 -827
  355. package/references/openhive/src/__tests__/swarm/fixtures/exit-immediately.js +0 -3
  356. package/references/openhive/src/__tests__/swarm/fixtures/map-server.js +0 -147
  357. package/references/openhive/src/__tests__/swarm/fixtures/sleep-server.js +0 -52
  358. package/references/openhive/src/__tests__/swarm/local-provider.test.ts +0 -279
  359. package/references/openhive/src/__tests__/swarm/manager.test.ts +0 -305
  360. package/references/openhive/src/__tests__/swarm/routes.test.ts +0 -396
  361. package/references/openhive/src/__tests__/swarm/workspace.test.ts +0 -257
  362. package/references/openhive/src/__tests__/swarmhub/client.test.ts +0 -324
  363. package/references/openhive/src/__tests__/swarmhub/config.test.ts +0 -213
  364. package/references/openhive/src/__tests__/swarmhub/connector.test.ts +0 -581
  365. package/references/openhive/src/__tests__/swarmhub/routes.test.ts +0 -639
  366. package/references/openhive/src/__tests__/swarmhub/slack-client.test.ts +0 -164
  367. package/references/openhive/src/__tests__/swarmhub/slack-connector.test.ts +0 -164
  368. package/references/openhive/src/__tests__/swarmhub/slack-routes.test.ts +0 -373
  369. package/references/openhive/src/__tests__/swarmhub/webhook-handler.test.ts +0 -295
  370. package/references/openhive/src/__tests__/sync/resource-sync.test.ts +0 -1418
  371. package/references/openhive/src/__tests__/sync/sync.test.ts +0 -800
  372. package/references/openhive/src/api/index.ts +0 -65
  373. package/references/openhive/src/api/middleware/auth.ts +0 -227
  374. package/references/openhive/src/api/middleware/hostname-guard.ts +0 -38
  375. package/references/openhive/src/api/routes/admin.ts +0 -366
  376. package/references/openhive/src/api/routes/agents.ts +0 -223
  377. package/references/openhive/src/api/routes/auth.ts +0 -164
  378. package/references/openhive/src/api/routes/bridges.ts +0 -384
  379. package/references/openhive/src/api/routes/comments.ts +0 -294
  380. package/references/openhive/src/api/routes/coordination.ts +0 -312
  381. package/references/openhive/src/api/routes/events.ts +0 -158
  382. package/references/openhive/src/api/routes/federation.ts +0 -367
  383. package/references/openhive/src/api/routes/feed.ts +0 -212
  384. package/references/openhive/src/api/routes/hives.ts +0 -264
  385. package/references/openhive/src/api/routes/map.ts +0 -674
  386. package/references/openhive/src/api/routes/memory-banks.ts +0 -971
  387. package/references/openhive/src/api/routes/posts.ts +0 -342
  388. package/references/openhive/src/api/routes/resource-content.ts +0 -727
  389. package/references/openhive/src/api/routes/resources.ts +0 -1013
  390. package/references/openhive/src/api/routes/search.ts +0 -45
  391. package/references/openhive/src/api/routes/sessions.ts +0 -1187
  392. package/references/openhive/src/api/routes/swarm-hosting.ts +0 -313
  393. package/references/openhive/src/api/routes/sync-protocol.ts +0 -168
  394. package/references/openhive/src/api/routes/sync.ts +0 -279
  395. package/references/openhive/src/api/routes/uploads.ts +0 -174
  396. package/references/openhive/src/api/routes/webhooks.ts +0 -603
  397. package/references/openhive/src/api/schemas/agents.ts +0 -26
  398. package/references/openhive/src/api/schemas/comments.ts +0 -22
  399. package/references/openhive/src/api/schemas/hives.ts +0 -33
  400. package/references/openhive/src/api/schemas/posts.ts +0 -37
  401. package/references/openhive/src/api/schemas/sync.ts +0 -56
  402. package/references/openhive/src/auth/index.ts +0 -2
  403. package/references/openhive/src/auth/jwks.ts +0 -58
  404. package/references/openhive/src/bridge/adapters/slack.ts +0 -306
  405. package/references/openhive/src/bridge/credentials.ts +0 -72
  406. package/references/openhive/src/bridge/inbound.ts +0 -288
  407. package/references/openhive/src/bridge/index.ts +0 -42
  408. package/references/openhive/src/bridge/manager.ts +0 -425
  409. package/references/openhive/src/bridge/mentions.ts +0 -42
  410. package/references/openhive/src/bridge/outbound.ts +0 -103
  411. package/references/openhive/src/bridge/schema.ts +0 -82
  412. package/references/openhive/src/bridge/types.ts +0 -238
  413. package/references/openhive/src/cli/network.ts +0 -480
  414. package/references/openhive/src/cli.ts +0 -620
  415. package/references/openhive/src/config.ts +0 -611
  416. package/references/openhive/src/coordination/index.ts +0 -43
  417. package/references/openhive/src/coordination/listener.ts +0 -92
  418. package/references/openhive/src/coordination/schema.ts +0 -79
  419. package/references/openhive/src/coordination/service.ts +0 -233
  420. package/references/openhive/src/coordination/types.ts +0 -177
  421. package/references/openhive/src/data-dir.ts +0 -105
  422. package/references/openhive/src/db/adapters/index.ts +0 -21
  423. package/references/openhive/src/db/adapters/postgres.ts +0 -310
  424. package/references/openhive/src/db/adapters/sqlite.ts +0 -56
  425. package/references/openhive/src/db/adapters/types.ts +0 -65
  426. package/references/openhive/src/db/dal/agents.ts +0 -430
  427. package/references/openhive/src/db/dal/bridge.ts +0 -336
  428. package/references/openhive/src/db/dal/comments.ts +0 -213
  429. package/references/openhive/src/db/dal/coordination.ts +0 -361
  430. package/references/openhive/src/db/dal/events.ts +0 -381
  431. package/references/openhive/src/db/dal/follows.ts +0 -96
  432. package/references/openhive/src/db/dal/hives.ts +0 -198
  433. package/references/openhive/src/db/dal/ingest-keys.ts +0 -176
  434. package/references/openhive/src/db/dal/instances.ts +0 -196
  435. package/references/openhive/src/db/dal/invites.ts +0 -123
  436. package/references/openhive/src/db/dal/map.ts +0 -750
  437. package/references/openhive/src/db/dal/posts.ts +0 -274
  438. package/references/openhive/src/db/dal/remote-agents.ts +0 -56
  439. package/references/openhive/src/db/dal/search.ts +0 -238
  440. package/references/openhive/src/db/dal/sync-events.ts +0 -160
  441. package/references/openhive/src/db/dal/sync-groups.ts +0 -100
  442. package/references/openhive/src/db/dal/sync-peer-configs.ts +0 -216
  443. package/references/openhive/src/db/dal/sync-peers.ts +0 -145
  444. package/references/openhive/src/db/dal/syncable-resources.ts +0 -888
  445. package/references/openhive/src/db/dal/trajectory-checkpoints.ts +0 -291
  446. package/references/openhive/src/db/dal/uploads.ts +0 -124
  447. package/references/openhive/src/db/dal/votes.ts +0 -124
  448. package/references/openhive/src/db/index.ts +0 -293
  449. package/references/openhive/src/db/providers/index.ts +0 -75
  450. package/references/openhive/src/db/providers/postgres.ts +0 -529
  451. package/references/openhive/src/db/providers/sqlite.ts +0 -1383
  452. package/references/openhive/src/db/providers/turso.ts +0 -1360
  453. package/references/openhive/src/db/providers/types.ts +0 -516
  454. package/references/openhive/src/db/schema.ts +0 -641
  455. package/references/openhive/src/discovery/index.ts +0 -403
  456. package/references/openhive/src/events/dispatch.ts +0 -106
  457. package/references/openhive/src/events/index.ts +0 -17
  458. package/references/openhive/src/events/normalizers/github.ts +0 -133
  459. package/references/openhive/src/events/normalizers/index.ts +0 -62
  460. package/references/openhive/src/events/normalizers/slack.ts +0 -50
  461. package/references/openhive/src/events/router.ts +0 -156
  462. package/references/openhive/src/events/schema.ts +0 -66
  463. package/references/openhive/src/events/types.ts +0 -130
  464. package/references/openhive/src/federation/index.ts +0 -1
  465. package/references/openhive/src/federation/service.ts +0 -776
  466. package/references/openhive/src/headscale/client.ts +0 -256
  467. package/references/openhive/src/headscale/config.ts +0 -212
  468. package/references/openhive/src/headscale/index.ts +0 -23
  469. package/references/openhive/src/headscale/manager.ts +0 -249
  470. package/references/openhive/src/headscale/sync.ts +0 -272
  471. package/references/openhive/src/headscale/types.ts +0 -231
  472. package/references/openhive/src/index.ts +0 -225
  473. package/references/openhive/src/map/client-entry.ts +0 -26
  474. package/references/openhive/src/map/index.ts +0 -76
  475. package/references/openhive/src/map/schema.ts +0 -119
  476. package/references/openhive/src/map/service.ts +0 -323
  477. package/references/openhive/src/map/sync-client.ts +0 -696
  478. package/references/openhive/src/map/sync-listener.ts +0 -409
  479. package/references/openhive/src/map/types.ts +0 -290
  480. package/references/openhive/src/network/factory.ts +0 -118
  481. package/references/openhive/src/network/headscale-provider.ts +0 -437
  482. package/references/openhive/src/network/index.ts +0 -43
  483. package/references/openhive/src/network/tailscale-client.ts +0 -289
  484. package/references/openhive/src/network/tailscale-provider.ts +0 -287
  485. package/references/openhive/src/network/types.ts +0 -178
  486. package/references/openhive/src/opentasks-client/client.ts +0 -374
  487. package/references/openhive/src/opentasks-client/index.ts +0 -7
  488. package/references/openhive/src/realtime/index.ts +0 -282
  489. package/references/openhive/src/server.ts +0 -1069
  490. package/references/openhive/src/services/email.ts +0 -177
  491. package/references/openhive/src/services/sitemap.ts +0 -135
  492. package/references/openhive/src/sessions/adapters/claude.ts +0 -466
  493. package/references/openhive/src/sessions/adapters/codex.ts +0 -265
  494. package/references/openhive/src/sessions/adapters/index.ts +0 -263
  495. package/references/openhive/src/sessions/adapters/raw.ts +0 -144
  496. package/references/openhive/src/sessions/adapters/types.ts +0 -83
  497. package/references/openhive/src/sessions/index.ts +0 -50
  498. package/references/openhive/src/sessions/storage/adapters/gcs.ts +0 -277
  499. package/references/openhive/src/sessions/storage/adapters/local.ts +0 -240
  500. package/references/openhive/src/sessions/storage/adapters/s3.ts +0 -321
  501. package/references/openhive/src/sessions/storage/index.ts +0 -231
  502. package/references/openhive/src/sessions/storage/types.ts +0 -189
  503. package/references/openhive/src/sessions/types.ts +0 -415
  504. package/references/openhive/src/shared/types/index.ts +0 -45
  505. package/references/openhive/src/shared/types/map-coordination.ts +0 -92
  506. package/references/openhive/src/shared/types/map-session-sync.ts +0 -170
  507. package/references/openhive/src/shared/types/map-sync.ts +0 -68
  508. package/references/openhive/src/skill.ts +0 -203
  509. package/references/openhive/src/storage/adapters/local.ts +0 -169
  510. package/references/openhive/src/storage/adapters/s3.ts +0 -195
  511. package/references/openhive/src/storage/index.ts +0 -64
  512. package/references/openhive/src/storage/types.ts +0 -69
  513. package/references/openhive/src/swarm/credentials.ts +0 -98
  514. package/references/openhive/src/swarm/dal.ts +0 -206
  515. package/references/openhive/src/swarm/index.ts +0 -28
  516. package/references/openhive/src/swarm/manager.ts +0 -917
  517. package/references/openhive/src/swarm/providers/local.ts +0 -338
  518. package/references/openhive/src/swarm/providers/sandboxed-local.ts +0 -478
  519. package/references/openhive/src/swarm/providers/workspace.ts +0 -52
  520. package/references/openhive/src/swarm/schema.ts +0 -43
  521. package/references/openhive/src/swarm/types.ts +0 -333
  522. package/references/openhive/src/swarmhub/client.ts +0 -279
  523. package/references/openhive/src/swarmhub/connector.ts +0 -463
  524. package/references/openhive/src/swarmhub/index.ts +0 -43
  525. package/references/openhive/src/swarmhub/routes.ts +0 -296
  526. package/references/openhive/src/swarmhub/types.ts +0 -213
  527. package/references/openhive/src/swarmhub/webhook-handler.ts +0 -126
  528. package/references/openhive/src/sync/compaction.ts +0 -193
  529. package/references/openhive/src/sync/coordination-hooks.ts +0 -154
  530. package/references/openhive/src/sync/crypto.ts +0 -79
  531. package/references/openhive/src/sync/gossip.ts +0 -136
  532. package/references/openhive/src/sync/hooks.ts +0 -202
  533. package/references/openhive/src/sync/materializer-repo.ts +0 -256
  534. package/references/openhive/src/sync/materializer.ts +0 -682
  535. package/references/openhive/src/sync/middleware.ts +0 -140
  536. package/references/openhive/src/sync/peer-resolver.ts +0 -157
  537. package/references/openhive/src/sync/resource-hooks.ts +0 -161
  538. package/references/openhive/src/sync/schema.ts +0 -158
  539. package/references/openhive/src/sync/service.ts +0 -990
  540. package/references/openhive/src/sync/types.ts +0 -369
  541. package/references/openhive/src/terminal/index.ts +0 -4
  542. package/references/openhive/src/terminal/pty-manager.ts +0 -337
  543. package/references/openhive/src/terminal/resolve-tui.ts +0 -44
  544. package/references/openhive/src/terminal/terminal-ws.ts +0 -251
  545. package/references/openhive/src/types.ts +0 -442
  546. package/references/openhive/src/utils/git-remote.ts +0 -329
  547. package/references/openhive/src/web/App.tsx +0 -77
  548. package/references/openhive/src/web/__tests__/components/dashboard/RecentActivity.test.tsx +0 -77
  549. package/references/openhive/src/web/__tests__/components/dashboard/StatsOverview.test.tsx +0 -62
  550. package/references/openhive/src/web/__tests__/components/dashboard/SwarmStatusSummary.test.tsx +0 -122
  551. package/references/openhive/src/web/__tests__/components/dashboard/SyncResourcesStatus.test.tsx +0 -104
  552. package/references/openhive/src/web/__tests__/components/layout/Sidebar.test.tsx +0 -110
  553. package/references/openhive/src/web/__tests__/components/swarm/StatusBadges.test.tsx +0 -65
  554. package/references/openhive/src/web/__tests__/components/terminal/query-responses.test.ts +0 -143
  555. package/references/openhive/src/web/__tests__/components/terminal/terminal-mouse.test.ts +0 -509
  556. package/references/openhive/src/web/__tests__/hooks/useEventsApi.test.ts +0 -378
  557. package/references/openhive/src/web/__tests__/pages/Dashboard.test.tsx +0 -57
  558. package/references/openhive/src/web/__tests__/pages/Events.test.tsx +0 -886
  559. package/references/openhive/src/web/__tests__/pages/Explore.test.tsx +0 -63
  560. package/references/openhive/src/web/__tests__/routing.test.tsx +0 -79
  561. package/references/openhive/src/web/__tests__/setup.ts +0 -37
  562. package/references/openhive/src/web/__tests__/stores/dashboard.test.ts +0 -49
  563. package/references/openhive/src/web/components/common/AgentBadge.tsx +0 -58
  564. package/references/openhive/src/web/components/common/Avatar.tsx +0 -78
  565. package/references/openhive/src/web/components/common/ErrorBoundary.tsx +0 -76
  566. package/references/openhive/src/web/components/common/Highlight.tsx +0 -79
  567. package/references/openhive/src/web/components/common/ImageUpload.tsx +0 -209
  568. package/references/openhive/src/web/components/common/LoadingSpinner.tsx +0 -37
  569. package/references/openhive/src/web/components/common/Logo.tsx +0 -21
  570. package/references/openhive/src/web/components/common/Markdown.tsx +0 -53
  571. package/references/openhive/src/web/components/common/ProtectedRoute.tsx +0 -18
  572. package/references/openhive/src/web/components/common/ThemeToggle.tsx +0 -38
  573. package/references/openhive/src/web/components/common/TimeAgo.tsx +0 -17
  574. package/references/openhive/src/web/components/common/Toast.tsx +0 -70
  575. package/references/openhive/src/web/components/common/VoteButtons.tsx +0 -100
  576. package/references/openhive/src/web/components/dashboard/RecentActivity.tsx +0 -100
  577. package/references/openhive/src/web/components/dashboard/StatsOverview.tsx +0 -40
  578. package/references/openhive/src/web/components/dashboard/SwarmStatusSummary.tsx +0 -89
  579. package/references/openhive/src/web/components/dashboard/SyncResourcesStatus.tsx +0 -81
  580. package/references/openhive/src/web/components/feed/FeedControls.tsx +0 -38
  581. package/references/openhive/src/web/components/feed/NewPostsIndicator.tsx +0 -75
  582. package/references/openhive/src/web/components/feed/PostCard.tsx +0 -129
  583. package/references/openhive/src/web/components/feed/PostList.tsx +0 -83
  584. package/references/openhive/src/web/components/layout/Footer.tsx +0 -5
  585. package/references/openhive/src/web/components/layout/Layout.tsx +0 -29
  586. package/references/openhive/src/web/components/layout/Sidebar.tsx +0 -348
  587. package/references/openhive/src/web/components/post/CommentForm.tsx +0 -59
  588. package/references/openhive/src/web/components/post/CommentTree.tsx +0 -145
  589. package/references/openhive/src/web/components/resources/MemoryBrowser.tsx +0 -208
  590. package/references/openhive/src/web/components/resources/OpenTasksSummary.tsx +0 -138
  591. package/references/openhive/src/web/components/resources/SkillBrowser.tsx +0 -284
  592. package/references/openhive/src/web/components/swarm/StatusBadges.tsx +0 -56
  593. package/references/openhive/src/web/components/terminal/TerminalPanel.tsx +0 -485
  594. package/references/openhive/src/web/components/terminal/index.ts +0 -2
  595. package/references/openhive/src/web/components/terminal/query-responses.ts +0 -70
  596. package/references/openhive/src/web/components/terminal/terminal-mouse.ts +0 -222
  597. package/references/openhive/src/web/hooks/useApi.ts +0 -740
  598. package/references/openhive/src/web/hooks/useDocumentTitle.ts +0 -49
  599. package/references/openhive/src/web/hooks/useInfiniteScroll.ts +0 -58
  600. package/references/openhive/src/web/hooks/useRealtimeUpdates.ts +0 -154
  601. package/references/openhive/src/web/hooks/useWebSocket.ts +0 -225
  602. package/references/openhive/src/web/index.html +0 -73
  603. package/references/openhive/src/web/lib/api.ts +0 -518
  604. package/references/openhive/src/web/main.tsx +0 -32
  605. package/references/openhive/src/web/pages/About.tsx +0 -131
  606. package/references/openhive/src/web/pages/Agent.tsx +0 -130
  607. package/references/openhive/src/web/pages/Agents.tsx +0 -69
  608. package/references/openhive/src/web/pages/AuthCallback.tsx +0 -75
  609. package/references/openhive/src/web/pages/Dashboard.tsx +0 -41
  610. package/references/openhive/src/web/pages/Events.tsx +0 -1025
  611. package/references/openhive/src/web/pages/Explore.tsx +0 -43
  612. package/references/openhive/src/web/pages/Hive.tsx +0 -134
  613. package/references/openhive/src/web/pages/Hives.tsx +0 -64
  614. package/references/openhive/src/web/pages/Home.tsx +0 -43
  615. package/references/openhive/src/web/pages/Login.tsx +0 -122
  616. package/references/openhive/src/web/pages/Post.tsx +0 -216
  617. package/references/openhive/src/web/pages/ResourceDetail.tsx +0 -426
  618. package/references/openhive/src/web/pages/Resources.tsx +0 -276
  619. package/references/openhive/src/web/pages/Search.tsx +0 -234
  620. package/references/openhive/src/web/pages/SessionDetail.tsx +0 -703
  621. package/references/openhive/src/web/pages/Sessions.tsx +0 -129
  622. package/references/openhive/src/web/pages/Settings.tsx +0 -826
  623. package/references/openhive/src/web/pages/SwarmCraft.tsx +0 -16
  624. package/references/openhive/src/web/pages/Swarms.tsx +0 -981
  625. package/references/openhive/src/web/pages/Terminal.tsx +0 -69
  626. package/references/openhive/src/web/postcss.config.js +0 -5
  627. package/references/openhive/src/web/public/favicon.svg +0 -11
  628. package/references/openhive/src/web/public/manifest.json +0 -21
  629. package/references/openhive/src/web/stores/auth.ts +0 -207
  630. package/references/openhive/src/web/stores/dashboard.ts +0 -23
  631. package/references/openhive/src/web/stores/realtime.ts +0 -90
  632. package/references/openhive/src/web/stores/theme.ts +0 -70
  633. package/references/openhive/src/web/stores/toast.ts +0 -63
  634. package/references/openhive/src/web/styles/globals.css +0 -503
  635. package/references/openhive/src/web/sw.ts +0 -228
  636. package/references/openhive/src/web/utils/serviceWorker.ts +0 -86
  637. package/references/openhive/src/web/vite.config.ts +0 -81
  638. package/references/openhive/tsconfig.json +0 -32
  639. package/references/openhive/tsup.config.ts +0 -17
  640. package/references/openhive/vitest.config.ts +0 -30
  641. package/references/openhive/vitest.web.config.ts +0 -20
  642. package/references/opentasks/.claude/settings.json +0 -6
  643. package/references/opentasks/.claude-plugin/plugin.json +0 -20
  644. package/references/opentasks/.lintstagedrc.json +0 -4
  645. package/references/opentasks/.prettierignore +0 -4
  646. package/references/opentasks/.prettierrc.json +0 -11
  647. package/references/opentasks/.sudocode/issues.jsonl +0 -89
  648. package/references/opentasks/.sudocode/specs.jsonl +0 -24
  649. package/references/opentasks/README.md +0 -401
  650. package/references/opentasks/docs/ARCHITECTURE.md +0 -841
  651. package/references/opentasks/docs/DESIGN.md +0 -689
  652. package/references/opentasks/docs/INTERFACE.md +0 -670
  653. package/references/opentasks/docs/PERSISTENCE.md +0 -1638
  654. package/references/opentasks/docs/PROVIDERS.md +0 -1412
  655. package/references/opentasks/docs/SCHEMA.md +0 -815
  656. package/references/opentasks/docs/TESTING.md +0 -1081
  657. package/references/opentasks/eslint.config.js +0 -58
  658. package/references/opentasks/package-lock.json +0 -4348
  659. package/references/opentasks/package.json +0 -81
  660. package/references/opentasks/skills/opentasks/SKILL.md +0 -139
  661. package/references/opentasks/skills/opentasks/dependency-management.md +0 -119
  662. package/references/opentasks/skills/opentasks/feedback-and-review.md +0 -100
  663. package/references/opentasks/skills/opentasks/linking-external-data.md +0 -103
  664. package/references/opentasks/skills/opentasks/spec-to-implementation.md +0 -98
  665. package/references/opentasks/src/__tests__/cli-tools.test.ts +0 -800
  666. package/references/opentasks/src/__tests__/cli.test.ts +0 -97
  667. package/references/opentasks/src/__tests__/p1-p3-gaps.test.ts +0 -635
  668. package/references/opentasks/src/cli.ts +0 -929
  669. package/references/opentasks/src/client/__tests__/client-crud.test.ts +0 -546
  670. package/references/opentasks/src/client/__tests__/client.test.ts +0 -658
  671. package/references/opentasks/src/client/__tests__/socket-discovery.test.ts +0 -122
  672. package/references/opentasks/src/client/client.ts +0 -560
  673. package/references/opentasks/src/client/index.ts +0 -32
  674. package/references/opentasks/src/config/__tests__/defaults.test.ts +0 -66
  675. package/references/opentasks/src/config/__tests__/env.test.ts +0 -155
  676. package/references/opentasks/src/config/__tests__/index.test.ts +0 -148
  677. package/references/opentasks/src/config/__tests__/loader.test.ts +0 -173
  678. package/references/opentasks/src/config/__tests__/merge.test.ts +0 -121
  679. package/references/opentasks/src/config/__tests__/schema.test.ts +0 -446
  680. package/references/opentasks/src/config/defaults.ts +0 -18
  681. package/references/opentasks/src/config/env.ts +0 -170
  682. package/references/opentasks/src/config/errors.ts +0 -33
  683. package/references/opentasks/src/config/index.ts +0 -63
  684. package/references/opentasks/src/config/loader.ts +0 -90
  685. package/references/opentasks/src/config/merge.ts +0 -64
  686. package/references/opentasks/src/config/schema.ts +0 -767
  687. package/references/opentasks/src/core/__tests__/conditional-redirects.test.ts +0 -116
  688. package/references/opentasks/src/core/__tests__/connections.test.ts +0 -194
  689. package/references/opentasks/src/core/__tests__/hash.test.ts +0 -161
  690. package/references/opentasks/src/core/__tests__/id.test.ts +0 -175
  691. package/references/opentasks/src/core/__tests__/init.test.ts +0 -115
  692. package/references/opentasks/src/core/__tests__/location.test.ts +0 -94
  693. package/references/opentasks/src/core/__tests__/merge-driver.test.ts +0 -300
  694. package/references/opentasks/src/core/__tests__/redirects.test.ts +0 -169
  695. package/references/opentasks/src/core/__tests__/resolve-location-target.test.ts +0 -468
  696. package/references/opentasks/src/core/__tests__/uri.test.ts +0 -228
  697. package/references/opentasks/src/core/__tests__/worktree.test.ts +0 -160
  698. package/references/opentasks/src/core/conditional-redirects.ts +0 -100
  699. package/references/opentasks/src/core/connections.ts +0 -217
  700. package/references/opentasks/src/core/discover.ts +0 -195
  701. package/references/opentasks/src/core/hash.ts +0 -74
  702. package/references/opentasks/src/core/id.ts +0 -174
  703. package/references/opentasks/src/core/index.ts +0 -108
  704. package/references/opentasks/src/core/init.ts +0 -66
  705. package/references/opentasks/src/core/location.ts +0 -139
  706. package/references/opentasks/src/core/merge-driver.ts +0 -280
  707. package/references/opentasks/src/core/redirects.ts +0 -182
  708. package/references/opentasks/src/core/uri.ts +0 -270
  709. package/references/opentasks/src/core/worktree.ts +0 -504
  710. package/references/opentasks/src/daemon/__tests__/e2e-live-agent.test.ts +0 -344
  711. package/references/opentasks/src/daemon/__tests__/e2e-session-pipeline.test.ts +0 -447
  712. package/references/opentasks/src/daemon/__tests__/e2e-watch.test.ts +0 -279
  713. package/references/opentasks/src/daemon/__tests__/entire-linker.test.ts +0 -1074
  714. package/references/opentasks/src/daemon/__tests__/entire-watcher.test.ts +0 -659
  715. package/references/opentasks/src/daemon/__tests__/flush.test.ts +0 -306
  716. package/references/opentasks/src/daemon/__tests__/integration.test.ts +0 -338
  717. package/references/opentasks/src/daemon/__tests__/ipc.test.ts +0 -406
  718. package/references/opentasks/src/daemon/__tests__/lifecycle.test.ts +0 -378
  719. package/references/opentasks/src/daemon/__tests__/lock.test.ts +0 -240
  720. package/references/opentasks/src/daemon/__tests__/methods/graph.test.ts +0 -372
  721. package/references/opentasks/src/daemon/__tests__/methods/provider.test.ts +0 -238
  722. package/references/opentasks/src/daemon/__tests__/methods/tools.test.ts +0 -690
  723. package/references/opentasks/src/daemon/__tests__/multi-location.test.ts +0 -945
  724. package/references/opentasks/src/daemon/__tests__/registry.test.ts +0 -268
  725. package/references/opentasks/src/daemon/__tests__/watcher.test.ts +0 -329
  726. package/references/opentasks/src/daemon/entire-linker.ts +0 -615
  727. package/references/opentasks/src/daemon/entire-watcher.ts +0 -415
  728. package/references/opentasks/src/daemon/factory.ts +0 -133
  729. package/references/opentasks/src/daemon/flush.ts +0 -168
  730. package/references/opentasks/src/daemon/index.ts +0 -120
  731. package/references/opentasks/src/daemon/ipc.ts +0 -491
  732. package/references/opentasks/src/daemon/lifecycle.ts +0 -1106
  733. package/references/opentasks/src/daemon/location-state.ts +0 -481
  734. package/references/opentasks/src/daemon/lock.ts +0 -168
  735. package/references/opentasks/src/daemon/methods/__tests__/graph.test.ts +0 -359
  736. package/references/opentasks/src/daemon/methods/__tests__/provider.test.ts +0 -227
  737. package/references/opentasks/src/daemon/methods/__tests__/tools.test.ts +0 -360
  738. package/references/opentasks/src/daemon/methods/__tests__/watch.test.ts +0 -656
  739. package/references/opentasks/src/daemon/methods/archive.ts +0 -193
  740. package/references/opentasks/src/daemon/methods/graph.ts +0 -274
  741. package/references/opentasks/src/daemon/methods/lifecycle.ts +0 -112
  742. package/references/opentasks/src/daemon/methods/location.ts +0 -118
  743. package/references/opentasks/src/daemon/methods/provider.ts +0 -159
  744. package/references/opentasks/src/daemon/methods/tools.ts +0 -221
  745. package/references/opentasks/src/daemon/methods/watch.ts +0 -206
  746. package/references/opentasks/src/daemon/registry.ts +0 -244
  747. package/references/opentasks/src/daemon/types.ts +0 -163
  748. package/references/opentasks/src/daemon/watcher.ts +0 -248
  749. package/references/opentasks/src/entire/__tests__/agent-registry.test.ts +0 -127
  750. package/references/opentasks/src/entire/__tests__/claude-generator.test.ts +0 -49
  751. package/references/opentasks/src/entire/__tests__/commit-msg.test.ts +0 -89
  752. package/references/opentasks/src/entire/__tests__/cursor-agent.test.ts +0 -224
  753. package/references/opentasks/src/entire/__tests__/flush-sentinel.test.ts +0 -93
  754. package/references/opentasks/src/entire/__tests__/gemini-agent.test.ts +0 -375
  755. package/references/opentasks/src/entire/__tests__/git-hooks.test.ts +0 -85
  756. package/references/opentasks/src/entire/__tests__/hook-managers.test.ts +0 -128
  757. package/references/opentasks/src/entire/__tests__/opencode-agent.test.ts +0 -329
  758. package/references/opentasks/src/entire/__tests__/redaction.test.ts +0 -143
  759. package/references/opentasks/src/entire/__tests__/session-store.test.ts +0 -83
  760. package/references/opentasks/src/entire/__tests__/summarize.test.ts +0 -346
  761. package/references/opentasks/src/entire/__tests__/transcript-timestamp.test.ts +0 -127
  762. package/references/opentasks/src/entire/__tests__/types.test.ts +0 -112
  763. package/references/opentasks/src/entire/__tests__/utils.test.ts +0 -296
  764. package/references/opentasks/src/entire/__tests__/validation.test.ts +0 -103
  765. package/references/opentasks/src/entire/__tests__/worktree.test.ts +0 -66
  766. package/references/opentasks/src/entire/agent/registry.ts +0 -143
  767. package/references/opentasks/src/entire/agent/session-types.ts +0 -117
  768. package/references/opentasks/src/entire/agent/types.ts +0 -217
  769. package/references/opentasks/src/entire/commands/clean.ts +0 -134
  770. package/references/opentasks/src/entire/commands/disable.ts +0 -85
  771. package/references/opentasks/src/entire/commands/doctor.ts +0 -152
  772. package/references/opentasks/src/entire/commands/enable.ts +0 -149
  773. package/references/opentasks/src/entire/commands/explain.ts +0 -271
  774. package/references/opentasks/src/entire/commands/reset.ts +0 -105
  775. package/references/opentasks/src/entire/commands/resume.ts +0 -194
  776. package/references/opentasks/src/entire/commands/rewind.ts +0 -204
  777. package/references/opentasks/src/entire/commands/status.ts +0 -150
  778. package/references/opentasks/src/entire/config.ts +0 -153
  779. package/references/opentasks/src/entire/git-operations.ts +0 -485
  780. package/references/opentasks/src/entire/hooks/git-hooks.ts +0 -171
  781. package/references/opentasks/src/entire/hooks/lifecycle.ts +0 -224
  782. package/references/opentasks/src/entire/index.ts +0 -644
  783. package/references/opentasks/src/entire/security/redaction.ts +0 -263
  784. package/references/opentasks/src/entire/session/state-machine.ts +0 -463
  785. package/references/opentasks/src/entire/store/checkpoint-store.ts +0 -489
  786. package/references/opentasks/src/entire/store/native-store.ts +0 -178
  787. package/references/opentasks/src/entire/store/provider-types.ts +0 -99
  788. package/references/opentasks/src/entire/store/session-store.ts +0 -233
  789. package/references/opentasks/src/entire/strategy/attribution.ts +0 -300
  790. package/references/opentasks/src/entire/strategy/common.ts +0 -222
  791. package/references/opentasks/src/entire/strategy/content-overlap.ts +0 -242
  792. package/references/opentasks/src/entire/strategy/manual-commit.ts +0 -1008
  793. package/references/opentasks/src/entire/strategy/types.ts +0 -285
  794. package/references/opentasks/src/entire/summarize/claude-generator.ts +0 -119
  795. package/references/opentasks/src/entire/summarize/summarize.ts +0 -432
  796. package/references/opentasks/src/entire/types.ts +0 -408
  797. package/references/opentasks/src/entire/utils/chunk-files.ts +0 -49
  798. package/references/opentasks/src/entire/utils/commit-message.ts +0 -65
  799. package/references/opentasks/src/entire/utils/detect-agent.ts +0 -36
  800. package/references/opentasks/src/entire/utils/hook-managers.ts +0 -118
  801. package/references/opentasks/src/entire/utils/ide-tags.ts +0 -32
  802. package/references/opentasks/src/entire/utils/paths.ts +0 -59
  803. package/references/opentasks/src/entire/utils/preview-rewind.ts +0 -86
  804. package/references/opentasks/src/entire/utils/rewind-conflict.ts +0 -121
  805. package/references/opentasks/src/entire/utils/shadow-branch.ts +0 -113
  806. package/references/opentasks/src/entire/utils/string-utils.ts +0 -46
  807. package/references/opentasks/src/entire/utils/todo-extract.ts +0 -193
  808. package/references/opentasks/src/entire/utils/trailers.ts +0 -190
  809. package/references/opentasks/src/entire/utils/transcript-parse.ts +0 -177
  810. package/references/opentasks/src/entire/utils/transcript-timestamp.ts +0 -61
  811. package/references/opentasks/src/entire/utils/tree-ops.ts +0 -227
  812. package/references/opentasks/src/entire/utils/tty.ts +0 -72
  813. package/references/opentasks/src/entire/utils/validation.ts +0 -67
  814. package/references/opentasks/src/entire/utils/worktree.ts +0 -58
  815. package/references/opentasks/src/graph/EdgeTypeRegistry.ts +0 -330
  816. package/references/opentasks/src/graph/FederatedGraph.ts +0 -796
  817. package/references/opentasks/src/graph/GraphologyAdapter.ts +0 -374
  818. package/references/opentasks/src/graph/HydratingFederatedGraph.ts +0 -533
  819. package/references/opentasks/src/graph/__tests__/EdgeTypeRegistry.test.ts +0 -263
  820. package/references/opentasks/src/graph/__tests__/FederatedGraph.test.ts +0 -821
  821. package/references/opentasks/src/graph/__tests__/GraphologyAdapter.test.ts +0 -408
  822. package/references/opentasks/src/graph/__tests__/HydratingFederatedGraph.test.ts +0 -735
  823. package/references/opentasks/src/graph/__tests__/debounce.test.ts +0 -276
  824. package/references/opentasks/src/graph/__tests__/e2e-store-roundtrip.test.ts +0 -349
  825. package/references/opentasks/src/graph/__tests__/edge-cases.test.ts +0 -595
  826. package/references/opentasks/src/graph/__tests__/expansion.test.ts +0 -304
  827. package/references/opentasks/src/graph/__tests__/git-graph-syncer.test.ts +0 -572
  828. package/references/opentasks/src/graph/__tests__/provider-store.test.ts +0 -1091
  829. package/references/opentasks/src/graph/__tests__/query.test.ts +0 -991
  830. package/references/opentasks/src/graph/__tests__/store.test.ts +0 -998
  831. package/references/opentasks/src/graph/__tests__/sync.test.ts +0 -178
  832. package/references/opentasks/src/graph/__tests__/validation.test.ts +0 -657
  833. package/references/opentasks/src/graph/coordination.ts +0 -454
  834. package/references/opentasks/src/graph/debounce.ts +0 -154
  835. package/references/opentasks/src/graph/expansion.ts +0 -364
  836. package/references/opentasks/src/graph/git-graph-syncer.ts +0 -321
  837. package/references/opentasks/src/graph/history.ts +0 -438
  838. package/references/opentasks/src/graph/index.ts +0 -145
  839. package/references/opentasks/src/graph/provider-store.ts +0 -1077
  840. package/references/opentasks/src/graph/query.ts +0 -651
  841. package/references/opentasks/src/graph/store.ts +0 -861
  842. package/references/opentasks/src/graph/sync.ts +0 -116
  843. package/references/opentasks/src/graph/types.ts +0 -420
  844. package/references/opentasks/src/graph/validation.ts +0 -520
  845. package/references/opentasks/src/index.ts +0 -270
  846. package/references/opentasks/src/materialization/CLAUDE.md +0 -88
  847. package/references/opentasks/src/materialization/README.md +0 -187
  848. package/references/opentasks/src/materialization/__tests__/archive-methods.test.ts +0 -194
  849. package/references/opentasks/src/materialization/__tests__/archiver.test.ts +0 -528
  850. package/references/opentasks/src/materialization/__tests__/config.test.ts +0 -123
  851. package/references/opentasks/src/materialization/__tests__/git-remote-store.test.ts +0 -533
  852. package/references/opentasks/src/materialization/__tests__/graph-id.test.ts +0 -82
  853. package/references/opentasks/src/materialization/__tests__/http-remote-store.test.ts +0 -263
  854. package/references/opentasks/src/materialization/__tests__/materialize-before-archive.test.ts +0 -246
  855. package/references/opentasks/src/materialization/__tests__/remote-store-factory.test.ts +0 -152
  856. package/references/opentasks/src/materialization/__tests__/snapshot.test.ts +0 -209
  857. package/references/opentasks/src/materialization/archiver.ts +0 -318
  858. package/references/opentasks/src/materialization/git-archive-store.ts +0 -568
  859. package/references/opentasks/src/materialization/git-remote-store.ts +0 -551
  860. package/references/opentasks/src/materialization/graph-id.ts +0 -173
  861. package/references/opentasks/src/materialization/http-remote-store.ts +0 -190
  862. package/references/opentasks/src/materialization/index.ts +0 -62
  863. package/references/opentasks/src/materialization/remote-store-factory.ts +0 -55
  864. package/references/opentasks/src/materialization/snapshot.ts +0 -230
  865. package/references/opentasks/src/materialization/types.ts +0 -410
  866. package/references/opentasks/src/providers/__tests__/beads.test.ts +0 -752
  867. package/references/opentasks/src/providers/__tests__/claude-tasks.test.ts +0 -485
  868. package/references/opentasks/src/providers/__tests__/entire-e2e.test.ts +0 -692
  869. package/references/opentasks/src/providers/__tests__/entire-sessionlog-e2e.test.ts +0 -1113
  870. package/references/opentasks/src/providers/__tests__/entire.test.ts +0 -1016
  871. package/references/opentasks/src/providers/__tests__/from-config.test.ts +0 -183
  872. package/references/opentasks/src/providers/__tests__/global.test.ts +0 -515
  873. package/references/opentasks/src/providers/__tests__/materialization.test.ts +0 -567
  874. package/references/opentasks/src/providers/__tests__/native.test.ts +0 -693
  875. package/references/opentasks/src/providers/__tests__/registry.test.ts +0 -232
  876. package/references/opentasks/src/providers/beads.ts +0 -1155
  877. package/references/opentasks/src/providers/claude-tasks.ts +0 -402
  878. package/references/opentasks/src/providers/entire.ts +0 -608
  879. package/references/opentasks/src/providers/from-config.ts +0 -210
  880. package/references/opentasks/src/providers/global.ts +0 -460
  881. package/references/opentasks/src/providers/index.ts +0 -147
  882. package/references/opentasks/src/providers/location.ts +0 -237
  883. package/references/opentasks/src/providers/materialization.ts +0 -346
  884. package/references/opentasks/src/providers/native.ts +0 -725
  885. package/references/opentasks/src/providers/registry.ts +0 -114
  886. package/references/opentasks/src/providers/sudocode.ts +0 -1292
  887. package/references/opentasks/src/providers/sync.ts +0 -485
  888. package/references/opentasks/src/providers/traits/RelationshipQueryable.ts +0 -169
  889. package/references/opentasks/src/providers/traits/TaskManageable.ts +0 -211
  890. package/references/opentasks/src/providers/traits/Watchable.ts +0 -260
  891. package/references/opentasks/src/providers/traits/__tests__/RelationshipQueryable.test.ts +0 -217
  892. package/references/opentasks/src/providers/traits/__tests__/TaskManageable.test.ts +0 -241
  893. package/references/opentasks/src/providers/traits/index.ts +0 -42
  894. package/references/opentasks/src/providers/types.ts +0 -439
  895. package/references/opentasks/src/schema/__tests__/validation.test.ts +0 -283
  896. package/references/opentasks/src/schema/base.ts +0 -88
  897. package/references/opentasks/src/schema/edges.ts +0 -78
  898. package/references/opentasks/src/schema/index.ts +0 -37
  899. package/references/opentasks/src/schema/nodes.ts +0 -119
  900. package/references/opentasks/src/schema/storage.ts +0 -130
  901. package/references/opentasks/src/schema/validation.ts +0 -209
  902. package/references/opentasks/src/storage/__tests__/atomic-write.test.ts +0 -227
  903. package/references/opentasks/src/storage/__tests__/file-lock.test.ts +0 -120
  904. package/references/opentasks/src/storage/__tests__/jsonl.test.ts +0 -267
  905. package/references/opentasks/src/storage/__tests__/locked-writer.test.ts +0 -134
  906. package/references/opentasks/src/storage/__tests__/sqlite.test.ts +0 -572
  907. package/references/opentasks/src/storage/atomic-write.ts +0 -86
  908. package/references/opentasks/src/storage/file-lock.ts +0 -215
  909. package/references/opentasks/src/storage/index.ts +0 -24
  910. package/references/opentasks/src/storage/interface.ts +0 -289
  911. package/references/opentasks/src/storage/jsonl.ts +0 -264
  912. package/references/opentasks/src/storage/locked-writer.ts +0 -140
  913. package/references/opentasks/src/storage/sqlite-schema.ts +0 -177
  914. package/references/opentasks/src/storage/sqlite.ts +0 -791
  915. package/references/opentasks/src/tools/__tests__/annotate.test.ts +0 -381
  916. package/references/opentasks/src/tools/__tests__/link.test.ts +0 -299
  917. package/references/opentasks/src/tools/__tests__/query.test.ts +0 -350
  918. package/references/opentasks/src/tools/__tests__/task.test.ts +0 -218
  919. package/references/opentasks/src/tools/annotate.ts +0 -277
  920. package/references/opentasks/src/tools/index.ts +0 -57
  921. package/references/opentasks/src/tools/link.ts +0 -163
  922. package/references/opentasks/src/tools/query.ts +0 -468
  923. package/references/opentasks/src/tools/task.ts +0 -213
  924. package/references/opentasks/src/tools/types.ts +0 -451
  925. package/references/opentasks/src/tracking/__tests__/claude-tool-categorizer.test.ts +0 -223
  926. package/references/opentasks/src/tracking/__tests__/transcript-extractor.test.ts +0 -262
  927. package/references/opentasks/src/tracking/claude-tool-categorizer.ts +0 -155
  928. package/references/opentasks/src/tracking/index.ts +0 -32
  929. package/references/opentasks/src/tracking/skill-tracker.ts +0 -322
  930. package/references/opentasks/src/tracking/transcript-extractor.ts +0 -225
  931. package/references/opentasks/tests/e2e/helpers/assertions.ts +0 -211
  932. package/references/opentasks/tests/e2e/helpers/beads-helpers.ts +0 -487
  933. package/references/opentasks/tests/e2e/helpers/fixtures.ts +0 -236
  934. package/references/opentasks/tests/e2e/helpers/index.ts +0 -122
  935. package/references/opentasks/tests/e2e/helpers/sudocode-helpers.ts +0 -341
  936. package/references/opentasks/tests/e2e/helpers/system-setup.ts +0 -504
  937. package/references/opentasks/tests/e2e/helpers/test-agent.ts +0 -504
  938. package/references/opentasks/tests/e2e/infrastructure.e2e.test.ts +0 -521
  939. package/references/opentasks/tests/e2e/skill-tracking.e2e.test.ts +0 -625
  940. package/references/opentasks/tests/e2e/workflows/feedback-loop.e2e.test.ts +0 -279
  941. package/references/opentasks/tests/e2e/workflows/multi-agent.e2e.test.ts +0 -304
  942. package/references/opentasks/tests/e2e/workflows/provider-sync/background-sync.e2e.test.ts +0 -292
  943. package/references/opentasks/tests/e2e/workflows/provider-sync/beads-provider-compat.e2e.test.ts +0 -249
  944. package/references/opentasks/tests/e2e/workflows/provider-sync/cross-provider-edges.e2e.test.ts +0 -407
  945. package/references/opentasks/tests/e2e/workflows/provider-sync/federated-ready.e2e.test.ts +0 -504
  946. package/references/opentasks/tests/e2e/workflows/provider-sync/hydration.e2e.test.ts +0 -340
  947. package/references/opentasks/tests/e2e/workflows/provider-sync/materialization.e2e.test.ts +0 -370
  948. package/references/opentasks/tests/e2e/workflows/provider-sync/sudocode-provider-compat.e2e.test.ts +0 -683
  949. package/references/opentasks/tests/e2e/workflows/provider-sync/watchable-beads.e2e.test.ts +0 -573
  950. package/references/opentasks/tests/e2e/workflows/spec-driven.e2e.test.ts +0 -244
  951. package/references/opentasks/tests/e2e/worktree-location.e2e.test.ts +0 -699
  952. package/references/opentasks/tests/integration/daemon/helpers.ts +0 -147
  953. package/references/opentasks/tests/integration/daemon/ipc.integration.test.ts +0 -343
  954. package/references/opentasks/tests/integration/daemon/lifecycle.integration.test.ts +0 -407
  955. package/references/opentasks/tests/integration/graph/federated-graph.integration.test.ts +0 -660
  956. package/references/opentasks/tests/integration/helpers/flags.ts +0 -28
  957. package/references/opentasks/tests/integration/helpers/index.ts +0 -47
  958. package/references/opentasks/tests/integration/helpers/process.ts +0 -133
  959. package/references/opentasks/tests/integration/helpers/temp.ts +0 -105
  960. package/references/opentasks/tests/integration/helpers/wait.ts +0 -133
  961. package/references/opentasks/tests/integration/helpers.test.ts +0 -120
  962. package/references/opentasks/tests/integration/providers/beads-task-manageable.integration.test.ts +0 -450
  963. package/references/opentasks/tests/integration/providers/beads.integration.test.ts +0 -388
  964. package/references/opentasks/tests/integration/providers/native-task-manageable.integration.test.ts +0 -667
  965. package/references/opentasks/tests/integration/providers/sudocode-task-manageable.integration.test.ts +0 -406
  966. package/references/opentasks/tests/integration/providers/sudocode.integration.test.ts +0 -342
  967. package/references/opentasks/tests/integration/storage/jsonl-durability.integration.test.ts +0 -390
  968. package/references/opentasks/tests/integration/storage/sqlite-durability.integration.test.ts +0 -527
  969. package/references/opentasks/tests/integration/worktree/redirect-location-resolution.integration.test.ts +0 -578
  970. package/references/opentasks/tests/integration/worktree/worktree-flow.integration.test.ts +0 -656
  971. package/references/opentasks/tsconfig.json +0 -18
  972. package/references/opentasks/vitest.config.ts +0 -27
  973. package/references/opentasks/vitest.e2e.config.ts +0 -35
  974. package/references/opentasks/vitest.integration.config.ts +0 -19
  975. package/references/openteams/.claude/settings.json +0 -6
  976. package/references/openteams/CLAUDE.md +0 -98
  977. package/references/openteams/README.md +0 -508
  978. package/references/openteams/SKILL.md +0 -198
  979. package/references/openteams/design.md +0 -250
  980. package/references/openteams/docs/visual-editor-design.md +0 -1225
  981. package/references/openteams/editor/index.html +0 -15
  982. package/references/openteams/editor/package.json +0 -39
  983. package/references/openteams/editor/src/App.tsx +0 -48
  984. package/references/openteams/editor/src/components/canvas/Canvas.tsx +0 -131
  985. package/references/openteams/editor/src/components/canvas/QuickAddMenu.tsx +0 -134
  986. package/references/openteams/editor/src/components/edges/PeerRouteEdge.tsx +0 -82
  987. package/references/openteams/editor/src/components/edges/SignalFlowEdge.tsx +0 -77
  988. package/references/openteams/editor/src/components/edges/SpawnEdge.tsx +0 -54
  989. package/references/openteams/editor/src/components/inspector/ChannelInspector.tsx +0 -158
  990. package/references/openteams/editor/src/components/inspector/EdgeInspector.tsx +0 -168
  991. package/references/openteams/editor/src/components/inspector/Inspector.tsx +0 -46
  992. package/references/openteams/editor/src/components/inspector/RoleInspector.tsx +0 -508
  993. package/references/openteams/editor/src/components/inspector/TeamInspector.tsx +0 -126
  994. package/references/openteams/editor/src/components/nodes/ChannelNode.tsx +0 -103
  995. package/references/openteams/editor/src/components/nodes/RoleNode.tsx +0 -157
  996. package/references/openteams/editor/src/components/nodes/node-styles.ts +0 -101
  997. package/references/openteams/editor/src/components/sidebar/Sidebar.tsx +0 -227
  998. package/references/openteams/editor/src/components/toolbar/ExportModal.tsx +0 -110
  999. package/references/openteams/editor/src/components/toolbar/ImportModal.tsx +0 -139
  1000. package/references/openteams/editor/src/components/toolbar/Toolbar.tsx +0 -190
  1001. package/references/openteams/editor/src/hooks/use-autosave.ts +0 -126
  1002. package/references/openteams/editor/src/hooks/use-keyboard.ts +0 -106
  1003. package/references/openteams/editor/src/hooks/use-validation.ts +0 -45
  1004. package/references/openteams/editor/src/index.css +0 -245
  1005. package/references/openteams/editor/src/lib/auto-layout.ts +0 -51
  1006. package/references/openteams/editor/src/lib/bundled-templates.ts +0 -42
  1007. package/references/openteams/editor/src/lib/compiler.ts +0 -75
  1008. package/references/openteams/editor/src/lib/load-template.ts +0 -103
  1009. package/references/openteams/editor/src/lib/rebuild-edges.ts +0 -104
  1010. package/references/openteams/editor/src/lib/serializer.ts +0 -408
  1011. package/references/openteams/editor/src/lib/signal-catalog.ts +0 -50
  1012. package/references/openteams/editor/src/lib/validator.ts +0 -172
  1013. package/references/openteams/editor/src/main.tsx +0 -10
  1014. package/references/openteams/editor/src/stores/canvas-store.ts +0 -80
  1015. package/references/openteams/editor/src/stores/config-store.ts +0 -243
  1016. package/references/openteams/editor/src/stores/history-store.ts +0 -143
  1017. package/references/openteams/editor/src/stores/theme-store.ts +0 -66
  1018. package/references/openteams/editor/src/stores/ui-store.ts +0 -46
  1019. package/references/openteams/editor/src/stores/validation-store.ts +0 -27
  1020. package/references/openteams/editor/src/types/editor.ts +0 -74
  1021. package/references/openteams/editor/src/vite-env.d.ts +0 -1
  1022. package/references/openteams/editor/tests/compiler.test.ts +0 -151
  1023. package/references/openteams/editor/tests/e2e-add-remove.test.ts +0 -386
  1024. package/references/openteams/editor/tests/e2e-components.test.tsx +0 -424
  1025. package/references/openteams/editor/tests/e2e-export-roundtrip.test.ts +0 -299
  1026. package/references/openteams/editor/tests/e2e-template-load.test.ts +0 -204
  1027. package/references/openteams/editor/tests/e2e-ui-store.test.ts +0 -126
  1028. package/references/openteams/editor/tests/e2e-undo-redo.test.ts +0 -203
  1029. package/references/openteams/editor/tests/e2e-validation.test.ts +0 -307
  1030. package/references/openteams/editor/tests/serializer.test.ts +0 -142
  1031. package/references/openteams/editor/tests/setup.ts +0 -52
  1032. package/references/openteams/editor/tests/validator.test.ts +0 -92
  1033. package/references/openteams/editor/tsconfig.json +0 -21
  1034. package/references/openteams/editor/tsconfig.tsbuildinfo +0 -1
  1035. package/references/openteams/editor/vite.config.ts +0 -28
  1036. package/references/openteams/examples/bmad-method/prompts/analyst/ROLE.md +0 -16
  1037. package/references/openteams/examples/bmad-method/prompts/analyst/SOUL.md +0 -5
  1038. package/references/openteams/examples/bmad-method/prompts/architect/ROLE.md +0 -24
  1039. package/references/openteams/examples/bmad-method/prompts/architect/SOUL.md +0 -5
  1040. package/references/openteams/examples/bmad-method/prompts/developer/ROLE.md +0 -25
  1041. package/references/openteams/examples/bmad-method/prompts/developer/SOUL.md +0 -5
  1042. package/references/openteams/examples/bmad-method/prompts/master/ROLE.md +0 -21
  1043. package/references/openteams/examples/bmad-method/prompts/master/SOUL.md +0 -5
  1044. package/references/openteams/examples/bmad-method/prompts/pm/ROLE.md +0 -20
  1045. package/references/openteams/examples/bmad-method/prompts/pm/SOUL.md +0 -5
  1046. package/references/openteams/examples/bmad-method/prompts/qa/ROLE.md +0 -17
  1047. package/references/openteams/examples/bmad-method/prompts/qa/SOUL.md +0 -5
  1048. package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/ROLE.md +0 -23
  1049. package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/SOUL.md +0 -5
  1050. package/references/openteams/examples/bmad-method/prompts/scrum-master/ROLE.md +0 -27
  1051. package/references/openteams/examples/bmad-method/prompts/scrum-master/SOUL.md +0 -5
  1052. package/references/openteams/examples/bmad-method/prompts/tech-writer/ROLE.md +0 -21
  1053. package/references/openteams/examples/bmad-method/prompts/tech-writer/SOUL.md +0 -5
  1054. package/references/openteams/examples/bmad-method/prompts/ux-designer/ROLE.md +0 -16
  1055. package/references/openteams/examples/bmad-method/prompts/ux-designer/SOUL.md +0 -5
  1056. package/references/openteams/examples/bmad-method/roles/analyst.yaml +0 -9
  1057. package/references/openteams/examples/bmad-method/roles/architect.yaml +0 -9
  1058. package/references/openteams/examples/bmad-method/roles/developer.yaml +0 -8
  1059. package/references/openteams/examples/bmad-method/roles/master.yaml +0 -8
  1060. package/references/openteams/examples/bmad-method/roles/pm.yaml +0 -9
  1061. package/references/openteams/examples/bmad-method/roles/qa.yaml +0 -8
  1062. package/references/openteams/examples/bmad-method/roles/quick-flow-dev.yaml +0 -8
  1063. package/references/openteams/examples/bmad-method/roles/scrum-master.yaml +0 -9
  1064. package/references/openteams/examples/bmad-method/roles/tech-writer.yaml +0 -8
  1065. package/references/openteams/examples/bmad-method/roles/ux-designer.yaml +0 -8
  1066. package/references/openteams/examples/bmad-method/team.yaml +0 -161
  1067. package/references/openteams/examples/bug-fix-pipeline/roles/fixer.yaml +0 -9
  1068. package/references/openteams/examples/bug-fix-pipeline/roles/investigator.yaml +0 -8
  1069. package/references/openteams/examples/bug-fix-pipeline/roles/pr-creator.yaml +0 -6
  1070. package/references/openteams/examples/bug-fix-pipeline/roles/triager.yaml +0 -7
  1071. package/references/openteams/examples/bug-fix-pipeline/roles/verifier.yaml +0 -8
  1072. package/references/openteams/examples/bug-fix-pipeline/team.yaml +0 -88
  1073. package/references/openteams/examples/codebase-migration/roles/assessor.yaml +0 -7
  1074. package/references/openteams/examples/codebase-migration/roles/migrator.yaml +0 -9
  1075. package/references/openteams/examples/codebase-migration/roles/planner.yaml +0 -5
  1076. package/references/openteams/examples/codebase-migration/roles/test-extractor.yaml +0 -9
  1077. package/references/openteams/examples/codebase-migration/roles/validator.yaml +0 -7
  1078. package/references/openteams/examples/codebase-migration/team.yaml +0 -81
  1079. package/references/openteams/examples/docs-sync/roles/adr-writer.yaml +0 -7
  1080. package/references/openteams/examples/docs-sync/roles/api-doc-writer.yaml +0 -7
  1081. package/references/openteams/examples/docs-sync/roles/change-detector.yaml +0 -7
  1082. package/references/openteams/examples/docs-sync/roles/doc-reviewer.yaml +0 -7
  1083. package/references/openteams/examples/docs-sync/roles/guide-writer.yaml +0 -7
  1084. package/references/openteams/examples/docs-sync/team.yaml +0 -84
  1085. package/references/openteams/examples/gsd/prompts/codebase-mapper/ROLE.md +0 -17
  1086. package/references/openteams/examples/gsd/prompts/codebase-mapper/SOUL.md +0 -5
  1087. package/references/openteams/examples/gsd/prompts/debugger/ROLE.md +0 -25
  1088. package/references/openteams/examples/gsd/prompts/debugger/SOUL.md +0 -5
  1089. package/references/openteams/examples/gsd/prompts/executor/ROLE.md +0 -34
  1090. package/references/openteams/examples/gsd/prompts/executor/SOUL.md +0 -5
  1091. package/references/openteams/examples/gsd/prompts/integration-checker/ROLE.md +0 -18
  1092. package/references/openteams/examples/gsd/prompts/integration-checker/SOUL.md +0 -3
  1093. package/references/openteams/examples/gsd/prompts/orchestrator/ROLE.md +0 -42
  1094. package/references/openteams/examples/gsd/prompts/orchestrator/SOUL.md +0 -5
  1095. package/references/openteams/examples/gsd/prompts/phase-researcher/ROLE.md +0 -15
  1096. package/references/openteams/examples/gsd/prompts/phase-researcher/SOUL.md +0 -3
  1097. package/references/openteams/examples/gsd/prompts/plan-checker/ROLE.md +0 -17
  1098. package/references/openteams/examples/gsd/prompts/plan-checker/SOUL.md +0 -3
  1099. package/references/openteams/examples/gsd/prompts/planner/ROLE.md +0 -28
  1100. package/references/openteams/examples/gsd/prompts/planner/SOUL.md +0 -5
  1101. package/references/openteams/examples/gsd/prompts/project-researcher/ROLE.md +0 -16
  1102. package/references/openteams/examples/gsd/prompts/project-researcher/SOUL.md +0 -3
  1103. package/references/openteams/examples/gsd/prompts/research-synthesizer/ROLE.md +0 -13
  1104. package/references/openteams/examples/gsd/prompts/research-synthesizer/SOUL.md +0 -3
  1105. package/references/openteams/examples/gsd/prompts/roadmapper/ROLE.md +0 -14
  1106. package/references/openteams/examples/gsd/prompts/roadmapper/SOUL.md +0 -3
  1107. package/references/openteams/examples/gsd/prompts/verifier/ROLE.md +0 -19
  1108. package/references/openteams/examples/gsd/prompts/verifier/SOUL.md +0 -5
  1109. package/references/openteams/examples/gsd/roles/codebase-mapper.yaml +0 -8
  1110. package/references/openteams/examples/gsd/roles/debugger.yaml +0 -8
  1111. package/references/openteams/examples/gsd/roles/executor.yaml +0 -8
  1112. package/references/openteams/examples/gsd/roles/integration-checker.yaml +0 -8
  1113. package/references/openteams/examples/gsd/roles/orchestrator.yaml +0 -9
  1114. package/references/openteams/examples/gsd/roles/phase-researcher.yaml +0 -7
  1115. package/references/openteams/examples/gsd/roles/plan-checker.yaml +0 -8
  1116. package/references/openteams/examples/gsd/roles/planner.yaml +0 -8
  1117. package/references/openteams/examples/gsd/roles/project-researcher.yaml +0 -8
  1118. package/references/openteams/examples/gsd/roles/research-synthesizer.yaml +0 -7
  1119. package/references/openteams/examples/gsd/roles/roadmapper.yaml +0 -7
  1120. package/references/openteams/examples/gsd/roles/verifier.yaml +0 -8
  1121. package/references/openteams/examples/gsd/team.yaml +0 -154
  1122. package/references/openteams/examples/incident-response/roles/communicator.yaml +0 -5
  1123. package/references/openteams/examples/incident-response/roles/fix-proposer.yaml +0 -7
  1124. package/references/openteams/examples/incident-response/roles/incident-triager.yaml +0 -8
  1125. package/references/openteams/examples/incident-response/roles/investigator.yaml +0 -8
  1126. package/references/openteams/examples/incident-response/team.yaml +0 -68
  1127. package/references/openteams/examples/pr-review-checks/roles/code-reviewer.yaml +0 -7
  1128. package/references/openteams/examples/pr-review-checks/roles/security-scanner.yaml +0 -6
  1129. package/references/openteams/examples/pr-review-checks/roles/summarizer.yaml +0 -6
  1130. package/references/openteams/examples/pr-review-checks/roles/test-checker.yaml +0 -8
  1131. package/references/openteams/examples/pr-review-checks/team.yaml +0 -64
  1132. package/references/openteams/examples/security-audit/roles/code-analyzer.yaml +0 -6
  1133. package/references/openteams/examples/security-audit/roles/dep-scanner.yaml +0 -7
  1134. package/references/openteams/examples/security-audit/roles/fixer.yaml +0 -9
  1135. package/references/openteams/examples/security-audit/roles/pr-creator.yaml +0 -6
  1136. package/references/openteams/examples/security-audit/roles/prioritizer.yaml +0 -6
  1137. package/references/openteams/examples/security-audit/roles/secrets-scanner.yaml +0 -6
  1138. package/references/openteams/examples/security-audit/roles/verifier.yaml +0 -8
  1139. package/references/openteams/examples/security-audit/team.yaml +0 -102
  1140. package/references/openteams/media/banner.png +0 -0
  1141. package/references/openteams/media/editor.png +0 -0
  1142. package/references/openteams/package-lock.json +0 -4804
  1143. package/references/openteams/package.json +0 -58
  1144. package/references/openteams/schema/role.schema.json +0 -147
  1145. package/references/openteams/schema/team.schema.json +0 -311
  1146. package/references/openteams/src/cli/editor.ts +0 -170
  1147. package/references/openteams/src/cli/generate.test.ts +0 -191
  1148. package/references/openteams/src/cli/generate.ts +0 -242
  1149. package/references/openteams/src/cli/prompt-utils.ts +0 -42
  1150. package/references/openteams/src/cli/template.test.ts +0 -365
  1151. package/references/openteams/src/cli/template.ts +0 -205
  1152. package/references/openteams/src/cli.ts +0 -22
  1153. package/references/openteams/src/generators/agent-prompt-generator.test.ts +0 -426
  1154. package/references/openteams/src/generators/agent-prompt-generator.ts +0 -556
  1155. package/references/openteams/src/generators/package-generator.test.ts +0 -129
  1156. package/references/openteams/src/generators/package-generator.ts +0 -110
  1157. package/references/openteams/src/generators/skill-generator.test.ts +0 -274
  1158. package/references/openteams/src/generators/skill-generator.ts +0 -394
  1159. package/references/openteams/src/index.ts +0 -84
  1160. package/references/openteams/src/template/builtins.test.ts +0 -74
  1161. package/references/openteams/src/template/builtins.ts +0 -108
  1162. package/references/openteams/src/template/install-service.test.ts +0 -452
  1163. package/references/openteams/src/template/install-service.ts +0 -332
  1164. package/references/openteams/src/template/loader.test.ts +0 -1696
  1165. package/references/openteams/src/template/loader.ts +0 -804
  1166. package/references/openteams/src/template/resolver.test.ts +0 -304
  1167. package/references/openteams/src/template/resolver.ts +0 -251
  1168. package/references/openteams/src/template/types.ts +0 -229
  1169. package/references/openteams/tsconfig.cjs.json +0 -7
  1170. package/references/openteams/tsconfig.esm.json +0 -8
  1171. package/references/openteams/tsconfig.json +0 -16
  1172. package/references/openteams/vitest.config.ts +0 -9
  1173. package/references/sessionlog/.husky/pre-commit +0 -1
  1174. package/references/sessionlog/.lintstagedrc.json +0 -4
  1175. package/references/sessionlog/.prettierignore +0 -4
  1176. package/references/sessionlog/.prettierrc.json +0 -11
  1177. package/references/sessionlog/LICENSE +0 -21
  1178. package/references/sessionlog/README.md +0 -453
  1179. package/references/sessionlog/eslint.config.js +0 -58
  1180. package/references/sessionlog/package-lock.json +0 -3672
  1181. package/references/sessionlog/package.json +0 -65
  1182. package/references/sessionlog/src/__tests__/agent-hooks.test.ts +0 -570
  1183. package/references/sessionlog/src/__tests__/agent-registry.test.ts +0 -127
  1184. package/references/sessionlog/src/__tests__/claude-code-hooks.test.ts +0 -225
  1185. package/references/sessionlog/src/__tests__/claude-generator.test.ts +0 -46
  1186. package/references/sessionlog/src/__tests__/commit-msg.test.ts +0 -86
  1187. package/references/sessionlog/src/__tests__/cursor-agent.test.ts +0 -224
  1188. package/references/sessionlog/src/__tests__/e2e-live.test.ts +0 -890
  1189. package/references/sessionlog/src/__tests__/event-log.test.ts +0 -183
  1190. package/references/sessionlog/src/__tests__/flush-sentinel.test.ts +0 -105
  1191. package/references/sessionlog/src/__tests__/gemini-agent.test.ts +0 -375
  1192. package/references/sessionlog/src/__tests__/git-hooks.test.ts +0 -78
  1193. package/references/sessionlog/src/__tests__/hook-managers.test.ts +0 -121
  1194. package/references/sessionlog/src/__tests__/lifecycle-tasks.test.ts +0 -759
  1195. package/references/sessionlog/src/__tests__/opencode-agent.test.ts +0 -338
  1196. package/references/sessionlog/src/__tests__/redaction.test.ts +0 -136
  1197. package/references/sessionlog/src/__tests__/session-repo.test.ts +0 -353
  1198. package/references/sessionlog/src/__tests__/session-store.test.ts +0 -166
  1199. package/references/sessionlog/src/__tests__/setup-ccweb.test.ts +0 -466
  1200. package/references/sessionlog/src/__tests__/skill-live.test.ts +0 -461
  1201. package/references/sessionlog/src/__tests__/summarize.test.ts +0 -348
  1202. package/references/sessionlog/src/__tests__/task-plan-e2e.test.ts +0 -610
  1203. package/references/sessionlog/src/__tests__/task-plan-live.test.ts +0 -632
  1204. package/references/sessionlog/src/__tests__/transcript-timestamp.test.ts +0 -121
  1205. package/references/sessionlog/src/__tests__/types.test.ts +0 -166
  1206. package/references/sessionlog/src/__tests__/utils.test.ts +0 -333
  1207. package/references/sessionlog/src/__tests__/validation.test.ts +0 -103
  1208. package/references/sessionlog/src/__tests__/worktree.test.ts +0 -57
  1209. package/references/sessionlog/src/agent/registry.ts +0 -143
  1210. package/references/sessionlog/src/agent/session-types.ts +0 -113
  1211. package/references/sessionlog/src/agent/types.ts +0 -220
  1212. package/references/sessionlog/src/cli.ts +0 -597
  1213. package/references/sessionlog/src/commands/clean.ts +0 -133
  1214. package/references/sessionlog/src/commands/disable.ts +0 -84
  1215. package/references/sessionlog/src/commands/doctor.ts +0 -145
  1216. package/references/sessionlog/src/commands/enable.ts +0 -202
  1217. package/references/sessionlog/src/commands/explain.ts +0 -261
  1218. package/references/sessionlog/src/commands/reset.ts +0 -105
  1219. package/references/sessionlog/src/commands/resume.ts +0 -180
  1220. package/references/sessionlog/src/commands/rewind.ts +0 -195
  1221. package/references/sessionlog/src/commands/setup-ccweb.ts +0 -275
  1222. package/references/sessionlog/src/commands/status.ts +0 -172
  1223. package/references/sessionlog/src/config.ts +0 -165
  1224. package/references/sessionlog/src/events/event-log.ts +0 -126
  1225. package/references/sessionlog/src/git-operations.ts +0 -558
  1226. package/references/sessionlog/src/hooks/git-hooks.ts +0 -165
  1227. package/references/sessionlog/src/hooks/lifecycle.ts +0 -391
  1228. package/references/sessionlog/src/index.ts +0 -650
  1229. package/references/sessionlog/src/security/redaction.ts +0 -283
  1230. package/references/sessionlog/src/session/state-machine.ts +0 -452
  1231. package/references/sessionlog/src/store/checkpoint-store.ts +0 -509
  1232. package/references/sessionlog/src/store/native-store.ts +0 -173
  1233. package/references/sessionlog/src/store/provider-types.ts +0 -99
  1234. package/references/sessionlog/src/store/session-store.ts +0 -266
  1235. package/references/sessionlog/src/strategy/attribution.ts +0 -296
  1236. package/references/sessionlog/src/strategy/common.ts +0 -207
  1237. package/references/sessionlog/src/strategy/content-overlap.ts +0 -228
  1238. package/references/sessionlog/src/strategy/manual-commit.ts +0 -988
  1239. package/references/sessionlog/src/strategy/types.ts +0 -279
  1240. package/references/sessionlog/src/summarize/claude-generator.ts +0 -115
  1241. package/references/sessionlog/src/summarize/summarize.ts +0 -432
  1242. package/references/sessionlog/src/types.ts +0 -508
  1243. package/references/sessionlog/src/utils/chunk-files.ts +0 -49
  1244. package/references/sessionlog/src/utils/commit-message.ts +0 -65
  1245. package/references/sessionlog/src/utils/detect-agent.ts +0 -36
  1246. package/references/sessionlog/src/utils/hook-managers.ts +0 -125
  1247. package/references/sessionlog/src/utils/ide-tags.ts +0 -32
  1248. package/references/sessionlog/src/utils/paths.ts +0 -79
  1249. package/references/sessionlog/src/utils/preview-rewind.ts +0 -80
  1250. package/references/sessionlog/src/utils/rewind-conflict.ts +0 -121
  1251. package/references/sessionlog/src/utils/shadow-branch.ts +0 -109
  1252. package/references/sessionlog/src/utils/string-utils.ts +0 -46
  1253. package/references/sessionlog/src/utils/todo-extract.ts +0 -188
  1254. package/references/sessionlog/src/utils/trailers.ts +0 -187
  1255. package/references/sessionlog/src/utils/transcript-parse.ts +0 -177
  1256. package/references/sessionlog/src/utils/transcript-timestamp.ts +0 -59
  1257. package/references/sessionlog/src/utils/tree-ops.ts +0 -219
  1258. package/references/sessionlog/src/utils/tty.ts +0 -72
  1259. package/references/sessionlog/src/utils/validation.ts +0 -65
  1260. package/references/sessionlog/src/utils/worktree.ts +0 -58
  1261. package/references/sessionlog/src/wire-types.ts +0 -59
  1262. package/references/sessionlog/templates/setup-env.sh +0 -153
  1263. package/references/sessionlog/tsconfig.json +0 -18
  1264. package/references/sessionlog/vitest.config.ts +0 -12
  1265. package/references/skill-tree/.claude/settings.json +0 -6
  1266. package/references/skill-tree/.sudocode/issues.jsonl +0 -19
  1267. package/references/skill-tree/.sudocode/specs.jsonl +0 -3
  1268. package/references/skill-tree/CLAUDE.md +0 -132
  1269. package/references/skill-tree/README.md +0 -396
  1270. package/references/skill-tree/docs/GAPS_v1.md +0 -221
  1271. package/references/skill-tree/docs/INTEGRATION_PLAN.md +0 -467
  1272. package/references/skill-tree/docs/TODOS.md +0 -91
  1273. package/references/skill-tree/docs/anthropic_skill_guide.md +0 -1364
  1274. package/references/skill-tree/docs/design/federated-skill-trees.md +0 -524
  1275. package/references/skill-tree/docs/design/multi-agent-sync.md +0 -759
  1276. package/references/skill-tree/docs/scraper/BRAINSTORM.md +0 -583
  1277. package/references/skill-tree/docs/scraper/POC_PLAN.md +0 -420
  1278. package/references/skill-tree/docs/scraper/README.md +0 -170
  1279. package/references/skill-tree/examples/basic-usage.ts +0 -157
  1280. package/references/skill-tree/package-lock.json +0 -1852
  1281. package/references/skill-tree/package.json +0 -66
  1282. package/references/skill-tree/plan.md +0 -78
  1283. package/references/skill-tree/scraper/README.md +0 -123
  1284. package/references/skill-tree/scraper/docs/DESIGN.md +0 -683
  1285. package/references/skill-tree/scraper/docs/PLAN.md +0 -336
  1286. package/references/skill-tree/scraper/drizzle.config.ts +0 -10
  1287. package/references/skill-tree/scraper/package-lock.json +0 -6329
  1288. package/references/skill-tree/scraper/package.json +0 -68
  1289. package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-description.md +0 -7
  1290. package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-name.md +0 -7
  1291. package/references/skill-tree/scraper/test/fixtures/minimal-skill/SKILL.md +0 -27
  1292. package/references/skill-tree/scraper/test/fixtures/skill-json/SKILL.json +0 -21
  1293. package/references/skill-tree/scraper/test/fixtures/skill-with-meta/SKILL.md +0 -54
  1294. package/references/skill-tree/scraper/test/fixtures/skill-with-meta/_meta.json +0 -24
  1295. package/references/skill-tree/scraper/test/fixtures/valid-skill/SKILL.md +0 -93
  1296. package/references/skill-tree/scraper/test/fixtures/valid-skill/_meta.json +0 -22
  1297. package/references/skill-tree/scraper/tsup.config.ts +0 -14
  1298. package/references/skill-tree/scraper/vitest.config.ts +0 -17
  1299. package/references/skill-tree/scripts/convert-to-vitest.ts +0 -166
  1300. package/references/skill-tree/skills/skill-writer/SKILL.md +0 -339
  1301. package/references/skill-tree/skills/skill-writer/references/examples.md +0 -326
  1302. package/references/skill-tree/skills/skill-writer/references/patterns.md +0 -210
  1303. package/references/skill-tree/skills/skill-writer/references/quality-checklist.md +0 -123
  1304. package/references/skill-tree/test/run-all.ts +0 -106
  1305. package/references/skill-tree/test/utils.ts +0 -128
  1306. package/references/skill-tree/vitest.config.ts +0 -16
  1307. package/references/swarmkit/LICENSE +0 -21
  1308. package/references/swarmkit/README.md +0 -130
  1309. package/references/swarmkit/docs/design.md +0 -453
  1310. package/references/swarmkit/docs/package-setup-reference.md +0 -519
  1311. package/references/swarmkit/package-lock.json +0 -1938
  1312. package/references/swarmkit/package.json +0 -43
  1313. package/references/swarmkit/src/cli.ts +0 -41
  1314. package/references/swarmkit/src/commands/add.ts +0 -126
  1315. package/references/swarmkit/src/commands/doctor.ts +0 -117
  1316. package/references/swarmkit/src/commands/hive.ts +0 -279
  1317. package/references/swarmkit/src/commands/init/phases/configure.ts +0 -74
  1318. package/references/swarmkit/src/commands/init/phases/global-setup.ts +0 -104
  1319. package/references/swarmkit/src/commands/init/phases/packages.ts +0 -44
  1320. package/references/swarmkit/src/commands/init/phases/project.ts +0 -81
  1321. package/references/swarmkit/src/commands/init/phases/use-case.ts +0 -47
  1322. package/references/swarmkit/src/commands/init/state.test.ts +0 -23
  1323. package/references/swarmkit/src/commands/init/state.ts +0 -22
  1324. package/references/swarmkit/src/commands/init/wizard.ts +0 -160
  1325. package/references/swarmkit/src/commands/init.ts +0 -17
  1326. package/references/swarmkit/src/commands/login.ts +0 -106
  1327. package/references/swarmkit/src/commands/logout.ts +0 -22
  1328. package/references/swarmkit/src/commands/remove.ts +0 -72
  1329. package/references/swarmkit/src/commands/status.ts +0 -101
  1330. package/references/swarmkit/src/commands/update.ts +0 -62
  1331. package/references/swarmkit/src/commands/whoami.ts +0 -41
  1332. package/references/swarmkit/src/config/global.test.ts +0 -258
  1333. package/references/swarmkit/src/config/global.ts +0 -141
  1334. package/references/swarmkit/src/config/keys.test.ts +0 -109
  1335. package/references/swarmkit/src/config/keys.ts +0 -49
  1336. package/references/swarmkit/src/doctor/checks.test.ts +0 -366
  1337. package/references/swarmkit/src/doctor/checks.ts +0 -292
  1338. package/references/swarmkit/src/doctor/types.ts +0 -33
  1339. package/references/swarmkit/src/hub/auth-flow.test.ts +0 -127
  1340. package/references/swarmkit/src/hub/auth-flow.ts +0 -144
  1341. package/references/swarmkit/src/hub/client.test.ts +0 -224
  1342. package/references/swarmkit/src/hub/client.ts +0 -185
  1343. package/references/swarmkit/src/hub/credentials.test.ts +0 -132
  1344. package/references/swarmkit/src/hub/credentials.ts +0 -51
  1345. package/references/swarmkit/src/index.ts +0 -116
  1346. package/references/swarmkit/src/packages/installer.test.ts +0 -365
  1347. package/references/swarmkit/src/packages/installer.ts +0 -206
  1348. package/references/swarmkit/src/packages/plugin.test.ts +0 -141
  1349. package/references/swarmkit/src/packages/plugin.ts +0 -46
  1350. package/references/swarmkit/src/packages/registry.test.ts +0 -235
  1351. package/references/swarmkit/src/packages/registry.ts +0 -209
  1352. package/references/swarmkit/src/packages/setup.test.ts +0 -1395
  1353. package/references/swarmkit/src/packages/setup.ts +0 -671
  1354. package/references/swarmkit/src/utils/ui.test.ts +0 -115
  1355. package/references/swarmkit/src/utils/ui.ts +0 -62
  1356. package/references/swarmkit/tsconfig.json +0 -17
  1357. package/references/swarmkit/vitest.config.ts +0 -9
@@ -1,120 +0,0 @@
1
- {"id":"i-2fao","uuid":"a882b187-cbbd-4991-b01d-ecf245d7f097","title":"Add agent permission type definitions","content":"# Add Agent Permission Types\n\n## Context\nImplements Phase 1 of [[s-4cts]] for permissions (PERM-004).\n\n## Requirements\nAdd type definitions for the hybrid agent permission model (role defaults + per-agent overrides).\n\n## Types to Add\n\n### Permission Rule Types\n```typescript\ntype AgentVisibilityRule =\n | 'all' | 'hierarchy' | 'scoped' | 'direct'\n | { include: AgentId[] };\n\ntype ScopeVisibilityRule =\n | 'all' | 'member'\n | { include: ScopeId[] };\n\ntype StructureVisibilityRule = 'full' | 'local' | 'none';\n\ntype AgentMessagingRule =\n | 'all' | 'hierarchy' | 'scoped'\n | { include: AgentId[] };\n\ntype ScopeMessagingRule =\n | 'all' | 'member'\n | { include: ScopeId[] };\n\ntype AgentAcceptanceRule =\n | 'all' | 'hierarchy' | 'scoped'\n | { include: AgentId[] };\n\ntype ClientAcceptanceRule =\n | 'all' | 'none'\n | { include: ParticipantId[] };\n\ntype SystemAcceptanceRule =\n | 'all' | 'none'\n | { include: string[] };\n```\n\n### AgentPermissions Interface\n```typescript\ninterface AgentPermissions {\n canSee?: {\n agents?: AgentVisibilityRule;\n scopes?: ScopeVisibilityRule;\n structure?: StructureVisibilityRule;\n };\n canMessage?: {\n agents?: AgentMessagingRule;\n scopes?: ScopeMessagingRule;\n };\n acceptsFrom?: {\n agents?: AgentAcceptanceRule;\n clients?: ClientAcceptanceRule;\n systems?: SystemAcceptanceRule;\n };\n}\n```\n\n### Agent Interface Update\nAdd `permissionOverrides?: Partial<AgentPermissions>` to `Agent` interface.\n\n### AgentPermissionConfig\n```typescript\ninterface AgentPermissionConfig {\n defaultPermissions: AgentPermissions;\n rolePermissions: { [role: string]: AgentPermissions };\n}\n```\n\n## Files to Modify\n- `ts-sdk/src/types/index.ts`\n\n## Acceptance Criteria\n- [ ] All rule types added and exported\n- [ ] `AgentPermissions` interface added\n- [ ] `Agent.permissionOverrides` field added\n- [ ] `AgentPermissionConfig` added\n- [ ] Existing `Agent.visibility` preserved (backwards compat)\n- [ ] Types documented with JSDoc comments","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 04:28:42","updated_at":"2026-01-29 04:33:58","closed_at":"2026-01-29 04:33:58","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-2fao","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["p1","permissions","phase-1","types"]}
2
- {"id":"i-3f48","uuid":"74c909af-a785-4df7-840c-15a739cb9aea","title":"Add streaming backpressure type definitions","content":"# Add Streaming Backpressure Types\n\n## Context\nImplements Phase 1 of [[s-4cts]] for streaming (STREAM-004/005/006).\n\n## Requirements\nAdd type definitions for streaming backpressure, pause/resume, and overflow handling.\n\n## Types to Add\n\n### StreamingCapabilities\n```typescript\ninterface StreamingCapabilities {\n supportsAck?: boolean;\n supportsFlowControl?: boolean;\n supportsPause?: boolean;\n}\n```\n\nAdd to `ParticipantCapabilities.streaming`.\n\n### SubscriptionState\n```typescript\ntype SubscriptionState = 'active' | 'paused' | 'closed';\n```\n\n### OverflowInfo\n```typescript\ninterface OverflowInfo {\n eventsDropped: number;\n oldestDroppedId?: string;\n newestDroppedId?: string;\n timestamp: number;\n totalDropped: number;\n}\n\ntype OverflowHandler = (info: OverflowInfo) => void;\n```\n\n### SubscriptionAckParams\n```typescript\ninterface SubscriptionAckParams {\n subscriptionId: SubscriptionId;\n upToSequence: number;\n}\n```\n\n## Files to Modify\n- `ts-sdk/src/types/index.ts`\n\n## Acceptance Criteria\n- [ ] All types added and exported\n- [ ] `ParticipantCapabilities` extended with `streaming` field\n- [ ] Types documented with JSDoc comments\n- [ ] No breaking changes to existing types","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 04:28:42","updated_at":"2026-01-29 04:33:58","closed_at":"2026-01-29 04:33:58","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-3f48","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["p1","phase-1","streaming","types"]}
3
- {"id":"i-1ha9","uuid":"6a10452a-a15c-4876-bf74-44c3fae64a53","title":"Add dynamic permission update type definitions","content":"# Add Dynamic Permission Update Types\n\n## Context\nImplements Phase 1 of [[s-4cts]] for permissions (PERM-005).\n\n## Requirements\nAdd type definitions for dynamic permission updates (Flow 1: system→client, Flow 4: owner→agent).\n\n## Types to Add\n\n### PermissionsUpdateRequestParams\n```typescript\ninterface PermissionsUpdateRequestParams {\n clientId?: ParticipantId;\n permissions: Partial<ParticipantCapabilities>;\n _meta?: Meta;\n}\n\ninterface PermissionsUpdateResponseResult {\n success: boolean;\n effectivePermissions: ParticipantCapabilities;\n _meta?: Meta;\n}\n```\n\n### UpdateAgentRequestParams Update\nAdd `permissionOverrides?: Partial<AgentPermissions>` to existing interface.\n\n### Permission Event Types\n```typescript\nconst PERMISSION_EVENT_TYPES = {\n PERMISSIONS_CLIENT_UPDATED: 'permissions_client_updated',\n PERMISSIONS_AGENT_UPDATED: 'permissions_agent_updated',\n} as const;\n\ninterface PermissionsClientUpdatedEventData {\n clientId: ParticipantId;\n changes: Partial<ParticipantCapabilities>;\n effectivePermissions: ParticipantCapabilities;\n updatedBy: ParticipantId;\n}\n\ninterface PermissionsAgentUpdatedEventData {\n agentId: AgentId;\n changes: Partial<AgentPermissions>;\n effectivePermissions: AgentPermissions;\n updatedBy: ParticipantId;\n}\n```\n\n### Method Registration\nAdd `'map/permissions/update'` to protocol method registry.\n\n## Files to Modify\n- `ts-sdk/src/types/index.ts`\n- `ts-sdk/src/protocol/index.ts`\n\n## Acceptance Criteria\n- [ ] Request/response types added\n- [ ] Event types and data interfaces added\n- [ ] `UpdateAgentRequestParams` extended\n- [ ] Method registered in protocol registry\n- [ ] Types documented with JSDoc comments","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 04:28:43","updated_at":"2026-01-29 04:37:56","closed_at":"2026-01-29 04:37:56","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1ha9","from_type":"issue","to":"i-2fao","to_type":"issue","type":"depends-on"},{"from":"i-1ha9","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["p1","permissions","phase-1","types"],"feedback":[{"id":"d96771a0-b70a-4598-b82c-db9dbcb5667a","from_id":"i-1ha9","to_id":"s-4cts","feedback_type":"comment","content":"Implementation completed for dynamic permission update types:\n- Added PermissionsUpdateRequest to MAPRequest union type\n- All permission update types now properly integrated into the type system\n- TypeScript compilation verified","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T04:37:51.549Z","updated_at":"2026-01-29T04:37:51.549Z"}]}
4
- {"id":"i-6yme","uuid":"83ed31ac-ba4a-4578-afe7-d1b18bd7211f","title":"Add federation envelope type definitions","content":"# Add Federation Envelope Types\n\n## Context\nImplements Phase 1 of [[s-4cts]] for federation (FED-001).\n\n## Requirements\nAdd type definitions for federation envelope with routing metadata.\n\n## Types to Add\n\n### FederationMetadata\n```typescript\ninterface FederationMetadata {\n sourceSystem: string;\n targetSystem: string;\n hopCount: number;\n maxHops?: number;\n path?: string[];\n originTimestamp: Timestamp;\n correlationId?: string;\n signature?: string; // TODO: Define signing later\n}\n```\n\n### FederationEnvelope\n```typescript\ninterface FederationEnvelope<T = unknown> {\n payload: T;\n federation: FederationMetadata;\n}\n```\n\n### FederationRoutingConfig\n```typescript\ninterface FederationRoutingConfig {\n systemId: string;\n maxHops?: number;\n trackPath?: boolean;\n allowedTargets?: string[];\n allowedSources?: string[];\n}\n```\n\n### Updated FederationRouteRequestParams\n```typescript\ninterface FederationRouteRequestParams {\n systemId: string;\n envelope: FederationEnvelope<Message>;\n /** @deprecated Use envelope instead */\n message?: Message;\n _meta?: Meta;\n}\n```\n\n### New Error Codes\n```typescript\n// Add to ERROR_CODES\nFEDERATION_LOOP_DETECTED: 5010,\nFEDERATION_MAX_HOPS_EXCEEDED: 5011,\n```\n\n## Files to Modify\n- `ts-sdk/src/types/index.ts`\n\n## Acceptance Criteria\n- [ ] `FederationMetadata` interface added\n- [ ] `FederationEnvelope<T>` generic added\n- [ ] `FederationRoutingConfig` added\n- [ ] `FederationRouteRequestParams` updated with envelope\n- [ ] Old `message` field marked deprecated\n- [ ] Error codes added\n- [ ] Types documented with JSDoc comments","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 04:28:43","updated_at":"2026-01-29 04:33:59","closed_at":"2026-01-29 04:33:59","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6yme","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["federation","p1","phase-1","types"]}
5
- {"id":"i-9xsr","uuid":"896b545d-d63b-4c5a-8fb7-c86fe5ec43a2","title":"Add federation reconnection type definitions","content":"# Add Federation Reconnection Types\n\n## Context\nImplements Phase 1 of [[s-4cts]] for federation (FED-003/004).\n\n## Requirements\nAdd type definitions for gateway reconnection and recovery (buffer + replay).\n\n## Types to Add\n\n### GatewayReconnectionOptions\n```typescript\ninterface GatewayReconnectionOptions {\n enabled: boolean;\n maxRetries?: number;\n baseDelayMs?: number;\n maxDelayMs?: number;\n jitter?: boolean;\n}\n```\n\n### FederationBufferConfig\n```typescript\ninterface FederationBufferConfig {\n enabled?: boolean;\n maxQueueSize?: number;\n maxQueueDuration?: number;\n overflowPolicy?: 'drop-oldest' | 'drop-newest' | 'reject-new';\n}\n```\n\n### FederationReplayConfig\n```typescript\ninterface FederationReplayConfig {\n enabled?: boolean;\n eventTypes?: EventType[];\n maxEvents?: number;\n maxAgeMs?: number;\n}\n```\n\n### GatewayConnectionOptions Update\n```typescript\ninterface GatewayConnectionOptions extends BaseConnectionOptions {\n name?: string;\n capabilities?: ParticipantCapabilities;\n routing?: FederationRoutingConfig;\n reconnection?: GatewayReconnectionOptions;\n buffer?: FederationBufferConfig;\n replay?: FederationReplayConfig;\n createStream?: () => Promise<Stream>;\n}\n```\n\n### GatewayReconnectionEvent\n```typescript\ntype GatewayReconnectionEventType =\n | 'disconnected'\n | 'reconnecting'\n | 'reconnected'\n | 'reconnectFailed'\n | 'bufferOverflow'\n | 'replayStarted'\n | 'replayCompleted';\n\ninterface GatewayReconnectionEvent {\n type: GatewayReconnectionEventType;\n timestamp: number;\n attempt?: number;\n peerId?: string;\n eventsReplayed?: number;\n messagesBuffered?: number;\n error?: Error;\n}\n\ntype GatewayReconnectionEventHandler = (event: GatewayReconnectionEvent) => void;\n```\n\n## Files to Modify\n- `ts-sdk/src/types/index.ts`\n- `ts-sdk/src/connection/gateway.ts` (update options interface)\n\n## Acceptance Criteria\n- [ ] All config interfaces added\n- [ ] `GatewayConnectionOptions` extended\n- [ ] Reconnection event types added\n- [ ] Types documented with JSDoc comments\n- [ ] Consistent with ClientConnection/AgentConnection patterns","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 04:28:43","updated_at":"2026-01-29 04:37:56","closed_at":"2026-01-29 04:37:56","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-9xsr","from_type":"issue","to":"i-6yme","to_type":"issue","type":"depends-on"},{"from":"i-9xsr","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["federation","p1","phase-1","types"],"feedback":[{"id":"391e9508-6d60-4076-8ff2-80e581a259bf","from_id":"i-9xsr","to_id":"s-4cts","feedback_type":"comment","content":"Implementation completed for federation reconnection types:\n- Added FederationBufferConfig for outage message buffering\n- Added FederationReplayConfig for event store recovery\n- Added GatewayReconnectionEventType and GatewayReconnectionEvent for lifecycle tracking\n- Added GatewayReconnectionEventHandler type\n- Added GatewayReconnectionOptions combining all reconnection settings\n- TypeScript compilation verified","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T04:37:51.910Z","updated_at":"2026-01-29T04:37:51.910Z"}]}
6
- {"id":"i-1jg7","uuid":"9f090a9f-0b69-48b9-bbf2-5a59f4e8811a","title":"Implement agent permission resolution","content":"# Implement Agent Permission Resolution\n\n## Context\nImplements Phase 2 of [[s-4cts]] for permissions (PERM-004).\n\n## Requirements\nImplement the permission resolution algorithm and acceptance check functions.\n\n## Implementation\n\n### Create Permission Module\nCreate `ts-sdk/src/permissions/index.ts`:\n\n```typescript\nimport type {\n Agent,\n AgentId,\n AgentPermissions,\n AgentPermissionConfig,\n ParticipantId,\n ParticipantType,\n} from '../types';\n\n/**\n * Deep merge two permission objects.\n * Second object's fields override first at the leaf level.\n */\nexport function deepMergePermissions(\n base: AgentPermissions,\n override: Partial<AgentPermissions>\n): AgentPermissions {\n const result = { ...base };\n \n if (override.canSee) {\n result.canSee = { ...base.canSee, ...override.canSee };\n }\n if (override.canMessage) {\n result.canMessage = { ...base.canMessage, ...override.canMessage };\n }\n if (override.acceptsFrom) {\n result.acceptsFrom = { ...base.acceptsFrom, ...override.acceptsFrom };\n }\n \n return result;\n}\n\n/**\n * Resolve effective permissions for an agent.\n * Resolution order: system defaults → role permissions → agent overrides\n */\nexport function resolveAgentPermissions(\n agent: Agent,\n config: AgentPermissionConfig\n): AgentPermissions {\n let permissions = deepClone(config.defaultPermissions);\n\n // Apply role permissions\n if (agent.role && config.rolePermissions[agent.role]) {\n permissions = deepMergePermissions(permissions, config.rolePermissions[agent.role]);\n }\n\n // Apply agent overrides\n if (agent.permissionOverrides) {\n permissions = deepMergePermissions(permissions, agent.permissionOverrides);\n }\n\n // Backwards compatibility: map legacy visibility\n if (agent.visibility && !agent.permissionOverrides?.canSee?.agents) {\n permissions.canSee = permissions.canSee ?? {};\n permissions.canSee.agents = mapVisibilityToRule(agent.visibility);\n }\n\n return permissions;\n}\n\n/**\n * Map legacy AgentVisibility to AgentVisibilityRule\n */\nfunction mapVisibilityToRule(visibility: string): AgentVisibilityRule {\n switch (visibility) {\n case 'public': return 'all';\n case 'parent-only': return 'hierarchy';\n case 'scope': return 'scoped';\n case 'system': return 'direct';\n default: return 'all';\n }\n}\n```\n\n### Implement Acceptance Check\n```typescript\nexport interface AcceptanceContext {\n senderType: ParticipantType;\n senderId: ParticipantId;\n senderAgentId?: AgentId;\n senderSystemId?: string;\n /** Agent hierarchy info for 'hierarchy' rules */\n isParent?: boolean;\n isChild?: boolean;\n isAncestor?: boolean;\n isDescendant?: boolean;\n /** Scope info for 'scoped' rules */\n sharedScopes?: string[];\n}\n\n/**\n * Check if an agent accepts messages from the given sender.\n */\nexport function canAgentAcceptMessage(\n targetAgent: Agent,\n context: AcceptanceContext,\n config: AgentPermissionConfig\n): boolean {\n const permissions = resolveAgentPermissions(targetAgent, config);\n const acceptsFrom = permissions.acceptsFrom;\n if (!acceptsFrom) return true; // No restrictions = accept all\n\n // Check based on sender type\n switch (context.senderType) {\n case 'agent':\n return checkAgentAcceptance(acceptsFrom.agents, context);\n case 'client':\n return checkClientAcceptance(acceptsFrom.clients, context.senderId);\n case 'system':\n case 'gateway':\n return checkSystemAcceptance(acceptsFrom.systems, context.senderSystemId);\n default:\n return false;\n }\n}\n\nfunction checkAgentAcceptance(rule: AgentAcceptanceRule | undefined, ctx: AcceptanceContext): boolean {\n if (!rule || rule === 'all') return true;\n if (rule === 'hierarchy') {\n return ctx.isParent || ctx.isChild || ctx.isAncestor || ctx.isDescendant || false;\n }\n if (rule === 'scoped') {\n return (ctx.sharedScopes?.length ?? 0) > 0;\n }\n if (typeof rule === 'object' && 'include' in rule) {\n return rule.include.includes(ctx.senderAgentId!);\n }\n return false;\n}\n```\n\n### Export from Module\nUpdate `ts-sdk/src/permissions/index.ts` to export all functions.\n\n## Files to Create/Modify\n- Create `ts-sdk/src/permissions/index.ts`\n- Update `ts-sdk/src/index.ts` to export permission utilities\n\n## Acceptance Criteria\n- [ ] `deepMergePermissions()` correctly merges at field level\n- [ ] `resolveAgentPermissions()` applies resolution order correctly\n- [ ] Legacy `visibility` field is mapped to `canSee.agents`\n- [ ] `canAgentAcceptMessage()` handles all sender types\n- [ ] Hierarchy rules work with parent/child/ancestor/descendant\n- [ ] Scoped rules check shared scope membership\n- [ ] Explicit include lists are checked correctly\n- [ ] Default permissions returned when no config provided","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 04:41:40","updated_at":"2026-01-29 04:47:03","closed_at":"2026-01-29 04:47:03","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1jg7","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["p1","permissions","phase-2"],"feedback":[{"id":"c9cd84df-b520-4a30-9b8c-7dbf0dc721c7","from_id":"i-1jg7","to_id":"s-4cts","feedback_type":"comment","content":"Implementation completed for agent permission resolution:\n- Added `deepMergePermissions()` for merging permission objects\n- Added `mapVisibilityToRule()` for backwards compatibility\n- Added `resolveAgentPermissions()` with 3-layer resolution (defaults → role → overrides)\n- Added `AcceptanceContext` interface for message acceptance checks\n- Added `canAgentAcceptMessage()` for checking message acceptance\n- Added `canAgentSeeAgent()` and `canAgentMessageAgent()` for visibility/messaging checks\n- Added `DEFAULT_AGENT_PERMISSION_CONFIG` for sensible defaults\n- All exports added to main index.ts","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T04:46:54.177Z","updated_at":"2026-01-29T04:46:54.177Z"}]}
7
- {"id":"i-39zy","uuid":"0b303224-dc8b-4284-842a-e57b805ade68","title":"Implement Subscription pause/resume and overflow handling","content":"# Implement Subscription Pause/Resume and Overflow\n\n## Context\nImplements Phase 2 of [[s-4cts]] for streaming (STREAM-004, STREAM-005).\n\n## Requirements\nAdd pause/resume functionality and overflow notification support to the Subscription class.\n\n## Implementation\n\n### Add New Fields to Subscription\n```typescript\n// In src/subscription/index.ts\nclass Subscription {\n // New private fields\n #state: SubscriptionState = 'active';\n #totalDropped = 0;\n readonly #overflowHandlers: Set<OverflowHandler> = new Set();\n #oldestDroppedId?: string;\n #newestDroppedId?: string;\n\n // New getters\n get state(): SubscriptionState { return this.#state; }\n get isPaused(): boolean { return this.#state === 'paused'; }\n get totalDropped(): number { return this.#totalDropped; }\n}\n```\n\n### Implement pause() and resume()\n```typescript\npause(): void {\n if (this.#state === 'closed') return;\n this.#state = 'paused';\n}\n\nresume(): void {\n if (this.#state === 'closed') return;\n this.#state = 'active';\n // Wake up iterator if waiting\n if (this.#eventResolver && this.#eventQueue.length > 0) {\n this.#eventResolver(this.#eventQueue.shift()!);\n this.#eventResolver = null;\n }\n}\n```\n\n### Update Async Iterator\n```typescript\nasync *[Symbol.asyncIterator](): AsyncIterator<Event> {\n while (!this.#closed) {\n // Check if paused - wait for resume\n while (this.#state === 'paused') {\n await new Promise<void>(resolve => {\n // Store resolver to wake on resume\n });\n }\n // ... rest of iterator logic\n }\n}\n```\n\n### Implement Overflow Handling\n```typescript\non(type: 'event' | 'overflow', handler: EventHandler | OverflowHandler): this {\n if (type === 'event') {\n this.#eventHandlers.add(handler as EventHandler);\n } else if (type === 'overflow') {\n this.#overflowHandlers.add(handler as OverflowHandler);\n }\n return this;\n}\n\n// In _pushEvent, update overflow logic:\nif (this.#eventQueue.length >= this.#bufferSize) {\n // Track dropped event info\n if (!this.#oldestDroppedId && eventId) {\n this.#oldestDroppedId = eventId;\n }\n this.#newestDroppedId = eventId;\n this.#totalDropped++;\n\n // Notify overflow handlers\n const info: OverflowInfo = {\n eventsDropped: 1,\n oldestDroppedId: this.#oldestDroppedId,\n newestDroppedId: this.#newestDroppedId,\n timestamp: Date.now(),\n totalDropped: this.#totalDropped,\n };\n for (const handler of this.#overflowHandlers) {\n try { handler(info); } catch (e) { console.error('Overflow handler error:', e); }\n }\n}\n```\n\n## Files to Modify\n- `ts-sdk/src/subscription/index.ts`\n\n## Acceptance Criteria\n- [ ] `state` getter returns current subscription state\n- [ ] `isPaused` returns true when paused\n- [ ] `pause()` stops event delivery from iterator\n- [ ] `resume()` restarts event delivery\n- [ ] Events are still buffered during pause\n- [ ] Overflow handlers are called when buffer is full\n- [ ] `totalDropped` tracks cumulative dropped events\n- [ ] `off('overflow', handler)` removes handler\n- [ ] All existing tests still pass","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 04:41:40","updated_at":"2026-01-29 04:47:02","closed_at":"2026-01-29 04:47:02","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-39zy","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["p1","phase-2","streaming"],"feedback":[{"id":"041744fe-8a01-440a-9304-2b650b3ed3ed","from_id":"i-39zy","to_id":"s-4cts","feedback_type":"comment","content":"Implementation completed for subscription pause/resume and overflow handling:\n- Added `state`, `isPaused`, `totalDropped` getters\n- Implemented `pause()` and `resume()` methods\n- Added overflow handler support via `on('overflow', handler)`\n- Events still buffered during pause, handlers still receive events\n- Async iterator properly waits during pause and resumes on `resume()`\n- TypeScript compilation verified","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T04:46:53.896Z","updated_at":"2026-01-29T04:46:53.896Z"}]}
8
- {"id":"i-3t7v","uuid":"3250c0ca-14c3-4d2e-b193-f6b9fc9165b8","title":"Implement federation envelope utilities","content":"# Implement Federation Envelope Utilities\n\n## Context\nImplements Phase 2 of [[s-4cts]] for federation (FED-001).\n\n## Requirements\nCreate utility functions for creating and processing federation envelopes.\n\n## Implementation\n\n### Create Federation Module\nCreate `ts-sdk/src/federation/envelope.ts`:\n\n```typescript\nimport type {\n FederationEnvelope,\n FederationMetadata,\n FederationRoutingConfig,\n Message,\n Timestamp,\n} from '../types';\nimport { ERROR_CODES } from '../types';\n\nexport interface CreateEnvelopeOptions {\n correlationId?: string;\n maxHops?: number;\n trackPath?: boolean;\n}\n\n/**\n * Create a new federation envelope for outbound messages.\n */\nexport function createFederationEnvelope<T>(\n payload: T,\n sourceSystem: string,\n targetSystem: string,\n options?: CreateEnvelopeOptions\n): FederationEnvelope<T> {\n return {\n payload,\n federation: {\n sourceSystem,\n targetSystem,\n hopCount: 0,\n maxHops: options?.maxHops,\n path: options?.trackPath ? [sourceSystem] : undefined,\n originTimestamp: Date.now(),\n correlationId: options?.correlationId,\n },\n };\n}\n\nexport interface ProcessEnvelopeResult<T> {\n success: true;\n envelope: FederationEnvelope<T>;\n} | {\n success: false;\n errorCode: number;\n errorMessage: string;\n}\n\n/**\n * Process an incoming federation envelope for forwarding.\n * Returns updated envelope or error if routing should be rejected.\n */\nexport function processFederationEnvelope<T>(\n envelope: FederationEnvelope<T>,\n config: FederationRoutingConfig\n): ProcessEnvelopeResult<T> {\n const { federation } = envelope;\n const maxHops = federation.maxHops ?? config.maxHops ?? 10;\n\n // Check hop count\n if (federation.hopCount >= maxHops) {\n return {\n success: false,\n errorCode: ERROR_CODES.FEDERATION_MAX_HOPS_EXCEEDED,\n errorMessage: `Message exceeded maximum hop count of ${maxHops}`,\n };\n }\n\n // Check for loops (if path tracking enabled)\n if (federation.path?.includes(config.systemId)) {\n return {\n success: false,\n errorCode: ERROR_CODES.FEDERATION_LOOP_DETECTED,\n errorMessage: `Loop detected: message already visited ${config.systemId}`,\n };\n }\n\n // Check source allowlist\n if (config.allowedSources && !config.allowedSources.includes(federation.sourceSystem)) {\n return {\n success: false,\n errorCode: ERROR_CODES.FEDERATION_ROUTE_REJECTED,\n errorMessage: `Source system ${federation.sourceSystem} not in allowed sources`,\n };\n }\n\n // Check target allowlist\n if (config.allowedTargets && !config.allowedTargets.includes(federation.targetSystem)) {\n return {\n success: false,\n errorCode: ERROR_CODES.FEDERATION_ROUTE_REJECTED,\n errorMessage: `Target system ${federation.targetSystem} not in allowed targets`,\n };\n }\n\n // Update for forwarding\n return {\n success: true,\n envelope: {\n payload: envelope.payload,\n federation: {\n ...federation,\n hopCount: federation.hopCount + 1,\n path: config.trackPath\n ? [...(federation.path ?? []), config.systemId]\n : federation.path,\n },\n },\n };\n}\n\n/**\n * Check if an envelope has reached its final destination.\n */\nexport function isEnvelopeAtDestination(\n envelope: FederationEnvelope<unknown>,\n currentSystemId: string\n): boolean {\n return envelope.federation.targetSystem === currentSystemId;\n}\n\n/**\n * Extract the original message from a federation envelope.\n */\nexport function unwrapEnvelope<T>(envelope: FederationEnvelope<T>): T {\n return envelope.payload;\n}\n\n/**\n * Get routing metadata for logging/debugging.\n */\nexport function getEnvelopeRoutingInfo(envelope: FederationEnvelope<unknown>): {\n source: string;\n target: string;\n hops: number;\n path?: string[];\n age: number;\n} {\n const { federation } = envelope;\n return {\n source: federation.sourceSystem,\n target: federation.targetSystem,\n hops: federation.hopCount,\n path: federation.path,\n age: Date.now() - federation.originTimestamp,\n };\n}\n```\n\n### Export from Index\nCreate `ts-sdk/src/federation/index.ts`:\n```typescript\nexport * from './envelope';\n```\n\nUpdate `ts-sdk/src/index.ts` to export federation utilities.\n\n## Files to Create/Modify\n- Create `ts-sdk/src/federation/envelope.ts`\n- Create `ts-sdk/src/federation/index.ts`\n- Update `ts-sdk/src/index.ts`\n\n## Acceptance Criteria\n- [ ] `createFederationEnvelope()` creates valid envelopes\n- [ ] Path is only included when `trackPath: true`\n- [ ] `processFederationEnvelope()` increments hop count\n- [ ] Loop detection works when path tracking enabled\n- [ ] Max hops exceeded returns correct error code\n- [ ] Source/target allowlists are enforced\n- [ ] `isEnvelopeAtDestination()` correctly identifies final hop\n- [ ] `unwrapEnvelope()` returns payload\n- [ ] `getEnvelopeRoutingInfo()` returns debugging metadata","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 04:41:40","updated_at":"2026-01-29 04:47:03","closed_at":"2026-01-29 04:47:03","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-3t7v","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["federation","p1","phase-2"],"feedback":[{"id":"7527c107-f524-4008-aa6e-056d388ecbd7","from_id":"i-3t7v","to_id":"s-4cts","feedback_type":"comment","content":"Implementation completed for federation envelope utilities:\n- Created `ts-sdk/src/federation/envelope.ts`\n- Added `createFederationEnvelope()` for creating new envelopes\n- Added `processFederationEnvelope()` for routing validation\n- Loop detection via path tracking\n- Hop count validation\n- Source/target allowlist checking\n- Added helper functions: `isEnvelopeAtDestination()`, `unwrapEnvelope()`, `getEnvelopeRoutingInfo()`, `isValidEnvelope()`, `withPayload()`\n- Created `ts-sdk/src/federation/index.ts` export barrel\n- All exports added to main index.ts","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T04:46:54.424Z","updated_at":"2026-01-29T04:46:54.424Z"}]}
9
- {"id":"i-1mzr","uuid":"5a445594-0d4b-49be-bd00-6f269d98a46e","title":"Implement subscription acknowledgment support","content":"# Implement Subscription Acknowledgment Support\n\n## Context\nImplements Phase 2 of [[s-4cts]] for streaming (STREAM-006).\n\n## Requirements\nAdd optional acknowledgment support to subscriptions for backpressure.\n\n## Implementation\n\n### Add ack() Method to Subscription\n```typescript\n// In src/subscription/index.ts\n\nclass Subscription {\n // Add field to track connection for sending acks\n readonly #sendAck: ((params: SubscriptionAckParams) => void) | undefined;\n #serverSupportsAck = false;\n\n constructor(\n id: SubscriptionId,\n unsubscribe: () => Promise<void>,\n options: SubscriptionOptions = {},\n sendAck?: (params: SubscriptionAckParams) => void\n ) {\n // ... existing ...\n this.#sendAck = sendAck;\n }\n\n /**\n * Set whether server supports acknowledgments.\n * Called by connection after capability negotiation.\n * @internal\n */\n _setServerSupportsAck(supports: boolean): void {\n this.#serverSupportsAck = supports;\n }\n\n /**\n * Whether acknowledgments are supported.\n */\n get supportsAck(): boolean {\n return this.#serverSupportsAck && !!this.#sendAck;\n }\n\n /**\n * Acknowledge events up to a sequence number.\n * No-op if server doesn't support acks.\n * \n * @param upToSequence - Acknowledge all events up to and including this sequence.\n * If omitted, acknowledges up to lastSequenceNumber.\n */\n ack(upToSequence?: number): void {\n if (!this.supportsAck) return;\n \n const seq = upToSequence ?? this.#lastSequenceNumber;\n if (seq < 0) return; // No events received yet\n\n this.#sendAck!({\n subscriptionId: this.id,\n upToSequence: seq,\n });\n }\n}\n```\n\n### Update createSubscription Factory\n```typescript\nexport function createSubscription(\n id: SubscriptionId,\n unsubscribe: () => Promise<void>,\n options?: SubscriptionOptions,\n sendAck?: (params: SubscriptionAckParams) => void\n): Subscription {\n return new Subscription(id, unsubscribe, options, sendAck);\n}\n```\n\n### Update ClientConnection\n```typescript\n// In src/connection/client.ts\n\nasync subscribe(params?: SubscribeRequestParams): Promise<Subscription> {\n // ... existing request logic ...\n\n const sendAck = (ackParams: SubscriptionAckParams) => {\n this.notify(NOTIFICATION_METHODS.SUBSCRIBE_ACK, ackParams);\n };\n\n const subscription = createSubscription(\n result.subscriptionId,\n () => this.unsubscribe(result.subscriptionId),\n { filter: params?.filter },\n sendAck\n );\n\n // Check server capabilities\n const serverCaps = this.serverCapabilities?.streaming;\n subscription._setServerSupportsAck(serverCaps?.supportsAck ?? false);\n\n this.#subscriptions.set(result.subscriptionId, subscription);\n return subscription;\n}\n```\n\n## Files to Modify\n- `ts-sdk/src/subscription/index.ts`\n- `ts-sdk/src/connection/client.ts`\n- `ts-sdk/src/connection/agent.ts` (if agent supports subscriptions)\n\n## Acceptance Criteria\n- [ ] `ack()` sends notification when server supports it\n- [ ] `ack()` is no-op when server doesn't support\n- [ ] `supportsAck` getter reflects capability\n- [ ] `ack()` without argument uses lastSequenceNumber\n- [ ] Connection passes sendAck callback to subscription\n- [ ] Server capabilities are checked on subscribe\n- [ ] Notification uses correct method name","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 04:41:41","updated_at":"2026-01-29 04:47:03","closed_at":"2026-01-29 04:47:03","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1mzr","from_type":"issue","to":"i-39zy","to_type":"issue","type":"depends-on"},{"from":"i-1mzr","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["p1","phase-2","streaming"],"feedback":[{"id":"f967176a-6a51-4b93-8e71-b5160a35ab87","from_id":"i-1mzr","to_id":"s-4cts","feedback_type":"comment","content":"Implementation completed for subscription acknowledgment support:\n- Added `sendAck` callback to Subscription constructor\n- Added `_setServerSupportsAck()` internal method for capability setting\n- Added `supportsAck` getter\n- Implemented `ack(upToSequence?)` method\n- Updated `createSubscription()` factory to accept sendAck callback\n- Ack is no-op when server doesn't support or no events received\n- Note: Connection integration deferred to Phase 3","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T04:47:17.678Z","updated_at":"2026-01-29T04:47:17.678Z"}]}
10
- {"id":"i-6qjs","uuid":"86c65825-3eb5-4e30-8ac1-3577a6d3eeaf","title":"Implement federation outage buffer","content":"# Implement Federation Outage Buffer\n\n## Context\nImplements Phase 2 of [[s-4cts]] for federation (FED-003).\n\n## Requirements\nCreate a buffer class for storing messages during federation outages.\n\n## Implementation\n\n### Create Buffer Class\nCreate `ts-sdk/src/federation/buffer.ts`:\n\n```typescript\nimport type {\n FederationEnvelope,\n FederationBufferConfig,\n Message,\n Timestamp,\n} from '../types';\n\ninterface BufferedMessage {\n envelope: FederationEnvelope<Message>;\n enqueuedAt: Timestamp;\n}\n\ninterface PeerBuffer {\n messages: BufferedMessage[];\n totalEnqueued: number;\n totalDropped: number;\n}\n\nconst DEFAULT_CONFIG: Required<FederationBufferConfig> = {\n enabled: true,\n maxMessages: 1000,\n maxBytes: 10 * 1024 * 1024, // 10MB\n retentionMs: 60 * 60 * 1000, // 1 hour\n overflowStrategy: 'drop-oldest',\n};\n\n/**\n * Buffer for storing outbound messages during federation outages.\n * Messages are stored per-peer and drained on reconnection.\n */\nexport class FederationOutageBuffer {\n readonly #config: Required<FederationBufferConfig>;\n readonly #buffers: Map<string, PeerBuffer> = new Map();\n\n constructor(config?: FederationBufferConfig) {\n this.#config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Enqueue a message for a peer.\n * Returns true if message was buffered, false if rejected.\n */\n enqueue(peerId: string, envelope: FederationEnvelope<Message>): boolean {\n if (!this.#config.enabled) return false;\n\n let buffer = this.#buffers.get(peerId);\n if (!buffer) {\n buffer = { messages: [], totalEnqueued: 0, totalDropped: 0 };\n this.#buffers.set(peerId, buffer);\n }\n\n // Evict expired messages first\n this.#evictExpired(buffer);\n\n // Check if at capacity\n if (buffer.messages.length >= this.#config.maxMessages) {\n switch (this.#config.overflowStrategy) {\n case 'drop-oldest':\n buffer.messages.shift();\n buffer.totalDropped++;\n break;\n case 'drop-newest':\n buffer.totalDropped++;\n return false;\n case 'reject':\n return false;\n }\n }\n\n buffer.messages.push({\n envelope,\n enqueuedAt: Date.now(),\n });\n buffer.totalEnqueued++;\n return true;\n }\n\n /**\n * Drain all buffered messages for a peer.\n * Returns messages in FIFO order and clears the buffer.\n */\n drain(peerId: string): FederationEnvelope<Message>[] {\n const buffer = this.#buffers.get(peerId);\n if (!buffer) return [];\n\n // Evict expired before draining\n this.#evictExpired(buffer);\n\n const messages = buffer.messages.map(m => m.envelope);\n buffer.messages = [];\n return messages;\n }\n\n /**\n * Get stats for all peer buffers.\n */\n stats(): Map<string, { count: number; oldestAge: number; totalEnqueued: number; totalDropped: number }> {\n const result = new Map();\n const now = Date.now();\n\n for (const [peerId, buffer] of this.#buffers) {\n const oldestAge = buffer.messages.length > 0\n ? now - buffer.messages[0].enqueuedAt\n : 0;\n result.set(peerId, {\n count: buffer.messages.length,\n oldestAge,\n totalEnqueued: buffer.totalEnqueued,\n totalDropped: buffer.totalDropped,\n });\n }\n\n return result;\n }\n\n /**\n * Get count for a specific peer.\n */\n count(peerId: string): number {\n return this.#buffers.get(peerId)?.messages.length ?? 0;\n }\n\n /**\n * Check if buffer has messages for a peer.\n */\n has(peerId: string): boolean {\n return this.count(peerId) > 0;\n }\n\n /**\n * Clear buffer for a specific peer.\n */\n clear(peerId: string): void {\n this.#buffers.delete(peerId);\n }\n\n /**\n * Clear all buffers.\n */\n clearAll(): void {\n this.#buffers.clear();\n }\n\n #evictExpired(buffer: PeerBuffer): void {\n const cutoff = Date.now() - this.#config.retentionMs;\n const originalLength = buffer.messages.length;\n buffer.messages = buffer.messages.filter(m => m.enqueuedAt > cutoff);\n buffer.totalDropped += originalLength - buffer.messages.length;\n }\n}\n```\n\n### Export from Index\nUpdate `ts-sdk/src/federation/index.ts`:\n```typescript\nexport * from './envelope';\nexport * from './buffer';\n```\n\n## Files to Create/Modify\n- Create `ts-sdk/src/federation/buffer.ts`\n- Update `ts-sdk/src/federation/index.ts`\n\n## Acceptance Criteria\n- [ ] Messages are stored per-peer\n- [ ] `enqueue()` returns false when buffer disabled\n- [ ] `drain()` returns messages in FIFO order\n- [ ] Expired messages are evicted before operations\n- [ ] `drop-oldest` strategy removes oldest on overflow\n- [ ] `drop-newest` strategy rejects new on overflow\n- [ ] `reject` strategy returns false on overflow\n- [ ] `stats()` returns count, age, and totals\n- [ ] `clear()` removes buffer for specific peer\n- [ ] `clearAll()` removes all buffers","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 04:41:41","updated_at":"2026-01-29 04:47:03","closed_at":"2026-01-29 04:47:03","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6qjs","from_type":"issue","to":"i-3t7v","to_type":"issue","type":"depends-on"},{"from":"i-6qjs","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["federation","p1","phase-2"],"feedback":[{"id":"65f94dc1-5001-4158-b1af-33b510b403bc","from_id":"i-6qjs","to_id":"s-4cts","feedback_type":"comment","content":"Implementation completed for federation outage buffer:\n- Created `ts-sdk/src/federation/buffer.ts`\n- Implemented `FederationOutageBuffer` class with per-peer message storage\n- Added configurable limits: maxMessages, maxBytes, retentionMs\n- Implemented overflow strategies: drop-oldest, drop-newest, reject\n- Added methods: enqueue(), drain(), peek(), stats(), count(), has(), clear(), clearAll(), peers()\n- Automatic expiry of old messages before operations\n- Size estimation for byte-based limits\n- Exported from main index.ts","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T04:47:17.459Z","updated_at":"2026-01-29T04:47:17.459Z"}]}
11
- {"id":"i-6z2w","uuid":"ddd1b8e3-b478-4378-968f-eba0aae888a2","title":"Add streaming capability advertisement to connect response","content":"## Summary\nServer should advertise streaming capabilities (particularly `supportsAck`) in the connect response so clients know whether to enable acknowledgment flow.\n\n## Tasks\n- Ensure `StreamingCapabilities` type includes `supportsAck?: boolean`\n- Update `TestServerOptions` to allow configuring streaming capabilities\n- TestServer includes `streaming` in `capabilities` field of `ConnectResponseResult`\n- Default to `supportsAck: true` for TestServer\n\n## Acceptance Criteria\n- After `connect()`, `serverCapabilities.streaming?.supportsAck` reflects server support\n- TestServer advertises ack support by default\n- Can be disabled via TestServerOptions","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 05:42:03","updated_at":"2026-01-29 05:52:50","closed_at":"2026-01-29 05:52:50","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6z2w","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["integration","phase-3","streaming"]}
12
- {"id":"i-6x1w","uuid":"983ee3b3-6522-4571-8937-05ad2d864c9d","title":"Add map/subscription/ack notification method","content":"## Summary\nDefine the JSON-RPC notification method for subscription acknowledgments.\n\n## Tasks\n- Add `SUBSCRIPTION_ACK = 'map/subscription/ack'` to appropriate method constants\n- Register in `METHOD_REGISTRY` as a notification (no response)\n- Add `SubscriptionAckNotification` type if needed\n- Document the notification format\n\n## Wire Format\n```typescript\n// Notification (no response)\n{\n jsonrpc: '2.0',\n method: 'map/subscription/ack',\n params: {\n subscriptionId: SubscriptionId,\n upToSequence: number\n }\n}\n```\n\n## Acceptance Criteria\n- Method registered in METHOD_REGISTRY\n- TypeScript types available for the notification","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 05:42:04","updated_at":"2026-01-29 05:52:50","closed_at":"2026-01-29 05:52:50","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6x1w","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["phase-3","protocol","streaming"]}
13
- {"id":"i-9ua3","uuid":"7b743e26-1790-47d9-b6cf-6b1d73d5f8bf","title":"ClientConnection ack integration with subscriptions","content":"## Summary\nWire up ClientConnection to pass ack callback to subscriptions when server supports it.\n\n## Tasks\n- After connect, check `serverCapabilities.streaming?.supportsAck`\n- In `subscribe()`, if server supports acks:\n - Create `sendAck` callback that sends `map/subscription/ack` notification\n - Pass callback to `createSubscription()`\n - Call `subscription._setServerSupportsAck(true)`\n- If server doesn't support acks, subscriptions work as before (ack is no-op)\n\n## Implementation\n```typescript\n// In subscribe()\nconst sendAck = this.#serverCapabilities?.streaming?.supportsAck\n ? (params: SubscriptionAckParams) => {\n this.#connection.sendNotification('map/subscription/ack', params);\n }\n : undefined;\n\nconst subscription = createSubscription(\n result.subscriptionId,\n () => this.unsubscribe(result.subscriptionId),\n { filter, bufferSize: options?.bufferSize },\n sendAck\n);\n\nif (sendAck) {\n subscription._setServerSupportsAck(true);\n}\n```\n\n## Acceptance Criteria\n- `subscription.supportsAck` is true when server advertises support\n- `subscription.ack()` sends notification to server\n- Works seamlessly when server doesn't support acks","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 05:42:04","updated_at":"2026-01-29 05:52:36","closed_at":"2026-01-29 05:52:36","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-9ua3","from_type":"issue","to":"i-6x1w","to_type":"issue","type":"depends-on"},{"from":"i-9ua3","from_type":"issue","to":"i-6z2w","to_type":"issue","type":"depends-on"},{"from":"i-9ua3","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["integration","phase-3","streaming"]}
14
- {"id":"i-du5c","uuid":"f48c5006-caff-4ae6-80dd-9e2a71d83fe5","title":"TestServer handles subscription ack notifications","content":"## Summary\nTestServer should receive and track subscription acknowledgments for testing and potential flow control.\n\n## Tasks\n- Add notification handler for `map/subscription/ack`\n- Track last acked sequence number per subscription in `ServerSubscription`\n- Add `lastAckedSequence` field to `ServerSubscription` interface\n- Optionally expose ack state for test assertions\n\n## Implementation\n```typescript\ninterface ServerSubscription {\n id: SubscriptionId;\n participantId: ParticipantId;\n filter?: SubscriptionFilter;\n sequenceNumber: number;\n lastAckedSequence?: number; // NEW\n}\n\n// Handle notification\ncase 'map/subscription/ack': {\n const { subscriptionId, upToSequence } = params as SubscriptionAckParams;\n const sub = this.#subscriptions.get(subscriptionId);\n if (sub) {\n sub.lastAckedSequence = upToSequence;\n }\n break;\n}\n```\n\n## Acceptance Criteria\n- TestServer receives ack notifications without error\n- Ack state accessible for test assertions\n- Server continues to function if acks not received","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 05:42:05","updated_at":"2026-01-29 05:59:25","closed_at":"2026-01-29 05:59:25","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-du5c","from_type":"issue","to":"i-6x1w","to_type":"issue","type":"depends-on"},{"from":"i-du5c","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["phase-3","streaming","testserver"]}
15
- {"id":"i-12xs","uuid":"45695664-5c44-4e90-b70b-4add26935c30","title":"TestServer permission update handler and events","content":"## Summary\nTestServer handles `map/permissions/update` requests and emits permission events.\n\n## Tasks\n### Handler for map/permissions/update\n- Add request handler for `map/permissions/update`\n- Authorization: only system participant can call this\n- Update participant's capabilities\n- Return effective permissions\n\n### Handler for agent permission updates via map/agents/update\n- Check for `permissionOverrides` in update params\n- Authorization: owner or parent owner can update\n- Store `permissionOverrides` on agent\n- Emit `permissions_agent_updated` event\n\n### Event Emission\n- Emit `permissions_client_updated` when client permissions change\n- Emit `permissions_agent_updated` when agent permissions change\n- Include changes, effective permissions, and updatedBy\n\n## Authorization Rules\n- `map/permissions/update`: Only system participants\n- Agent `permissionOverrides`: Owner or owner of parent agent\n\n## Acceptance Criteria\n- `map/permissions/update` works for system participants\n- Agent permission updates via `map/agents/update` work for owners\n- Permission events emitted to subscribers\n- Unauthorized updates rejected with PERMISSION_DENIED","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 05:42:22","updated_at":"2026-01-29 05:52:37","closed_at":"2026-01-29 05:52:37","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-12xs","from_type":"issue","to":"i-5wfz","to_type":"issue","type":"depends-on"},{"from":"i-12xs","from_type":"issue","to":"i-74vm","to_type":"issue","type":"depends-on"},{"from":"i-12xs","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["permissions","phase-3","testserver"]}
16
- {"id":"i-5wfz","uuid":"9aef2308-c887-444e-ad8f-56cc8cb8be40","title":"Add permission event types to EVENT_TYPES","content":"## Summary\nAdd permission-related event types so clients can subscribe to permission changes.\n\n## Tasks\n- Add to `EVENT_TYPES` constant:\n - `PERMISSIONS_CLIENT_UPDATED: 'permissions_client_updated'`\n - `PERMISSIONS_AGENT_UPDATED: 'permissions_agent_updated'`\n- Add event data interfaces:\n - `PermissionsClientUpdatedEventData`\n - `PermissionsAgentUpdatedEventData`\n- Export new types\n\n## Type Definitions\n```typescript\ninterface PermissionsClientUpdatedEventData {\n clientId: ParticipantId;\n changes: Partial<ParticipantCapabilities>;\n effectivePermissions: ParticipantCapabilities;\n updatedBy: ParticipantId;\n}\n\ninterface PermissionsAgentUpdatedEventData {\n agentId: AgentId;\n changes: Partial<AgentPermissions>;\n effectivePermissions: AgentPermissions;\n updatedBy: ParticipantId;\n}\n```\n\n## Acceptance Criteria\n- Event types in EVENT_TYPES constant\n- Can subscribe with `eventTypes: ['permissions_agent_updated']`\n- Event data types exported","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 05:42:22","updated_at":"2026-01-29 05:52:50","closed_at":"2026-01-29 05:52:50","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-5wfz","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["events","permissions","phase-3"]}
17
- {"id":"i-74vm","uuid":"0ce12cc2-be31-4f53-a27c-9c0393155da4","title":"Add permissionOverrides to UpdateAgentRequestParams","content":"## Summary\nAllow agent owners to update agent permissions via `map/agents/update`.\n\n## Tasks\n- Add `permissionOverrides?: Partial<AgentPermissions>` to `UpdateAgentRequestParams`\n- Add `permissionOverrides?: Partial<AgentPermissions>` to `AgentsUpdateRequestParams` (if separate)\n- Ensure type is exported\n\n## Type Update\n```typescript\ninterface UpdateAgentRequestParams {\n agentId: AgentId;\n // ... existing fields ...\n permissionOverrides?: Partial<AgentPermissions>; // NEW\n _meta?: Meta;\n}\n```\n\n## Acceptance Criteria\n- TypeScript allows `permissionOverrides` in update request\n- Type properly exported from index","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 05:42:22","updated_at":"2026-01-29 05:52:49","closed_at":"2026-01-29 05:52:49","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-74vm","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["permissions","phase-3","types"]}
18
- {"id":"i-1o8i","uuid":"6dd41eef-cc95-4baf-afe0-c2283cb77146","title":"Gateway reconnection with outage buffer integration","content":"## Summary\nAdd automatic reconnection to GatewayConnection similar to ClientConnection pattern, integrating the outage buffer for message resilience.\n\n## Tasks\n### Reconnection Infrastructure\n- Add `reconnection?: GatewayReconnectionOptions` to `GatewayConnectionOptions`\n- Add `buffer?: FederationBufferConfig` to `GatewayConnectionOptions`\n- Add `createStream?: () => Promise<Stream>` for reconnection\n- Add reconnection event handlers (`onReconnectionEvent()`)\n- Implement reconnection loop with exponential backoff\n\n### Outage Buffer Integration\n- Create `FederationOutageBuffer` instance if buffer config enabled\n- On disconnect: start buffering outbound messages\n- On reconnect: drain buffer immediately (before replay)\n- Emit `bufferOverflow` events when buffer fills\n\n### State Tracking\n- Track `lastSyncTimestamp` per connected peer\n- Update timestamp when events successfully sent/received\n- Use for replay positioning on reconnect\n\n### Reconnection Flow\n1. Detect disconnect → emit `disconnected`\n2. Start buffering outbound messages\n3. Retry connection with backoff → emit `reconnecting`\n4. On success → emit `reconnected`\n5. Drain buffered messages to peer\n6. Request replay from `lastSyncTimestamp`\n7. Emit `replayCompleted`\n\n## Event Types\n```typescript\ntype GatewayReconnectionEventType =\n | 'disconnected'\n | 'reconnecting'\n | 'reconnected'\n | 'reconnectFailed'\n | 'bufferOverflow'\n | 'replayStarted'\n | 'replayCompleted';\n```\n\n## Acceptance Criteria\n- Auto-reconnect on disconnect (if enabled)\n- Messages buffered during outage\n- Buffer drained on reconnect before replay\n- Events emitted for lifecycle tracking\n- Works without reconnection (existing behavior)","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 05:43:04","updated_at":"2026-01-29 06:01:17","closed_at":"2026-01-29 06:01:17","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1o8i","from_type":"issue","to":"i-6bgb","to_type":"issue","type":"depends-on"},{"from":"i-1o8i","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["federation","gateway","phase-3","reconnection"]}
19
- {"id":"i-3sgr","uuid":"ac013123-e8d7-41b4-92c3-80fd3edfbe71","title":"Add routing config to GatewayConnectionOptions","content":"## Summary\nAdd federation routing configuration to GatewayConnectionOptions for envelope creation.\n\n## Tasks\n- Add `routing?: FederationRoutingConfig` to `GatewayConnectionOptions`\n- Store routing config in GatewayConnection\n- Add getter for routing config\n\n## Type Update\n```typescript\nexport interface GatewayConnectionOptions extends BaseConnectionOptions {\n name?: string;\n capabilities?: ParticipantCapabilities;\n routing?: FederationRoutingConfig; // NEW\n}\n```\n\n## Usage\n```typescript\nconst gateway = new GatewayConnection(stream, {\n routing: {\n systemId: 'my-system',\n maxHops: 5,\n trackPath: true,\n allowedSources: ['trusted-peer'],\n }\n});\n```\n\n## Acceptance Criteria\n- `routing` option accepted in constructor\n- Config accessible for envelope creation\n- TypeScript types correct","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 05:43:04","updated_at":"2026-01-29 05:52:49","closed_at":"2026-01-29 05:52:49","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-3sgr","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["federation","gateway","phase-3"]}
20
- {"id":"i-6bgb","uuid":"e077988d-fa24-4cd7-98a8-d3be13a37e56","title":"Update routeToSystem to wrap messages in federation envelopes","content":"## Summary\nInternally wrap messages in federation envelopes when routing to remote systems. Backwards compatible - callers still pass Message, wrapping is internal.\n\n## Tasks\n- Update `routeToSystem()` to create envelope internally using `createFederationEnvelope()`\n- Use routing config for sourceSystem, maxHops, trackPath\n- Update `FederationRouteRequestParams` to accept both `message` (deprecated) and `envelope`\n- Send envelope in request params\n- Add optional `routeEnvelope()` method for pre-wrapped envelopes\n\n## Implementation\n```typescript\nasync routeToSystem(\n systemId: string,\n message: Message,\n options?: { correlationId?: string }\n): Promise<FederationRouteResponseResult> {\n const routing = this.#options.routing;\n \n // Create envelope internally\n const envelope = createFederationEnvelope(\n message,\n routing?.systemId ?? 'unknown',\n systemId,\n {\n maxHops: routing?.maxHops,\n trackPath: routing?.trackPath,\n correlationId: options?.correlationId,\n }\n );\n\n const params: FederationRouteRequestParams = {\n systemId,\n envelope,\n message, // Keep for backwards compat\n };\n\n return this.#connection.sendRequest(...);\n}\n\n// Optional: for pre-wrapped envelopes\nasync routeEnvelope(\n envelope: FederationEnvelope<Message>\n): Promise<FederationRouteResponseResult> {\n // ...\n}\n```\n\n## Acceptance Criteria\n- `routeToSystem()` creates envelope internally\n- Existing callers work without changes\n- Envelope includes proper routing metadata\n- Optional `routeEnvelope()` for advanced use","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 05:43:04","updated_at":"2026-01-29 05:52:36","closed_at":"2026-01-29 05:52:36","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6bgb","from_type":"issue","to":"i-3sgr","to_type":"issue","type":"depends-on"},{"from":"i-6bgb","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["federation","gateway","phase-3"]}
21
- {"id":"i-51g3","uuid":"7f69a16e-4f6d-4f01-a72f-3a55e61fe2b0","title":"TestServer federation envelope support","content":"## Summary\nUpdate TestServer to handle federation envelope format in `map/federation/route`, with backwards compatibility for plain message format.\n\n## Tasks\n### Envelope Handling\n- Check for `envelope` field in `FederationRouteRequestParams`\n- If present, extract message from `envelope.payload`\n- Validate envelope using `isValidEnvelope()`\n- Process envelope using `processFederationEnvelope()` for hop/loop checks\n- Fall back to `message` field for backwards compatibility\n\n### Routing Validation\n- Add optional `federationRouting?: FederationRoutingConfig` to `TestServerOptions`\n- If configured, validate incoming envelopes against routing config\n- Reject with appropriate error codes (loop detected, max hops, etc.)\n\n### Implementation\n```typescript\ncase FEDERATION_METHODS.FEDERATION_ROUTE: {\n const { systemId, envelope, message } = params as FederationRouteRequestParams;\n \n let actualMessage: Message;\n \n if (envelope && isValidEnvelope(envelope)) {\n // Validate routing if configured\n if (this.#options.federationRouting) {\n const result = processFederationEnvelope(envelope, this.#options.federationRouting);\n if (!result.success) {\n throw new MAPRequestError(result.errorCode, result.errorMessage);\n }\n }\n actualMessage = unwrapEnvelope(envelope);\n } else if (message) {\n // Backwards compat\n actualMessage = message;\n } else {\n throw new MAPRequestError(ERROR_CODES.INVALID_PARAMS, 'Missing envelope or message');\n }\n \n // Process message...\n}\n```\n\n## Acceptance Criteria\n- Envelope format handled correctly\n- Plain message format still works (backwards compat)\n- Routing validation when config provided\n- Proper error codes for routing failures","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 05:43:05","updated_at":"2026-01-29 05:52:49","closed_at":"2026-01-29 05:52:49","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-51g3","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["federation","phase-3","testserver"]}
22
- {"id":"i-6on2","uuid":"f1a28f86-7b18-4137-ba72-8949b86b7160","title":"Gateway event replay on reconnection","content":"## Summary\nAfter gateway reconnects, replay missed events from the peer system using existing replay infrastructure.\n\n## Tasks\n### Replay Config\n- Add `replay?: FederationReplayConfig` to `GatewayConnectionOptions`\n- Config includes: `enabled`, `eventTypes`, `maxEvents`, `maxAgeMs`\n\n### Replay Flow\n- Track `lastSyncTimestamp` per peer during normal operation\n- On reconnect, after buffer drain, request replay\n- Use `map/replay` with `afterTimestamp` parameter\n- Process replayed events through normal event handling\n- Emit `replayStarted` and `replayCompleted` events\n\n### Implementation\n```typescript\nprivate async #replayFromPeer(peerId: string): Promise<void> {\n const lastSync = this.#lastSyncTimestamps.get(peerId);\n if (!lastSync || !this.#options.replay?.enabled) return;\n\n this.#emitReconnectionEvent({ type: 'replayStarted', peerId });\n\n const result = await this.#connection.sendRequest<ReplayRequestParams, ReplayResponseResult>(\n 'map/replay',\n {\n afterTimestamp: lastSync,\n eventTypes: this.#options.replay.eventTypes,\n maxEvents: this.#options.replay.maxEvents ?? 1000,\n }\n );\n\n // Process replayed events...\n \n this.#emitReconnectionEvent({ \n type: 'replayCompleted', \n peerId, \n eventsReplayed: result.events.length \n });\n}\n```\n\n### ReplayRequestParams Update\n- Ensure `afterTimestamp?: number` is available in `ReplayRequestParams`\n- TestServer should support timestamp-based replay\n\n## Acceptance Criteria\n- Events replayed from last sync point on reconnect\n- Configurable event types and limits\n- Replay events properly processed\n- Works without replay (if disabled)","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 05:43:05","updated_at":"2026-01-29 06:02:36","closed_at":"2026-01-29 06:02:36","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6on2","from_type":"issue","to":"i-1o8i","to_type":"issue","type":"depends-on"},{"from":"i-6on2","from_type":"issue","to":"s-4cts","to_type":"spec","type":"implements"}],"tags":["federation","gateway","phase-3","replay"]}
23
- {"id":"i-3d1y","uuid":"fc02650b-3bc5-43ef-8da0-a8b0a8bb1e88","title":"Set up server module structure and shared types","content":"## Overview\n\nCreate the foundational file structure and type definitions for the MAP Server SDK.\n\n## Acceptance Criteria\n\n- [ ] Create `ts-sdk/src/server/` directory structure per spec\n- [ ] Create `types.ts` with all shared interfaces:\n - MAPEvent, EventFilter\n - AgentState, RegisteredAgent, AgentFilter\n - Scope, ScopeFilter\n - Session, SessionRole, SessionStatus, ResumeResult\n - Subscription, SubscriptionFilter, CausalOrderingOptions\n - Message, QueuedMessage, MessageQueueOptions\n - Handler, HandlerContext, HandlerRegistry, Middleware\n - PermissionResult, PermissionRule\n - CleanupStrategy, CleanupThresholds, CleanupStats\n- [ ] Create `index.ts` with placeholder exports\n- [ ] Ensure types compile without errors\n- [ ] Add JSDoc comments to all interfaces\n\n## Files to Create\n\n```\nts-sdk/src/server/\n├── index.ts\n├── types.ts\n├── events/index.ts\n├── agents/index.ts\n├── scopes/index.ts\n├── sessions/index.ts\n├── subscriptions/index.ts\n├── messages/index.ts\n├── router/index.ts\n├── permissions/index.ts\n├── cleanup/index.ts\n└── federation/index.ts\n```\n\n## Notes\n\nThis is the foundation - all other issues depend on this completing first.\n\nImplements [[s-10j2]]","status":"closed","priority":0,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:40:44","updated_at":"2026-01-29 19:57:08","closed_at":"2026-01-29 19:57:08","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-3d1y","from_type":"issue","to":"i-1xrg","to_type":"issue","type":"blocks"},{"from":"i-3d1y","from_type":"issue","to":"i-20rp","to_type":"issue","type":"blocks"},{"from":"i-3d1y","from_type":"issue","to":"i-66rq","to_type":"issue","type":"blocks"},{"from":"i-3d1y","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["foundation","server-sdk","types"]}
24
- {"id":"i-1xrg","uuid":"8c2b03fe-c002-4d20-8646-1c753185a48d","title":"Implement EventBus and InMemoryEventStore","content":"## Overview\n\nImplement the central event dispatcher and default in-memory storage backend.\n\n## Acceptance Criteria\n\n- [ ] Implement `EventStore` interface\n- [ ] Implement `InMemoryEventStore`:\n - `append(event)` - add event to storage\n - `query(filter)` - filter by types, since, until, limit\n - `getById(id)` - retrieve specific event\n - `clear()` - remove all events\n - Configurable max size with LRU eviction\n- [ ] Implement `EventBus`:\n - `emit(event)` - assigns ULID and timestamp, stores, notifies listeners\n - `on(types, handler)` - subscribe to event types, returns unsubscribe fn\n - `getEvents(filter)` - query historical events\n - Support '*' wildcard for all events\n- [ ] Unit tests for EventStore and EventBus\n- [ ] Export from `events/index.ts`\n\n## Dependencies\n\nRequires [[i-3d1y]] (types)\n\n## Technical Notes\n\n- Use ULID for event IDs (preserves time ordering)\n- EventBus should be synchronous for emit, async handlers run separately\n- Consider using Map for O(1) event lookup by ID\n\nImplements [[s-10j2]]","status":"closed","priority":0,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:40:54","updated_at":"2026-01-29 19:58:53","closed_at":"2026-01-29 19:58:53","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1xrg","from_type":"issue","to":"i-5x5t","to_type":"issue","type":"blocks"},{"from":"i-1xrg","from_type":"issue","to":"i-66rq","to_type":"issue","type":"blocks"},{"from":"i-1xrg","from_type":"issue","to":"i-6hw1","to_type":"issue","type":"blocks"},{"from":"i-1xrg","from_type":"issue","to":"i-s8b9","to_type":"issue","type":"blocks"},{"from":"i-1xrg","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["core","events","server-sdk"]}
25
- {"id":"i-s8b9","uuid":"cc1322e9-27be-42ad-b2da-ee24a594d58c","title":"Implement AgentRegistry and InMemoryAgentStore","content":"## Overview\n\nImplement agent lifecycle management with pluggable storage.\n\n## Acceptance Criteria\n\n- [ ] Implement `AgentStore` interface\n- [ ] Implement `InMemoryAgentStore`:\n - `save(agent)` - create/update agent\n - `get(id)` - retrieve by ID\n - `list(filter)` - filter by state, role, sessionId\n - `delete(id)` - remove agent\n - `clear()` - remove all\n- [ ] Implement `AgentRegistry`:\n - `register(params)` - create agent with ULID, emit `agent.registered`\n - `get(id)` - retrieve agent\n - `list(filter)` - list with filters\n - `unregister(id)` - remove agent, emit `agent.unregistered`\n - `updateState(id, state)` - change state, emit `agent.state.changed`\n - `updateMetadata(id, metadata)` - merge metadata, emit `agent.metadata.changed`\n - `unregisterBySession(sessionId)` - bulk cleanup\n- [ ] Validate state transitions (idle/busy/suspended/stopped)\n- [ ] Unit tests\n- [ ] Export from `agents/index.ts`\n\n## Dependencies\n\nRequires [[i-1xrg]] (EventBus)\n\n## Events Emitted\n\n- `agent.registered` - data: { agent }\n- `agent.unregistered` - data: { agentId }\n- `agent.state.changed` - data: { agent, previousState }\n- `agent.metadata.changed` - data: { agent, changes }\n\nImplements [[s-10j2]]","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:41:03","updated_at":"2026-01-29 20:00:29","closed_at":"2026-01-29 20:00:29","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-s8b9","from_type":"issue","to":"i-55h5","to_type":"issue","type":"blocks"},{"from":"i-s8b9","from_type":"issue","to":"i-5qhf","to_type":"issue","type":"blocks"},{"from":"i-s8b9","from_type":"issue","to":"i-7k83","to_type":"issue","type":"blocks"},{"from":"i-s8b9","from_type":"issue","to":"i-81ls","to_type":"issue","type":"blocks"},{"from":"i-s8b9","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["agents","core","server-sdk"]}
26
- {"id":"i-5x5t","uuid":"9f42161c-86e1-4f07-a865-1c36a8e7df90","title":"Implement SessionManager and InMemorySessionStore","content":"## Overview\n\nImplement session tracking with resume support.\n\n## Acceptance Criteria\n\n- [ ] Implement `SessionStore` interface\n- [ ] Implement `InMemorySessionStore`:\n - `save(session)` - create/update\n - `get(id)` - retrieve by ID\n - `getByResumeToken(token)` - lookup by resume token\n - `list(filter)` - filter by role, status\n - `delete(id)` - remove\n - `clear()` - remove all\n- [ ] Implement `SessionManager`:\n - `create(params)` - new session with ULID, status='connected', emit `session.connected`\n - `get(id)` - retrieve session\n - `list(filter)` - list with filters\n - `disconnect(id)` - set status='disconnected', generate resume token, emit `session.disconnected`\n - `resume(resumeToken)` - restore session, set status='connected', emit `session.resumed`\n - `close(id)` - permanent close, return session for cleanup\n - `expireStale(maxDisconnectMs)` - expire old disconnected sessions, emit `session.expired`\n - `addAgent/removeAgent` - track agent IDs\n - `addSubscription/removeSubscription` - track subscription IDs\n - `touch(id)` - update lastActivity\n- [ ] Configurable `resumeWindowMs` (default 5 minutes)\n- [ ] Unit tests for all lifecycle transitions\n- [ ] Export from `sessions/index.ts`\n\n## Dependencies\n\nRequires [[i-1xrg]] (EventBus)\n\n## Events Emitted\n\n- `session.connected` - data: { session }\n- `session.disconnected` - data: { sessionId, resumeToken }\n- `session.resumed` - data: { session }\n- `session.expired` - data: { sessionId }\n\nImplements [[s-10j2]]","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:41:14","updated_at":"2026-01-29 20:02:25","closed_at":"2026-01-29 20:02:25","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-5x5t","from_type":"issue","to":"i-55h5","to_type":"issue","type":"blocks"},{"from":"i-5x5t","from_type":"issue","to":"i-5w1z","to_type":"issue","type":"blocks"},{"from":"i-5x5t","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["core","server-sdk","sessions"]}
27
- {"id":"i-6hw1","uuid":"d159c38d-344c-4e6c-af29-3fadfe97ad25","title":"Implement ScopeManager and InMemoryScopeStore with hierarchy","content":"## Overview\n\nImplement scope management with parent-child hierarchy support.\n\n## Acceptance Criteria\n\n- [ ] Implement `ScopeStore` interface\n- [ ] Implement `InMemoryScopeStore`:\n - `saveScope(scope)` - create/update\n - `getScope(id)` - retrieve by ID\n - `listScopes(filter)` - filter by parentId, ancestorId\n - `deleteScope(id)` - remove\n - `getAncestors(scopeId)` - return parent chain to root\n - `getDescendants(scopeId)` - return all children recursively\n - Membership: `addMember`, `removeMember`, `getMembers`, `getScopesForAgent`\n - `clear()` - remove all\n- [ ] Implement `ScopeManager`:\n - `create(params)` - new scope with ULID, validate parentId exists, emit `scope.created`\n - `get(id)` - retrieve scope\n - `list(filter)` - list with filters\n - `delete(id, opts)` - remove scope, optionally cascade to descendants, emit `scope.deleted`\n - `getParent(scopeId)` - get parent scope\n - `getChildren(scopeId)` - get direct children\n - `getAncestors(scopeId)` - get parent chain as Scope[]\n - `getDescendants(scopeId)` - get all descendants as Scope[]\n - `join(scopeId, agentId)` - add membership, emit `scope.agent.joined`\n - `leave(scopeId, agentId)` - remove membership, emit `scope.agent.left`\n - `getMembers(scopeId, opts)` - get agents, optionally include descendants\n - `getScopesForAgent(agentId)` - get all scopes agent belongs to\n - `isMember(scopeId, agentId, opts)` - check membership, optionally check ancestors\n - `leaveAll(agentId)` - remove from all scopes (cleanup)\n- [ ] Unit tests including hierarchy operations\n- [ ] Export from `scopes/index.ts`\n\n## Dependencies\n\nRequires [[i-1xrg]] (EventBus)\n\n## Events Emitted\n\n- `scope.created` - data: { scope }\n- `scope.deleted` - data: { scopeId, deletedDescendants? }\n- `scope.agent.joined` - data: { scopeId, agentId }\n- `scope.agent.left` - data: { scopeId, agentId }\n\nImplements [[s-10j2]]","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:41:25","updated_at":"2026-01-29 20:04:19","closed_at":"2026-01-29 20:04:19","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6hw1","from_type":"issue","to":"i-5qhf","to_type":"issue","type":"blocks"},{"from":"i-6hw1","from_type":"issue","to":"i-7k83","to_type":"issue","type":"blocks"},{"from":"i-6hw1","from_type":"issue","to":"i-81ls","to_type":"issue","type":"blocks"},{"from":"i-6hw1","from_type":"issue","to":"i-h18w","to_type":"issue","type":"blocks"},{"from":"i-6hw1","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["core","scopes","server-sdk"]}
28
- {"id":"i-h18w","uuid":"91f9701e-238e-4e60-b357-651975ca4802","title":"Implement SubscriptionManager with causal ordering","content":"## Overview\n\nImplement event subscription management with causal ordering support.\n\n## Acceptance Criteria\n\n- [ ] Implement `SubscriptionStore` interface\n- [ ] Implement `InMemorySubscriptionStore`:\n - `save(subscription)` - create/update\n - `get(id)` - retrieve by ID\n - `list(filter)` - filter by sessionId\n - `delete(id)` - remove\n - `clear()` - remove all\n- [ ] Implement `CausalEventBuffer`:\n - Buffer events waiting for dependencies\n - Release events when `causedBy` event has been delivered\n - Timeout after `maxWaitMs` (default 5000ms)\n - Limit buffer size with `maxBufferSize` (default 1000)\n- [ ] Implement `SubscriptionManager`:\n - `create(params)` - new subscription with ULID, setup event listener\n - `get(id)` - retrieve subscription\n - `cancel(id)` - remove subscription, cleanup listener\n - `cancelBySession(sessionId)` - bulk cancel\n - `pause(id)` - pause delivery\n - `resume(id)` - resume delivery\n - `acknowledge(id, eventId)` - update lastEventId for replay\n - `match(event)` - find subscriptions matching event (by type, agent, scope)\n - `getEventStream(id)` - return AsyncIterable with causal ordering\n- [ ] Scope matching should include nested scopes (integrate with ScopeManager)\n- [ ] Unit tests including causal ordering scenarios\n- [ ] Export from `subscriptions/index.ts`\n\n## Dependencies\n\nRequires [[i-1xrg]] (EventBus), [[i-6hw1]] (ScopeManager for nested scope matching)\n\n## Technical Notes\n\n- Use `causedBy` field in MAPEvent for dependency tracking\n- CausalEventBuffer maintains per-subscription state\n- Consider using async generators for getEventStream\n\nImplements [[s-10j2]]","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:41:36","updated_at":"2026-01-29 20:06:44","closed_at":"2026-01-29 20:06:44","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-h18w","from_type":"issue","to":"i-55h5","to_type":"issue","type":"blocks"},{"from":"i-h18w","from_type":"issue","to":"i-7k83","to_type":"issue","type":"blocks"},{"from":"i-h18w","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["core","server-sdk","subscriptions"]}
29
- {"id":"i-81ls","uuid":"0bde587a-e748-4551-9308-c5f6a4cbc8c4","title":"Implement MessageRouter with queuing","content":"## Overview\n\nImplement message routing between agents with offline queuing support.\n\n## Acceptance Criteria\n\n- [ ] Implement `MessageQueueStore` interface\n- [ ] Implement `InMemoryMessageQueueStore`:\n - `enqueue(msg)` - add to queue with expiry\n - `dequeue(agentId, limit)` - remove and return messages\n - `peek(agentId, limit)` - view without removing\n - `remove(messageId)` - remove specific message\n - `getQueueSize(agentId)` - count for agent\n - `getTotalSize()` - total count\n - `expireOld()` - remove expired messages, return count\n - `clear()` - remove all\n- [ ] Implement `MessageRouter`:\n - `sendToAgent(params)` - send to specific agent\n - If agent online: deliver immediately via callback\n - If agent offline and queue enabled: queue message\n - Emit `message.sent`, then `message.delivered` or `message.queued`\n - `sendToScope(params)` - broadcast to scope members\n - Optionally include descendants\n - Optionally exclude sender\n - `onDeliver(handler)` - set delivery callback\n - `flushQueue(agentId)` - deliver all queued messages, return count\n - `getQueueStats()` - return total and per-agent counts\n- [ ] Configurable queue options:\n - `enabled` (default: true)\n - `maxPerAgent` (default: 100)\n - `defaultTtlMs` (default: 60000)\n - `maxTotal` (default: 10000)\n- [ ] Message priority support (lower = higher priority)\n- [ ] Unit tests including queue overflow scenarios\n- [ ] Export from `messages/index.ts`\n\n## Dependencies\n\nRequires [[i-1xrg]] (EventBus), [[i-s8b9]] (AgentRegistry), [[i-6hw1]] (ScopeManager)\n\n## Events Emitted\n\n- `message.sent` - data: { message }\n- `message.delivered` - data: { message, agentId }\n- `message.queued` - data: { message, agentId }\n- `message.expired` - data: { messageId, agentId }\n\nImplements [[s-10j2]]","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:41:49","updated_at":"2026-01-29 20:10:21","closed_at":"2026-01-29 20:10:21","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-81ls","from_type":"issue","to":"i-55h5","to_type":"issue","type":"blocks"},{"from":"i-81ls","from_type":"issue","to":"i-5qhf","to_type":"issue","type":"blocks"},{"from":"i-81ls","from_type":"issue","to":"i-7k83","to_type":"issue","type":"blocks"},{"from":"i-81ls","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["core","messages","server-sdk"]}
30
- {"id":"i-5w1z","uuid":"6a60caa1-6f4e-432d-aa87-9be62dcfd696","title":"Implement RouterConnection with middleware support","content":"## Overview\n\nImplement the JSON-RPC router that dispatches requests to handlers with middleware chain.\n\n## Acceptance Criteria\n\n- [ ] Implement `RouterConnection`:\n - Constructor takes stream, handlers, middleware, sessions, role, name, resumeToken\n - `start()` - begin processing messages\n - If resumeToken provided: attempt resume via SessionManager\n - Otherwise: create new session\n - Start reading from stream, dispatch to handlers\n - `close()` - stop processing, close stream\n - `closed` - Promise that resolves when connection ends\n - `session` - getter for current session\n - `notify(method, params)` - send JSON-RPC notification to peer\n- [ ] Request/response handling:\n - Parse incoming JSON-RPC requests\n - Correlate responses by ID\n - Handle errors with proper JSON-RPC error format\n- [ ] Middleware chain:\n - Execute middleware in order\n - Each middleware calls `next()` to continue\n - Support short-circuiting (return without calling next)\n- [ ] Session integration:\n - Create session on connect\n - Touch session on activity\n - Handle disconnect/cleanup\n- [ ] Export from `router/index.ts`\n\n## Dependencies\n\nRequires [[i-3d1y]] (types), [[i-5x5t]] (SessionManager)\n\n## Technical Notes\n\n- Middleware signature: `(method, params, ctx, next) => Promise<unknown>`\n- HandlerContext includes: session, requestId, AbortSignal\n- Use existing JSON-RPC utilities from client SDK if available\n\n## Files\n\n- `router/connection.ts` - RouterConnection implementation\n- `router/middleware.ts` - Built-in middleware helpers\n\nImplements [[s-10j2]]","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:42:00","updated_at":"2026-01-29 20:13:05","closed_at":"2026-01-29 20:13:05","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-5w1z","from_type":"issue","to":"i-7k83","to_type":"issue","type":"blocks"},{"from":"i-5w1z","from_type":"issue","to":"i-8yew","to_type":"issue","type":"blocks"},{"from":"i-5w1z","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["router","server-sdk"]}
31
- {"id":"i-7k83","uuid":"2bae366d-3438-44bd-aea8-b8ee660cd9ff","title":"Implement handler factories for all building blocks","content":"## Overview\n\nCreate handler factory functions that wire building blocks to protocol methods.\n\n## Acceptance Criteria\n\n- [ ] Implement `createConnectionHandlers(opts)`:\n - `map/connect` - handled by RouterConnection internally\n - `map/disconnect` - close session\n - `map/resume` - resume session (if supported)\n- [ ] Implement `createAgentHandlers(opts)`:\n - `map/agents/register` - call agents.register()\n - `map/agents/unregister` - call agents.unregister()\n - `map/agents/list` - call agents.list()\n - `map/agents/get` - call agents.get()\n - `map/agents/update` - call agents.updateState() or updateMetadata()\n- [ ] Implement `createScopeHandlers(opts)`:\n - `map/scopes/create` - call scopes.create()\n - `map/scopes/delete` - call scopes.delete()\n - `map/scopes/list` - call scopes.list()\n - `map/scopes/get` - call scopes.get()\n - `map/scopes/join` - call scopes.join()\n - `map/scopes/leave` - call scopes.leave()\n- [ ] Implement `createSubscriptionHandlers(opts)`:\n - `map/subscribe` - call subscriptions.create()\n - `map/unsubscribe` - call subscriptions.cancel()\n - `map/replay` - query events and send to subscriber\n- [ ] Implement `createMessageHandlers(opts)`:\n - `map/send` - call messages.sendToAgent() or sendToScope()\n- [ ] Each factory accepts optional `permissions` for fine-grained checks\n- [ ] Proper error handling with JSON-RPC error codes\n- [ ] Unit tests for each handler\n- [ ] Export all factories from `router/index.ts`\n\n## Dependencies\n\nRequires [[i-5w1z]] (RouterConnection), [[i-s8b9]] (AgentRegistry), [[i-6hw1]] (ScopeManager), [[i-h18w]] (SubscriptionManager), [[i-81ls]] (MessageRouter)\n\n## Files\n\n- `agents/handlers.ts`\n- `scopes/handlers.ts`\n- `subscriptions/handlers.ts`\n- `messages/handlers.ts`\n- `router/handlers.ts` (connection handlers)\n\nImplements [[s-10j2]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:42:12","updated_at":"2026-01-29 20:15:50","closed_at":"2026-01-29 20:15:50","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-7k83","from_type":"issue","to":"i-30vz","to_type":"issue","type":"blocks"},{"from":"i-7k83","from_type":"issue","to":"i-6tuy","to_type":"issue","type":"blocks"},{"from":"i-7k83","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["handlers","router","server-sdk"]}
32
- {"id":"i-20rp","uuid":"f54c3868-08f0-4b97-90c1-35fd117d6653","title":"Implement PermissionChecker and permission middleware","content":"## Overview\n\nImplement the permission system with method-level middleware and fine-grained checks.\n\n## Acceptance Criteria\n\n- [ ] Implement `PermissionChecker`:\n - Constructor takes rules array and defaultAllow option\n - `canCallMethod(session, method)` - check if session role can call method\n - Support glob patterns in method rules (e.g., `map/agents/*`)\n - Return `{ allowed, reason }`\n - `canAccessScope(session, scopeId, action)` - scope-level permission check\n - `canAgentPerform(agentId, action, targetId)` - agent-to-agent permission check\n- [ ] Implement `permissionMiddleware(checker)`:\n - Returns Middleware function\n - Calls `checker.canCallMethod()` before passing to next\n - Throws appropriate JSON-RPC error if denied\n- [ ] Permission rule structure:\n - `method` - glob pattern to match\n - `roles` - required session roles\n - `check` - custom function for complex logic\n- [ ] Unit tests for:\n - Glob pattern matching\n - Role-based access\n - Custom check functions\n - Default allow/deny behavior\n- [ ] Export from `permissions/index.ts`\n\n## Dependencies\n\nRequires [[i-3d1y]] (types), [[i-5x5t]] (Session types)\n\n## Files\n\n- `permissions/checker.ts` - PermissionChecker implementation\n- `permissions/middleware.ts` - permissionMiddleware function\n\n## Example Usage\n\n```typescript\nconst checker = new PermissionChecker({\n rules: [\n { method: 'map/agents/register', roles: ['agent'] },\n { method: 'map/agents/*', roles: ['client', 'agent'] },\n { method: 'map/send', check: (session, params) => {\n // Custom logic\n return { allowed: true };\n }},\n ],\n defaultAllow: false,\n});\n```\n\nImplements [[s-10j2]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:42:25","updated_at":"2026-01-29 20:17:52","closed_at":"2026-01-29 20:17:52","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-20rp","from_type":"issue","to":"i-30vz","to_type":"issue","type":"blocks"},{"from":"i-20rp","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["middleware","permissions","server-sdk"]}
33
- {"id":"i-55h5","uuid":"915ab69d-4b79-4a22-94d2-7fb789e6621e","title":"Implement ResourceCleaner for stale resource cleanup","content":"## Overview\n\nImplement the cleanup component that handles stale sessions, orphaned agents, and expired messages.\n\n## Acceptance Criteria\n\n- [ ] Implement `ResourceCleaner`:\n - Constructor takes all building blocks + thresholds + strategy\n - `run()` - execute one cleanup cycle:\n 1. Find and expire stale disconnected sessions\n 2. Unregister orphaned agents (session closed)\n 3. Cancel orphaned subscriptions (session closed)\n 4. Expire old queued messages\n 5. Call strategy callbacks for each cleanup action\n 6. Return `CleanupStats`\n - `start()` - begin automatic cleanup interval\n - `stop()` - stop automatic cleanup\n - `running` - getter for interval status\n- [ ] Configurable thresholds:\n - `sessionDisconnectMs` - max disconnect time before expire\n - `sessionInactiveMs` - max inactivity before stale\n - `intervalMs` - cleanup interval (0 = manual only)\n- [ ] Pluggable strategy:\n - `onStaleSession(session)` - called for each expired session\n - `onOrphanedAgent(agent)` - called for each unregistered agent\n - `onOrphanedSubscription(subscription)` - called for each cancelled subscription\n - `onExpiredMessages(count)` - called with expired message count\n- [ ] Unit tests for cleanup logic\n- [ ] Export from `cleanup/index.ts`\n\n## Dependencies\n\nRequires [[i-5x5t]] (SessionManager), [[i-s8b9]] (AgentRegistry), [[i-h18w]] (SubscriptionManager), [[i-81ls]] (MessageRouter)\n\n## Files\n\n- `cleanup/cleaner.ts` - ResourceCleaner implementation\n\n## Example Usage\n\n```typescript\nconst cleaner = new ResourceCleaner({\n sessions, agents, subscriptions, messages,\n thresholds: {\n sessionDisconnectMs: 5 * 60 * 1000,\n intervalMs: 60 * 1000,\n },\n strategy: {\n onStaleSession: (s) => logger.info('Cleaned session', s.id),\n },\n});\ncleaner.start();\n```\n\nImplements [[s-10j2]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:42:37","updated_at":"2026-01-29 20:19:49","closed_at":"2026-01-29 20:19:49","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-55h5","from_type":"issue","to":"i-30vz","to_type":"issue","type":"blocks"},{"from":"i-55h5","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["cleanup","server-sdk"]}
34
- {"id":"i-6tuy","uuid":"92c7a7f3-fcc6-4ce9-a37f-8d50c290ac68","title":"Implement MAPRouter interface and BaseMAPRouter class","content":"## Overview\n\nImplement the optional OOP interface for users who prefer class-based implementations.\n\n## Acceptance Criteria\n\n- [ ] Define `MAPRouter` interface with all protocol methods:\n - Connection: `connect`, `disconnect`, `resume`\n - Agents: `registerAgent`, `unregisterAgent`, `listAgents`, `getAgent`, `updateAgentState`, `updateAgentMetadata`\n - Scopes: `createScope`, `deleteScope`, `listScopes`, `getScope`, `joinScope`, `leaveScope`\n - Messages: `send`\n - Subscriptions: `subscribe`, `unsubscribe`, `replay`\n- [ ] Implement `routerToHandlers(router: MAPRouter)`:\n - Returns HandlerRegistry\n - Maps interface methods to protocol method names\n - Handles method binding correctly\n- [ ] Implement `BaseMAPRouter` abstract class:\n - Constructor takes all building blocks\n - Provides default implementations that delegate to building blocks\n - All methods can be overridden in subclasses\n- [ ] Unit tests for adapter and base router\n- [ ] Export from `router/index.ts`\n\n## Dependencies\n\nRequires [[i-7k83]] (handler factories for reference implementation)\n\n## Files\n\n- `router/interface.ts` - MAPRouter interface definition\n- `router/adapter.ts` - routerToHandlers function\n- `router/base-router.ts` - BaseMAPRouter abstract class\n\n## Example Usage\n\n```typescript\nclass MyRouter extends BaseMAPRouter {\n async registerAgent(params, ctx) {\n // Custom pre-processing\n const agent = await super.registerAgent(params, ctx);\n // Custom post-processing\n return agent;\n }\n}\n\nconst router = new MyRouter({ agents, scopes, sessions, subscriptions, messages, eventBus });\nconst connection = new RouterConnection(stream, {\n handlers: routerToHandlers(router),\n sessions,\n role: 'agent',\n});\n```\n\nImplements [[s-10j2]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:42:49","updated_at":"2026-01-29 20:23:36","closed_at":"2026-01-29 20:23:36","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6tuy","from_type":"issue","to":"i-30vz","to_type":"issue","type":"blocks"},{"from":"i-6tuy","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["oop","router","server-sdk"],"feedback":[{"id":"8116ceab-7f9f-4c90-ba69-04fa98e0d3f0","from_id":"i-6tuy","to_id":"s-10j2","feedback_type":"comment","content":"✅ **MAPRouter interface and BaseMAPRouter implementation complete**\n\n**Implementation:**\n- `routerToHandlers()` adapter converts MAPRouterInterface to HandlerRegistry using method mapping\n- `BaseMAPRouter` abstract class with default implementations delegating to building blocks\n- `DefaultMAPRouter` concrete class for direct use\n- Helper functions: `getProtocolMethods()`, `getInterfaceMethod()`\n\n**Key design decisions:**\n- Method binding preserves `this` context for subclasses\n- All 20 protocol methods mapped (connect, disconnect, agents/*, scopes/*, send, subscribe, unsubscribe, replay)\n- Default `send()` auto-detects scope vs agent recipients\n\n**Tests:** 25 tests covering adapter, base router, custom router extension, and integration with handlers","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T20:23:32.553Z","updated_at":"2026-01-29T20:23:32.553Z"}]}
35
- {"id":"i-66rq","uuid":"4dfe8c63-8f62-4f78-9c21-7a899bcd4502","title":"Implement FederationGateway and OutageBuffer","content":"## Overview\n\nImplement the federation gateway for cross-system communication with outage resilience.\n\n## Acceptance Criteria\n\n- [ ] Implement `OutageBuffer`:\n - `add(systemId, envelope)` - buffer message for system\n - `flush(systemId)` - return and clear buffered messages\n - `stats()` - return total and per-system counts\n - Configurable max messages per system\n - FIFO ordering\n- [ ] Implement `FederationGateway`:\n - Constructor takes systemId and buffer config\n - `connectPeer(params)` - establish connection to peer system\n - Handle WebSocket or other transport\n - Return PeerConnection with status\n - `routeToPeer(systemId, envelope)` - send message to peer\n - If peer connected: send immediately\n - If peer disconnected: buffer (if enabled)\n - Track hops for loop detection\n - `onPeerMessage(handler)` - register incoming message handler\n - `listPeers()` - return all peer connections\n - `disconnectPeer(systemId)` - close peer connection\n - `buffer` - getter for OutageBuffer\n- [ ] Federation envelope structure:\n - `payload` - original message\n - `routing` - from, to, hops[], maxHops\n - `timestamp`\n- [ ] Loop detection via hop tracking\n- [ ] Unit tests for buffer and gateway\n- [ ] Export from `federation/index.ts`\n\n## Dependencies\n\nRequires [[i-3d1y]] (types), [[i-1xrg]] (EventBus for internal events)\n\n## Files\n\n- `federation/gateway.ts` - FederationGateway implementation\n- `federation/buffer.ts` - OutageBuffer implementation\n\n## Technical Notes\n\n- Gateway should be transport-agnostic\n- Consider reconnection logic for peers\n- maxHops prevents infinite routing loops\n\nImplements [[s-10j2]]","status":"closed","priority":3,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:43:01","updated_at":"2026-01-29 20:26:07","closed_at":"2026-01-29 20:26:07","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-66rq","from_type":"issue","to":"i-5qhf","to_type":"issue","type":"blocks"},{"from":"i-66rq","from_type":"issue","to":"i-8yew","to_type":"issue","type":"blocks"},{"from":"i-66rq","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["federation","server-sdk"],"feedback":[{"id":"23e9ae18-65f1-47e4-b3af-b56f98ff225b","from_id":"i-66rq","to_id":"s-10j2","feedback_type":"comment","content":"✅ **FederationGateway and OutageBuffer implementation complete**\n\n**OutageBuffer:**\n- FIFO message buffering per peer system\n- Configurable max messages with oldest-drop on overflow\n- `add()`, `flush()`, `stats()`, `clear()`, `clearSystem()` methods\n\n**FederationGateway:**\n- Peer connection management with connect/disconnect/markDisconnected\n- `routeToPeer()` with automatic buffering during outages\n- Loop detection via hop tracking (throws RoutingLoopError)\n- Max hops validation (throws MaxHopsExceededError)\n- Transport-agnostic via PeerTransport interface\n- Activity tracking via lastActivity timestamps\n- `createEnvelope()` helper for creating properly structured messages\n\n**Key decisions:**\n- Transport is injected via `connectPeer()` allowing flexible transport mechanisms\n- Buffered messages are auto-flushed on peer reconnect\n- Handler errors are caught to prevent cascade failures\n\n**Tests:** 34 tests covering buffer operations, gateway routing, loop/hop validation, and activity tracking","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T20:26:03.831Z","updated_at":"2026-01-29T20:26:03.831Z"}]}
36
- {"id":"i-5qhf","uuid":"718e6b09-6564-4175-bea4-b52c64170cc6","title":"Implement federated decorators for building blocks","content":"## Overview\n\nImplement decorator classes that wrap core building blocks to add federation capabilities.\n\n## Acceptance Criteria\n\n- [ ] Implement `FederatedAgentRegistry`:\n - Wraps local AgentRegistry\n - Constructor takes local registry, gateway, and sync options\n - Sync options:\n - `onRegister` - sync new agents to peers\n - `onStateChange` - sync state changes\n - `includeRemote` - include remote agents in list()\n - Intercepts register/unregister/updateState to broadcast\n - Merges remote agents into list() results\n - Handles incoming peer agent events\n- [ ] Implement `FederatedScopeManager`:\n - Wraps local ScopeManager\n - Sync options:\n - `onCreateScope` - sync scope creation\n - `onMembershipChange` - sync join/leave\n - `includeRemote` - include remote scopes in list()\n - Similar broadcast/merge pattern as agents\n- [ ] Implement `FederatedMessageRouter`:\n - Wraps local MessageRouter\n - Routes messages to remote agents via gateway\n - Determines if target is local or remote\n - Handles incoming messages from peers\n- [ ] All decorators implement same interface as wrapped component\n- [ ] Unit tests for sync behavior\n- [ ] Export from `federation/index.ts`\n\n## Dependencies\n\nRequires [[i-66rq]] (FederationGateway), [[i-s8b9]] (AgentRegistry), [[i-6hw1]] (ScopeManager), [[i-81ls]] (MessageRouter)\n\n## Files\n\n- `federation/decorators/agents.ts` - FederatedAgentRegistry\n- `federation/decorators/scopes.ts` - FederatedScopeManager\n- `federation/decorators/messages.ts` - FederatedMessageRouter\n\n## Technical Notes\n\n- Decorators should be transparent - code using AgentRegistry works with FederatedAgentRegistry\n- Remote entities need system ID prefix or metadata to distinguish\n- Consider conflict resolution for concurrent updates\n\nImplements [[s-10j2]]","status":"closed","priority":3,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:43:13","updated_at":"2026-01-29 20:29:41","closed_at":"2026-01-29 20:29:41","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-5qhf","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["decorators","federation","server-sdk"],"feedback":[{"id":"b315c50c-4c57-448a-9c1f-d2e99ca447c8","from_id":"i-5qhf","to_id":"s-10j2","feedback_type":"comment","content":"✅ **Federated decorators implementation complete**\n\n**FederatedAgentRegistry:**\n- Wraps AgentRegistry with peer sync capabilities\n- Broadcasts register/unregister/state changes to connected peers\n- Tracks remote agents with `remote:systemId:agentId` ID format\n- Merges local+remote agents in list() when includeRemote=true\n- Handles incoming peer agent events automatically\n\n**FederatedScopeManager:**\n- Wraps ScopeManager with peer sync capabilities\n- Broadcasts scope creation/deletion and membership changes\n- Tracks remote scopes and their members\n- Throws when trying to join/leave remote scopes locally\n\n**FederatedMessageRouter:**\n- Wraps MessageRouter with remote routing\n- Auto-detects remote agents by ID prefix and routes via gateway\n- Translates remote agent IDs for target system\n- Delivers incoming federated messages to local agents\n- Prefixes sender ID with `remote:systemId:` for traceability\n\n**Key patterns:**\n- All decorators implement same interface as wrapped component (decorator pattern)\n- Remote entities prefixed with `remote:systemId:` for identification\n- Async broadcast with error handling to prevent cascade failures\n\n**Tests:** 33 tests covering all three decorators","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T20:29:37.769Z","updated_at":"2026-01-29T20:29:37.769Z"}]}
37
- {"id":"i-8yew","uuid":"aebdd1ff-0fa4-4276-b7e5-3b3a20d37b2d","title":"Implement federation handlers","content":"## Overview\n\nCreate handler factory for federation-specific protocol methods.\n\n## Acceptance Criteria\n\n- [ ] Implement `createFederationHandlers(opts)`:\n - `map/federation/connect` - connect to peer system\n - `map/federation/disconnect` - disconnect from peer\n - `map/federation/list` - list connected peers\n - `map/federation/route` - route message to peer system\n- [ ] Validate federation permissions (only gateways can call these)\n- [ ] Error handling for peer connection failures\n- [ ] Unit tests\n- [ ] Export from `federation/index.ts`\n\n## Dependencies\n\nRequires [[i-66rq]] (FederationGateway), [[i-5w1z]] (RouterConnection for handler types)\n\n## Files\n\n- `federation/handlers.ts`\n\nImplements [[s-10j2]]","status":"closed","priority":3,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:43:20","updated_at":"2026-01-29 20:31:11","closed_at":"2026-01-29 20:31:11","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-8yew","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["federation","handlers","server-sdk"],"feedback":[{"id":"4644174e-b880-47c0-a96e-f936721901be","from_id":"i-8yew","to_id":"s-10j2","feedback_type":"comment","content":"✅ **Federation handlers implementation complete**\n\n**Implemented handlers:**\n- `map/federation/connect` - Connect to a peer system\n- `map/federation/disconnect` - Disconnect from peer\n- `map/federation/list` - List connected peers\n- `map/federation/route` - Route message to peer (with queuing if disconnected)\n- `map/federation/buffer/stats` - Get buffer statistics\n- `map/federation/buffer/flush` - Flush buffered messages for a peer\n\n**Security:**\n- All handlers validate gateway role via `validateGatewayRole()`\n- Throws `FederationPermissionError` for non-gateway callers\n- Input validation for required parameters\n\n**Error handling:**\n- `FederationError` base class with JSON-RPC error code\n- `FederationPermissionError` with code -32003\n- Connection failures wrapped with descriptive messages\n\n**Tests:** 21 tests covering all handlers, permission validation, and error cases","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T20:31:07.865Z","updated_at":"2026-01-29T20:31:07.865Z"}]}
38
- {"id":"i-30vz","uuid":"60b393c5-2db9-444f-b0fa-a2cbb1a5c005","title":"Write integration tests for server SDK","content":"## Overview\n\nCreate comprehensive integration tests that verify all building blocks work together correctly.\n\n## Acceptance Criteria\n\n- [ ] Test: Basic server lifecycle\n - Create all building blocks\n - Wire handlers\n - Create RouterConnection\n - Connect client, register agent, send message\n - Verify events emitted correctly\n- [ ] Test: Session resume flow\n - Connect, disconnect with resume token\n - Reconnect with token\n - Verify session state preserved\n - Verify queued messages delivered\n- [ ] Test: Subscription with causal ordering\n - Subscribe to events\n - Emit events with dependencies\n - Verify delivery order respects causedBy\n- [ ] Test: Scope hierarchy\n - Create nested scopes\n - Join agents to various levels\n - Verify getMembers with includeDescendants\n - Verify message broadcast to scope\n- [ ] Test: Message queuing\n - Agent goes offline\n - Send messages\n - Agent reconnects\n - Verify queued messages delivered\n- [ ] Test: Permissions\n - Configure permission rules\n - Verify allowed calls succeed\n - Verify denied calls fail with proper error\n- [ ] Test: Resource cleanup\n - Create sessions/agents\n - Let them go stale\n - Run cleanup\n - Verify resources removed\n- [ ] Test: OOP interface\n - Create custom router extending BaseMAPRouter\n - Override methods\n - Verify custom logic executes\n- [ ] Export TestServer helper if needed\n\n## Dependencies\n\nRequires all building blocks to be implemented:\n- [[i-7k83]] (handlers)\n- [[i-20rp]] (permissions)\n- [[i-55h5]] (cleanup)\n- [[i-6tuy]] (OOP interface)\n\n## Files\n\n- `server/__tests__/integration.test.ts`\n- `server/__tests__/federation.test.ts` (if federation complete)\n\nImplements [[s-10j2]]","status":"closed","priority":3,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:43:32","updated_at":"2026-01-29 20:34:52","closed_at":"2026-01-29 20:34:52","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-30vz","from_type":"issue","to":"i-8ljo","to_type":"issue","type":"blocks"},{"from":"i-30vz","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["integration","server-sdk","testing"],"feedback":[{"id":"b1fb5356-0e22-4471-abf4-06a5e13ac7b0","from_id":"i-30vz","to_id":"s-10j2","feedback_type":"comment","content":"✅ **Integration tests for server SDK complete**\n\n**Test coverage:**\n1. ✅ Basic server lifecycle - building blocks wiring, event emission\n2. ✅ Session resume flow - disconnect/reconnect, session state preservation \n3. ✅ Scope hierarchy - nested scopes, hierarchy traversal, member inheritance\n4. ✅ Message broadcast - scope-level message delivery with excludeSender\n5. ✅ Permissions - method-level access control with glob patterns\n6. ✅ Resource cleanup - stale session/agent/subscription cleanup\n7. ✅ OOP interface - custom BaseMAPRouter subclasses, routerToHandlers\n8. ✅ Federation - agent sync, remote message routing, gateway role validation\n9. ✅ Full stack - complete agent workflow through handlers\n\n**Tests added:** 15 integration tests covering all building blocks working together\n\n**Total tests:** 914 passing across 32 test files","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T20:34:48.808Z","updated_at":"2026-01-29T20:34:48.808Z"}]}
39
- {"id":"i-8ljo","uuid":"ff451537-049e-408d-b28f-b07b0690d004","title":"Update server SDK exports and documentation","content":"## Overview\n\nFinalize exports from the server module and ensure all public APIs are documented.\n\n## Acceptance Criteria\n\n- [ ] Update `server/index.ts` with all public exports:\n - Types (all interfaces)\n - Building blocks (EventBus, AgentRegistry, ScopeManager, SessionManager, SubscriptionManager, MessageRouter)\n - Stores (all InMemory* implementations)\n - Router (RouterConnection, handler factories)\n - Permissions (PermissionChecker, permissionMiddleware)\n - Cleanup (ResourceCleaner)\n - OOP (MAPRouter, BaseMAPRouter, routerToHandlers)\n- [ ] Update `federation/index.ts` with federation exports\n- [ ] Ensure tree-shaking works (no side effects)\n- [ ] Add JSDoc to all exported functions/classes\n- [ ] Create usage examples in code comments\n- [ ] Update main SDK README with server usage section\n\n## Dependencies\n\nRequires [[i-30vz]] (integration tests passing)\n\n## Files\n\n- `server/index.ts` - main exports\n- `federation/index.ts` - federation exports\n- `README.md` - documentation update\n\nImplements [[s-10j2]]","status":"closed","priority":3,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 19:43:40","updated_at":"2026-01-29 20:36:51","closed_at":"2026-01-29 20:36:51","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-8ljo","from_type":"issue","to":"s-10j2","to_type":"spec","type":"implements"}],"tags":["documentation","exports","server-sdk"],"feedback":[{"id":"76bc0fa5-0baa-46a7-b893-20e6bd707b08","from_id":"i-8ljo","to_id":"s-10j2","feedback_type":"comment","content":"## Implementation Complete: Server SDK Exports and Documentation\n\n### Requirements Met\n- ✅ `server/index.ts` exports all building blocks with organized sections\n- ✅ `federation/index.ts` exports gateway, buffer, decorators, and handlers\n- ✅ Tree-shaking friendly with `export *` pattern (no side effects)\n- ✅ JSDoc documentation on exported classes and functions\n- ✅ Comprehensive integration tests serve as usage examples\n\n### Export Structure\n```typescript\n// server/index.ts sections:\n- Types (all interfaces)\n- Events (EventBus, EventStore)\n- Agents (AgentRegistry, AgentStore)\n- Sessions (SessionManager, SessionStore)\n- Scopes (ScopeManager, ScopeStore)\n- Subscriptions (SubscriptionManager with causal ordering)\n- Messages (MessageRouter with queuing)\n- Router (handler factories, BaseMAPRouter, routerToHandlers)\n- Permissions (PermissionChecker, middleware)\n- Cleanup (ResourceCleaner)\n- Federation (Gateway, Buffer, Decorators, Handlers)\n```\n\n### Evidence\n- All 914 tests passing across 32 test files\n- Integration tests demonstrate full workflows\n- Handler factories compose cleanly\n- OOP interface (BaseMAPRouter) provides clean extension points","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T20:36:51.040Z","updated_at":"2026-01-29T20:36:51.040Z"}]}
40
- {"id":"i-4d6o","uuid":"69a0d430-d265-478a-bcb2-a4020592f79f","title":"Integration tests: Connection lifecycle","content":"## Overview\n\nTest connection lifecycle flows between client SDK and server SDK.\n\n## Acceptance Criteria\n\n- [ ] Test: ClientConnection.connect() creates session on server\n- [ ] Test: AgentConnection.connect() creates session on server\n- [ ] Test: Client disconnect removes session from server\n- [ ] Test: Disconnect with `sessionPolicy: \"end\"` vs `\"pause\"`\n- [ ] Test: Connection state transitions match on both sides\n- [ ] Test: Abort signal fires on disconnect\n- [ ] Test: `closed` promise resolves on disconnect\n\n## Test Cases\n\n```typescript\ndescribe(\"Connection Lifecycle\", () => {\n it(\"client connect creates server session\")\n it(\"agent connect creates server session\")\n it(\"disconnect removes session\")\n it(\"disconnect policy 'pause' keeps session resumable\")\n it(\"disconnect policy 'end' removes session immediately\")\n it(\"connection state is 'connected' after connect\")\n it(\"connection state is 'closed' after disconnect\")\n});\n```\n\n## Files\n\n- `src/__tests__/client-server-integration.test.ts` (new)\n\nImplements [[s-2uns]]","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 21:27:35","updated_at":"2026-01-29 22:41:36","closed_at":"2026-01-29 22:41:36","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-4d6o","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["connection","integration","testing"],"feedback":[{"id":"af2fe14d-41d8-4c07-9f2d-7a9890b231f7","from_id":"i-4d6o","to_id":"s-2uns","feedback_type":"comment","content":"Connection lifecycle tests implemented in `client-server-integration.test.ts`:\n\n**Tests:**\n- `client connect creates server session`\n- `agent connect creates server session`\n- `disconnect removes client from active state`\n- `multiple clients can connect simultaneously`\n- `closed promise resolves on disconnect` (NEW)\n- `onStateChange fires during lifecycle` (NEW)\n\n**Note:** Session policy (pause/end) tests deferred - requires client SDK implementation of disconnect options first.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:41:35.871Z","updated_at":"2026-01-29T22:41:35.871Z"}]}
41
- {"id":"i-q0e1","uuid":"ea457982-a93d-4c4c-b5ee-b818fcd03d7f","title":"Create integration test harness for client-server SDK testing","content":"## Overview\n\nCreate a reusable test harness that wires client SDK connections to server SDK building blocks via stream pairs. This is the foundation for all client-server integration tests.\n\n## Acceptance Criteria\n\n- [ ] Create `src/__tests__/helpers/integration-harness.ts`\n- [ ] Implement `createIntegrationHarness()` that:\n - Creates all server building blocks (EventBus, AgentRegistry, etc.)\n - Combines handlers with `combineHandlers()`\n - Tracks active connections for cleanup\n- [ ] Implement `harness.createClient(name?)` that:\n - Creates stream pair\n - Creates ClientConnection on client stream\n - Creates RouterConnectionImpl on server stream\n - Connects and returns connection + disconnect function\n- [ ] Implement `harness.createAgent(name)` that:\n - Same as createClient but with AgentConnection\n - Registers agent and returns agent info\n- [ ] Implement `harness.cleanup()` that closes all connections\n- [ ] Add helper for message delivery tracking (`harness.onDeliver`)\n- [ ] Export types for test use\n\n## Technical Notes\n\n```typescript\ninterface IntegrationTestHarness {\n // Server building blocks (exposed for assertions)\n eventBus: EventBusImpl;\n agents: AgentRegistryImpl;\n scopes: ScopeManagerImpl;\n sessions: SessionManagerImpl;\n subscriptions: SubscriptionManagerImpl;\n messages: MessageRouterImpl;\n\n createClient(name?: string): Promise<ConnectedClient>;\n createAgent(name: string): Promise<ConnectedAgent>;\n cleanup(): Promise<void>;\n}\n```\n\n## Files\n\n- `src/__tests__/helpers/integration-harness.ts` (new)\n\nImplements [[s-2uns]]","status":"closed","priority":0,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 21:27:35","updated_at":"2026-01-29 22:39:45","closed_at":"2026-01-29 22:39:45","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-q0e1","from_type":"issue","to":"i-2fgd","to_type":"issue","type":"blocks"},{"from":"i-q0e1","from_type":"issue","to":"i-3hrd","to_type":"issue","type":"blocks"},{"from":"i-q0e1","from_type":"issue","to":"i-3tad","to_type":"issue","type":"blocks"},{"from":"i-q0e1","from_type":"issue","to":"i-4d6o","to_type":"issue","type":"blocks"},{"from":"i-q0e1","from_type":"issue","to":"i-6cfb","to_type":"issue","type":"blocks"},{"from":"i-q0e1","from_type":"issue","to":"i-7hv3","to_type":"issue","type":"blocks"},{"from":"i-q0e1","from_type":"issue","to":"i-7wos","to_type":"issue","type":"blocks"},{"from":"i-q0e1","from_type":"issue","to":"i-efmy","to_type":"issue","type":"blocks"},{"from":"i-q0e1","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["foundation","integration","testing"],"feedback":[{"id":"2fd79c8a-3032-4fd4-95d2-b9f62a999cca","from_id":"i-q0e1","to_id":"s-2uns","feedback_type":"comment","content":"Implemented the integration test harness in `src/__tests__/helpers/integration-harness.ts`:\n\n**Features:**\n- `createIntegrationHarness()` creates all server building blocks wired together\n- `harness.createClient(name?)` creates ClientConnection wired to RouterConnection via stream pair\n- `harness.createAgent(name, role?)` creates AgentConnection with automatic registration\n- `harness.cleanup()` closes all connections and clears state\n- Message delivery tracking via `getDeliveredMessages()`/`clearDeliveredMessages()`\n- Event wiring from EventBus to subscription notifications\n\n**Helper utilities:**\n- `waitForEvent(harness, eventType, timeout)` - waits for specific event\n- `waitForMessages(harness, count, timeout)` - waits for N messages to be delivered\n\n**Export structure:**\n- All types and functions exported from `helpers/index.ts`\n- Ready for use in all integration test files","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:39:42.421Z","updated_at":"2026-01-29T22:39:42.421Z"}]}
42
- {"id":"i-3hrd","uuid":"608a3b47-3b40-4b2a-a3ad-0aa83c252be5","title":"Integration tests: Agent operations","content":"## Overview\n\nTest agent registration and management flows between client SDK and server SDK.\n\n## Acceptance Criteria\n\n- [ ] Test: AgentConnection.register() creates agent on server\n- [ ] Test: ClientConnection.listAgents() returns registered agents\n- [ ] Test: ClientConnection.getAgent(id) returns specific agent\n- [ ] Test: AgentConnection.updateState() changes state on server\n- [ ] Test: AgentConnection.updateMetadata() merges metadata on server\n- [ ] Test: AgentConnection.unregister() removes agent from server\n- [ ] Test: Same session can register multiple agents\n- [ ] Test: Agent data matches between client response and server state\n\n## Test Cases\n\n```typescript\ndescribe(\"Agent Operations\", () => {\n it(\"register creates agent on server\")\n it(\"registered agent appears in listAgents\")\n it(\"getAgent returns correct agent data\")\n it(\"updateState changes server state\")\n it(\"updateMetadata merges with existing\")\n it(\"unregister removes from server\")\n it(\"multiple agents per session\")\n it(\"agent fields match between client and server\")\n});\n```\n\n## Files\n\n- `src/__tests__/client-server-integration.test.ts`\n\nImplements [[s-2uns]]","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 21:27:36","updated_at":"2026-01-29 22:42:06","closed_at":"2026-01-29 22:42:06","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-3hrd","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["agents","integration","testing"],"feedback":[{"id":"57be5fdf-a2ee-4624-ab35-a8d6f3350c0d","from_id":"i-3hrd","to_id":"s-2uns","feedback_type":"comment","content":"Agent operations tests implemented in `client-server-integration.test.ts`:\n\n**Tests:**\n- `register creates agent on server`\n- `registered agent appears in listAgents`\n- `getAgent returns correct agent data`\n- `updateState changes server state`\n- `updateMetadata merges with existing`\n- `disconnect unregisters agent from server`\n- `multiple independent agents`\n\n**Note:** \"Same session can register multiple agents\" - current architecture uses 1 agent per AgentConnection. Multiple agents achieved via multiple connections.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:41:57.161Z","updated_at":"2026-01-29T22:41:57.161Z"}]}
43
- {"id":"i-6cfb","uuid":"066b0de3-3f65-446b-a9b9-6a1af50aa9f5","title":"Integration tests: Scope operations","content":"## Overview\n\nTest scope creation and membership flows between client SDK and server SDK.\n\n## Acceptance Criteria\n\n- [ ] Test: AgentConnection.createScope() creates scope on server\n- [ ] Test: ClientConnection.listScopes() returns created scopes\n- [ ] Test: AgentConnection.joinScope() adds membership on server\n- [ ] Test: AgentConnection.leaveScope() removes membership on server\n- [ ] Test: Nested scopes (parentId) work correctly\n- [ ] Test: getScope() includes member list\n- [ ] Test: Scope hierarchy queries work (ancestors, descendants)\n\n## Test Cases\n\n```typescript\ndescribe(\"Scope Operations\", () => {\n it(\"createScope creates on server\")\n it(\"created scope appears in listScopes\")\n it(\"joinScope adds agent to scope members\")\n it(\"leaveScope removes agent from scope members\")\n it(\"nested scopes with parentId\")\n it(\"getScope includes members array\")\n it(\"scope hierarchy traversal\")\n});\n```\n\n## Files\n\n- `src/__tests__/client-server-integration.test.ts`\n\nImplements [[s-2uns]]","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 21:27:36","updated_at":"2026-01-29 22:42:06","closed_at":"2026-01-29 22:42:06","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6cfb","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["integration","scopes","testing"],"feedback":[{"id":"402e4236-0424-4498-bd01-2833c2c3816e","from_id":"i-6cfb","to_id":"s-2uns","feedback_type":"comment","content":"Scope operations tests implemented in `client-server-integration.test.ts`:\n\n**Tests:**\n- `createScope creates on server`\n- `created scope appears in listScopes`\n- `joinScope adds agent to scope members`\n- `leaveScope removes agent from scope members`\n- `nested scopes with parentId`\n\n**Note:** getScope with members and hierarchy traversal tested via server-side assertions using harness.scopes.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:41:57.321Z","updated_at":"2026-01-29T22:41:57.321Z"}]}
44
- {"id":"i-efmy","uuid":"823e0fea-b4d9-4759-ae00-f3cef66b451f","title":"Integration tests: Messaging","content":"## Overview\n\nTest message routing between agents via client SDK and server SDK.\n\n## Acceptance Criteria\n\n- [ ] Test: Agent A sends message to Agent B, B receives it\n- [ ] Test: Agent sends to scope, all members receive\n- [ ] Test: Client can send message to agent\n- [ ] Test: onMessage handler receives sent messages\n- [ ] Test: Message fields (id, from, to, timestamp) preserved\n- [ ] Test: excludeSender option works for scope broadcast\n- [ ] Test: Message payload is preserved exactly\n\n## Test Cases\n\n```typescript\ndescribe(\"Messaging\", () => {\n it(\"agent to agent delivery\")\n it(\"agent to scope broadcast\")\n it(\"client to agent message\")\n it(\"onMessage handler invoked\")\n it(\"message id is unique\")\n it(\"message from/to fields correct\")\n it(\"message timestamp is set\")\n it(\"excludeSender excludes sender from broadcast\")\n it(\"payload preserved exactly\")\n});\n```\n\n## Files\n\n- `src/__tests__/client-server-integration.test.ts`\n\nImplements [[s-2uns]]","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 21:27:36","updated_at":"2026-01-29 22:42:07","closed_at":"2026-01-29 22:42:07","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-efmy","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["integration","messaging","testing"],"feedback":[{"id":"2a6f41cf-8467-4f69-96b0-a4879f9f97ed","from_id":"i-efmy","to_id":"s-2uns","feedback_type":"comment","content":"Messaging tests implemented in `client-server-integration.test.ts`:\n\n**Tests:**\n- `agent to agent delivery`\n- `message payload preserved exactly`\n- `scope broadcast reaches all members`\n\nMessage delivery tracked via harness.getDeliveredMessages() for assertions.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:41:57.534Z","updated_at":"2026-01-29T22:41:57.534Z"}]}
45
- {"id":"i-2fgd","uuid":"26f46e66-96b8-4f07-8045-6a09df0c99d8","title":"Integration tests: Error handling","content":"## Overview\n\nTest that errors propagate correctly from server SDK to client SDK.\n\n## Acceptance Criteria\n\n- [ ] Test: Unknown method returns METHOD_NOT_FOUND error\n- [ ] Test: Invalid params return INVALID_PARAMS error\n- [ ] Test: Getting nonexistent agent returns NOT_FOUND error\n- [ ] Test: Getting nonexistent scope returns NOT_FOUND error\n- [ ] Test: JSON-RPC error codes are correct (-32601, -32602, etc.)\n- [ ] Test: Error messages are descriptive\n- [ ] Test: Client can catch and handle errors\n\n## Test Cases\n\n```typescript\ndescribe(\"Error Handling\", () => {\n it(\"unknown method returns METHOD_NOT_FOUND\")\n it(\"invalid params returns INVALID_PARAMS\")\n it(\"nonexistent agent returns NOT_FOUND\")\n it(\"nonexistent scope returns NOT_FOUND\")\n it(\"error codes match JSON-RPC spec\")\n it(\"error messages are descriptive\")\n it(\"errors are catchable promises\")\n});\n```\n\n## Files\n\n- `src/__tests__/client-server-integration.test.ts`\n\nImplements [[s-2uns]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 21:27:37","updated_at":"2026-01-29 22:42:07","closed_at":"2026-01-29 22:42:07","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-2fgd","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["errors","integration","testing"],"feedback":[{"id":"ce774de3-900a-4d1e-851a-39eb98090c0b","from_id":"i-2fgd","to_id":"s-2uns","feedback_type":"comment","content":"Error handling tests implemented in `client-server-integration.test.ts`:\n\n**Tests:**\n- `nonexistent agent returns error`\n- `errors are catchable promises`\n\nTests verify errors propagate correctly from server to client as catchable promise rejections.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:41:57.825Z","updated_at":"2026-01-29T22:41:57.825Z"}]}
46
- {"id":"i-3tad","uuid":"03d76966-502d-427e-bd83-a6bbd25fe8e2","title":"Integration tests: Session resume","content":"## Overview\n\nTest session resume functionality across disconnect/reconnect cycles.\n\n## Acceptance Criteria\n\n- [ ] Test: Disconnect returns resumeToken\n- [ ] Test: Connect with resumeToken restores same session\n- [ ] Test: Resumed session has same sessionId\n- [ ] Test: Agents survive disconnect/resume\n- [ ] Test: Subscriptions survive disconnect/resume\n- [ ] Test: Queued messages delivered after resume\n- [ ] Test: Expired/invalid token fails gracefully\n- [ ] Test: Resume after session expiry fails\n\n## Test Cases\n\n```typescript\ndescribe(\"Session Resume\", () => {\n it(\"disconnect returns resumeToken\")\n it(\"connect with token restores session\")\n it(\"resumed session has same id\")\n it(\"agents preserved across resume\")\n it(\"subscriptions preserved across resume\")\n it(\"queued messages flushed on resume\")\n it(\"invalid token returns error\")\n it(\"expired token returns error\")\n});\n```\n\n## Files\n\n- `src/__tests__/client-server-integration.test.ts`\n\nImplements [[s-2uns]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 21:27:37","updated_at":"2026-01-29 22:49:08","closed_at":"2026-01-29 22:49:08","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-3tad","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["integration","resume","session","testing"],"feedback":[{"id":"7e84a8a5-3b06-43b1-86f9-9fcc94467802","from_id":"i-3tad","to_id":"s-2uns","feedback_type":"comment","content":"Session resume integration tests deferred.\n\n**Reason:** The server SDK has full session resume support (resumeToken generation, disconnect/resume flow), but the client SDK (ClientConnection, AgentConnection) doesn't yet expose resume token handling.\n\n**Required first:**\n1. Add `resumeToken` to disconnect response handling in client SDK\n2. Add `resumeToken` option to connect() in client SDK\n3. Then integration tests can verify end-to-end resume flow\n\nServer SDK resume functionality is tested in `server-sessions.test.ts`.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:42:44.286Z","updated_at":"2026-01-29T22:42:44.286Z"},{"id":"bf7a67b8-9658-4bb7-ab14-ca0296b060a0","from_id":"i-3tad","to_id":"s-2uns","feedback_type":"comment","content":"Session resume integration tests implemented. Required client SDK changes:\n\n**Client SDK Changes:**\n1. Added `resumeToken?: string` to `ConnectRequestParams` in types\n2. Added `resumeToken?: string` to `DisconnectResponseResult` in types\n3. Updated `ClientConnection.connect()` to accept `resumeToken` option\n4. Updated `ClientConnection.disconnect()` to return resume token\n5. Updated `AgentConnection.connect()` to accept `resumeToken` option\n6. Updated `AgentConnection.disconnect()` to return resume token\n\n**Integration Harness Changes:**\n- `createClient(name?, resumeToken?)` now supports resume tokens\n- `createAgent(name, role?, resumeToken?)` now supports resume tokens\n- `disconnect()` now returns the resume token\n\n**Integration Tests Added:**\n- `disconnect returns resumeToken`\n- `connect with resumeToken restores same session`\n- `invalid resumeToken creates new session`\n- `session marked disconnected on server after disconnect`\n- `resumed session status returns to connected`\n\nNote: Agent preservation and subscription preservation across resume require additional server-side work (agents are currently unregistered on disconnect). Queued message delivery and token expiry tests deferred.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:49:08.414Z","updated_at":"2026-01-29T22:49:08.414Z"}]}
47
- {"id":"i-7hv3","uuid":"97d5302a-9db3-4d29-86c0-345611f77e49","title":"Integration tests: Concurrent operations","content":"## Overview\n\nTest concurrent client and agent operations to verify thread safety and correct behavior under load.\n\n## Acceptance Criteria\n\n- [ ] Test: Multiple clients connect simultaneously\n- [ ] Test: Multiple agents register simultaneously\n- [ ] Test: Cross-agent messaging (A → B, B → A)\n- [ ] Test: Broadcast reaches all scope members\n- [ ] Test: Events fan out to all subscribers\n- [ ] Test: Operations don't interfere with each other\n- [ ] Test: Cleanup handles multiple connections\n\n## Test Cases\n\n```typescript\ndescribe(\"Concurrent Operations\", () => {\n it(\"multiple clients connect\")\n it(\"multiple agents register\")\n it(\"cross-agent messaging works\")\n it(\"scope broadcast reaches all members\")\n it(\"event fanout to multiple subscribers\")\n it(\"parallel operations don't conflict\")\n it(\"cleanup closes all connections\")\n});\n```\n\n## Files\n\n- `src/__tests__/client-server-integration.test.ts`\n\nImplements [[s-2uns]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 21:27:37","updated_at":"2026-01-29 22:42:07","closed_at":"2026-01-29 22:42:07","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-7hv3","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["concurrency","integration","testing"],"feedback":[{"id":"c556fdd0-e1d2-4f76-80a1-be5987e668bd","from_id":"i-7hv3","to_id":"s-2uns","feedback_type":"comment","content":"Concurrent operations tests implemented in `client-server-integration.test.ts`:\n\n**Tests:**\n- `multiple agents register simultaneously`\n- `cross-agent messaging works`\n- `cleanup closes all connections`\n\nTests verify parallel operations don't conflict and cleanup handles all connections properly.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:41:57.979Z","updated_at":"2026-01-29T22:41:57.979Z"}]}
48
- {"id":"i-7wos","uuid":"82006f43-2091-4415-a799-a5de1ef3e046","title":"Integration tests: Subscriptions and events","content":"## Overview\n\nTest event subscriptions and delivery between client SDK and server SDK.\n\n## Acceptance Criteria\n\n- [ ] Test: subscribe() returns subscription with id\n- [ ] Test: agent.registered event delivered to subscribers\n- [ ] Test: agent.unregistered event delivered\n- [ ] Test: agent.state.changed event delivered\n- [ ] Test: scope.created event delivered\n- [ ] Test: scope.agent.joined event delivered\n- [ ] Test: eventTypes filter works (only specified types)\n- [ ] Test: scopes filter works (only events from scope)\n- [ ] Test: unsubscribe() stops event delivery\n- [ ] Test: Events have correct structure (id, type, timestamp, data)\n\n## Test Cases\n\n```typescript\ndescribe(\"Subscriptions and Events\", () => {\n it(\"subscribe returns subscription id\")\n it(\"receives agent.registered event\")\n it(\"receives agent.unregistered event\")\n it(\"receives agent.state.changed event\")\n it(\"receives scope.created event\")\n it(\"receives scope.agent.joined event\")\n it(\"eventTypes filter limits events\")\n it(\"scopes filter limits to scope events\")\n it(\"unsubscribe stops delivery\")\n it(\"event structure is correct\")\n});\n```\n\n## Files\n\n- `src/__tests__/client-server-integration.test.ts`\n\nImplements [[s-2uns]]","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 21:27:37","updated_at":"2026-01-29 22:42:07","closed_at":"2026-01-29 22:42:07","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-7wos","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["events","integration","subscriptions","testing"],"feedback":[{"id":"d9a4e241-7d73-4ab2-b769-d222e969d099","from_id":"i-7wos","to_id":"s-2uns","feedback_type":"comment","content":"Subscription and event tests implemented in `client-server-integration.test.ts`:\n\n**Tests:**\n- `subscribe returns subscription id`\n- `receives agent.registered event`\n- `eventTypes filter limits events`\n\nEvent delivery wired through integration harness EventBus → subscription matching → notification.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:41:57.669Z","updated_at":"2026-01-29T22:41:57.669Z"}]}
49
- {"id":"i-6pli","uuid":"2db10982-8112-49a1-aa8f-bba8571e035a","title":"Add subscription filter expressiveness with match modes and $or/$and","content":"## Overview\n\nAdd support for more expressive subscription filters with `match` mode and `$or`/`$and` operators.\n\n## Changes\n\n1. Update `SubscriptionFilter` type:\n```typescript\ninterface SubscriptionFilter {\n eventTypes?: string[];\n agents?: string[];\n scopes?: string[];\n messageTypes?: string[]; // NEW: filter by message type\n match?: \"any\" | \"all\"; // NEW: default \"all\"\n $or?: SubscriptionFilter[]; // NEW: OR conditions\n $and?: SubscriptionFilter[]; // NEW: AND conditions (explicit)\n}\n```\n\n2. Update `SubscriptionManager.match()` logic:\n- Default behavior (`match: \"all\"`): all criteria must match (current behavior)\n- `match: \"any\"`: any single criterion matching is sufficient\n- `$or`: match if ANY sub-filter matches\n- `$and`: match if ALL sub-filters match\n- Nested combinations supported\n\n3. All complexity handled internally - implementers just use the filter syntax.\n\n## Files\n- `types.ts` - Update SubscriptionFilter\n- `subscriptions/manager.ts` - Update match() logic\n\n## Acceptance Criteria\n- [ ] `match: \"any\"` works\n- [ ] `$or` operator works\n- [ ] `$and` operator works \n- [ ] Nested filters work\n- [ ] `messageTypes` filter works\n- [ ] Default behavior unchanged (backward compatible)\n\nImplements [[s-1x3s]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 22:23:46","updated_at":"2026-01-29 22:29:08","closed_at":"2026-01-29 22:29:08","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6pli","from_type":"issue","to":"s-1x3s","to_type":"spec","type":"implements"}],"tags":["filters","phase-2","subscriptions"],"feedback":[{"id":"9fcf64ed-d4ca-46ff-a643-c307cbcda041","from_id":"i-6pli","to_id":"s-1x3s","feedback_type":"comment","content":"Implemented subscription filter expressiveness with match modes and logical operators:\n- Added `match: \"any\" | \"all\"` mode to SubscriptionFilter (default: \"all\")\n- Added `$or` operator for matching if ANY sub-filter matches\n- Added `$and` operator for matching if ALL sub-filters match\n- Added `messageTypes` filter for filtering by message type in event data\n- Supports nested $or/$and combinations\n- All complexity handled internally in SubscriptionManager\n- Backward compatible - default behavior unchanged\n- Added comprehensive tests (41 tests passing)","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:29:08.755Z","updated_at":"2026-01-29T22:29:08.755Z"}]}
50
- {"id":"i-8ncq","uuid":"c087dabe-4ea5-4807-85f6-9e745ef274a6","title":"Add agent state extensibility with custom:* states","content":"## Overview\n\nAllow agents to use custom states beyond the standard `idle`, `busy`, `suspended`, `stopped`.\n\n## Changes\n\n1. Update `ServerAgentState` type:\n```typescript\ntype StandardAgentState = \"idle\" | \"busy\" | \"suspended\" | \"stopped\";\ntype CustomAgentState = `custom:${string}`;\ntype ServerAgentState = StandardAgentState | CustomAgentState;\n```\n\n2. Add validation in `AgentRegistry.updateState()`:\n- Custom states must start with `custom:`\n- Basic validation: no empty string after prefix, reasonable length limit\n- Standard states remain unchanged\n\n3. Add helper functions:\n```typescript\nfunction isStandardState(state: string): state is StandardAgentState\nfunction isCustomState(state: string): state is CustomAgentState\nfunction validateAgentState(state: string): boolean\n```\n\n## Files\n- `types.ts` - Update type definitions\n- `agents/registry.ts` - Add validation\n- `agents/index.ts` - Export helpers\n\n## Acceptance Criteria\n- [ ] Custom states like `custom:thinking` work\n- [ ] Standard states still work\n- [ ] Invalid states are rejected with clear error\n- [ ] Helpers exported for type checking\n\nImplements [[s-1x3s]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 22:23:46","updated_at":"2026-01-29 22:27:30","closed_at":"2026-01-29 22:27:30","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-8ncq","from_type":"issue","to":"s-1x3s","to_type":"spec","type":"implements"}],"tags":["agents","phase-2","types"],"feedback":[{"id":"eecccc1c-771c-41ae-a048-af1f93152132","from_id":"i-8ncq","to_id":"s-1x3s","feedback_type":"comment","content":"Implemented agent state extensibility with `custom:*` prefix pattern:\n- Added `isStandardState()`, `isCustomState()`, `validateAgentState()` helpers\n- Updated `isValidTransition()` to allow custom states to bypass standard state machine\n- Custom states can transition to/from any state except \"stopped\" (terminal)\n- Added `InvalidAgentStateError` for validation failures\n- Basic validation: custom states must have non-empty suffix <= 64 characters\n- All helpers exported from `server/agents` module\n- Added comprehensive tests (67 tests passing)","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:27:29.896Z","updated_at":"2026-01-29T22:27:29.896Z"}]}
51
- {"id":"i-5js4","uuid":"1516a6de-b529-4220-bae2-ccd44fdb4186","title":"Add multi-cause event dependencies with configurable behavior","content":"## Overview\n\nAllow events to have multiple causal dependencies via `causedBy: string | string[]`.\n\n## Changes\n\n1. Update `MAPEvent` type:\n```typescript\ninterface MAPEvent {\n // ...existing fields\n causedBy?: string | string[]; // Changed from string\n}\n```\n\n2. Update `CausalEventBuffer` to handle arrays:\n```typescript\ninterface CausalOrderingOptions {\n // ...existing options\n multiCauseMode?: \"all\" | \"any\"; // NEW: default \"all\"\n}\n```\n- `\"all\"`: Wait for ALL causes before releasing (stricter, default)\n- `\"any\"`: Release when ANY cause is seen (more permissive)\n\n3. Update dependency tracking to handle multiple parents.\n\n## Files\n- `types.ts` - Update causedBy type\n- `utils/causal-buffer.ts` - Handle array causedBy\n- `subscriptions/manager.ts` - Pass through option\n\n## Acceptance Criteria\n- [ ] Single causedBy still works (backward compatible)\n- [ ] Array causedBy works\n- [ ] `multiCauseMode: \"all\"` waits for all causes\n- [ ] `multiCauseMode: \"any\"` releases on first cause\n- [ ] Default is \"all\" (stricter)\n\nImplements [[s-1x3s]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 22:23:47","updated_at":"2026-01-29 22:32:52","closed_at":"2026-01-29 22:32:52","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-5js4","from_type":"issue","to":"s-1x3s","to_type":"spec","type":"implements"}],"tags":["causal-ordering","events","phase-2"],"feedback":[{"id":"bb042d0b-9e67-4818-b37a-fe4f5c030b1f","from_id":"i-5js4","to_id":"s-1x3s","feedback_type":"comment","content":"Implemented multi-cause event dependencies:\n- Updated `MAPEvent.causedBy` to support `string | string[]`\n- Added `MultiCauseMode` type with \"all\" (default) and \"any\" modes\n- Added `multiCauseMode` option to `CausalOrderingOptions`\n- Updated `CausalEventBuffer` to support \"any\" mode (releases when ANY predecessor is seen)\n- Default \"all\" mode waits for ALL predecessors (backward compatible)\n- SubscriptionManager passes through the multiCauseMode option\n- Added comprehensive tests for both modes (31 causal buffer tests, 44 subscription tests)","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:32:51.910Z","updated_at":"2026-01-29T22:32:51.910Z"}]}
52
- {"id":"i-7xes","uuid":"06c9096c-c01e-4bf1-8cf2-7920d3ebf9f5","title":"Add capability discovery to agents","content":"## Overview\n\nAdd `capabilities` field to agent registration and support capability-based queries.\n\n## Changes\n\n1. Update `RegisteredAgent` type:\n```typescript\ninterface RegisteredAgent {\n // ...existing fields\n capabilities?: string[]; // NEW\n}\n```\n\n2. Update registration params to accept capabilities.\n\n3. Update `AgentFilter` type:\n```typescript\ninterface AgentFilter {\n // ...existing fields\n capability?: string; // NEW: supports glob patterns\n}\n```\n\n4. Add capability matching with glob support:\n```typescript\n// Exact match\nagents.list({ capability: \"translate:fr\" });\n\n// Glob pattern\nagents.list({ capability: \"translate:*\" });\n```\n\n5. Add helper for capability matching:\n```typescript\nfunction matchesCapability(capabilities: string[], pattern: string): boolean\n```\n\n## Files\n- `types.ts` - Update RegisteredAgent, AgentFilter\n- `agents/registry.ts` - Add capability filtering\n- `agents/stores/in-memory.ts` - Update list filtering\n- `agents/handlers.ts` - Pass through capabilities\n- `agents/index.ts` - Export helpers\n\n## Acceptance Criteria\n- [ ] Capabilities can be set on registration\n- [ ] Exact match filtering works\n- [ ] Glob pattern filtering works (`translate:*`)\n- [ ] Empty capabilities array handled gracefully\n- [ ] Backward compatible (capabilities optional)\n\nImplements [[s-1x3s]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 22:23:47","updated_at":"2026-01-29 22:37:37","closed_at":"2026-01-29 22:37:37","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-7xes","from_type":"issue","to":"s-1x3s","to_type":"spec","type":"implements"}],"tags":["agents","discovery","phase-2"],"feedback":[{"id":"a8798b7a-4e29-42a5-b38c-2bbd0e8fcc29","from_id":"i-7xes","to_id":"s-1x3s","feedback_type":"comment","content":"Implemented capability discovery for agents:\n- Added `capabilities?: string[]` to `RegisteredAgent` type\n- Added `capability?: string` filter to `AgentFilter` (supports glob patterns)\n- Added `matchesCapability()` helper supporting:\n - Exact match: \"translate:en\"\n - Single-level glob (*): \"translate:*\" matches \"translate:en\"\n - Multi-level glob (**): \"translate:**\" matches \"translate:en:formal\"\n- Added `hasCapability()` helper for checking if an agent has a matching capability\n- Updated registration handlers to accept and return capabilities\n- Updated listing/get handlers to return capabilities\n- Updated InMemoryAgentStore to filter by capability\n- All helpers exported from `server/agents` module\n- Added comprehensive tests (81 tests passing)","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:37:37.628Z","updated_at":"2026-01-29T22:37:37.628Z"}]}
53
- {"id":"i-8s45","uuid":"7978fbc6-6da6-4778-8e48-15e991877bb5","title":"Add messageType field to messages","content":"## Overview\n\nAdd optional `messageType` field to messages for easier routing/filtering without payload inspection.\n\n## Changes\n\n1. Update `ServerMessage` type:\n```typescript\ninterface ServerMessage {\n // ...existing fields\n messageType?: string; // NEW\n}\n```\n\n2. Update `MessageRouter.sendToAgent()` and `sendToScope()`:\n- Accept `messageType` in params\n- Pass through to created message\n\n3. Already handled in previous issue: `messageTypes` filter in SubscriptionFilter.\n\n## Files\n- `types.ts` - Update ServerMessage\n- `messages/router.ts` - Pass through messageType\n- `messages/handlers.ts` - Accept in handler params\n\n## Acceptance Criteria\n- [ ] `messageType` can be set when sending\n- [ ] `messageType` is preserved on delivered message\n- [ ] Works with subscription `messageTypes` filter\n- [ ] Optional - backward compatible\n\nImplements [[s-1x3s]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 22:23:47","updated_at":"2026-01-29 22:34:45","closed_at":"2026-01-29 22:34:45","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-8s45","from_type":"issue","to":"s-1x3s","to_type":"spec","type":"implements"}],"tags":["messages","phase-2","types"],"feedback":[{"id":"ae4e1401-c731-410a-b421-245850c1e9f4","from_id":"i-8s45","to_id":"s-1x3s","feedback_type":"comment","content":"Implemented messageType field for messages:\n- Added `messageType?: string` to `ServerMessage` type\n- Updated `sendToAgent()` to accept and include messageType\n- Updated `sendToScope()` to accept and include messageType\n- Updated message handlers (`map/send` and `map/send/scope`) to pass through messageType\n- Works with subscription `messageTypes` filter (implemented in i-6pli)\n- Optional field - backward compatible\n- Added tests (35 tests passing)","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T22:34:45.350Z","updated_at":"2026-01-29T22:34:45.350Z"}]}
54
- {"id":"i-1qpg","uuid":"57f1e1f3-5676-42dd-8357-2eb3e23ff6c0","title":"Implement federation ID format standardization","content":"## Overview\n\nStandardize remote agent/scope ID format for federation interoperability.\n\n## Acceptance Criteria\n\n- [ ] Define canonical format: `{systemId}:{entityType}:{entityId}` (e.g., `system-west:agent:agent-123`)\n- [ ] Add `FederatedId` type with parsing/formatting utilities\n- [ ] Update federation decorators to use standard format\n- [ ] Update gateway to parse/format IDs consistently\n- [ ] Add validation for federated IDs\n\n## Format\n\n```typescript\n// Canonical format\n\"{systemId}:{entityType}:{entityId}\"\n\n// Examples\n\"system-west:agent:agent-123\"\n\"system-east:scope:room-456\"\n```\n\nImplements [[s-1x3s]] Phase 3","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 22:54:41","updated_at":"2026-01-29 23:01:16","closed_at":"2026-01-29 23:01:16","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1qpg","from_type":"issue","to":"s-1x3s","to_type":"spec","type":"implements"}],"tags":["breaking-change","federation","phase-3"],"feedback":[{"id":"90b5c212-6a49-447c-aab8-8d52969b29b5","from_id":"i-1qpg","to_id":"s-1x3s","feedback_type":"comment","content":"Implemented federation ID format standardization:\n\n**New utilities in `federation/federated-id.ts`:**\n- `formatFederatedId(systemId, entityType, entityId)` - Creates canonical format\n- `parseFederatedId(id)` - Extracts components with validation\n- `isFederatedId(id)` - Type guard for any federated ID\n- `isFederatedAgent(id)` / `isFederatedScope(id)` - Entity-specific guards\n- `isFromSystem(id, systemId)` - Check origin system\n- `extractEntityId(id)` / `extractSystemId(id)` - Extract components\n- `InvalidFederatedIdError` - Custom error class\n\n**Updated components:**\n- `FederatedAgentRegistry` - Uses `formatFederatedId(from, \"agent\", ...)` for remote agents\n- `FederatedScopeManager` - Uses `formatFederatedId(from, \"scope\", ...)` for remote scopes\n- `FederatedMessageRouter` - Uses `isFederatedAgent()` and `parseFederatedId()` for routing\n\n**Format:** `{systemId}:{entityType}:{entityId}` where entityType is `agent` | `scope` | `message`\n\nAll 1063 tests pass including 30 new federated ID tests.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T23:01:11.017Z","updated_at":"2026-01-29T23:01:11.017Z"}]}
55
- {"id":"i-26aw","uuid":"42686bcd-d36e-4937-8b74-c169854f0cea","title":"Implement recipient disambiguation with type prefix","content":"## Overview\n\nAdd prefix convention to message `to` field to distinguish between agents and scopes.\n\n## Acceptance Criteria\n\n- [ ] Update `Address` type to support prefixed format\n- [ ] Add `parseAddress()` utility to extract type and ID\n- [ ] Add `formatAddress()` utility to create prefixed address\n- [ ] Update MessageRouter to parse prefixed addresses\n- [ ] Update send handlers to accept both formats (backward compatible during transition)\n- [ ] Add `toAgent` and `toScope` convenience methods\n\n## Format\n\n```typescript\n// Prefixed format\n\"agent:{agentId}\"\n\"scope:{scopeId}\"\n\n// Examples\nsend({ to: \"agent:abc123\", payload: {} })\nsend({ to: \"scope:room-1\", payload: {} })\n```\n\nImplements [[s-1x3s]] Phase 3","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 22:54:41","updated_at":"2026-01-29 23:11:36","closed_at":"2026-01-29 23:11:36","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-26aw","from_type":"issue","to":"s-1x3s","to_type":"spec","type":"implements"}],"tags":["breaking-change","messaging","phase-3"],"feedback":[{"id":"70f4510d-e97a-4d0d-8df0-65a1a17e0c9f","from_id":"i-26aw","to_id":"s-1x3s","feedback_type":"comment","content":"Implemented recipient disambiguation with type prefix:\n\n**New utilities in `messages/address.ts`:**\n- `formatAddress(type, id)` - Create prefixed address (e.g., `agent:abc123`)\n- `parseAddress(address)` - Parse address into type and id components\n- `isAddress(address)` - Check if valid prefixed address\n- `isAgentAddress(address)` / `isScopeAddress(address)` - Type-specific checks\n- `extractId(address)` - Extract ID, returns original if not prefixed\n- `extractType(address)` - Extract type or undefined\n- `toAgent(id)` / `toScope(id)` - Convenience functions\n- `InvalidAddressError` - Custom error class\n\n**Address format:** `{type}:{id}` where type is `agent` or `scope`\n\n**Backward compatibility:**\n- Message handlers accept both prefixed and unprefixed addresses\n- Unprefixed addresses fall back to scope lookup, then agent\n\n**Updated components:**\n- `messages/handlers.ts` - `map/send` handler parses prefixed addresses\n- `router/base-router.ts` - `send()` method parses prefixed addresses\n\n**Tests added:** 37 new tests (34 for utilities + 3 for handlers)\n\nAll 1102 tests pass.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T23:11:32.511Z","updated_at":"2026-01-29T23:11:32.511Z"}]}
56
- {"id":"i-11cx","uuid":"a1fd54da-5d9b-4239-b6ab-fd2091caddda","title":"Preserve agents across session resume","content":"## Overview\n\nKeep agent registrations alive during disconnect so they can be reclaimed on resume.\n\n## Acceptance Criteria\n\n- [ ] Don't unregister agents on disconnect (mark session as disconnected but keep agents)\n- [ ] On resume, restore agent ownership to the resumed session\n- [ ] Add timeout for orphaned agents (unregister if not reclaimed within X minutes)\n- [ ] Update AgentConnection to reclaim agents on resume\n- [ ] Add `reclaimAgents` option to connect for explicit agent reclaim\n\n## Behavior\n\n```typescript\n// Disconnect - agents stay registered but orphaned\nawait agent.disconnect(); // Returns resume token, agent still exists\n\n// Resume - reclaim the agent\nconst { agent } = await newConnection.connect({ resumeToken });\n// Agent is now owned by new session\n```\n\nImplements [[s-2uns]]","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 22:54:42","updated_at":"2026-01-29 23:07:18","closed_at":"2026-01-29 23:07:18","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-11cx","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["agents","resume","session"],"feedback":[{"id":"71228b1e-95d2-4323-a687-43a871d6d3e6","from_id":"i-11cx","to_id":"s-2uns","feedback_type":"comment","content":"Implemented agent preservation across session resume:\n\n**Changes:**\n\n1. **`router/handlers.ts`** - `map/disconnect` handler no longer unregisters agents, cancels subscriptions, or removes scope memberships. Resources are preserved for session resume.\n\n2. **`router/base-router.ts`** - `disconnect()` method simplified to only call `sessions.disconnect()`, preserving all resources.\n\n3. **Added `close()` method** to both `BaseMAPRouter` and `MAPRouterInterface` for permanent session closure with full resource cleanup.\n\n4. **Connect response** now sets `reconnected: true` when session has pre-existing agents (indicating resume).\n\n**Behavior:**\n- `map/disconnect` → Preserves agents, subscriptions, scope memberships (resumable)\n- `map/session/close` → Full cleanup of all resources (not resumable)\n- `ResourceCleaner` → Cleans up orphaned agents when sessions expire after timeout\n\n**Tests added:**\n- `should preserve agents across session disconnect/resume`\n- `should clean up agents when session expires (via ResourceCleaner)`\n\nAll 1065 tests pass.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T23:07:11.411Z","updated_at":"2026-01-29T23:07:11.411Z"}]}
57
- {"id":"i-2h3o","uuid":"e5b063ab-e5af-4a6f-b25a-e614cef020a8","title":"Preserve subscriptions across session resume","content":"## Overview\n\nKeep subscriptions alive during disconnect so events can be replayed on resume.\n\n## Acceptance Criteria\n\n- [ ] Don't cancel subscriptions on disconnect (pause them instead)\n- [ ] On resume, unpause subscriptions for the session\n- [ ] Track last delivered event ID per subscription\n- [ ] Replay missed events on resume (up to configured limit)\n- [ ] Add configurable max replay count and max age\n\n## Behavior\n\n```typescript\n// Disconnect - subscriptions paused, events buffered\nawait client.disconnect();\n\n// Resume - subscriptions resumed, missed events replayed\nconst client2 = await harness.createClient(\"Client\", resumeToken);\n// Receives events that occurred during disconnect\n```\n\nImplements [[s-2uns]]","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 22:54:42","updated_at":"2026-01-29 23:07:59","closed_at":"2026-01-29 23:07:59","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-2h3o","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["resume","session","subscriptions"],"feedback":[{"id":"29ef3ee6-cd71-4449-baac-88a6adc5764f","from_id":"i-2h3o","to_id":"s-2uns","feedback_type":"comment","content":"Partially implemented - subscriptions are now preserved on disconnect:\n\n**Done:**\n- Subscriptions are not cancelled on `map/disconnect` (preserved for resume)\n- Subscriptions are associated with session via `subscriptionIds` array\n- On resume, session's subscriptions are still active\n\n**Not implemented (may need follow-up):**\n- Explicit pause/unpause state tracking\n- Last delivered event ID tracking per subscription\n- Event replay on resume (the EventBus already has `getEvents()` for replay, but automatic replay integration not done)\n- Configurable max replay count and max age\n\nThe basic preservation is complete. Event replay can be added as a future enhancement.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T23:07:54.492Z","updated_at":"2026-01-29T23:07:54.492Z"}]}
58
- {"id":"i-7m1p","uuid":"2d11cc60-e4ad-4f39-8c66-06a04d0bcc87","title":"Implement automatic event replay on session resume","content":"## Overview\n\nWhen a session resumes after disconnect, automatically replay missed events to subscriptions.\n\n## Acceptance Criteria\n\n- [ ] Track `lastDeliveredEventId` on each subscription\n- [ ] On session resume, query `EventBus.getEvents()` for events after lastDeliveredEventId\n- [ ] Deliver missed events to subscription in order\n- [ ] Add `maxReplayCount` option (default: 1000) to limit replay size\n- [ ] Add `maxReplayAgeMs` option (default: 5 minutes) to limit how old events can be\n- [ ] Emit `subscription.replay.started` and `subscription.replay.completed` events\n\n## Implementation Notes\n\n- `EventBus.getEvents()` already supports time-range queries\n- Need to update `SubscriptionManager` to track last delivered event\n- Resume flow in `RouterConnection.start()` should trigger replay\n\n## Related\n\n- Server has `EventBus.getEvents({ since, until, limit })` for querying\n- Session resume already preserves subscription IDs","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:19:44","updated_at":"2026-01-29 23:30:02","closed_at":"2026-01-29 23:30:02","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-7m1p","from_type":"issue","to":"i-9pe3","to_type":"issue","type":"depends-on"},{"from":"i-7m1p","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["events","resume","session","subscriptions"],"feedback":[{"id":"5e6c0320-c888-472a-8b80-d1c5dc4ca0f4","from_id":"i-7m1p","to_id":"s-10j2","feedback_type":"comment","content":"Implemented automatic event replay on session resume:\n\n**SubscriptionManager changes:**\n- Added `replayEvents(id, options?)` method to replay events since lastEventId\n- Added `replaySessionEvents(sessionId, options?)` convenience method for resuming all subscriptions for a session\n- Added `ReplayOptions` type with `maxReplayCount` (default: 1000), `maxReplayAgeMs` (default: 5 minutes), and `applyFilter` (default: true)\n- Pauses subscription during replay to prevent live events from interfering\n- Emits `subscription.replay.started` and `subscription.replay.completed` events\n- Filters out `subscription.replay.*` events from replay results to prevent self-referential issues\n\n**EventBus changes:**\n- Fixed ULID generation to use `monotonicFactory()` instead of `ulid()` to ensure event IDs are always monotonically increasing even when emitted within the same millisecond. This was causing intermittent test failures due to non-deterministic ordering.\n\n**Tests added:**\n- 10 new tests for event replay functionality covering: basic replay, maxReplayCount, maxReplayAgeMs, applyFilter, replay events emission, unknown subscriptions, and session-wide replay\n\n**Usage on resume:**\n```typescript\n// After session.resume() succeeds, replay missed events\nconst results = subscriptions.replaySessionEvents(session.id);\nfor (const [subId, events] of results) {\n console.log(`Replayed ${events.length} events to subscription ${subId}`);\n}\n```","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T23:30:02.564Z","updated_at":"2026-01-29T23:30:02.564Z"}]}
59
- {"id":"i-9pe3","uuid":"a57333d8-16b5-4849-8ce0-d00462cd7ba0","title":"Track lastDeliveredEventId per subscription","content":"## Overview\n\nTrack the last successfully delivered event ID for each subscription to support event replay on resume.\n\n## Acceptance Criteria\n\n- [ ] Add `lastDeliveredEventId?: string` to `ServerSubscription` type\n- [ ] Update subscription delivery to track last delivered event\n- [ ] Persist in subscription store\n- [ ] Add `getLastEventId(subscriptionId)` method to SubscriptionManager\n\n## Implementation Notes\n\n- This is a prerequisite for event replay on resume\n- Should be updated after successful delivery callback","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:19:44","updated_at":"2026-01-29 23:23:19","closed_at":"2026-01-29 23:23:19","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-9pe3","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["resume","subscriptions"],"feedback":[{"id":"6c58ab2f-f6f4-46aa-bcbc-c89909b673d9","from_id":"i-9pe3","to_id":"s-10j2","feedback_type":"comment","content":"Implemented lastEventId tracking in SubscriptionManager:\n- `deliverEvent()` now automatically updates `lastEventId` on the subscription when events are delivered\n- Added `getLastEventId(id: string): string | undefined` method to the SubscriptionManager interface\n- Added 5 new tests covering automatic tracking, sequential updates, unknown subscriptions, startAfter preservation, and non-matching events\n- This enables event replay on session resume (i-7m1p) by knowing where each subscription left off","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T23:23:19.524Z","updated_at":"2026-01-29T23:23:19.524Z"}]}
60
- {"id":"i-3q1a","uuid":"bab4a681-0be8-4775-8568-56fbb9bbd5b4","title":"Verify GatewayConnection resume token handling","content":"## Overview\n\nVerify that `GatewayConnection` in the client SDK properly handles resume tokens for federation gateway connections.\n\n## Acceptance Criteria\n\n- [ ] Review `GatewayConnection.connect()` for resumeToken support\n- [ ] Review `GatewayConnection.disconnect()` returns resumeToken\n- [ ] Add integration tests for gateway resume\n- [ ] Document gateway-specific resume behavior\n\n## Notes\n\n- `ClientConnection` and `AgentConnection` already support resume tokens\n- Gateway connections may have different semantics due to federation state","status":"closed","priority":3,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:19:45","updated_at":"2026-01-29 23:31:51","closed_at":"2026-01-29 23:31:51","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-3q1a","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["federation","gateway","resume"],"feedback":[{"id":"2944a500-3bdd-41c2-a460-6b8cab2970fb","from_id":"i-3q1a","to_id":"s-2uns","feedback_type":"comment","content":"**Verification Results for GatewayConnection Resume Token Handling:**\n\n**Current State:**\n- `connect()` does NOT accept a `resumeToken` parameter\n- `disconnect()` returns `void` instead of a resume token \n- Reconnection creates a NEW session rather than resuming the old one\n\n**Existing Reconnection Features (that work without resume tokens):**\n- Outage buffering: Messages are buffered during disconnect and drained on reconnect\n- Peer replay: Events are replayed from peers based on `lastSyncTimestamp`\n- Connected systems are tracked locally (but lost on reconnect)\n\n**Gap Analysis:**\nThe gateway uses a different reconnection strategy than clients/agents. Instead of session resume, it relies on:\n1. Message buffering for outgoing messages\n2. Event replay from peers for incoming events\n\n**Recommendation:**\nFor future enhancement, consider adding resume token support for gateway connections to:\n- Preserve the same sessionId across reconnects (useful for server-side tracking)\n- Allow federation peer connections to be preserved server-side\n\n**Current Behavior is Acceptable Because:**\n- Gateway buffering handles outgoing message continuity\n- Event replay handles incoming event continuity\n- Federation peer connections are typically re-established anyway\n\nMarking as verified - current behavior is intentional and has working reconnection semantics, just different from client/agent resume.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T23:31:50.919Z","updated_at":"2026-01-29T23:31:50.919Z"}]}
61
- {"id":"i-45ea","uuid":"d8bf09ff-b00f-4392-8450-d6cdbd4ad389","title":"Export address utilities from client SDK","content":"## Overview\n\nThe server SDK has `toAgent()` and `toScope()` convenience functions for creating prefixed addresses. These should be available to client SDK users as well.\n\n## Acceptance Criteria\n\n- [ ] Export address utilities from main SDK entry point (not just server)\n- [ ] Or create a separate `@multi-agent-protocol/sdk/addresses` export\n- [ ] Document usage in README\n\n## Functions to Export\n\n```typescript\nimport { toAgent, toScope } from \"@multi-agent-protocol/sdk\";\n\n// Usage\nclient.send({ to: toAgent(\"agent-123\"), payload: {} });\nclient.send({ to: toScope(\"room-1\"), payload: {} });\n```\n\n## Implementation Notes\n\n- Utilities already exist in `server/messages/address.ts`\n- Just need to re-export from appropriate location","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:19:45","updated_at":"2026-01-29 23:30:57","closed_at":"2026-01-29 23:30:57","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-45ea","from_type":"issue","to":"s-1x3s","to_type":"spec","type":"implements"}],"tags":["addresses","client-sdk","ergonomics"],"feedback":[{"id":"6228ca51-234a-4c40-b87f-1c71f1660212","from_id":"i-45ea","to_id":"s-1x3s","feedback_type":"comment","content":"Exported address utilities from main SDK entry point:\n\n**Exports added to `@multi-agent-protocol/sdk`:**\n```typescript\n// Convenience functions\ntoAgent(agentId: string): string // \"agent:abc123\"\ntoScope(scopeId: string): string // \"scope:room-1\"\n\n// Address validation\nisAddress(address: string): boolean\nisAgentAddress(address: string): boolean\nisScopeAddress(address: string): boolean\n\n// Address parsing\nformatAddress(type: AddressType, id: string): string\nparseAddress(address: string): AddressComponents\nextractId(address: string): string\nextractType(address: string): AddressType | undefined\n\n// Types\ntype AddressType = \"agent\" | \"scope\"\ninterface AddressComponents { type: AddressType; id: string }\n\n// Errors\nclass InvalidAddressError extends Error\n```\n\n**Usage:**\n```typescript\nimport { toAgent, toScope } from \"@multi-agent-protocol/sdk\";\n\n// Send to a specific agent\nclient.send({ to: toAgent(\"agent-123\"), payload: {} });\n\n// Send to all agents in a scope\nclient.send({ to: toScope(\"room-1\"), payload: {} });\n```","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T23:30:57.400Z","updated_at":"2026-01-29T23:30:57.400Z"}]}
62
- {"id":"i-55no","uuid":"ff509541-6996-4754-b392-7fce6f4ea09c","title":"Add reclaimAgents option to connect","content":"## Overview\n\nWhen resuming a session, allow explicit specification of which agents to reclaim ownership of.\n\n## Acceptance Criteria\n\n- [ ] Add `reclaimAgents?: string[]` to connect options in client SDK\n- [ ] Server validates that requested agents belong to the session\n- [ ] Return error if agent doesn't exist or belongs to different session\n- [ ] Update connect response to indicate which agents were reclaimed\n\n## API\n\n```typescript\n// Resume and reclaim specific agents\nconst result = await connection.connect({\n resumeToken: token,\n reclaimAgents: [\"agent-123\", \"agent-456\"],\n});\n\n// result.reclaimedAgents = [\"agent-123\", \"agent-456\"]\n```\n\n## Implementation Notes\n\n- Currently all agents are implicitly reclaimed via session.agentIds\n- This adds explicit control for partial reclaim scenarios","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:19:45","updated_at":"2026-01-29 23:40:27","closed_at":"2026-01-29 23:40:27","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-55no","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["agents","client-sdk","resume"],"feedback":[{"id":"42125a7e-73ca-485e-9211-bdb93eddefcd","from_id":"i-55no","to_id":"s-2uns","feedback_type":"comment","content":"Implemented `reclaimAgents` option for connect request:\n\n**Server Changes (`router/handlers.ts`):**\n- Added `ConnectParams` interface with `reclaimAgents?: string[]`\n- Updated `map/connect` handler to:\n - Validate specified agents exist and belong to the session\n - Return error if any agent doesn't exist or belongs to different session\n - Return all session agents if `reclaimAgents` not specified (backward compatible)\n- Added `reclaimedAgents: string[]` to connect response\n\n**Validation Behavior:**\n- If `reclaimAgents` is not provided: all session agents are reclaimed (existing behavior)\n- If `reclaimAgents` is provided: only those agents are validated and returned\n- Multiple validation errors are combined into single error message\n\n**Tests Added (6 new tests):**\n- \"should reclaim all agents when reclaimAgents is not specified\"\n- \"should reclaim only specified agents\"\n- \"should throw error if agent does not exist\"\n- \"should throw error if agent belongs to different session\"\n- \"should report multiple errors for multiple invalid agents\"\n- \"should return empty reclaimedAgents for new session\"\n\n**Usage:**\n```typescript\n// Resume and validate specific agents\nconst result = await connection.connect({\n resumeToken: token,\n reclaimAgents: [\"agent-123\", \"agent-456\"],\n});\n\n// result.reclaimedAgents = [\"agent-123\", \"agent-456\"]\n// Throws if any agent doesn't exist or belongs to different session\n```","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T23:40:27.075Z","updated_at":"2026-01-29T23:40:27.075Z"}]}
63
- {"id":"i-7nux","uuid":"d3fab148-7102-4bca-960f-bd15a6d59791","title":"Add explicit subscription pause/unpause state tracking","content":"## Overview\n\nAdd explicit pause state to subscriptions that persists across disconnect/resume, separate from just not delivering events.\n\n## Acceptance Criteria\n\n- [ ] Add `paused: boolean` to `ServerSubscription` type\n- [ ] Add `map/pause` and `map/resume` handlers (already exist in handlers.ts)\n- [ ] Paused state persists across session disconnect/resume\n- [ ] Paused subscriptions don't receive events but track lastEventId\n- [ ] Add `pausedAt?: number` timestamp\n\n## Current State\n\nThe handlers exist but may not fully integrate with the subscription state machine.","status":"closed","priority":3,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:19:45","updated_at":"2026-01-29 23:33:14","closed_at":"2026-01-29 23:33:14","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-7nux","from_type":"issue","to":"s-2uns","to_type":"spec","type":"implements"}],"tags":["pause","subscriptions"],"feedback":[{"id":"b73e8eea-4a1e-4154-a6d3-070dc14fd122","from_id":"i-7nux","to_id":"s-2uns","feedback_type":"comment","content":"Verified and enhanced subscription pause/unpause state tracking:\n\n**Already Implemented (verified):**\n- ✅ `paused: boolean` in `ServerSubscription` type\n- ✅ `map/pause` and `map/resume` handlers in `subscriptions/handlers.ts`\n- ✅ Paused state persists in SubscriptionStore across disconnect/resume\n- ✅ Paused subscriptions don't receive events (checked in `handleEvent`)\n\n**New Enhancement:**\n- ✅ Added `pausedAt?: number` timestamp to `ServerSubscription`\n- `pause()` now sets `pausedAt = Date.now()` when pausing (only if not already paused)\n- `resume()` clears `pausedAt = undefined` when resuming\n\n**Tests Added:**\n- \"should track pausedAt timestamp when paused\"\n- \"should clear pausedAt timestamp when resumed\" \n- \"should not update pausedAt if already paused\"\n\n**Usage:**\n```typescript\nconst sub = subscriptions.get(subscriptionId);\nif (sub?.paused) {\n console.log(`Paused since: ${new Date(sub.pausedAt!)}`);\n}\n```","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-29T23:33:14.530Z","updated_at":"2026-01-29T23:33:14.530Z"}]}
64
- {"id":"i-259x","uuid":"59d10aa8-50fc-4933-bb83-3f0544d90b0c","title":"Add MAPServer types to server/types.ts","content":"## Summary\n\nAdd TypeScript interfaces for the MAPServer convenience layer to `server/types.ts`.\n\n## Acceptance Criteria\n\n- [ ] `MAPServerOptions` interface with all fields from spec:\n - Basic config: `name`, `version`, `capabilities`\n - Building block overrides: `eventBus`, `agents`, `scopes`, `sessions`, `subscriptions`, `messages`\n - Storage overrides: `stores` object with all store types\n - Handler customization: `handlers`, `additionalHandlers`, `middleware`\n - Event delivery: `eventDelivery` with `enabled` and `filter`\n - Session config: `resumeWindowMs`\n- [ ] `AcceptOptions` interface: `role`, `name`, `resumeToken`\n- [ ] `CloseOptions` interface: `timeout`, `force`\n- [ ] JSDoc comments documenting precedence rules (block overrides ignore stores)\n- [ ] Export all new types from `server/index.ts`\n\n## Implementation Notes\n\n- Follow existing type patterns in `server/types.ts`\n- Use existing types: `EventBus`, `AgentRegistry`, `ScopeManager`, etc.\n- Use existing store types: `EventStore`, `AgentStore`, etc.\n\n## Files to Modify\n\n- `ts-sdk/src/server/types.ts` - Add new interfaces\n- `ts-sdk/src/server/index.ts` - Export new types","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:53:01","updated_at":"2026-01-30 00:08:30","closed_at":"2026-01-30 00:08:30","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-259x","from_type":"issue","to":"i-h4ac","to_type":"issue","type":"blocks"},{"from":"i-259x","from_type":"issue","to":"s-7hnb","to_type":"spec","type":"implements"}],"tags":["mapserver","types"]}
65
- {"id":"i-h4ac","uuid":"9c24093b-3c34-478a-8289-59f60406615e","title":"Implement MAPServer constructor with building block wiring","content":"## Summary\n\nImplement the core `MAPServer` class constructor that creates and wires building blocks in dependency order.\n\n## Acceptance Criteria\n\n- [ ] `MAPServer` class in new file `server/server.ts`\n- [ ] Constructor accepts optional `MAPServerOptions`\n- [ ] Creates building blocks in dependency order:\n 1. EventBus (no deps)\n 2. SessionManager (depends on EventBus)\n 3. AgentRegistry (depends on EventBus)\n 4. ScopeManager (depends on EventBus)\n 5. SubscriptionManager (depends on EventBus, ScopeManager)\n 6. MessageRouter (depends on EventBus, AgentRegistry, ScopeManager)\n- [ ] User-provided blocks take precedence over auto-creation\n- [ ] User-provided blocks are used as dependencies for auto-created blocks\n- [ ] Custom stores are passed to auto-created blocks (only when block not provided)\n- [ ] Handlers composed with `combineHandlers()`:\n - `createConnectionHandlers` with name, version, capabilities\n - `createAgentHandlers`\n - `createScopeHandlers`\n - `createMessageHandlers`\n - `createSubscriptionHandlers`\n - `additionalHandlers` merged last\n- [ ] All building blocks exposed as readonly properties\n- [ ] `handlers` exposed as readonly property\n- [ ] Convenience methods: `on()` and `emit()` delegating to eventBus\n- [ ] Export from `server/index.ts`\n\n## Implementation Notes\n\n```typescript\nclass MAPServer {\n readonly eventBus: EventBus;\n readonly agents: AgentRegistry;\n // ... other blocks\n \n constructor(options?: MAPServerOptions) {\n // Wire in dependency order\n this.eventBus = options?.eventBus ?? new EventBusImpl({\n store: options?.stores?.events\n });\n // ... continue for other blocks\n }\n \n on(type: string | string[], handler: (event: MAPEvent) => void): () => void {\n return this.eventBus.on(type, handler);\n }\n \n emit(event: Omit<MAPEvent, 'id' | 'timestamp'>): MAPEvent {\n return this.eventBus.emit(event);\n }\n}\n```\n\n## Files to Create/Modify\n\n- `ts-sdk/src/server/server.ts` - NEW: MAPServer class\n- `ts-sdk/src/server/index.ts` - Export MAPServer","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:53:15","updated_at":"2026-01-30 00:08:31","closed_at":"2026-01-30 00:08:31","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-h4ac","from_type":"issue","to":"i-7wuw","to_type":"issue","type":"blocks"},{"from":"i-h4ac","from_type":"issue","to":"i-9m8u","to_type":"issue","type":"blocks"},{"from":"i-h4ac","from_type":"issue","to":"s-7hnb","to_type":"spec","type":"implements"}],"tags":["core","mapserver"]}
66
- {"id":"i-7wuw","uuid":"9dd52d39-73ac-4fc2-b62d-dabd11000817","title":"Implement MAPServer event delivery wiring","content":"## Summary\n\nWire automatic event delivery from EventBus to subscriptions via RouterConnections.\n\n## Acceptance Criteria\n\n- [ ] Event delivery wired in constructor (when `eventDelivery.enabled !== false`)\n- [ ] Subscribe to `eventBus.on('*', ...)` for all events\n- [ ] For each event:\n - Call `subscriptions.match(event)` to find matching subscriptions\n - Skip paused subscriptions\n - Apply custom `eventDelivery.filter` if provided\n - Find router for subscription's session ID\n - Track sequence numbers per subscription (Map<subId, number>)\n - Call `router.notify()` with event notification\n- [ ] Error handling:\n - Catch `notify()` errors\n - Log warning with session ID and error message\n - Remove dead connection from tracking\n- [ ] Event delivery can be disabled with `eventDelivery: { enabled: false }`\n- [ ] Private helper: `#findRouterForSession(sessionId: string): RouterConnection | undefined`\n- [ ] Private helper: `#removeConnection(sessionId: string): void`\n\n## Implementation Notes\n\n```typescript\n// In constructor, after building blocks created:\nif (options?.eventDelivery?.enabled !== false) {\n const subscriptionSequences = new Map<string, number>();\n \n this.eventBus.on('*', (event) => {\n const matchingSubs = this.subscriptions.match(event);\n \n for (const subId of matchingSubs) {\n const sub = this.subscriptions.get(subId);\n if (!sub || sub.paused) continue;\n \n if (options?.eventDelivery?.filter) {\n if (!options.eventDelivery.filter(event, sub)) continue;\n }\n \n const router = this.#findRouterForSession(sub.sessionId);\n if (!router) continue;\n \n const seq = (subscriptionSequences.get(subId) ?? 0) + 1;\n subscriptionSequences.set(subId, seq);\n \n router.notify(NOTIFICATION_METHODS.EVENT, {\n subscriptionId: subId,\n sequenceNumber: seq,\n eventId: event.id,\n timestamp: event.timestamp,\n event,\n }).catch((error) => {\n console.warn(`Event delivery failed for session ${sub.sessionId}:`, error.message);\n this.#removeConnection(sub.sessionId);\n });\n }\n });\n}\n```\n\n## Files to Modify\n\n- `ts-sdk/src/server/server.ts` - Add event delivery wiring","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:53:31","updated_at":"2026-01-30 00:08:31","closed_at":"2026-01-30 00:08:31","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-7wuw","from_type":"issue","to":"i-8edg","to_type":"issue","type":"blocks"},{"from":"i-7wuw","from_type":"issue","to":"s-7hnb","to_type":"spec","type":"implements"}],"tags":["events","mapserver"]}
67
- {"id":"i-9m8u","uuid":"7f40fa2c-0fc3-4a71-a184-ee87b4c90a76","title":"Implement MAPServer.accept() and connection tracking","content":"## Summary\n\nImplement the `accept()` method for accepting new connections and tracking them by session ID.\n\n## Acceptance Criteria\n\n- [ ] `readonly connections: ReadonlyMap<string, RouterConnection>` property\n- [ ] Private mutable map: `#connections: Map<string, RouterConnection>`\n- [ ] `accept(stream: Stream, options?: AcceptOptions): RouterConnection` method:\n - Creates `RouterConnectionImpl` with server's handlers, sessions, middleware\n - Default role is `'agent'` if not specified\n - Passes `name` and `resumeToken` from options\n - Sets up cleanup on `router.closed` to remove from connections map\n - Returns router (caller must call `start()`)\n- [ ] Connection tracking:\n - Add to map after session is established (listen for session creation)\n - Remove from map when connection closes\n - Handle case where connection closes before session established\n- [ ] `#findRouterForSession(sessionId)` works with connections map\n- [ ] `#removeConnection(sessionId)` removes from map\n\n## Implementation Notes\n\nThe tricky part is that session ID isn't known until after `router.start()` processes `map/connect`. Options:\n\n**Option A:** Track by a temporary ID, update key when session established\n```typescript\naccept(stream, options) {\n const router = new RouterConnectionImpl({ ... });\n \n // Track immediately with temporary key\n const tempId = ulid();\n this.#connections.set(tempId, router);\n \n // Update key when session established\n // (RouterConnection may need to expose session or emit event)\n \n router.closed.then(() => {\n // Clean up by either key\n if (router.session) {\n this.#connections.delete(router.session.id);\n }\n this.#connections.delete(tempId);\n });\n \n return router;\n}\n```\n\n**Option B:** Only track after start() is called\nThis requires user to notify us, or we wrap start().\n\n**Recommendation:** Option A with temporary ID, or expose session from RouterConnection.\n\n## Files to Modify\n\n- `ts-sdk/src/server/server.ts` - Add accept() and connection tracking\n- `ts-sdk/src/server/router/connection.ts` - May need to expose session property","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:53:52","updated_at":"2026-01-30 00:08:31","closed_at":"2026-01-30 00:08:31","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-9m8u","from_type":"issue","to":"i-8edg","to_type":"issue","type":"blocks"},{"from":"i-9m8u","from_type":"issue","to":"s-7hnb","to_type":"spec","type":"implements"}],"tags":["connections","mapserver"]}
68
- {"id":"i-8edg","uuid":"ff6307bc-e4f8-4f81-835a-23471fbe4f33","title":"Implement MAPServer.close() with graceful shutdown","content":"## Summary\n\nImplement the `close()` method for graceful server shutdown.\n\n## Acceptance Criteria\n\n- [ ] `close(options?: CloseOptions): Promise<void>` method\n- [ ] Force-expire disconnected sessions first:\n - Call `this.sessions.expireStale(0)` to expire all disconnected sessions\n- [ ] Graceful shutdown (default):\n - For each connection, attempt `router.close()`\n - Race against timeout (default 5000ms)\n - Force close if timeout expires\n - Wait for all connections to close\n- [ ] Force shutdown (`force: true`):\n - Immediately close all connections without waiting\n- [ ] Clear connections map after all closed\n- [ ] Document that queued messages are lost\n\n## Implementation Notes\n\n```typescript\nasync close(options?: CloseOptions): Promise<void> {\n const { timeout = 5000, force = false } = options ?? {};\n \n // Force-expire disconnected sessions\n this.sessions.expireStale(0);\n \n if (force) {\n await Promise.all(\n [...this.#connections.values()].map(r => r.close())\n );\n this.#connections.clear();\n return;\n }\n \n // Graceful with timeout\n const closePromises = [...this.#connections.values()].map(async (router) => {\n try {\n await Promise.race([\n router.close(),\n new Promise((_, reject) => \n setTimeout(() => reject(new Error('Timeout')), timeout)\n )\n ]);\n } catch {\n await router.close();\n }\n });\n \n await Promise.all(closePromises);\n this.#connections.clear();\n}\n```\n\n## Files to Modify\n\n- `ts-sdk/src/server/server.ts` - Add close() method","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:54:07","updated_at":"2026-01-30 00:08:31","closed_at":"2026-01-30 00:08:31","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-8edg","from_type":"issue","to":"i-gq26","to_type":"issue","type":"blocks"},{"from":"i-8edg","from_type":"issue","to":"s-7hnb","to_type":"spec","type":"implements"}],"tags":["mapserver","shutdown"]}
69
- {"id":"i-gq26","uuid":"20f1b4fa-60b5-4c95-a1d2-fefac3d3d454","title":"Add MAPServer unit tests","content":"## Summary\n\nWrite comprehensive unit tests for MAPServer covering all functionality.\n\n## Acceptance Criteria\n\n- [ ] Test file: `ts-sdk/src/__tests__/server-mapserver.test.ts`\n\n### Constructor Tests\n- [ ] Creates all building blocks with defaults (zero options)\n- [ ] All building blocks accessible via readonly properties\n- [ ] Custom stores passed to auto-created blocks\n- [ ] Custom stores ignored when block is provided directly\n- [ ] Custom building block used when provided\n- [ ] Partial overrides: custom block used as dependency for auto-created blocks\n- [ ] Handlers composed correctly with additionalHandlers\n- [ ] Middleware stored for use in accept()\n- [ ] Server name/version/capabilities passed to connection handlers\n\n### Event Delivery Tests\n- [ ] Events delivered to matching subscriptions\n- [ ] Sequence numbers increment per subscription\n- [ ] Paused subscriptions skipped\n- [ ] Custom filter applied\n- [ ] Event delivery disabled when `enabled: false`\n- [ ] Notify errors logged and connection removed\n\n### Connection Tracking Tests\n- [ ] Connections map starts empty\n- [ ] Connection added after accept() and start()\n- [ ] Connection removed when closed\n- [ ] findRouterForSession returns correct router\n- [ ] Multiple concurrent connections tracked correctly\n\n### accept() Tests\n- [ ] Returns RouterConnection\n- [ ] Default role is 'agent'\n- [ ] Custom role respected\n- [ ] Resume token passed through\n- [ ] Name passed through\n\n### close() Tests\n- [ ] Graceful shutdown waits for connections\n- [ ] Timeout causes force close\n- [ ] Force shutdown closes immediately\n- [ ] Disconnected sessions expired\n- [ ] Connections map cleared after close\n\n### Convenience Methods Tests\n- [ ] on() delegates to eventBus.on()\n- [ ] emit() delegates to eventBus.emit()\n\n## Implementation Notes\n\nUse `createStreamPair()` for testing connections.\nMock or use real building blocks as appropriate.","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:54:23","updated_at":"2026-01-30 00:08:32","closed_at":"2026-01-30 00:08:32","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-gq26","from_type":"issue","to":"i-3kds","to_type":"issue","type":"blocks"},{"from":"i-gq26","from_type":"issue","to":"s-7hnb","to_type":"spec","type":"implements"}],"tags":["mapserver","tests"]}
70
- {"id":"i-3kds","uuid":"3af0a8c8-7bf5-4962-bbde-4f1e0ca435b0","title":"Add MAPServer integration tests with client SDK","content":"## Summary\n\nWrite integration tests verifying MAPServer works end-to-end with the client SDK.\n\n## Acceptance Criteria\n\n- [ ] Test file: `ts-sdk/src/__tests__/server-mapserver-integration.test.ts`\n\n### Basic Flow Tests\n- [ ] Client connects to MAPServer\n- [ ] Agent connects, registers, appears in listAgents()\n- [ ] Client subscribes and receives events\n- [ ] Agent sends message, client receives\n- [ ] Client disconnects cleanly\n\n### Multiple Connections Tests\n- [ ] Multiple agents connect concurrently\n- [ ] Multiple clients subscribe to same events\n- [ ] Messages route to correct agents\n\n### Session Resume Tests\n- [ ] Agent disconnects with resume token\n- [ ] Agent reconnects with token\n- [ ] Session state preserved\n\n### Shutdown Tests\n- [ ] Graceful shutdown notifies clients\n- [ ] Clients see connection close\n- [ ] No errors during shutdown\n\n### Comparison Test\n- [ ] MAPServer produces identical behavior to manual wiring\n- [ ] Same test scenario run against both, compare results\n\n## Implementation Notes\n\n```typescript\ndescribe('MAPServer Integration', () => {\n it('should handle full client-agent flow', async () => {\n const server = new MAPServer({ name: 'Test' });\n const [clientStream, serverStream] = createStreamPair();\n \n // Server accepts\n const router = server.accept(serverStream);\n router.start();\n \n // Client connects\n const client = new ClientConnection(clientStream);\n await client.connect();\n \n // Subscribe and verify events...\n \n await server.close();\n });\n});\n```","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:54:35","updated_at":"2026-01-30 00:08:32","closed_at":"2026-01-30 00:08:32","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-3kds","from_type":"issue","to":"i-1kat","to_type":"issue","type":"blocks"},{"from":"i-3kds","from_type":"issue","to":"s-7hnb","to_type":"spec","type":"implements"}],"tags":["integration","mapserver","tests"]}
71
- {"id":"i-1kat","uuid":"9c322d56-4764-43b7-b1ef-9c076c5d4a7c","title":"Refactor integration-harness.ts to use MAPServer","content":"## Summary\n\nSimplify the existing integration test harness to use the new MAPServer class, demonstrating the reduction in boilerplate.\n\n## Acceptance Criteria\n\n- [ ] Refactor `integration-harness.ts` to use `MAPServer`\n- [ ] Maintain same public interface (`createClient`, `createAgent`, etc.)\n- [ ] Remove manual building block wiring (~50 lines)\n- [ ] Remove manual event delivery wiring (~30 lines)\n- [ ] All existing integration tests still pass\n- [ ] Document before/after line count reduction\n\n### Before (current)\n```typescript\n// ~80 lines of setup\nconst eventBus = new EventBusImpl();\nconst sessions = new SessionManagerImpl({ eventBus });\n// ... 4 more building blocks\nconst handlers = combineHandlers(...);\n// ... event delivery wiring\n```\n\n### After (with MAPServer)\n```typescript\n// ~10 lines of setup\nconst server = new MAPServer({ name: 'Test Server' });\n```\n\n## Implementation Notes\n\nThe harness exposes internal building blocks for test assertions. MAPServer provides this via readonly properties, so:\n\n```typescript\n// Before\nharness.eventBus\nharness.agents\n\n// After (same access pattern)\nserver.eventBus\nserver.agents\n```\n\nMay need to update some test helpers that reference harness internals.\n\n## Files to Modify\n\n- `ts-sdk/src/__tests__/helpers/integration-harness.ts` - Refactor to use MAPServer\n\n## Verification\n\n- Run full test suite: `npm test`\n- All 900+ tests should pass\n- Harness file should be significantly shorter","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-29 23:54:47","updated_at":"2026-01-30 00:08:32","closed_at":"2026-01-30 00:08:32","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1kat","from_type":"issue","to":"s-7hnb","to_type":"spec","type":"implements"}],"tags":["mapserver","refactor","tests"]}
72
- {"id":"i-4ogv","uuid":"9fd0562e-dad1-416f-8c4a-6ca39a5aea34","title":"Define ACP type definitions and interfaces","content":"## Acceptance Criteria\n- [ ] ACP JSON-RPC types defined (request, response, notification, error)\n- [ ] ACP method-specific types (InitializeRequest, PromptRequest, SessionNotification, etc.)\n- [ ] ACPEnvelope interface with acp and acpContext fields\n- [ ] ACPError class with code, message, and data properties\n- [ ] ACPClientHandlers interface for client-side callbacks\n- [ ] ACPAgentHandler interface for agent-side implementations\n- [ ] ACPContext interface with streamId, sessionId, clientParticipantId\n- [ ] All types exported from main SDK entry point\n- [ ] TypeScript definitions compile without errors\n- [ ] JSDoc documentation for all exported types\n\n## Context\nImplements [[s-9kpn]] requirement: \"Bundle ACP types directly in MAP SDK\"\n\nThis is the foundation for all ACP-over-MAP functionality. The types must match the ACP 2024-10-07 specification while integrating cleanly with the existing MAP SDK type system.\n\n## Technical Notes\n- Place types in `ts-sdk/src/acp/types.ts`\n- Export from `ts-sdk/src/index.ts` as both named exports and ACP namespace\n- Consider versioning (e.g., `ACP_2024_10_07` namespace)\n- Include only stable ACP methods initially (defer unstable methods)\n- Types should be compatible with both client and agent sides","status":"closed","priority":0,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-30 18:57:39","updated_at":"2026-01-30 19:07:34","closed_at":"2026-01-30 19:07:34","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-4ogv","from_type":"issue","to":"i-59n2","to_type":"issue","type":"blocks"},{"from":"i-4ogv","from_type":"issue","to":"i-5o4x","to_type":"issue","type":"blocks"},{"from":"i-4ogv","from_type":"issue","to":"i-6622","to_type":"issue","type":"blocks"},{"from":"i-4ogv","from_type":"issue","to":"s-9kpn","to_type":"spec","type":"implements"}],"tags":["acp","foundation","types"],"feedback":[{"id":"c22185ac-939f-42b6-b3eb-714554cdafe5","from_id":"i-4ogv","to_id":"s-9kpn","feedback_type":"comment","content":"## Implementation Complete: ACP Type Definitions\n\n### What was implemented\nCreated `ts-sdk/src/acp/types.ts` with comprehensive ACP type definitions:\n\n1. **Core ID types**: `ACPSessionId`, `ACPRequestId`, `ACPProtocolVersion`, etc.\n2. **JSON-RPC base types**: `ACPRequest`, `ACPNotification`, `ACPResponse`, `ACPErrorResponse`\n3. **ACPError class**: Full implementation with `fromResponse()` and `toErrorObject()` methods\n4. **Capability types**: `ACPClientCapabilities`, `ACPAgentCapabilities`, `ACPFileSystemCapability`\n5. **Method-specific types**: All initialize, session, prompt, terminal, and file system types\n6. **ACP-over-MAP envelope**: `ACPEnvelope` and `ACPContext` interfaces\n7. **Handler interfaces**: `ACPClientHandlers` and `ACPAgentHandler`\n8. **Constants**: `ACP_PROTOCOL_VERSION`, `ACP_METHODS`, `ACP_ERROR_CODES`\n9. **Type guards**: `isACPRequest`, `isACPEnvelope`, etc.\n\n### Files created/modified\n- Created: `ts-sdk/src/acp/types.ts` (~900 lines)\n- Created: `ts-sdk/src/acp/index.ts`\n- Modified: `ts-sdk/src/index.ts` (added exports)\n\n### Design decisions\n- All types prefixed with `ACP` to avoid conflicts with MAP types\n- Types match ACP 2024-10-07 specification\n- JSDoc documentation on all exported types\n- Both stable and unstable ACP methods included for completeness\n- Type guards provided for runtime type checking\n\n### Evidence\n- TypeScript compiles without errors for the ACP module\n- All acceptance criteria met","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-30T19:07:34.617Z","updated_at":"2026-01-30T19:07:34.617Z"}]}
73
- {"id":"i-6622","uuid":"289d9b5f-eeef-427c-9ff6-ea85ee52f312","title":"Implement ACPStreamConnection class (client-side)","content":"## Acceptance Criteria\n- [ ] ACPStreamConnection class with streamId, targetAgent, sessionId properties\n- [ ] Constructor accepts ACPStreamOptions (targetAgent, client handlers)\n- [ ] All stable ACP methods implemented (initialize, authenticate, newSession, loadSession, setSessionMode, prompt, cancel)\n- [ ] Request/response correlation using pending requests map\n- [ ] Timeout handling (30s default) with cleanup\n- [ ] EventEmitter for sessionLost event\n- [ ] close() method to clean up subscriptions and pending requests\n- [ ] Proper error propagation (ACPError for ACP errors, regular Error for transport)\n- [ ] Unit tests covering all methods and error paths\n- [ ] Integration test with TestServer\n\n## Context\nImplements [[s-9kpn]] requirement: \"ACPStreamConnection class (client-side virtual ACP connection)\"\n\nThis is the primary client-facing API for ACP-over-MAP. It wraps MAP's send/subscribe primitives to provide a familiar ACP interface.\n\n## Technical Notes\n- Use MAP's send() for requests, subscribe() for receiving responses\n- Each request generates a correlationId for matching responses\n- Maintain #pendingRequests map: correlationId -> {resolve, reject, timeout}\n- Subscription filter: fromAgents=[targetAgent], protocol='acp', streamId=this.streamId\n- Handle both ACP responses and ACP notifications via subscription\n- Reference implementation in spec's \"Request/Response Correlation\" section","status":"closed","priority":0,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-30 18:57:39","updated_at":"2026-01-30 19:15:57","closed_at":"2026-01-30 19:15:57","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6622","from_type":"issue","to":"i-3mdm","to_type":"issue","type":"blocks"},{"from":"i-6622","from_type":"issue","to":"i-6nfk","to_type":"issue","type":"blocks"},{"from":"i-6622","from_type":"issue","to":"i-6o5v","to_type":"issue","type":"blocks"},{"from":"i-6622","from_type":"issue","to":"s-9kpn","to_type":"spec","type":"implements"}],"tags":["acp","client","core"]}
74
- {"id":"i-59n2","uuid":"fac13daa-1af1-4578-9328-0b83c31450c1","title":"Implement ACPAgentAdapter class (agent-side)","content":"## Acceptance Criteria\n- [ ] ACPAgentAdapter constructor accepts MapAgent and ACPAgentHandler\n- [ ] Automatic message routing from MAP onMessage to appropriate handler method\n- [ ] sendSessionUpdate() method for agent->client notifications\n- [ ] requestPermission() method with request/response correlation\n- [ ] All client-facing methods (readTextFile, writeTextFile, createTerminal, etc.)\n- [ ] Proper ACPEnvelope wrapping/unwrapping\n- [ ] Error handling and propagation to client\n- [ ] Unit tests with mock MapAgent\n- [ ] Integration test with real agent and client\n\n## Context\nImplements [[s-9kpn]] requirement: \"ACPAgentAdapter class (agent-side helper)\"\n\nThis adapter simplifies implementing ACP-compatible agents by handling the MAP<->ACP translation layer.\n\n## Technical Notes\n- Listen to mapAgent.onMessage, filter for protocol='acp'\n- Extract ACPEnvelope from message payload\n- Route to handler based on acp.method\n- For agent->client calls, use mapAgent.send() with proper correlation\n- Maintain pending client requests map for agent->client request/response\n- Reference implementation in spec's \"Agent SDK Interface\" section","status":"closed","priority":0,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-30 18:57:40","updated_at":"2026-01-30 19:15:58","closed_at":"2026-01-30 19:15:58","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-59n2","from_type":"issue","to":"i-1nl1","to_type":"issue","type":"blocks"},{"from":"i-59n2","from_type":"issue","to":"i-6o5v","to_type":"issue","type":"blocks"},{"from":"i-59n2","from_type":"issue","to":"s-9kpn","to_type":"spec","type":"implements"}],"tags":["acp","agent","core"]}
75
- {"id":"i-3mdm","uuid":"4c8c4399-8002-429b-94de-6c4cdb78a646","title":"Extend ClientConnection with createACPStream method","content":"## Acceptance Criteria\n- [ ] createACPStream() method added to ClientConnection class\n- [ ] Method accepts ACPStreamOptions parameter\n- [ ] Returns initialized ACPStreamConnection instance\n- [ ] Subscription set up for receiving messages from target agent\n- [ ] Multiple concurrent streams supported (each with unique streamId)\n- [ ] Stream cleanup on ClientConnection.disconnect()\n- [ ] TypeScript types updated\n- [ ] Unit tests for stream creation and lifecycle\n- [ ] Documentation updated with usage examples\n\n## Context\nImplements [[s-9kpn]] requirement: \"Client SDK Interface - Creating ACP Streams\"\n\nThis is the entry point for clients to create virtual ACP connections over MAP.\n\n## Technical Notes\n- Generate unique streamId (use existing ID generation utilities)\n- Store active streams in Map<streamId, ACPStreamConnection>\n- Each stream creates its own subscription with filters for protocol='acp' and streamId\n- On disconnect, call close() on all active streams\n- Reference usage example in spec's \"Usage Example\" section","status":"closed","priority":0,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-30 18:57:41","updated_at":"2026-01-30 19:17:58","closed_at":"2026-01-30 19:17:58","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-3mdm","from_type":"issue","to":"i-1nl1","to_type":"issue","type":"blocks"},{"from":"i-3mdm","from_type":"issue","to":"s-9kpn","to_type":"spec","type":"implements"}],"tags":["acp","client","integration"],"feedback":[{"id":"7f339791-f41d-4429-a57c-14dfb04c67af","from_id":"i-3mdm","to_id":"s-9kpn","feedback_type":"comment","content":"## Phase 3 Implementation Complete: Integration\n\n### Event Subscription and Routing (i-6nfk)\n✅ ACPStreamConnection sets up subscription lazily in `#setupSubscription()`\n✅ Subscription filter: `fromAgents=[targetAgent]` (streamId filtered at message level)\n✅ Message routing: responses → pending request resolution, notifications → client handler, agent requests → response correlation\n✅ `sessionUpdate` notifications dispatched to `client.sessionUpdate()`\n✅ All agent→client requests handled with response correlation and timeout\n✅ Subscription cleanup in `close()` method\n✅ `lastEventId` tracking for reconnection support\n\n### ClientConnection.createACPStream (i-3mdm)\n✅ `createACPStream()` method added to ClientConnection\n✅ Accepts `ACPStreamOptions` parameter (minus mapClient, auto-injected)\n✅ Returns ACPStreamConnection instance\n✅ Streams tracked in `#acpStreams` Map keyed by streamId\n✅ Multiple concurrent streams supported\n✅ Stream cleanup on `disconnect()` - closes all active ACP streams\n✅ Getter methods: `getACPStream(streamId)`, `acpStreams` (ReadonlyMap)\n✅ JSDoc with usage examples\n\n### Design Decisions\n- Subscription filter uses only `fromAgents`, streamId filtering done at message handling level (more efficient than server-side filtering)\n- Streams auto-removed from tracking when closed via 'close' event listener\n- ClientConnection.disconnect() now properly cleans up ACP streams before subscriptions","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-30T19:18:10.213Z","updated_at":"2026-01-30T19:18:10.213Z"}]}
76
- {"id":"i-5o4x","uuid":"217a8ad3-51d5-407c-9dde-e86f6e883be3","title":"Implement agent capability advertisement for ACP","content":"## Acceptance Criteria\n- [ ] AgentCapabilities interface extended with protocols array and acp field\n- [ ] AgentConnection.connect() accepts and registers ACP capabilities\n- [ ] listAgents() response includes capabilities.protocols and capabilities.acp\n- [ ] Example agent registration with ACP capability\n- [ ] Client can filter agents by protocols=['acp']\n- [ ] Unit tests for capability registration and discovery\n- [ ] Documentation with examples\n\n## Context\nImplements [[s-9kpn]] requirement: \"Agent discovery via capabilities\"\n\nAllows clients to discover which agents support ACP tunneling and what ACP features they support.\n\n## Technical Notes\n- Extend existing AgentCapabilities type (don't break existing agents)\n- protocols: string[] for protocol support advertisement\n- acp: { version: string; features: string[] } for ACP-specific metadata\n- Update agent registration flow to include capabilities in metadata\n- Update listAgents to return full capabilities object\n- Reference spec's \"Agent Discovery for ACP\" section","status":"closed","priority":0,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-30 18:57:41","updated_at":"2026-01-30 19:15:55","closed_at":"2026-01-30 19:15:55","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-5o4x","from_type":"issue","to":"i-1nl1","to_type":"issue","type":"blocks"},{"from":"i-5o4x","from_type":"issue","to":"s-9kpn","to_type":"spec","type":"implements"}],"tags":["acp","capabilities","discovery"],"feedback":[{"id":"be7e2625-0bcd-42c7-b63c-6412bc99723f","from_id":"i-5o4x","to_id":"s-9kpn","feedback_type":"comment","content":"## Phase 2 Implementation Complete: Core Classes\n\n### Capability Advertisement (i-5o4x)\n✅ Added `ACPCapability` interface to `types/index.ts`\n✅ Extended `ParticipantCapabilities` with `protocols?: string[]` and `acp?: ACPCapability`\n✅ Added `protocol?: string` to `MessageMeta` for protocol identification\n\n### ACPStreamConnection (i-6622)\n✅ Implemented full client-side ACP stream in `src/acp/stream.ts`\n✅ All stable ACP methods: initialize, authenticate, newSession, loadSession, setSessionMode, prompt, cancel\n✅ Request/response correlation with pending requests map\n✅ Timeout handling (30s default) with cleanup\n✅ EventEmitter for session updates and errors\n✅ Subscription-based message receiving from agent\n✅ `lastEventId` getter for reconnection support\n\n### ACPAgentAdapter (i-59n2)\n✅ Implemented agent-side adapter in `src/acp/adapter.ts`\n✅ Automatic MAP→ACP message routing via `onMessage` handler\n✅ Stream context tracking per client\n✅ All agent→client methods: sendSessionUpdate, requestPermission, readTextFile, writeTextFile, createTerminal, terminalOutput, releaseTerminal, waitForTerminalExit, killTerminal\n✅ Agent→client request/response correlation with timeout\n✅ Proper ACPEnvelope wrapping for all directions\n\n### Design Decisions\n- Used EventEmitter pattern for ACPStreamConnection events (sessionUpdate, error, close)\n- Stream contexts tracked in Map keyed by streamId for multi-client support\n- Hybrid delivery: subscriptions for notifications, correlation for requests\n- `createACPStream()` factory function for simpler client usage\n\n### All exports added to `src/index.ts` and `src/acp/index.ts`","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-30T19:16:14.530Z","updated_at":"2026-01-30T19:16:14.530Z"}]}
77
- {"id":"i-6nfk","uuid":"58629362-ce9b-4fa4-b57b-0e37b257356d","title":"Implement event subscription and routing for ACP streams","content":"## Acceptance Criteria\n- [ ] ACPStreamConnection sets up subscription on creation with proper filters\n- [ ] Subscription filters: fromAgents=[targetAgent], protocol='acp', streamId=this.streamId\n- [ ] Incoming messages routed to correct handler (response vs notification vs agent->client request)\n- [ ] sessionUpdate notifications dispatched to client.sessionUpdate handler\n- [ ] Agent->client requests (requestPermission, fs/*, terminal/*) handled with response correlation\n- [ ] Subscription cleanup on stream close\n- [ ] Unit tests for routing logic\n- [ ] Integration test with multiple message types\n\n## Context\nImplements [[s-9kpn]] requirement: \"Event subscription and routing\"\n\nThis handles the receive path for ACP messages over MAP subscriptions.\n\n## Technical Notes\n- Use existing Subscription class from MAP SDK\n- Message routing logic:\n - If acp.result or acp.error exists -> resolve pending request\n - If acp.method === 'session/update' -> call client.sessionUpdate()\n - If acp.method starts with 'session/request_' or 'fs/' or 'terminal/' -> handle as agent request\n- Track last event ID for reconnection support\n- Reference spec's \"Event Flow\" and \"Message Delivery\" sections","status":"closed","priority":0,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-30 18:57:42","updated_at":"2026-01-30 19:17:58","closed_at":"2026-01-30 19:17:58","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6nfk","from_type":"issue","to":"i-887a","to_type":"issue","type":"blocks"},{"from":"i-6nfk","from_type":"issue","to":"s-9kpn","to_type":"spec","type":"implements"}],"tags":["acp","events","routing"]}
78
- {"id":"i-887a","uuid":"e877e9d8-c44f-4005-ae97-4022995907dc","title":"Implement reconnection and session restoration for ACP streams","content":"## Acceptance Criteria\n- [ ] ACPStreamConnection detects MAP reconnection\n- [ ] Subscription re-established with resumeFrom last event ID\n- [ ] ACP session validity check after reconnection (session/status or similar)\n- [ ] sessionLost event emitted if ACP session no longer valid\n- [ ] Pending requests properly handled during reconnection (reject or retry)\n- [ ] Unit tests for reconnection scenarios\n- [ ] Integration test with TestServer disconnect/reconnect\n\n## Context\nImplements [[s-9kpn]] requirement: \"Reconnection and session restoration\"\n\nEnsures ACP streams survive temporary network disconnections by leveraging MAP's event replay.\n\n## Technical Notes\n- Listen to ClientConnection reconnection events\n- Store #lastEventId from each received message\n- On reconnect, call subscribe() with resumeFrom: this.#lastEventId\n- Verify ACP session still valid (may need to ping agent or check session state)\n- If session lost, emit 'sessionLost' event so client can call loadSession()\n- Reference spec's \"Reconnection & Session Resume\" section","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-30 18:57:42","updated_at":"2026-01-30 19:21:52","closed_at":"2026-01-30 19:21:52","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-887a","from_type":"issue","to":"s-9kpn","to_type":"spec","type":"implements"}],"tags":["acp","reconnection","reliability"],"feedback":[{"id":"c2b807c6-b260-43c2-a228-a8c8568ad352","from_id":"i-887a","to_id":"s-9kpn","feedback_type":"comment","content":"## Phase 4 Implementation Complete: Testing & Reliability\n\n### TestACPAgent Mock (i-6o5v)\n✅ `TestACPAgent` class with configurable handlers in `src/testing/test-acp-agent.ts`\n✅ Mock implementation of all ACP methods (initialize, authenticate, newSession, loadSession, setSessionMode, prompt, cancel)\n✅ `sendSessionUpdate()` for streaming notifications\n✅ `sendClientRequest()` and specific methods (requestPermission, readTextFile, writeTextFile, terminal*)\n✅ Configurable delays via `defaultDelay` option\n✅ Error injection via `errorOnMethod` option\n✅ `MockACPStream` helper for client-side testing without full MAP setup\n✅ Request tracking via `receivedRequests` property\n✅ Exported from testing module\n\n### Reconnection Support (i-887a)\n✅ ACPStreamConnection listens to MAP `onReconnection` events\n✅ New events: `reconnecting`, `reconnected`, `sessionLost`\n✅ `isReconnecting` property for state tracking\n✅ Subscription re-established on reconnect (subscription cleared, lazily recreated)\n✅ Session validity check via cancel notification after reconnection\n✅ `sessionLost` event with reason if session no longer valid\n✅ Pending requests rejected during reconnection with clear error\n✅ Cleanup: reconnection listener removed on `close()`\n\n### Design Decisions\n- Session verification uses cancel notification (non-destructive) since ACP has no status method\n- MockACPStream provides simplified testing without MAP server\n- TestACPAgent tracks all received requests for test assertions\n- Reconnection rejects pending requests rather than retrying (client decides retry policy)","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-30T19:22:05.883Z","updated_at":"2026-01-30T19:22:05.883Z"}]}
79
- {"id":"i-6o5v","uuid":"492e89bb-e2ba-400e-a92d-aa7619afade8","title":"Implement TestACPAgent mock for unit testing","content":"## Acceptance Criteria\n- [ ] TestACPAgent class with configurable handlers\n- [ ] Mock implementation of all ACP methods (initialize, newSession, prompt, etc.)\n- [ ] sendUpdate() method to simulate streaming session/update notifications\n- [ ] sendRequest() method to simulate agent->client requests\n- [ ] Configurable delays and errors for testing error handling\n- [ ] Helper to create ACPStreamConnection with mock agent\n- [ ] Example usage in documentation\n- [ ] Exported from @anthropic/map-sdk/testing\n\n## Context\nImplements [[s-9kpn]] requirement: \"Testing infrastructure (TestACPAgent)\"\n\nProvides lightweight mocks for unit testing ACP client code without a full server.\n\n## Technical Notes\n- Place in ts-sdk/src/testing/test-acp-agent.ts\n- Constructor accepts partial handler implementations with sensible defaults\n- Use EventEmitter for async simulation of streaming updates\n- Should work standalone (no server required) for pure unit tests\n- Reference spec's \"Testing Strategy - Unit Testing\" section","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-30 18:57:43","updated_at":"2026-01-30 19:20:50","closed_at":"2026-01-30 19:20:50","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6o5v","from_type":"issue","to":"i-20lt","to_type":"issue","type":"blocks"},{"from":"i-6o5v","from_type":"issue","to":"s-9kpn","to_type":"spec","type":"implements"}],"tags":["acp","infrastructure","testing"]}
80
- {"id":"i-1nl1","uuid":"b0b2bb64-ab45-4578-af8e-f5639fe00c3c","title":"Add comprehensive ACP-over-MAP documentation","content":"## Acceptance Criteria\n- [ ] Architecture guide explaining ACP-over-MAP design\n- [ ] Client-side usage guide with createACPStream examples\n- [ ] Agent-side implementation guide with ACPAgentAdapter examples\n- [ ] Testing guide with TestACPAgent and TestServer examples\n- [ ] API reference for all ACP types and classes\n- [ ] Migration guide for existing ACP users\n- [ ] Troubleshooting section for common issues\n- [ ] Code examples compile and run correctly\n\n## Context\nImplements [[s-9kpn]] documentation requirements.\n\nComplete documentation ensures developers can successfully implement and use ACP-over-MAP.\n\n## Technical Notes\n- Place in ts-sdk/docs/acp-over-map.md\n- Include architecture diagrams (can reference spec diagrams)\n- Provide complete working examples (copy from spec where applicable)\n- Cover all major use cases: basic usage, multiple streams, error handling, testing\n- Link from main README and API docs","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-30 18:57:44","updated_at":"2026-01-31 05:02:08","closed_at":"2026-01-31 05:02:08","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1nl1","from_type":"issue","to":"i-584z","to_type":"issue","type":"blocks"},{"from":"i-1nl1","from_type":"issue","to":"s-9kpn","to_type":"spec","type":"implements"}],"tags":["acp","documentation"],"feedback":[{"id":"fd10199b-f266-4258-9228-9be97d6584cf","from_id":"i-1nl1","to_id":"s-9kpn","feedback_type":"comment","content":"## Documentation Complete (i-1nl1)\n\nCreated comprehensive documentation at `ts-sdk/docs/acp-over-map.md`:\n\n### Sections Covered\n- Overview with architecture diagram\n- Quick Start for both client and agent\n- Client-Side API (createACPStream, ACPStreamConnection, handlers, multiple streams)\n- Agent-Side API (capability advertisement, ACPAgentAdapter, handlers, communication)\n- Reconnection Handling\n- Error Handling (ACP errors, stream errors)\n- Testing (TestACPAgent, error injection, integration with TestServer)\n- ACP Type Reference (core types, request/response types, type guards)\n- Migration Guide from direct ACP\n- Troubleshooting section\n\n### Design Decisions\n- Focused on practical usage with working code examples\n- Referenced spec diagrams rather than duplicating\n- Organized by use case (client vs agent)\n- Included common pitfalls in troubleshooting","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-31T05:02:07.964Z","updated_at":"2026-01-31T05:02:07.964Z"}]}
81
- {"id":"i-20lt","uuid":"2a4a0c58-8c02-42cf-ad06-4930014fa063","title":"Integrate ACP support into TestServer","content":"## Acceptance Criteria\n- [ ] TestServer.registerACPAgent() method added\n- [ ] Method accepts agent ID and ACPAgentHandler or TestACPAgent\n- [ ] Registered agents advertise ACP capability automatically\n- [ ] Full request/response flow works through TestServer\n- [ ] Multiple concurrent ACP streams supported\n- [ ] Example integration test demonstrating full flow\n- [ ] Documentation updated with testing examples\n\n## Context\nImplements [[s-9kpn]] requirement: \"Testing infrastructure (TestServer integration)\"\n\nEnables full integration testing of ACP-over-MAP with realistic multi-agent scenarios.\n\n## Technical Notes\n- Extend existing TestServer class (don't break existing tests)\n- registerACPAgent() internally creates an agent with ACP capability\n- Wire up ACPAgentAdapter behind the scenes\n- Should support both TestACPAgent mocks and real ACPAgentHandler implementations\n- Reference spec's \"Testing Strategy - Integration Testing\" section","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-30 18:57:44","updated_at":"2026-01-30 19:23:17","closed_at":"2026-01-30 19:23:17","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-20lt","from_type":"issue","to":"i-584z","to_type":"issue","type":"blocks"},{"from":"i-20lt","from_type":"issue","to":"s-9kpn","to_type":"spec","type":"implements"}],"tags":["acp","integration","testing"],"feedback":[{"id":"28afe8f7-4f20-4887-a347-2ba62dc65fc5","from_id":"i-20lt","to_id":"s-9kpn","feedback_type":"comment","content":"## TestServer Integration (i-20lt)\n\n### Implementation\n✅ `createACPTestAgent()` function in `src/testing/test-acp-agent.ts`\n✅ Accepts ACPAgentHandler and optional ACPCapability\n✅ Creates TestAgent with `protocols: ['acp']` capability automatically\n✅ Wires up ACPAgentAdapter to handle ACP messages\n✅ Returns both `agent` (TestAgent) and `adapter` (ACPAgentAdapter)\n✅ Supports multiple concurrent ACP streams (inherits from TestServer)\n✅ Full request/response flow through TestServer messaging\n✅ Exported from testing module\n\n### Design Decision\n- Used helper function instead of modifying TestServer directly\n- Keeps TestServer simple and unchanged\n- `createACPTestAgent()` composes TestAgent + ACPAgentAdapter\n- Returns both for full control in tests (can access agent.receivedMessages, adapter.sendSessionUpdate, etc.)\n\n### Usage Example in JSDoc\n```typescript\nconst { agent, adapter } = await createACPTestAgent(server, {\n name: 'CodingAgent',\n handler: {\n initialize: async () => ({ ... }),\n newSession: async () => ({ sessionId: 'session-1' }),\n prompt: async (params, ctx) => {\n await adapter.sendSessionUpdate(ctx.streamId, { ... });\n return { stopReason: 'end_turn' };\n },\n cancel: async () => {},\n },\n});\n```","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-30T19:23:28.539Z","updated_at":"2026-01-30T19:23:28.539Z"}]}
82
- {"id":"i-584z","uuid":"1c6b020e-fb4a-4633-92e9-ac4dd26313c8","title":"Create end-to-end ACP-over-MAP example","content":"## Acceptance Criteria\n- [ ] Complete example client using createACPStream\n- [ ] Example agent using ACPAgentAdapter\n- [ ] Demonstrates full ACP flow (initialize, newSession, prompt with streaming)\n- [ ] Shows agent->client requests (permission, file system, terminal)\n- [ ] Error handling examples\n- [ ] Runnable with simple npm commands\n- [ ] README with setup and usage instructions\n- [ ] Documented in main SDK examples\n\n## Context\nImplements [[s-9kpn]] by providing a working reference implementation.\n\nA complete example helps developers understand the full picture and serves as a starting point.\n\n## Technical Notes\n- Place in ts-sdk/examples/acp-over-map/\n- Keep dependencies minimal (just the SDK)\n- Use TypeScript with clear type annotations\n- Include both simple and advanced scenarios\n- Reference spec's \"Usage Example\" and \"Event Flow\" sections","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-30 18:57:45","updated_at":"2026-01-31 05:12:16","closed_at":"2026-01-31 05:12:16","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-584z","from_type":"issue","to":"s-9kpn","to_type":"spec","type":"implements"}],"tags":["acp","documentation","examples"],"feedback":[{"id":"6445eb6c-e108-4322-91d8-62830981ac4c","from_id":"i-584z","to_id":"s-9kpn","feedback_type":"comment","content":"## End-to-End Example Implementation Complete\n\nCreated comprehensive examples in `ts-sdk/examples/acp-over-map/`:\n\n### Files Created\n\n1. **main.ts** - Complete end-to-end example demonstrating:\n - Setting up a MAP server (TestServer)\n - Registering an ACP-enabled agent with full handler implementation\n - Connecting a client via MAP\n - Full ACP lifecycle: initialize → newSession → prompt\n - Streaming session updates (agent_message_chunk)\n - Agent→client requests (permissions, file read/write)\n - Error handling patterns\n\n2. **client-example.ts** - Focused client implementation showing:\n - ExampleACPClient wrapper class pattern\n - Handling permission requests with UI-ready structure\n - Streaming update handlers\n - File system and terminal handlers\n - Session lifecycle management\n\n3. **agent-example.ts** - Focused agent implementation showing:\n - ExampleACPAgent class using ACPAgentAdapter\n - Session storage and management\n - Streaming response generation\n - Agent→client request patterns (permissions, files, terminals)\n - Conversation history tracking\n\n4. **README.md** - Documentation including:\n - Overview and prerequisites\n - Run instructions for each example\n - Code snippets for quick reference\n - ACP flow diagram\n - Error handling patterns\n - Reconnection handling\n\n### Key Implementation Details\n\n- All examples use correct ACP types (optionId, kind with \"allow_once\"/\"reject_once\", toolCall)\n- Proper TypeScript types imported from SDK\n- TestServer used for demonstration (real apps would use actual MAP server)\n- Examples compile without TypeScript errors\n- All 78 ACP tests still pass","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-31T05:12:15.928Z","updated_at":"2026-01-31T05:12:15.928Z"}]}
83
- {"id":"i-82ky","uuid":"610cb6e4-a6d6-4ce0-b03b-57e7f45d6b33","title":"Add agentic-mesh as optional peer dependency","content":"## Summary\nUpdate `ts-sdk/package.json` to declare agentic-mesh as an optional peer dependency.\n\n## Changes\nAdd to package.json:\n```json\n{\n \"peerDependencies\": {\n \"agentic-mesh\": \"^0.1.0\"\n },\n \"peerDependenciesMeta\": {\n \"agentic-mesh\": {\n \"optional\": true\n }\n }\n}\n```\n\n## Acceptance Criteria\n- [ ] agentic-mesh added as optional peer dependency\n- [ ] SDK builds successfully without agentic-mesh installed\n- [ ] TypeScript compilation works without agentic-mesh types","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:07:33","updated_at":"2026-01-31 08:10:23","closed_at":"2026-01-31 08:10:23","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-82ky","from_type":"issue","to":"i-4jb9","to_type":"issue","type":"blocks"},{"from":"i-82ky","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["package-json","part-1","setup"]}
84
- {"id":"i-4jb9","uuid":"58c88e04-f469-4718-b39f-03a5ba5ec94f","title":"Create agenticMeshStream() adapter function","content":"## Summary\nCreate `ts-sdk/src/stream/agentic-mesh.ts` with the stream adapter that converts agentic-mesh's `TunnelStream` to MAP SDK's `Stream` interface.\n\n## Implementation\n\n### Types to define\n- `AgenticMeshStreamConfig` - configuration interface\n\n### Functions to implement\n- `agenticMeshStream(config)` - main factory function\n- `tunnelStreamToMapStream(tunnel)` - internal adapter\n\n### Key behaviors\n1. Uses dynamic import (`await import('agentic-mesh')`) for optional dependency\n2. Starts transport if not already active\n3. Connects to peer endpoint\n4. Creates TunnelStream with unique streamId\n5. Adapts to MAP Stream interface (readable/writable)\n\n## Files\n- Create: `ts-sdk/src/stream/agentic-mesh.ts`\n\n## Acceptance Criteria\n- [ ] `AgenticMeshStreamConfig` interface exported\n- [ ] `agenticMeshStream()` creates valid MAP Stream from TunnelStream\n- [ ] Dynamic import used for agentic-mesh (optional dependency)\n- [ ] Transport auto-starts if not active\n- [ ] Proper error thrown if peer connection fails\n- [ ] JSDoc documentation with usage example","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:07:42","updated_at":"2026-01-31 08:11:49","closed_at":"2026-01-31 08:11:49","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-4jb9","from_type":"issue","to":"i-22dh","to_type":"issue","type":"blocks"},{"from":"i-4jb9","from_type":"issue","to":"i-4upv","to_type":"issue","type":"blocks"},{"from":"i-4jb9","from_type":"issue","to":"i-7dm4","to_type":"issue","type":"blocks"},{"from":"i-4jb9","from_type":"issue","to":"i-v9kq","to_type":"issue","type":"blocks"},{"from":"i-4jb9","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["core","part-1","stream"]}
85
- {"id":"i-4upv","uuid":"7a12fd51-fcbb-4415-a314-3e7d7b2054a8","title":"Export agenticMeshStream from stream module","content":"## Summary\nUpdate `ts-sdk/src/stream/index.ts` to conditionally re-export the agentic-mesh stream adapter.\n\n## Changes\nAdd to `ts-sdk/src/stream/index.ts`:\n```typescript\n// Agentic-mesh transport (optional)\nexport {\n agenticMeshStream,\n type AgenticMeshStreamConfig,\n} from './agentic-mesh';\n```\n\n## Acceptance Criteria\n- [ ] `agenticMeshStream` exported from stream module\n- [ ] `AgenticMeshStreamConfig` type exported\n- [ ] Existing stream exports unchanged","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:07:48","updated_at":"2026-01-31 08:12:18","closed_at":"2026-01-31 08:12:18","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-4upv","from_type":"issue","to":"i-2ut4","to_type":"issue","type":"blocks"},{"from":"i-4upv","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["exports","part-1"]}
86
- {"id":"i-22dh","uuid":"60697972-97e6-4d68-847d-60e2e9fea082","title":"Add ClientConnection.connectMesh() static method","content":"## Summary\nAdd `connectMesh()` static factory method to `ClientConnection` for connecting via agentic-mesh transport.\n\n## Implementation\n\n### Types to add\n- `MeshConnectOptions` extends `ClientConnectOptions` with:\n - `transport: TransportAdapter`\n - `peer: PeerEndpoint`\n - `localPeerId: string`\n\n### Method to implement\n```typescript\nstatic async connectMesh(options: MeshConnectOptions): Promise<ClientConnection>\n```\n\n### Key behaviors\n1. Dynamic import of `agenticMeshStream` from `../stream/agentic-mesh`\n2. Create stream using `agenticMeshStream()`\n3. Configure `createStream` factory for reconnection support\n4. Normalize reconnection options (true → { enabled: true })\n5. Create ClientConnection with stream\n6. Call `connect()` with auth options\n7. Return connected client\n\n## Files\n- Modify: `ts-sdk/src/connection/client.ts`\n\n## Acceptance Criteria\n- [ ] `MeshConnectOptions` interface exported\n- [ ] `ClientConnection.connectMesh()` works with Nebula transport\n- [ ] `ClientConnection.connectMesh()` works with Tailscale transport\n- [ ] Reconnection works correctly over mesh transport\n- [ ] Dynamic import used (doesn't break if agentic-mesh not installed)\n- [ ] JSDoc documentation with usage example","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:07:57","updated_at":"2026-01-31 08:15:19","closed_at":"2026-01-31 08:15:19","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-22dh","from_type":"issue","to":"i-2ut4","to_type":"issue","type":"blocks"},{"from":"i-22dh","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["client","convenience","part-1"]}
87
- {"id":"i-7dm4","uuid":"aeec950e-7bfe-4661-884a-18557e1e296b","title":"Add AgentConnection.connectMesh() static method","content":"## Summary\nAdd `connectMesh()` static factory method to `AgentConnection` for connecting and registering via agentic-mesh transport.\n\n## Implementation\n\n### Types to add\n- `AgentMeshConnectOptions` extends `AgentConnectOptions` with:\n - `transport: TransportAdapter`\n - `peer: PeerEndpoint`\n - `localPeerId: string`\n\n### Method to implement\n```typescript\nstatic async connectMesh(options: AgentMeshConnectOptions): Promise<AgentConnection>\n```\n\n### Key behaviors\n1. Dynamic import of `agenticMeshStream` from `../stream/agentic-mesh`\n2. Create stream using `agenticMeshStream()`\n3. Configure `createStream` factory for reconnection support\n4. Normalize reconnection options\n5. Create AgentConnection with stream and agent options (role, visibility, parent, scopes)\n6. Call `connect()` with auth options (performs handshake + registration)\n7. Return connected and registered agent\n\n## Files\n- Modify: `ts-sdk/src/connection/agent.ts`\n\n## Acceptance Criteria\n- [ ] `AgentMeshConnectOptions` interface exported\n- [ ] `AgentConnection.connectMesh()` works with Nebula transport\n- [ ] `AgentConnection.connectMesh()` works with Tailscale transport\n- [ ] Agent registration works correctly over mesh\n- [ ] Reconnection restores agent and scope memberships\n- [ ] Dynamic import used (doesn't break if agentic-mesh not installed)\n- [ ] JSDoc documentation with usage example","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:08:05","updated_at":"2026-01-31 08:15:20","closed_at":"2026-01-31 08:15:20","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-7dm4","from_type":"issue","to":"i-2ut4","to_type":"issue","type":"blocks"},{"from":"i-7dm4","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["agent","convenience","part-1"]}
88
- {"id":"i-2ut4","uuid":"c3d167c8-2764-4f51-95b3-12eb4903f97c","title":"Update main SDK exports for mesh transport","content":"## Summary\nUpdate `ts-sdk/src/index.ts` to export the new mesh transport types and functions.\n\n## Changes\nAdd to the Stream section:\n```typescript\nexport {\n // ... existing exports ...\n agenticMeshStream,\n type AgenticMeshStreamConfig,\n} from \"./stream\";\n```\n\nAdd to Connections section:\n```typescript\nexport {\n // ... existing exports ...\n type MeshConnectOptions,\n type AgentMeshConnectOptions,\n} from \"./connection\";\n```\n\n## Files\n- Modify: `ts-sdk/src/index.ts`\n- Modify: `ts-sdk/src/connection/index.ts` (re-export new types)\n\n## Acceptance Criteria\n- [ ] `agenticMeshStream` exported from main entry point\n- [ ] `AgenticMeshStreamConfig` type exported\n- [ ] `MeshConnectOptions` type exported\n- [ ] `AgentMeshConnectOptions` type exported\n- [ ] All existing exports unchanged","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:08:12","updated_at":"2026-01-31 08:15:57","closed_at":"2026-01-31 08:15:57","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-2ut4","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["exports","part-1"]}
89
- {"id":"i-v9kq","uuid":"d7f4c0a0-93ae-48b4-8bfe-52961047baf8","title":"Write tests for agenticMeshStream adapter","content":"## Summary\nCreate unit tests for the agentic-mesh stream adapter with mocked agentic-mesh components.\n\n## Test Cases\n\n### agenticMeshStream()\n- [ ] Creates valid Stream from TunnelStream\n- [ ] Starts transport if not active\n- [ ] Connects to peer endpoint\n- [ ] Throws error if peer connection fails\n- [ ] Creates unique streamId for each call\n\n### tunnelStreamToMapStream()\n- [ ] Readable stream yields frames from TunnelStream\n- [ ] Writable stream writes to TunnelStream\n- [ ] Close propagates to TunnelStream\n- [ ] Errors propagate correctly\n\n## Files\n- Create: `ts-sdk/src/__tests__/stream-agentic-mesh.test.ts`\n\n## Acceptance Criteria\n- [ ] All test cases passing\n- [ ] Mocks agentic-mesh components (doesn't require real dependency)\n- [ ] Tests work in CI without agentic-mesh installed","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:08:20","updated_at":"2026-01-31 08:16:46","closed_at":"2026-01-31 08:16:46","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-v9kq","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["part-1","testing"]}
90
- {"id":"i-2t9w","uuid":"efe20105-ed89-480d-8e66-c7e67df2b47f","title":"Create MAPMeshPeer class with core lifecycle","content":"## Summary\nCreate the `MAPMeshPeer` class as a thin wrapper around agentic-mesh's `MeshPeer` for decentralized P2P MAP networks.\n\n## Implementation\n\n### File Structure\n```\nts-sdk/src/mesh/\n├── index.ts # Module exports\n├── peer.ts # MAPMeshPeer class\n└── types.ts # Type definitions (re-exports + extensions)\n```\n\n### MAPMeshPeer Class\n```typescript\nexport class MAPMeshPeer {\n readonly peerId: string;\n readonly peerName: string;\n \n // Wrapped agentic-mesh MeshPeer\n private readonly meshPeer: MeshPeer;\n \n private constructor(meshPeer: MeshPeer);\n \n // Factory method\n static async create(config: MAPMeshPeerConfig): Promise<MAPMeshPeer>;\n \n // Lifecycle\n async start(): Promise<void>;\n async stop(): Promise<void>;\n get isRunning(): boolean;\n}\n```\n\n### MAPMeshPeerConfig Interface\n```typescript\nexport interface MAPMeshPeerConfig {\n /** Unique peer ID */\n peerId: string;\n /** Display name */\n peerName?: string;\n /** Transport adapter (from agentic-mesh) */\n transport: TransportAdapter;\n /** Git sync configuration */\n git?: {\n enabled: boolean;\n repoPath: string;\n httpPort?: number;\n };\n /** Initial peers to connect to on start */\n peers?: PeerEndpoint[];\n /** MAP server configuration */\n map?: {\n // Any MapServer config options\n };\n}\n```\n\n## Key Behaviors\n1. `create()` instantiates agentic-mesh's `MeshPeer` with config\n2. `start()` calls `meshPeer.start(transport)`\n3. `stop()` calls `meshPeer.stop()`\n4. Uses dynamic import for agentic-mesh (optional peer dependency)\n\n## Files\n- Create: `ts-sdk/src/mesh/index.ts`\n- Create: `ts-sdk/src/mesh/peer.ts`\n- Create: `ts-sdk/src/mesh/types.ts`\n\n## Acceptance Criteria\n- [ ] MAPMeshPeer class created with lifecycle methods\n- [ ] Dynamic import for agentic-mesh dependency\n- [ ] Config interface defined\n- [ ] Basic start/stop works\n- [ ] JSDoc documentation","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:48:57","updated_at":"2026-01-31 16:10:52","closed_at":"2026-01-31 16:10:52","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-2t9w","from_type":"issue","to":"i-1ey6","to_type":"issue","type":"blocks"},{"from":"i-2t9w","from_type":"issue","to":"i-629k","to_type":"issue","type":"blocks"},{"from":"i-2t9w","from_type":"issue","to":"i-6iwi","to_type":"issue","type":"blocks"},{"from":"i-2t9w","from_type":"issue","to":"i-6trb","to_type":"issue","type":"blocks"},{"from":"i-2t9w","from_type":"issue","to":"i-74ub","to_type":"issue","type":"blocks"},{"from":"i-2t9w","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["foundation","mesh-peer","part-3"]}
91
- {"id":"i-6trb","uuid":"fd72b907-baa8-4f63-a398-f0435fe0c218","title":"Add agent management to MAPMeshPeer","content":"## Summary\nAdd methods for creating and managing local agents on the MAPMeshPeer's internal MapServer.\n\n## Implementation\n\n### Methods to Add\n```typescript\nclass MAPMeshPeer {\n // Create a local agent on this peer's MapServer\n async createAgent(config: CreateAgentConfig): Promise<LocalAgent>;\n \n // Get an agent by ID\n getAgent(agentId: AgentId): LocalAgent | undefined;\n \n // List all local agents\n getLocalAgents(): Agent[];\n \n // List all known agents (local + discovered from peers)\n getAllAgents(): Agent[];\n}\n```\n\n### CreateAgentConfig Interface\n```typescript\nexport interface CreateAgentConfig {\n /** Agent ID (auto-generated if not provided) */\n agentId?: AgentId;\n /** Agent name */\n name?: string;\n /** Agent role */\n role?: string;\n /** Initial scopes to join */\n scopes?: ScopeId[];\n /** Agent visibility */\n visibility?: AgentVisibility;\n /** Initial metadata */\n metadata?: Record<string, unknown>;\n}\n```\n\n### LocalAgent Interface\nWrap agentic-mesh's AgentConnection with MAP SDK compatible interface:\n```typescript\nexport interface LocalAgent {\n readonly agentId: AgentId;\n readonly name: string;\n readonly role?: string;\n readonly state: AgentState;\n \n // State management\n busy(): Promise<void>;\n idle(): Promise<void>;\n updateState(state: AgentState): Promise<void>;\n updateMetadata(metadata: Record<string, unknown>): Promise<void>;\n \n // Messaging\n send(to: Address, payload: unknown, meta?: MessageMeta): Promise<SendResult>;\n onMessage(handler: (message: Message) => void): () => void;\n \n // Lifecycle\n unregister(reason?: string): Promise<void>;\n}\n```\n\n## Files\n- Modify: `ts-sdk/src/mesh/peer.ts`\n- Modify: `ts-sdk/src/mesh/types.ts`\n\n## Acceptance Criteria\n- [ ] `createAgent()` creates agent on internal MapServer\n- [ ] `LocalAgent` wrapper provides MAP SDK compatible interface\n- [ ] Agent state management works (busy/idle)\n- [ ] Agent messaging works\n- [ ] `getAllAgents()` includes discovered peer agents","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:49:09","updated_at":"2026-01-31 16:10:59","closed_at":"2026-01-31 16:10:59","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6trb","from_type":"issue","to":"i-1zi4","to_type":"issue","type":"blocks"},{"from":"i-6trb","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["agents","mesh-peer","part-3"]}
92
- {"id":"i-6iwi","uuid":"626bd36f-f090-44ee-a325-974d80adceac","title":"Add peer connection methods to MAPMeshPeer","content":"## Summary\nAdd methods for connecting to and managing other mesh peers (P2P connections).\n\n## Implementation\n\n### Methods to Add\n```typescript\nclass MAPMeshPeer {\n // Connect to a remote peer\n async connectToPeer(endpoint: PeerEndpoint): Promise<void>;\n \n // Disconnect from a peer\n async disconnectFromPeer(peerId: string, reason?: string): Promise<void>;\n \n // Get connected peer IDs\n get connectedPeers(): string[];\n \n // Check if connected to a specific peer\n isConnectedTo(peerId: string): boolean;\n \n // Event handlers for peer connections\n onPeerConnected(handler: (peerId: string, endpoint: PeerEndpoint) => void): () => void;\n onPeerDisconnected(handler: (peerId: string, reason?: string) => void): () => void;\n}\n```\n\n### PeerEndpoint Type\nRe-export from agentic-mesh or define compatible type:\n```typescript\nexport interface PeerEndpoint {\n peerId: string;\n address: string;\n port?: number;\n metadata?: Record<string, unknown>;\n}\n```\n\n## Key Behaviors\n1. `connectToPeer()` establishes P2P connection via mesh transport\n2. Connected peers automatically discover each other's agents\n3. Disconnection cleans up peer state\n4. Events emitted for connection state changes\n\n## Files\n- Modify: `ts-sdk/src/mesh/peer.ts`\n- Modify: `ts-sdk/src/mesh/types.ts`\n\n## Acceptance Criteria\n- [ ] `connectToPeer()` establishes connection\n- [ ] `disconnectFromPeer()` cleanly disconnects\n- [ ] `connectedPeers` returns active peer IDs\n- [ ] Connection events work\n- [ ] Peer agents are discovered after connection","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:49:18","updated_at":"2026-01-31 16:11:00","closed_at":"2026-01-31 16:11:00","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6iwi","from_type":"issue","to":"i-1zi4","to_type":"issue","type":"blocks"},{"from":"i-6iwi","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["mesh-peer","part-3","peers"]}
93
- {"id":"i-74ub","uuid":"36909259-f501-46a9-8c4a-96d6f1356efb","title":"Add git sync integration to MAPMeshPeer","content":"## Summary\nExpose git sync capabilities from the wrapped MeshPeer's GitTransportService.\n\n## Implementation\n\n### Property to Add\n```typescript\nclass MAPMeshPeer {\n // Access to git sync (null if git not enabled)\n get git(): GitSyncService | null;\n}\n```\n\n### GitSyncService Interface\nWrapper around agentic-mesh's GitTransportService with sync client:\n```typescript\nexport interface GitSyncService {\n /** Whether git service is running */\n readonly isRunning: boolean;\n \n /** HTTP port for git-remote-mesh helper */\n readonly httpPort: number;\n \n /** Create a sync client for a repository */\n createSyncClient(repoPath: string): GitSyncClient;\n \n /** Convenience: sync with a peer */\n sync(peerId: string, options?: SyncOptions): Promise<SyncResult>;\n \n /** Convenience: pull from a peer */\n pull(peerId: string, branch?: string, options?: PullOptions): Promise<SyncResult>;\n \n /** Convenience: push to a peer */\n push(peerId: string, branch?: string, options?: PushOptions): Promise<SyncResult>;\n \n /** Clone from a peer */\n clone(peerId: string, destPath: string, options?: CloneOptions): Promise<void>;\n}\n```\n\n### GitSyncClient Interface\nRe-export or wrap agentic-mesh's GitSyncClient:\n```typescript\nexport interface GitSyncClient {\n sync(peerId: string, options?: SyncOptions): Promise<SyncResult>;\n fetch(peerId: string, branch?: string): Promise<SyncResult>;\n pull(peerId: string, branch?: string, options?: PullOptions): Promise<SyncResult>;\n push(peerId: string, branch?: string, options?: PushOptions): Promise<SyncResult>;\n clone(peerId: string, destPath: string, options?: CloneOptions): Promise<SyncResult>;\n listRemoteRefs(peerId: string): Promise<{ ref: string; sha: string }[]>;\n}\n```\n\n### Sync Types (re-export from agentic-mesh)\n```typescript\nexport interface SyncOptions {\n branch?: string;\n bidirectional?: boolean;\n force?: boolean;\n}\n\nexport interface SyncResult {\n success: boolean;\n operation: 'fetch' | 'pull' | 'push' | 'clone' | 'sync';\n peerId: string;\n branch?: string;\n commits?: string[];\n error?: string;\n}\n```\n\n## Files\n- Modify: `ts-sdk/src/mesh/peer.ts`\n- Modify: `ts-sdk/src/mesh/types.ts`\n\n## Acceptance Criteria\n- [ ] `peer.git` returns GitSyncService when enabled\n- [ ] `peer.git` returns null when not enabled\n- [ ] `sync()`, `pull()`, `push()` work with connected peers\n- [ ] `createSyncClient()` returns functional client\n- [ ] Types exported for user code","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:49:32","updated_at":"2026-01-31 16:11:01","closed_at":"2026-01-31 16:11:01","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-74ub","from_type":"issue","to":"i-1zi4","to_type":"issue","type":"blocks"},{"from":"i-74ub","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["git","mesh-peer","part-3"]}
94
- {"id":"i-629k","uuid":"a200ed92-ab1e-4f52-aaca-220e30b0204f","title":"Add messaging and events to MAPMeshPeer","content":"## Summary\nAdd messaging convenience methods and event subscription support to MAPMeshPeer.\n\n## Implementation\n\n### Messaging Methods\n```typescript\nclass MAPMeshPeer {\n // Send a message (routes to local or remote agents)\n async send(\n from: AgentId,\n to: Address,\n payload: unknown,\n meta?: MessageMeta\n ): Promise<SendResult>;\n \n // Broadcast to all agents\n async broadcast(from: AgentId, payload: unknown, meta?: MessageMeta): Promise<SendResult>;\n}\n```\n\n### Event Subscription\n```typescript\nclass MAPMeshPeer {\n // Subscribe to system events\n subscribe(filter?: SubscriptionFilter): EventSubscription;\n \n // Convenience event handlers\n onAgentRegistered(handler: (agent: Agent) => void): () => void;\n onAgentUnregistered(handler: (agent: Agent) => void): () => void;\n onError(handler: (error: Error) => void): () => void;\n}\n```\n\n### EventSubscription Interface\n```typescript\nexport interface EventSubscription {\n readonly id: SubscriptionId;\n \n // Async iteration\n [Symbol.asyncIterator](): AsyncIterator<Event>;\n \n // Unsubscribe\n unsubscribe(): Promise<void>;\n}\n```\n\n## Key Behaviors\n1. `send()` routes to local MapServer, which handles local/remote delivery\n2. Events from internal MapServer exposed via subscription\n3. Convenience handlers for common events\n\n## Files\n- Modify: `ts-sdk/src/mesh/peer.ts`\n- Modify: `ts-sdk/src/mesh/types.ts`\n\n## Acceptance Criteria\n- [ ] `send()` delivers to local and remote agents\n- [ ] `subscribe()` returns working async iterable\n- [ ] Event handlers work for agent lifecycle\n- [ ] Error events propagated","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:49:44","updated_at":"2026-01-31 16:11:01","closed_at":"2026-01-31 16:11:01","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-629k","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["mesh-peer","messaging","part-3"]}
95
- {"id":"i-1ey6","uuid":"a846d1be-0376-427e-b5e9-e0b4a1526017","title":"Add scope management to MAPMeshPeer","content":"## Summary\nAdd methods for creating and managing scopes on the MAPMeshPeer's internal MapServer.\n\n## Implementation\n\n### Methods to Add\n```typescript\nclass MAPMeshPeer {\n // Create a scope\n createScope(config: CreateScopeConfig): Scope;\n \n // Get a scope by ID\n getScope(scopeId: ScopeId): Scope | undefined;\n \n // List all scopes\n listScopes(): Scope[];\n \n // Delete a scope\n deleteScope(scopeId: ScopeId): boolean;\n}\n```\n\n### CreateScopeConfig Interface\n```typescript\nexport interface CreateScopeConfig {\n scopeId?: ScopeId;\n name?: string;\n description?: string;\n visibility?: ScopeVisibility;\n permissions?: ScopePermissions;\n metadata?: Record<string, unknown>;\n}\n```\n\n## Files\n- Modify: `ts-sdk/src/mesh/peer.ts`\n- Modify: `ts-sdk/src/mesh/types.ts`\n\n## Acceptance Criteria\n- [ ] `createScope()` creates scope on internal MapServer\n- [ ] `getScope()` retrieves scope\n- [ ] `listScopes()` returns all scopes\n- [ ] Scope types exported","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:49:47","updated_at":"2026-01-31 16:11:01","closed_at":"2026-01-31 16:11:01","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1ey6","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["mesh-peer","part-3","scopes"]}
96
- {"id":"i-1zi4","uuid":"b8c7f1c2-d0a0-42ee-9dcc-01f887d3d8a2","title":"Export MAPMeshPeer from main SDK entry point","content":"## Summary\nUpdate main SDK exports to include MAPMeshPeer and related types.\n\n## Implementation\n\n### Update ts-sdk/src/index.ts\n```typescript\n// ===========================================================================\n// Mesh - Decentralized P2P mesh peer (optional agentic-mesh dependency)\n// ===========================================================================\nexport {\n MAPMeshPeer,\n type MAPMeshPeerConfig,\n type LocalAgent,\n type CreateAgentConfig,\n type GitSyncService,\n type GitSyncClient,\n type SyncOptions,\n type SyncResult,\n type PullOptions,\n type PushOptions,\n type CloneOptions,\n type PeerEndpoint,\n type CreateScopeConfig,\n} from \"./mesh\";\n```\n\n### Update ts-sdk/src/mesh/index.ts\nEnsure all public types and classes are exported.\n\n## Files\n- Modify: `ts-sdk/src/index.ts`\n- Modify: `ts-sdk/src/mesh/index.ts`\n\n## Acceptance Criteria\n- [ ] MAPMeshPeer exported from main entry\n- [ ] All public types exported\n- [ ] Build succeeds\n- [ ] Types available to consumers","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:49:52","updated_at":"2026-01-31 16:13:28","closed_at":"2026-01-31 16:13:28","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1zi4","from_type":"issue","to":"i-52rn","to_type":"issue","type":"blocks"},{"from":"i-1zi4","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["exports","part-3"]}
97
- {"id":"i-52rn","uuid":"78287b55-7486-4ca5-b51e-309a471ebb93","title":"Write tests for MAPMeshPeer","content":"## Summary\nCreate unit tests for MAPMeshPeer with mocked agentic-mesh components.\n\n## Status\n**Blocked** - Tests created but mocking dynamic imports requires either:\n1. Refactoring MAPMeshPeer to support dependency injection for testing\n2. Using real agentic-mesh as integration tests once available\n\n## What Was Completed\n- Test file created: `ts-sdk/src/__tests__/mesh-peer.test.ts`\n- All test cases written covering:\n - Lifecycle (create, start, stop)\n - Agent management (create, get, list)\n - Peer connections (connect, disconnect, status)\n - Git sync (sync, pull, push, clone)\n - Messaging (send with metadata)\n - Subscriptions (subscribe with filter)\n - Scopes (create, get, list)\n - Event handlers (peer/agent events)\n\n## Challenge\nThe `MAPMeshPeer.create()` uses `await import('agentic-mesh')` for the optional peer dependency. Vitest's `vi.mock()` doesn't properly intercept this dynamic import pattern.\n\n## Files\n- Created: `ts-sdk/src/__tests__/mesh-peer.test.ts` (test structure complete, mocking needs resolution)","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-01-31 08:49:57","updated_at":"2026-01-31 16:35:19","closed_at":"2026-01-31 16:35:19","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-52rn","from_type":"issue","to":"s-37t6","to_type":"spec","type":"implements"}],"tags":["part-3","testing"],"feedback":[{"id":"e44c0988-0b5a-4000-8f34-1df5a1ce887a","from_id":"i-52rn","to_id":"s-37t6","feedback_type":"comment","content":"**Implementation Status: Partial**\n\n**What was completed:**\n- Test file created at `ts-sdk/src/__tests__/mesh-peer.test.ts`\n- Comprehensive test cases covering all major functionality:\n - Creation and configuration\n - Lifecycle (start/stop)\n - Agent management\n - Peer connections\n - Git sync operations\n - Messaging\n - Event subscriptions\n - Scopes\n - Event handlers\n\n**Challenge encountered:**\nThe MAPMeshPeer uses dynamic `await import('agentic-mesh')` for the optional peer dependency. Vitest's `vi.mock()` doesn't properly intercept dynamic imports in this scenario. The mock factory is hoisted but the dynamic import at runtime isn't using the mock.\n\n**Options to resolve:**\n1. Refactor `MAPMeshPeer.create()` to accept an optional factory function for testing\n2. Use `vi.doMock()` with careful import ordering\n3. Move to integration tests with actual agentic-mesh once published\n\n**Recommendation:**\nKeep the test file as documentation of intended test coverage. Once agentic-mesh is available as a real dependency, the tests can be converted to integration tests that use the actual module.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-31T16:19:10.880Z","updated_at":"2026-01-31T16:19:10.880Z"},{"id":"f9d00c09-cac2-466c-a2ac-2fac9270b637","from_id":"i-52rn","to_id":"s-37t6","feedback_type":"comment","content":"## Implementation Complete: MAPMeshPeer Tests\n\n### Solution to Dynamic Import Mocking\nConverted from dynamic imports (`await import('agentic-mesh')`) to static imports with agentic-mesh as a devDependency. This approach:\n- Works reliably with Vitest's `vi.mock()` + `vi.hoisted()` pattern\n- Allows proper module mocking for unit tests\n- agentic-mesh is linked via local file path for development\n\n### Key Testing Pattern\n```typescript\n// Create mocks using vi.hoisted() BEFORE imports\nconst { mockMeshPeer, mockCreateMeshPeer } = vi.hoisted(() => {\n const meshPeer = { /* mock implementation */ };\n return { mockMeshPeer: meshPeer, mockCreateMeshPeer: vi.fn().mockReturnValue(meshPeer) };\n});\n\n// Mock the module\nvi.mock('agentic-mesh', () => ({ createMeshPeer: mockCreateMeshPeer }));\n\n// Import AFTER mock setup\nimport { MAPMeshPeer } from '../mesh';\n```\n\n### Test Coverage (36 tests)\n- Creation: config passing, git optional\n- Lifecycle: start/stop\n- Agent Management: create, get, list, state management, messaging\n- Peer Connections: connect, disconnect, status\n- Git Sync: sync, pull, push, clone, createSyncClient\n- Messaging: send with metadata\n- Events: subscribe, event handlers\n- Scopes: create, get, list","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-01-31T16:35:31.749Z","updated_at":"2026-01-31T16:35:31.749Z"}]}
98
- {"id":"i-3f04","uuid":"96e72168-5106-4024-bb10-8a14bcee989f","title":"Define Mail Protocol TypeScript types and interfaces","content":"## Acceptance Criteria\n- [ ] All Mail types defined in `ts-sdk/src/types/index.ts`\n- [ ] ConversationId, TurnId, ThreadId branded types\n- [ ] Conversation, ConversationParticipant, Thread, Turn interfaces\n- [ ] Content type interfaces (text, data, event, reference)\n- [ ] TurnSource, TurnVisibility types\n- [ ] MailMessageMeta interface for map/send integration\n- [ ] All 13 mail method request/response types\n- [ ] Mail event data types (8 event types)\n- [ ] Mail filter extension for SubscriptionFilter\n- [ ] Mail capability interfaces for connect handshake\n- [ ] Mail error codes (10000-10010 range)\n\n## Context\nImplements [[s-1bob]] type system. These types form the foundation for all mail functionality. They integrate with existing MAP types (MessageMeta, SubscriptionFilter, ParticipantCapabilities).\n\n## Technical Notes\n- Conversation and Turn types use ULID format IDs\n- ContentType is extensible: well-known types + x-prefixed custom\n- TurnSource discriminated union: explicit (mail/turn) vs intercepted (map/send)\n- Mail capabilities nest under ParticipantCapabilities.mail\n- Extends SubscriptionFilter with optional mail field\n- Follows MAP type conventions (branded IDs, Meta extension field)\n","status":"closed","priority":0,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:16:30","updated_at":"2026-02-05 20:50:01","closed_at":"2026-02-05 20:50:01","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-3f04","from_type":"issue","to":"i-2k3k","to_type":"issue","type":"blocks"},{"from":"i-3f04","from_type":"issue","to":"i-2pl3","to_type":"issue","type":"blocks"},{"from":"i-3f04","from_type":"issue","to":"i-3pxq","to_type":"issue","type":"blocks"},{"from":"i-3f04","from_type":"issue","to":"i-4vhm","to_type":"issue","type":"blocks"},{"from":"i-3f04","from_type":"issue","to":"i-5i4x","to_type":"issue","type":"blocks"},{"from":"i-3f04","from_type":"issue","to":"i-71rq","to_type":"issue","type":"blocks"},{"from":"i-3f04","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"},{"from":"i-3f04","from_type":"issue","to":"s-1bob","to_type":"spec","type":"references"}],"tags":["foundation","mail","types"],"feedback":[{"id":"b10a3e9a-55c9-4003-bcce-9b82b17ae821","from_id":"i-3f04","to_id":"s-1bob","feedback_type":"comment","content":"Implemented all Mail Protocol TypeScript types in `ts-sdk/src/types/index.ts` and method registry entries in `ts-sdk/src/protocol/index.ts`.\n\n**Types added (~65 new exports):**\n- 3 ID type aliases (ConversationId, TurnId, ThreadId)\n- 6 string union types (ConversationType, ConversationStatus, ParticipantRole, TurnStatus, TurnVisibility, TurnSource)\n- 7 core interfaces (Conversation, ConversationParticipant, ConversationPermissions, Thread, Turn, MailMessageMeta, MailSubscriptionFilter)\n- 8 event data interfaces\n- 39 request/response interfaces (13 methods x 3)\n- 2 constants (MAIL_METHODS, MAIL_ERROR_CODES)\n\n**Existing types extended:**\n- ParticipantCapabilities.mail (capability group)\n- MessageMeta.mail (turn tracking metadata)\n- SubscriptionFilter.mail (event filtering)\n- EVENT_TYPES (8 mail events)\n- ErrorCategory ('mail' added)\n- ERROR_CODES (11 mail error codes, 10000-10010)\n- MAP_METHODS (13 mail methods)\n- CAPABILITY_REQUIREMENTS (13 mail method entries)\n- MAPRequest union (13 mail request types)\n- METHOD_REGISTRY (13 mail entries)\n- MethodCategory ('mail' added)\n\n**Design decisions applied:**\n- Generic content model (contentType: string + content: unknown) - no per-type interfaces\n- `mail/` wire prefix (not `map/mail/`) per spec\n- `MAIL_` key prefix on MAIL_METHODS to avoid spread collision\n- `MAIL_PERMISSION_DENIED` to avoid collision with AUTH_ERROR_CODES.PERMISSION_DENIED\n- `_meta?: Meta` on all major interfaces\n\nAll 1451 existing tests pass.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T20:50:01.217Z","updated_at":"2026-02-05T20:50:01.217Z"}]}
99
- {"id":"i-71rq","uuid":"e332ca8c-268c-4ea3-bf3f-e3c3001de75e","title":"Create Mail storage interfaces and in-memory stores","content":"## Acceptance Criteria\n- [ ] ConversationStore interface with CRUD operations\n- [ ] ParticipantStore interface for conversation participants\n- [ ] TurnStore interface with query/pagination\n- [ ] ThreadStore interface\n- [ ] InMemoryConversationStore implementation\n- [ ] InMemoryParticipantStore implementation\n- [ ] InMemoryTurnStore implementation\n- [ ] InMemoryThreadStore implementation\n- [ ] Efficient querying (by conversation, thread, participant, timestamp)\n- [ ] Pagination support for turn listing\n\n## Context\nImplements [[s-1bob]] storage layer. Follows server SDK pattern of store interfaces with in-memory defaults. Each entity type gets its own store for separation of concerns.\n\n## Technical Notes\n- Follow pattern from `ts-sdk/src/server/*/stores/in-memory.ts`\n- TurnStore needs indexed queries: by conversation, thread, contentType, participant\n- Support afterTurnId/beforeTurnId cursor pagination\n- Timestamp range queries for turn replay\n- Store interfaces in `ts-sdk/src/server/types.ts`\n- Implementations in `ts-sdk/src/server/mail/stores/`","status":"closed","priority":0,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:16:37","updated_at":"2026-02-05 21:43:28","closed_at":"2026-02-05 21:43:28","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-71rq","from_type":"issue","to":"i-2k3k","to_type":"issue","type":"blocks"},{"from":"i-71rq","from_type":"issue","to":"i-3pxq","to_type":"issue","type":"blocks"},{"from":"i-71rq","from_type":"issue","to":"i-5i4x","to_type":"issue","type":"blocks"},{"from":"i-71rq","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"}],"tags":["foundation","mail","storage"],"feedback":[{"id":"8e1ac12a-c2cf-47b3-bd92-a6779080dbcc","from_id":"i-71rq","to_id":"s-1bob","feedback_type":"comment","content":"Implemented all 4 store interfaces and in-memory implementations:\n\n**Store interfaces** (in `server/types.ts`):\n- `ConversationStore` — CRUD + filter by type[], status[], participantId, time range, parentConversationId\n- `TurnStore` — append/get/list/delete + deleteByConversation, count; `TurnFilter` supports cursor pagination (afterTurnId/beforeTurnId), timestamp range, contentTypes, participantId, threadId, limit, order\n- `ThreadStore` — CRUD + deleteByConversation; `ThreadFilter` by conversationId + optional parentThreadId\n- `ParticipantStore` — CRUD with composite key (conversationId, participantId) + bidirectional lookup (getConversationsForParticipant), filter by role, active status\n\n**Server-side entity types** (in `server/types.ts`):\n- `ServerConversation`, `ServerTurn`, `ServerThread`, `ServerParticipant` — server-internal representations following the RegisteredAgent pattern (metadata as `Record<string, unknown>`, timestamps as `number`)\n\n**In-memory implementations** (in `server/mail/stores/`):\n- `InMemoryConversationStore` — Map-based with optional ParticipantStore injection for participant filtering\n- `InMemoryTurnStore` — Map + per-conversation ordered ID list for O(1) lookup + efficient range iteration\n- `InMemoryThreadStore` — Map + conversationId index\n- `InMemoryParticipantStore` — Composite key Map + bidirectional indexes (byConversation, byParticipant)\n\nAll follow existing SDK patterns: defensive copies, clear() for testing, size getter.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T21:43:28.190Z","updated_at":"2026-02-05T21:43:28.190Z"}]}
100
- {"id":"i-2k3k","uuid":"93db1ba7-8801-4ef0-957b-86dbd7b1700e","title":"Implement ConversationManager core logic","content":"## Acceptance Criteria\n- [ ] ConversationManager interface in server types\n- [ ] ConversationManagerImpl in `ts-sdk/src/server/mail/conversation-manager.ts`\n- [ ] create() with participant auto-join\n- [ ] get() with optional includes (participants, threads, stats)\n- [ ] list() with filtering and pagination\n- [ ] close() with status update\n- [ ] join() with permission checks\n- [ ] leave() with timestamp tracking\n- [ ] invite() with pending state\n- [ ] Emit mail.created, mail.closed, mail.participant.joined/left events\n- [ ] Validate parent conversation exists\n- [ ] Track participant counts and active status\n\n## Context\nImplements [[s-1bob]] conversation lifecycle. Core building block that manages conversation state and participants. EventBus integration for observability.\n\n## Technical Notes\n- Constructor injection: ConversationStore, ParticipantStore, EventBus\n- Use ULID generation for IDs (conv-, thread- prefixes)\n- Emit events through EventBus for audit trail\n- Permission validation delegated to caller (handlers)\n- Support nested conversations via parentConversationId","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:16:44","updated_at":"2026-02-05 22:27:05","closed_at":"2026-02-05 22:27:05","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-2k3k","from_type":"issue","to":"i-co01","to_type":"issue","type":"blocks"},{"from":"i-2k3k","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"}],"tags":["conversation","core","mail"],"feedback":[{"id":"4ea58398-d6f8-481a-93b1-0c7fabc41fad","from_id":"i-2k3k","to_id":"s-1bob","feedback_type":"comment","content":"Implemented ConversationManagerImpl in `server/mail/conversation-manager.ts`:\n- create() with auto-join of creator as initiator + optional initialParticipants\n- get() with optional includes (participants)\n- list() with ConversationFilter delegation to store\n- close() with status validation (rejects already closed)\n- join() with duplicate detection and active status check\n- leave() with leftAt timestamp and participant count decrement\n- invite() (same as join, different semantic intent)\n- Emits: mail.created, mail.closed, mail.participant.joined, mail.participant.left\n- Validates parent conversation exists on nested creation\n- Error types: ConversationNotFoundError, ConversationClosedError, ParticipantAlreadyJoinedError, ParticipantNotFoundError\n- Default permissions applied to new participants\n- 34 tests covering all operations and error cases","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T22:26:52.899Z","updated_at":"2026-02-05T22:26:52.899Z"}]}
101
- {"id":"i-5i4x","uuid":"5978a3ed-1ba1-467f-bb67-4494d1f6b54d","title":"Implement TurnManager for turn recording and querying","content":"## Acceptance Criteria\n- [ ] TurnManager interface in server types\n- [ ] TurnManagerImpl in `ts-sdk/src/server/mail/turn-manager.ts`\n- [ ] recordTurn() for both explicit (mail/turn) and intercepted (map/send)\n- [ ] listTurns() with filtering (thread, contentType, participant, time range)\n- [ ] getTurn() by ID\n- [ ] Support for turn threading (inReplyTo, threadId)\n- [ ] Visibility filtering enforcement\n- [ ] Emit mail.turn.added events\n- [ ] Validate conversation exists and participant is member\n- [ ] Support pagination with cursor (afterTurnId/beforeTurnId)\n- [ ] Content type validation for well-known types\n\n## Context\nImplements [[s-1bob]] turn persistence. Handles both direct recording (mail/turn) and intercepted recording (map/send + mail meta). Central to mail observability.\n\n## Technical Notes\n- TurnSource discriminated union tracks origin\n- Visibility rules filter turns at query time\n- Thread support via optional threadId/inReplyTo\n- Content validation: well-known types (text, data, event, reference) + x-prefixed\n- ULID IDs with turn- prefix for ordering\n","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:16:50","updated_at":"2026-02-05 22:27:05","closed_at":"2026-02-05 22:27:05","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-5i4x","from_type":"issue","to":"i-co01","to_type":"issue","type":"blocks"},{"from":"i-5i4x","from_type":"issue","to":"i-r1dp","to_type":"issue","type":"blocks"},{"from":"i-5i4x","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"},{"from":"i-5i4x","from_type":"issue","to":"s-1bob","to_type":"spec","type":"references"}],"tags":["core","mail","turns"],"feedback":[{"id":"67701c23-61ea-4820-816e-238179d2b742","from_id":"i-5i4x","to_id":"s-1bob","feedback_type":"comment","content":"Implemented TurnManagerImpl in `server/mail/turn-manager.ts`:\n- recordTurn() for explicit turns (mail/turn) with TurnSource { type: \"explicit\", method: \"mail/turn\" }\n- recordInterceptedTurn() for map/send with mail meta, TurnSource { type: \"intercepted\", messageId }\n- Content type validation: well-known (text, data, event, reference) + custom x-* prefix\n- Conversation existence validation via ConversationManager dependency\n- list() delegates to TurnStore with full filter support\n- updateStatus() for streaming → complete transitions with mail.turn.updated event\n- count() for conversation/thread turn counts\n- Emits: mail.turn.added, mail.turn.updated\n- Error types: TurnNotFoundError, TurnConversationNotFoundError, InvalidContentTypeError\n- 22 tests covering explicit/intercepted recording, content validation, pagination, status updates","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T22:26:58.913Z","updated_at":"2026-02-05T22:26:58.913Z"}]}
102
- {"id":"i-3pxq","uuid":"216eeb52-7f8a-462b-96ac-da72d91e727a","title":"Implement ThreadManager for conversation threading","content":"## Acceptance Criteria\n- [ ] ThreadManager interface in server types\n- [ ] ThreadManagerImpl in `ts-sdk/src/server/mail/thread-manager.ts`\n- [ ] createThread() with rootTurnId validation\n- [ ] listThreads() with optional parent filter\n- [ ] getThread() by ID\n- [ ] Support nested threads via parentThreadId\n- [ ] Track turn counts per thread\n- [ ] Emit mail.thread.created events\n- [ ] Validate rootTurn exists in conversation\n- [ ] Auto-update thread turnCount on turn additions\n\n## Context\nImplements [[s-1bob]] threading. Allows focused sub-conversations within conversations. Supports nested thread hierarchies.\n\n## Technical Notes\n- Threads are scoped to conversations\n- rootTurnId references first turn in thread\n- Optional parentThreadId for nested threads\n- ThreadStore tracks participant counts separately\n- ULID IDs with thread- prefix","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:16:55","updated_at":"2026-02-05 22:27:06","closed_at":"2026-02-05 22:27:06","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-3pxq","from_type":"issue","to":"i-co01","to_type":"issue","type":"blocks"},{"from":"i-3pxq","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"}],"tags":["core","mail","threads"],"feedback":[{"id":"dd1acf01-f126-4f69-bb3a-9881eb725548","from_id":"i-3pxq","to_id":"s-1bob","feedback_type":"comment","content":"Implemented ThreadManagerImpl in `server/mail/thread-manager.ts`:\n- create() with rootTurnId validation (must exist, must belong to conversation)\n- Nested threads via parentThreadId with existence validation\n- list() by conversation with optional parentThreadId filter\n- incrementTurnCount() and incrementParticipantCount() for tracking\n- Emits: mail.thread.created\n- Error types: ThreadNotFoundError, RootTurnNotFoundError, RootTurnConversationMismatchError, ParentThreadNotFoundError\n- 12 tests covering creation, validation, listing, and count tracking","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T22:27:01.860Z","updated_at":"2026-02-05T22:27:01.860Z"}]}
103
- {"id":"i-r1dp","uuid":"7feaa16d-5e47-4793-8e2f-6d3cb662818e","title":"Extend map/send handler to support mail meta interception","content":"## Acceptance Criteria\n- [ ] Update SendRequestParams type to include optional mail in meta\n- [ ] Modify map/send handler in message router\n- [ ] After routing, check for meta.mail presence\n- [ ] If mail capability enabled and mail meta present, record turn\n- [ ] Turn recording is non-blocking (log errors, don't fail send)\n- [ ] Source type is 'intercepted' with messageId\n- [ ] ContentType is 'data' with message payload as content\n- [ ] Warning in response if turn recording fails (optional)\n- [ ] Integration tests for send + mail recording\n\n## Context\nImplements [[s-1bob]] message interception. This is how map/send routes AND records turns. Core integration point between transport and persistence layers.\n\n## Technical Notes\n- Mail recording happens AFTER routing succeeds\n- Errors in turn recording don't affect message delivery\n- Check mail capability in session before recording\n- Use TurnManager.recordTurn() with intercepted source\n- Validate conversationId exists and sender is participant\n","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:17:02","updated_at":"2026-02-05 22:54:22","closed_at":"2026-02-05 22:54:22","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-r1dp","from_type":"issue","to":"i-1ghu","to_type":"issue","type":"blocks"},{"from":"i-r1dp","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"},{"from":"i-r1dp","from_type":"issue","to":"s-1bob","to_type":"spec","type":"references"}],"tags":["integration","mail","routing"],"feedback":[{"id":"9c6fa014-ae60-4dca-afb4-73e2f79fcd9c","from_id":"i-r1dp","to_id":"s-1bob","feedback_type":"comment","content":"Implemented mail meta interception in `map/send` handler at `ts-sdk/src/server/messages/handlers.ts`. Key details:\n\n- Added `meta?: { mail?: { conversationId, threadId?, inReplyTo?, visibility? } }` to SendParams\n- Added optional `turns?: TurnManager` to MessageHandlerOptions\n- Refactored map/send to capture result variable, then intercept after routing succeeds\n- Non-blocking: turn recording failures are caught and suppressed (send still succeeds)\n- Intercepted turns use `contentType: \"data\"` with the message payload as content\n- Source is `{ type: \"intercepted\", messageId }` linking back to the routed message\n- 5 interception tests covering: recording, absence, threadId/inReplyTo/visibility pass-through, failure tolerance, absent TurnManager","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T22:54:19.760Z","updated_at":"2026-02-05T22:54:19.760Z"}]}
104
- {"id":"i-co01","uuid":"805aaa8e-5407-47bc-a3ee-3120f2323cd0","title":"Implement mail/* protocol method handlers","content":"## Acceptance Criteria\n- [ ] createMailHandlers() factory in `ts-sdk/src/server/mail/handlers.ts`\n- [ ] mail/create handler\n- [ ] mail/get handler with optional includes\n- [ ] mail/list handler with filtering/pagination\n- [ ] mail/close handler\n- [ ] mail/join handler with catch-up support\n- [ ] mail/leave handler\n- [ ] mail/invite handler\n- [ ] mail/turn handler (explicit recording)\n- [ ] mail/turns/list handler with filtering\n- [ ] mail/thread/create handler\n- [ ] mail/thread/list handler\n- [ ] mail/summary handler (basic implementation)\n- [ ] mail/replay handler (turn replay)\n- [ ] Permission checks via HandlerContext\n- [ ] Error handling with mail error codes (10000-10010)\n\n## Context\nImplements [[s-1bob]] 13 protocol methods. These handlers expose mail functionality via JSON-RPC. Follows server SDK handler pattern.\n\n## Technical Notes\n- Handler signature: (params, ctx) => Promise&lt;result&gt;\n- Use ConversationManager, TurnManager, ThreadManager\n- Permission checks: validate participant is member\n- mail/summary returns placeholder or cached value (full AI generation is optional)\n- mail/replay uses TurnManager.listTurns() with timestamp/ID filters\n- Combine into single registry for MAPServer","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:17:10","updated_at":"2026-02-05 22:54:22","closed_at":"2026-02-05 22:54:22","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-co01","from_type":"issue","to":"i-1ghu","to_type":"issue","type":"blocks"},{"from":"i-co01","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"}],"tags":["handlers","mail","protocol"],"feedback":[{"id":"7b2d4e95-df97-46ae-b59d-65d533a4bb6e","from_id":"i-co01","to_id":"s-1bob","feedback_type":"comment","content":"Implemented all 13 mail/* protocol method handlers in `createMailHandlers()` factory at `ts-sdk/src/server/mail/handlers.ts`. Handlers follow the established server SDK pattern (HandlerRegistry, HandlerContext). Key implementation details:\n\n- Error mapping from manager errors to MAIL_ERROR_CODES (10000-10010) via `mapMailError()` helper\n- `mail/get` handler composes includes from multiple managers (threads, turns, stats) at the handler level per the ConversationManager design comment\n- `mail/summary` returns placeholder (`generated: false`) per spec\n- Cursor-based pagination for list/turns/list/thread/list/replay using entity IDs\n- Thread turn count auto-increment in `mail/turn` handler when threadId provided (non-fatal)\n- 57 handler tests covering all 13 methods with error cases","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T22:54:13.690Z","updated_at":"2026-02-05T22:54:13.690Z"}]}
105
- {"id":"i-2pl3","uuid":"fa462cb2-ae71-4668-9cd5-199e8d8aea1a","title":"Extend SubscriptionFilter for mail events","content":"## Acceptance Criteria\n- [ ] Add optional mail field to SubscriptionFilter type\n- [ ] Mail filter properties: conversationId, threadId, participantId, contentType\n- [ ] Update SubscriptionManager to handle mail filters\n- [ ] matchesFilter() function for mail events\n- [ ] Filter events by mail.conversationId\n- [ ] Filter events by mail.threadId\n- [ ] Filter events by mail.participantId\n- [ ] Filter events by mail-specific event types\n- [ ] Integration with existing event filtering logic\n- [ ] Tests for mail event filtering\n\n## Context\nImplements [[s-1bob]] event subscription filtering. Allows subscribers to listen to mail events for specific conversations, threads, or participants.\n\n## Technical Notes\n- Mail filter is optional in SubscriptionFilter\n- Combine with existing eventTypes filter (AND logic)\n- Check event.data for mail-specific properties\n- Mail events: mail.created, mail.closed, mail.participant.joined/left, mail.turn.added, mail.turn.updated, mail.thread.created, mail.summary.generated\n- Follows existing subscription filter pattern","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:17:15","updated_at":"2026-02-05 23:04:12","closed_at":"2026-02-05 23:04:12","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-2pl3","from_type":"issue","to":"i-1ghu","to_type":"issue","type":"blocks"},{"from":"i-2pl3","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"}],"tags":["events","mail","subscriptions"],"feedback":[{"id":"cac28912-fc4c-4ee0-8f16-e7ea7cf287b3","from_id":"i-2pl3","to_id":"s-1bob","feedback_type":"comment","content":"Implemented mail subscription filter for mail events.\n\n**Changes:**\n- Added `MailSubscriptionFilter` interface to `server/types.ts` with fields: `conversationId`, `threadId`, `participantId`, `contentType`\n- Added `mail?: MailSubscriptionFilter` field to server `SubscriptionFilter`\n- Added `matchesMailFilter()` method to `SubscriptionManagerImpl` that:\n - Only matches `mail.*` events\n - Extracts `conversationId` from `event.data.conversationId`\n - Extracts `threadId` from `turn.threadId` or `thread.id`\n - Extracts `participantId` from `participant.id`, `data.participantId`, `data.createdBy`, `data.closedBy`, or `turn.participant`\n - Extracts `contentType` from `turn.contentType`\n - All criteria use AND logic (all specified must match)\n- Integrates with existing filter via `matchesFilter()` criteria collection\n\n**Tests:** 18 new tests in `server-subscriptions.test.ts` covering all filter properties, event types, AND logic, combination with eventTypes, match modes, edge cases.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T23:04:08.751Z","updated_at":"2026-02-05T23:04:08.751Z"}]}
106
- {"id":"i-4vhm","uuid":"1b2e80fc-6f65-44e2-bd11-1229f66e00d2","title":"Update connect handshake for mail capability negotiation","content":"## Acceptance Criteria\n- [ ] Add mail field to ParticipantCapabilities type\n- [ ] Mail capabilities: canCreate, canJoin, canInvite, canViewHistory, canCreateThreads\n- [ ] Update ConnectRequestParams to accept mail capabilities\n- [ ] Update ConnectResponseResult to return mail capabilities\n- [ ] Server checks if mail is enabled before granting capabilities\n- [ ] Client without mail capability can still connect (mail omitted from response)\n- [ ] map/connect handler includes mail in capabilities response\n- [ ] Role-based capability defaults for mail\n- [ ] Update capability checking for mail/* methods\n- [ ] Integration tests for capability negotiation\n\n## Context\nImplements [[s-1bob]] capability negotiation. Mail is capability-gated - servers/clients advertise support during connect. Missing capability means mail methods return method-not-found.\n\n## Technical Notes\n- Mail capabilities nest under ParticipantCapabilities.mail\n- Server config determines if mail is enabled\n- Individual capabilities (canCreate, etc.) can be role-based\n- Missing mail in response = server doesn't support mail\n- Client sending mail meta without capability should get ignored\n- Add to METHOD_REGISTRY capability requirements","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:17:23","updated_at":"2026-02-05 23:04:12","closed_at":"2026-02-05 23:04:12","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-4vhm","from_type":"issue","to":"i-1ghu","to_type":"issue","type":"blocks"},{"from":"i-4vhm","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"}],"tags":["capabilities","handshake","mail"],"feedback":[{"id":"ffae9da8-4237-4637-8a7c-b52d5748861c","from_id":"i-4vhm","to_id":"s-1bob","feedback_type":"comment","content":"Implemented mail capability negotiation in the connect handshake.\n\n**Changes:**\n- Added `MailCapabilityConfig` interface to `router/handlers.ts` with fields: `enabled`, `canCreate`, `canJoin`, `canInvite`, `canViewHistory`, `canCreateThreads`\n- Added `mailCapabilities` option to `ConnectionHandlerOptions`\n- `map/connect` handler now includes `capabilities.mail` in the response when `mailCapabilities.enabled` is true\n- All sub-capabilities default to `true` when not explicitly set\n- When mail is not configured or disabled, mail field is omitted from capabilities\n\n**Tests:** 6 new tests in `server-handlers.test.ts` covering: no config, disabled, enabled with defaults, custom overrides, alongside existing fields.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T23:04:02.648Z","updated_at":"2026-02-05T23:04:02.648Z"}]}
107
- {"id":"i-1ghu","uuid":"1d8f9f88-22ef-431f-bb11-a2be1fc9a90f","title":"Add mail support to MAPServer and DefaultMAPRouter","content":"## Acceptance Criteria\n- [ ] MAPServerOptions includes optional mail config\n- [ ] Mail config: enabled, stores, capabilities\n- [ ] Create mail managers in MAPServer constructor\n- [ ] Register mail handlers in combineHandlers()\n- [ ] BaseMAPRouter includes mail methods\n- [ ] routerToHandlers() includes mail handlers\n- [ ] Mail building blocks initialized with EventBus\n- [ ] Storage interfaces passed via config\n- [ ] Documentation for enabling mail feature\n- [ ] Integration test with full mail functionality\n\n## Context\nImplements [[s-1bob]] server integration. Makes mail a first-class feature in the server SDK. Follows same pattern as agents, scopes, etc.\n\n## Technical Notes\n- Mail managers: ConversationManager, TurnManager, ThreadManager\n- All share same EventBus instance\n- Stores injectable via config\n- Mail handlers added to handler registry\n- Capability checking via permissionMiddleware\n- Optional feature - defaults to disabled if config omitted","status":"closed","priority":3,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:17:29","updated_at":"2026-02-05 23:31:03","closed_at":"2026-02-05 23:31:03","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1ghu","from_type":"issue","to":"i-2kei","to_type":"issue","type":"blocks"},{"from":"i-1ghu","from_type":"issue","to":"i-2may","to_type":"issue","type":"blocks"},{"from":"i-1ghu","from_type":"issue","to":"i-3lf4","to_type":"issue","type":"blocks"},{"from":"i-1ghu","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"}],"tags":["integration","mail","server"],"feedback":[{"id":"8f2b9f83-059c-4157-823d-b708c16db91f","from_id":"i-1ghu","to_id":"s-1bob","feedback_type":"comment","content":"Implemented mail support in MAPServer as a first-class opt-in feature.\n\n**Changes:**\n\n1. **`server/server.ts`** - MAPServer integration:\n - Added `mail` config section to `MAPServerOptions` with `enabled`, `capabilities`, `stores`, and manager overrides\n - Added `conversations`, `turns`, `threads` readonly fields (null when disabled)\n - Constructor creates `ConversationManagerImpl`, `TurnManagerImpl`, `ThreadManagerImpl` with shared `EventBus` and `TurnStore` when `mail.enabled` is true\n - `combineHandlers()` now includes `createMailHandlers()` when mail is enabled\n - `createConnectionHandlers()` passes `mailCapabilities` for connect handshake\n - `createMessageHandlers()` passes `turns` for send interception\n\n2. **`server/router/index.ts`** - Exports `MailCapabilityConfig` type from barrel\n\n3. **`__tests__/server-mail-server-integration.test.ts`** - 18 integration tests:\n - Mail disabled: null managers, no handlers, no capabilities\n - Mail enabled: non-null managers, all 13 handlers registered, capabilities in connect response\n - Full lifecycle: create conversation, add turn, list turns, create thread, close conversation, get with includes, list conversations\n - Send interception: meta.mail records intercepted turn, absence does not\n - Custom capabilities: overrides flow through to connect response\n - EventBus integration: mail events emitted through shared eventBus\n\n**Design decisions:**\n- Mail disabled by default (must set `enabled: true`)\n- Shared TurnStore between TurnManager and ThreadManager\n- No BaseMAPRouter/MAPRouterInterface changes (deferred - functional handlers cover all 13 methods)","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T23:31:00.043Z","updated_at":"2026-02-05T23:31:00.043Z"}]}
108
- {"id":"i-2may","uuid":"c5b5ab0b-082f-48fc-8c73-b1ab9f965a03","title":"Create mail client convenience methods","content":"## Acceptance Criteria\n- [ ] ClientConnection.createConversation() method\n- [ ] ClientConnection.listConversations() method\n- [ ] ClientConnection.joinConversation() method\n- [ ] ClientConnection.leaveConversation() method\n- [ ] ClientConnection.recordTurn() method\n- [ ] ClientConnection.listTurns() method\n- [ ] ClientConnection.createThread() method\n- [ ] Type-safe parameter objects\n- [ ] Error handling with mail error codes\n- [ ] JSDoc documentation\n- [ ] Integration tests using TestServer\n\n## Context\nImplements [[s-1bob]] client API. Provides developer-friendly methods for mail operations. Follows pattern of existing client convenience methods.\n\n## Technical Notes\n- Methods are async wrappers around request()\n- Type parameters for payload types\n- Return typed responses\n- Handle mail capability check (throw if not available)\n- Follow naming convention of existing methods\n","status":"closed","priority":3,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:17:34","updated_at":"2026-02-05 23:53:09","closed_at":"2026-02-05 23:53:09","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-2may","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"},{"from":"i-2may","from_type":"issue","to":"s-1bob","to_type":"spec","type":"references"}],"tags":["api","client","mail"],"feedback":[{"id":"97915724-cfc2-428f-b6c8-8a081356557d","from_id":"i-2may","to_id":"s-1bob","feedback_type":"comment","content":"Implemented all 13 mail convenience methods on ClientConnection plus sendWithMail():\n\nSame method set as AgentConnection: createConversation(), getConversation(), listConversations(), closeConversation(), joinConversation(), leaveConversation(), inviteToConversation(), recordTurn(), listTurns(), createThread(), listThreads(), getConversationSummary(), replayConversation(), sendWithMail().\n\nFollows existing ClientConnection patterns with MAIL_METHODS constants and full type safety.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T23:52:54.339Z","updated_at":"2026-02-05T23:52:54.339Z"}]}
109
- {"id":"i-3lf4","uuid":"08e543d8-7472-4b5f-9866-322afc7c3c54","title":"Create mail agent convenience methods","content":"## Acceptance Criteria\n- [ ] AgentConnection.sendWithMail() method (map/send + mail meta)\n- [ ] AgentConnection.recordTurn() method (mail/turn)\n- [ ] AgentConnection.joinConversation() method\n- [ ] AgentConnection.listConversations() method\n- [ ] Type-safe parameter objects\n- [ ] Automatic sessionId injection\n- [ ] Error handling\n- [ ] JSDoc documentation\n- [ ] Integration tests\n\n## Context\nImplements [[s-1bob]] agent API. Agents are primary mail users - they send messages within conversations and record explicit turns.\n\n## Technical Notes\n- sendWithMail() wraps map/send with mail meta\n- Validates mail capability before sending\n- Conversation membership checks\n- Follow AgentConnection API patterns\n","status":"closed","priority":3,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:17:38","updated_at":"2026-02-05 23:53:08","closed_at":"2026-02-05 23:53:08","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-3lf4","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"},{"from":"i-3lf4","from_type":"issue","to":"s-1bob","to_type":"spec","type":"references"}],"tags":["agent","api","mail"],"feedback":[{"id":"b04c1968-6ece-42d6-b360-68725c0f9eb6","from_id":"i-3lf4","to_id":"s-1bob","feedback_type":"comment","content":"Implemented all 13 mail convenience methods on AgentConnection plus sendWithMail():\n\n- createConversation(), getConversation(), listConversations(), closeConversation()\n- joinConversation(), leaveConversation(), inviteToConversation()\n- recordTurn(), listTurns()\n- createThread(), listThreads()\n- getConversationSummary(), replayConversation()\n- sendWithMail() - wraps send() with meta.mail for turn interception\n\nAll methods follow the existing AgentConnection pattern: async wrappers around `this.#connection.sendRequest<Params, Result>(MAIL_METHODS.XXX, params)` with full JSDoc documentation and type-safe `Omit<...RequestParams, '_meta'>` parameter types.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T23:52:52.049Z","updated_at":"2026-02-05T23:52:52.049Z"}]}
110
- {"id":"i-2kei","uuid":"7305b0da-a829-4e32-af66-c684a3d236ec","title":"Write comprehensive mail protocol tests","content":"## Acceptance Criteria\n- [ ] Unit tests for ConversationManager\n- [ ] Unit tests for TurnManager\n- [ ] Unit tests for ThreadManager\n- [ ] Integration tests for all 13 mail/* methods\n- [ ] Test mail meta interception in map/send\n- [ ] Test capability negotiation\n- [ ] Test mail event filtering\n- [ ] Test permission checks (participant membership)\n- [ ] Test error cases (conversation not found, not a participant, etc.)\n- [ ] Test turn visibility filtering\n- [ ] Test conversation hierarchy (parent/child)\n- [ ] Test thread nesting\n- [ ] Test pagination (turns/list, conversations/list)\n- [ ] Test concurrent operations\n- [ ] 90%+ code coverage for mail modules\n\n## Context\nImplements [[s-1bob]] test coverage. Ensures mail protocol works correctly and handles edge cases. Critical for a persistence layer.\n\n## Technical Notes\n- Use TestServer for integration tests\n- Mock stores for unit tests\n- Test turn ordering and ULID generation\n- Test causal dependencies in events\n- Validate error codes match spec\n- Test visibility rules thoroughly\n- File: `ts-sdk/src/__tests__/mail-protocol.test.ts`\n","status":"closed","priority":3,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:17:44","updated_at":"2026-02-05 23:53:09","closed_at":"2026-02-05 23:53:09","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-2kei","from_type":"issue","to":"i-8nvo","to_type":"issue","type":"blocks"},{"from":"i-2kei","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"},{"from":"i-2kei","from_type":"issue","to":"s-1bob","to_type":"spec","type":"references"}],"tags":["mail","quality","testing"],"feedback":[{"id":"07318e28-82f8-47b7-bce7-4f56f598a80c","from_id":"i-2kei","to_id":"s-1bob","feedback_type":"comment","content":"Created comprehensive mail protocol test suite at `ts-sdk/src/__tests__/mail-protocol.test.ts` with 74 tests covering:\n\n- **Turn visibility** (6 tests): all, private, participants, role visibility types; mixed visibility in same conversation\n- **Conversation hierarchy** (7 tests): parent/child creation, 3-level deep hierarchies, parentConversationId filtering, parentTurnId anchoring, independent close\n- **Thread nesting** (8 tests): 3-level deep thread hierarchies, listing children by parentThreadId, turnCount/participantCount tracking, error cases\n- **Pagination edge cases** (11 tests): limit=1, afterTurnId/beforeTurnId cursors, desc ordering, limit > total, combined filters with pagination, conversation count\n- **Concurrent operations** (4 tests): concurrent turn recording, concurrent thread creation, rapid join/leave cycles\n- **Error state transitions** (13 tests): close-twice, join-closed, join-twice, leave-twice, invalid content types, x- validation\n- **Participant permissions** (10 tests): default permissions, custom join/invite permissions, initialParticipants, active/inactive filtering\n- **Event emissions** (7 tests): all 7 mail event types verified\n- **Turn status lifecycle** (5 tests): pending→streaming→complete, failed status, intercepted vs explicit source\n- **Cross-manager integration** (4 tests): full lifecycle, multiple threads, inReplyTo, metadata\n\nTotal test count across all mail test files: 42 (stores) + 67 (managers) + 60 (handlers) + 19 (server integration) + 74 (protocol) = 262 tests.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-05T23:53:05.316Z","updated_at":"2026-02-05T23:53:05.316Z"}]}
111
- {"id":"i-8nvo","uuid":"4e541108-fb29-4e6b-898b-6e5a9349a93e","title":"Document Mail Protocol SDK usage and examples","content":"## Acceptance Criteria\n- [ ] Mail protocol overview in SDK docs\n- [ ] Server setup guide (enabling mail)\n- [ ] Client usage examples\n- [ ] Agent usage examples\n- [ ] Common patterns (user sessions, agent trajectories)\n- [ ] Storage customization guide\n- [ ] Event subscription examples\n- [ ] API reference for all mail methods\n- [ ] Migration guide (if upgrading from pre-mail SDK)\n- [ ] Troubleshooting section\n\n## Context\nImplements [[s-1bob]] documentation. Developers need clear guidance on using the mail protocol effectively.\n\n## Technical Notes\n- Add to `ts-sdk/docs/mail-protocol.md`\n- Include TypeScript code examples\n- Document capability negotiation clearly\n- Explain map/send + mail vs mail/turn distinction\n- Show trajectory tracking pattern\n- Link to protocol spec for details\n- Update main README with mail feature\n","status":"closed","priority":3,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-05 20:17:49","updated_at":"2026-02-06 00:06:52","closed_at":"2026-02-06 00:06:52","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-8nvo","from_type":"issue","to":"s-1bob","to_type":"spec","type":"implements"},{"from":"i-8nvo","from_type":"issue","to":"s-1bob","to_type":"spec","type":"references"}],"tags":["documentation","examples","mail"],"feedback":[{"id":"d65e85e5-17f1-4255-abd9-f5a3fbc51b2b","from_id":"i-8nvo","to_id":"s-1bob","feedback_type":"comment","content":"Created comprehensive mail protocol documentation at `ts-sdk/docs/mail-protocol.md` covering all acceptance criteria:\n\n- **Overview**: Transport vs persistence layers, three operations (map/send, map/send+mail, mail/turn)\n- **Server setup**: Enabling mail, capability overrides, custom storage, custom managers, accessing managers\n- **Agent usage**: Creating conversations, recording turns, sendWithMail, joining/leaving, inviting, querying, threading, summary/replay\n- **Client usage**: Same API surface via ClientConnection\n- **Content types**: Well-known types (text, data, event, reference) and custom x- types\n- **Common patterns**: User sessions, agent trajectory tracking, multi-agent collaboration\n- **Event subscriptions**: All 8 mail events, mail subscription filters with AND logic\n- **map/send vs mail/turn**: Decision table for when to use each\n- **API reference**: All 14 convenience methods mapped to protocol methods\n- **Error codes**: All 11 mail error codes (10000-10010)\n- **Troubleshooting**: Method not found, turns not recorded, capabilities missing, content type rejection, silent failures\n\nFollows existing docs style (server-quickstart.md, agent-integration.md) with TypeScript code examples throughout.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-06T00:06:52.506Z","updated_at":"2026-02-06T00:06:52.506Z"}]}
112
- {"id":"i-64qb","uuid":"081a5424-b433-48f5-8bad-c5b71a9419bd","title":"Implement AuthProvider interface & capability intersection","content":"Phase 1 of s-6kja implementation.\n\n**New types** in `ts-sdk/src/server/auth/types.ts`:\n- `AuthProvider extends Authenticator` with `providerId`, `mapCapabilities()`, `delegateForSpawn()`, `handleFederatedToken()`, `prepareFederatedToken()`\n- `CapabilityMapping`, `SpawnDelegationRequest`, `DelegatedCredentials`, `FederationContext`, `FederationTrustConfig`, `FederationResult`\n\n**Modify `AuthResult`** in `ts-sdk/src/types/index.ts`:\n- Add `providerData?: unknown`\n\n**Modify `ServerSession`** in `ts-sdk/src/server/types.ts`:\n- Add `providers?: Record<string, { principal, providerData }>`\n\n**New file** `ts-sdk/src/server/auth/capabilities.ts`:\n- `intersectCapabilities(base, overlay)` — most-restrictive AND merge\n- `intersectAgentPermissions(base, overlay)` — ordered restrictiveness merge\n\n**Modify `AuthManagerImpl`** in `ts-sdk/src/server/auth/manager.ts`:\n- Add `providers?: AuthProvider[]` to options\n- Build provider map, auto-detect providers\n- Add `getProvider()`, `getCapabilityMapping()`, `delegateForSpawn()`\n\n**Update exports** in `ts-sdk/src/server/auth/index.ts`","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-06 03:51:46","updated_at":"2026-02-06 03:54:24","closed_at":"2026-02-06 03:54:24","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-64qb","from_type":"issue","to":"s-6kja","to_type":"spec","type":"implements"}],"tags":["agent-iam","auth","phase-1"]}
113
- {"id":"i-4ys8","uuid":"72fb6651-e66b-4fc6-bf5f-45c9fbb76b80","title":"Implement AgentIAMProvider and capability mapper","content":"Phase 2 of s-6kja implementation. Depends on Phase 1 (AuthProvider interface).\n\n**New file** `ts-sdk/src/server/auth/providers/agent-iam-mapper.ts`:\n- `AgentIAMCapabilityMapper` — maps agent-iam tokens to MAP ParticipantCapabilities\n- Priority: agentCapabilities field > scope-based inference\n\n**New file** `ts-sdk/src/server/auth/providers/agent-iam.ts`:\n- `AgentIAMProvider implements AuthProvider`\n- methods: `['x-agent-iam']`, providerId: `'agent-iam'`\n- authenticate: deserialize → verify → validate identity → build principal\n- mapCapabilities: delegate to mapper\n- delegateForSpawn: tokenService.delegate() with attenuation\n- Federation: stubbed for Phase 4\n\n**New file** `ts-sdk/src/server/auth/providers/index.ts`\n\n**Dependency**: Add `agent-iam` as optional peer dep in package.json","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-06 03:51:50","updated_at":"2026-02-06 03:58:44","closed_at":"2026-02-06 03:58:44","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-4ys8","from_type":"issue","to":"i-64qb","to_type":"issue","type":"depends-on"},{"from":"i-4ys8","from_type":"issue","to":"s-6kja","to_type":"spec","type":"implements"}],"tags":["agent-iam","auth","phase-2"],"feedback":[{"id":"bd454566-1e8e-4a0e-8545-74f8d0a03194","from_id":"i-4ys8","to_id":"s-6kja","feedback_type":"comment","content":"Phase 2 complete. Created:\n- `providers/agent-iam.ts`: `AgentIAMProvider` implementing `AuthProvider` with `TokenServiceLike` interface for DI (no hard dep on agent-iam package)\n- `providers/agent-iam-mapper.ts`: `AgentIAMCapabilityMapper` mapping tokens to MAP capabilities\n- `providers/index.ts`: Re-exports\n- Updated `auth/index.ts` with provider exports\n\nKey design decision: Used `TokenServiceLike` interface instead of importing agent-iam directly, allowing constructor injection. Fixed `AgentAcceptanceRule` — 'none' isn't a valid value; used `{ include: [] }` instead.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-06T03:58:44.569Z","updated_at":"2026-02-06T03:58:44.569Z"}]}
114
- {"id":"i-76xe","uuid":"50d0f56d-0de9-4992-a824-534749a04c38","title":"Integrate auth providers with connect and spawn handlers","content":"Phase 3 of s-6kja implementation. Depends on Phase 1 + 2.\n\n**Modify connect handler** in `ts-sdk/src/server/router/handlers.ts`:\n- After auth success, store providerData on session.providers\n- Get capability mapping and intersect with built capabilities\n- Also update map/authenticate and map/auth/refresh handlers\n\n**Add spawn handler** to `ts-sdk/src/server/agents/handlers.ts`:\n- Add `authManager?` to `AgentHandlerOptions`\n- Implement `map/agents/spawn`: validate parent, register child, delegate credentials\n- Return delegated credentials in response for child process setup","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-06 03:51:53","updated_at":"2026-02-06 04:00:45","closed_at":"2026-02-06 04:00:45","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-76xe","from_type":"issue","to":"i-4ys8","to_type":"issue","type":"depends-on"},{"from":"i-76xe","from_type":"issue","to":"s-6kja","to_type":"spec","type":"implements"}],"tags":["agent-iam","auth","phase-3"],"feedback":[{"id":"46a0e434-e271-4896-b55b-46d190c3ce71","from_id":"i-76xe","to_id":"s-6kja","feedback_type":"comment","content":"Phase 3 complete. Handler integration:\n\n**Connect handler** (`router/handlers.ts`):\n- Added `storeProviderData()` helper — stores provider data on `session.providers[providerId]` after successful auth\n- Connect handler: stores provider data and includes `providerCapabilities` + `defaultAgentPermissions` in capabilities response\n- Authenticate handler: stores provider data on session\n- Auth refresh handler: updates provider data on session\n\n**Spawn handler** (`agents/handlers.ts`):\n- Added `authManager?` to `AgentHandlerOptions`\n- Added `SpawnParams` interface\n- Implemented `map/agents/spawn`: validates parent, registers child, delegates credentials via `authManager.delegateForSpawn()`, returns agent + optional delegatedCredentials","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-06T04:00:45.575Z","updated_at":"2026-02-06T04:00:45.575Z"}]}
115
- {"id":"i-1dnu","uuid":"8b5ea2e3-f136-42d7-b409-e49e4aa16bf6","title":"Implement AgentIAM federation gateway","content":"Phase 4 of s-6kja implementation. Lower priority.\n\n**New file** `ts-sdk/src/server/auth/providers/agent-iam-federation.ts`:\n- `AgentIAMFederationGateway` class\n- Trusted peer config with per-peer signing secrets and scope mapping\n- handleIncoming: verify with peer key → check federation metadata → translate scopes → mint short-TTL local token\n- prepareOutgoing: check federation policy → serialize with local key\n- Wire into AgentIAMProvider to replace federation stubs","status":"closed","priority":2,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-06 03:51:55","updated_at":"2026-02-06 05:57:18","closed_at":"2026-02-06 05:57:18","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1dnu","from_type":"issue","to":"i-76xe","to_type":"issue","type":"depends-on"},{"from":"i-1dnu","from_type":"issue","to":"s-6kja","to_type":"spec","type":"implements"}],"tags":["agent-iam","auth","federation","phase-4"],"feedback":[{"id":"512e8613-f61c-41a9-839a-706094ec8930","from_id":"i-1dnu","to_id":"s-6kja","feedback_type":"comment","content":"Implemented `AgentIAMFederationGateway` as specified in Phase 4.\n\n**New file**: `ts-sdk/src/server/auth/providers/agent-iam-federation.ts` (~327 lines)\n- `handleFederatedToken()`: 11-step incoming verification (peer lookup → deserialize → verify → federation checks → scope translation → principal construction)\n- `prepareFederatedToken()`: 9-step outgoing preparation (policy checks → scope translation → delegate with short TTL → federation metadata → serialize)\n- Per-peer `TokenServiceLike` map for cross-system signing key management\n- Prefix-based longest-match scope translation\n- Fail-closed defaults — missing federation fields always deny\n\n**Modified files**:\n- `agent-iam.ts`: Added `federationGateway?` option, replaced stubs with delegation (falls back to \"not configured\")\n- `providers/index.ts` + `auth/index.ts`: Export new class and types\n\n**Tests**: 45 new tests in `agent-iam-federation.test.ts` covering:\n- handleFederatedToken: 9 happy-path + 11 rejection cases\n- prepareFederatedToken: 8 happy-path + 7 rejection cases\n- AgentIAMProvider integration: 4 delegation tests\n- Scope translation: 5 tests (passthrough, prefix match, longest match, exact match, non-matching passthrough)\n\nFull suite: 1994 tests, 0 regressions.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-06T05:57:18.125Z","updated_at":"2026-02-06T05:57:18.125Z"}]}
116
- {"id":"i-5yda","uuid":"7e557ec0-8f0f-43da-8c62-efae04262e8a","title":"Add tests for auth providers and capability intersection","content":"Phase 5 of s-6kja implementation.\n\n**New test files**:\n- `ts-sdk/src/__tests__/auth-capabilities.test.ts` — intersection logic (and() combos, intersectCapabilities, intersectAgentPermissions)\n- `ts-sdk/src/__tests__/auth-provider.test.ts` — AgentIAMProvider unit tests (authenticate, mapCapabilities, delegateForSpawn)\n- `ts-sdk/src/__tests__/auth-provider-integration.test.ts` — E2E (connect with x-agent-iam, spawn delegation, multi-provider)\n\nAll tests use vitest patterns matching existing test files.","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-06 03:51:58","updated_at":"2026-02-06 04:02:36","closed_at":"2026-02-06 04:02:36","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-5yda","from_type":"issue","to":"i-76xe","to_type":"issue","type":"depends-on"},{"from":"i-5yda","from_type":"issue","to":"s-6kja","to_type":"spec","type":"implements"}],"tags":["agent-iam","auth","phase-5","testing"],"feedback":[{"id":"a072da5d-9425-42ca-94c2-faeb2c81f3ce","from_id":"i-5yda","to_id":"s-6kja","feedback_type":"comment","content":"Phase 5 complete. 47 tests passing across 2 test files:\n\n- `auth-capabilities.test.ts` (15 tests): `and()` boolean logic, `intersectCapabilities()` with full/partial/empty overlays, server-config passthrough, `intersectAgentPermissions()` with rule ordering and include lists\n- `auth-provider.test.ts` (32 tests): `AgentIAMCapabilityMapper` (agentCapabilities mapping, wildcard inference, individual scope inference, visibility mapping), `AgentIAMProvider` (authenticate valid/invalid/expired/wrong-system/wrong-tenant, identity claims, mapCapabilities, delegateForSpawn, federation stubs), `AuthManagerImpl` provider integration (lookup by id/method, capability mapping, spawn delegation)","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-06T04:02:35.815Z","updated_at":"2026-02-06T04:02:35.815Z"}]}
117
- {"id":"i-4e95","uuid":"5f23af36-8864-4969-a6d1-514aace307b7","title":"Create credential brokering types and BrokerLike interface","content":"Phase 1 of s-2w2c. Create `ts-sdk/src/server/credentials/types.ts` with:\n- `CredentialCapabilityConfig` (follows MailCapabilityConfig pattern)\n- `BrokerLike` DI interface matching agent-iam Broker API surface (checkPermission, getCredential, getStatus)\n- `CredentialResult` type mirroring agent-iam's type\n\nReuses `AgentIAMToken` from `../auth/providers/agent-iam`.","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-06 04:53:46","updated_at":"2026-02-06 04:55:08","closed_at":"2026-02-06 04:55:08","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-4e95","from_type":"issue","to":"s-2w2c","to_type":"spec","type":"implements"}],"tags":["credentials","phase-1","types"],"feedback":[{"id":"4cb6322e-f3f7-4cf5-ae5d-cc57275d5659","from_id":"i-4e95","to_id":"s-2w2c","feedback_type":"comment","content":"Phases 1-4 complete. Implementation:\n\n**New files:**\n- `credentials/types.ts`: `CredentialCapabilityConfig`, `BrokerLike` (DI interface), `CredentialResult`\n- `credentials/handlers.ts`: `createCredentialHandlers()` with `cred/get`, `cred/list`, `cred/status`\n- `credentials/index.ts`: Module exports\n\n**Modified files:**\n- `router/handlers.ts`: Added `credentialCapabilities` to connect response (same pattern as mail)\n- `server.ts`: Added `credentials` config to `MAPServerOptions`, wired handlers\n- `server/index.ts`: Export credentials module\n- `package.json`: Added agent-iam ^0.0.2 as optional peer dep\n\n**Key decisions:**\n- Token read from `session.providers['agent-iam'].providerData` (not `authMetadata` from spec)\n- `BrokerStatus.providers` (matches agent-iam, not `configuredProviders` from spec)\n- `BrokerLike` interface for DI (consistent with `TokenServiceLike` pattern)\n\n**Tests:** 19 tests passing. Full suite: 1947 tests, 0 regressions.","agent":"alexngai","anchor":null,"dismissed":false,"created_at":"2026-02-06T04:57:49.570Z","updated_at":"2026-02-06T04:57:49.570Z"}]}
118
- {"id":"i-9ys3","uuid":"4887b31e-d3e8-4ee3-97bd-b77091fceb91","title":"Implement credential handler factory (cred/get, cred/list, cred/status)","content":"Phase 2 of s-2w2c. Create `ts-sdk/src/server/credentials/handlers.ts` and `index.ts`:\n- `createCredentialHandlers(options)` factory returning HandlerRegistry\n- `cred/get`: extract token from session.providers['agent-iam'].providerData → broker.checkPermission → broker.getCredential → emit audit event\n- `cred/list`: return token scopes, constraints, agentId, expiresAt\n- `cred/status`: return broker.getStatus() filtered by allowedProviders\n- `getTokenFromSession()` helper\n- Audit events via EventBus (credential.issued, credential.denied)","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-06 04:53:48","updated_at":"2026-02-06 04:55:09","closed_at":"2026-02-06 04:55:09","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-9ys3","from_type":"issue","to":"i-4e95","to_type":"issue","type":"depends-on"},{"from":"i-9ys3","from_type":"issue","to":"s-2w2c","to_type":"spec","type":"implements"}],"tags":["credentials","handlers","phase-2"]}
119
- {"id":"i-1gbe","uuid":"1f7c2af2-2975-4dfe-87b4-8cb011c28dd2","title":"Integrate credential capabilities into connect response and MAPServer","content":"Phase 3-4 of s-2w2c.\n\n**router/handlers.ts**:\n- Add `credentialCapabilities?: CredentialCapabilityConfig` to ConnectionHandlerOptions\n- Advertise in connect response (same pattern as mail)\n\n**server.ts**:\n- Add `credentials?: { enabled, broker, capabilities, allowedProviders }` to MAPServerOptions\n- Wire createCredentialHandlers() when enabled\n- Pass credentialCapabilities to createConnectionHandlers()\n\n**server/index.ts**:\n- Export credentials module\n\n**package.json**:\n- Add agent-iam ^0.0.2 as optional peer dependency","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-06 04:53:51","updated_at":"2026-02-06 04:56:33","closed_at":"2026-02-06 04:56:33","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-1gbe","from_type":"issue","to":"i-9ys3","to_type":"issue","type":"depends-on"},{"from":"i-1gbe","from_type":"issue","to":"s-2w2c","to_type":"spec","type":"implements"}],"tags":["credentials","integration","phase-3-4"]}
120
- {"id":"i-6uez","uuid":"f2da9401-73a3-4e50-a48f-7b3298c39417","title":"Write credential brokering tests","content":"Phase 6 of s-2w2c. Create `ts-sdk/src/__tests__/server-credentials.test.ts`:\n\n- cred/get: valid token + scope, missing scope denied, no token error, audit events, credential not in events\n- cred/list: returns scopes/constraints/agentId/expiresAt, no token error\n- cred/status: returns providers, filters by allowedProviders\n- Connect response: credentials advertised when enabled, omitted when disabled, defaults","status":"closed","priority":1,"assignee":null,"archived":0,"archived_at":null,"created_at":"2026-02-06 04:53:54","updated_at":"2026-02-06 04:57:49","closed_at":"2026-02-06 04:57:49","parent_id":null,"parent_uuid":null,"relationships":[{"from":"i-6uez","from_type":"issue","to":"i-9ys3","to_type":"issue","type":"depends-on"},{"from":"i-6uez","from_type":"issue","to":"s-2w2c","to_type":"spec","type":"implements"}],"tags":["credentials","phase-6","tests"]}