@chatpanel/events 0.102.0 → 0.104.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 (139) hide show
  1. package/adapters.js +1 -83
  2. package/adaptive-tool-policy.js +1 -45
  3. package/agent.js +2 -255
  4. package/attribution.js +1 -132
  5. package/backup-envelope.js +1 -221
  6. package/board-tool.js +2 -165
  7. package/budget.js +1 -116
  8. package/capability.js +1 -126
  9. package/citations.js +5 -127
  10. package/client-prefs.js +1 -148
  11. package/context-attachments.js +8 -144
  12. package/cowriter-router.js +1 -83
  13. package/cowriter-writer.js +19 -193
  14. package/cowriter.js +1 -190
  15. package/curate.js +3 -509
  16. package/distance.js +1 -124
  17. package/engine.js +1 -131
  18. package/entitlement.js +1 -332
  19. package/entity.js +1 -354
  20. package/event.js +1 -175
  21. package/extraction.js +4 -293
  22. package/failover.js +1 -93
  23. package/find-tool.js +1 -66
  24. package/flowchart.js +2 -644
  25. package/gate.js +1 -74
  26. package/harness.js +4 -101
  27. package/index.js +1 -345
  28. package/invariants.js +1 -174
  29. package/job.js +3 -147
  30. package/kernel.js +1 -255
  31. package/knowledge-derive.js +1 -267
  32. package/knowledge.js +3 -230
  33. package/library.js +11 -280
  34. package/loop.js +1 -132
  35. package/manifest.js +1 -107
  36. package/markdown-authoring.js +11 -288
  37. package/markdown-render.js +0 -0
  38. package/mcp-client.js +8 -358
  39. package/mcp-dispatch.js +1 -52
  40. package/mcp-errors.js +1 -106
  41. package/mcp-manager.js +1 -127
  42. package/media-transcript.js +8 -531
  43. package/meeting-analyzers.js +1 -83
  44. package/meeting-insights.js +7 -164
  45. package/meeting-shape.js +1 -282
  46. package/meeting-text.js +5 -94
  47. package/memory.js +2 -638
  48. package/model-candidates.js +1 -358
  49. package/model-health.js +1 -182
  50. package/model-ledger.js +1 -228
  51. package/model-picker.js +1 -188
  52. package/note-actions.js +15 -246
  53. package/note-graph.js +1 -158
  54. package/note-links.js +1 -68
  55. package/note-mentions.js +8 -114
  56. package/note-plan.js +9 -107
  57. package/note-research.js +1 -135
  58. package/observability.js +1 -119
  59. package/omni.js +1 -125
  60. package/order.js +1 -78
  61. package/package.json +4 -5
  62. package/pdf-layout.js +7 -253
  63. package/policy.js +1 -0
  64. package/project-run.js +20 -444
  65. package/project.js +1 -170
  66. package/promotion.js +1 -171
  67. package/queue.js +1 -98
  68. package/reach.js +1 -23
  69. package/recipe-tool.js +2 -161
  70. package/recipe.js +1 -264
  71. package/record-list.js +2 -110
  72. package/recruit.js +3 -456
  73. package/redaction-tokens.js +1 -61
  74. package/ref.js +1 -55
  75. package/registry.js +1 -240
  76. package/route-graph.js +1 -115
  77. package/route-strategies.js +2 -232
  78. package/router.js +2 -880
  79. package/rrf.js +1 -89
  80. package/rules.js +1 -142
  81. package/schedule.js +1 -663
  82. package/scm-connection.js +1 -180
  83. package/scopes.js +1 -12
  84. package/scorecard.js +1 -335
  85. package/search-engines.js +1 -81
  86. package/skill-manifest.js +1 -330
  87. package/skill-scan.js +3 -209
  88. package/skill-sources.js +1 -162
  89. package/skill-vars.js +2 -252
  90. package/slash-commands.js +1 -158
  91. package/source-gate.js +1 -92
  92. package/sources-retrieval.js +5 -186
  93. package/sources.js +1 -273
  94. package/store.js +1 -171
  95. package/structured.js +4 -901
  96. package/subject-kinds.js +1 -5
  97. package/subject-name.js +1 -96
  98. package/sync-plan.js +1 -213
  99. package/synthesis.js +3 -123
  100. package/tags.js +1 -203
  101. package/team-board.js +6 -337
  102. package/team-cache.js +2 -63
  103. package/team-observe.js +1 -118
  104. package/team-org.js +1 -442
  105. package/team-plan.js +4 -131
  106. package/team-record.js +1 -225
  107. package/team-run.js +9 -652
  108. package/team-subtask.js +2 -191
  109. package/team-task.js +2 -124
  110. package/team-tool.js +2 -196
  111. package/team-trail.js +2 -73
  112. package/team-worklog.js +2 -149
  113. package/team.js +1 -302
  114. package/text-search.js +1 -155
  115. package/theme.js +17 -154
  116. package/titles.js +4 -285
  117. package/tool-discovery.js +1 -87
  118. package/tool-dispatch.js +5 -230
  119. package/tool-groups.js +1 -81
  120. package/tool-hints.js +10 -185
  121. package/tool-loop-guard.js +4 -182
  122. package/tool-need.js +2 -124
  123. package/tool-result.js +2 -438
  124. package/tool-round.js +0 -0
  125. package/tool-schema.js +1 -155
  126. package/tool-traits.js +1 -182
  127. package/toolset.js +2 -88
  128. package/trajectory.js +1 -530
  129. package/turn-loop.js +4 -440
  130. package/upcast.js +1 -37
  131. package/vault.js +2 -250
  132. package/view.js +1 -88
  133. package/voice-intents.js +2 -1488
  134. package/voice-speaker.js +1 -98
  135. package/weather-tool.js +1 -65
  136. package/weather.js +2 -211
  137. package/web-search-tool.js +14 -102
  138. package/web-search.js +1 -160
  139. package/widget.js +1 -153
