@chatpanel/events 0.102.0 → 0.103.1

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 (138) 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 +1 -4
  62. package/pdf-layout.js +7 -253
  63. package/project-run.js +20 -444
  64. package/project.js +1 -170
  65. package/promotion.js +1 -171
  66. package/queue.js +1 -98
  67. package/reach.js +1 -23
  68. package/recipe-tool.js +2 -161
  69. package/recipe.js +1 -264
  70. package/record-list.js +2 -110
  71. package/recruit.js +3 -456
  72. package/redaction-tokens.js +1 -61
  73. package/ref.js +1 -55
  74. package/registry.js +1 -240
  75. package/route-graph.js +1 -115
  76. package/route-strategies.js +2 -232
  77. package/router.js +2 -880
  78. package/rrf.js +1 -89
  79. package/rules.js +1 -142
  80. package/schedule.js +1 -663
  81. package/scm-connection.js +1 -180
  82. package/scopes.js +1 -12
  83. package/scorecard.js +1 -335
  84. package/search-engines.js +1 -81
  85. package/skill-manifest.js +1 -330
  86. package/skill-scan.js +3 -209
  87. package/skill-sources.js +1 -162
  88. package/skill-vars.js +2 -252
  89. package/slash-commands.js +1 -158
  90. package/source-gate.js +1 -92
  91. package/sources-retrieval.js +5 -186
  92. package/sources.js +1 -273
  93. package/store.js +1 -171
  94. package/structured.js +4 -901
  95. package/subject-kinds.js +1 -5
  96. package/subject-name.js +1 -96
  97. package/sync-plan.js +1 -213
  98. package/synthesis.js +3 -123
  99. package/tags.js +1 -203
  100. package/team-board.js +6 -337
  101. package/team-cache.js +2 -63
  102. package/team-observe.js +1 -118
  103. package/team-org.js +1 -442
  104. package/team-plan.js +4 -131
  105. package/team-record.js +1 -225
  106. package/team-run.js +9 -652
  107. package/team-subtask.js +2 -191
  108. package/team-task.js +2 -124
  109. package/team-tool.js +2 -196
  110. package/team-trail.js +2 -73
  111. package/team-worklog.js +2 -149
  112. package/team.js +1 -302
  113. package/text-search.js +1 -155
  114. package/theme.js +17 -154
  115. package/titles.js +4 -285
  116. package/tool-discovery.js +1 -87
  117. package/tool-dispatch.js +5 -230
  118. package/tool-groups.js +1 -81
  119. package/tool-hints.js +10 -185
  120. package/tool-loop-guard.js +4 -182
  121. package/tool-need.js +2 -124
  122. package/tool-result.js +2 -438
  123. package/tool-round.js +0 -0
  124. package/tool-schema.js +1 -155
  125. package/tool-traits.js +1 -182
  126. package/toolset.js +2 -88
  127. package/trajectory.js +1 -530
  128. package/turn-loop.js +4 -440
  129. package/upcast.js +1 -37
  130. package/vault.js +2 -250
  131. package/view.js +1 -88
  132. package/voice-intents.js +2 -1488
  133. package/voice-speaker.js +1 -98
  134. package/weather-tool.js +1 -65
  135. package/weather.js +2 -211
  136. package/web-search-tool.js +14 -102
  137. package/web-search.js +1 -160
  138. 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};