@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.
Files changed (371) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +56 -2
  3. package/dist/generated/types.d.ts +4052 -0
  4. package/dist/generated/types.d.ts.map +1 -0
  5. package/dist/generated/types.js +7 -0
  6. package/dist/generated/types.js.map +1 -0
  7. package/dist/src/address.d.ts +106 -0
  8. package/dist/src/address.d.ts.map +1 -0
  9. package/dist/src/address.js +141 -0
  10. package/dist/src/address.js.map +1 -0
  11. package/dist/src/agent-context-windows.d.ts +235 -0
  12. package/dist/src/agent-context-windows.d.ts.map +1 -0
  13. package/dist/src/agent-context-windows.js +213 -0
  14. package/dist/src/agent-context-windows.js.map +1 -0
  15. package/dist/src/agent-heartbeats.d.ts +106 -0
  16. package/dist/src/agent-heartbeats.d.ts.map +1 -0
  17. package/dist/src/agent-heartbeats.js +111 -0
  18. package/dist/src/agent-heartbeats.js.map +1 -0
  19. package/dist/src/agent-models.d.ts +158 -0
  20. package/dist/src/agent-models.d.ts.map +1 -0
  21. package/dist/src/agent-models.js +171 -0
  22. package/dist/src/agent-models.js.map +1 -0
  23. package/dist/src/agent-place.d.ts +76 -0
  24. package/dist/src/agent-place.d.ts.map +1 -0
  25. package/dist/src/agent-place.js +80 -0
  26. package/dist/src/agent-place.js.map +1 -0
  27. package/dist/src/agents.d.ts +24 -0
  28. package/dist/src/agents.d.ts.map +1 -0
  29. package/dist/src/agents.js +58 -0
  30. package/dist/src/agents.js.map +1 -0
  31. package/dist/src/capabilities.d.ts +121 -0
  32. package/dist/src/capabilities.d.ts.map +1 -0
  33. package/dist/src/capabilities.js +120 -0
  34. package/dist/src/capabilities.js.map +1 -0
  35. package/dist/src/checklist.d.ts +19 -0
  36. package/dist/src/checklist.d.ts.map +1 -0
  37. package/dist/src/checklist.js +22 -0
  38. package/dist/src/checklist.js.map +1 -0
  39. package/dist/src/commands.d.ts +50 -0
  40. package/dist/src/commands.d.ts.map +1 -0
  41. package/dist/src/commands.js +274 -0
  42. package/dist/src/commands.js.map +1 -0
  43. package/dist/src/connectors.d.ts +90 -0
  44. package/dist/src/connectors.d.ts.map +1 -0
  45. package/dist/src/connectors.js +119 -0
  46. package/dist/src/connectors.js.map +1 -0
  47. package/dist/src/context-files.d.ts +304 -0
  48. package/dist/src/context-files.d.ts.map +1 -0
  49. package/dist/src/context-files.js +247 -0
  50. package/dist/src/context-files.js.map +1 -0
  51. package/dist/src/context.d.ts +369 -0
  52. package/dist/src/context.d.ts.map +1 -0
  53. package/dist/src/context.js +526 -0
  54. package/dist/src/context.js.map +1 -0
  55. package/dist/src/direct-asks.d.ts +36 -0
  56. package/dist/src/direct-asks.d.ts.map +1 -0
  57. package/dist/src/direct-asks.js +43 -0
  58. package/dist/src/direct-asks.js.map +1 -0
  59. package/dist/src/envelope.d.ts +70 -0
  60. package/dist/src/envelope.d.ts.map +1 -0
  61. package/dist/src/envelope.js +46 -0
  62. package/dist/src/envelope.js.map +1 -0
  63. package/dist/src/events/catalogue.d.ts +50 -0
  64. package/dist/src/events/catalogue.d.ts.map +1 -0
  65. package/dist/src/events/catalogue.js +70 -0
  66. package/dist/src/events/catalogue.js.map +1 -0
  67. package/dist/src/events/chips-to-harness.d.ts +37 -0
  68. package/dist/src/events/chips-to-harness.d.ts.map +1 -0
  69. package/dist/src/events/chips-to-harness.js +511 -0
  70. package/dist/src/events/chips-to-harness.js.map +1 -0
  71. package/dist/src/events/harness-to-chips.d.ts +38 -0
  72. package/dist/src/events/harness-to-chips.d.ts.map +1 -0
  73. package/dist/src/events/harness-to-chips.js +593 -0
  74. package/dist/src/events/harness-to-chips.js.map +1 -0
  75. package/dist/src/events/index.d.ts +6 -0
  76. package/dist/src/events/index.d.ts.map +1 -0
  77. package/dist/src/events/index.js +5 -0
  78. package/dist/src/events/index.js.map +1 -0
  79. package/dist/src/events/workspace.d.ts +222 -0
  80. package/dist/src/events/workspace.d.ts.map +1 -0
  81. package/dist/src/events/workspace.js +1039 -0
  82. package/dist/src/events/workspace.js.map +1 -0
  83. package/dist/src/exchange.d.ts +262 -0
  84. package/dist/src/exchange.d.ts.map +1 -0
  85. package/dist/src/exchange.js +413 -0
  86. package/dist/src/exchange.js.map +1 -0
  87. package/dist/src/first-names.d.ts +29 -0
  88. package/dist/src/first-names.d.ts.map +1 -0
  89. package/dist/src/first-names.js +80 -0
  90. package/dist/src/first-names.js.map +1 -0
  91. package/dist/src/frames.d.ts +526 -0
  92. package/dist/src/frames.d.ts.map +1 -0
  93. package/dist/src/frames.js +346 -0
  94. package/dist/src/frames.js.map +1 -0
  95. package/dist/src/harness-jobs.d.ts +313 -0
  96. package/dist/src/harness-jobs.d.ts.map +1 -0
  97. package/dist/src/harness-jobs.js +210 -0
  98. package/dist/src/harness-jobs.js.map +1 -0
  99. package/dist/src/ids/index.d.ts +3 -0
  100. package/dist/src/ids/index.d.ts.map +1 -0
  101. package/dist/src/ids/index.js +2 -0
  102. package/dist/src/ids/index.js.map +1 -0
  103. package/dist/src/ids/ulid.d.ts +96 -0
  104. package/dist/src/ids/ulid.d.ts.map +1 -0
  105. package/dist/src/ids/ulid.js +212 -0
  106. package/dist/src/ids/ulid.js.map +1 -0
  107. package/dist/src/index.d.ts +81 -0
  108. package/dist/src/index.d.ts.map +1 -0
  109. package/dist/src/index.js +47 -0
  110. package/dist/src/index.js.map +1 -0
  111. package/dist/src/invite-link.d.ts +64 -0
  112. package/dist/src/invite-link.d.ts.map +1 -0
  113. package/dist/src/invite-link.js +99 -0
  114. package/dist/src/invite-link.js.map +1 -0
  115. package/dist/src/join.d.ts +188 -0
  116. package/dist/src/join.d.ts.map +1 -0
  117. package/dist/src/join.js +190 -0
  118. package/dist/src/join.js.map +1 -0
  119. package/dist/src/limits.d.ts +50 -0
  120. package/dist/src/limits.d.ts.map +1 -0
  121. package/dist/src/limits.js +106 -0
  122. package/dist/src/limits.js.map +1 -0
  123. package/dist/src/matters.d.ts +22 -0
  124. package/dist/src/matters.d.ts.map +1 -0
  125. package/dist/src/matters.js +26 -0
  126. package/dist/src/matters.js.map +1 -0
  127. package/dist/src/mentions.d.ts +63 -0
  128. package/dist/src/mentions.d.ts.map +1 -0
  129. package/dist/src/mentions.js +129 -0
  130. package/dist/src/mentions.js.map +1 -0
  131. package/dist/src/names.d.ts +58 -0
  132. package/dist/src/names.d.ts.map +1 -0
  133. package/dist/src/names.js +192 -0
  134. package/dist/src/names.js.map +1 -0
  135. package/dist/src/no-reply.d.ts +17 -0
  136. package/dist/src/no-reply.d.ts.map +1 -0
  137. package/dist/src/no-reply.js +48 -0
  138. package/dist/src/no-reply.js.map +1 -0
  139. package/dist/src/notifications.d.ts +81 -0
  140. package/dist/src/notifications.d.ts.map +1 -0
  141. package/dist/src/notifications.js +65 -0
  142. package/dist/src/notifications.js.map +1 -0
  143. package/dist/src/pages.d.ts +32 -0
  144. package/dist/src/pages.d.ts.map +1 -0
  145. package/dist/src/pages.js +32 -0
  146. package/dist/src/pages.js.map +1 -0
  147. package/dist/src/pairing.d.ts +99 -0
  148. package/dist/src/pairing.d.ts.map +1 -0
  149. package/dist/src/pairing.js +163 -0
  150. package/dist/src/pairing.js.map +1 -0
  151. package/dist/src/primitives.d.ts +267 -0
  152. package/dist/src/primitives.d.ts.map +1 -0
  153. package/dist/src/primitives.js +279 -0
  154. package/dist/src/primitives.js.map +1 -0
  155. package/dist/src/project.d.ts +335 -0
  156. package/dist/src/project.d.ts.map +1 -0
  157. package/dist/src/project.js +499 -0
  158. package/dist/src/project.js.map +1 -0
  159. package/dist/src/ranges.d.ts +31 -0
  160. package/dist/src/ranges.d.ts.map +1 -0
  161. package/dist/src/ranges.js +51 -0
  162. package/dist/src/ranges.js.map +1 -0
  163. package/dist/src/relay.d.ts +177 -0
  164. package/dist/src/relay.d.ts.map +1 -0
  165. package/dist/src/relay.js +147 -0
  166. package/dist/src/relay.js.map +1 -0
  167. package/dist/src/room-files.d.ts +146 -0
  168. package/dist/src/room-files.d.ts.map +1 -0
  169. package/dist/src/room-files.js +135 -0
  170. package/dist/src/room-files.js.map +1 -0
  171. package/dist/src/room-note.d.ts +213 -0
  172. package/dist/src/room-note.d.ts.map +1 -0
  173. package/dist/src/room-note.js +457 -0
  174. package/dist/src/room-note.js.map +1 -0
  175. package/dist/src/space-icons.d.ts +68 -0
  176. package/dist/src/space-icons.d.ts.map +1 -0
  177. package/dist/src/space-icons.js +142 -0
  178. package/dist/src/space-icons.js.map +1 -0
  179. package/dist/src/spend.d.ts +57 -0
  180. package/dist/src/spend.d.ts.map +1 -0
  181. package/dist/src/spend.js +94 -0
  182. package/dist/src/spend.js.map +1 -0
  183. package/dist/src/visibility.d.ts +170 -0
  184. package/dist/src/visibility.d.ts.map +1 -0
  185. package/dist/src/visibility.js +218 -0
  186. package/dist/src/visibility.js.map +1 -0
  187. package/fixtures/agent.asked.json +15 -0
  188. package/fixtures/agent.attached.json +15 -0
  189. package/fixtures/agent.deleted.json +16 -0
  190. package/fixtures/agent.fork.json +14 -0
  191. package/fixtures/agent.lock_set.json +13 -0
  192. package/fixtures/agent.registered.json +17 -0
  193. package/fixtures/agent.released.json +16 -0
  194. package/fixtures/agent.updated.json +14 -0
  195. package/fixtures/approval.executed.json +16 -0
  196. package/fixtures/approval.request.json +45 -0
  197. package/fixtures/approval.resolved.json +20 -0
  198. package/fixtures/approval.routed.json +20 -0
  199. package/fixtures/artifact.create.json +18 -0
  200. package/fixtures/attachment.fetched.json +15 -0
  201. package/fixtures/attachment.limits_set.json +15 -0
  202. package/fixtures/budget.warning.json +20 -0
  203. package/fixtures/checkpoint.json +16 -0
  204. package/fixtures/context.compacted.json +16 -0
  205. package/fixtures/context.usage.json +17 -0
  206. package/fixtures/exchange.limits_set.json +15 -0
  207. package/fixtures/exchange.set.json +13 -0
  208. package/fixtures/feedback.json +21 -0
  209. package/fixtures/frames/ack.json +6 -0
  210. package/fixtures/frames/context.edit.json +11 -0
  211. package/fixtures/frames/context_window.change.json +9 -0
  212. package/fixtures/frames/context_window.compact.json +8 -0
  213. package/fixtures/frames/error.json +6 -0
  214. package/fixtures/frames/event.json +20 -0
  215. package/fixtures/frames/events.json +39 -0
  216. package/fixtures/frames/folder.open.json +6 -0
  217. package/fixtures/frames/folder.open.page.json +7 -0
  218. package/fixtures/frames/folder.run.json +8 -0
  219. package/fixtures/frames/folder.run_state.json +12 -0
  220. package/fixtures/frames/heartbeat.change.json +10 -0
  221. package/fixtures/frames/hello.json +18 -0
  222. package/fixtures/frames/job.change.json +9 -0
  223. package/fixtures/frames/join.json +19 -0
  224. package/fixtures/frames/model.change.json +10 -0
  225. package/fixtures/frames/ping.json +4 -0
  226. package/fixtures/frames/pong.json +4 -0
  227. package/fixtures/frames/presence.json +12 -0
  228. package/fixtures/frames/receipt.json +5 -0
  229. package/fixtures/frames/restart.json +5 -0
  230. package/fixtures/frames/subscribe.json +6 -0
  231. package/fixtures/handoff.json +20 -0
  232. package/fixtures/harness.removed.json +15 -0
  233. package/fixtures/harness.transferred.json +15 -0
  234. package/fixtures/hello.json +61 -0
  235. package/fixtures/join.allowed.json +20 -0
  236. package/fixtures/join.denied.json +17 -0
  237. package/fixtures/lane.updated.json +17 -0
  238. package/fixtures/membership.added.json +16 -0
  239. package/fixtures/membership.removed.json +14 -0
  240. package/fixtures/membership.replaced.json +15 -0
  241. package/fixtures/message.deleted.json +15 -0
  242. package/fixtures/message.edited.json +15 -0
  243. package/fixtures/message.handed.json +14 -0
  244. package/fixtures/message.heard.json +14 -0
  245. package/fixtures/message.held.json +14 -0
  246. package/fixtures/message.hidden.json +14 -0
  247. package/fixtures/message.new.json +96 -0
  248. package/fixtures/message.overheard.json +22 -0
  249. package/fixtures/message.pinned.json +14 -0
  250. package/fixtures/message.post.json +14 -0
  251. package/fixtures/message.shown.json +14 -0
  252. package/fixtures/message.unpinned.json +14 -0
  253. package/fixtures/person.face_set.json +17 -0
  254. package/fixtures/person.joined.json +16 -0
  255. package/fixtures/person.removed.json +16 -0
  256. package/fixtures/person.renamed.json +14 -0
  257. package/fixtures/policy.updated.json +30 -0
  258. package/fixtures/project.changed.json +21 -0
  259. package/fixtures/question.answered.json +23 -0
  260. package/fixtures/question.ask.json +37 -0
  261. package/fixtures/receipt.json +15 -0
  262. package/fixtures/relay.set.json +12 -0
  263. package/fixtures/role.changed.json +15 -0
  264. package/fixtures/run.cancel.json +15 -0
  265. package/fixtures/run.completed.json +20 -0
  266. package/fixtures/run.failed.json +20 -0
  267. package/fixtures/run.pause.json +15 -0
  268. package/fixtures/run.plan.json +24 -0
  269. package/fixtures/run.requested.json +34 -0
  270. package/fixtures/run.resume.json +15 -0
  271. package/fixtures/run.started.json +33 -0
  272. package/fixtures/run.status.json +17 -0
  273. package/fixtures/run.steer.json +21 -0
  274. package/fixtures/session.ended.json +15 -0
  275. package/fixtures/session.renamed.json +15 -0
  276. package/fixtures/session.started.json +17 -0
  277. package/fixtures/space.claimed.json +15 -0
  278. package/fixtures/space.created.json +14 -0
  279. package/fixtures/space.erased.json +13 -0
  280. package/fixtures/space.lead_set.json +13 -0
  281. package/fixtures/space.lock_set.json +13 -0
  282. package/fixtures/space.spend_ceiling_set.json +13 -0
  283. package/fixtures/space.updated.json +14 -0
  284. package/fixtures/step.log.json +26 -0
  285. package/fixtures/task.json +22 -0
  286. package/fixtures/turn.passed.json +14 -0
  287. package/fixtures/usage.json +21 -0
  288. package/fixtures/workspace.renamed.json +13 -0
  289. package/generated/agent-connect.json +13966 -0
  290. package/generated/schema/agent.asked.json +114 -0
  291. package/generated/schema/agent.attached.json +465 -0
  292. package/generated/schema/agent.deleted.json +127 -0
  293. package/generated/schema/agent.fork.json +107 -0
  294. package/generated/schema/agent.lock_set.json +105 -0
  295. package/generated/schema/agent.registered.json +130 -0
  296. package/generated/schema/agent.released.json +129 -0
  297. package/generated/schema/agent.updated.json +151 -0
  298. package/generated/schema/approval.executed.json +125 -0
  299. package/generated/schema/approval.request.json +279 -0
  300. package/generated/schema/approval.resolved.json +162 -0
  301. package/generated/schema/approval.routed.json +185 -0
  302. package/generated/schema/artifact.create.json +206 -0
  303. package/generated/schema/attachment.fetched.json +114 -0
  304. package/generated/schema/attachment.limits_set.json +136 -0
  305. package/generated/schema/budget.warning.json +152 -0
  306. package/generated/schema/checkpoint.json +111 -0
  307. package/generated/schema/context.compacted.json +124 -0
  308. package/generated/schema/context.usage.json +120 -0
  309. package/generated/schema/exchange.limits_set.json +127 -0
  310. package/generated/schema/exchange.set.json +144 -0
  311. package/generated/schema/feedback.json +173 -0
  312. package/generated/schema/handoff.json +122 -0
  313. package/generated/schema/harness.removed.json +122 -0
  314. package/generated/schema/harness.transferred.json +117 -0
  315. package/generated/schema/hello.json +509 -0
  316. package/generated/schema/join.allowed.json +176 -0
  317. package/generated/schema/join.denied.json +150 -0
  318. package/generated/schema/lane.updated.json +223 -0
  319. package/generated/schema/membership.added.json +153 -0
  320. package/generated/schema/membership.removed.json +126 -0
  321. package/generated/schema/membership.replaced.json +106 -0
  322. package/generated/schema/message.deleted.json +105 -0
  323. package/generated/schema/message.edited.json +107 -0
  324. package/generated/schema/message.handed.json +111 -0
  325. package/generated/schema/message.heard.json +100 -0
  326. package/generated/schema/message.held.json +181 -0
  327. package/generated/schema/message.hidden.json +100 -0
  328. package/generated/schema/message.new.json +1369 -0
  329. package/generated/schema/message.overheard.json +701 -0
  330. package/generated/schema/message.pinned.json +100 -0
  331. package/generated/schema/message.post.json +290 -0
  332. package/generated/schema/message.shown.json +100 -0
  333. package/generated/schema/message.unpinned.json +100 -0
  334. package/generated/schema/person.face_set.json +134 -0
  335. package/generated/schema/person.joined.json +128 -0
  336. package/generated/schema/person.removed.json +133 -0
  337. package/generated/schema/person.renamed.json +114 -0
  338. package/generated/schema/policy.updated.json +277 -0
  339. package/generated/schema/project.changed.json +199 -0
  340. package/generated/schema/question.answered.json +154 -0
  341. package/generated/schema/question.ask.json +194 -0
  342. package/generated/schema/receipt.json +109 -0
  343. package/generated/schema/relay.set.json +99 -0
  344. package/generated/schema/role.changed.json +116 -0
  345. package/generated/schema/run.cancel.json +106 -0
  346. package/generated/schema/run.completed.json +139 -0
  347. package/generated/schema/run.failed.json +135 -0
  348. package/generated/schema/run.pause.json +106 -0
  349. package/generated/schema/run.plan.json +128 -0
  350. package/generated/schema/run.requested.json +309 -0
  351. package/generated/schema/run.resume.json +106 -0
  352. package/generated/schema/run.started.json +142 -0
  353. package/generated/schema/run.status.json +120 -0
  354. package/generated/schema/run.steer.json +163 -0
  355. package/generated/schema/session.ended.json +106 -0
  356. package/generated/schema/session.renamed.json +108 -0
  357. package/generated/schema/session.started.json +116 -0
  358. package/generated/schema/space.claimed.json +107 -0
  359. package/generated/schema/space.created.json +148 -0
  360. package/generated/schema/space.erased.json +129 -0
  361. package/generated/schema/space.lead_set.json +108 -0
  362. package/generated/schema/space.lock_set.json +99 -0
  363. package/generated/schema/space.spend_ceiling_set.json +102 -0
  364. package/generated/schema/space.updated.json +112 -0
  365. package/generated/schema/step.log.json +187 -0
  366. package/generated/schema/task.json +268 -0
  367. package/generated/schema/turn.passed.json +99 -0
  368. package/generated/schema/usage.json +155 -0
  369. package/generated/schema/workspace.renamed.json +107 -0
  370. package/generated/types.ts +4178 -0
  371. package/package.json +38 -3
