@agent-native/core 0.4.5 → 0.5.0-dev.b51eaae

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 (479) hide show
  1. package/dist/a2a/client.d.ts +7 -0
  2. package/dist/a2a/client.d.ts.map +1 -1
  3. package/dist/a2a/client.js +24 -3
  4. package/dist/a2a/client.js.map +1 -1
  5. package/dist/a2a/handlers.d.ts +6 -3
  6. package/dist/a2a/handlers.d.ts.map +1 -1
  7. package/dist/a2a/handlers.js +45 -39
  8. package/dist/a2a/handlers.js.map +1 -1
  9. package/dist/a2a/index.d.ts +1 -1
  10. package/dist/a2a/index.d.ts.map +1 -1
  11. package/dist/a2a/index.js +2 -2
  12. package/dist/a2a/index.js.map +1 -1
  13. package/dist/a2a/server.d.ts +7 -2
  14. package/dist/a2a/server.d.ts.map +1 -1
  15. package/dist/a2a/server.js +54 -14
  16. package/dist/a2a/server.js.map +1 -1
  17. package/dist/a2a/task-store.d.ts +6 -6
  18. package/dist/a2a/task-store.d.ts.map +1 -1
  19. package/dist/a2a/task-store.js +102 -42
  20. package/dist/a2a/task-store.js.map +1 -1
  21. package/dist/a2a/types.d.ts +2 -0
  22. package/dist/a2a/types.d.ts.map +1 -1
  23. package/dist/action.d.ts +46 -0
  24. package/dist/action.d.ts.map +1 -0
  25. package/dist/action.js +35 -0
  26. package/dist/action.js.map +1 -0
  27. package/dist/adapters/sync/file-sync.js +1 -1
  28. package/dist/agent/index.d.ts +2 -2
  29. package/dist/agent/index.d.ts.map +1 -1
  30. package/dist/agent/index.js.map +1 -1
  31. package/dist/agent/production-agent.d.ts +22 -6
  32. package/dist/agent/production-agent.d.ts.map +1 -1
  33. package/dist/agent/production-agent.js +336 -123
  34. package/dist/agent/production-agent.js.map +1 -1
  35. package/dist/agent/run-manager.d.ts +43 -0
  36. package/dist/agent/run-manager.d.ts.map +1 -0
  37. package/dist/agent/run-manager.js +358 -0
  38. package/dist/agent/run-manager.js.map +1 -0
  39. package/dist/agent/run-store.d.ts +26 -0
  40. package/dist/agent/run-store.d.ts.map +1 -0
  41. package/dist/agent/run-store.js +145 -0
  42. package/dist/agent/run-store.js.map +1 -0
  43. package/dist/agent/thread-data-builder.d.ts +30 -0
  44. package/dist/agent/thread-data-builder.d.ts.map +1 -0
  45. package/dist/agent/thread-data-builder.js +88 -0
  46. package/dist/agent/thread-data-builder.js.map +1 -0
  47. package/dist/agent/types.d.ts +52 -1
  48. package/dist/agent/types.d.ts.map +1 -1
  49. package/dist/application-state/emitter.d.ts +3 -2
  50. package/dist/application-state/emitter.d.ts.map +1 -1
  51. package/dist/application-state/emitter.js +14 -4
  52. package/dist/application-state/emitter.js.map +1 -1
  53. package/dist/application-state/handlers.d.ts.map +1 -1
  54. package/dist/application-state/handlers.js +13 -16
  55. package/dist/application-state/handlers.js.map +1 -1
  56. package/dist/application-state/script-helpers.d.ts +1 -1
  57. package/dist/application-state/script-helpers.d.ts.map +1 -1
  58. package/dist/application-state/script-helpers.js +15 -5
  59. package/dist/application-state/script-helpers.js.map +1 -1
  60. package/dist/application-state/store.d.ts +4 -3
  61. package/dist/application-state/store.d.ts.map +1 -1
  62. package/dist/application-state/store.js +31 -59
  63. package/dist/application-state/store.js.map +1 -1
  64. package/dist/chat-threads/emitter.d.ts +9 -0
  65. package/dist/chat-threads/emitter.d.ts.map +1 -0
  66. package/dist/chat-threads/emitter.js +14 -0
  67. package/dist/chat-threads/emitter.js.map +1 -0
  68. package/dist/chat-threads/store.d.ts +28 -0
  69. package/dist/chat-threads/store.d.ts.map +1 -0
  70. package/dist/chat-threads/store.js +124 -0
  71. package/dist/chat-threads/store.js.map +1 -0
  72. package/dist/cli/create.d.ts.map +1 -1
  73. package/dist/cli/create.js +4 -18
  74. package/dist/cli/create.js.map +1 -1
  75. package/dist/cli/index.js +30 -3
  76. package/dist/cli/index.js.map +1 -1
  77. package/dist/cli/setup-agents.d.ts +11 -0
  78. package/dist/cli/setup-agents.d.ts.map +1 -0
  79. package/dist/cli/setup-agents.js +123 -0
  80. package/dist/cli/setup-agents.js.map +1 -0
  81. package/dist/client/AgentPanel.d.ts +9 -2
  82. package/dist/client/AgentPanel.d.ts.map +1 -1
  83. package/dist/client/AgentPanel.js +466 -29
  84. package/dist/client/AgentPanel.js.map +1 -1
  85. package/dist/client/AssistantChat.d.ts +25 -3
  86. package/dist/client/AssistantChat.d.ts.map +1 -1
  87. package/dist/client/AssistantChat.js +613 -83
  88. package/dist/client/AssistantChat.js.map +1 -1
  89. package/dist/client/ClientOnly.d.ts +14 -0
  90. package/dist/client/ClientOnly.d.ts.map +1 -0
  91. package/dist/client/ClientOnly.js +17 -0
  92. package/dist/client/ClientOnly.js.map +1 -0
  93. package/dist/client/CommandMenu.d.ts +71 -0
  94. package/dist/client/CommandMenu.d.ts.map +1 -0
  95. package/dist/client/CommandMenu.js +257 -0
  96. package/dist/client/CommandMenu.js.map +1 -0
  97. package/dist/client/DefaultSpinner.d.ts +7 -0
  98. package/dist/client/DefaultSpinner.d.ts.map +1 -0
  99. package/dist/client/DefaultSpinner.js +28 -0
  100. package/dist/client/DefaultSpinner.js.map +1 -0
  101. package/dist/client/MultiTabAssistantChat.d.ts +34 -2
  102. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  103. package/dist/client/MultiTabAssistantChat.js +346 -57
  104. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  105. package/dist/client/PoweredByBadge.d.ts.map +1 -1
  106. package/dist/client/PoweredByBadge.js +2 -1
  107. package/dist/client/PoweredByBadge.js.map +1 -1
  108. package/dist/client/active-run-state.d.ts +10 -0
  109. package/dist/client/active-run-state.d.ts.map +1 -0
  110. package/dist/client/active-run-state.js +32 -0
  111. package/dist/client/active-run-state.js.map +1 -0
  112. package/dist/client/agent-chat-adapter.d.ts +2 -1
  113. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  114. package/dist/client/agent-chat-adapter.js +83 -129
  115. package/dist/client/agent-chat-adapter.js.map +1 -1
  116. package/dist/client/agent-chat.js +2 -2
  117. package/dist/client/agent-chat.js.map +1 -1
  118. package/dist/client/components/ApiKeySettings.d.ts +2 -2
  119. package/dist/client/components/ApiKeySettings.js +4 -4
  120. package/dist/client/components/ApiKeySettings.js.map +1 -1
  121. package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
  122. package/dist/client/components/CodeRequiredDialog.js +4 -3
  123. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  124. package/dist/client/composer/MentionPopover.d.ts +26 -0
  125. package/dist/client/composer/MentionPopover.d.ts.map +1 -0
  126. package/dist/client/composer/MentionPopover.js +130 -0
  127. package/dist/client/composer/MentionPopover.js.map +1 -0
  128. package/dist/client/composer/TiptapComposer.d.ts +19 -0
  129. package/dist/client/composer/TiptapComposer.d.ts.map +1 -0
  130. package/dist/client/composer/TiptapComposer.js +415 -0
  131. package/dist/client/composer/TiptapComposer.js.map +1 -0
  132. package/dist/client/composer/extensions/FileReference.d.ts +3 -0
  133. package/dist/client/composer/extensions/FileReference.d.ts.map +1 -0
  134. package/dist/client/composer/extensions/FileReference.js +36 -0
  135. package/dist/client/composer/extensions/FileReference.js.map +1 -0
  136. package/dist/client/composer/extensions/MentionReference.d.ts +3 -0
  137. package/dist/client/composer/extensions/MentionReference.d.ts.map +1 -0
  138. package/dist/client/composer/extensions/MentionReference.js +63 -0
  139. package/dist/client/composer/extensions/MentionReference.js.map +1 -0
  140. package/dist/client/composer/extensions/SkillReference.d.ts +3 -0
  141. package/dist/client/composer/extensions/SkillReference.d.ts.map +1 -0
  142. package/dist/client/composer/extensions/SkillReference.js +40 -0
  143. package/dist/client/composer/extensions/SkillReference.js.map +1 -0
  144. package/dist/client/composer/index.d.ts +8 -0
  145. package/dist/client/composer/index.d.ts.map +1 -0
  146. package/dist/client/composer/index.js +7 -0
  147. package/dist/client/composer/index.js.map +1 -0
  148. package/dist/client/composer/types.d.ts +32 -0
  149. package/dist/client/composer/types.d.ts.map +1 -0
  150. package/dist/client/composer/types.js +2 -0
  151. package/dist/client/composer/types.js.map +1 -0
  152. package/dist/client/composer/use-file-search.d.ts +6 -0
  153. package/dist/client/composer/use-file-search.d.ts.map +1 -0
  154. package/dist/client/composer/use-file-search.js +40 -0
  155. package/dist/client/composer/use-file-search.js.map +1 -0
  156. package/dist/client/composer/use-mention-search.d.ts +6 -0
  157. package/dist/client/composer/use-mention-search.d.ts.map +1 -0
  158. package/dist/client/composer/use-mention-search.js +39 -0
  159. package/dist/client/composer/use-mention-search.js.map +1 -0
  160. package/dist/client/composer/use-skills.d.ts +7 -0
  161. package/dist/client/composer/use-skills.d.ts.map +1 -0
  162. package/dist/client/composer/use-skills.js +38 -0
  163. package/dist/client/composer/use-skills.js.map +1 -0
  164. package/dist/client/index.d.ts +9 -4
  165. package/dist/client/index.d.ts.map +1 -1
  166. package/dist/client/index.js +8 -3
  167. package/dist/client/index.js.map +1 -1
  168. package/dist/client/resources/ResourceEditor.d.ts +7 -0
  169. package/dist/client/resources/ResourceEditor.d.ts.map +1 -0
  170. package/dist/client/resources/ResourceEditor.js +851 -0
  171. package/dist/client/resources/ResourceEditor.js.map +1 -0
  172. package/dist/client/resources/ResourceTree.d.ts +13 -0
  173. package/dist/client/resources/ResourceTree.d.ts.map +1 -0
  174. package/dist/client/resources/ResourceTree.js +122 -0
  175. package/dist/client/resources/ResourceTree.js.map +1 -0
  176. package/dist/client/resources/ResourcesPanel.d.ts +2 -0
  177. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -0
  178. package/dist/client/resources/ResourcesPanel.js +341 -0
  179. package/dist/client/resources/ResourcesPanel.js.map +1 -0
  180. package/dist/client/resources/index.d.ts +5 -0
  181. package/dist/client/resources/index.d.ts.map +1 -0
  182. package/dist/client/resources/index.js +5 -0
  183. package/dist/client/resources/index.js.map +1 -0
  184. package/dist/client/resources/use-resources.d.ts +45 -0
  185. package/dist/client/resources/use-resources.d.ts.map +1 -0
  186. package/dist/client/resources/use-resources.js +102 -0
  187. package/dist/client/resources/use-resources.js.map +1 -0
  188. package/dist/client/sse-event-processor.d.ts +50 -0
  189. package/dist/client/sse-event-processor.d.ts.map +1 -0
  190. package/dist/client/sse-event-processor.js +267 -0
  191. package/dist/client/sse-event-processor.js.map +1 -0
  192. package/dist/client/terminal/AgentTerminal.d.ts +1 -1
  193. package/dist/client/terminal/AgentTerminal.d.ts.map +1 -1
  194. package/dist/client/terminal/AgentTerminal.js +11 -6
  195. package/dist/client/terminal/AgentTerminal.js.map +1 -1
  196. package/dist/client/use-agent-chat.d.ts +1 -1
  197. package/dist/client/use-agent-chat.d.ts.map +1 -1
  198. package/dist/client/use-agent-chat.js +3 -3
  199. package/dist/client/use-agent-chat.js.map +1 -1
  200. package/dist/client/use-chat-threads.d.ts +36 -0
  201. package/dist/client/use-chat-threads.d.ts.map +1 -0
  202. package/dist/client/use-chat-threads.js +175 -0
  203. package/dist/client/use-chat-threads.js.map +1 -0
  204. package/dist/client/use-db-sync.d.ts +35 -0
  205. package/dist/client/use-db-sync.d.ts.map +1 -0
  206. package/dist/client/use-db-sync.js +74 -0
  207. package/dist/client/use-db-sync.js.map +1 -0
  208. package/dist/client/use-dev-mode.d.ts +4 -2
  209. package/dist/client/use-dev-mode.d.ts.map +1 -1
  210. package/dist/client/use-dev-mode.js +39 -12
  211. package/dist/client/use-dev-mode.js.map +1 -1
  212. package/dist/client/use-file-sync-status.d.ts +1 -1
  213. package/dist/client/use-file-sync-status.js +3 -3
  214. package/dist/client/use-file-sync-status.js.map +1 -1
  215. package/dist/client/use-session.d.ts +1 -1
  216. package/dist/client/use-session.js +2 -2
  217. package/dist/client/use-session.js.map +1 -1
  218. package/dist/client/useProductionAgent.d.ts +1 -1
  219. package/dist/client/useProductionAgent.d.ts.map +1 -1
  220. package/dist/client/useProductionAgent.js +38 -3
  221. package/dist/client/useProductionAgent.js.map +1 -1
  222. package/dist/credentials/index.d.ts +18 -0
  223. package/dist/credentials/index.d.ts.map +1 -0
  224. package/dist/credentials/index.js +32 -0
  225. package/dist/credentials/index.js.map +1 -0
  226. package/dist/db/client.d.ts +35 -0
  227. package/dist/db/client.d.ts.map +1 -0
  228. package/dist/db/client.js +248 -0
  229. package/dist/db/client.js.map +1 -0
  230. package/dist/db/create-get-db.d.ts.map +1 -1
  231. package/dist/db/create-get-db.js +103 -16
  232. package/dist/db/create-get-db.js.map +1 -1
  233. package/dist/db/index.d.ts +10 -6
  234. package/dist/db/index.d.ts.map +1 -1
  235. package/dist/db/index.js +10 -4
  236. package/dist/db/index.js.map +1 -1
  237. package/dist/db/migrations.d.ts.map +1 -1
  238. package/dist/db/migrations.js +31 -30
  239. package/dist/db/migrations.js.map +1 -1
  240. package/dist/db/schema.d.ts +45 -0
  241. package/dist/db/schema.d.ts.map +1 -0
  242. package/dist/db/schema.js +61 -0
  243. package/dist/db/schema.js.map +1 -0
  244. package/dist/deploy/build.js +35 -6
  245. package/dist/deploy/build.js.map +1 -1
  246. package/dist/deploy/route-discovery.d.ts +9 -0
  247. package/dist/deploy/route-discovery.d.ts.map +1 -1
  248. package/dist/deploy/route-discovery.js +30 -1
  249. package/dist/deploy/route-discovery.js.map +1 -1
  250. package/dist/index.browser.d.ts +1 -1
  251. package/dist/index.browser.d.ts.map +1 -1
  252. package/dist/index.browser.js +1 -1
  253. package/dist/index.browser.js.map +1 -1
  254. package/dist/index.d.ts +3 -2
  255. package/dist/index.d.ts.map +1 -1
  256. package/dist/index.js +2 -1
  257. package/dist/index.js.map +1 -1
  258. package/dist/oauth-tokens/store.d.ts.map +1 -1
  259. package/dist/oauth-tokens/store.js +43 -81
  260. package/dist/oauth-tokens/store.js.map +1 -1
  261. package/dist/resources/emitter.d.ts +13 -0
  262. package/dist/resources/emitter.d.ts.map +1 -0
  263. package/dist/resources/emitter.js +32 -0
  264. package/dist/resources/emitter.js.map +1 -0
  265. package/dist/resources/handlers.d.ts +45 -0
  266. package/dist/resources/handlers.d.ts.map +1 -0
  267. package/dist/resources/handlers.js +219 -0
  268. package/dist/resources/handlers.js.map +1 -0
  269. package/dist/resources/index.d.ts +5 -0
  270. package/dist/resources/index.d.ts.map +1 -0
  271. package/dist/resources/index.js +5 -0
  272. package/dist/resources/index.js.map +1 -0
  273. package/dist/resources/script-helpers.d.ts +24 -0
  274. package/dist/resources/script-helpers.d.ts.map +1 -0
  275. package/dist/resources/script-helpers.js +36 -0
  276. package/dist/resources/script-helpers.js.map +1 -0
  277. package/dist/resources/store.d.ts +35 -0
  278. package/dist/resources/store.d.ts.map +1 -0
  279. package/dist/resources/store.js +453 -0
  280. package/dist/resources/store.js.map +1 -0
  281. package/dist/scripts/call-agent.d.ts +5 -0
  282. package/dist/scripts/call-agent.d.ts.map +1 -0
  283. package/dist/scripts/call-agent.js +107 -0
  284. package/dist/scripts/call-agent.js.map +1 -0
  285. package/dist/scripts/core-scripts.d.ts.map +1 -1
  286. package/dist/scripts/core-scripts.js +2 -0
  287. package/dist/scripts/core-scripts.js.map +1 -1
  288. package/dist/scripts/db/exec.d.ts +6 -2
  289. package/dist/scripts/db/exec.d.ts.map +1 -1
  290. package/dist/scripts/db/exec.js +127 -36
  291. package/dist/scripts/db/exec.js.map +1 -1
  292. package/dist/scripts/db/query.d.ts +7 -2
  293. package/dist/scripts/db/query.d.ts.map +1 -1
  294. package/dist/scripts/db/query.js +89 -45
  295. package/dist/scripts/db/query.js.map +1 -1
  296. package/dist/scripts/db/schema.d.ts +2 -2
  297. package/dist/scripts/db/schema.d.ts.map +1 -1
  298. package/dist/scripts/db/schema.js +145 -6
  299. package/dist/scripts/db/schema.js.map +1 -1
  300. package/dist/scripts/db/scoping.d.ts +36 -0
  301. package/dist/scripts/db/scoping.d.ts.map +1 -0
  302. package/dist/scripts/db/scoping.js +198 -0
  303. package/dist/scripts/db/scoping.js.map +1 -0
  304. package/dist/scripts/dev/index.d.ts +2 -2
  305. package/dist/scripts/dev/index.js +1 -1
  306. package/dist/scripts/dev/list-files.d.ts +2 -2
  307. package/dist/scripts/dev/read-file.d.ts +2 -2
  308. package/dist/scripts/dev/read-file.js +1 -1
  309. package/dist/scripts/dev/read-file.js.map +1 -1
  310. package/dist/scripts/dev/search-files.d.ts +2 -2
  311. package/dist/scripts/dev/search-files.js +1 -1
  312. package/dist/scripts/dev/search-files.js.map +1 -1
  313. package/dist/scripts/dev/shell.d.ts +2 -2
  314. package/dist/scripts/dev/shell.js +1 -1
  315. package/dist/scripts/dev/shell.js.map +1 -1
  316. package/dist/scripts/dev/write-file.d.ts +2 -2
  317. package/dist/scripts/dev/write-file.js +1 -1
  318. package/dist/scripts/dev/write-file.js.map +1 -1
  319. package/dist/scripts/resources/delete.d.ts +10 -0
  320. package/dist/scripts/resources/delete.d.ts.map +1 -0
  321. package/dist/scripts/resources/delete.js +38 -0
  322. package/dist/scripts/resources/delete.js.map +1 -0
  323. package/dist/scripts/resources/index.d.ts +2 -0
  324. package/dist/scripts/resources/index.d.ts.map +1 -0
  325. package/dist/scripts/resources/index.js +8 -0
  326. package/dist/scripts/resources/index.js.map +1 -0
  327. package/dist/scripts/resources/list.d.ts +10 -0
  328. package/dist/scripts/resources/list.d.ts.map +1 -0
  329. package/dist/scripts/resources/list.js +57 -0
  330. package/dist/scripts/resources/list.js.map +1 -0
  331. package/dist/scripts/resources/migrate-learnings.d.ts +10 -0
  332. package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -0
  333. package/dist/scripts/resources/migrate-learnings.js +23 -0
  334. package/dist/scripts/resources/migrate-learnings.js.map +1 -0
  335. package/dist/scripts/resources/read.d.ts +10 -0
  336. package/dist/scripts/resources/read.d.ts.map +1 -0
  337. package/dist/scripts/resources/read.js +59 -0
  338. package/dist/scripts/resources/read.js.map +1 -0
  339. package/dist/scripts/resources/write.d.ts +10 -0
  340. package/dist/scripts/resources/write.d.ts.map +1 -0
  341. package/dist/scripts/resources/write.js +67 -0
  342. package/dist/scripts/resources/write.js.map +1 -0
  343. package/dist/scripts/runner.d.ts +7 -7
  344. package/dist/scripts/runner.d.ts.map +1 -1
  345. package/dist/scripts/runner.js +68 -27
  346. package/dist/scripts/runner.js.map +1 -1
  347. package/dist/scripts/utils.d.ts +4 -1
  348. package/dist/scripts/utils.d.ts.map +1 -1
  349. package/dist/scripts/utils.js +5 -3
  350. package/dist/scripts/utils.js.map +1 -1
  351. package/dist/server/action-discovery.d.ts +40 -0
  352. package/dist/server/action-discovery.d.ts.map +1 -0
  353. package/dist/server/action-discovery.js +189 -0
  354. package/dist/server/action-discovery.js.map +1 -0
  355. package/dist/server/agent-chat-plugin.d.ts +12 -23
  356. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  357. package/dist/server/agent-chat-plugin.js +1087 -36
  358. package/dist/server/agent-chat-plugin.js.map +1 -1
  359. package/dist/server/agent-discovery.d.ts +16 -0
  360. package/dist/server/agent-discovery.d.ts.map +1 -0
  361. package/dist/server/agent-discovery.js +136 -0
  362. package/dist/server/agent-discovery.js.map +1 -0
  363. package/dist/server/auth-plugin.d.ts +5 -0
  364. package/dist/server/auth-plugin.d.ts.map +1 -1
  365. package/dist/server/auth-plugin.js +12 -1
  366. package/dist/server/auth-plugin.js.map +1 -1
  367. package/dist/server/auth.d.ts +3 -1
  368. package/dist/server/auth.d.ts.map +1 -1
  369. package/dist/server/auth.js +576 -117
  370. package/dist/server/auth.js.map +1 -1
  371. package/dist/server/core-routes-plugin.d.ts +57 -0
  372. package/dist/server/core-routes-plugin.d.ts.map +1 -0
  373. package/dist/server/core-routes-plugin.js +125 -0
  374. package/dist/server/core-routes-plugin.js.map +1 -0
  375. package/dist/server/create-server.d.ts +4 -4
  376. package/dist/server/create-server.d.ts.map +1 -1
  377. package/dist/server/create-server.js +5 -5
  378. package/dist/server/create-server.js.map +1 -1
  379. package/dist/server/default-watcher.d.ts +9 -3
  380. package/dist/server/default-watcher.d.ts.map +1 -1
  381. package/dist/server/default-watcher.js +26 -6
  382. package/dist/server/default-watcher.js.map +1 -1
  383. package/dist/server/google-auth-plugin.js +3 -3
  384. package/dist/server/google-auth-plugin.js.map +1 -1
  385. package/dist/server/google-oauth.d.ts +72 -0
  386. package/dist/server/google-oauth.d.ts.map +1 -0
  387. package/dist/server/google-oauth.js +187 -0
  388. package/dist/server/google-oauth.js.map +1 -0
  389. package/dist/server/index.d.ts +9 -2
  390. package/dist/server/index.d.ts.map +1 -1
  391. package/dist/server/index.js +8 -1
  392. package/dist/server/index.js.map +1 -1
  393. package/dist/server/oauth-helpers.d.ts +16 -0
  394. package/dist/server/oauth-helpers.d.ts.map +1 -0
  395. package/dist/server/oauth-helpers.js +25 -0
  396. package/dist/server/oauth-helpers.js.map +1 -0
  397. package/dist/server/poll.d.ts +40 -0
  398. package/dist/server/poll.d.ts.map +1 -0
  399. package/dist/server/poll.js +49 -0
  400. package/dist/server/poll.js.map +1 -0
  401. package/dist/server/resources-plugin.d.ts +27 -0
  402. package/dist/server/resources-plugin.d.ts.map +1 -0
  403. package/dist/server/resources-plugin.js +74 -0
  404. package/dist/server/resources-plugin.js.map +1 -0
  405. package/dist/server/script-discovery.d.ts +6 -0
  406. package/dist/server/script-discovery.d.ts.map +1 -0
  407. package/dist/server/script-discovery.js +6 -0
  408. package/dist/server/script-discovery.js.map +1 -0
  409. package/dist/server/sse.d.ts +1 -1
  410. package/dist/server/sse.js +1 -1
  411. package/dist/settings/handlers.d.ts +3 -3
  412. package/dist/settings/handlers.d.ts.map +1 -1
  413. package/dist/settings/handlers.js +8 -6
  414. package/dist/settings/handlers.js.map +1 -1
  415. package/dist/settings/index.d.ts +1 -1
  416. package/dist/settings/index.d.ts.map +1 -1
  417. package/dist/settings/index.js.map +1 -1
  418. package/dist/settings/store.d.ts +6 -2
  419. package/dist/settings/store.d.ts.map +1 -1
  420. package/dist/settings/store.js +26 -63
  421. package/dist/settings/store.js.map +1 -1
  422. package/dist/settings/user-settings.d.ts +3 -2
  423. package/dist/settings/user-settings.d.ts.map +1 -1
  424. package/dist/settings/user-settings.js +5 -5
  425. package/dist/settings/user-settings.js.map +1 -1
  426. package/dist/tailwind.preset.d.ts +7 -6
  427. package/dist/tailwind.preset.d.ts.map +1 -1
  428. package/dist/tailwind.preset.js +18 -1
  429. package/dist/tailwind.preset.js.map +1 -1
  430. package/dist/terminal/cli-registry.d.ts +1 -1
  431. package/dist/terminal/cli-registry.js +3 -3
  432. package/dist/terminal/cli-registry.js.map +1 -1
  433. package/dist/terminal/pty-server.d.ts.map +1 -1
  434. package/dist/terminal/pty-server.js +65 -11
  435. package/dist/terminal/pty-server.js.map +1 -1
  436. package/dist/terminal/terminal-plugin.d.ts +2 -2
  437. package/dist/terminal/terminal-plugin.d.ts.map +1 -1
  438. package/dist/terminal/terminal-plugin.js +27 -21
  439. package/dist/terminal/terminal-plugin.js.map +1 -1
  440. package/dist/vite/client.d.ts.map +1 -1
  441. package/dist/vite/client.js +114 -8
  442. package/dist/vite/client.js.map +1 -1
  443. package/dist/vite/dev-api-server.d.ts +1 -1
  444. package/dist/vite/dev-api-server.d.ts.map +1 -1
  445. package/dist/vite/dev-api-server.js +105 -22
  446. package/dist/vite/dev-api-server.js.map +1 -1
  447. package/package.json +22 -6
  448. package/src/templates/default/.agents/skills/actions/SKILL.md +136 -0
  449. package/src/templates/default/.agents/skills/create-skill/SKILL.md +1 -1
  450. package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +1 -1
  451. package/src/templates/default/.agents/skills/files-as-database/SKILL.md +2 -2
  452. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +112 -0
  453. package/src/templates/default/AGENTS.md +56 -164
  454. package/src/templates/default/DEVELOPING.md +117 -0
  455. package/src/templates/default/{scripts → actions}/hello.ts +1 -1
  456. package/src/templates/default/actions/navigate.ts +53 -0
  457. package/src/templates/default/actions/view-screen.ts +39 -0
  458. package/src/templates/default/app/global.css +2 -2
  459. package/src/templates/default/app/root.tsx +19 -16
  460. package/src/templates/default/app/routes/_index.tsx +1 -1
  461. package/src/templates/default/package.json +4 -0
  462. package/src/templates/default/server/plugins/.gitkeep +0 -0
  463. package/dist/a2a/middleware.d.ts +0 -3
  464. package/dist/a2a/middleware.d.ts.map +0 -1
  465. package/dist/a2a/middleware.js +0 -36
  466. package/dist/a2a/middleware.js.map +0 -1
  467. package/dist/client/use-file-watcher.d.ts +0 -23
  468. package/dist/client/use-file-watcher.d.ts.map +0 -1
  469. package/dist/client/use-file-watcher.js +0 -50
  470. package/dist/client/use-file-watcher.js.map +0 -1
  471. package/src/templates/default/.agents/skills/scripts/SKILL.md +0 -121
  472. package/src/templates/default/.agents/skills/sse-file-watcher/SKILL.md +0 -80
  473. package/src/templates/default/server/plugins/agent-chat.ts +0 -1
  474. package/src/templates/default/server/plugins/auth.ts +0 -1
  475. package/src/templates/default/server/plugins/file-sync.ts +0 -1
  476. package/src/templates/default/server/plugins/terminal.ts +0 -1
  477. package/src/templates/default/server/routes/api/events.get.ts +0 -3
  478. package/src/templates/default/server/routes/api/file-sync/status.get.ts +0 -4
  479. /package/src/templates/default/{scripts → actions}/run.ts +0 -0
