@chipschat/protocol 0.0.0-stage → 1.0.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.
- package/LICENSE +201 -0
- package/README.md +56 -2
- package/dist/generated/types.d.ts +4052 -0
- package/dist/generated/types.d.ts.map +1 -0
- package/dist/generated/types.js +7 -0
- package/dist/generated/types.js.map +1 -0
- package/dist/src/address.d.ts +106 -0
- package/dist/src/address.d.ts.map +1 -0
- package/dist/src/address.js +141 -0
- package/dist/src/address.js.map +1 -0
- package/dist/src/agent-context-windows.d.ts +235 -0
- package/dist/src/agent-context-windows.d.ts.map +1 -0
- package/dist/src/agent-context-windows.js +213 -0
- package/dist/src/agent-context-windows.js.map +1 -0
- package/dist/src/agent-heartbeats.d.ts +106 -0
- package/dist/src/agent-heartbeats.d.ts.map +1 -0
- package/dist/src/agent-heartbeats.js +111 -0
- package/dist/src/agent-heartbeats.js.map +1 -0
- package/dist/src/agent-models.d.ts +158 -0
- package/dist/src/agent-models.d.ts.map +1 -0
- package/dist/src/agent-models.js +171 -0
- package/dist/src/agent-models.js.map +1 -0
- package/dist/src/agent-place.d.ts +76 -0
- package/dist/src/agent-place.d.ts.map +1 -0
- package/dist/src/agent-place.js +80 -0
- package/dist/src/agent-place.js.map +1 -0
- package/dist/src/agents.d.ts +24 -0
- package/dist/src/agents.d.ts.map +1 -0
- package/dist/src/agents.js +58 -0
- package/dist/src/agents.js.map +1 -0
- package/dist/src/capabilities.d.ts +121 -0
- package/dist/src/capabilities.d.ts.map +1 -0
- package/dist/src/capabilities.js +120 -0
- package/dist/src/capabilities.js.map +1 -0
- package/dist/src/checklist.d.ts +19 -0
- package/dist/src/checklist.d.ts.map +1 -0
- package/dist/src/checklist.js +22 -0
- package/dist/src/checklist.js.map +1 -0
- package/dist/src/commands.d.ts +50 -0
- package/dist/src/commands.d.ts.map +1 -0
- package/dist/src/commands.js +274 -0
- package/dist/src/commands.js.map +1 -0
- package/dist/src/connectors.d.ts +90 -0
- package/dist/src/connectors.d.ts.map +1 -0
- package/dist/src/connectors.js +119 -0
- package/dist/src/connectors.js.map +1 -0
- package/dist/src/context-files.d.ts +304 -0
- package/dist/src/context-files.d.ts.map +1 -0
- package/dist/src/context-files.js +247 -0
- package/dist/src/context-files.js.map +1 -0
- package/dist/src/context.d.ts +369 -0
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +526 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/direct-asks.d.ts +36 -0
- package/dist/src/direct-asks.d.ts.map +1 -0
- package/dist/src/direct-asks.js +43 -0
- package/dist/src/direct-asks.js.map +1 -0
- package/dist/src/envelope.d.ts +70 -0
- package/dist/src/envelope.d.ts.map +1 -0
- package/dist/src/envelope.js +46 -0
- package/dist/src/envelope.js.map +1 -0
- package/dist/src/events/catalogue.d.ts +50 -0
- package/dist/src/events/catalogue.d.ts.map +1 -0
- package/dist/src/events/catalogue.js +70 -0
- package/dist/src/events/catalogue.js.map +1 -0
- package/dist/src/events/chips-to-harness.d.ts +37 -0
- package/dist/src/events/chips-to-harness.d.ts.map +1 -0
- package/dist/src/events/chips-to-harness.js +511 -0
- package/dist/src/events/chips-to-harness.js.map +1 -0
- package/dist/src/events/harness-to-chips.d.ts +38 -0
- package/dist/src/events/harness-to-chips.d.ts.map +1 -0
- package/dist/src/events/harness-to-chips.js +593 -0
- package/dist/src/events/harness-to-chips.js.map +1 -0
- package/dist/src/events/index.d.ts +6 -0
- package/dist/src/events/index.d.ts.map +1 -0
- package/dist/src/events/index.js +5 -0
- package/dist/src/events/index.js.map +1 -0
- package/dist/src/events/workspace.d.ts +222 -0
- package/dist/src/events/workspace.d.ts.map +1 -0
- package/dist/src/events/workspace.js +1039 -0
- package/dist/src/events/workspace.js.map +1 -0
- package/dist/src/exchange.d.ts +262 -0
- package/dist/src/exchange.d.ts.map +1 -0
- package/dist/src/exchange.js +413 -0
- package/dist/src/exchange.js.map +1 -0
- package/dist/src/first-names.d.ts +29 -0
- package/dist/src/first-names.d.ts.map +1 -0
- package/dist/src/first-names.js +80 -0
- package/dist/src/first-names.js.map +1 -0
- package/dist/src/frames.d.ts +526 -0
- package/dist/src/frames.d.ts.map +1 -0
- package/dist/src/frames.js +346 -0
- package/dist/src/frames.js.map +1 -0
- package/dist/src/harness-jobs.d.ts +313 -0
- package/dist/src/harness-jobs.d.ts.map +1 -0
- package/dist/src/harness-jobs.js +210 -0
- package/dist/src/harness-jobs.js.map +1 -0
- package/dist/src/ids/index.d.ts +3 -0
- package/dist/src/ids/index.d.ts.map +1 -0
- package/dist/src/ids/index.js +2 -0
- package/dist/src/ids/index.js.map +1 -0
- package/dist/src/ids/ulid.d.ts +96 -0
- package/dist/src/ids/ulid.d.ts.map +1 -0
- package/dist/src/ids/ulid.js +212 -0
- package/dist/src/ids/ulid.js.map +1 -0
- package/dist/src/index.d.ts +81 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +47 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/invite-link.d.ts +64 -0
- package/dist/src/invite-link.d.ts.map +1 -0
- package/dist/src/invite-link.js +99 -0
- package/dist/src/invite-link.js.map +1 -0
- package/dist/src/join.d.ts +188 -0
- package/dist/src/join.d.ts.map +1 -0
- package/dist/src/join.js +190 -0
- package/dist/src/join.js.map +1 -0
- package/dist/src/limits.d.ts +50 -0
- package/dist/src/limits.d.ts.map +1 -0
- package/dist/src/limits.js +106 -0
- package/dist/src/limits.js.map +1 -0
- package/dist/src/matters.d.ts +22 -0
- package/dist/src/matters.d.ts.map +1 -0
- package/dist/src/matters.js +26 -0
- package/dist/src/matters.js.map +1 -0
- package/dist/src/mentions.d.ts +63 -0
- package/dist/src/mentions.d.ts.map +1 -0
- package/dist/src/mentions.js +129 -0
- package/dist/src/mentions.js.map +1 -0
- package/dist/src/names.d.ts +58 -0
- package/dist/src/names.d.ts.map +1 -0
- package/dist/src/names.js +192 -0
- package/dist/src/names.js.map +1 -0
- package/dist/src/no-reply.d.ts +17 -0
- package/dist/src/no-reply.d.ts.map +1 -0
- package/dist/src/no-reply.js +48 -0
- package/dist/src/no-reply.js.map +1 -0
- package/dist/src/notifications.d.ts +81 -0
- package/dist/src/notifications.d.ts.map +1 -0
- package/dist/src/notifications.js +65 -0
- package/dist/src/notifications.js.map +1 -0
- package/dist/src/pages.d.ts +32 -0
- package/dist/src/pages.d.ts.map +1 -0
- package/dist/src/pages.js +32 -0
- package/dist/src/pages.js.map +1 -0
- package/dist/src/pairing.d.ts +99 -0
- package/dist/src/pairing.d.ts.map +1 -0
- package/dist/src/pairing.js +163 -0
- package/dist/src/pairing.js.map +1 -0
- package/dist/src/primitives.d.ts +267 -0
- package/dist/src/primitives.d.ts.map +1 -0
- package/dist/src/primitives.js +279 -0
- package/dist/src/primitives.js.map +1 -0
- package/dist/src/project.d.ts +335 -0
- package/dist/src/project.d.ts.map +1 -0
- package/dist/src/project.js +499 -0
- package/dist/src/project.js.map +1 -0
- package/dist/src/ranges.d.ts +31 -0
- package/dist/src/ranges.d.ts.map +1 -0
- package/dist/src/ranges.js +51 -0
- package/dist/src/ranges.js.map +1 -0
- package/dist/src/relay.d.ts +177 -0
- package/dist/src/relay.d.ts.map +1 -0
- package/dist/src/relay.js +147 -0
- package/dist/src/relay.js.map +1 -0
- package/dist/src/room-files.d.ts +146 -0
- package/dist/src/room-files.d.ts.map +1 -0
- package/dist/src/room-files.js +135 -0
- package/dist/src/room-files.js.map +1 -0
- package/dist/src/room-note.d.ts +213 -0
- package/dist/src/room-note.d.ts.map +1 -0
- package/dist/src/room-note.js +457 -0
- package/dist/src/room-note.js.map +1 -0
- package/dist/src/space-icons.d.ts +68 -0
- package/dist/src/space-icons.d.ts.map +1 -0
- package/dist/src/space-icons.js +142 -0
- package/dist/src/space-icons.js.map +1 -0
- package/dist/src/spend.d.ts +57 -0
- package/dist/src/spend.d.ts.map +1 -0
- package/dist/src/spend.js +94 -0
- package/dist/src/spend.js.map +1 -0
- package/dist/src/visibility.d.ts +170 -0
- package/dist/src/visibility.d.ts.map +1 -0
- package/dist/src/visibility.js +218 -0
- package/dist/src/visibility.js.map +1 -0
- package/fixtures/agent.asked.json +15 -0
- package/fixtures/agent.attached.json +15 -0
- package/fixtures/agent.deleted.json +16 -0
- package/fixtures/agent.fork.json +14 -0
- package/fixtures/agent.lock_set.json +13 -0
- package/fixtures/agent.registered.json +17 -0
- package/fixtures/agent.released.json +16 -0
- package/fixtures/agent.updated.json +14 -0
- package/fixtures/approval.executed.json +16 -0
- package/fixtures/approval.request.json +45 -0
- package/fixtures/approval.resolved.json +20 -0
- package/fixtures/approval.routed.json +20 -0
- package/fixtures/artifact.create.json +18 -0
- package/fixtures/attachment.fetched.json +15 -0
- package/fixtures/attachment.limits_set.json +15 -0
- package/fixtures/budget.warning.json +20 -0
- package/fixtures/checkpoint.json +16 -0
- package/fixtures/context.compacted.json +16 -0
- package/fixtures/context.usage.json +17 -0
- package/fixtures/exchange.limits_set.json +15 -0
- package/fixtures/exchange.set.json +13 -0
- package/fixtures/feedback.json +21 -0
- package/fixtures/frames/ack.json +6 -0
- package/fixtures/frames/context.edit.json +11 -0
- package/fixtures/frames/context_window.change.json +9 -0
- package/fixtures/frames/context_window.compact.json +8 -0
- package/fixtures/frames/error.json +6 -0
- package/fixtures/frames/event.json +20 -0
- package/fixtures/frames/events.json +39 -0
- package/fixtures/frames/folder.open.json +6 -0
- package/fixtures/frames/folder.open.page.json +7 -0
- package/fixtures/frames/folder.run.json +8 -0
- package/fixtures/frames/folder.run_state.json +12 -0
- package/fixtures/frames/heartbeat.change.json +10 -0
- package/fixtures/frames/hello.json +18 -0
- package/fixtures/frames/job.change.json +9 -0
- package/fixtures/frames/join.json +19 -0
- package/fixtures/frames/model.change.json +10 -0
- package/fixtures/frames/ping.json +4 -0
- package/fixtures/frames/pong.json +4 -0
- package/fixtures/frames/presence.json +12 -0
- package/fixtures/frames/receipt.json +5 -0
- package/fixtures/frames/restart.json +5 -0
- package/fixtures/frames/subscribe.json +6 -0
- package/fixtures/handoff.json +20 -0
- package/fixtures/harness.removed.json +15 -0
- package/fixtures/harness.transferred.json +15 -0
- package/fixtures/hello.json +61 -0
- package/fixtures/join.allowed.json +20 -0
- package/fixtures/join.denied.json +17 -0
- package/fixtures/lane.updated.json +17 -0
- package/fixtures/membership.added.json +16 -0
- package/fixtures/membership.removed.json +14 -0
- package/fixtures/membership.replaced.json +15 -0
- package/fixtures/message.deleted.json +15 -0
- package/fixtures/message.edited.json +15 -0
- package/fixtures/message.handed.json +14 -0
- package/fixtures/message.heard.json +14 -0
- package/fixtures/message.held.json +14 -0
- package/fixtures/message.hidden.json +14 -0
- package/fixtures/message.new.json +96 -0
- package/fixtures/message.overheard.json +22 -0
- package/fixtures/message.pinned.json +14 -0
- package/fixtures/message.post.json +14 -0
- package/fixtures/message.shown.json +14 -0
- package/fixtures/message.unpinned.json +14 -0
- package/fixtures/person.face_set.json +17 -0
- package/fixtures/person.joined.json +16 -0
- package/fixtures/person.removed.json +16 -0
- package/fixtures/person.renamed.json +14 -0
- package/fixtures/policy.updated.json +30 -0
- package/fixtures/project.changed.json +21 -0
- package/fixtures/question.answered.json +23 -0
- package/fixtures/question.ask.json +37 -0
- package/fixtures/receipt.json +15 -0
- package/fixtures/relay.set.json +12 -0
- package/fixtures/role.changed.json +15 -0
- package/fixtures/run.cancel.json +15 -0
- package/fixtures/run.completed.json +20 -0
- package/fixtures/run.failed.json +20 -0
- package/fixtures/run.pause.json +15 -0
- package/fixtures/run.plan.json +24 -0
- package/fixtures/run.requested.json +34 -0
- package/fixtures/run.resume.json +15 -0
- package/fixtures/run.started.json +33 -0
- package/fixtures/run.status.json +17 -0
- package/fixtures/run.steer.json +21 -0
- package/fixtures/session.ended.json +15 -0
- package/fixtures/session.renamed.json +15 -0
- package/fixtures/session.started.json +17 -0
- package/fixtures/space.claimed.json +15 -0
- package/fixtures/space.created.json +14 -0
- package/fixtures/space.erased.json +13 -0
- package/fixtures/space.lead_set.json +13 -0
- package/fixtures/space.lock_set.json +13 -0
- package/fixtures/space.spend_ceiling_set.json +13 -0
- package/fixtures/space.updated.json +14 -0
- package/fixtures/step.log.json +26 -0
- package/fixtures/task.json +22 -0
- package/fixtures/turn.passed.json +14 -0
- package/fixtures/usage.json +21 -0
- package/fixtures/workspace.renamed.json +13 -0
- package/generated/agent-connect.json +13966 -0
- package/generated/schema/agent.asked.json +114 -0
- package/generated/schema/agent.attached.json +465 -0
- package/generated/schema/agent.deleted.json +127 -0
- package/generated/schema/agent.fork.json +107 -0
- package/generated/schema/agent.lock_set.json +105 -0
- package/generated/schema/agent.registered.json +130 -0
- package/generated/schema/agent.released.json +129 -0
- package/generated/schema/agent.updated.json +151 -0
- package/generated/schema/approval.executed.json +125 -0
- package/generated/schema/approval.request.json +279 -0
- package/generated/schema/approval.resolved.json +162 -0
- package/generated/schema/approval.routed.json +185 -0
- package/generated/schema/artifact.create.json +206 -0
- package/generated/schema/attachment.fetched.json +114 -0
- package/generated/schema/attachment.limits_set.json +136 -0
- package/generated/schema/budget.warning.json +152 -0
- package/generated/schema/checkpoint.json +111 -0
- package/generated/schema/context.compacted.json +124 -0
- package/generated/schema/context.usage.json +120 -0
- package/generated/schema/exchange.limits_set.json +127 -0
- package/generated/schema/exchange.set.json +144 -0
- package/generated/schema/feedback.json +173 -0
- package/generated/schema/handoff.json +122 -0
- package/generated/schema/harness.removed.json +122 -0
- package/generated/schema/harness.transferred.json +117 -0
- package/generated/schema/hello.json +509 -0
- package/generated/schema/join.allowed.json +176 -0
- package/generated/schema/join.denied.json +150 -0
- package/generated/schema/lane.updated.json +223 -0
- package/generated/schema/membership.added.json +153 -0
- package/generated/schema/membership.removed.json +126 -0
- package/generated/schema/membership.replaced.json +106 -0
- package/generated/schema/message.deleted.json +105 -0
- package/generated/schema/message.edited.json +107 -0
- package/generated/schema/message.handed.json +111 -0
- package/generated/schema/message.heard.json +100 -0
- package/generated/schema/message.held.json +181 -0
- package/generated/schema/message.hidden.json +100 -0
- package/generated/schema/message.new.json +1369 -0
- package/generated/schema/message.overheard.json +701 -0
- package/generated/schema/message.pinned.json +100 -0
- package/generated/schema/message.post.json +290 -0
- package/generated/schema/message.shown.json +100 -0
- package/generated/schema/message.unpinned.json +100 -0
- package/generated/schema/person.face_set.json +134 -0
- package/generated/schema/person.joined.json +128 -0
- package/generated/schema/person.removed.json +133 -0
- package/generated/schema/person.renamed.json +114 -0
- package/generated/schema/policy.updated.json +277 -0
- package/generated/schema/project.changed.json +199 -0
- package/generated/schema/question.answered.json +154 -0
- package/generated/schema/question.ask.json +194 -0
- package/generated/schema/receipt.json +109 -0
- package/generated/schema/relay.set.json +99 -0
- package/generated/schema/role.changed.json +116 -0
- package/generated/schema/run.cancel.json +106 -0
- package/generated/schema/run.completed.json +139 -0
- package/generated/schema/run.failed.json +135 -0
- package/generated/schema/run.pause.json +106 -0
- package/generated/schema/run.plan.json +128 -0
- package/generated/schema/run.requested.json +309 -0
- package/generated/schema/run.resume.json +106 -0
- package/generated/schema/run.started.json +142 -0
- package/generated/schema/run.status.json +120 -0
- package/generated/schema/run.steer.json +163 -0
- package/generated/schema/session.ended.json +106 -0
- package/generated/schema/session.renamed.json +108 -0
- package/generated/schema/session.started.json +116 -0
- package/generated/schema/space.claimed.json +107 -0
- package/generated/schema/space.created.json +148 -0
- package/generated/schema/space.erased.json +129 -0
- package/generated/schema/space.lead_set.json +108 -0
- package/generated/schema/space.lock_set.json +99 -0
- package/generated/schema/space.spend_ceiling_set.json +102 -0
- package/generated/schema/space.updated.json +112 -0
- package/generated/schema/step.log.json +187 -0
- package/generated/schema/task.json +268 -0
- package/generated/schema/turn.passed.json +99 -0
- package/generated/schema/usage.json +155 -0
- package/generated/schema/workspace.renamed.json +107 -0
- package/generated/types.ts +4178 -0
- package/package.json +38 -3
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The face a person has chosen for a space: a mark from Chips' own library and the ground it
|
|
3
|
+
* sits on (21 September 2026).
|
|
4
|
+
*
|
|
5
|
+
* It is a person's own setting, not a fact about the room (the alternative — `space.icon_set`
|
|
6
|
+
* on the log, one face for everybody — is a bigger thing and nobody has asked for it). So it
|
|
7
|
+
* lives beside the notification settings from M5.6 rather than in the event log: read and
|
|
8
|
+
* written over `/v1/me/space-icons`, private to the person who chose it, and carried to every
|
|
9
|
+
* device they sign in on. Two people may see one room differently, which is the point.
|
|
10
|
+
*
|
|
11
|
+
* An agent's face is the same pair, a mark and a ground, but it is the agent's and one for
|
|
12
|
+
* everybody: it rides on `agent.updated` and in the directory, not here (ADR 0089). So is a
|
|
13
|
+
* person's own face, on `person.face_set` (ADR 0139).
|
|
14
|
+
*
|
|
15
|
+
* Since 7 October 2026 a face may be letters in place of a mark: one or two of them, or an emoji
|
|
16
|
+
* or two, typed by the person choosing it ("AB", "X", "🦊"). Arjun asked for it on every face at
|
|
17
|
+
* once — a space's, an agent's and a person's own — so it is a third field of the one shape, not
|
|
18
|
+
* a shape of its own (ADR 0139).
|
|
19
|
+
*
|
|
20
|
+
* The ground is an **index**, not a colour. A hex on the wire would freeze the palette into
|
|
21
|
+
* every stored row: the lift of 21 September 2026 moved all eight avatar hues, and an index
|
|
22
|
+
* means everyone's chosen face moved with it instead of stranding them on the old paint.
|
|
23
|
+
*/
|
|
24
|
+
import { z } from "zod";
|
|
25
|
+
/**
|
|
26
|
+
* How many grounds a client offers: the design system's eight avatar hues, and nineteen more
|
|
27
|
+
* that belong to no participant. A client draws index `n` from its own list; the wire only
|
|
28
|
+
* agrees on how many there are.
|
|
29
|
+
*
|
|
30
|
+
* Twelve until 26 September 2026, when Arjun asked for more colours: fifteen were added after
|
|
31
|
+
* them (a red, an orange, an olive, three greys and a deep shade of every hue), so a face chosen
|
|
32
|
+
* on the twelve kept its index and its colour. A client older than that draws an index past its
|
|
33
|
+
* own list on its first ground.
|
|
34
|
+
*/
|
|
35
|
+
export const SPACE_ICON_GROUNDS = 27;
|
|
36
|
+
/** As many letters as a face holds: "AB", or one emoji beside another. */
|
|
37
|
+
export const MOST_FACE_LETTERS = 2;
|
|
38
|
+
/**
|
|
39
|
+
* One letter as a reader sees it: a base and whatever joins it — a combining accent, a skin tone,
|
|
40
|
+
* an emoji's variation selector or keycap, a flag's tags, or another emoji after a joiner — and a
|
|
41
|
+
* flag's two regional indicators. A face's "two letters" are two of these, so "👨👩👧" is one and
|
|
42
|
+
* "é" is one however it was typed.
|
|
43
|
+
*
|
|
44
|
+
* Written out rather than `Intl.Segmenter`, which Hermes does not have: the phone, the server and
|
|
45
|
+
* the web count the same letters the same way, and a face one of them takes the others take. It
|
|
46
|
+
* leaves out what a face would never be (Hangul typed jamo by jamo); a cluster it splits in two
|
|
47
|
+
* counts as two letters, which is a refusal, never a face drawn wrong.
|
|
48
|
+
*/
|
|
49
|
+
const LETTER = /\p{Regional_Indicator}{2}|\P{M}(?:[\p{M}\p{Emoji_Modifier}\u{E0020}-\u{E007F}]|\u200d\P{M}?)*|\p{M}+/gu;
|
|
50
|
+
/** The letters of some text, as a reader counts them (`LETTER`). */
|
|
51
|
+
export function lettersIn(text) {
|
|
52
|
+
return text.match(LETTER) ?? [];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* What a face's letters are, from what was typed: no spaces, and no more than two. What a field
|
|
56
|
+
* keeps as somebody types, so a third letter or a space never reaches the face.
|
|
57
|
+
*/
|
|
58
|
+
export function faceLetters(typed) {
|
|
59
|
+
return lettersIn(typed.replace(/\s+/gu, "")).slice(0, MOST_FACE_LETTERS).join("");
|
|
60
|
+
}
|
|
61
|
+
/** How wide one letter is, in the font's size: a capital, a CJK character, an emoji. */
|
|
62
|
+
const WIDTHS = { letter: 0.7, wide: 1, emoji: 1.2 };
|
|
63
|
+
/** As wide as a face's letters may stand, in the initials' size: what two capitals take. */
|
|
64
|
+
const ROOM = 1.7;
|
|
65
|
+
/** A single emoji is this much larger than the initials, filling the face as one capital does. */
|
|
66
|
+
const ONE_EMOJI = 1.25;
|
|
67
|
+
const EMOJI = /\p{Extended_Pictographic}|\p{Regional_Indicator}/u;
|
|
68
|
+
const WIDE = /\p{Ideographic}|[\u3040-\u30ff\uac00-\ud7a3]/u;
|
|
69
|
+
function widthOf(letter) {
|
|
70
|
+
if (EMOJI.test(letter))
|
|
71
|
+
return WIDTHS.emoji;
|
|
72
|
+
return WIDE.test(letter) ? WIDTHS.wide : WIDTHS.letter;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* How large a face's letters are drawn, against the size its initials are (ADR 0139): 1 for
|
|
76
|
+
* letters, which is the initials' own size; larger for one emoji, which fills a face as one
|
|
77
|
+
* capital does; smaller where two emoji, an emoji and a letter, or two wide characters would not
|
|
78
|
+
* fit inside it. Here, beside the letters' own rule, so the phone and the Mac draw them alike.
|
|
79
|
+
*/
|
|
80
|
+
export function lettersScale(letters) {
|
|
81
|
+
const each = lettersIn(letters);
|
|
82
|
+
const only = each[0];
|
|
83
|
+
if (each.length === 1 && only !== undefined && EMOJI.test(only))
|
|
84
|
+
return ONE_EMOJI;
|
|
85
|
+
const width = each.reduce((sum, letter) => sum + widthOf(letter), 0);
|
|
86
|
+
return width <= ROOM ? 1 : Math.round((ROOM / width) * 100) / 100;
|
|
87
|
+
}
|
|
88
|
+
/** Whether these are a face's letters as they are: one or two, nothing round them, nothing hidden. */
|
|
89
|
+
function areFaceLetters(letters) {
|
|
90
|
+
const count = lettersIn(letters).length;
|
|
91
|
+
return (count >= 1 &&
|
|
92
|
+
count <= MOST_FACE_LETTERS &&
|
|
93
|
+
!/[\s\p{Cc}]/u.test(letters) &&
|
|
94
|
+
faceLetters(letters) === letters);
|
|
95
|
+
}
|
|
96
|
+
export const spaceIcon = z.object({
|
|
97
|
+
/**
|
|
98
|
+
* A mark's name in the library — letters only, as every name in it is — or empty, for a face
|
|
99
|
+
* that is a colour and nothing else.
|
|
100
|
+
*
|
|
101
|
+
* A ground is a choice in its own right: a room can be *the teal one* before it is the one
|
|
102
|
+
* with the rocket on it, and down a list of eighty rows the colour is what the eye catches
|
|
103
|
+
* first. Requiring a mark meant the picker's colour strip wrote nothing until a mark had been
|
|
104
|
+
* tapped — the swatch ticked, the row behind did not move, and it read as a broken button
|
|
105
|
+
* (Arjun, 22 September 2026: "it always fails the first time, then after 2-3 tries it starts
|
|
106
|
+
* working"). An empty mark draws the initials on the chosen ground, which is exactly what the
|
|
107
|
+
* picker previews.
|
|
108
|
+
*/
|
|
109
|
+
icon: z
|
|
110
|
+
.string()
|
|
111
|
+
.max(40)
|
|
112
|
+
.regex(/^[a-zA-Z]*$/, "A mark's name is letters."),
|
|
113
|
+
ground: z
|
|
114
|
+
.number()
|
|
115
|
+
.int()
|
|
116
|
+
.min(0)
|
|
117
|
+
.max(SPACE_ICON_GROUNDS - 1),
|
|
118
|
+
/**
|
|
119
|
+
* Letters the face wears in place of a mark (ADR 0139): one or two, or an emoji or two, on the
|
|
120
|
+
* ground. With them the mark is empty. Absent, the face is its mark, or the initials on the
|
|
121
|
+
* ground when the mark is empty too. A client older than them draws the initials on the ground.
|
|
122
|
+
*/
|
|
123
|
+
letters: z
|
|
124
|
+
.string()
|
|
125
|
+
.min(1)
|
|
126
|
+
.max(32)
|
|
127
|
+
.refine(areFaceLetters, "Up to two letters or emoji, and no spaces.")
|
|
128
|
+
.optional()
|
|
129
|
+
.describe("One or two letters, or an emoji or two, the face wears on its ground in place of a mark (ADR 0139); the mark is empty beside them. Absent on a face that is a mark, or only a colour."),
|
|
130
|
+
});
|
|
131
|
+
/** The face a person sent, or the reason it is not one. */
|
|
132
|
+
export function parseSpaceIcon(raw) {
|
|
133
|
+
const parsed = spaceIcon.safeParse(raw);
|
|
134
|
+
if (parsed.success)
|
|
135
|
+
return { ok: true, value: parsed.data };
|
|
136
|
+
const first = parsed.error.issues[0];
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
message: first === undefined ? "not a face" : `${first.path.join(".")}: ${first.message}`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=space-icons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"space-icons.js","sourceRoot":"","sources":["../../src/space-icons.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a room's job has spent, and what the room allows a job (ADR 0117).
|
|
3
|
+
*
|
|
4
|
+
* A **job** is the work a room's agents do after the last thing a person did there (a message, an
|
|
5
|
+
* answer, letting the agents carry on: the `PERSON_ACTS` the referee counts from), or after a brief
|
|
6
|
+
* was handed into the room, whichever is later. Its **spend** is what the runs reported costing
|
|
7
|
+
* after that point, of any harness: a run's own report is its total so far, so a run that began
|
|
8
|
+
* before the point counts only what it reported after it. A run that reported no cost counts
|
|
9
|
+
* nothing, and the room says how many did.
|
|
10
|
+
*
|
|
11
|
+
* Every room allows a job a **ceiling**: `DEFAULT_SPEND_CEILING_USD` until the workspace's owner,
|
|
12
|
+
* in the room, sets another (`space.spend_ceiling_set`, ADR 0196), from `SPEND_CEILING_MIN` to
|
|
13
|
+
* `SPEND_CEILING_MAX` in steps of `SPEND_CEILING_STEP`. Chips works the spend out and hands it to
|
|
14
|
+
* every harness with the message that gives a turn (`context.spend`), and to the agent in the
|
|
15
|
+
* room's note (`spendWords`).
|
|
16
|
+
*
|
|
17
|
+
* At `SPEND_WARN_AT` of the ceiling Chips warns the room's harnesses, and at the ceiling it holds
|
|
18
|
+
* the agents until a person acts (ADR 0118): `spendStage` says which.
|
|
19
|
+
*/
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
/** What a room allows a job until a person there says otherwise, in US dollars. */
|
|
22
|
+
export declare const DEFAULT_SPEND_CEILING_USD = 3;
|
|
23
|
+
/** The least a room may allow a job. */
|
|
24
|
+
export declare const SPEND_CEILING_MIN = 0.25;
|
|
25
|
+
/** The most a room may allow a job. */
|
|
26
|
+
export declare const SPEND_CEILING_MAX = 100;
|
|
27
|
+
/** A ceiling is a whole number of these. */
|
|
28
|
+
export declare const SPEND_CEILING_STEP = 0.25;
|
|
29
|
+
/** The share of the ceiling at which Chips warns the room's harnesses (ADR 0118). */
|
|
30
|
+
export declare const SPEND_WARN_AT = 0.8;
|
|
31
|
+
/** Whether `usd` is a ceiling a room may have: in range, and a whole number of steps. */
|
|
32
|
+
export declare function isSpendCeiling(usd: number): boolean;
|
|
33
|
+
/** A ceiling as a room sets it: an amount, or `null` for the default. */
|
|
34
|
+
export declare const spendCeiling: z.ZodNullable<z.ZodNumber>;
|
|
35
|
+
export declare const jobSpend: z.ZodObject<{
|
|
36
|
+
ceiling_usd: z.ZodNumber;
|
|
37
|
+
spent_usd: z.ZodNumber;
|
|
38
|
+
since_seq: z.ZodInt;
|
|
39
|
+
uncounted_runs: z.ZodInt;
|
|
40
|
+
}, z.core.$strip>;
|
|
41
|
+
export type JobSpend = z.infer<typeof jobSpend>;
|
|
42
|
+
/** An amount as the room's words say it: "$3.00", "$0.25". */
|
|
43
|
+
export declare function dollars(usd: number): string;
|
|
44
|
+
/**
|
|
45
|
+
* Where a job stands against its room's ceiling (ADR 0118): `within` it, `most` spent (from
|
|
46
|
+
* `SPEND_WARN_AT`), or at the `ceiling`, where Chips holds the agents until a person acts.
|
|
47
|
+
*/
|
|
48
|
+
export type SpendStage = "within" | "most" | "ceiling";
|
|
49
|
+
export declare function spendStage(spend: Pick<JobSpend, "ceiling_usd" | "spent_usd">): SpendStage;
|
|
50
|
+
/**
|
|
51
|
+
* The room note's line about the job's spend (ADR 0117), with what Chips does at the ceiling
|
|
52
|
+
* (ADR 0118): "This job has spent $1.20 of the $3.00 this room allows a job; at $3.00 Chips holds
|
|
53
|
+
* the agents until a person acts." From most of it spent, what to do about it; at the ceiling,
|
|
54
|
+
* that the agents are held. Then how many runs reported no cost, when any did.
|
|
55
|
+
*/
|
|
56
|
+
export declare function spendWords(spend: JobSpend): string;
|
|
57
|
+
//# sourceMappingURL=spend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spend.d.ts","sourceRoot":"","sources":["../../src/spend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,mFAAmF;AACnF,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,wCAAwC;AACxC,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,uCAAuC;AACvC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,4CAA4C;AAC5C,eAAO,MAAM,kBAAkB,OAAO,CAAC;AACvC,qFAAqF;AACrF,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED,yEAAyE;AACzE,eAAO,MAAM,YAAY,4BAKZ,CAAC;AAEd,eAAO,MAAM,QAAQ;;;;;iBAyBqE,CAAC;AAC3F,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEhD,8DAA8D;AAC9D,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAEvD,wBAAgB,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,aAAa,GAAG,WAAW,CAAC,GAAG,UAAU,CAMzF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAWlD"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a room's job has spent, and what the room allows a job (ADR 0117).
|
|
3
|
+
*
|
|
4
|
+
* A **job** is the work a room's agents do after the last thing a person did there (a message, an
|
|
5
|
+
* answer, letting the agents carry on: the `PERSON_ACTS` the referee counts from), or after a brief
|
|
6
|
+
* was handed into the room, whichever is later. Its **spend** is what the runs reported costing
|
|
7
|
+
* after that point, of any harness: a run's own report is its total so far, so a run that began
|
|
8
|
+
* before the point counts only what it reported after it. A run that reported no cost counts
|
|
9
|
+
* nothing, and the room says how many did.
|
|
10
|
+
*
|
|
11
|
+
* Every room allows a job a **ceiling**: `DEFAULT_SPEND_CEILING_USD` until the workspace's owner,
|
|
12
|
+
* in the room, sets another (`space.spend_ceiling_set`, ADR 0196), from `SPEND_CEILING_MIN` to
|
|
13
|
+
* `SPEND_CEILING_MAX` in steps of `SPEND_CEILING_STEP`. Chips works the spend out and hands it to
|
|
14
|
+
* every harness with the message that gives a turn (`context.spend`), and to the agent in the
|
|
15
|
+
* room's note (`spendWords`).
|
|
16
|
+
*
|
|
17
|
+
* At `SPEND_WARN_AT` of the ceiling Chips warns the room's harnesses, and at the ceiling it holds
|
|
18
|
+
* the agents until a person acts (ADR 0118): `spendStage` says which.
|
|
19
|
+
*/
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
/** What a room allows a job until a person there says otherwise, in US dollars. */
|
|
22
|
+
export const DEFAULT_SPEND_CEILING_USD = 3;
|
|
23
|
+
/** The least a room may allow a job. */
|
|
24
|
+
export const SPEND_CEILING_MIN = 0.25;
|
|
25
|
+
/** The most a room may allow a job. */
|
|
26
|
+
export const SPEND_CEILING_MAX = 100;
|
|
27
|
+
/** A ceiling is a whole number of these. */
|
|
28
|
+
export const SPEND_CEILING_STEP = 0.25;
|
|
29
|
+
/** The share of the ceiling at which Chips warns the room's harnesses (ADR 0118). */
|
|
30
|
+
export const SPEND_WARN_AT = 0.8;
|
|
31
|
+
/** Whether `usd` is a ceiling a room may have: in range, and a whole number of steps. */
|
|
32
|
+
export function isSpendCeiling(usd) {
|
|
33
|
+
if (!Number.isFinite(usd) || usd < SPEND_CEILING_MIN || usd > SPEND_CEILING_MAX)
|
|
34
|
+
return false;
|
|
35
|
+
return Number.isInteger(Math.round(usd * 1e6) / (SPEND_CEILING_STEP * 1e6));
|
|
36
|
+
}
|
|
37
|
+
/** A ceiling as a room sets it: an amount, or `null` for the default. */
|
|
38
|
+
export const spendCeiling = z
|
|
39
|
+
.number()
|
|
40
|
+
.refine(isSpendCeiling, {
|
|
41
|
+
message: `From $${SPEND_CEILING_MIN} to $${SPEND_CEILING_MAX}, in steps of $${SPEND_CEILING_STEP}.`,
|
|
42
|
+
})
|
|
43
|
+
.nullable();
|
|
44
|
+
export const jobSpend = z
|
|
45
|
+
.object({
|
|
46
|
+
ceiling_usd: z
|
|
47
|
+
.number()
|
|
48
|
+
.positive()
|
|
49
|
+
.describe("What the room allows a job, in US dollars: its own ceiling, or the default (3) when nobody has set one."),
|
|
50
|
+
spent_usd: z
|
|
51
|
+
.number()
|
|
52
|
+
.nonnegative()
|
|
53
|
+
.describe("What the room's runs reported costing since the job began, in US dollars, every harness's together."),
|
|
54
|
+
since_seq: z
|
|
55
|
+
.int()
|
|
56
|
+
.nonnegative()
|
|
57
|
+
.describe("Where the job began: the `seq` of the last thing a person did in the room, or of the last brief handed into it, whichever is later; 0 when neither has happened."),
|
|
58
|
+
uncounted_runs: z
|
|
59
|
+
.int()
|
|
60
|
+
.nonnegative()
|
|
61
|
+
.describe("How many of the job's runs reported no cost, and so count nothing."),
|
|
62
|
+
})
|
|
63
|
+
.describe("What a room's job has spent, against what the room allows a job (ADR 0117).");
|
|
64
|
+
/** An amount as the room's words say it: "$3.00", "$0.25". */
|
|
65
|
+
export function dollars(usd) {
|
|
66
|
+
return `$${usd.toFixed(2)}`;
|
|
67
|
+
}
|
|
68
|
+
export function spendStage(spend) {
|
|
69
|
+
// To the cent, as the words say it: a job at $2.999 has spent the $3.00 it was allowed.
|
|
70
|
+
const spent = Math.round(spend.spent_usd * 100);
|
|
71
|
+
const ceiling = Math.round(spend.ceiling_usd * 100);
|
|
72
|
+
if (spent >= ceiling)
|
|
73
|
+
return "ceiling";
|
|
74
|
+
return spent >= Math.round(ceiling * SPEND_WARN_AT) ? "most" : "within";
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The room note's line about the job's spend (ADR 0117), with what Chips does at the ceiling
|
|
78
|
+
* (ADR 0118): "This job has spent $1.20 of the $3.00 this room allows a job; at $3.00 Chips holds
|
|
79
|
+
* the agents until a person acts." From most of it spent, what to do about it; at the ceiling,
|
|
80
|
+
* that the agents are held. Then how many runs reported no cost, when any did.
|
|
81
|
+
*/
|
|
82
|
+
export function spendWords(spend) {
|
|
83
|
+
const spent = dollars(spend.spent_usd);
|
|
84
|
+
const ceiling = dollars(spend.ceiling_usd);
|
|
85
|
+
const stage = spendStage(spend);
|
|
86
|
+
const line = stage === "ceiling"
|
|
87
|
+
? `This job has spent ${spent} of the ${ceiling} this space allows a job, so Chips holds the agents until a person acts: start nothing new, and say what is done and what is left.`
|
|
88
|
+
: `This job has spent ${spent} of the ${ceiling} this space allows a job; at ${ceiling} Chips holds the agents until a person acts.${stage === "most" ? " Most of it is spent: finish the step you are on, and say what is left." : ""}`;
|
|
89
|
+
const n = spend.uncounted_runs;
|
|
90
|
+
if (n === 0)
|
|
91
|
+
return line;
|
|
92
|
+
return `${line} ${n === 1 ? "1 run here reported no cost and is" : `${n} runs here reported no cost and are`} not counted.`;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=spend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spend.js","sourceRoot":"","sources":["../../src/spend.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who may see an event (phase-0-review finding 6).
|
|
3
|
+
*
|
|
4
|
+
* Reading the log and subscribing to it are both scoped by membership: a credential sees the
|
|
5
|
+
* spaces it belongs to, and nothing else. Before this, any credential in a workspace
|
|
6
|
+
* could read every space's events, including a direct space it was not in.
|
|
7
|
+
*
|
|
8
|
+
* The rule, in one place so the live path and the replay path cannot drift:
|
|
9
|
+
*
|
|
10
|
+
* - An event that belongs to a space is visible only to that space's members.
|
|
11
|
+
* - An event with no space — a workspace-wide thing — is visible to everyone in the
|
|
12
|
+
* workspace. In Phase 1 nothing appends one in normal flow; the ones that arrive in M1.4 and
|
|
13
|
+
* M3 (a policy change, a budget warning) will want per-recipient scoping, which is theirs to
|
|
14
|
+
* add. What an agent said in no room (`message.held`, ADR 0087) has no space either, and is
|
|
15
|
+
* its harness's alone: its words are for the room it joins next, not for the workspace.
|
|
16
|
+
* - A person asking for a copy of an agent (`agent.fork`, ADR 0087) is visible to the agent's
|
|
17
|
+
* harness, which makes the copy for a room it is not in.
|
|
18
|
+
* - A person asking a harness for a new agent (`agent.asked`, ADR 0108) is visible to that
|
|
19
|
+
* harness, which makes the agent for a room it is not in.
|
|
20
|
+
* - A harness's agent being made, renamed, archived, given a face or deleted (`agent.registered`,
|
|
21
|
+
* `agent.updated`, `agent.deleted`) has no space either, and went to everybody: a guest in no room with the
|
|
22
|
+
* agent, and every other harness, were sent its name and its harness's own key for it (agents
|
|
23
|
+
* review, finding 3). It is its harness's to hear, and anybody's who is told every agent: an
|
|
24
|
+
* owner or admin of the workspace. Since his call of 19 October 2026 (ADR 0034's addendum) that
|
|
25
|
+
* is no longer every person who is not a guest: a member is told the agents in their rooms, as
|
|
26
|
+
* a guest is. Whoever shares a room with the agent, and a person who owns its harness, are told
|
|
27
|
+
* too, which the caller works out, since a room is not something an event with none can say.
|
|
28
|
+
* - The event that adds or removes a participant is always visible to that participant, so a
|
|
29
|
+
* person can see themselves join a space they are not yet listed in.
|
|
30
|
+
* - The event that opens a space is visible to whoever opened it, who is its first
|
|
31
|
+
* member (ADR 0018) but is not yet listed anywhere a live session has read — and to the
|
|
32
|
+
* person it was opened *for*, since ADR 0024, because a harness opens a space for its owner
|
|
33
|
+
* as it finds one and they would otherwise never be sent the event that names it — and to the
|
|
34
|
+
* harness it was asked *of*, when a person opens a room for a harness to claim, which is how
|
|
35
|
+
* the harness hears that there is one before it is added to it.
|
|
36
|
+
* - The event that opens a thread is visible to everyone in the space it grows in (M5.4): a
|
|
37
|
+
* thread has no members of its own, and its events are theirs from then on.
|
|
38
|
+
* - An approval that names the viewer as somebody who may answer it is visible to them
|
|
39
|
+
* wherever it is (M5.5): the lane's lead, handed a low-risk ask by policy, is not in the
|
|
40
|
+
* specialist's room and would otherwise never be sent what it is to decide. Since ADR 0042 a
|
|
41
|
+
* person named from elsewhere in the workspace is in the same position, and the decision and
|
|
42
|
+
* its outcome name them too, so what they were sent is answered on their screen as well.
|
|
43
|
+
* - A message a person deleted for themselves, and their Undo (ADR 0167), are theirs alone,
|
|
44
|
+
* though they belong to a room: nobody else in it, and no harness, is told that one person
|
|
45
|
+
* stopped seeing a line. The one rule that takes something away from a room's members.
|
|
46
|
+
*
|
|
47
|
+
* The replay path builds a SQL predicate from the same member set (see the server's event store)
|
|
48
|
+
* plus the membership events naming the viewer. The join needs no special case — a viewer's set
|
|
49
|
+
* already lists every space they are in — but a removal is from a space they are no longer in,
|
|
50
|
+
* and a client resuming after it left a space elsewhere must still be told.
|
|
51
|
+
*
|
|
52
|
+
* It lives with the protocol so that the server and the conformance fake ask the same function:
|
|
53
|
+
* the fake's own copy had come to send what an agent said in no room to everybody (agents
|
|
54
|
+
* review, finding 37).
|
|
55
|
+
*/
|
|
56
|
+
/** An event as the rule needs it: what it is, where, by whom, and what it carries. */
|
|
57
|
+
export interface SeenEvent {
|
|
58
|
+
readonly type: string;
|
|
59
|
+
readonly space_id: string | null;
|
|
60
|
+
readonly actor: {
|
|
61
|
+
readonly id: string;
|
|
62
|
+
};
|
|
63
|
+
readonly payload: Readonly<Record<string, unknown>>;
|
|
64
|
+
}
|
|
65
|
+
export interface Viewer {
|
|
66
|
+
readonly participantId: string;
|
|
67
|
+
/** The spaces this viewer is a member of, resolved from the memberships projection. */
|
|
68
|
+
readonly memberSpaces: ReadonlySet<string>;
|
|
69
|
+
/**
|
|
70
|
+
* Whether the viewer is told who every person in the workspace is: a person who is not a guest
|
|
71
|
+
* (ADR 0034). A guest and a harness are told only whom they share a room with.
|
|
72
|
+
*/
|
|
73
|
+
readonly seesDirectory?: boolean | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Whether the viewer is told every agent in the workspace: an owner or admin, who may move,
|
|
76
|
+
* archive or delete any of them (his call of 19 October 2026, ADR 0034's addendum). Anybody
|
|
77
|
+
* else is told the agents in their rooms, and a harness its own.
|
|
78
|
+
*/
|
|
79
|
+
readonly seesAgents?: boolean | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Who else the viewer is in rooms: a harness's agents (ADR 0087), which it speaks for on one
|
|
82
|
+
* connection. What names one of them names the viewer.
|
|
83
|
+
*/
|
|
84
|
+
readonly alsoIs?: ReadonlySet<string> | undefined;
|
|
85
|
+
}
|
|
86
|
+
/** The events that add a participant to a space or remove one. Always visible to that participant. */
|
|
87
|
+
export declare const MEMBERSHIP_EVENTS: ReadonlySet<string>;
|
|
88
|
+
/**
|
|
89
|
+
* Where an agent is (ADR 0087): put in a room or taken out of one. The room is told, as of
|
|
90
|
+
* anything in it, and so is the agent's harness, which has left the room by the time its agent's
|
|
91
|
+
* release is written. Nobody else: a person reads an agent's room from the directory, and an
|
|
92
|
+
* event naming a room a client has never heard of would make it one.
|
|
93
|
+
*/
|
|
94
|
+
export declare const WHEREABOUTS_EVENTS: ReadonlySet<string>;
|
|
95
|
+
/**
|
|
96
|
+
* A person asking for a copy of an agent in a room (ADR 0087, Fork). The room is told, as of
|
|
97
|
+
* anything in it, and so is the agent's harness, which makes the copy: the agent it names is in
|
|
98
|
+
* another room, so its harness is not a member of the room the copy is for.
|
|
99
|
+
*/
|
|
100
|
+
export declare const FORK_EVENTS: ReadonlySet<string>;
|
|
101
|
+
/**
|
|
102
|
+
* A person asking a harness for a new agent in a room (ADR 0108). The room is told, as of anything
|
|
103
|
+
* in it, and so is the harness the event names, which makes the agent: no agent of its is there
|
|
104
|
+
* yet, and a harness is a member of no room itself.
|
|
105
|
+
*/
|
|
106
|
+
export declare const ASK_EVENTS: ReadonlySet<string>;
|
|
107
|
+
/**
|
|
108
|
+
* What an agent said while in no room (ADR 0087, rule 6). It has no space, so the workspace-wide
|
|
109
|
+
* rule would send it to everyone — every person, guests too, and every other harness — before
|
|
110
|
+
* the room it is meant for hears it. Only the agent's own harness is told; a person reads how
|
|
111
|
+
* many wait from the directory (`held`).
|
|
112
|
+
*/
|
|
113
|
+
export declare const HELD_EVENTS: ReadonlySet<string>;
|
|
114
|
+
/**
|
|
115
|
+
* A harness's agent made or changed (ADR 0087): who it is, what it is called, whether it is
|
|
116
|
+
* archived, the face it wears. No space, and not everybody's: see the rule above.
|
|
117
|
+
*/
|
|
118
|
+
export declare const DIRECTORY_EVENTS: ReadonlySet<string>;
|
|
119
|
+
/**
|
|
120
|
+
* What came of a join request (ADR 0122): who asked, from where, and what a person let in. No
|
|
121
|
+
* space, and not everybody's: a harness and a guest are told nothing of who else is let in. A
|
|
122
|
+
* person who sees the whole directory is, as they see the harness appear in it.
|
|
123
|
+
*/
|
|
124
|
+
export declare const JOIN_EVENTS: ReadonlySet<string>;
|
|
125
|
+
/**
|
|
126
|
+
* A person's face chosen (ADR 0139). No space, and a person's to see, not a harness's: a harness
|
|
127
|
+
* draws nobody, and one that does not know the event has no business being sent it. A person who
|
|
128
|
+
* sees the directory is told, as of a join; a guest reads it the next time it reads who is who.
|
|
129
|
+
*/
|
|
130
|
+
export declare const FACE_EVENTS: ReadonlySet<string>;
|
|
131
|
+
/**
|
|
132
|
+
* An agent's changes locked or let go (ADR 0199). No space, and a person's to see, not a harness's,
|
|
133
|
+
* as a face is: the lock holds people's hands, and a harness is held by nothing it says. A person
|
|
134
|
+
* told every agent is told; anybody else reads it the next time they read who is who.
|
|
135
|
+
*/
|
|
136
|
+
export declare const LOCK_EVENTS: ReadonlySet<string>;
|
|
137
|
+
/**
|
|
138
|
+
* A person deleting a message for themselves, and taking that back (ADR 0167). They belong to the
|
|
139
|
+
* room the message is in, and are sent only to the person who did them, on each of their devices.
|
|
140
|
+
*/
|
|
141
|
+
export declare const SELF_EVENTS: ReadonlySet<string>;
|
|
142
|
+
/**
|
|
143
|
+
* Whether a live event should be delivered to a viewer. For `DIRECTORY_EVENTS` a caller that
|
|
144
|
+
* gets `false` asks one thing more, which this cannot: whether the viewer shares a room with the
|
|
145
|
+
* agent the event is about, or is a person who owns its harness.
|
|
146
|
+
*/
|
|
147
|
+
export declare function canSee(event: SeenEvent, viewer: Viewer): boolean;
|
|
148
|
+
/**
|
|
149
|
+
* The events that carry who may answer an approval, resolved to ids. The two decisions are
|
|
150
|
+
* here as well since ADR 0042: somebody named outside the room is sent the ask, so they are
|
|
151
|
+
* sent what came of it — otherwise the card on their phone would never cool.
|
|
152
|
+
*/
|
|
153
|
+
export declare const APPROVER_EVENTS: ReadonlySet<string>;
|
|
154
|
+
/** True when an approval names the viewer as somebody who may answer it (M5.5). */
|
|
155
|
+
export declare function namesApprover(event: SeenEvent, participantId: string): boolean;
|
|
156
|
+
/** True when this opens a thread in one of the viewer's spaces, which makes it theirs too (M5.4). */
|
|
157
|
+
export declare function opensThreadIn(event: SeenEvent, memberSpaces: ReadonlySet<string>): boolean;
|
|
158
|
+
/**
|
|
159
|
+
* True when this is a space being opened for the viewer: by them, on their behalf, or for them
|
|
160
|
+
* to claim. A harness asked beside another from the + (`also_asked_of`) is asked as much as the
|
|
161
|
+
* first: it was sent nothing until its next `hello`, so it never learnt the room was asked of it,
|
|
162
|
+
* and the first words there went unanswered (agents review, finding 17).
|
|
163
|
+
*/
|
|
164
|
+
export declare function opensFor(event: SeenEvent, participantId: string): boolean;
|
|
165
|
+
/**
|
|
166
|
+
* True when a membership event is about this viewer, so they see the moment they are added: the
|
|
167
|
+
* one added or removed, or either side of a replacement (ADR 0087).
|
|
168
|
+
*/
|
|
169
|
+
export declare function namesViewer(event: SeenEvent, participantId: string): boolean;
|
|
170
|
+
//# sourceMappingURL=visibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visibility.d.ts","sourceRoot":"","sources":["../../src/visibility.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,sFAAsF;AACtF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,uFAAuF;IACvF,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1C;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;CACnD;AAOD,sGAAsG;AACtG,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAIhD,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAGjD,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,MAAM,CAA2B,CAAC;AAExE;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,MAAM,CAA4B,CAAC;AAExE;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,MAAM,CAA6B,CAAC;AAE1E;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAI/C,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,MAAM,CAA4C,CAAC;AAEzF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,MAAM,CAAgC,CAAC;AAE7E;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,MAAM,CAA+B,CAAC;AAE5E;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,MAAM,CAAgD,CAAC;AAkB7F;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAgBhE;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAK9C,CAAC;AAEH,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAI9E;AAED,qGAAqG;AACrG,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAI1F;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CASzE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAO5E"}
|