@@ -0,0 +1,58 @@
1
+ /**
2
+ * When two names are one @-name, and the free name an agent is given (ADR 0091).
3
+ *
4
+ * A participant's whole-name handle is its name with the spaces left out, case aside (ADR 0081),
5
+ * so two names clash when that is the same: "Open Claw", "OpenClaw" and "openclaw". People are
6
+ * refused a name that clashes; an agent is numbered, "OpenClaw", "OpenClaw 2", "OpenClaw 3", so
7
+ * its @-name is `@OpenClaw2`. The server names agents with these, and the conformance fake and the
8
+ * clients read the same rule.
9
+ */
10
+ /** The longest name a participant is called, a person's or an agent's. */
11
+ export declare const MAX_NAME = 120;
12
+ /**
13
+ * What a workspace's first person is called until they name themselves: what `chips serve` and
14
+ * the demo give them. Nobody they invite should read "You invited you" (JR-17): the join card says
15
+ * nobody's name for it, and You asks them for one before they invite anybody.
16
+ */
17
+ export declare const FIRST_PERSON_NAME = "You";
18
+ /** Why an agent can't be called Main or You. */
19
+ export declare const NOT_AN_AGENT_WORDS = "An agent can't be called Main or You: Chips uses those words for the Main agent and for you.";
20
+ /** Whether a name is Main or You as an @-name, which no agent may be called. */
21
+ export declare function notAnAgentName(name: string): boolean;
22
+ /** Why a name can't have a hidden character. */
23
+ export declare const HIDDEN_CHARACTER_WORDS = "A name can't have hidden characters in it, such as a zero-width space or a mark that changes the text's direction.";
24
+ /** Why a word of a name can't mix alphabets. */
25
+ export declare const MIXED_LETTERS_WORDS = "A name can't mix Latin, Cyrillic and Greek letters in one word, since they can look the same.";
26
+ /**
27
+ * Why a name a person typed, for themselves, an agent or a workspace, can't be had as it is, or
28
+ * nothing (SEC-33): a character nobody sees, which could make it pass for a name it isn't or turn
29
+ * the words after it around, or a word that mixes alphabets whose letters look alike.
30
+ */
31
+ export declare function nameProblem(name: string): string | undefined;
32
+ /**
33
+ * A name a harness or a device gave itself, with what nobody sees taken out (SEC-33). It isn't
34
+ * refused, since nobody typed it to be told; its clash is judged as it reads.
35
+ */
36
+ export declare function withoutHidden(name: string): string;
37
+ /**
38
+ * What a name is as an @-name: lowercased, its spaces left out, and what a reader sees, not what
39
+ * the characters are (SEC-33). Full-width and mathematical letters fold to plain ones, a hidden
40
+ * character counts for nothing, and a Cyrillic or Greek letter that looks Latin is that Latin
41
+ * letter, so "\u0410rjun", "Ar\u200bjun" and "\uff21rjun" clash with Arjun.
42
+ */
43
+ export declare function clashKey(name: string): string;
44
+ /**
45
+ * Whether a name is `base` or `base` numbered from 2: "OpenClaw 3" is a form of "OpenClaw". Case
46
+ * and spaces aside, as a clash is.
47
+ */
48
+ export declare function isFormOf(name: string, base: string): boolean;
49
+ /**
50
+ * The name an agent is given when it asks for `wanted`, beside the names `taken` (clash keys of
51
+ * everybody else who counts). It keeps `current` when that is `wanted`, or a numbered form of it,
52
+ * and still free, so a number never moves because a lower one came free. Otherwise `wanted` when
53
+ * it is free, else the smallest free number after it: "OpenClaw 2". A number at the end of
54
+ * `wanted` is the family's only when the name before it is taken, so "OpenClaw 2" beside an
55
+ * "OpenClaw" comes out "OpenClaw 3", and "India trip 2026" is a name of its own.
56
+ */
57
+ export declare function freeAgentName(wanted: string, taken: ReadonlySet<string>, current?: string): string;
58
+ //# sourceMappingURL=names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../src/names.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,0EAA0E;AAC1E,eAAO,MAAM,QAAQ,MAAM,CAAC;AAE5B;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AASvC,gDAAgD;AAChD,eAAO,MAAM,kBAAkB,iGACiE,CAAC;AAEjG,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AA0FD,gDAAgD;AAChD,eAAO,MAAM,sBAAsB,uHACmF,CAAC;AAEvH,gDAAgD;AAChD,eAAO,MAAM,mBAAmB,kGACiE,CAAC;AASlG;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAK5D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO7C;AAKD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAI5D;AAQD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAC1B,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAYR"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * When two names are one @-name, and the free name an agent is given (ADR 0091).
3
+ *
4
+ * A participant's whole-name handle is its name with the spaces left out, case aside (ADR 0081),
5
+ * so two names clash when that is the same: "Open Claw", "OpenClaw" and "openclaw". People are
6
+ * refused a name that clashes; an agent is numbered, "OpenClaw", "OpenClaw 2", "OpenClaw 3", so
7
+ * its @-name is `@OpenClaw2`. The server names agents with these, and the conformance fake and the
8
+ * clients read the same rule.
9
+ */
10
+ /** The longest name a participant is called, a person's or an agent's. */
11
+ export const MAX_NAME = 120;
12
+ /**
13
+ * What a workspace's first person is called until they name themselves: what `chips serve` and
14
+ * the demo give them. Nobody they invite should read "You invited you" (JR-17): the join card says
15
+ * nobody's name for it, and You asks them for one before they invite anybody.
16
+ */
17
+ export const FIRST_PERSON_NAME = "You";
18
+ /**
19
+ * What an agent can't be called (SEC-33): the word on the Main agent's tag, and the word a person
20
+ * reads in place of their own name. An agent asking for one is numbered, "Main 2", as one asking
21
+ * for a name somebody has; a person renaming one to it is told why not.
22
+ */
23
+ const NOT_AN_AGENT = new Set(["main", "you"]);
24
+ /** Why an agent can't be called Main or You. */
25
+ export const NOT_AN_AGENT_WORDS = "An agent can't be called Main or You: Chips uses those words for the Main agent and for you.";
26
+ /** Whether a name is Main or You as an @-name, which no agent may be called. */
27
+ export function notAnAgentName(name) {
28
+ return NOT_AN_AGENT.has(clashKey(name));
29
+ }
30
+ /**
31
+ * The Cyrillic and Greek letters a reader takes for Latin ones, under the Latin letter they look
32
+ * like (SEC-33). A name in them is the Latin name for a clash, so "\u0410rjun" with a Cyrillic А is
33
+ * Arjun's. Not all of Unicode's confusables: the letters a name borrows to pass for somebody, with
34
+ * NFKC folding the full-width and mathematical ones before.
35
+ */
36
+ const LOOK_LIKE = {
37
+ A: "\u0410\u0391", // Cyrillic А, Greek Α
38
+ B: "\u0412\u0392", // Cyrillic В, Greek Β
39
+ C: "\u0421", // Cyrillic С
40
+ E: "\u0415\u0395", // Cyrillic Е, Greek Ε
41
+ H: "\u041d\u0397", // Cyrillic Н, Greek Η
42
+ I: "\u0406\u04c0\u0399", // Cyrillic І and Ӏ, Greek Ι
43
+ J: "\u0408", // Cyrillic Ј
44
+ K: "\u041a\u039a", // Cyrillic К, Greek Κ
45
+ M: "\u041c\u039c", // Cyrillic М, Greek Μ
46
+ N: "\u039d", // Greek Ν
47
+ O: "\u041e\u039f", // Cyrillic О, Greek Ο
48
+ P: "\u0420\u03a1", // Cyrillic Р, Greek Ρ
49
+ Q: "\u051a", // Cyrillic Ԛ
50
+ S: "\u0405", // Cyrillic Ѕ
51
+ T: "\u0422\u03a4", // Cyrillic Т, Greek Τ
52
+ W: "\u051c", // Cyrillic Ԝ
53
+ X: "\u0425\u03a7", // Cyrillic Х, Greek Χ
54
+ Y: "\u0423\u04ae\u03a5", // Cyrillic У and Ү, Greek Υ
55
+ Z: "\u0396", // Greek Ζ
56
+ a: "\u0430\u03b1", // Cyrillic а, Greek α
57
+ c: "\u0441", // Cyrillic с
58
+ d: "\u0501", // Cyrillic ԁ
59
+ e: "\u0435", // Cyrillic е
60
+ h: "\u04bb", // Cyrillic һ
61
+ i: "\u0456\u03b9\u0131", // Cyrillic і, Greek ι, Latin dotless ı
62
+ j: "\u0458", // Cyrillic ј
63
+ k: "\u03ba", // Greek κ
64
+ l: "\u04cf", // Cyrillic ӏ
65
+ o: "\u043e\u03bf", // Cyrillic о, Greek ο
66
+ p: "\u0440\u03c1", // Cyrillic р, Greek ρ
67
+ q: "\u051b", // Cyrillic ԛ
68
+ s: "\u0455", // Cyrillic ѕ
69
+ u: "\u03c5", // Greek υ
70
+ v: "\u03bd", // Greek ν
71
+ w: "\u051d", // Cyrillic ԝ
72
+ x: "\u0445\u03c7", // Cyrillic х, Greek χ
73
+ y: "\u0443\u04af", // Cyrillic у and ү
74
+ };
75
+ const LATIN_OF = new Map(Object.entries(LOOK_LIKE).flatMap(([latin, others]) => [...others].map((other) => [other, latin])));
76
+ /**
77
+ * What a reader doesn't see (SEC-33): control and format characters (zero-width spaces and
78
+ * joiners, text-direction marks, a soft hyphen), the joiner that combines graphemes, and the blank
79
+ * letters of Hangul and Braille.
80
+ */
81
+ const HIDDEN = "\\p{Cc}\\p{Cf}\\u034f\\u115f\\u1160\\u3164\\uffa0\\u2800";
82
+ /** Every unseen character, and the variation selectors an emoji is typed with, for a clash. */
83
+ const UNSEEN = new RegExp(`[${HIDDEN}\\ufe00-\\ufe0f\\u{e0100}-\\u{e01ef}]`, "gu");
84
+ /** One hidden character. */
85
+ const HIDDEN_ONE = new RegExp(`[${HIDDEN}]`, "u");
86
+ /** The zero-width non-joiner and joiner, which `hiddenAt` judges by what is either side. */
87
+ const JOINER = /^[\u200c\u200d]$/u;
88
+ /** A Latin, Cyrillic or Greek letter, a digit or a space: nothing a joiner shapes. */
89
+ const PLAIN = /[\p{Script=Latin}\p{Script=Cyrillic}\p{Script=Greek}\p{Nd}\s]/u;
90
+ /**
91
+ * Whether the character at `i` is one a reader can't account for. A joiner between two emoji makes
92
+ * one, "\u{1f469}\u200d\u{1f4bb}", and in Persian or an Indian script it shapes the letters beside it, so there it
93
+ * counts as seen; at an end, or beside a plain letter, a digit, a space or another hidden
94
+ * character, it is hidden.
95
+ */
96
+ function hiddenAt(chars, i) {
97
+ const each = chars[i];
98
+ if (!HIDDEN_ONE.test(each))
99
+ return false;
100
+ if (!JOINER.test(each))
101
+ return true;
102
+ const before = chars[i - 1];
103
+ const after = chars[i + 1];
104
+ const bare = (side) => side === undefined || PLAIN.test(side) || HIDDEN_ONE.test(side);
105
+ return bare(before) || bare(after);
106
+ }
107
+ /** Why a name can't have a hidden character. */
108
+ export const HIDDEN_CHARACTER_WORDS = "A name can't have hidden characters in it, such as a zero-width space or a mark that changes the text's direction.";
109
+ /** Why a word of a name can't mix alphabets. */
110
+ export const MIXED_LETTERS_WORDS = "A name can't mix Latin, Cyrillic and Greek letters in one word, since they can look the same.";
111
+ const ALPHABETS = [/\p{Script=Latin}/u, /\p{Script=Cyrillic}/u, /\p{Script=Greek}/u];
112
+ /** Whether a word holds letters of two of Latin, Cyrillic and Greek: "\u0410rjun" with a Cyrillic А. */
113
+ function mixesAlphabets(word) {
114
+ return ALPHABETS.filter((alphabet) => alphabet.test(word)).length > 1;
115
+ }
116
+ /**
117
+ * Why a name a person typed, for themselves, an agent or a workspace, can't be had as it is, or
118
+ * nothing (SEC-33): a character nobody sees, which could make it pass for a name it isn't or turn
119
+ * the words after it around, or a word that mixes alphabets whose letters look alike.
120
+ */
121
+ export function nameProblem(name) {
122
+ const chars = [...name];
123
+ if (chars.some((_, i) => hiddenAt(chars, i)))
124
+ return HIDDEN_CHARACTER_WORDS;
125
+ if (name.split(/\s+/).some(mixesAlphabets))
126
+ return MIXED_LETTERS_WORDS;
127
+ return undefined;
128
+ }
129
+ /**
130
+ * A name a harness or a device gave itself, with what nobody sees taken out (SEC-33). It isn't
131
+ * refused, since nobody typed it to be told; its clash is judged as it reads.
132
+ */
133
+ export function withoutHidden(name) {
134
+ const chars = [...name];
135
+ return chars.filter((_, i) => !hiddenAt(chars, i)).join("");
136
+ }
137
+ /**
138
+ * What a name is as an @-name: lowercased, its spaces left out, and what a reader sees, not what
139
+ * the characters are (SEC-33). Full-width and mathematical letters fold to plain ones, a hidden
140
+ * character counts for nothing, and a Cyrillic or Greek letter that looks Latin is that Latin
141
+ * letter, so "\u0410rjun", "Ar\u200bjun" and "\uff21rjun" clash with Arjun.
142
+ */
143
+ export function clashKey(name) {
144
+ const seen = name.normalize("NFKC").replace(UNSEEN, "");
145
+ return [...seen]
146
+ .map((each) => LATIN_OF.get(each) ?? each)
147
+ .join("")
148
+ .toLowerCase()
149
+ .replace(/\s+/g, "");
150
+ }
151
+ /** A name ending in a space and a number: the name before it, and the number. */
152
+ const NUMBERED = /^(.*\S)\s+([1-9]\d*)$/;
153
+ /**
154
+ * Whether a name is `base` or `base` numbered from 2: "OpenClaw 3" is a form of "OpenClaw". Case
155
+ * and spaces aside, as a clash is.
156
+ */
157
+ export function isFormOf(name, base) {
158
+ if (clashKey(name) === clashKey(base))
159
+ return true;
160
+ const parts = NUMBERED.exec(name.trim());
161
+ return parts !== null && parts[2] !== "1" && clashKey(parts[1]) === clashKey(base);
162
+ }
163
+ /** `family` with `n` after it, cut so the whole is no longer than a name may be. */
164
+ function numbered(family, n) {
165
+ const suffix = ` ${n}`;
166
+ return `${family.slice(0, MAX_NAME - suffix.length).trimEnd()}${suffix}`;
167
+ }
168
+ /**
169
+ * The name an agent is given when it asks for `wanted`, beside the names `taken` (clash keys of
170
+ * everybody else who counts). It keeps `current` when that is `wanted`, or a numbered form of it,
171
+ * and still free, so a number never moves because a lower one came free. Otherwise `wanted` when
172
+ * it is free, else the smallest free number after it: "OpenClaw 2". A number at the end of
173
+ * `wanted` is the family's only when the name before it is taken, so "OpenClaw 2" beside an
174
+ * "OpenClaw" comes out "OpenClaw 3", and "India trip 2026" is a name of its own.
175
+ */
176
+ export function freeAgentName(wanted, taken, current) {
177
+ const free = (name) => !taken.has(clashKey(name)) && !notAnAgentName(name);
178
+ const parts = NUMBERED.exec(wanted);
179
+ const family = parts !== null && !free(parts[1]) ? parts[1] : wanted;
180
+ if (current !== undefined && free(current)) {
181
+ if (isFormOf(current, wanted) || isFormOf(current, family))
182
+ return current;
183
+ }
184
+ if (free(wanted))
185
+ return wanted;
186
+ for (let n = 2;; n += 1) {
187
+ const name = numbered(family, n);
188
+ if (free(name))
189
+ return name;
190
+ }
191
+ }
192
+ //# sourceMappingURL=names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"names.js","sourceRoot":"","sources":["../../src/names.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,CAAC;AAE5B;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAEvC;;;;GAIG;AACH,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAEnE,gDAAgD;AAChD,MAAM,CAAC,MAAM,kBAAkB,GAC7B,8FAA8F,CAAC;AAEjG,gFAAgF;AAChF,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;GAKG;AACH,MAAM,SAAS,GAAqC;IAClD,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,oBAAoB,EAAE,4BAA4B;IACrD,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,QAAQ,EAAE,UAAU;IACvB,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,oBAAoB,EAAE,4BAA4B;IACrD,CAAC,EAAE,QAAQ,EAAE,UAAU;IACvB,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,oBAAoB,EAAE,uCAAuC;IAChE,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,QAAQ,EAAE,UAAU;IACvB,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,QAAQ,EAAE,UAAU;IACvB,CAAC,EAAE,QAAQ,EAAE,UAAU;IACvB,CAAC,EAAE,QAAQ,EAAE,aAAa;IAC1B,CAAC,EAAE,cAAc,EAAE,sBAAsB;IACzC,CAAC,EAAE,cAAc,EAAE,mBAAmB;CACvC,CAAC;AAEF,MAAM,QAAQ,GAAgC,IAAI,GAAG,CACnD,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,CACpD,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,CAAU,CAAC,CACpD,CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,GAAG,0DAA0D,CAAC;AAE1E,+FAA+F;AAC/F,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,MAAM,uCAAuC,EAAE,IAAI,CAAC,CAAC;AAEnF,4BAA4B;AAC5B,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,IAAI,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC;AAElD,4FAA4F;AAC5F,MAAM,MAAM,GAAG,mBAAmB,CAAC;AAEnC,sFAAsF;AACtF,MAAM,KAAK,GAAG,gEAAgE,CAAC;AAE/E;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,KAAwB,EAAE,CAAS;IACnD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAW,CAAC;IAChC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,MAAM,IAAI,GAAG,CAAC,IAAwB,EAAE,EAAE,CACxC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;AACrC,CAAC;AAED,gDAAgD;AAChD,MAAM,CAAC,MAAM,sBAAsB,GACjC,oHAAoH,CAAC;AAEvH,gDAAgD;AAChD,MAAM,CAAC,MAAM,mBAAmB,GAC9B,+FAA+F,CAAC;AAElG,MAAM,SAAS,GAAG,CAAC,mBAAmB,EAAE,sBAAsB,EAAE,mBAAmB,CAAC,CAAC;AAErF,wGAAwG;AACxG,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AACxE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACxB,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAAE,OAAO,sBAAsB,CAAC;IAC5E,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;QAAE,OAAO,mBAAmB,CAAC;IACvE,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACxB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,IAAI,CAAC;SACb,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;SACzC,IAAI,CAAC,EAAE,CAAC;SACR,WAAW,EAAE;SACb,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACzB,CAAC;AAED,iFAAiF;AACjF,MAAM,QAAQ,GAAG,uBAAuB,CAAC;AAEzC;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,IAAY;IACjD,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC/F,CAAC;AAED,oFAAoF;AACpF,SAAS,QAAQ,CAAC,MAAc,EAAE,CAAS;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IACvB,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC;AAC3E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAc,EACd,KAA0B,EAC1B,OAAgB;IAEhB,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IACnF,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC,CAAC,CAAC,CAAE,KAAK,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3F,IAAI,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3C,IAAI,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;YAAE,OAAO,OAAO,CAAC;IAC7E,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IAC9B,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * How an agent says it has nothing to say (ADR 0105): a post whose words are `NO_REPLY` and nothing
3
+ * else, the word OpenClaw's own agents already answer with. Chips records it as `turn.passed`, not
4
+ * as a message, so nobody is shown it and no agent is handed it; and a run that ends on it draws
5
+ * no line in the room. The server, the conformance fake and the client read it with one rule.
6
+ */
7
+ /** The word itself. */
8
+ export declare const NO_REPLY = "NO_REPLY";
9
+ /** Whether words say only that there is nothing to say. */
10
+ export declare function isNoReply(text: unknown): boolean;
11
+ /**
12
+ * An agent's post that says only `NO_REPLY` made into its turn passed, in place: `turn.passed`,
13
+ * keeping its room, its run and what it answered. A person's words are theirs, whatever they are,
14
+ * and a post with files says something; both are left as they are. True when it was made one.
15
+ */
16
+ export declare function passIfNothingSaid(event: Record<string, unknown>): boolean;
17
+ //# sourceMappingURL=no-reply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-reply.d.ts","sourceRoot":"","sources":["../../src/no-reply.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,uBAAuB;AACvB,eAAO,MAAM,QAAQ,aAAa,CAAC;AAKnC,2DAA2D;AAC3D,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAEhD;AAgBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAUzE"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * How an agent says it has nothing to say (ADR 0105): a post whose words are `NO_REPLY` and nothing
3
+ * else, the word OpenClaw's own agents already answer with. Chips records it as `turn.passed`, not
4
+ * as a message, so nobody is shown it and no agent is handed it; and a run that ends on it draws
5
+ * no line in the room. The server, the conformance fake and the client read it with one rule.
6
+ */
7
+ /** The word itself. */
8
+ export const NO_REPLY = "NO_REPLY";
9
+ /** `NO_REPLY` alone, as a model writes it: in backticks, bold or quotes, or with a full stop. */
10
+ const ALONE = /^[\s`*_"'“”]*NO_REPLY[\s`*_"'“”.!]*$/;
11
+ /** Whether words say only that there is nothing to say. */
12
+ export function isNoReply(text) {
13
+ return typeof text === "string" && ALONE.test(text);
14
+ }
15
+ /** What a passed turn keeps of the post it was: the envelope, and what it was answering. */
16
+ const PASSED_KEEPS = new Set([
17
+ "v",
18
+ "type",
19
+ "id",
20
+ "ts",
21
+ "workspace_id",
22
+ "space_id",
23
+ "run_id",
24
+ "actor",
25
+ "idempotency_key",
26
+ "reply_to",
27
+ ]);
28
+ /**
29
+ * An agent's post that says only `NO_REPLY` made into its turn passed, in place: `turn.passed`,
30
+ * keeping its room, its run and what it answered. A person's words are theirs, whatever they are,
31
+ * and a post with files says something; both are left as they are. True when it was made one.
32
+ */
33
+ export function passIfNothingSaid(event) {
34
+ if (event["type"] !== "message.post" || !isNoReply(event["text"]))
35
+ return false;
36
+ const actor = event["actor"];
37
+ if (actor?.kind === "person" || actor?.kind === "system" || actor?.kind === undefined)
38
+ return false;
39
+ const files = [event["upload_ids"], event["attachments"]];
40
+ if (files.some((each) => Array.isArray(each) && each.length > 0))
41
+ return false;
42
+ for (const key of Object.keys(event))
43
+ if (!PASSED_KEEPS.has(key))
44
+ delete event[key];
45
+ event["type"] = "turn.passed";
46
+ return true;
47
+ }
48
+ //# sourceMappingURL=no-reply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-reply.js","sourceRoot":"","sources":["../../src/no-reply.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,uBAAuB;AACvB,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;AAEnC,iGAAiG;AACjG,MAAM,KAAK,GAAG,sCAAsC,CAAC;AAErD,2DAA2D;AAC3D,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtD,CAAC;AAED,4FAA4F;AAC5F,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC;IAChD,GAAG;IACH,MAAM;IACN,IAAI;IACJ,IAAI;IACJ,cAAc;IACd,UAAU;IACV,QAAQ;IACR,OAAO;IACP,iBAAiB;IACjB,UAAU;CACX,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAA8B;IAC9D,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,cAAc,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAChF,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAA4C,CAAC;IACxE,IAAI,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,EAAE,IAAI,KAAK,SAAS;QACnF,OAAO,KAAK,CAAC;IACf,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;IAC1D,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/E,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;IACpF,KAAK,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC;IAC9B,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * A person's notification settings (M5.6): the three tiers of attention (blueprint: Decide now
3
+ * breaks through, Review today is batched hourly, FYI is a daily digest), quiet hours, a word
4
+ * per harness, and one per room. Held on the server, per person, private to them; read and written over
5
+ * `/v1/me/notifications`, and applied on whichever device raises the banner.
6
+ */
7
+ import { z } from "zod";
8
+ /** A time of day, `HH:MM`, in the person's own clock. */
9
+ export declare const timeOfDay: z.ZodString;
10
+ export declare const quietHours: z.ZodObject<{
11
+ from: z.ZodString;
12
+ to: z.ZodString;
13
+ breakthrough: z.ZodDefault<z.ZodEnum<{
14
+ decide: "decide";
15
+ none: "none";
16
+ }>>;
17
+ }, z.core.$strip>;
18
+ /** How much a person hears from one harness: everything, only its decisions, or nothing. */
19
+ export declare const harnessNotifications: z.ZodEnum<{
20
+ all: "all";
21
+ decide: "decide";
22
+ none: "none";
23
+ }>;
24
+ /**
25
+ * How much a person hears from one room on their phone (ADRs 0198, 0216): every message in it,
26
+ * what its people write and what @s them, only what @s them, or nothing. A decision is the Decide
27
+ * tier's, whatever this says.
28
+ */
29
+ export declare const spaceNotifications: z.ZodEnum<{
30
+ all: "all";
31
+ mentions: "mentions";
32
+ none: "none";
33
+ people: "people";
34
+ }>;
35
+ export declare const notificationSettings: z.ZodObject<{
36
+ decide: z.ZodDefault<z.ZodEnum<{
37
+ off: "off";
38
+ now: "now";
39
+ }>>;
40
+ review: z.ZodDefault<z.ZodEnum<{
41
+ off: "off";
42
+ hourly: "hourly";
43
+ }>>;
44
+ fyi: z.ZodDefault<z.ZodEnum<{
45
+ off: "off";
46
+ daily: "daily";
47
+ }>>;
48
+ quiet: z.ZodOptional<z.ZodObject<{
49
+ from: z.ZodString;
50
+ to: z.ZodString;
51
+ breakthrough: z.ZodDefault<z.ZodEnum<{
52
+ decide: "decide";
53
+ none: "none";
54
+ }>>;
55
+ }, z.core.$strip>>;
56
+ harnesses: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodEnum<{
57
+ all: "all";
58
+ decide: "decide";
59
+ none: "none";
60
+ }>>>;
61
+ spaces: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
62
+ all: "all";
63
+ mentions: "mentions";
64
+ none: "none";
65
+ people: "people";
66
+ }>>>;
67
+ }, z.core.$strip>;
68
+ export type NotificationSettings = z.infer<typeof notificationSettings>;
69
+ export type QuietHours = z.infer<typeof quietHours>;
70
+ export type HarnessNotifications = z.infer<typeof harnessNotifications>;
71
+ export type SpaceNotifications = z.infer<typeof spaceNotifications>;
72
+ export declare const DEFAULT_NOTIFICATION_SETTINGS: NotificationSettings;
73
+ /** The settings a person sent, with the defaults filled in, or the reason they are not settings. */
74
+ export declare function parseNotificationSettings(raw: unknown): {
75
+ ok: true;
76
+ value: NotificationSettings;
77
+ } | {
78
+ ok: false;
79
+ message: string;
80
+ };
81
+ //# sourceMappingURL=notifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/notifications.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,yDAAyD;AACzD,eAAO,MAAM,SAAS,aAGyC,CAAC;AAEhE,eAAO,MAAM,UAAU;;;;;;;iBAYpB,CAAC;AAEJ,4FAA4F;AAC5F,eAAO,MAAM,oBAAoB;;;;EAAoC,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;EAAgD,CAAC;AAEhF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAe/B,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACxE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AACpD,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACxE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,eAAO,MAAM,6BAA6B,EAAE,oBAK3C,CAAC;AAEF,oGAAoG;AACpG,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,OAAO,GACX;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,oBAAoB,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAQ5E"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * A person's notification settings (M5.6): the three tiers of attention (blueprint: Decide now
3
+ * breaks through, Review today is batched hourly, FYI is a daily digest), quiet hours, a word
4
+ * per harness, and one per room. Held on the server, per person, private to them; read and written over
5
+ * `/v1/me/notifications`, and applied on whichever device raises the banner.
6
+ */
7
+ import { z } from "zod";
8
+ /** A time of day, `HH:MM`, in the person's own clock. */
9
+ export const timeOfDay = z
10
+ .string()
11
+ .regex(/^([01]\d|2[0-3]):[0-5]\d$/)
12
+ .describe("A time of day, HH:MM, on the device's own clock.");
13
+ export const quietHours = z
14
+ .object({
15
+ from: timeOfDay,
16
+ to: timeOfDay,
17
+ /**
18
+ * What still gets through: a decision, since an approval expires and a run is blocked on it
19
+ * (the blueprint's "breaks through"), or nothing at all.
20
+ */
21
+ breakthrough: z.enum(["decide", "none"]).default("decide"),
22
+ })
23
+ .describe("A window each day in which Review and FYI wait; `from` may be after `to` for a window across midnight.");
24
+ /** How much a person hears from one harness: everything, only its decisions, or nothing. */
25
+ export const harnessNotifications = z.enum(["all", "decide", "none"]);
26
+ /**
27
+ * How much a person hears from one room on their phone (ADRs 0198, 0216): every message in it,
28
+ * what its people write and what @s them, only what @s them, or nothing. A decision is the Decide
29
+ * tier's, whatever this says.
30
+ */
31
+ export const spaceNotifications = z.enum(["all", "people", "mentions", "none"]);
32
+ export const notificationSettings = z.object({
33
+ /** Decide now: at once, or never a banner (its room still shows it). */
34
+ decide: z.enum(["now", "off"]).default("now"),
35
+ /** Review today: batched, one banner an hour at most, or off. */
36
+ review: z.enum(["hourly", "off"]).default("hourly"),
37
+ /** FYI: rolled into one banner a day, or off. */
38
+ fyi: z.enum(["daily", "off"]).default("daily"),
39
+ quiet: quietHours.optional(),
40
+ /** By harness id; a harness not listed is `all`. */
41
+ harnesses: z.record(z.string().min(1).max(120), harnessNotifications).default({}),
42
+ /**
43
+ * By space id; a room not listed is `people` (ADR 0216). Absent from what an app older than
44
+ * ADR 0198 sends, and then what was saved is kept.
45
+ */
46
+ spaces: z.record(z.string().min(1).max(120), spaceNotifications).optional(),
47
+ });
48
+ export const DEFAULT_NOTIFICATION_SETTINGS = {
49
+ decide: "now",
50
+ review: "hourly",
51
+ fyi: "daily",
52
+ harnesses: {},
53
+ };
54
+ /** The settings a person sent, with the defaults filled in, or the reason they are not settings. */
55
+ export function parseNotificationSettings(raw) {
56
+ const parsed = notificationSettings.safeParse(raw);
57
+ if (parsed.success)
58
+ return { ok: true, value: parsed.data };
59
+ const issue = parsed.error.issues[0];
60
+ return {
61
+ ok: false,
62
+ message: issue === undefined ? "not settings" : `${issue.path.join(".")}: ${issue.message}`,
63
+ };
64
+ }
65
+ //# sourceMappingURL=notifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../src/notifications.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,yDAAyD;AACzD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC;KACvB,MAAM,EAAE;KACR,KAAK,CAAC,2BAA2B,CAAC;KAClC,QAAQ,CAAC,kDAAkD,CAAC,CAAC;AAEhE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,MAAM,CAAC;IACN,IAAI,EAAE,SAAS;IACf,EAAE,EAAE,SAAS;IACb;;;OAGG;IACH,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;CAC3D,CAAC;KACD,QAAQ,CACP,wGAAwG,CACzG,CAAC;AAEJ,4FAA4F;AAC5F,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAEtE;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;AAEhF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,wEAAwE;IACxE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAC7C,iEAAiE;IACjE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IACnD,iDAAiD;IACjD,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IAC9C,KAAK,EAAE,UAAU,CAAC,QAAQ,EAAE;IAC5B,oDAAoD;IACpD,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,oBAAoB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACjF;;;OAGG;IACH,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,kBAAkB,CAAC,CAAC,QAAQ,EAAE;CAC5E,CAAC,CAAC;AAOH,MAAM,CAAC,MAAM,6BAA6B,GAAyB;IACjE,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,QAAQ;IAChB,GAAG,EAAE,OAAO;IACZ,SAAS,EAAE,EAAE;CACd,CAAC;AAEF,oGAAoG;AACpG,MAAM,UAAU,yBAAyB,CACvC,GAAY;IAEZ,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACnD,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACrC,OAAO;QACL,EAAE,EAAE,KAAK;QACT,OAAO,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE;KAC5F,CAAC;AACJ,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * What somebody else's HTML page may do (ADR 0059 and its addendum, ADR 0201). A harness writes
3
+ * what its model writes, so a page it sends is untrusted whatever the harness is; and a mock is
4
+ * what it is for, so its script runs. Under this policy a script written in the page runs, an
5
+ * inline handler too, and a picture, a font, a sound or a clip the page carries in itself is
6
+ * drawn and played (a `data:` address, or a `blob:` its script made), so a page that is one
7
+ * file whole is everything it needs. Nothing leaves: no script by address, no `eval`, nothing
8
+ * fetched, sent, framed or connected, and no picture, font or media from the network, so a
9
+ * script cannot reach the network the device is on, not even by loading something from it and
10
+ * timing the answer.
11
+ *
12
+ * It is here, in the package the server and the clients share, because it is written in two
13
+ * places that must agree: the phone writes it into the document (`withHtmlPolicy` in core), and
14
+ * the server answers it as a header from the page door (`GET /v1/pages/:ticket`), where the
15
+ * frame on the web loads the page from. A directive added for one is added for both.
16
+ */
17
+ export declare const HTML_POLICY = "default-src 'none'; img-src data: blob:; font-src data:; media-src data: blob:; style-src 'unsafe-inline'; script-src 'unsafe-inline'";
18
+ /**
19
+ * What the frame the Mac and the web draw a page in may do (ADR 0059, decision 2; ADR 0100):
20
+ * scripts, and a window opened by a tap, which escapes the sandbox so a link in a mock opens as a
21
+ * page of its own. No `allow-same-origin`, so the page's origin is nobody's and it reaches nothing
22
+ * of the app's; no top navigation, no forms. The page door answers the same words in its policy's
23
+ * `sandbox` directive, so the document sandboxes itself wherever it is opened.
24
+ */
25
+ export declare const PAGE_SANDBOX = "allow-scripts allow-popups allow-popups-to-escape-sandbox";
26
+ /**
27
+ * The policy a page's door answers as a header, on the server (`GET /v1/pages/:ticket`) and in
28
+ * the Mac shell (`chips-page://`, ADR 0201's addendum): what the page may do, and the sandbox it
29
+ * is drawn in, so the document sandboxes itself wherever it is opened.
30
+ */
31
+ export declare const PAGE_HEADER_POLICY = "default-src 'none'; img-src data: blob:; font-src data:; media-src data: blob:; style-src 'unsafe-inline'; script-src 'unsafe-inline'; sandbox allow-scripts allow-popups allow-popups-to-escape-sandbox";
32
+ //# sourceMappingURL=pages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../../src/pages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,WAAW,0IACiH,CAAC;AAE1I;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,8DAA8D,CAAC;AAExF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,6MAA4C,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * What somebody else's HTML page may do (ADR 0059 and its addendum, ADR 0201). A harness writes
3
+ * what its model writes, so a page it sends is untrusted whatever the harness is; and a mock is
4
+ * what it is for, so its script runs. Under this policy a script written in the page runs, an
5
+ * inline handler too, and a picture, a font, a sound or a clip the page carries in itself is
6
+ * drawn and played (a `data:` address, or a `blob:` its script made), so a page that is one
7
+ * file whole is everything it needs. Nothing leaves: no script by address, no `eval`, nothing
8
+ * fetched, sent, framed or connected, and no picture, font or media from the network, so a
9
+ * script cannot reach the network the device is on, not even by loading something from it and
10
+ * timing the answer.
11
+ *
12
+ * It is here, in the package the server and the clients share, because it is written in two
13
+ * places that must agree: the phone writes it into the document (`withHtmlPolicy` in core), and
14
+ * the server answers it as a header from the page door (`GET /v1/pages/:ticket`), where the
15
+ * frame on the web loads the page from. A directive added for one is added for both.
16
+ */
17
+ export const HTML_POLICY = "default-src 'none'; img-src data: blob:; font-src data:; media-src data: blob:; style-src 'unsafe-inline'; script-src 'unsafe-inline'";
18
+ /**
19
+ * What the frame the Mac and the web draw a page in may do (ADR 0059, decision 2; ADR 0100):
20
+ * scripts, and a window opened by a tap, which escapes the sandbox so a link in a mock opens as a
21
+ * page of its own. No `allow-same-origin`, so the page's origin is nobody's and it reaches nothing
22
+ * of the app's; no top navigation, no forms. The page door answers the same words in its policy's
23
+ * `sandbox` directive, so the document sandboxes itself wherever it is opened.
24
+ */
25
+ export const PAGE_SANDBOX = "allow-scripts allow-popups allow-popups-to-escape-sandbox";
26
+ /**
27
+ * The policy a page's door answers as a header, on the server (`GET /v1/pages/:ticket`) and in
28
+ * the Mac shell (`chips-page://`, ADR 0201's addendum): what the page may do, and the sandbox it
29
+ * is drawn in, so the document sandboxes itself wherever it is opened.
30
+ */
31
+ export const PAGE_HEADER_POLICY = `${HTML_POLICY}; sandbox ${PAGE_SANDBOX}`;
32
+ //# sourceMappingURL=pages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pages.js","sourceRoot":"","sources":["../../src/pages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,WAAW,GACtB,uIAAuI,CAAC;AAE1I;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,2DAA2D,CAAC;AAExF;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,WAAW,aAAa,YAAY,EAAE,CAAC"}