@@ -1,82 +1,82 @@
1
1
  import crypto from "node:crypto";
2
- import fs from "node:fs";
3
- import path from "node:path";
4
- import { defineEventHandler, readBody, getMethod, setResponseHeader, setResponseStatus, getCookie, setCookie, deleteCookie, } from "h3";
5
- import { createClient } from "@libsql/client";
2
+ import { defineEventHandler, readBody, getMethod, getQuery, getRequestIP, setResponseHeader, setResponseStatus, getCookie, setCookie, deleteCookie, } from "h3";
3
+ import { getDbExec, isPostgres, intType } from "../db/client.js";
6
4
  // ---------------------------------------------------------------------------
7
5
  // Constants
8
6
  // ---------------------------------------------------------------------------
9
7
  const COOKIE_NAME = "an_session";
10
8
  const DEFAULT_MAX_AGE = 60 * 60 * 24 * 30; // 30 days
9
+ const RATE_LIMIT_WINDOW = 15 * 60 * 1000; // 15 minutes
10
+ const RATE_LIMIT_MAX = 10; // max attempts per window
11
+ const rateLimitMap = new Map();
12
+ // Prune stale entries every 5 minutes to prevent unbounded growth
13
+ setInterval(() => {
14
+ const now = Date.now();
15
+ for (const [key, entry] of rateLimitMap) {
16
+ if (now > entry.resetAt)
17
+ rateLimitMap.delete(key);
18
+ }
19
+ }, 5 * 60 * 1000).unref();
20
+ function getClientIp(event) {
21
+ return getRequestIP(event, { xForwardedFor: true }) ?? "unknown";
22
+ }
23
+ /**
24
+ * Check rate limit for a given key (typically IP + route).
25
+ * Returns null if allowed, or a response object if blocked.
26
+ */
27
+ function checkRateLimit(event, key) {
28
+ const now = Date.now();
29
+ const entry = rateLimitMap.get(key);
30
+ if (!entry || now > entry.resetAt) {
31
+ rateLimitMap.set(key, { count: 1, resetAt: now + RATE_LIMIT_WINDOW });
32
+ return null;
33
+ }
34
+ entry.count++;
35
+ if (entry.count > RATE_LIMIT_MAX) {
36
+ const retryAfter = Math.ceil((entry.resetAt - now) / 1000);
37
+ setResponseStatus(event, 429);
38
+ setResponseHeader(event, "Retry-After", retryAfter);
39
+ return {
40
+ error: "Too many attempts. Please try again later.",
41
+ retryAfter,
42
+ };
43
+ }
44
+ return null;
45
+ }
46
+ /** Reset rate limit on successful auth (so valid users aren't penalized). */
47
+ function resetRateLimit(key) {
48
+ rateLimitMap.delete(key);
49
+ }
11
50
  // ---------------------------------------------------------------------------
