agentshire 1.0.0

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 (406) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/LICENSE +21 -0
  3. package/README.md +437 -0
  4. package/README.zh-CN.md +441 -0
  5. package/ROADMAP.md +207 -0
  6. package/THIRD_PARTY_NOTICES.md +49 -0
  7. package/VISION.md +101 -0
  8. package/index.ts +386 -0
  9. package/openclaw.plugin.json +27 -0
  10. package/package.json +100 -0
  11. package/src/bridge/AGENTS.md +136 -0
  12. package/src/bridge/ActivityStream.ts +184 -0
  13. package/src/bridge/CitizenManager.ts +280 -0
  14. package/src/bridge/DirectorBridge.ts +1076 -0
  15. package/src/bridge/EventTranslator.ts +142 -0
  16. package/src/bridge/NpcEventQueue.ts +61 -0
  17. package/src/bridge/ReconnectManager.ts +42 -0
  18. package/src/bridge/RouteManager.ts +270 -0
  19. package/src/bridge/StateTracker.ts +100 -0
  20. package/src/bridge/ToolVfxMapper.ts +94 -0
  21. package/src/bridge/__tests__/ActivityStream.test.ts +156 -0
  22. package/src/bridge/__tests__/CitizenManager.test.ts +174 -0
  23. package/src/bridge/__tests__/EventTranslator.test.ts +292 -0
  24. package/src/bridge/__tests__/NpcEventQueue.test.ts +92 -0
  25. package/src/bridge/__tests__/RouteManager.test.ts +106 -0
  26. package/src/bridge/data/route-config.json +36 -0
  27. package/src/bridge/data/route-config.ts +19 -0
  28. package/src/bridge/implicit-chat.ts +192 -0
  29. package/src/bridge/index.ts +12 -0
  30. package/src/contracts/agent-state.ts +87 -0
  31. package/src/contracts/agui.ts +212 -0
  32. package/src/contracts/chat.ts +67 -0
  33. package/src/contracts/events.ts +170 -0
  34. package/src/contracts/index.ts +71 -0
  35. package/src/contracts/media.ts +77 -0
  36. package/src/contracts/registry.ts +32 -0
  37. package/src/plugin/AGENTS.md +192 -0
  38. package/src/plugin/__tests__/editor-serve-megapack.test.ts +150 -0
  39. package/src/plugin/__tests__/hook-translator.test.ts +197 -0
  40. package/src/plugin/auto-config.ts +131 -0
  41. package/src/plugin/channel.ts +399 -0
  42. package/src/plugin/chat-asset-resolver.ts +75 -0
  43. package/src/plugin/chat-session-watcher.ts +98 -0
  44. package/src/plugin/citizen-agent-manager.ts +178 -0
  45. package/src/plugin/citizen-chat-router.ts +83 -0
  46. package/src/plugin/citizen-workshop-manager.ts +96 -0
  47. package/src/plugin/custom-asset-manager.ts +250 -0
  48. package/src/plugin/editor-serve.ts +1368 -0
  49. package/src/plugin/group-discussion.ts +223 -0
  50. package/src/plugin/hook-translator.ts +202 -0
  51. package/src/plugin/llm-agent-proxy.ts +193 -0
  52. package/src/plugin/outbound-adapter.ts +187 -0
  53. package/src/plugin/paths.ts +33 -0
  54. package/src/plugin/plan-manager.ts +594 -0
  55. package/src/plugin/runtime.ts +9 -0
  56. package/src/plugin/session-history.ts +838 -0
  57. package/src/plugin/session-log-watcher.ts +221 -0
  58. package/src/plugin/soul-prompt-template.ts +290 -0
  59. package/src/plugin/subagent-tracker.ts +205 -0
  60. package/src/plugin/tools.ts +493 -0
  61. package/src/plugin/town-session.ts +40 -0
  62. package/src/plugin/ws-server.ts +680 -0
  63. package/src/town-souls.ts +134 -0
  64. package/town-frontend/dist/assets/CustomAssetStore-oi8aIurt.js +2 -0
  65. package/town-frontend/dist/assets/GLTFLoader-BA5RqSME.js +3804 -0
  66. package/town-frontend/dist/assets/OrbitControls-ZmySp9sQ.js +2 -0
  67. package/town-frontend/dist/assets/SettingsPanel-BO52reJe.js +2 -0
  68. package/town-frontend/dist/assets/SkeletonUtils-BCVmgslc.js +2 -0
  69. package/town-frontend/dist/assets/SkillLearnCard-Dk38iDpy.js +6 -0
  70. package/town-frontend/dist/assets/TopicSetupPanel-DLaLHB_Z.js +2 -0
  71. package/town-frontend/dist/assets/Trap-Bold-CT0JBE39.woff2 +0 -0
  72. package/town-frontend/dist/assets/Trap-SemiBold-R4_-Ld0j.woff2 +0 -0
  73. package/town-frontend/dist/assets/WeatherSystem-Cb3BvHes.js +550 -0
  74. package/town-frontend/dist/assets/avatars/char-female-a.webp +0 -0
  75. package/town-frontend/dist/assets/avatars/char-female-b.webp +0 -0
  76. package/town-frontend/dist/assets/avatars/char-female-c.webp +0 -0
  77. package/town-frontend/dist/assets/avatars/char-female-d.webp +0 -0
  78. package/town-frontend/dist/assets/avatars/char-female-e.webp +0 -0
  79. package/town-frontend/dist/assets/avatars/char-female-f.webp +0 -0
  80. package/town-frontend/dist/assets/avatars/char-male-a.webp +0 -0
  81. package/town-frontend/dist/assets/avatars/char-male-b.webp +0 -0
  82. package/town-frontend/dist/assets/avatars/char-male-c.webp +0 -0
  83. package/town-frontend/dist/assets/avatars/char-male-d.webp +0 -0
  84. package/town-frontend/dist/assets/avatars/char-male-e.webp +0 -0
  85. package/town-frontend/dist/assets/avatars/char-male-f.webp +0 -0
  86. package/town-frontend/dist/assets/avatars/char-pet-beaver.webp +0 -0
  87. package/town-frontend/dist/assets/avatars/char-pet-bee.webp +0 -0
  88. package/town-frontend/dist/assets/avatars/char-pet-bunny.webp +0 -0
  89. package/town-frontend/dist/assets/avatars/char-pet-cat.webp +0 -0
  90. package/town-frontend/dist/assets/avatars/char-pet-caterpillar.webp +0 -0
  91. package/town-frontend/dist/assets/avatars/char-pet-chick.webp +0 -0
  92. package/town-frontend/dist/assets/avatars/char-pet-cow.webp +0 -0
  93. package/town-frontend/dist/assets/avatars/char-pet-crab.webp +0 -0
  94. package/town-frontend/dist/assets/avatars/char-pet-deer.webp +0 -0
  95. package/town-frontend/dist/assets/avatars/char-pet-dog.webp +0 -0
  96. package/town-frontend/dist/assets/avatars/char-pet-elephant.webp +0 -0
  97. package/town-frontend/dist/assets/avatars/char-pet-fish.webp +0 -0
  98. package/town-frontend/dist/assets/avatars/char-pet-fox.webp +0 -0
  99. package/town-frontend/dist/assets/avatars/char-pet-giraffe.webp +0 -0
  100. package/town-frontend/dist/assets/avatars/char-pet-hog.webp +0 -0
  101. package/town-frontend/dist/assets/avatars/char-pet-koala.webp +0 -0
  102. package/town-frontend/dist/assets/avatars/char-pet-lion.webp +0 -0
  103. package/town-frontend/dist/assets/avatars/char-pet-monkey.webp +0 -0
  104. package/town-frontend/dist/assets/avatars/char-pet-panda.webp +0 -0
  105. package/town-frontend/dist/assets/avatars/char-pet-parrot.webp +0 -0
  106. package/town-frontend/dist/assets/avatars/char-pet-penguin.webp +0 -0
  107. package/town-frontend/dist/assets/avatars/char-pet-pig.webp +0 -0
  108. package/town-frontend/dist/assets/avatars/char-pet-polar.webp +0 -0
  109. package/town-frontend/dist/assets/avatars/char-pet-tiger.webp +0 -0
  110. package/town-frontend/dist/assets/character-catalog-DSmLtlNC.js +2 -0
  111. package/town-frontend/dist/assets/citizenEditor-DubGSJOQ.js +296 -0
  112. package/town-frontend/dist/assets/command-parser-BUd15Bmv.js +12 -0
  113. package/town-frontend/dist/assets/editor-B5QO0OtX.js +258 -0
  114. package/town-frontend/dist/assets/editor-Bk8g1NCD.css +1 -0
  115. package/town-frontend/dist/assets/index-BWfrufil.js +2 -0
  116. package/town-frontend/dist/assets/index-faS20RJk.js +6 -0
  117. package/town-frontend/dist/assets/logo-DJI6EtST.png +0 -0
  118. package/town-frontend/dist/assets/logo-title-AdKPZX5E.png +0 -0
  119. package/town-frontend/dist/assets/main-CqsN43aT.js +224 -0
  120. package/town-frontend/dist/assets/main-D7neuy3w.css +1 -0
  121. package/town-frontend/dist/assets/models/buildings/base.bin +0 -0
  122. package/town-frontend/dist/assets/models/buildings/base.gltf +136 -0
  123. package/town-frontend/dist/assets/models/buildings/bench.bin +0 -0
  124. package/town-frontend/dist/assets/models/buildings/bench.gltf +136 -0
  125. package/town-frontend/dist/assets/models/buildings/box_A.bin +0 -0
  126. package/town-frontend/dist/assets/models/buildings/box_A.gltf +136 -0
  127. package/town-frontend/dist/assets/models/buildings/box_B.bin +0 -0
  128. package/town-frontend/dist/assets/models/buildings/box_B.gltf +136 -0
  129. package/town-frontend/dist/assets/models/buildings/building_A.bin +0 -0
  130. package/town-frontend/dist/assets/models/buildings/building_A.gltf +136 -0
  131. package/town-frontend/dist/assets/models/buildings/building_A_withoutBase.bin +0 -0
  132. package/town-frontend/dist/assets/models/buildings/building_A_withoutBase.gltf +136 -0
  133. package/town-frontend/dist/assets/models/buildings/building_B.bin +0 -0
  134. package/town-frontend/dist/assets/models/buildings/building_B.gltf +136 -0
  135. package/town-frontend/dist/assets/models/buildings/building_B_withoutBase.bin +0 -0
  136. package/town-frontend/dist/assets/models/buildings/building_B_withoutBase.gltf +136 -0
  137. package/town-frontend/dist/assets/models/buildings/building_C.bin +0 -0
  138. package/town-frontend/dist/assets/models/buildings/building_C.gltf +136 -0
  139. package/town-frontend/dist/assets/models/buildings/building_C_withoutBase.bin +0 -0
  140. package/town-frontend/dist/assets/models/buildings/building_C_withoutBase.gltf +136 -0
  141. package/town-frontend/dist/assets/models/buildings/building_D.bin +0 -0
  142. package/town-frontend/dist/assets/models/buildings/building_D.gltf +136 -0
  143. package/town-frontend/dist/assets/models/buildings/building_D_withoutBase.bin +0 -0
  144. package/town-frontend/dist/assets/models/buildings/building_D_withoutBase.gltf +136 -0
  145. package/town-frontend/dist/assets/models/buildings/building_E.bin +0 -0
  146. package/town-frontend/dist/assets/models/buildings/building_E.gltf +136 -0
  147. package/town-frontend/dist/assets/models/buildings/building_E_withoutBase.bin +0 -0
  148. package/town-frontend/dist/assets/models/buildings/building_E_withoutBase.gltf +136 -0
  149. package/town-frontend/dist/assets/models/buildings/building_F.bin +0 -0
  150. package/town-frontend/dist/assets/models/buildings/building_F.gltf +136 -0
  151. package/town-frontend/dist/assets/models/buildings/building_F_withoutBase.bin +0 -0
  152. package/town-frontend/dist/assets/models/buildings/building_F_withoutBase.gltf +136 -0
  153. package/town-frontend/dist/assets/models/buildings/building_G.bin +0 -0
  154. package/town-frontend/dist/assets/models/buildings/building_G.gltf +136 -0
  155. package/town-frontend/dist/assets/models/buildings/building_G_withoutBase.bin +0 -0
  156. package/town-frontend/dist/assets/models/buildings/building_G_withoutBase.gltf +136 -0
  157. package/town-frontend/dist/assets/models/buildings/building_H.bin +0 -0
  158. package/town-frontend/dist/assets/models/buildings/building_H.gltf +136 -0
  159. package/town-frontend/dist/assets/models/buildings/building_H_withoutBase.bin +0 -0
  160. package/town-frontend/dist/assets/models/buildings/building_H_withoutBase.gltf +136 -0
  161. package/town-frontend/dist/assets/models/buildings/bush.bin +0 -0
  162. package/town-frontend/dist/assets/models/buildings/bush.gltf +136 -0
  163. package/town-frontend/dist/assets/models/buildings/car_hatchback.bin +0 -0
  164. package/town-frontend/dist/assets/models/buildings/car_hatchback.gltf +442 -0
  165. package/town-frontend/dist/assets/models/buildings/car_police.bin +0 -0
  166. package/town-frontend/dist/assets/models/buildings/car_police.gltf +442 -0
  167. package/town-frontend/dist/assets/models/buildings/car_sedan.bin +0 -0
  168. package/town-frontend/dist/assets/models/buildings/car_sedan.gltf +442 -0
  169. package/town-frontend/dist/assets/models/buildings/car_stationwagon.bin +0 -0
  170. package/town-frontend/dist/assets/models/buildings/car_stationwagon.gltf +442 -0
  171. package/town-frontend/dist/assets/models/buildings/car_taxi.bin +0 -0
  172. package/town-frontend/dist/assets/models/buildings/car_taxi.gltf +442 -0
  173. package/town-frontend/dist/assets/models/buildings/citybits_texture.png +0 -0
  174. package/town-frontend/dist/assets/models/buildings/dumpster.bin +0 -0
  175. package/town-frontend/dist/assets/models/buildings/dumpster.gltf +136 -0
  176. package/town-frontend/dist/assets/models/buildings/firehydrant.bin +0 -0
  177. package/town-frontend/dist/assets/models/buildings/firehydrant.gltf +136 -0
  178. package/town-frontend/dist/assets/models/buildings/road_corner.bin +0 -0
  179. package/town-frontend/dist/assets/models/buildings/road_corner.gltf +136 -0
  180. package/town-frontend/dist/assets/models/buildings/road_corner_curved.bin +0 -0
  181. package/town-frontend/dist/assets/models/buildings/road_corner_curved.gltf +136 -0
  182. package/town-frontend/dist/assets/models/buildings/road_junction.bin +0 -0
  183. package/town-frontend/dist/assets/models/buildings/road_junction.gltf +136 -0
  184. package/town-frontend/dist/assets/models/buildings/road_straight.bin +0 -0
  185. package/town-frontend/dist/assets/models/buildings/road_straight.gltf +136 -0
  186. package/town-frontend/dist/assets/models/buildings/road_straight_crossing.bin +0 -0
  187. package/town-frontend/dist/assets/models/buildings/road_straight_crossing.gltf +136 -0
  188. package/town-frontend/dist/assets/models/buildings/road_tsplit.bin +0 -0
  189. package/town-frontend/dist/assets/models/buildings/road_tsplit.gltf +136 -0
  190. package/town-frontend/dist/assets/models/buildings/streetlight.bin +0 -0
  191. package/town-frontend/dist/assets/models/buildings/streetlight.gltf +136 -0
  192. package/town-frontend/dist/assets/models/buildings/trafficlight_A.bin +0 -0
  193. package/town-frontend/dist/assets/models/buildings/trafficlight_A.gltf +136 -0
  194. package/town-frontend/dist/assets/models/buildings/trafficlight_B.bin +0 -0
  195. package/town-frontend/dist/assets/models/buildings/trafficlight_B.gltf +136 -0
  196. package/town-frontend/dist/assets/models/buildings/trafficlight_C.bin +0 -0
  197. package/town-frontend/dist/assets/models/buildings/trafficlight_C.gltf +136 -0
  198. package/town-frontend/dist/assets/models/buildings/trash_A.bin +0 -0
  199. package/town-frontend/dist/assets/models/buildings/trash_A.gltf +136 -0
  200. package/town-frontend/dist/assets/models/buildings/trash_B.bin +0 -0
  201. package/town-frontend/dist/assets/models/buildings/trash_B.gltf +136 -0
  202. package/town-frontend/dist/assets/models/buildings/watertower.bin +0 -0
  203. package/town-frontend/dist/assets/models/buildings/watertower.gltf +136 -0
  204. package/town-frontend/dist/assets/models/characters/Textures/colormap.png +0 -0
  205. package/town-frontend/dist/assets/models/characters/character-female-a.glb +0 -0
  206. package/town-frontend/dist/assets/models/characters/character-female-b.glb +0 -0
  207. package/town-frontend/dist/assets/models/characters/character-female-c.glb +0 -0
  208. package/town-frontend/dist/assets/models/characters/character-female-d.glb +0 -0
  209. package/town-frontend/dist/assets/models/characters/character-female-e.glb +0 -0
  210. package/town-frontend/dist/assets/models/characters/character-female-f.glb +0 -0
  211. package/town-frontend/dist/assets/models/characters/character-male-a.glb +0 -0
  212. package/town-frontend/dist/assets/models/characters/character-male-b.glb +0 -0
  213. package/town-frontend/dist/assets/models/characters/character-male-c.glb +0 -0
  214. package/town-frontend/dist/assets/models/characters/character-male-d.glb +0 -0
  215. package/town-frontend/dist/assets/models/characters/character-male-e.glb +0 -0
  216. package/town-frontend/dist/assets/models/characters/character-male-f.glb +0 -0
  217. package/town-frontend/dist/assets/models/characters/character-pet-beaver.glb +0 -0
  218. package/town-frontend/dist/assets/models/characters/character-pet-bee.glb +0 -0
  219. package/town-frontend/dist/assets/models/characters/character-pet-bunny.glb +0 -0
  220. package/town-frontend/dist/assets/models/characters/character-pet-cat.glb +0 -0
  221. package/town-frontend/dist/assets/models/characters/character-pet-caterpillar.glb +0 -0
  222. package/town-frontend/dist/assets/models/characters/character-pet-chick.glb +0 -0
  223. package/town-frontend/dist/assets/models/characters/character-pet-cow.glb +0 -0
  224. package/town-frontend/dist/assets/models/characters/character-pet-crab.glb +0 -0
  225. package/town-frontend/dist/assets/models/characters/character-pet-deer.glb +0 -0
  226. package/town-frontend/dist/assets/models/characters/character-pet-dog.glb +0 -0
  227. package/town-frontend/dist/assets/models/characters/character-pet-elephant.glb +0 -0
  228. package/town-frontend/dist/assets/models/characters/character-pet-fish.glb +0 -0
  229. package/town-frontend/dist/assets/models/characters/character-pet-fox.glb +0 -0
  230. package/town-frontend/dist/assets/models/characters/character-pet-giraffe.glb +0 -0
  231. package/town-frontend/dist/assets/models/characters/character-pet-hog.glb +0 -0
  232. package/town-frontend/dist/assets/models/characters/character-pet-koala.glb +0 -0
  233. package/town-frontend/dist/assets/models/characters/character-pet-lion.glb +0 -0
  234. package/town-frontend/dist/assets/models/characters/character-pet-monkey.glb +0 -0
  235. package/town-frontend/dist/assets/models/characters/character-pet-panda.glb +0 -0
  236. package/town-frontend/dist/assets/models/characters/character-pet-parrot.glb +0 -0
  237. package/town-frontend/dist/assets/models/characters/character-pet-penguin.glb +0 -0
  238. package/town-frontend/dist/assets/models/characters/character-pet-pig.glb +0 -0
  239. package/town-frontend/dist/assets/models/characters/character-pet-polar.glb +0 -0
  240. package/town-frontend/dist/assets/models/characters/character-pet-tiger.glb +0 -0
  241. package/town-frontend/dist/assets/models/characters/colormap.png +0 -0
  242. package/town-frontend/dist/assets/models/furniture/armchair.bin +0 -0
  243. package/town-frontend/dist/assets/models/furniture/armchair.gltf +136 -0
  244. package/town-frontend/dist/assets/models/furniture/armchair_pillows.bin +0 -0
  245. package/town-frontend/dist/assets/models/furniture/armchair_pillows.gltf +136 -0
  246. package/town-frontend/dist/assets/models/furniture/bed_double_A.bin +0 -0
  247. package/town-frontend/dist/assets/models/furniture/bed_double_A.gltf +136 -0
  248. package/town-frontend/dist/assets/models/furniture/bed_double_B.bin +0 -0
  249. package/town-frontend/dist/assets/models/furniture/bed_double_B.gltf +136 -0
  250. package/town-frontend/dist/assets/models/furniture/bed_single_A.bin +0 -0
  251. package/town-frontend/dist/assets/models/furniture/bed_single_A.gltf +136 -0
  252. package/town-frontend/dist/assets/models/furniture/bed_single_B.bin +0 -0
  253. package/town-frontend/dist/assets/models/furniture/bed_single_B.gltf +136 -0
  254. package/town-frontend/dist/assets/models/furniture/book_set.bin +0 -0
  255. package/town-frontend/dist/assets/models/furniture/book_set.gltf +136 -0
  256. package/town-frontend/dist/assets/models/furniture/book_single.bin +0 -0
  257. package/town-frontend/dist/assets/models/furniture/book_single.gltf +136 -0
  258. package/town-frontend/dist/assets/models/furniture/cabinet_medium.bin +0 -0
  259. package/town-frontend/dist/assets/models/furniture/cabinet_medium.gltf +136 -0
  260. package/town-frontend/dist/assets/models/furniture/cabinet_medium_decorated.bin +0 -0
  261. package/town-frontend/dist/assets/models/furniture/cabinet_medium_decorated.gltf +136 -0
  262. package/town-frontend/dist/assets/models/furniture/cabinet_small.bin +0 -0
  263. package/town-frontend/dist/assets/models/furniture/cabinet_small.gltf +136 -0
  264. package/town-frontend/dist/assets/models/furniture/cabinet_small_decorated.bin +0 -0
  265. package/town-frontend/dist/assets/models/furniture/cabinet_small_decorated.gltf +136 -0
  266. package/town-frontend/dist/assets/models/furniture/cactus_medium_A.bin +0 -0
  267. package/town-frontend/dist/assets/models/furniture/cactus_medium_A.gltf +136 -0
  268. package/town-frontend/dist/assets/models/furniture/cactus_medium_B.bin +0 -0
  269. package/town-frontend/dist/assets/models/furniture/cactus_medium_B.gltf +136 -0
  270. package/town-frontend/dist/assets/models/furniture/cactus_small_A.bin +0 -0
  271. package/town-frontend/dist/assets/models/furniture/cactus_small_A.gltf +136 -0
  272. package/town-frontend/dist/assets/models/furniture/cactus_small_B.bin +0 -0
  273. package/town-frontend/dist/assets/models/furniture/cactus_small_B.gltf +136 -0
  274. package/town-frontend/dist/assets/models/furniture/chair_A.bin +0 -0
  275. package/town-frontend/dist/assets/models/furniture/chair_A.gltf +136 -0
  276. package/town-frontend/dist/assets/models/furniture/chair_A_wood.bin +0 -0
  277. package/town-frontend/dist/assets/models/furniture/chair_A_wood.gltf +136 -0
  278. package/town-frontend/dist/assets/models/furniture/chair_B.bin +0 -0
  279. package/town-frontend/dist/assets/models/furniture/chair_B.gltf +136 -0
  280. package/town-frontend/dist/assets/models/furniture/chair_B_wood.bin +0 -0
  281. package/town-frontend/dist/assets/models/furniture/chair_B_wood.gltf +136 -0
  282. package/town-frontend/dist/assets/models/furniture/chair_C.bin +0 -0
  283. package/town-frontend/dist/assets/models/furniture/chair_C.gltf +136 -0
  284. package/town-frontend/dist/assets/models/furniture/chair_stool.bin +0 -0
  285. package/town-frontend/dist/assets/models/furniture/chair_stool.gltf +136 -0
  286. package/town-frontend/dist/assets/models/furniture/chair_stool_wood.bin +0 -0
  287. package/town-frontend/dist/assets/models/furniture/chair_stool_wood.gltf +136 -0
  288. package/town-frontend/dist/assets/models/furniture/couch.bin +0 -0
  289. package/town-frontend/dist/assets/models/furniture/couch.gltf +136 -0
  290. package/town-frontend/dist/assets/models/furniture/couch_pillows.bin +0 -0
  291. package/town-frontend/dist/assets/models/furniture/couch_pillows.gltf +136 -0
  292. package/town-frontend/dist/assets/models/furniture/furniturebits_texture.png +0 -0
  293. package/town-frontend/dist/assets/models/furniture/lamp_standing.bin +0 -0
  294. package/town-frontend/dist/assets/models/furniture/lamp_standing.gltf +136 -0
  295. package/town-frontend/dist/assets/models/furniture/lamp_table.bin +0 -0
  296. package/town-frontend/dist/assets/models/furniture/lamp_table.gltf +136 -0
  297. package/town-frontend/dist/assets/models/furniture/pictureframe_large_A.bin +0 -0
  298. package/town-frontend/dist/assets/models/furniture/pictureframe_large_A.gltf +136 -0
  299. package/town-frontend/dist/assets/models/furniture/pictureframe_large_B.bin +0 -0
  300. package/town-frontend/dist/assets/models/furniture/pictureframe_large_B.gltf +136 -0
  301. package/town-frontend/dist/assets/models/furniture/pictureframe_medium.bin +0 -0
  302. package/town-frontend/dist/assets/models/furniture/pictureframe_medium.gltf +136 -0
  303. package/town-frontend/dist/assets/models/furniture/pictureframe_small_A.bin +0 -0
  304. package/town-frontend/dist/assets/models/furniture/pictureframe_small_A.gltf +136 -0
  305. package/town-frontend/dist/assets/models/furniture/pictureframe_small_B.bin +0 -0
  306. package/town-frontend/dist/assets/models/furniture/pictureframe_small_B.gltf +136 -0
  307. package/town-frontend/dist/assets/models/furniture/pictureframe_small_C.bin +0 -0
  308. package/town-frontend/dist/assets/models/furniture/pictureframe_small_C.gltf +136 -0
  309. package/town-frontend/dist/assets/models/furniture/pictureframe_standing_A.bin +0 -0
  310. package/town-frontend/dist/assets/models/furniture/pictureframe_standing_A.gltf +136 -0
  311. package/town-frontend/dist/assets/models/furniture/pictureframe_standing_B.bin +0 -0
  312. package/town-frontend/dist/assets/models/furniture/pictureframe_standing_B.gltf +136 -0
  313. package/town-frontend/dist/assets/models/furniture/pillow_A.bin +0 -0
  314. package/town-frontend/dist/assets/models/furniture/pillow_A.gltf +136 -0
  315. package/town-frontend/dist/assets/models/furniture/pillow_B.bin +0 -0
  316. package/town-frontend/dist/assets/models/furniture/pillow_B.gltf +136 -0
  317. package/town-frontend/dist/assets/models/furniture/rug_oval_A.bin +0 -0
  318. package/town-frontend/dist/assets/models/furniture/rug_oval_A.gltf +136 -0
  319. package/town-frontend/dist/assets/models/furniture/rug_oval_B.bin +0 -0
  320. package/town-frontend/dist/assets/models/furniture/rug_oval_B.gltf +136 -0
  321. package/town-frontend/dist/assets/models/furniture/rug_rectangle_A.bin +0 -0
  322. package/town-frontend/dist/assets/models/furniture/rug_rectangle_A.gltf +136 -0
  323. package/town-frontend/dist/assets/models/furniture/rug_rectangle_B.bin +0 -0
  324. package/town-frontend/dist/assets/models/furniture/rug_rectangle_B.gltf +136 -0
  325. package/town-frontend/dist/assets/models/furniture/rug_rectangle_stripes_A.bin +0 -0
  326. package/town-frontend/dist/assets/models/furniture/rug_rectangle_stripes_A.gltf +136 -0
  327. package/town-frontend/dist/assets/models/furniture/rug_rectangle_stripes_B.bin +0 -0
  328. package/town-frontend/dist/assets/models/furniture/rug_rectangle_stripes_B.gltf +136 -0
  329. package/town-frontend/dist/assets/models/furniture/shelf_A_big.bin +0 -0
  330. package/town-frontend/dist/assets/models/furniture/shelf_A_big.gltf +136 -0
  331. package/town-frontend/dist/assets/models/furniture/shelf_A_small.bin +0 -0
  332. package/town-frontend/dist/assets/models/furniture/shelf_A_small.gltf +136 -0
  333. package/town-frontend/dist/assets/models/furniture/shelf_B_large.bin +0 -0
  334. package/town-frontend/dist/assets/models/furniture/shelf_B_large.gltf +136 -0
  335. package/town-frontend/dist/assets/models/furniture/shelf_B_large_decorated.bin +0 -0
  336. package/town-frontend/dist/assets/models/furniture/shelf_B_large_decorated.gltf +136 -0
  337. package/town-frontend/dist/assets/models/furniture/shelf_B_small.bin +0 -0
  338. package/town-frontend/dist/assets/models/furniture/shelf_B_small.gltf +136 -0
  339. package/town-frontend/dist/assets/models/furniture/shelf_B_small_decorated.bin +0 -0
  340. package/town-frontend/dist/assets/models/furniture/shelf_B_small_decorated.gltf +136 -0
  341. package/town-frontend/dist/assets/models/furniture/table_low.bin +0 -0
  342. package/town-frontend/dist/assets/models/furniture/table_low.gltf +136 -0
  343. package/town-frontend/dist/assets/models/furniture/table_medium.bin +0 -0
  344. package/town-frontend/dist/assets/models/furniture/table_medium.gltf +136 -0
  345. package/town-frontend/dist/assets/models/furniture/table_medium_long.bin +0 -0
  346. package/town-frontend/dist/assets/models/furniture/table_medium_long.gltf +136 -0
  347. package/town-frontend/dist/assets/models/furniture/table_small.bin +0 -0
  348. package/town-frontend/dist/assets/models/furniture/table_small.gltf +136 -0
  349. package/town-frontend/dist/assets/models/props/bench.bin +0 -0
  350. package/town-frontend/dist/assets/models/props/bench.gltf +136 -0
  351. package/town-frontend/dist/assets/models/props/bush.bin +0 -0
  352. package/town-frontend/dist/assets/models/props/bush.gltf +136 -0
  353. package/town-frontend/dist/assets/models/props/capybara.glb +0 -0
  354. package/town-frontend/dist/assets/models/props/car_hatchback.bin +0 -0
  355. package/town-frontend/dist/assets/models/props/car_hatchback.gltf +442 -0
  356. package/town-frontend/dist/assets/models/props/car_sedan.bin +0 -0
  357. package/town-frontend/dist/assets/models/props/car_sedan.gltf +442 -0
  358. package/town-frontend/dist/assets/models/props/car_taxi.bin +0 -0
  359. package/town-frontend/dist/assets/models/props/car_taxi.gltf +442 -0
  360. package/town-frontend/dist/assets/models/props/citybits_texture.png +0 -0
  361. package/town-frontend/dist/assets/models/props/dumpster.bin +0 -0
  362. package/town-frontend/dist/assets/models/props/dumpster.gltf +136 -0
  363. package/town-frontend/dist/assets/models/props/firehydrant.bin +0 -0
  364. package/town-frontend/dist/assets/models/props/firehydrant.gltf +136 -0
  365. package/town-frontend/dist/assets/models/props/streetlight.bin +0 -0
  366. package/town-frontend/dist/assets/models/props/streetlight.gltf +136 -0
  367. package/town-frontend/dist/assets/models/props/trafficlight_A.bin +0 -0
  368. package/town-frontend/dist/assets/models/props/trafficlight_A.gltf +136 -0
  369. package/town-frontend/dist/assets/models/props/trash_A.bin +0 -0
  370. package/town-frontend/dist/assets/models/props/trash_A.gltf +136 -0
  371. package/town-frontend/dist/assets/models/props/watertower.bin +0 -0
  372. package/town-frontend/dist/assets/models/props/watertower.gltf +136 -0
  373. package/town-frontend/dist/assets/models/stage-deco/Flowers_1_D.glb +0 -0
  374. package/town-frontend/dist/assets/models/stage-deco/Flowers_2_B.glb +0 -0
  375. package/town-frontend/dist/assets/models/stage-deco/Grass_A_1.glb +0 -0
  376. package/town-frontend/dist/assets/models/stage-deco/Park_GrassHill_A.glb +0 -0
  377. package/town-frontend/dist/assets/models/stage-deco/Pebles_1_A_2.glb +0 -0
  378. package/town-frontend/dist/assets/music/bgm_day.mp3 +0 -0
  379. package/town-frontend/dist/assets/music/bgm_dusk.mp3 +0 -0
  380. package/town-frontend/dist/assets/music/bgm_night.mp3 +0 -0
  381. package/town-frontend/dist/assets/music/bgm_work.mp3 +0 -0
  382. package/town-frontend/dist/assets/office-whiteboard-idle-CyEwBrq_.webp +0 -0
  383. package/town-frontend/dist/assets/preview-B6hYEQij.js +2 -0
  384. package/town-frontend/dist/assets/town-BKesnERP.js +8888 -0
  385. package/town-frontend/dist/assets/town-BnswKsjF.css +1 -0
  386. package/town-frontend/dist/citizen-editor.html +166 -0
  387. package/town-frontend/dist/editor.html +227 -0
  388. package/town-frontend/dist/index.html +22 -0
  389. package/town-frontend/dist/preview.html +56 -0
  390. package/town-frontend/dist/town.html +165 -0
  391. package/town-frontend/dist/viewer.html +91 -0
  392. package/town-souls/CHEN.md +130 -0
  393. package/town-souls/CHENGZI.md +92 -0
  394. package/town-souls/CITIZEN_tpl.md +16 -0
  395. package/town-souls/DIANDIAN.md +92 -0
  396. package/town-souls/HAITANG.md +94 -0
  397. package/town-souls/QIQI.md +119 -0
  398. package/town-souls/SOUL.md +141 -0
  399. package/town-souls/SOUL_tpl.md +135 -0
  400. package/town-souls/XIAOLIE.md +107 -0
  401. package/town-souls/YAN.md +107 -0
  402. package/town-workspace/IDENTITY.md +5 -0
  403. package/town-workspace/SOUL.md +141 -0
  404. package/town-workspace/project-workflow.md +81 -0
  405. package/town-workspace/town-defaults.json +92 -0
  406. package/town-workspace/town-guide.md +45 -0
