aimeat 2.5.0 → 2.6.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 (256) hide show
  1. package/dist/.env.example +33 -0
  2. package/dist/build-stamp.json +13 -0
  3. package/dist/locales/en.json +166 -3
  4. package/dist/locales/fi.json +166 -3
  5. package/dist/public/components/VoiceRecorder.js +116 -0
  6. package/dist/public/connection-done.html +53 -0
  7. package/dist/public/css/components/voice-recorder.css +66 -0
  8. package/dist/public/css/views/inbox.css +41 -0
  9. package/dist/public/css/views/profile.css +171 -95
  10. package/dist/public/js/services/audio-recorder.js +171 -0
  11. package/dist/public/js/services/messages.js +21 -2
  12. package/dist/public/spa.html +3 -0
  13. package/dist/public/views/profile/access-tab/connections.js +264 -0
  14. package/dist/public/views/profile/access-tab.js +2 -0
  15. package/dist/public/views/profile/inbox-tab/components.js +60 -10
  16. package/dist/public/views/profile/inbox-tab/helpers.js +33 -0
  17. package/dist/public/views/profile/inbox-tab/panels.js +6 -1
  18. package/dist/public/views/profile/inbox-tab/use-voice.js +50 -0
  19. package/dist/public/views/profile/inbox-tab/voice-parts.js +111 -0
  20. package/dist/public/views/profile/inbox-tab.js +18 -24
  21. package/dist/public/views/profile/openrouter/budget-panel.js +224 -0
  22. package/dist/public/views/profile/openrouter/model-picker.js +150 -0
  23. package/dist/public/views/profile/openrouter/pricing.js +139 -0
  24. package/dist/public/views/profile/openrouter-settings.js +425 -488
  25. package/dist/scripts/build-sdk-libs.d.ts.map +1 -1
  26. package/dist/scripts/build-sdk-libs.js +1 -0
  27. package/dist/scripts/build-sdk-libs.js.map +1 -1
  28. package/dist/scripts/check-ai-disclosure.d.ts.map +1 -1
  29. package/dist/scripts/check-ai-disclosure.js +65 -0
  30. package/dist/scripts/check-ai-disclosure.js.map +1 -1
  31. package/dist/src/cli/connect/ai-provenance-carry.d.ts +54 -3
  32. package/dist/src/cli/connect/ai-provenance-carry.d.ts.map +1 -1
  33. package/dist/src/cli/connect/ai-provenance-carry.js +84 -12
  34. package/dist/src/cli/connect/ai-provenance-carry.js.map +1 -1
  35. package/dist/src/cli/connect/api-client.d.ts +11 -0
  36. package/dist/src/cli/connect/api-client.d.ts.map +1 -1
  37. package/dist/src/cli/connect/api-client.js +2 -0
  38. package/dist/src/cli/connect/api-client.js.map +1 -1
  39. package/dist/src/cli/connect/mcp/local-server.d.ts.map +1 -1
  40. package/dist/src/cli/connect/mcp/local-server.js +11 -0
  41. package/dist/src/cli/connect/mcp/local-server.js.map +1 -1
  42. package/dist/src/cli/connect/mcp/tools/apps.d.ts +1 -0
  43. package/dist/src/cli/connect/mcp/tools/apps.d.ts.map +1 -1
  44. package/dist/src/cli/connect/mcp/tools/apps.js +3 -2
  45. package/dist/src/cli/connect/mcp/tools/apps.js.map +1 -1
  46. package/dist/src/cli/connect/mcp/tools/core.d.ts +2 -0
  47. package/dist/src/cli/connect/mcp/tools/core.d.ts.map +1 -1
  48. package/dist/src/cli/connect/mcp/tools/core.js +5 -2
  49. package/dist/src/cli/connect/mcp/tools/core.js.map +1 -1
  50. package/dist/src/cli/connect/mcp/tools/knowledge.d.ts +1 -0
  51. package/dist/src/cli/connect/mcp/tools/knowledge.d.ts.map +1 -1
  52. package/dist/src/cli/connect/mcp/tools/knowledge.js +3 -2
  53. package/dist/src/cli/connect/mcp/tools/knowledge.js.map +1 -1
  54. package/dist/src/config-types.d.ts +14 -0
  55. package/dist/src/config-types.d.ts.map +1 -1
  56. package/dist/src/config.d.ts.map +1 -1
  57. package/dist/src/config.js +10 -0
  58. package/dist/src/config.js.map +1 -1
  59. package/dist/src/generated/api-types.d.ts +969 -4
  60. package/dist/src/generated/api-types.d.ts.map +1 -1
  61. package/dist/src/mcp/ai-provenance-input.d.ts +33 -0
  62. package/dist/src/mcp/ai-provenance-input.d.ts.map +1 -1
  63. package/dist/src/mcp/ai-provenance-input.js +36 -0
  64. package/dist/src/mcp/ai-provenance-input.js.map +1 -1
  65. package/dist/src/mcp/apps.d.ts +7 -0
  66. package/dist/src/mcp/apps.d.ts.map +1 -1
  67. package/dist/src/mcp/apps.js +20 -2
  68. package/dist/src/mcp/apps.js.map +1 -1
  69. package/dist/src/models/ai-provenance-schemas.d.ts +7 -1
  70. package/dist/src/models/ai-provenance-schemas.d.ts.map +1 -1
  71. package/dist/src/models/ai-provenance-schemas.js +11 -1
  72. package/dist/src/models/ai-provenance-schemas.js.map +1 -1
  73. package/dist/src/models/connection-schemas.d.ts +203 -0
  74. package/dist/src/models/connection-schemas.d.ts.map +1 -0
  75. package/dist/src/models/connection-schemas.js +33 -0
  76. package/dist/src/models/connection-schemas.js.map +1 -0
  77. package/dist/src/models/message-schemas.d.ts +40 -0
  78. package/dist/src/models/message-schemas.d.ts.map +1 -1
  79. package/dist/src/models/message-schemas.js +23 -0
  80. package/dist/src/models/message-schemas.js.map +1 -1
  81. package/dist/src/routes/ai-provenance.d.ts +6 -0
  82. package/dist/src/routes/ai-provenance.d.ts.map +1 -1
  83. package/dist/src/routes/ai-provenance.js +34 -1
  84. package/dist/src/routes/ai-provenance.js.map +1 -1
  85. package/dist/src/routes/ai.d.ts +5 -0
  86. package/dist/src/routes/ai.d.ts.map +1 -1
  87. package/dist/src/routes/ai.js +83 -0
  88. package/dist/src/routes/ai.js.map +1 -1
  89. package/dist/src/routes/app-grants.d.ts.map +1 -1
  90. package/dist/src/routes/app-grants.js +4 -0
  91. package/dist/src/routes/app-grants.js.map +1 -1
  92. package/dist/src/routes/apps/drafts.d.ts +3 -0
  93. package/dist/src/routes/apps/drafts.d.ts.map +1 -1
  94. package/dist/src/routes/apps/drafts.js +13 -0
  95. package/dist/src/routes/apps/drafts.js.map +1 -1
  96. package/dist/src/routes/apps/publish.d.ts +5 -0
  97. package/dist/src/routes/apps/publish.d.ts.map +1 -1
  98. package/dist/src/routes/apps/publish.js +21 -5
  99. package/dist/src/routes/apps/publish.js.map +1 -1
  100. package/dist/src/routes/connections.d.ts +35 -0
  101. package/dist/src/routes/connections.d.ts.map +1 -0
  102. package/dist/src/routes/connections.js +406 -0
  103. package/dist/src/routes/connections.js.map +1 -0
  104. package/dist/src/routes/libs.js +1 -1
  105. package/dist/src/routes/libs.js.map +1 -1
  106. package/dist/src/routes/messages.d.ts +5 -0
  107. package/dist/src/routes/messages.d.ts.map +1 -1
  108. package/dist/src/routes/messages.js +92 -0
  109. package/dist/src/routes/messages.js.map +1 -1
  110. package/dist/src/routes/openrouter.d.ts +6 -1
  111. package/dist/src/routes/openrouter.d.ts.map +1 -1
  112. package/dist/src/routes/openrouter.js +37 -7
  113. package/dist/src/routes/openrouter.js.map +1 -1
  114. package/dist/src/routes/upload.d.ts +5 -0
  115. package/dist/src/routes/upload.d.ts.map +1 -1
  116. package/dist/src/routes/upload.js +32 -0
  117. package/dist/src/routes/upload.js.map +1 -1
  118. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
  119. package/dist/src/server-bootstrap/routes-loader.js +2 -0
  120. package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
  121. package/dist/src/services/ai-completion.d.ts +48 -0
  122. package/dist/src/services/ai-completion.d.ts.map +1 -1
  123. package/dist/src/services/ai-completion.js +112 -72
  124. package/dist/src/services/ai-completion.js.map +1 -1
  125. package/dist/src/services/ai-disclosure.d.ts +6 -0
  126. package/dist/src/services/ai-disclosure.d.ts.map +1 -1
  127. package/dist/src/services/ai-disclosure.js +20 -2
  128. package/dist/src/services/ai-disclosure.js.map +1 -1
  129. package/dist/src/services/ai-provenance-page.d.ts +59 -0
  130. package/dist/src/services/ai-provenance-page.d.ts.map +1 -0
  131. package/dist/src/services/ai-provenance-page.js +185 -0
  132. package/dist/src/services/ai-provenance-page.js.map +1 -0
  133. package/dist/src/services/ai-provenance.d.ts +6 -0
  134. package/dist/src/services/ai-provenance.d.ts.map +1 -1
  135. package/dist/src/services/ai-provenance.js +5 -0
  136. package/dist/src/services/ai-provenance.js.map +1 -1
  137. package/dist/src/services/ai-transcription.d.ts +66 -0
  138. package/dist/src/services/ai-transcription.d.ts.map +1 -0
  139. package/dist/src/services/ai-transcription.js +90 -0
  140. package/dist/src/services/ai-transcription.js.map +1 -0
  141. package/dist/src/services/app-publish.d.ts.map +1 -1
  142. package/dist/src/services/app-publish.js +16 -1
  143. package/dist/src/services/app-publish.js.map +1 -1
  144. package/dist/src/services/build-app-prompt.d.ts.map +1 -1
  145. package/dist/src/services/build-app-prompt.js +2 -1
  146. package/dist/src/services/build-app-prompt.js.map +1 -1
  147. package/dist/src/services/connections/attach.d.ts +62 -0
  148. package/dist/src/services/connections/attach.d.ts.map +1 -0
  149. package/dist/src/services/connections/attach.js +168 -0
  150. package/dist/src/services/connections/attach.js.map +1 -0
  151. package/dist/src/services/connections/credential.d.ts +39 -0
  152. package/dist/src/services/connections/credential.d.ts.map +1 -0
  153. package/dist/src/services/connections/credential.js +66 -0
  154. package/dist/src/services/connections/credential.js.map +1 -0
  155. package/dist/src/services/connections/instance.d.ts +65 -0
  156. package/dist/src/services/connections/instance.d.ts.map +1 -0
  157. package/dist/src/services/connections/instance.js +144 -0
  158. package/dist/src/services/connections/instance.js.map +1 -0
  159. package/dist/src/services/connections/oauth.d.ts +77 -0
  160. package/dist/src/services/connections/oauth.d.ts.map +1 -0
  161. package/dist/src/services/connections/oauth.js +290 -0
  162. package/dist/src/services/connections/oauth.js.map +1 -0
  163. package/dist/src/services/connections/providers.d.ts +118 -0
  164. package/dist/src/services/connections/providers.d.ts.map +1 -0
  165. package/dist/src/services/connections/providers.js +260 -0
  166. package/dist/src/services/connections/providers.js.map +1 -0
  167. package/dist/src/services/connections/publish-gate.d.ts +103 -0
  168. package/dist/src/services/connections/publish-gate.d.ts.map +1 -0
  169. package/dist/src/services/connections/publish-gate.js +0 -0
  170. package/dist/src/services/connections/publish-gate.js.map +1 -0
  171. package/dist/src/services/connections/publish.d.ts +60 -0
  172. package/dist/src/services/connections/publish.d.ts.map +1 -0
  173. package/dist/src/services/connections/publish.js +340 -0
  174. package/dist/src/services/connections/publish.js.map +1 -0
  175. package/dist/src/services/connections/refresh.d.ts +55 -0
  176. package/dist/src/services/connections/refresh.d.ts.map +1 -0
  177. package/dist/src/services/connections/refresh.js +307 -0
  178. package/dist/src/services/connections/refresh.js.map +1 -0
  179. package/dist/src/services/message-send.d.ts.map +1 -1
  180. package/dist/src/services/message-send.js +16 -2
  181. package/dist/src/services/message-send.js.map +1 -1
  182. package/dist/src/services/openrouter.d.ts +67 -1
  183. package/dist/src/services/openrouter.d.ts.map +1 -1
  184. package/dist/src/services/openrouter.js +102 -11
  185. package/dist/src/services/openrouter.js.map +1 -1
  186. package/dist/src/services/upload-token.d.ts +5 -1
  187. package/dist/src/services/upload-token.d.ts.map +1 -1
  188. package/dist/src/services/upload-token.js +13 -1
  189. package/dist/src/services/upload-token.js.map +1 -1
  190. package/dist/src/services/workflow/engine-util.d.ts +18 -0
  191. package/dist/src/services/workflow/engine-util.d.ts.map +1 -1
  192. package/dist/src/services/workflow/engine-util.js +27 -0
  193. package/dist/src/services/workflow/engine-util.js.map +1 -1
  194. package/dist/src/services/workflow/engine.d.ts.map +1 -1
  195. package/dist/src/services/workflow/engine.js +4 -2
  196. package/dist/src/services/workflow/engine.js.map +1 -1
  197. package/dist/src/storage/interface.d.ts +2 -1
  198. package/dist/src/storage/interface.d.ts.map +1 -1
  199. package/dist/src/storage/providers/postgres-kysely/db-types.d.ts +65 -0
  200. package/dist/src/storage/providers/postgres-kysely/db-types.d.ts.map +1 -1
  201. package/dist/src/storage/providers/postgres-kysely/index.d.ts.map +1 -1
  202. package/dist/src/storage/providers/postgres-kysely/index.js +2 -1
  203. package/dist/src/storage/providers/postgres-kysely/index.js.map +1 -1
  204. package/dist/src/storage/providers/postgres-kysely/methods/connections.d.ts +44 -0
  205. package/dist/src/storage/providers/postgres-kysely/methods/connections.d.ts.map +1 -0
  206. package/dist/src/storage/providers/postgres-kysely/methods/connections.js +308 -0
  207. package/dist/src/storage/providers/postgres-kysely/methods/connections.js.map +1 -0
  208. package/dist/src/storage/providers/postgres-kysely/methods/node-infra.d.ts.map +1 -1
  209. package/dist/src/storage/providers/postgres-kysely/methods/node-infra.js +4 -2
  210. package/dist/src/storage/providers/postgres-kysely/methods/node-infra.js.map +1 -1
  211. package/dist/src/storage/providers/postgres-kysely/migrations/0021_connections.sql +116 -0
  212. package/dist/src/storage/providers/postgres-kysely/migrations/0022_provider_clients.sql +36 -0
  213. package/dist/src/storage/providers/postgres-kysely/migrations/0023_nonce_payload.sql +13 -0
  214. package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
  215. package/dist/src/storage/providers/sqlite/index.js +2 -1
  216. package/dist/src/storage/providers/sqlite/index.js.map +1 -1
  217. package/dist/src/storage/providers/sqlite/methods/community.d.ts.map +1 -1
  218. package/dist/src/storage/providers/sqlite/methods/community.js +2 -1
  219. package/dist/src/storage/providers/sqlite/methods/community.js.map +1 -1
  220. package/dist/src/storage/providers/sqlite/methods/connections.d.ts +60 -0
  221. package/dist/src/storage/providers/sqlite/methods/connections.d.ts.map +1 -0
  222. package/dist/src/storage/providers/sqlite/methods/connections.js +287 -0
  223. package/dist/src/storage/providers/sqlite/methods/connections.js.map +1 -0
  224. package/dist/src/storage/providers/sqlite/schema-tables-1.d.ts.map +1 -1
  225. package/dist/src/storage/providers/sqlite/schema-tables-1.js +4 -0
  226. package/dist/src/storage/providers/sqlite/schema-tables-1.js.map +1 -1
  227. package/dist/src/storage/providers/sqlite/schema-tables-3.d.ts.map +1 -1
  228. package/dist/src/storage/providers/sqlite/schema-tables-3.js +106 -0
  229. package/dist/src/storage/providers/sqlite/schema-tables-3.js.map +1 -1
  230. package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
  231. package/dist/src/storage/providers/sqlite/schema.js +2 -0
  232. package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
  233. package/dist/src/storage/repositories/connection.repository.d.ts +124 -0
  234. package/dist/src/storage/repositories/connection.repository.d.ts.map +1 -0
  235. package/dist/src/storage/repositories/connection.repository.js +2 -0
  236. package/dist/src/storage/repositories/connection.repository.js.map +1 -0
  237. package/dist/src/storage/types/agents-messaging.d.ts +19 -0
  238. package/dist/src/storage/types/agents-messaging.d.ts.map +1 -1
  239. package/dist/src/storage/types/agents-messaging.js.map +1 -1
  240. package/dist/src/storage/types/auth.d.ts +8 -1
  241. package/dist/src/storage/types/auth.d.ts.map +1 -1
  242. package/dist/src/utils/build-stamp.d.ts +56 -0
  243. package/dist/src/utils/build-stamp.d.ts.map +1 -0
  244. package/dist/src/utils/build-stamp.js +142 -0
  245. package/dist/src/utils/build-stamp.js.map +1 -0
  246. package/dist/src/utils/messaging.d.ts +14 -0
  247. package/dist/src/utils/messaging.d.ts.map +1 -1
  248. package/dist/src/utils/messaging.js +0 -0
  249. package/dist/src/utils/messaging.js.map +1 -1
  250. package/dist/static/sdk-libs/connect/index.js +199 -0
  251. package/dist/static/sdk-libs/connect/notes.js +47 -0
  252. package/dist/static/sdk-libs/connect/panel.js +238 -0
  253. package/dist/static/sdk-libs/data/index.js +63 -11
  254. package/dist/static/sdk-libs/dist/aimeat-connect.js +357 -0
  255. package/dist/static/sdk-libs/dist/aimeat-data.js +40 -9
  256. package/package.json +2 -2