12
51
  // Session store — SQL-backed
13
52
  // ---------------------------------------------------------------------------
14
- let _sessionClient;
15
- let _sessionTableReady = false;
53
+ let _sessionInitPromise;
16
54
  let sessionMaxAge = DEFAULT_MAX_AGE;
17
- function getSessionClient() {
18
- if (!_sessionClient) {
19
- // Check for Cloudflare D1 binding
20
- const d1 = globalThis.__cf_env?.DB;
21
- if (d1) {
22
- _sessionClient = {
23
- async execute(sql) {
24
- if (typeof sql === "string") {
25
- const r = await d1.prepare(sql).all();
26
- return {
27
- rows: r.results || [],
28
- rowsAffected: r.meta?.changes ?? 0,
29
- };
30
- }
31
- const r = await d1
32
- .prepare(sql.sql)
33
- .bind(...sql.args)
34
- .all();
35
- return { rows: r.results || [], rowsAffected: r.meta?.changes ?? 0 };
36
- },
37
- };
38
- return _sessionClient;
39
- }
40
- // Fall back to libsql
41
- const url = process.env.DATABASE_URL || "file:./data/app.db";
42
- if (url.startsWith("file:")) {
55
+ async function ensureSessionTable() {
56
+ if (!_sessionInitPromise) {
57
+ _sessionInitPromise = (async () => {
58
+ const client = getDbExec();
59
+ await client.execute(`
60
+ CREATE TABLE IF NOT EXISTS sessions (
61
+ token TEXT PRIMARY KEY,
62
+ email TEXT,
63
+ created_at ${intType()} NOT NULL
64
+ )
65
+ `);
66
+ // Migration: add email column to existing tables that lack it
43
67
  try {
44
- fs.mkdirSync(path.join(process.cwd(), "data"), { recursive: true });
68
+ await client.execute(`ALTER TABLE sessions ADD COLUMN email TEXT`);
45
69
  }
46
70
  catch {
47
- // Edge runtimeno filesystem
71
+ // Column already exists ignore
48
72
  }
49
- }
50
- _sessionClient = createClient({
51
- url,
52
- authToken: process.env.DATABASE_AUTH_TOKEN,
53
- });
54
- }
55
- return _sessionClient;
56
- }
57
- async function ensureSessionTable() {
58
- if (_sessionTableReady)
59
- return;
60
- const client = getSessionClient();
61
- await client.execute(`
62
- CREATE TABLE IF NOT EXISTS sessions (
63
- token TEXT PRIMARY KEY,
64
- email TEXT,
65
- created_at INTEGER NOT NULL
66
- )
67
- `);
68
- // Migration: add email column to existing tables that lack it
69
- try {
70
- await client.execute(`ALTER TABLE sessions ADD COLUMN email TEXT`);
71
- }
72
- catch {
73
- // Column already exists — ignore
73
+ })();
74
74
  }
75
- _sessionTableReady = true;
75
+ return _sessionInitPromise;
76
76
  }
77
77
  async function pruneExpiredSessions() {
78
78
  await ensureSessionTable();
79
- const client = getSessionClient();
79
+ const client = getDbExec();
80
80
  const cutoff = Date.now() - sessionMaxAge * 1000;
81
81
  await client.execute({
82
82
  sql: `DELETE FROM sessions WHERE created_at < ?`,
@@ -89,16 +89,18 @@ async function pruneExpiredSessions() {
89
89
  */
90
90
  export async function addSession(token, email) {
91
91
  await ensureSessionTable();
92
- const client = getSessionClient();
92
+ const client = getDbExec();
93
93
  await client.execute({
94
- sql: `INSERT OR REPLACE INTO sessions (token, email, created_at) VALUES (?, ?, ?)`,
94
+ sql: isPostgres()
95
+ ? `INSERT INTO sessions (token, email, created_at) VALUES (?, ?, ?) ON CONFLICT (token) DO UPDATE SET email=EXCLUDED.email, created_at=EXCLUDED.created_at`
96
+ : `INSERT OR REPLACE INTO sessions (token, email, created_at) VALUES (?, ?, ?)`,
95
97
  args: [token, email ?? null, Date.now()],
96
98
  });
97
99
  }
98
100
  /** Remove a session by token. */
99
101
  export async function removeSession(token) {
100
102
  await ensureSessionTable();
101
- const client = getSessionClient();
103
+ const client = getDbExec();
102
104
  await client.execute({
103
105
  sql: `DELETE FROM sessions WHERE token = ?`,
104
106
  args: [token],
@@ -110,7 +112,7 @@ export async function removeSession(token) {
110
112
  */
111
113
  export async function getSessionEmail(token) {
112
114
  await ensureSessionTable();
113
- const client = getSessionClient();
115
+ const client = getDbExec();
114
116
  const { rows } = await client.execute({
115
117
  sql: `SELECT email, created_at FROM sessions WHERE token = ?`,
116
118
  args: [token],
@@ -129,7 +131,7 @@ export async function getSessionEmail(token) {
129
131
  }
130
132
  async function hasSession(token) {
131
133
  await ensureSessionTable();
132
- const client = getSessionClient();
134
+ const client = getDbExec();
133
135
  const { rows } = await client.execute({
134
136
  sql: `SELECT created_at FROM sessions WHERE token = ?`,
135
137
  args: [token],
@@ -182,20 +184,61 @@ const DEV_SESSION = { email: "local@localhost" };
182
184
  /**
183
185
  * Get the current auth session for a request.
184
186
  *
185
- * - In dev mode: always returns { email: "local@localhost" }
187
+ * - In dev mode: checks for a session cookie first (e.g. from Google OAuth),
188
+ * so the real email is used when sharing a DB with production.
189
+ * Falls back to { email: "local@localhost" } if no session cookie.
186
190
  * - In production with built-in auth: returns session if cookie is valid
187
191
  * - With custom auth (BYOA): delegates to the custom getSession
188
192
  */
189
193
  export async function getSession(event) {
190
- if (isDevMode())
191
- return DEV_SESSION;
192
- if (authDisabledMode)
194
+ if (isDevMode() || authDisabledMode) {
195
+ // Check for a real session cookie (created by Google OAuth callback)
196
+ // so dev and prod share the same identity on the same DB
197
+ try {
198
+ const cookie = getCookie(event, COOKIE_NAME);
199
+ if (cookie) {
200
+ const email = await getSessionEmail(cookie);
201
+ if (email)
202
+ return { email, token: cookie };
203
+ }
204
+ }
205
+ catch {
206
+ // DB not ready yet — fall back to dev session
207
+ }
193
208
  return DEV_SESSION;
194
- if (customGetSession)
195
- return customGetSession(event);
196
- const cookie = getCookie(event, COOKIE_NAME);
197
- if (cookie && (await hasSession(cookie))) {
198
- return { email: "user", token: cookie };
209
+ }
210
+ if (customGetSession) {
211
+ const session = await customGetSession(event);
212
+ if (session)
213
+ return session;
214
+ // Fall through to _session query param check (mobile WebView bridge)
215
+ }
216
+ else {
217
+ const cookie = getCookie(event, COOKIE_NAME);
218
+ if (cookie) {
219
+ const email = await getSessionEmail(cookie);
220
+ if (email)
221
+ return { email, token: cookie };
222
+ }
223
+ }
224
+ // Mobile WebViews have a separate cookie jar from Safari, so after OAuth
225
+ // completes in Safari the WebView won't have the session cookie. The mobile
226
+ // app passes the token as a query parameter; if it's valid we promote it to
227
+ // an httpOnly cookie so subsequent requests work normally.
228
+ // This MUST run even with custom auth providers (e.g. createGoogleAuthPlugin).
229
+ const qToken = getQuery(event)?._session;
230
+ if (qToken) {
231
+ const email = await getSessionEmail(qToken);
232
+ if (email) {
233
+ setCookie(event, COOKIE_NAME, qToken, {
234
+ httpOnly: true,
235
+ secure: process.env.NODE_ENV === "production",
236
+ sameSite: "lax",
237
+ path: "/",
238
+ maxAge: sessionMaxAge,
239
+ });
240
+ return { email, token: qToken };
241
+ }
199
242
  }
200
243
  return null;
201
244
  }
@@ -214,6 +257,102 @@ function safeTokenMatch(input, tokens) {
214
257
  return false;
215
258
  }
216
259
  // ---------------------------------------------------------------------------
260
+ // Password hashing — Web Crypto PBKDF2 (works on Node.js + CF Workers)
261
+ // ---------------------------------------------------------------------------
262
+ const PBKDF2_ITERATIONS = 100_000;
263
+ function toHex(buf) {
264
+ return Array.from(buf)
265
+ .map((b) => b.toString(16).padStart(2, "0"))
266
+ .join("");
267
+ }
268
+ function fromHex(hex) {
269
+ const bytes = new Uint8Array(hex.length / 2);
270
+ for (let i = 0; i < hex.length; i += 2) {
271
+ bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
272
+ }
273
+ return bytes;
274
+ }
275
+ async function hashPassword(password) {
276
+ const salt = crypto.getRandomValues(new Uint8Array(16));
277
+ const encoded = new TextEncoder().encode(password);
278
+ const keyMaterial = await globalThis.crypto.subtle.importKey("raw", encoded.buffer, "PBKDF2", false, ["deriveBits"]);
279
+ const derived = await globalThis.crypto.subtle.deriveBits({
280
+ name: "PBKDF2",
281
+ salt: salt.buffer,
282
+ iterations: PBKDF2_ITERATIONS,
283
+ hash: "SHA-256",
284
+ }, keyMaterial, 256);
285
+ return `${PBKDF2_ITERATIONS}:${toHex(salt)}:${toHex(new Uint8Array(derived))}`;
286
+ }
287
+ async function verifyPassword(password, stored) {
288
+ const [iterStr, saltHex, hashHex] = stored.split(":");
289
+ const iterations = parseInt(iterStr, 10);
290
+ const salt = fromHex(saltHex);
291
+ const expectedHash = fromHex(hashHex);
292
+ const encoded = new TextEncoder().encode(password);
293
+ const keyMaterial = await globalThis.crypto.subtle.importKey("raw", encoded.buffer, "PBKDF2", false, ["deriveBits"]);
294
+ const derived = new Uint8Array(await globalThis.crypto.subtle.deriveBits({
295
+ name: "PBKDF2",
296
+ salt: salt.buffer,
297
+ iterations,
298
+ hash: "SHA-256",
299
+ }, keyMaterial, 256));
300
+ if (derived.length !== expectedHash.length)
301
+ return false;
302
+ // Constant-time comparison
303
+ let diff = 0;
304
+ for (let i = 0; i < derived.length; i++) {
305
+ diff |= derived[i] ^ expectedHash[i];
306
+ }
307
+ return diff === 0;
308
+ }
309
+ // ---------------------------------------------------------------------------
310
+ // Users table — email/password accounts
311
+ // ---------------------------------------------------------------------------
312
+ let _usersTableReady = false;
313
+ async function ensureUsersTable() {
314
+ if (_usersTableReady)
315
+ return;
316
+ const client = getDbExec();
317
+ await client.execute(`
318
+ CREATE TABLE IF NOT EXISTS users (
319
+ email TEXT PRIMARY KEY,
320
+ password_hash TEXT NOT NULL,
321
+ created_at ${intType()} NOT NULL
322
+ )
323
+ `);
324
+ _usersTableReady = true;
325
+ }
326
+ async function createUser(email, password) {
327
+ await ensureUsersTable();
328
+ const client = getDbExec();
329
+ // Check if user already exists
330
+ const { rows } = await client.execute({
331
+ sql: `SELECT email FROM users WHERE email = ?`,
332
+ args: [email],
333
+ });
334
+ if (rows.length > 0) {
335
+ return { ok: false, error: "An account with this email already exists" };
336
+ }
337
+ const passwordHash = await hashPassword(password);
338
+ await client.execute({
339
+ sql: `INSERT INTO users (email, password_hash, created_at) VALUES (?, ?, ?)`,
340
+ args: [email, passwordHash, Date.now()],
341
+ });
342
+ return { ok: true };
343
+ }
344
+ async function authenticateUser(email, password) {
345
+ await ensureUsersTable();
346
+ const client = getDbExec();
347
+ const { rows } = await client.execute({
348
+ sql: `SELECT password_hash FROM users WHERE email = ?`,
349
+ args: [email],
350
+ });
351
+ if (rows.length === 0)
352
+ return false;
353
+ return verifyPassword(password, rows[0].password_hash);
354
+ }
355
+ // ---------------------------------------------------------------------------
217
356
  // Login page HTML
218
357
  // ---------------------------------------------------------------------------
219
358
  const LOGIN_HTML = `<!DOCTYPE html>
@@ -287,7 +426,7 @@ const LOGIN_HTML = `<!DOCTYPE html>
287
426
  document.getElementById('form').addEventListener('submit', async (e) => {
288
427
  e.preventDefault();
289
428
  const token = document.getElementById('token').value;
290
- const res = await fetch('/api/auth/login', {
429
+ const res = await fetch('/_agent-native/auth/login', {
291
430
  method: 'POST',
292
431
  headers: { 'Content-Type': 'application/json' },
293
432
  body: JSON.stringify({ token }),
@@ -302,6 +441,327 @@ const LOGIN_HTML = `<!DOCTYPE html>
302
441
  </body>
303
442
  </html>`;
304
443
  // ---------------------------------------------------------------------------
444
+ // Email/password auth HTML — combined login + register page
445
+ // ---------------------------------------------------------------------------
446
+ const EMAIL_AUTH_HTML = `<!DOCTYPE html>
447
+ <html lang="en">
448
+ <head>
449
+ <meta charset="UTF-8">
450
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
451
+ <title>Sign in</title>
452
+ <style>
453
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
454
+ body {
455
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
456
+ background: #0a0a0a;
457
+ color: #e5e5e5;
458
+ display: flex;
459
+ align-items: center;
460
+ justify-content: center;
461
+ min-height: 100vh;
462
+ }
463
+ .card {
464
+ width: 100%;
465
+ max-width: 380px;
466
+ padding: 2rem;
467
+ background: #141414;
468
+ border: 1px solid rgba(255,255,255,0.08);
469
+ border-radius: 12px;
470
+ }
471
+ .tabs {
472
+ display: inline-flex;
473
+ width: 100%;
474
+ padding: 4px;
475
+ margin-bottom: 1.5rem;
476
+ background: rgba(255,255,255,0.06);
477
+ border-radius: 8px;
478
+ }
479
+ .tab {
480
+ flex: 1;
481
+ padding: 0.5rem 0.75rem;
482
+ background: none;
483
+ border: none;
484
+ color: #888;
485
+ font-size: 0.8125rem;
486
+ font-weight: 500;
487
+ cursor: pointer;
488
+ border-radius: 6px;
489
+ }
490
+ .tab.active {
491
+ background: #1e1e1e;
492
+ color: #fff;
493
+ box-shadow: 0 1px 2px rgba(0,0,0,0.3);
494
+ }
495
+ .tab:hover:not(.active) { color: #bbb; }
496
+ .form { display: none; }
497
+ .form.active { display: block; }
498
+ label { display: block; font-size: 0.8125rem; color: #888; margin-bottom: 0.375rem; }
499
+ input {
500
+ width: 100%;
501
+ padding: 0.5rem 0.75rem;
502
+ background: transparent;
503
+ border: 1px solid rgba(255,255,255,0.12);
504
+ border-radius: 6px;
505
+ color: #e5e5e5;
506
+ font-size: 0.875rem;
507
+ outline: none;
508
+ margin-bottom: 0.875rem;
509
+ }
510
+ input:focus { border-color: rgba(255,255,255,0.3); box-shadow: 0 0 0 1px rgba(255,255,255,0.1); }
511
+ input::placeholder { color: #555; }
512
+ button[type="submit"] {
513
+ width: 100%;
514
+ margin-top: 0.25rem;
515
+ padding: 0.5rem;
516
+ background: #fff;
517
+ color: #000;
518
+ border: none;
519
+ border-radius: 6px;
520
+ font-size: 0.875rem;
521
+ font-weight: 500;
522
+ cursor: pointer;
523
+ }
524
+ button[type="submit"]:hover { background: #e5e5e5; }
525
+ button[type="submit"]:disabled { opacity: 0.5; cursor: not-allowed; }
526
+ .msg { margin-top: 0.75rem; font-size: 0.8125rem; display: none; }
527
+ .msg.error { color: #f87171; }
528
+ .msg.success { color: #4ade80; }
529
+ .msg.show { display: block; }
530
+ </style>
531
+ </head>
532
+ <body>
533
+ <div class="card">
534
+ <div class="tabs">
535
+ <button class="tab active" data-tab="login">Sign in</button>
536
+ <button class="tab" data-tab="register">Create account</button>
537
+ </div>
538
+ <form id="login-form" class="form active">
539
+ <label for="l-email">Email</label>
540
+ <input id="l-email" type="email" autocomplete="email" autofocus placeholder="you@example.com" required />
541
+ <label for="l-pass">Password</label>
542
+ <input id="l-pass" type="password" autocomplete="current-password" placeholder="Enter password" required />
543
+ <button type="submit">Sign in</button>
544
+ <p class="msg error" id="l-err"></p>
545
+ </form>
546
+ <form id="register-form" class="form">
547
+ <label for="r-email">Email</label>
548
+ <input id="r-email" type="email" autocomplete="email" placeholder="you@example.com" required />
549
+ <label for="r-pass">Password</label>
550
+ <input id="r-pass" type="password" autocomplete="new-password" placeholder="At least 8 characters" required minlength="8" />
551
+ <label for="r-pass2">Confirm password</label>
552
+ <input id="r-pass2" type="password" autocomplete="new-password" placeholder="Confirm password" required minlength="8" />
553
+ <button type="submit">Create account</button>
554
+ <p class="msg" id="r-msg"></p>
555
+ </form>
556
+ </div>
557
+ <script>
558
+ const tabs = document.querySelectorAll('.tab');
559
+ const forms = document.querySelectorAll('.form');
560
+ tabs.forEach(t => t.addEventListener('click', () => {
561
+ tabs.forEach(x => x.classList.remove('active'));
562
+ forms.forEach(x => x.classList.remove('active'));
563
+ t.classList.add('active');
564
+ document.getElementById(t.dataset.tab + '-form').classList.add('active');
565
+ }));
566
+
567
+ document.getElementById('login-form').addEventListener('submit', async (e) => {
568
+ e.preventDefault();
569
+ const err = document.getElementById('l-err');
570
+ err.classList.remove('show');
571
+ const res = await fetch('/_agent-native/auth/login', {
572
+ method: 'POST',
573
+ headers: { 'Content-Type': 'application/json' },
574
+ body: JSON.stringify({
575
+ email: document.getElementById('l-email').value,
576
+ password: document.getElementById('l-pass').value,
577
+ }),
578
+ });
579
+ if (res.ok) {
580
+ window.location.reload();
581
+ } else {
582
+ const data = await res.json().catch(() => ({}));
583
+ err.textContent = data.error || 'Invalid email or password';
584
+ err.classList.add('show');
585
+ }
586
+ });
587
+
588
+ document.getElementById('register-form').addEventListener('submit', async (e) => {
589
+ e.preventDefault();
590
+ const msg = document.getElementById('r-msg');
591
+ msg.classList.remove('show', 'error', 'success');
592
+ const pass = document.getElementById('r-pass').value;
593
+ const pass2 = document.getElementById('r-pass2').value;
594
+ if (pass !== pass2) {
595
+ msg.textContent = 'Passwords do not match';
596
+ msg.classList.add('show', 'error');
597
+ return;
598
+ }
599
+ const res = await fetch('/_agent-native/auth/register', {
600
+ method: 'POST',
601
+ headers: { 'Content-Type': 'application/json' },
602
+ body: JSON.stringify({
603
+ email: document.getElementById('r-email').value,
604
+ password: pass,
605
+ }),
606
+ });
607
+ const data = await res.json().catch(() => ({}));
608
+ if (res.ok) {
609
+ msg.textContent = 'Account created — signing you in...';
610
+ msg.classList.add('show', 'success');
611
+ // Auto-login after registration
612
+ const loginRes = await fetch('/_agent-native/auth/login', {
613
+ method: 'POST',
614
+ headers: { 'Content-Type': 'application/json' },
615
+ body: JSON.stringify({
616
+ email: document.getElementById('r-email').value,
617
+ password: pass,
618
+ }),
619
+ });
620
+ if (loginRes.ok) {
621
+ window.location.reload();
622
+ }
623
+ } else {
624
+ msg.textContent = data.error || 'Registration failed';
625
+ msg.classList.add('show', 'error');
626
+ }
627
+ });
628
+ </script>
629
+ </body>
630
+ </html>`;
631
+ // ---------------------------------------------------------------------------
632
+ // mountEmailAuthRoutes — email/password registration + login
633
+ // ---------------------------------------------------------------------------
634
+ function mountEmailAuthRoutes(app, publicPaths = []) {
635
+ // Also support ACCESS_TOKEN login for backward compat (API callers, scripts)
636
+ const accessTokens = getAccessTokens();
637
+ // POST /_agent-native/auth/register
638
+ app.use("/_agent-native/auth/register", defineEventHandler(async (event) => {
639
+ if (getMethod(event) !== "POST") {
640
+ setResponseStatus(event, 405);
641
+ return { error: "Method not allowed" };
642
+ }
643
+ const ip = getClientIp(event);
644
+ const limited = checkRateLimit(event, `register:${ip}`);
645
+ if (limited)
646
+ return limited;
647
+ const body = await readBody(event);
648
+ const email = body?.email?.trim?.()?.toLowerCase?.();
649
+ const password = body?.password;
650
+ if (!email || typeof email !== "string" || !email.includes("@")) {
651
+ setResponseStatus(event, 400);
652
+ return { error: "Valid email is required" };
653
+ }
654
+ if (!password || typeof password !== "string" || password.length < 8) {
655
+ setResponseStatus(event, 400);
656
+ return { error: "Password must be at least 8 characters" };
657
+ }
658
+ const result = await createUser(email, password);
659
+ if (!result.ok) {
660
+ setResponseStatus(event, 409);
661
+ return { error: result.error };
662
+ }
663
+ resetRateLimit(`register:${ip}`);
664
+ return { ok: true };
665
+ }));
666
+ // POST /_agent-native/auth/login — email/password or legacy ACCESS_TOKEN
667
+ app.use("/_agent-native/auth/login", defineEventHandler(async (event) => {
668
+ if (getMethod(event) !== "POST") {
669
+ setResponseStatus(event, 405);
670
+ return { error: "Method not allowed" };
671
+ }
672
+ const ip = getClientIp(event);
673
+ const rateLimitKey = `login:${ip}`;
674
+ const limited = checkRateLimit(event, rateLimitKey);
675
+ if (limited)
676
+ return limited;
677
+ const body = await readBody(event);
678
+ // Legacy: ACCESS_TOKEN login (for API callers, scripts)
679
+ if (body?.token &&
680
+ typeof body.token === "string" &&
681
+ accessTokens.length > 0) {
682
+ if (!safeTokenMatch(body.token, accessTokens)) {
683
+ setResponseStatus(event, 401);
684
+ return { error: "Invalid token" };
685
+ }
686
+ const sessionToken = crypto.randomBytes(32).toString("hex");
687
+ await addSession(sessionToken, "user");
688
+ setCookie(event, COOKIE_NAME, sessionToken, {
689
+ httpOnly: true,
690
+ secure: process.env.NODE_ENV === "production",
691
+ sameSite: "lax",
692
+ path: "/",
693
+ maxAge: sessionMaxAge,
694
+ });
695
+ resetRateLimit(rateLimitKey);
696
+ return { ok: true };
697
+ }
698
+ // Email/password login
699
+ const email = body?.email?.trim?.()?.toLowerCase?.();
700
+ const password = body?.password;
701
+ if (!email || !password) {
702
+ setResponseStatus(event, 400);
703
+ return { error: "Email and password are required" };
704
+ }
705
+ const valid = await authenticateUser(email, password);
706
+ if (!valid) {
707
+ setResponseStatus(event, 401);
708
+ return { error: "Invalid email or password" };
709
+ }
710
+ const sessionToken = crypto.randomBytes(32).toString("hex");
711
+ await addSession(sessionToken, email);
712
+ setCookie(event, COOKIE_NAME, sessionToken, {
713
+ httpOnly: true,
714
+ secure: process.env.NODE_ENV === "production",
715
+ sameSite: "lax",
716
+ path: "/",
717
+ maxAge: sessionMaxAge,
718
+ });
719
+ resetRateLimit(rateLimitKey);
720
+ return { ok: true };
721
+ }));
722
+ // POST /_agent-native/auth/logout
723
+ app.use("/_agent-native/auth/logout", defineEventHandler(async (event) => {
724
+ const cookie = getCookie(event, COOKIE_NAME);
725
+ if (cookie)
726
+ await removeSession(cookie);
727
+ deleteCookie(event, COOKIE_NAME, { path: "/" });
728
+ return { ok: true };
729
+ }));
730
+ // GET /_agent-native/auth/session
731
+ app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
732
+ if (getMethod(event) !== "GET") {
733
+ setResponseStatus(event, 405);
734
+ return { error: "Method not allowed" };
735
+ }
736
+ const session = await getSession(event);
737
+ return session ?? { error: "Not authenticated" };
738
+ }));
739
+ // Auth guard
740
+ const loginHtml = EMAIL_AUTH_HTML;
741
+ app.use(defineEventHandler(async (event) => {
742
+ const url = event.node?.req?.url ?? event.path ?? "/";
743
+ const p = url.split("?")[0];
744
+ if (p === "/_agent-native/auth/login" ||
745
+ p === "/_agent-native/auth/logout" ||
746
+ p === "/_agent-native/auth/session" ||
747
+ p === "/_agent-native/auth/register") {
748
+ return;
749
+ }
750
+ if (isPublicPath(url, publicPaths))
751
+ return;
752
+ const session = await getSession(event);
753
+ if (session)
754
+ return;
755
+ if (p.startsWith("/api/") || p.startsWith("/_agent-native/")) {
756
+ setResponseStatus(event, 401);
757
+ return { error: "Unauthorized" };
758
+ }
759
+ setResponseStatus(event, 200);
760
+ setResponseHeader(event, "Content-Type", "text/html");
761
+ return loginHtml;
762
+ }));
763
+ }
764
+ // ---------------------------------------------------------------------------
305
765
  // mountAuthMiddleware — mounts login/logout/session routes + auth guard
306
766
  // ---------------------------------------------------------------------------
307
767
  /**
@@ -319,12 +779,17 @@ function isPublicPath(url, publicPaths) {
319
779
  return publicPaths.some((pp) => p === pp || p.startsWith(pp + "/"));
320
780
  }
321
781
  function mountAuthRoutes(app, accessTokens, publicPaths = []) {
322
- // POST /api/auth/login
323
- app.use("/api/auth/login", defineEventHandler(async (event) => {
782
+ // POST /_agent-native/auth/login
783
+ app.use("/_agent-native/auth/login", defineEventHandler(async (event) => {
324
784
  if (getMethod(event) !== "POST") {
325
785
  setResponseStatus(event, 405);
326
786
  return { error: "Method not allowed" };
327
787
  }
788
+ const ip = getClientIp(event);
789
+ const rateLimitKey = `login:${ip}`;
790
+ const limited = checkRateLimit(event, rateLimitKey);
791
+ if (limited)
792
+ return limited;
328
793
  const body = await readBody(event);
329
794
  if (!body?.token ||
330
795
  typeof body.token !== "string" ||
@@ -333,26 +798,27 @@ function mountAuthRoutes(app, accessTokens, publicPaths = []) {
333
798
  return { error: "Invalid token" };
334
799
  }
335
800
  const sessionToken = crypto.randomBytes(32).toString("hex");
336
- await addSession(sessionToken);
801
+ await addSession(sessionToken, "user");
337
802
  setCookie(event, COOKIE_NAME, sessionToken, {
338
803
  httpOnly: true,
339
- secure: true,
804
+ secure: process.env.NODE_ENV === "production",
340
805
  sameSite: "lax",
341
806
  path: "/",
342
807
  maxAge: sessionMaxAge,
343
808
  });
809
+ resetRateLimit(rateLimitKey);
344
810
  return { ok: true };
345
811
  }));
346
- // POST /api/auth/logout
347
- app.use("/api/auth/logout", defineEventHandler(async (event) => {
812
+ // POST /_agent-native/auth/logout
813
+ app.use("/_agent-native/auth/logout", defineEventHandler(async (event) => {
348
814
  const cookie = getCookie(event, COOKIE_NAME);
349
815
  if (cookie)
350
816
  await removeSession(cookie);
351
817
  deleteCookie(event, COOKIE_NAME, { path: "/" });
352
818
  return { ok: true };
353
819
  }));
354
- // GET /api/auth/session — client session check
355
- app.use("/api/auth/session", defineEventHandler(async (event) => {
820
+ // GET /_agent-native/auth/session — client session check
821
+ app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
356
822
  if (getMethod(event) !== "GET") {
357
823
  setResponseStatus(event, 405);
358
824
  return { error: "Method not allowed" };
@@ -365,9 +831,9 @@ function mountAuthRoutes(app, accessTokens, publicPaths = []) {
365
831
  const url = event.node?.req?.url ?? event.path ?? "/";
366
832
  const p = url.split("?")[0];
367
833
  // Skip auth routes
368
- if (p === "/api/auth/login" ||
369
- p === "/api/auth/logout" ||
370
- p === "/api/auth/session") {
834
+ if (p === "/_agent-native/auth/login" ||
835
+ p === "/_agent-native/auth/logout" ||
836
+ p === "/_agent-native/auth/session") {
371
837
  return;
372
838
  }
373
839
  // Skip public paths
@@ -380,7 +846,7 @@ function mountAuthRoutes(app, accessTokens, publicPaths = []) {
380
846
  return; // Authenticated
381
847
  }
382
848
  // Unauthenticated
383
- if (p.startsWith("/api/")) {
849
+ if (p.startsWith("/api/") || p.startsWith("/_agent-native/")) {
384
850
  setResponseStatus(event, 401);
385
851
  return { error: "Unauthorized" };
386
852
  }
@@ -431,23 +897,23 @@ export function autoMountAuth(app, options = {}) {
431
897
  }
432
898
  // Dev mode — skip auth entirely
433
899
  if (isDevMode()) {
434
- // Mount a session endpoint that returns the dev stub
435
- app.use("/api/auth/session", defineEventHandler(async (event) => {
900
+ // Mount a session endpoint that checks for a real session first
901
+ app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
436
902
  if (getMethod(event) !== "GET") {
437
903
  setResponseStatus(event, 405);
438
904
  return { error: "Method not allowed" };
439
905
  }
440
- return DEV_SESSION;
906
+ return await getSession(event);
441
907
  }));
442
908
  // Mount no-op login/logout so client code doesn't break
443
- app.use("/api/auth/login", defineEventHandler(() => ({ ok: true })));
444
- app.use("/api/auth/logout", defineEventHandler(() => ({ ok: true })));
909
+ app.use("/_agent-native/auth/login", defineEventHandler(() => ({ ok: true })));
910
+ app.use("/_agent-native/auth/logout", defineEventHandler(() => ({ ok: true })));
445
911
  return false;
446
912
  }
447
913
  // BYOA with custom getSession — skip token check, mount session/guard routes
448
914
  if (customGetSession) {
449
915
  // Mount session endpoint
450
- app.use("/api/auth/session", defineEventHandler(async (event) => {
916
+ app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
451
917
  if (getMethod(event) !== "GET") {
452
918
  setResponseStatus(event, 405);
453
919
  return { error: "Method not allowed" };
@@ -455,8 +921,8 @@ export function autoMountAuth(app, options = {}) {
455
921
  const session = await getSession(event);
456
922
  return session ?? { error: "Not authenticated" };
457
923
  }));
458
- app.use("/api/auth/login", defineEventHandler(() => ({ ok: true })));
459
- app.use("/api/auth/logout", defineEventHandler(async (event) => {
924
+ app.use("/_agent-native/auth/login", defineEventHandler(() => ({ ok: true })));
925
+ app.use("/_agent-native/auth/logout", defineEventHandler(async (event) => {
460
926
  const cookie = getCookie(event, COOKIE_NAME);
461
927
  if (cookie)
462
928
  await removeSession(cookie);
@@ -469,9 +935,9 @@ export function autoMountAuth(app, options = {}) {
469
935
  // Use H3's getRequestURL for cross-platform compat (Node + Workers)
470
936
  const url = event.node?.req?.url ?? event.path ?? "/";
471
937
  const p = url.split("?")[0];
472
- if (p === "/api/auth/login" ||
473
- p === "/api/auth/logout" ||
474
- p === "/api/auth/session") {
938
+ if (p === "/_agent-native/auth/login" ||
939
+ p === "/_agent-native/auth/logout" ||
940
+ p === "/_agent-native/auth/session") {
475
941
  return;
476
942
  }
477
943
  // Skip public paths
@@ -481,7 +947,7 @@ export function autoMountAuth(app, options = {}) {
481
947
  const session = await getSession(event);
482
948
  if (session)
483
949
  return;
484
- if (p.startsWith("/api/")) {
950
+ if (p.startsWith("/api/") || p.startsWith("/_agent-native/")) {
485
951
  setResponseStatus(event, 401);
486
952
  return { error: "Unauthorized" };
487
953
  }
@@ -500,30 +966,23 @@ export function autoMountAuth(app, options = {}) {
500
966
  authDisabledMode = true;
501
967
  console.warn("[agent-native] AUTH_DISABLED=true — running in production without auth. " +
502
968
  "Ensure this app is behind infrastructure-level auth (Cloudflare Access, VPN, etc.).");
503
- // Mount session endpoint — getSession() will return DEV_SESSION
504
- app.use("/api/auth/session", defineEventHandler(async (event) => {
969
+ // Mount session endpoint
970
+ app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
505
971
  if (getMethod(event) !== "GET") {
506
972
  setResponseStatus(event, 405);
507
973
  return { error: "Method not allowed" };
508
974
  }
509
- return DEV_SESSION;
975
+ return await getSession(event);
510
976
  }));
511
- app.use("/api/auth/login", defineEventHandler(() => ({ ok: true })));
512
- app.use("/api/auth/logout", defineEventHandler(() => ({ ok: true })));
977
+ app.use("/_agent-native/auth/login", defineEventHandler(() => ({ ok: true })));
978
+ app.use("/_agent-native/auth/logout", defineEventHandler(() => ({ ok: true })));
513
979
  return false;
514
980
  }
515
- // Refuse to start without auth in production
516
- const msg = "\n" +
517
- "=".repeat(70) +
518
- "\n" +
519
- " ERROR: Running in production without authentication.\n\n" +
520
- " Set ACCESS_TOKEN=<your-secret> to enable auth, or\n" +
521
- " set AUTH_DISABLED=true if this app is behind infrastructure auth.\n\n" +
522
- " For multi-user access: ACCESS_TOKENS=token1,token2,token3\n" +
523
- "=".repeat(70) +
524
- "\n";
525
- console.error(msg);
526
- process.exit(1);
981
+ // No access tokens set enable email/password authentication
982
+ pruneExpiredSessions().catch(() => { });
983
+ mountEmailAuthRoutes(app, publicPaths);
984
+ console.log("[agent-native] Auth enabled — email/password authentication.");
985
+ return true;
527
986
  }
528
987
  // Production with tokens — mount auth
529
988
  pruneExpiredSessions().catch(() => { });