@@ -0,0 +1,170 @@
1
+ // @desc AgentEvent union type — the canonical event contract for all consumers
2
+ //
3
+ // 来源: OpenClaw 的 agentLoop() 通过 onEvent 回调发射这些事件
4
+ // 消费者: CLI (TerminalRenderer / App.tsx), Server (ws-handler 透传), Frontend (stream-display)
5
+ //
6
+ // 迁移注意:
7
+ // - src/core/types.ts 的 AgentEvent 已改为从本文件 re-export
8
+ // - 旧的 audio_delta / asr_result 已重命名为 media_delta / media_result
9
+ // - state_snapshot 是新增事件, OpenClaw 核心尚未发射, 预留给状态推送
10
+ // - tool_use.input 从 Record<string, any> 收紧为 Record<string, unknown>
11
+
12
+ import type { AudioContent, VideoContent, ContentKind } from './media.js';
13
+ import type { AgentStateSnapshot } from './agent-state.js';
14
+
15
+ // ── Shared sub-types ──
16
+
17
+ export interface MediaOutputMeta {
18
+ width?: number;
19
+ height?: number;
20
+ durationMs?: number;
21
+ filename?: string;
22
+ sizeBytes?: number;
23
+ alt?: string;
24
+ format?: string;
25
+ [key: string]: unknown;
26
+ }
27
+
28
+ export interface AgentStats {
29
+ tokensIn: number;
30
+ tokensOut: number;
31
+ contextPercent: number;
32
+ toolCalls: number;
33
+ agentSpawns: number;
34
+ skillCalls: number;
35
+ workflowCalls: number;
36
+ durationMs: number;
37
+ }
38
+
39
+ export interface ToolResultMeta {
40
+ pid?: number;
41
+ exitCode?: number;
42
+ durationMs?: number;
43
+ filePath?: string;
44
+ }
45
+
46
+ export interface TokenUsage {
47
+ inputTokens: number;
48
+ outputTokens: number;
49
+ thinkingTokens?: number;
50
+ }
51
+
52
+ export interface ASRSegment {
53
+ text: string;
54
+ start: number;
55
+ end: number;
56
+ }
57
+
58
+ // ── AgentEvent ──
59
+
60
+ export type AgentEvent =
61
+ // System lifecycle
62
+ | { type: 'system'; subtype: 'init'; sessionId: string; model: string; persona?: string }
63
+ | { type: 'system'; subtype: 'done'; result: string; sessionId: string }
64
+ | { type: 'system'; subtype: 'heartbeat'; elapsedSec: number; waiting: boolean }
65
+ | { type: 'system'; subtype: 'compacting'; reason: 'auto' | 'manual' | 'micro' }
66
+ | { type: 'system'; subtype: 'hot_reload_requested'; reason?: string }
67
+
68
+ // Text stream
69
+ | { type: 'text_delta'; delta: string }
70
+ | { type: 'text'; content: string }
71
+
72
+ // Tool calls
73
+ | { type: 'tool_input_delta'; toolUseId: string; name: string; delta: string }
74
+ | { type: 'tool_use'; toolUseId: string; name: string; input: Record<string, unknown> }
75
+ | { type: 'tool_result'; toolUseId: string; name: string; output: string;
76
+ displayOutput?: string; meta?: ToolResultMeta }
77
+
78
+ // Context & turn
79
+ | { type: 'context_update'; tokens: { used: number; limit: number; percent: number };
80
+ usage?: TokenUsage; messagesCount: number; iteration: number; maxIterations: number }
81
+ | { type: 'turn_end'; usage: TokenUsage; toolCalls: number; durationMs: number }
82
+
83
+ // Sub-agents
84
+ | { type: 'sub_agent'; subtype: 'started'; agentId: string; agentType: string;
85
+ parentToolUseId: string; task: string; model: string; displayName?: string }
86
+ | { type: 'sub_agent'; subtype: 'progress'; agentId: string; event: AgentEvent }
87
+ | { type: 'sub_agent'; subtype: 'done'; agentId: string;
88
+ result: string; toolCalls: number; status: 'completed' | 'failed' | 'killed';
89
+ stats?: AgentStats }
90
+
91
+ // State snapshot
92
+ | { type: 'state_snapshot'; state: AgentStateSnapshot }
93
+
94
+ // Multimodal media
95
+ | { type: 'media_delta'; streamId: string; content: AudioContent | VideoContent; final?: boolean }
96
+ | { type: 'media_result'; kind: 'asr'; text: string; confidence?: number; segments?: ASRSegment[] }
97
+ | { type: 'media_status'; stage: 'asr' | 'tts' | 'vlm';
98
+ status: 'processing' | 'done' | 'error'; detail?: string }
99
+
100
+ // Thinking / reasoning stream (parallel to text_delta)
101
+ | { type: 'thinking_delta'; delta: string }
102
+
103
+ // LLM call lifecycle
104
+ | { type: 'llm_call'; subtype: 'start';
105
+ model: string; iteration: number; maxIterations: number;
106
+ messagesCount: number; toolCount: number;
107
+ systemPromptPreview?: string }
108
+ | { type: 'llm_call'; subtype: 'end';
109
+ iteration: number; durationMs: number;
110
+ stopReason: string; retryCount: number;
111
+ usage: TokenUsage }
112
+
113
+ // Agent-to-agent messaging
114
+ | { type: 'bus_message'; from: string; to: string;
115
+ summary: string; contentPreview: string; timestamp: number }
116
+ | { type: 'bus_drain'; agentName: string;
117
+ messageCount: number; summaries: string[] }
118
+
119
+ // Hook execution
120
+ | { type: 'hook'; hookType: 'pre_tool' | 'post_tool';
121
+ toolName: string; toolUseId: string;
122
+ action: 'allow' | 'block' | 'modify';
123
+ reason?: string }
124
+ | { type: 'hook'; hookType: 'stop' | 'pre_compact' | 'session_start' | 'session_end';
125
+ action: 'executed';
126
+ reason?: string }
127
+
128
+ // Hook activity state (for UI rendering)
129
+ | { type: 'hook_activity';
130
+ event: string;
131
+ status: 'running' | 'success' | 'error' | 'blocked';
132
+ icon: string;
133
+ toolName?: string;
134
+ detail?: string;
135
+ durationMs?: number }
136
+
137
+ // Context compaction detail (follows system.compacting)
138
+ | { type: 'compaction_detail';
139
+ reason: 'auto' | 'manual' | 'micro';
140
+ tokensBefore: number; tokensAfter: number;
141
+ messagesRemoved: number;
142
+ transcriptPath?: string }
143
+
144
+ // Debug catch-all
145
+ | { type: 'debug'; category: string; message: string;
146
+ data?: Record<string, unknown> }
147
+
148
+ // Token usage (streaming)
149
+ | { type: 'streaming_usage'; usage: TokenUsage }
150
+
151
+ // Media output (unified: images, audio, video, files)
152
+ | { type: 'media_output';
153
+ kind: ContentKind;
154
+ mimeType: string;
155
+ path: string;
156
+ data?: string;
157
+ role: 'assistant' | 'user';
158
+ source?: string;
159
+ meta?: MediaOutputMeta }
160
+
161
+ // Frontend tool awaiting result (AG-UI frontend-defined tools)
162
+ | { type: 'awaiting_frontend_tool'; toolCallId: string; toolName: string;
163
+ args: Record<string, unknown> }
164
+
165
+ // World control (time & weather)
166
+ | { type: 'world_control'; target: 'time'; action: 'set' | 'pause' | 'resume'; hour?: number }
167
+ | { type: 'world_control'; target: 'weather'; action: 'set' | 'reset'; weather?: string }
168
+
169
+ // Error
170
+ | { type: 'error'; message: string; recoverable: boolean };
@@ -0,0 +1,71 @@
1
+ // @desc Public entry — re-exports all contract types
2
+ //
3
+ // ─── Architecture ───
4
+ //
5
+ // contracts/ <-- 你在这里:所有层的唯一类型真理之源
6
+ // │
7
+ // ├── media.ts 多模态内容块 (text/image/audio/video/file)
8
+ // ├── agent-state.ts Agent 状态机 & 递归快照树
9
+ // ├── events.ts AgentEvent 联合类型 (OpenClaw 核心对外契约)
10
+ // ├── registry.ts 中央注册表 (session ↔ project 关联)
11
+ // └── index.ts 本文件:公共导出入口
12
+ //
13
+ // ─── 消费者 ───
14
+ //
15
+ // CLI 层 → events.ts + agent-state.ts + media.ts
16
+ // OpenClaw 层 → events.ts + agent-state.ts (src/core/types.ts re-export)
17
+ //
18
+ // ─── 已移除 (Phase 0 清理, 2026-03) ───
19
+ //
20
+ // messages.ts — WS 新格式类型,从未被消费,已删除
21
+ // envelope.ts — 传输信封类型,从未被消费,已删除
22
+ //
23
+
24
+ // Media
25
+ export type {
26
+ ContentKind,
27
+ InlineSource,
28
+ UrlSource,
29
+ StreamSource,
30
+ TextContent,
31
+ ImageContent,
32
+ AudioContent,
33
+ VideoStreamSource,
34
+ VideoContent,
35
+ FileContent,
36
+ MediaContent,
37
+ MultimodalBody,
38
+ } from './media.js';
39
+
40
+ // Agent state
41
+ export type {
42
+ AgentPhase,
43
+ AgentActivity,
44
+ AgentResources,
45
+ AgentSnapStats,
46
+ AgentStateSnapshot,
47
+ SessionStatus,
48
+ SessionState,
49
+ } from './agent-state.js';
50
+
51
+ // Chat
52
+ export type {
53
+ ChatMediaType,
54
+ ChatItemKind,
55
+ ChatItem,
56
+ ChatTextItem,
57
+ ChatMediaItem,
58
+ ChatToolItem,
59
+ ChatStatusItem,
60
+ ChatItemHistoryResult,
61
+ } from './chat.js';
62
+
63
+ // Events
64
+ export type {
65
+ AgentStats,
66
+ ToolResultMeta,
67
+ TokenUsage,
68
+ ASRSegment,
69
+ AgentEvent,
70
+ MediaOutputMeta,
71
+ } from './events.js';
@@ -0,0 +1,77 @@
1
+ // @desc Multimodal content types: text, image, audio, video, file
2
+ //
3
+ // source 使用判别联合 (type: 'base64' | 'url' | 'stream'), 与传输层解耦
4
+ // 同一个 AudioContent 可以在 WS JSON (base64) 或 HTTP 上传 (url) 中使用
5
+ //
6
+ // 迁移注意:
7
+ // - VideoContent / VideoStreamSource 已定义但尚无实现
8
+ // - MediaPipeline TTS 输出已使用 AudioContent + InlineSource (base64)
9
+ // - 旧的 ContentBlock (src/core/types.ts) 是 LLM 内部格式, 与本文件的
10
+ // MediaContent 是不同抽象层: ContentBlock = LLM API, MediaContent = 传输契约
11
+
12
+ export type ContentKind = 'text' | 'image' | 'audio' | 'video' | 'file';
13
+
14
+ // ── Source discriminated union (transport-agnostic) ──
15
+
16
+ export type InlineSource = { type: 'base64'; data: string };
17
+ export type UrlSource = { type: 'url'; url: string };
18
+ export type StreamSource = { type: 'stream'; streamId: string };
19
+
20
+ // ── Content blocks ──
21
+
22
+ export interface TextContent {
23
+ kind: 'text';
24
+ text: string;
25
+ }
26
+
27
+ export interface ImageContent {
28
+ kind: 'image';
29
+ mimeType: 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif';
30
+ source: InlineSource | UrlSource;
31
+ width?: number;
32
+ height?: number;
33
+ alt?: string;
34
+ }
35
+
36
+ export interface AudioContent {
37
+ kind: 'audio';
38
+ format: 'mp3' | 'pcm' | 'wav' | 'webm' | 'opus';
39
+ source: InlineSource | UrlSource | StreamSource;
40
+ sampleRate?: number;
41
+ channels?: number;
42
+ durationMs?: number;
43
+ }
44
+
45
+ export type VideoStreamSource = {
46
+ type: 'stream';
47
+ streamId: string;
48
+ protocol: 'webrtc' | 'hls' | 'ws-binary';
49
+ };
50
+
51
+ export interface VideoContent {
52
+ kind: 'video';
53
+ format: 'mp4' | 'webm';
54
+ source: InlineSource | UrlSource | VideoStreamSource;
55
+ mimeType?: string;
56
+ width?: number;
57
+ height?: number;
58
+ durationMs?: number;
59
+ thumbnail?: ImageContent;
60
+ }
61
+
62
+ export interface FileContent {
63
+ kind: 'file';
64
+ filename: string;
65
+ mimeType: string;
66
+ source: InlineSource | UrlSource;
67
+ sizeBytes?: number;
68
+ }
69
+
70
+ export type MediaContent =
71
+ | TextContent
72
+ | ImageContent
73
+ | AudioContent
74
+ | VideoContent
75
+ | FileContent;
76
+
77
+ export type MultimodalBody = MediaContent[];
@@ -0,0 +1,32 @@
1
+ // @desc Central registry types for session ↔ project associations
2
+ //
3
+ // registry.json lives in .openclaw/ and tracks all projects (games + workspace apps).
4
+ // It is the single source of truth for:
5
+ // - Server API endpoints (/projects, /sessions enrichment)
6
+ // - Frontend project listing and session switching
7
+ // - Future network service mapping (game sharing platform)
8
+ //
9
+ // Projects are keyed by their directory name (which already contains timestamp + random suffix).
10
+
11
+ export type ProjectType = 'game' | 'app';
12
+ export type ProjectStatus = 'active' | 'archived' | 'error';
13
+
14
+ export interface ProjectEntry {
15
+ type: ProjectType;
16
+ name: string;
17
+ dir: string;
18
+ template?: string;
19
+ engine?: string;
20
+ port?: number;
21
+ vite: boolean;
22
+ createdAt: string;
23
+ sessionId: string;
24
+ status: ProjectStatus;
25
+ description?: string;
26
+ }
27
+
28
+ export interface Registry {
29
+ version: number;
30
+ projects: Record<string, ProjectEntry>;
31
+ activeGameDir?: string;
32
+ }
@@ -0,0 +1,192 @@
1
+ # Plugin 层架构指南
2
+
3
+ > OpenClaw 插件的 Node.js 端:Hook 监听、WebSocket 广播、AI 工具、编辑器 API、居民 Agent 管理。
4
+
5
+ ## 目录结构
6
+
7
+ ```
8
+ src/plugin/
9
+ ├── channel.ts # ChannelPlugin 实现(startAccount启动WS/注册回调)
10
+ ├── hook-translator.ts # 纯函数:OpenClaw Hook名 → AgentEvent
11
+ ├── ws-server.ts # WebSocket服务器 + 会话绑定 + 消息路由
12
+ ├── tools.ts # AI工具注册(11个工具)
13
+ ├── auto-config.ts # 零配置:自动创建town-steward Agent + Binding
14
+ ├── plan-manager.ts # 多Agent计划状态机(步骤/批次/enriched task)
15
+ ├── citizen-agent-manager.ts # 独立居民Agent CRUD(写openclaw.json)
16
+ ├── citizen-chat-router.ts # 用户↔居民Agent消息路由
17
+ ├── citizen-workshop-manager.ts # 居民工坊配置持久化(citizen-config.json)
18
+ ├── editor-serve.ts # 编辑器HTTP API(1176行,资产/工坊/发布)
19
+ ├── llm-agent-proxy.ts # LLM代理(走OpenClaw embedded agent runtime,2并发+10队列)
20
+ ├── session-history.ts # 跨会话聊天历史加载(管家+居民)
21
+ ├── soul-prompt-template.ts # 灵魂文件AI生成模板
22
+ ├── outbound-adapter.ts # 出站适配(text→AgentEvent, media→deliverable_card)
23
+ ├── subagent-tracker.ts # 子Agent会话日志实时转发
24
+ ├── session-log-watcher.ts # JSONL日志增量读取(300ms轮询)
25
+ ├── custom-asset-manager.ts # 自定义GLB资产管理(最多20个,10MB限制)
26
+ ├── town-session.ts # Session ID标准化/解析
27
+ └── runtime.ts # Runtime注入(getter/setter)
28
+ ```
29
+
30
+ ## 核心数据流
31
+
32
+ ```
33
+ index.ts register(api)
34
+ ├─ api.registerChannel(agentTownPlugin) → channel.ts
35
+ ├─ registerHooks(api) → 监听8种Hook
36
+ ├─ api.registerTool(createTownTools()) → tools.ts
37
+ ├─ ensureTownAgentConfig() → auto-config.ts
38
+ ├─ subagent_spawning hook → town-souls.ts 注入灵魂
39
+ └─ api.registerService("agentshire-frontend") → HTTP服务器(:55210)
40
+ └─ handleEditorRequest() → editor-serve.ts
41
+
42
+ Hook事件流:
43
+ OpenClaw Hook → isStewardDirect() 判断
44
+ ├─ 管家直接事件 → dispatchSteward() → hookToAgentEvent() → broadcastAgentEvent()
45
+ └─ 居民Agent事件 → dispatchCitizen() → 附加npcId → broadcastAgentEvent()
46
+
47
+ 子Agent生命周期:
48
+ subagent_spawned → pendingSpawnTasks缓存task → onSubagentSpawned()
49
+ → SessionLogWatcher监听JSONL → broadcastAgentEvent(子事件)
50
+ subagent_ended → onSubagentEnded() → plan-manager.onAgentCompleted()
51
+ → 批次完成?→ scheduleNudge(10s后提醒next_step)
52
+ ```
53
+
54
+ ## Hook 翻译表(hook-translator.ts)
55
+
56
+ | Hook名 | AgentEvent类型 | 备注 |
57
+ |--------|---------------|------|
58
+ | `before_agent_start` | `system.init` | sessionId/model/persona |
59
+ | `agent_end` | `turn_end` (+可选error) | usage/toolCalls/durationMs |
60
+ | `llm_input` | `thinking_delta` | 提取thinking/reasoning字段 |
61
+ | `llm_output` | `text` | assistantTexts最后一项 |
62
+ | `before_tool_call` | `tool_use` | name/input |
63
+ | `after_tool_call` | `tool_result` (+可选media_output) | 自动检测媒体文件 |
64
+ | `subagent_spawned` | `sub_agent.started` | label/task/agentId |
65
+ | `subagent_ended` | `sub_agent.done` | outcome→status映射 |
66
+ | `message_sending` | `text` | 发送中的消息 |
67
+ | `session_end` | `system.done` | — |
68
+
69
+ ## AI 工具(tools.ts)
70
+
71
+ | 工具名 | 功能 | 发出的事件 |
72
+ |--------|------|-----------|
73
+ | `town_announce` | 广播消息 | `text` |
74
+ | `town_spawn_npc` | 生成NPC | `sub_agent.started`(模拟) |
75
+ | `town_effect` | 触发VFX | `fx` |
76
+ | `town_set_time` | 控制时钟 | `world_control.time` |
77
+ | `town_set_weather` | 控制天气 | `world_control.weather` |
78
+ | `town_status` | 查看状态 | —(返回文本) |
79
+ | `register_project` | 注册项目 | — |
80
+ | `create_project` | 创建项目目录 | — |
81
+ | `create_plan` | 创建多Agent计划 | — |
82
+ | `next_step` | 获取下一步指令 | — |
83
+ | `project_complete` | 宣布完成 | `tool_result`(触发publishing) |
84
+
85
+ ## plan-manager:多 Agent 计划编排
86
+
87
+ ```
88
+ create_plan(steps) → 验证(多Agent步骤必须有files且不重叠)
89
+ → 存储计划(追加隐含_complete步骤)
90
+
91
+ next_step() → 生成当前进度报告 + 下一批spawn指令
92
+ → buildEnrichedTask(角色人设+项目目录+文件边界+通用规则)
93
+
94
+ onAgentStarted(label) → 标记agent为active
95
+ onAgentCompleted(label, success) → 标记完成 → isCurrentBatchDone()?
96
+ → 是 → index.ts scheduleNudge(10s后提醒管家)
97
+
98
+ 支持 parallel 标记:步骤可与前一步并行执行
99
+ ```
100
+
101
+ ## editor-serve:编辑器 HTTP API
102
+
103
+ 路由结构(全部走 `handleEditorRequest()`):
104
+
105
+ | 路径前缀 | 功能 |
106
+ |---------|------|
107
+ | `/ext-assets/*` | 角色/地图资产静态文件 |
108
+ | `/citizen-workshop/avatars/*` | 用户上传头像 |
109
+ | `/custom-assets/_api/{action}` | 自定义资产CRUD + GLB优化(@gltf-transform) |
110
+ | `/custom-assets/*` | 自定义资产静态文件 |
111
+ | `/citizen-workshop/_api/load` | 加载工坊草稿配置 |
112
+ | `/citizen-workshop/_api/save` | 保存工坊草稿 |
113
+ | `/citizen-workshop/_api/publish` | **发布**:changeset检测→Agent CRUD→同步town-defaults |
114
+ | `/citizen-workshop/_api/load-published` | 加载已发布配置 |
115
+ | `/citizen-workshop/_api/generate-soul` | AI生成灵魂文件 |
116
+ | `/citizen-workshop/_api/upload-avatar` | 上传头像 |
117
+ | `/citizen-workshop/_api/upload-anim` | 上传动画文件 |
118
+ | `/citizen-workshop/_api/agents` | 查询Agent列表 |
119
+ | `/citizen-workshop/_api/buildings` | 查询建筑列表 |
120
+ | `/citizen-workshop/_api/media` | 媒体文件代理 |
121
+
122
+ **发布流程**:
123
+ 1. 构建 `PublishedCitizenConfig`(bake所有URL)
124
+ 2. 比较新旧配置,检测 changeset(create/disable/update_soul)
125
+ 3. 调用 `citizen-agent-manager.applyAgentChanges()` 执行Agent CRUD
126
+ 4. 管家人设变更时更新管家SOUL.md
127
+ 5. 同步 `town-defaults.json`
128
+
129
+ ## citizen-agent-manager:独立居民 Agent
130
+
131
+ 居民不只是子Agent(工作时),也可以是独立Agent(有自己的工作区和会话)。
132
+
133
+ | 操作 | 行为 |
134
+ |------|------|
135
+ | `create` | 创建 `~/.openclaw/workspace-citizen-{id}/` + SOUL.md + 注册到openclaw.json |
136
+ | `disable` | 从 openclaw.json agents.list 中移除 |
137
+ | `update_soul` | 更新 SOUL.md 文件 |
138
+
139
+ `citizen-chat-router.ts` 路由用户消息到居民Agent的独立会话(SessionKey = `agent:{agentId}:main`)。
140
+
141
+ ## WebSocket 协议(ws-server.ts)
142
+
143
+ **浏览器 → 服务端**:
144
+
145
+ | 消息类型 | 说明 |
146
+ |---------|------|
147
+ | `town_session_init` | 绑定会话,回复 `town_session_bound` + `work_snapshot` |
148
+ | `chat` | 用户消息 → onChat回调 → 管家Agent |
149
+ | `multimodal` | 多模态消息(图片/视频/音频) |
150
+ | `citizen_chat` | 居民聊天 → citizen-chat-router |
151
+ | `implicit_chat_request` | 前端隐式LLM请求 → llm-agent-proxy |
152
+ | `chat_history_request` | 请求历史消息 → session-history |
153
+ | `command` | 命令消息(`/xxx`) |
154
+ | `abort` | 中止当前请求 |
155
+
156
+ **服务端 → 浏览器**:
157
+
158
+ | 消息类型 | 说明 |
159
+ |---------|------|
160
+ | `agent_event` | 主事件流(AgentEvent) |
161
+ | `work_snapshot` | 工作状态快照(子Agent列表+活动日志) |
162
+ | `chat_new_messages` | 新消息增量推送 |
163
+ | `chat_history` | 历史消息(含分页cursor) |
164
+ | `implicit_chat_response` | 隐式LLM响应 |
165
+
166
+ ## Nudge 机制(index.ts)
167
+
168
+ 当一批子Agent全部完成(`isCurrentBatchDone()`)但管家 10 秒内未响应时,自动发送系统通知"请调用 next_step()"。管家恢复活动(`before_agent_start` / `before_tool_call` / `llm_input`)时自动取消。
169
+
170
+ ## 常见改动
171
+
172
+ | 要做的事 | 改哪里 |
173
+ |---------|--------|
174
+ | 新增Hook→AgentEvent映射 | `hook-translator.ts` |
175
+ | 新增AI工具 | `tools.ts` |
176
+ | 修改计划编排/enriched task | `plan-manager.ts` |
177
+ | 修改编辑器API | `editor-serve.ts` |
178
+ | 修改居民Agent创建/销毁 | `citizen-agent-manager.ts` |
179
+ | 修改居民聊天路由 | `citizen-chat-router.ts` |
180
+ | 修改隐式LLM调用格式 | `llm-agent-proxy.ts` |
181
+ | 修改聊天历史解析 | `session-history.ts` |
182
+ | 修改灵魂文件生成模板 | `soul-prompt-template.ts` |
183
+ | 修改WS消息路由 | `ws-server.ts` |
184
+ | 修改出站消息格式 | `outbound-adapter.ts` |
185
+ | 修改自定义资产限制 | `custom-asset-manager.ts` |
186
+
187
+ ## 测试
188
+
189
+ ```
190
+ src/plugin/__tests__/
191
+ └── hook-translator.test.ts # Hook名 → AgentEvent 映射
192
+ ```
@@ -0,0 +1,150 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
2
+ import { join } from 'node:path'
3
+ import { mkdirSync, writeFileSync, rmSync, existsSync } from 'node:fs'
4
+
5
+ const TEST_PLUGIN_DIR = join(import.meta.dirname, '__fixtures_megapack__')
6
+ const MAP1_DIR = join(TEST_PLUGIN_DIR, 'assets', 'Map_1')
7
+
8
+ function createMockRes() {
9
+ const res: any = {
10
+ _status: 0,
11
+ _headers: {} as Record<string, string>,
12
+ _body: null as Buffer | string | null,
13
+ writeHead(status: number, headers?: Record<string, string>) {
14
+ res._status = status
15
+ if (headers) Object.assign(res._headers, headers)
16
+ },
17
+ end(body?: any) {
18
+ res._body = body ?? null
19
+ },
20
+ }
21
+ return res
22
+ }
23
+
24
+ function createMockReq(method: string, url: string): any {
25
+ return { method, url }
26
+ }
27
+
28
+ describe('editor-serve megapack route', () => {
29
+ beforeEach(() => {
30
+ mkdirSync(join(MAP1_DIR, 'Buildings', 'Building 1'), { recursive: true })
31
+ writeFileSync(
32
+ join(MAP1_DIR, 'Buildings', 'Building 1', 'Building_1.gltf'),
33
+ '{"asset":{"version":"2.0"}}',
34
+ )
35
+ writeFileSync(
36
+ join(MAP1_DIR, 'Buildings', 'Building 1', 'Building_1.bin'),
37
+ Buffer.from([0x00, 0x01, 0x02]),
38
+ )
39
+ mkdirSync(join(MAP1_DIR, 'Roads'), { recursive: true })
40
+ writeFileSync(
41
+ join(MAP1_DIR, 'Roads', 'Road_Straight.gltf'),
42
+ '{"asset":{"version":"2.0"}}',
43
+ )
44
+ mkdirSync(join(TEST_PLUGIN_DIR, 'town-data', 'custom-assets', 'models'), { recursive: true })
45
+ mkdirSync(join(TEST_PLUGIN_DIR, 'town-data', 'custom-assets', 'characters'), { recursive: true })
46
+ mkdirSync(join(TEST_PLUGIN_DIR, 'town-data', 'custom-assets', 'animations'), { recursive: true })
47
+ mkdirSync(join(TEST_PLUGIN_DIR, 'town-data', 'souls'), { recursive: true })
48
+ mkdirSync(join(TEST_PLUGIN_DIR, 'town-souls'), { recursive: true })
49
+ mkdirSync(join(TEST_PLUGIN_DIR, 'town-data', 'citizen-workshop', 'avatars'), { recursive: true })
50
+ if (!existsSync(join(TEST_PLUGIN_DIR, 'town-data', 'custom-assets', '_catalog.json'))) {
51
+ writeFileSync(
52
+ join(TEST_PLUGIN_DIR, 'town-data', 'custom-assets', '_catalog.json'),
53
+ '{"version":1,"assets":[]}',
54
+ )
55
+ }
56
+ })
57
+
58
+ afterEach(() => {
59
+ rmSync(TEST_PLUGIN_DIR, { recursive: true, force: true })
60
+ })
61
+
62
+ async function handle(method: string, url: string) {
63
+ const { handleEditorRequest } = await import('../editor-serve.js')
64
+ const req = createMockReq(method, url)
65
+ const res = createMockRes()
66
+ const handled = await handleEditorRequest(req, res, TEST_PLUGIN_DIR)
67
+ return { handled, res }
68
+ }
69
+
70
+ it('serves megapack gltf file when assets exist', async () => {
71
+ const { handled, res } = await handle(
72
+ 'GET',
73
+ '/assets/models/megapack/gltf/Buildings/Building%201/Building_1.gltf',
74
+ )
75
+ expect(handled).toBe(true)
76
+ expect(res._status).toBe(200)
77
+ expect(res._headers['Content-Type']).toContain('gltf')
78
+ })
79
+
80
+ it('serves megapack bin file when assets exist', async () => {
81
+ const { handled, res } = await handle(
82
+ 'GET',
83
+ '/assets/models/megapack/gltf/Buildings/Building%201/Building_1.bin',
84
+ )
85
+ expect(handled).toBe(true)
86
+ expect(res._status).toBe(200)
87
+ expect(res._headers['Content-Type']).toBe('application/octet-stream')
88
+ })
89
+
90
+ it('returns 404 for non-existent megapack file', async () => {
91
+ const { handled, res } = await handle(
92
+ 'GET',
93
+ '/assets/models/megapack/gltf/Buildings/NoSuch/model.gltf',
94
+ )
95
+ expect(handled).toBe(true)
96
+ expect(res._status).toBe(404)
97
+ })
98
+
99
+ it('correctly decodes URL-encoded paths with spaces', async () => {
100
+ const { handled, res } = await handle(
101
+ 'GET',
102
+ '/assets/models/megapack/gltf/Buildings/Building%201/Building_1.gltf',
103
+ )
104
+ expect(handled).toBe(true)
105
+ expect(res._status).toBe(200)
106
+ })
107
+
108
+ it('blocks path traversal attempts', async () => {
109
+ const { handled, res } = await handle(
110
+ 'GET',
111
+ '/assets/models/megapack/gltf/../../../../../../etc/passwd',
112
+ )
113
+ expect(handled).toBe(true)
114
+ expect(res._status).toBe(404)
115
+ })
116
+
117
+ it('does not intercept non-megapack asset requests', async () => {
118
+ const { handled } = await handle(
119
+ 'GET',
120
+ '/assets/models/buildings/building_A.gltf',
121
+ )
122
+ expect(handled).toBe(false)
123
+ })
124
+
125
+ it('does not intercept ext-assets requests (existing route)', async () => {
126
+ const { handled, res } = await handle(
127
+ 'GET',
128
+ '/ext-assets/Characters_1/gLTF/Animations/Animations.glb',
129
+ )
130
+ expect(handled).toBe(true)
131
+ expect(res._status).toBe(404)
132
+ })
133
+
134
+ it('serves simple path without URL encoding', async () => {
135
+ const { handled, res } = await handle(
136
+ 'GET',
137
+ '/assets/models/megapack/gltf/Roads/Road_Straight.gltf',
138
+ )
139
+ expect(handled).toBe(true)
140
+ expect(res._status).toBe(200)
141
+ })
142
+
143
+ it('sets cache header on megapack responses', async () => {
144
+ const { res } = await handle(
145
+ 'GET',
146
+ '/assets/models/megapack/gltf/Roads/Road_Straight.gltf',
147
+ )
148
+ expect(res._headers['Cache-Control']).toBe('public, max-age=86400')
149
+ })
150
+ })