package/store.js CHANGED
@@ -1,171 +1 @@
1
- // The log store and the blob store.
2
- //
3
- // PERSISTENCE IS A HOST ADAPTER. The spine is host-independent, so the *semantics* live
4
- // here and each host supplies the storage underneath: IndexedDB in the extension,
5
- // SQLite on a gateway or daemon, a capped ring buffer colocated. One in-memory adapter
6
- // ships here because tests, colocated hosts and the replay harness all want it.
7
- //
8
- // TWO STORES, DELIBERATELY SEPARATE.
9
- // • the LOG holds events — small, uniform, append-only, ~300-500 B each;
10
- // • the BLOB store holds content, addressed by hash and deduped, so the same note
11
- // excerpt attached across a hundred turns costs one copy.
12
- // Keeping them apart is what makes crypto-shredding work: drop a blob and the event
13
- // skeleton, causality chain and audit trail all survive.
14
- //
15
- // APPEND IS IDEMPOTENT ON EVENT ID. Replicating the log to a warm tier can retry
16
- // safely — the log-level counterpart of the idempotency keys capabilities carry.
17
-
18
- import { validateEvent, EventError } from './event.js';
19
- import { linearize } from './order.js';
20
-
21
- /**
22
- * Minimal adapter contract a host implements.
23
- * get(key) -> value | undefined put(key, value) delete(key)
24
- * keys(prefix?) -> string[] size() -> bytes (approximate)
25
- */
26
- export function createMemoryAdapter() {
27
- const map = new Map();
28
- return {
29
- get: (k) => map.get(k),
30
- put: (k, v) => { map.set(k, v); },
31
- delete: (k) => map.delete(k),
32
- keys: (prefix = '') => [...map.keys()].filter((k) => k.startsWith(prefix)).sort(),
33
- size: () => {
34
- let n = 0;
35
- for (const [k, v] of map) n += k.length + (typeof v === 'string' ? v.length : JSON.stringify(v).length);
36
- return n;
37
- },
38
- clear: () => map.clear(),
39
- };
40
- }
41
-
42
- const EV = 'e/'; // event by id
43
- const SEQ = 's/'; // host -> highest seq seen
44
-
45
- /** The append-only event log over a host adapter. */
46
- export function createLogStore(adapter = createMemoryAdapter()) {
47
- const store = {
48
- /**
49
- * Append a validated event. Idempotent on `id`: re-appending the same event is a
50
- * no-op returning `{ appended: false }`, so replication retries are safe.
51
- * Rejects a seq that moves backwards for a host — that is a corrupt writer, not a gap.
52
- */
53
- append(event) {
54
- validateEvent(event);
55
- if (adapter.get(EV + event.id) !== undefined) return { appended: false, event };
56
- const highest = adapter.get(SEQ + event.host);
57
- if (highest !== undefined && event.seq <= highest) {
58
- throw new EventError('SEQ', `seq ${event.seq} <= ${highest} already seen for host ${event.host}`, event.host);
59
- }
60
- adapter.put(EV + event.id, event);
61
- adapter.put(SEQ + event.host, event.seq);
62
- return { appended: true, event };
63
- },
64
-
65
- appendAll(events) {
66
- const res = events.map((e) => store.append(e));
67
- return { appended: res.filter((r) => r.appended).length, total: events.length };
68
- },
69
-
70
- get: (id) => adapter.get(EV + id),
71
- has: (id) => adapter.get(EV + id) !== undefined,
72
-
73
- all: () => adapter.keys(EV).map((k) => adapter.get(k)),
74
-
75
- /** Every event in replay order — the only ordering anything should read. */
76
- ordered: () => linearize(store.all()),
77
-
78
- byType: (type) => store.all().filter((e) => e.type === type),
79
-
80
- /** One host's slice, for replication cursors. */
81
- range({ host, fromSeq = 0, toSeq = Infinity } = {}) {
82
- return store.all()
83
- .filter((e) => (!host || e.host === host) && e.seq >= fromSeq && e.seq <= toSeq)
84
- .sort((a, b) => a.seq - b.seq);
85
- },
86
-
87
- /** Highest seq per host — the cursor a replica sends to ask for what it lacks. */
88
- cursor() {
89
- const out = {};
90
- for (const k of adapter.keys(SEQ)) out[k.slice(SEQ.length)] = adapter.get(k);
91
- return out;
92
- },
93
-
94
- /** Events a replica with this cursor has not seen. */
95
- since(cursor = {}) {
96
- return store.all()
97
- .filter((e) => e.seq > (cursor[e.host] ?? -1))
98
- .sort((a, b) => (a.host === b.host ? a.seq - b.seq : a.host < b.host ? -1 : 1));
99
- },
100
-
101
- /** Walk the causality chain backwards from an event. */
102
- ancestry(id, seen = new Set()) {
103
- const e = store.get(id);
104
- if (!e || seen.has(id)) return [];
105
- seen.add(id);
106
- return [e, ...e.causes.flatMap((c) => store.ancestry(c, seen))];
107
- },
108
-
109
- stats: () => ({ events: adapter.keys(EV).length, bytes: adapter.size() }),
110
- };
111
- return store;
112
- }
113
-
114
- /**
115
- * Content-addressed blob store. Dedupes by hash, so attaching the same excerpt a
116
- * hundred times costs one copy — the rule that keeps the log from growing linearly in
117
- * content.
118
- *
119
- * `digest` is injected: no ambient dependency on a crypto implementation, and tests stay
120
- * deterministic. Defaults to SHA-256 via WebCrypto, present in browsers and Node >= 18.
121
- */
122
- export function createBlobStore(adapter = createMemoryAdapter(), { digest = sha256Hex } = {}) {
123
- const B = 'b/';
124
- const store = {
125
- async put(content) {
126
- const hash = await digest(content);
127
- const key = B + hash;
128
- if (adapter.get(key) === undefined) adapter.put(key, content);
129
- return hash;
130
- },
131
- get: (hash) => adapter.get(B + hash),
132
- has: (hash) => adapter.get(B + hash) !== undefined,
133
-
134
- /**
135
- * CRYPTO-SHRED. Drops the payload and leaves a tombstone, so "delete this meeting"
136
- * can be honoured against an append-only log: the content is unrecoverable while
137
- * every event that referenced it, and the causality chain, stay intact. Replay then
138
- * reports verified-but-unavailable rather than substituting current content.
139
- */
140
- shred(hash) {
141
- if (adapter.get(B + hash) === undefined) return false;
142
- adapter.delete(B + hash);
143
- adapter.put(`t/${hash}`, { shredded: true });
144
- return true;
145
- },
146
- isShredded: (hash) => adapter.get(`t/${hash}`) !== undefined,
147
-
148
- /** Resolve a Ref the way replay must: exact, shredded, or absent. */
149
- lookup(ref) {
150
- const value = store.get(ref.hash);
151
- if (value === undefined) return null;
152
- return { hash: ref.hash, value };
153
- },
154
-
155
- stats: () => ({
156
- blobs: adapter.keys(B).length,
157
- shredded: adapter.keys('t/').length,
158
- bytes: adapter.size(),
159
- }),
160
- };
161
- return store;
162
- }
163
-
164
- // Global WebCrypto: present in every browser and in Node from 19 onward. Callers on an
165
- // older or unusual runtime inject their own `digest` rather than the package reaching
166
- // for `node:crypto`, which would put a Node import in a browser-first module.
167
- async function sha256Hex(content) {
168
- const bytes = typeof content === 'string' ? new TextEncoder().encode(content) : content;
169
- const buf = await globalThis.crypto.subtle.digest('SHA-256', bytes);
170
- return `sha256:${[...new Uint8Array(buf)].map((b) => b.toString(16).padStart(2, '0')).join('')}`;
171
- }
1
+ import{validateEvent as h,EventError as g}from"./event.js";import{linearize as c}from"./order.js";function f(){const t=new Map;return{get:r=>t.get(r),put:(r,e)=>{t.set(r,e)},delete:r=>t.delete(r),keys:(r="")=>[...t.keys()].filter(e=>e.startsWith(r)).sort(),size:()=>{let r=0;for(const[e,s]of t)r+=e.length+(typeof s=="string"?s.length:JSON.stringify(s).length);return r},clear:()=>t.clear()}}const i="e/",u="s/";function a(t=f()){const r={append(e){if(h(e),t.get(i+e.id)!==void 0)return{appended:!1,event:e};const s=t.get(u+e.host);if(s!==void 0&&e.seq<=s)throw new g("SEQ",`seq ${e.seq} <= ${s} already seen for host ${e.host}`,e.host);return t.put(i+e.id,e),t.put(u+e.host,e.seq),{appended:!0,event:e}},appendAll(e){return{appended:e.map(n=>r.append(n)).filter(n=>n.appended).length,total:e.length}},get:e=>t.get(i+e),has:e=>t.get(i+e)!==void 0,all:()=>t.keys(i).map(e=>t.get(e)),ordered:()=>c(r.all()),byType:e=>r.all().filter(s=>s.type===e),range({host:e,fromSeq:s=0,toSeq:n=1/0}={}){return r.all().filter(o=>(!e||o.host===e)&&o.seq>=s&&o.seq<=n).sort((o,l)=>o.seq-l.seq)},cursor(){const e={};for(const s of t.keys(u))e[s.slice(u.length)]=t.get(s);return e},since(e={}){return r.all().filter(s=>s.seq>(e[s.host]??-1)).sort((s,n)=>s.host===n.host?s.seq-n.seq:s.host<n.host?-1:1)},ancestry(e,s=new Set){const n=r.get(e);return!n||s.has(e)?[]:(s.add(e),[n,...n.causes.flatMap(o=>r.ancestry(o,s))])},stats:()=>({events:t.keys(i).length,bytes:t.size()})};return r}function k(t=f(),{digest:r=d}={}){const s={async put(n){const o=await r(n),l="b/"+o;return t.get(l)===void 0&&t.put(l,n),o},get:n=>t.get("b/"+n),has:n=>t.get("b/"+n)!==void 0,shred(n){return t.get("b/"+n)===void 0?!1:(t.delete("b/"+n),t.put(`t/${n}`,{shredded:!0}),!0)},isShredded:n=>t.get(`t/${n}`)!==void 0,lookup(n){const o=s.get(n.hash);return o===void 0?null:{hash:n.hash,value:o}},stats:()=>({blobs:t.keys("b/").length,shredded:t.keys("t/").length,bytes:t.size()})};return s}async function d(t){const r=typeof t=="string"?new TextEncoder().encode(t):t,e=await globalThis.crypto.subtle.digest("SHA-256",r);return`sha256:${[...new Uint8Array(e)].map(s=>s.toString(16).padStart(2,"0")).join("")}`}export{k as createBlobStore,a as createLogStore,f as createMemoryAdapter};