@@ -7,8 +7,9 @@
7
7
  * that actually CONSUMES the shared config: `NODE_URL` (direct public/micro fetches) and `NODE_ID`
8
8
  * (the `creator@node` construction in get()'s fallback) come from _core/config — the exact values
9
9
  * the legacy string form baked in via `${config.baseUrl}` / `${config.nodeId}`.
10
- * @structure imports NODE_URL/NODE_ID (config), authFetch (session), attach (namespace); data.set/
11
- * get/getEntry/update/delete/list/search/getPublic; data.micro()/microSets(); attach('data', …).
10
+ * @structure imports NODE_URL/NODE_ID (config), authFetch (session), attach (namespace);
11
+ * withProvenance()/publicEntryResponse(); data.set/get/getEntry/update/delete/list/search/
12
+ * getPublic/getPublicEntry; data.micro()/microSets(); attach('data', …).
12
13
  * @usage <script src="/v1/libs/aimeat-auth.js"></script><script src="/v1/libs/aimeat-data.js"></script>
13
14
  * await AIMEAT.data.set('key', { value }); await AIMEAT.data.get('key');
14
15
  * @version-history
@@ -19,6 +20,12 @@
19
20
  * library entirely to read their own owner's fleet output. All options are additive.
20
21
  * v1.2.0 — 2026-07-29 — delete() takes { ownerScope } like the reads. list({ ownerScope }) already
21
22
  * returned agent-written keys, so an app could render a record and then 404 trying to remove it.
23
+ * v1.3.0 — 2026-08-01 — TARGET-058: AI provenance survives the READ. getEntry() folds in the
24
+ * envelope's `meta.provenance`, and getPublicEntry() is the public sibling that does the same —
25
+ * getPublic() keeps returning the bare value, because every published app depends on that.
26
+ * Until now every read path here ended in `res.data`, so an app could render model-written
27
+ * content with no way to state its origin no matter how carefully the writing agent declared
28
+ * it. Same loss the connector had (ai-provenance-carry.ts v1.1.0); the browser had it too.
22
29
  */
23
30
  import { NODE_URL, NODE_ID } from '../_core/config.js';
24
31
  import { makeSession } from '../_core/session.js';
@@ -37,6 +44,33 @@ import { attach } from '../_core/namespace.js';
37
44
  * @param {{agent?: string, ownerScope?: boolean}} [opts]
38
45
  * @returns {URLSearchParams}
39
46
  */
47
+ /**
48
+ * Fold the envelope's `meta.provenance` onto the entry the caller gets back.
49
+ *
50
+ * The node puts it on `meta` rather than in `data` on purpose: provenance DESCRIBES the content
51
+ * instead of being part of it, and `data` shapes are what published apps read. That decision is
52
+ * right, and it is also exactly why every `return res.data` in a client library silently drops it.
53
+ * One helper, so a read path added later cannot lose it again.
54
+ *
55
+ * @param {{data: any, meta?: {provenance?: any}}} res
56
+ */
57
+ function withProvenance(res) {
58
+ const prov = res.meta?.provenance;
59
+ return prov ? { ...res.data, provenance: prov } : res.data;
60
+ }
61
+
62
+ /** The public (unauthenticated) memory read, shared by getPublic + getPublicEntry. */
63
+ async function publicEntryResponse(gaii, key) {
64
+ const url = NODE_URL + '/v1/memory/' + encodeURIComponent(gaii) + '/' + encodeURIComponent(key) + '?soft=1';
65
+ const r = await fetch(url);
66
+ const res = await r.json();
67
+ if (!res.ok) {
68
+ if (res.error?.code === 'NOT_FOUND') return null;
69
+ throw new Error(res.error?.message || 'Failed to read public memory');
70
+ }
71
+ return res;
72
+ }
73
+
40
74
  function scopeParams(opts) {
41
75
  const p = new URLSearchParams();
42
76
  if (opts?.agent) p.set('agent', opts.agent);
@@ -97,6 +131,7 @@ const data = {
97
131
  },
98
132
 
99
133
  // Read full entry metadata. opts: { agent, ownerScope } as in get().
134
+ // `provenance` is folded in from the envelope's `meta` — see withProvenance().
100
135
  async getEntry(key, opts) {
101
136
  const res = await authFetch(withParams(
102
137
  '/v1/memory/' + encodeURIComponent(key), scopeParams(opts)));
@@ -104,7 +139,7 @@ const data = {
104
139
  if (res.error?.code === 'NOT_FOUND') return null;
105
140
  throw new Error(res.error?.message || 'Failed to get memory');
106
141
  }
107
- return res.data;
142
+ return withProvenance(res);
108
143
  },
109
144
 
110
145
  // Update with optimistic locking
@@ -180,15 +215,32 @@ const data = {
180
215
 
181
216
  // Read another agent's public memory (no auth needed). ?soft=1: missing (or hidden)
182
217
  // keys resolve null via a clean 200 instead of logging a console 404.
218
+ //
219
+ // Returns the VALUE, deliberately unchanged: every published app reading this library expects
220
+ // the bare value here, so widening the return type would break them all. To see how the value
221
+ // was made, use getPublicEntry() below.
183
222
  async getPublic(gaii, key) {
184
- const url = NODE_URL + '/v1/memory/' + encodeURIComponent(gaii) + '/' + encodeURIComponent(key) + '?soft=1';
185
- const r = await fetch(url);
186
- const res = await r.json();
187
- if (!res.ok) {
188
- if (res.error?.code === 'NOT_FOUND') return null;
189
- throw new Error(res.error?.message || 'Failed to read public memory');
190
- }
191
- return res.data.value;
223
+ const res = await publicEntryResponse(gaii, key);
224
+ return res === null ? null : res.data.value;
225
+ },
226
+
227
+ /**
228
+ * The same public read, as a full entry: `{ key, value, visibility, version, …, provenance }`.
229
+ *
230
+ * WHY THIS EXISTS. The node serves an item's AI provenance on the envelope's `meta`, and
231
+ * getPublic() returns `res.data.value` — so the statement about how the content was made was
232
+ * being thrown away at the last hop, on the one read path published apps actually use. An app
233
+ * could render a model-written article and have no way to say so, however carefully the writing
234
+ * agent had declared it. This is the same READ-DIRECTION loss that had to be fixed in the
235
+ * connector (ai-provenance-carry.ts v1.1.0, "read_provenance() never returns anything"); the
236
+ * browser library had it too.
237
+ *
238
+ * `provenance` is `{ id, record, record_url }` or undefined when the node holds no record for
239
+ * the item. Undefined means UNSTATED, and never "a person wrote it".
240
+ */
241
+ async getPublicEntry(gaii, key) {
242
+ const res = await publicEntryResponse(gaii, key);
243
+ return res === null ? null : withProvenance(res);
192
244
  },
193
245
 
194
246
  // ── Micro-Memory (Tier 0.5, GET-based) ──
@@ -0,0 +1,357 @@
1
+ // GENERATED FILE — do not edit directly. Source: src/static/sdk-libs/connect/ (+ _core/).
2
+ // Rebuild: pnpm build:sdk · Served at /v1/libs/aimeat-connect.js (with a per-node config prelude).
3
+ "use strict";
4
+ (() => {
5
+ // src/static/sdk-libs/_core/session.js
6
+ function getSession(libLabel) {
7
+ const auth = window.AIMEAT && window.AIMEAT.auth;
8
+ if (!auth) {
9
+ throw new Error("AIMEAT.auth is required. Include aimeat-auth.js before " + (libLabel || "this library"));
10
+ }
11
+ const s = auth.getSession();
12
+ if (!s) throw new Error("Not logged in. Call AIMEAT.auth.login() first.");
13
+ return s;
14
+ }
15
+ function authFetch(path, opts, libLabel) {
16
+ return getSession(libLabel).fetch(path, opts);
17
+ }
18
+ function makeSession(libLabel) {
19
+ return {
20
+ getSession: () => getSession(libLabel),
21
+ authFetch: (path, opts) => authFetch(path, opts, libLabel)
22
+ };
23
+ }
24
+
25
+ // src/static/sdk-libs/_core/namespace.js
26
+ function namespace() {
27
+ if (!window.AIMEAT) window.AIMEAT = {};
28
+ return window.AIMEAT;
29
+ }
30
+ function attach(key, value) {
31
+ const ns = namespace();
32
+ ns[key] = value;
33
+ return ns;
34
+ }
35
+
36
+ // src/static/sdk-libs/connect/panel.js
37
+ var STYLE_ID = "aimeat-connect-style";
38
+ function el(tag, opts, children) {
39
+ const node = document.createElement(tag);
40
+ const o = opts || {};
41
+ if (o.cls) node.className = o.cls;
42
+ if (o.text != null) node.textContent = o.text;
43
+ if (o.attrs) for (const k of Object.keys(o.attrs)) node.setAttribute(k, o.attrs[k]);
44
+ if (o.on) for (const k of Object.keys(o.on)) node.addEventListener(k, o.on[k]);
45
+ for (const c of children || []) if (c) node.appendChild(c);
46
+ return node;
47
+ }
48
+ function injectStyle() {
49
+ if (document.getElementById(STYLE_ID)) return;
50
+ const css = `
51
+ .aim-conn { font: inherit; color: inherit; }
52
+ .aim-conn-list { display: flex; flex-direction: column; gap: .5rem; margin: .75rem 0; }
53
+ .aim-conn-row { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem;
54
+ padding: .6rem .75rem; border: 1px solid currentColor; border-radius: .5rem; opacity: .95; }
55
+ .aim-conn-main { display: flex; flex-direction: column; min-width: 0; flex: 1 1 12rem; }
56
+ .aim-conn-label { font-weight: 600; overflow-wrap: anywhere; }
57
+ .aim-conn-meta { font-size: .85em; opacity: .7; }
58
+ .aim-conn-actions { display: flex; gap: .5rem; flex-wrap: wrap; }
59
+ .aim-conn-btn { font: inherit; color: inherit; background: transparent; cursor: pointer;
60
+ border: 1px solid currentColor; border-radius: .4rem; padding: .35rem .7rem; }
61
+ .aim-conn-btn[disabled] { opacity: .5; cursor: default; }
62
+ .aim-conn-note { font-size: .85em; opacity: .75; margin: .35rem 0 0; }
63
+ .aim-conn-empty { opacity: .7; margin: .75rem 0; }
64
+ .aim-conn-add { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin-top: .75rem; }
65
+ .aim-conn-input { font: inherit; color: inherit; background: transparent; padding: .35rem .5rem;
66
+ border: 1px solid currentColor; border-radius: .4rem; min-width: 0; flex: 1 1 12rem; }
67
+ .aim-conn-err { font-size: .9em; margin: .5rem 0 0; }
68
+ `;
69
+ const style = document.createElement("style");
70
+ style.id = STYLE_ID;
71
+ style.textContent = css;
72
+ document.head.appendChild(style);
73
+ }
74
+ var DEFAULT_STRINGS = {
75
+ title: "Connected accounts",
76
+ intro: "Accounts you have connected so apps can act at those services on your behalf. The account credential stays on this node; an app is only ever told which account it may use.",
77
+ empty: "You have not connected any accounts yet.",
78
+ add: "Connect",
79
+ connecting: "Connecting…",
80
+ disconnect: "Disconnect",
81
+ reconnect: "Reconnect",
82
+ needsReauth: "needs reconnecting",
83
+ instancePlaceholder: "instance address, e.g. mastodon.social",
84
+ confirm: "Disconnect this account? Apps that publish to it will stop being able to.",
85
+ toldProvider: "Disconnected, and the service was told.",
86
+ notToldProvider: "Disconnected here. The service could not be reached to be told, so check it there too.",
87
+ unavailable: "Connecting accounts is not enabled on this node."
88
+ };
89
+ async function mountConnectPanel(connect2, opts = {}) {
90
+ const host = typeof opts.target === "string" ? document.querySelector(opts.target) : opts.target;
91
+ if (!host) throw new Error("aimeat-connect: panel target not found");
92
+ if (opts.styles !== false) injectStyle();
93
+ const s = { ...DEFAULT_STRINGS, ...opts.strings || {} };
94
+ const root = el("div", { cls: "aim-conn" });
95
+ host.replaceChildren(root);
96
+ let providers2 = [];
97
+ let busy = false;
98
+ async function render() {
99
+ let accounts;
100
+ try {
101
+ [accounts, providers2] = await Promise.all([connect2.list(), connect2.providers()]);
102
+ } catch (err) {
103
+ root.replaceChildren(el("p", { cls: "aim-conn-err", text: `${s.unavailable} (${err && err.message || err})` }));
104
+ return;
105
+ }
106
+ const rows = accounts.map((c) => {
107
+ const needsReauth = c.status === "needs_reauth";
108
+ return el("div", { cls: "aim-conn-row" }, [
109
+ el("div", { cls: "aim-conn-main" }, [
110
+ el("span", { cls: "aim-conn-label", text: c.accountLabel }),
111
+ el("span", {
112
+ cls: "aim-conn-meta",
113
+ text: needsReauth ? `${c.provider} · ${s.needsReauth}` : c.provider
114
+ })
115
+ ]),
116
+ el("div", { cls: "aim-conn-actions" }, [
117
+ // Shown as a FIX, not as an error. Two clicks and it works again.
118
+ needsReauth ? el("button", {
119
+ cls: "aim-conn-btn",
120
+ text: s.reconnect,
121
+ attrs: { type: "button" },
122
+ on: { click: () => void beginConnect(c.provider, null) }
123
+ }) : null,
124
+ el("button", {
125
+ cls: "aim-conn-btn",
126
+ text: s.disconnect,
127
+ attrs: { type: "button" },
128
+ on: {
129
+ click: () => {
130
+ if (!window.confirm(s.confirm)) return;
131
+ void (async () => {
132
+ const r = await connect2.revoke(c.id);
133
+ await render();
134
+ window.alert(r.toldProvider ? s.toldProvider : s.notToldProvider);
135
+ })();
136
+ }
137
+ }
138
+ })
139
+ ])
140
+ ]);
141
+ });
142
+ const list2 = rows.length ? el("div", { cls: "aim-conn-list" }, rows) : el("p", { cls: "aim-conn-empty", text: s.empty });
143
+ root.replaceChildren(
144
+ el("p", { cls: "aim-conn-note", text: s.intro }),
145
+ list2,
146
+ ...providers2.map(renderAdd)
147
+ );
148
+ }
149
+ function renderAdd(p) {
150
+ const note = connect2.notes && connect2.notes[p.id] || {};
151
+ let instanceInput = null;
152
+ if (p.instanceScoped) {
153
+ instanceInput = el("input", {
154
+ cls: "aim-conn-input",
155
+ attrs: { type: "text", placeholder: s.instancePlaceholder, "aria-label": s.instancePlaceholder }
156
+ });
157
+ }
158
+ const attachInputs = (p.attachFields || []).map((f) => el("input", {
159
+ cls: "aim-conn-input",
160
+ attrs: {
161
+ type: f.secret ? "password" : "text",
162
+ autocomplete: f.secret ? "new-password" : "off",
163
+ placeholder: f.placeholder || f.label,
164
+ "aria-label": f.label,
165
+ "data-field": f.name
166
+ }
167
+ }));
168
+ const btn = el("button", {
169
+ cls: "aim-conn-btn",
170
+ text: `${s.add} ${p.label}`,
171
+ attrs: { type: "button" },
172
+ on: {
173
+ click: () => {
174
+ if (!p.attachFields) return void beginConnect(p.id, instanceInput);
175
+ const fields = {};
176
+ for (const input of attachInputs) fields[input.getAttribute("data-field")] = input.value;
177
+ void beginAttach(p.id, fields, attachInputs);
178
+ }
179
+ }
180
+ });
181
+ return el("div", {}, [
182
+ el("div", { cls: "aim-conn-add" }, [instanceInput, ...attachInputs, btn]),
183
+ // Before the attempt, always. Each of these prevents a failure whose message does not
184
+ // explain itself.
185
+ note.needs ? el("p", { cls: "aim-conn-note", text: note.needs }) : null,
186
+ note.where ? el("p", { cls: "aim-conn-note", text: note.where }) : null,
187
+ note.before ? el("p", { cls: "aim-conn-note", text: note.before }) : null
188
+ ]);
189
+ }
190
+ async function beginConnect(providerId, instanceInput) {
191
+ if (busy) return;
192
+ busy = true;
193
+ const instance = instanceInput ? instanceInput.value.trim() : void 0;
194
+ try {
195
+ await connect2.start(providerId, { instance });
196
+ } catch (err) {
197
+ const msg = err && err.message || String(err);
198
+ root.appendChild(el("p", { cls: "aim-conn-err", text: msg }));
199
+ } finally {
200
+ busy = false;
201
+ await render();
202
+ }
203
+ }
204
+ async function beginAttach(providerId, fields, inputs) {
205
+ if (busy) return;
206
+ busy = true;
207
+ try {
208
+ await connect2.attach(providerId, fields);
209
+ for (const i of inputs) i.value = "";
210
+ } catch (err) {
211
+ root.appendChild(el("p", { cls: "aim-conn-err", text: err && err.message || String(err) }));
212
+ } finally {
213
+ busy = false;
214
+ await render();
215
+ }
216
+ }
217
+ connect2.on(() => void render());
218
+ await render();
219
+ return { refresh: render };
220
+ }
221
+
222
+ // src/static/sdk-libs/connect/notes.js
223
+ var PROVIDER_NOTES = {
224
+ mastodon: {
225
+ needs: "The address of your instance, for example mastodon.social.",
226
+ before: "Your account lives at one instance, and the same name at another instance is a different account."
227
+ },
228
+ youtube: {
229
+ before: "Sign in with the Google account that owns the channel. A Google account with no YouTube channel will connect and then have nowhere to publish."
230
+ },
231
+ bluesky: {
232
+ needs: "An app password. This is NOT your Bluesky password.",
233
+ where: "Bluesky → Settings → Privacy and security → App passwords.",
234
+ before: "This is the one provider that asks you to copy a secret to us instead of approving on their site. You can revoke it from Bluesky at any time, and it cannot be used to sign in as you."
235
+ },
236
+ instagram: {
237
+ before: "Instagram publishing needs a Business or Creator account linked to a Facebook Page. A personal account will connect and then refuse to publish, with an error that does not say why."
238
+ },
239
+ telegram: {
240
+ needs: "A bot token from @BotFather, and the bot added to your channel with permission to post.",
241
+ before: "Adding the bot to the channel is a step only you can do; without it the connection works and publishing does not."
242
+ }
243
+ };
244
+
245
+ // src/static/sdk-libs/connect/index.js
246
+ var { authFetch: authFetch2 } = makeSession("aimeat-connect.js");
247
+ var listeners = /* @__PURE__ */ new Set();
248
+ function announce() {
249
+ for (const fn of listeners) {
250
+ try {
251
+ fn();
252
+ } catch (err) {
253
+ console.warn("[aimeat-connect] a change listener threw", err);
254
+ }
255
+ }
256
+ }
257
+ async function list() {
258
+ const res = await authFetch2("/v1/connections");
259
+ return res?.data?.connections ?? [];
260
+ }
261
+ async function providers() {
262
+ const res = await authFetch2("/v1/connections/providers");
263
+ return res?.data?.providers ?? [];
264
+ }
265
+ async function start(provider, opts = {}) {
266
+ const before = await list();
267
+ const res = await authFetch2("/v1/connections/start", {
268
+ method: "POST",
269
+ body: JSON.stringify({
270
+ provider,
271
+ instance: opts.instance,
272
+ mode: opts.mode ?? "personal",
273
+ // The callback returns the browser here; a same-origin path only, which the node enforces.
274
+ // A static page whose only job is to close the pop-up, because the backend renders no HTML.
275
+ return_url: "/connection-done.html"
276
+ })
277
+ });
278
+ const url = res?.data?.authorize_url;
279
+ if (!url) throw new Error("the node did not return an authorization URL");
280
+ const win = window.open(url, "aimeat-connect", "width=620,height=760,noopener=no");
281
+ if (!win) throw new Error("the connect window was blocked; allow pop-ups for this site");
282
+ await waitForRound(before.length, opts.signal);
283
+ const after = await list();
284
+ const known = new Set(before.map((c) => c.id));
285
+ const added = after.find((c) => !known.has(c.id));
286
+ const repaired = after.find((c) => {
287
+ const prev = before.find((p) => p.id === c.id);
288
+ return prev && prev.status !== "active" && c.status === "active";
289
+ });
290
+ announce();
291
+ const connection = added ?? repaired;
292
+ return { connected: Boolean(connection), connection };
293
+ }
294
+ async function waitForRound(countBefore, signal) {
295
+ const DEADLINE = Date.now() + 18e4;
296
+ let channel = null;
297
+ let announced = false;
298
+ let aborted = false;
299
+ try {
300
+ channel = new BroadcastChannel("aimeat-connect");
301
+ channel.onmessage = () => {
302
+ announced = true;
303
+ };
304
+ } catch (err) {
305
+ console.warn("[aimeat-connect] BroadcastChannel unavailable; falling back to polling", err);
306
+ }
307
+ if (signal) signal.addEventListener("abort", () => {
308
+ aborted = true;
309
+ }, { once: true });
310
+ try {
311
+ while (Date.now() < DEADLINE && !aborted) {
312
+ await new Promise((r) => setTimeout(r, 1200));
313
+ if (announced) return true;
314
+ const now = await list();
315
+ if (now.length > countBefore) return true;
316
+ }
317
+ return false;
318
+ } finally {
319
+ if (channel) channel.close();
320
+ }
321
+ }
322
+ async function attachAccount(provider, fields) {
323
+ const res = await authFetch2("/v1/connections/attach", {
324
+ method: "POST",
325
+ body: JSON.stringify({ provider, mode: "personal", fields })
326
+ });
327
+ announce();
328
+ return { connected: true, connection: res?.data?.connection };
329
+ }
330
+ async function revoke(connectionId) {
331
+ const res = await authFetch2(`/v1/connections/${encodeURIComponent(connectionId)}`, { method: "DELETE" });
332
+ announce();
333
+ return { revoked: true, toldProvider: Boolean(res?.data?.told_provider) };
334
+ }
335
+ function on(fn) {
336
+ listeners.add(fn);
337
+ return () => listeners.delete(fn);
338
+ }
339
+ function off(fn) {
340
+ listeners.delete(fn);
341
+ }
342
+ var connect = {
343
+ list,
344
+ providers,
345
+ start,
346
+ attach: attachAccount,
347
+ revoke,
348
+ on,
349
+ off,
350
+ /** Per-provider things a user must be told BEFORE they try. See notes.js. */
351
+ notes: PROVIDER_NOTES,
352
+ /** Mount the ready-made panel. See panel.js. */
353
+ panel: (opts) => mountConnectPanel(connect, opts)
354
+ };
355
+ attach("connect", connect);
356
+ var index_default = connect;
357
+ })();
@@ -50,6 +50,20 @@
50
50
 
51
51
  // src/static/sdk-libs/data/index.js
52
52
  var { authFetch: authFetch2 } = makeSession("aimeat-data.js");
53
+ function withProvenance(res) {
54
+ const prov = res.meta?.provenance;
55
+ return prov ? { ...res.data, provenance: prov } : res.data;
56
+ }
57
+ async function publicEntryResponse(gaii, key) {
58
+ const url = NODE_URL + "/v1/memory/" + encodeURIComponent(gaii) + "/" + encodeURIComponent(key) + "?soft=1";
59
+ const r = await fetch(url);
60
+ const res = await r.json();
61
+ if (!res.ok) {
62
+ if (res.error?.code === "NOT_FOUND") return null;
63
+ throw new Error(res.error?.message || "Failed to read public memory");
64
+ }
65
+ return res;
66
+ }
53
67
  function scopeParams(opts) {
54
68
  const p = new URLSearchParams();
55
69
  if (opts?.agent) p.set("agent", opts.agent);
@@ -101,6 +115,7 @@
101
115
  return val;
102
116
  },
103
117
  // Read full entry metadata. opts: { agent, ownerScope } as in get().
118
+ // `provenance` is folded in from the envelope's `meta` — see withProvenance().
104
119
  async getEntry(key, opts) {
105
120
  const res = await authFetch2(withParams(
106
121
  "/v1/memory/" + encodeURIComponent(key),
@@ -110,7 +125,7 @@
110
125
  if (res.error?.code === "NOT_FOUND") return null;
111
126
  throw new Error(res.error?.message || "Failed to get memory");
112
127
  }
113
- return res.data;
128
+ return withProvenance(res);
114
129
  },
115
130
  // Update with optimistic locking
116
131
  async update(key, value, version, opts) {
@@ -183,15 +198,31 @@
183
198
  },
184
199
  // Read another agent's public memory (no auth needed). ?soft=1: missing (or hidden)
185
200
  // keys resolve null via a clean 200 instead of logging a console 404.
201
+ //
202
+ // Returns the VALUE, deliberately unchanged: every published app reading this library expects
203
+ // the bare value here, so widening the return type would break them all. To see how the value
204
+ // was made, use getPublicEntry() below.
186
205
  async getPublic(gaii, key) {
187
- const url = NODE_URL + "/v1/memory/" + encodeURIComponent(gaii) + "/" + encodeURIComponent(key) + "?soft=1";
188
- const r = await fetch(url);
189
- const res = await r.json();
190
- if (!res.ok) {
191
- if (res.error?.code === "NOT_FOUND") return null;
192
- throw new Error(res.error?.message || "Failed to read public memory");
193
- }
194
- return res.data.value;
206
+ const res = await publicEntryResponse(gaii, key);
207
+ return res === null ? null : res.data.value;
208
+ },
209
+ /**
210
+ * The same public read, as a full entry: `{ key, value, visibility, version, …, provenance }`.
211
+ *
212
+ * WHY THIS EXISTS. The node serves an item's AI provenance on the envelope's `meta`, and
213
+ * getPublic() returns `res.data.value` — so the statement about how the content was made was
214
+ * being thrown away at the last hop, on the one read path published apps actually use. An app
215
+ * could render a model-written article and have no way to say so, however carefully the writing
216
+ * agent had declared it. This is the same READ-DIRECTION loss that had to be fixed in the
217
+ * connector (ai-provenance-carry.ts v1.1.0, "read_provenance() never returns anything"); the
218
+ * browser library had it too.
219
+ *
220
+ * `provenance` is `{ id, record, record_url }` or undefined when the node holds no record for
221
+ * the item. Undefined means UNSTATED, and never "a person wrote it".
222
+ */
223
+ async getPublicEntry(gaii, key) {
224
+ const res = await publicEntryResponse(gaii, key);
225
+ return res === null ? null : withProvenance(res);
195
226
  },
196
227
  // ── Micro-Memory (Tier 0.5, GET-based) ──
197
228
  micro(setName, accessCode) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aimeat",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "AIME AT - AI Memory Exchange and Action Transfer - reference implementation",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -107,7 +107,7 @@
107
107
  "check:vendored": "node scripts/vendor-libs.mjs --check",
108
108
  "dev": "node scripts/vendor-libs.mjs && tsx scripts/kill-port.ts && tsx scripts/build-app-catalog.ts && tsx scripts/build-sdk-libs.ts && node --env-file=.env --import tsx src/index.ts start",
109
109
  "dev:watch": "tsx watch src/index.ts",
110
- "build": "node scripts/vendor-libs.mjs && tsc && node --input-type=module -e \"import fs from 'fs';fs.cpSync('locales','dist/locales',{recursive:true});fs.cpSync('public','dist/public',{recursive:true});fs.cpSync('src/static','dist/static',{recursive:true});fs.cpSync('.env.example','dist/.env.example');fs.cpSync('src/storage/providers/postgres-kysely/migrations','dist/src/storage/providers/postgres-kysely/migrations',{recursive:true});\"",
110
+ "build": "node scripts/vendor-libs.mjs && tsc && node --input-type=module -e \"import fs from 'fs';fs.cpSync('locales','dist/locales',{recursive:true});fs.cpSync('public','dist/public',{recursive:true});fs.cpSync('src/static','dist/static',{recursive:true});fs.cpSync('.env.example','dist/.env.example');fs.cpSync('src/storage/providers/postgres-kysely/migrations','dist/src/storage/providers/postgres-kysely/migrations',{recursive:true});\" && node scripts/write-build-stamp.mjs",
111
111
  "build:app-catalog": "tsx scripts/build-app-catalog.ts",
112
112
  "check:app-catalog": "tsx scripts/build-app-catalog.ts --check",
113
113
  "check:changelog": "tsx scripts/check-changelog.ts",