bom-pi 0.0.0-stage → 0.0.2

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 (131) hide show
  1. package/README.md +33 -2
  2. package/apps/README.md +7 -0
  3. package/apps/web/README.md +21 -0
  4. package/apps/web/pocket-adapter.mjs +323 -0
  5. package/apps/web/public/LICENSE.pocket +21 -0
  6. package/apps/web/public/activity-fold.js +28 -0
  7. package/apps/web/public/agent-now.js +37 -0
  8. package/apps/web/public/agent-tile.js +79 -0
  9. package/apps/web/public/app.js +975 -0
  10. package/apps/web/public/apple-touch-icon.png +0 -0
  11. package/apps/web/public/artifact-bridge.js +687 -0
  12. package/apps/web/public/avatar.js +87 -0
  13. package/apps/web/public/back.js +554 -0
  14. package/apps/web/public/box-keys.js +216 -0
  15. package/apps/web/public/browser-panel.js +1097 -0
  16. package/apps/web/public/browser.js +68 -0
  17. package/apps/web/public/calls.js +139 -0
  18. package/apps/web/public/chat.js +919 -0
  19. package/apps/web/public/clock.js +34 -0
  20. package/apps/web/public/commands.js +578 -0
  21. package/apps/web/public/composer.js +2068 -0
  22. package/apps/web/public/diff-parse.js +672 -0
  23. package/apps/web/public/diff.js +1646 -0
  24. package/apps/web/public/dock.js +299 -0
  25. package/apps/web/public/extension-ui.js +2734 -0
  26. package/apps/web/public/files-panel.js +775 -0
  27. package/apps/web/public/files.js +368 -0
  28. package/apps/web/public/fonts/FiraCode-VF.woff2 +0 -0
  29. package/apps/web/public/fonts/Geist.woff2 +0 -0
  30. package/apps/web/public/fonts/IBMPlexMono-Variable-Italic.woff2 +0 -0
  31. package/apps/web/public/fonts/IBMPlexMono-Variable.woff2 +0 -0
  32. package/apps/web/public/fonts/InterVariable-Italic.woff2 +0 -0
  33. package/apps/web/public/fonts/InterVariable.woff2 +0 -0
  34. package/apps/web/public/fonts/Iosevka-Bold.woff2 +0 -0
  35. package/apps/web/public/fonts/Iosevka-BoldItalic.woff2 +0 -0
  36. package/apps/web/public/fonts/Iosevka-Italic.woff2 +0 -0
  37. package/apps/web/public/fonts/Iosevka-Regular.woff2 +0 -0
  38. package/apps/web/public/fonts/Iosevka-SemiBold.woff2 +0 -0
  39. package/apps/web/public/fonts/Iosevka-SemiBoldItalic.woff2 +0 -0
  40. package/apps/web/public/fonts/JetBrainsMono-Italic.woff2 +0 -0
  41. package/apps/web/public/fonts/JetBrainsMono.woff2 +0 -0
  42. package/apps/web/public/fonts/NerdFontsSymbolsMono.woff2 +0 -0
  43. package/apps/web/public/fonts/SOURCES.md +69 -0
  44. package/apps/web/public/gestures.js +610 -0
  45. package/apps/web/public/highlight.js +480 -0
  46. package/apps/web/public/history.js +70 -0
  47. package/apps/web/public/home.js +169 -0
  48. package/apps/web/public/icon-192.png +0 -0
  49. package/apps/web/public/icon-512.png +0 -0
  50. package/apps/web/public/icon-maskable-512.png +0 -0
  51. package/apps/web/public/icon.svg +16 -0
  52. package/apps/web/public/index.html +71 -0
  53. package/apps/web/public/launcher.js +1293 -0
  54. package/apps/web/public/linked-sessions.js +55 -0
  55. package/apps/web/public/live.js +39 -0
  56. package/apps/web/public/manifest.webmanifest +32 -0
  57. package/apps/web/public/model-refresh.js +73 -0
  58. package/apps/web/public/notify.js +251 -0
  59. package/apps/web/public/peeks.js +920 -0
  60. package/apps/web/public/pip-attachments.js +182 -0
  61. package/apps/web/public/pip-window.js +141 -0
  62. package/apps/web/public/pip.js +1217 -0
  63. package/apps/web/public/quote-reply.js +109 -0
  64. package/apps/web/public/quote-text.js +31 -0
  65. package/apps/web/public/rich.js +403 -0
  66. package/apps/web/public/run-frame.js +106 -0
  67. package/apps/web/public/safe-mode.js +71 -0
  68. package/apps/web/public/seen.js +169 -0
  69. package/apps/web/public/session-tree.js +117 -0
  70. package/apps/web/public/sessions.js +2695 -0
  71. package/apps/web/public/share.js +126 -0
  72. package/apps/web/public/sheets/appearance.js +820 -0
  73. package/apps/web/public/sheets/branch.js +353 -0
  74. package/apps/web/public/sheets/extensions.js +818 -0
  75. package/apps/web/public/sheets/file.js +318 -0
  76. package/apps/web/public/sheets/find.js +250 -0
  77. package/apps/web/public/sheets/folder.js +680 -0
  78. package/apps/web/public/sheets/gallery.js +2340 -0
  79. package/apps/web/public/sheets/hooks.js +350 -0
  80. package/apps/web/public/sheets/memory.js +531 -0
  81. package/apps/web/public/sheets/menu.js +580 -0
  82. package/apps/web/public/sheets/message.js +220 -0
  83. package/apps/web/public/sheets/model.js +412 -0
  84. package/apps/web/public/sheets/people.js +414 -0
  85. package/apps/web/public/sheets/pi-sessions.js +264 -0
  86. package/apps/web/public/sheets/providers.js +525 -0
  87. package/apps/web/public/sheets/running.js +130 -0
  88. package/apps/web/public/sheets/schedules.js +71 -0
  89. package/apps/web/public/sheets/session.js +249 -0
  90. package/apps/web/public/sheets/shortcuts.js +101 -0
  91. package/apps/web/public/sheets/spend.js +150 -0
  92. package/apps/web/public/sheets/text.js +53 -0
  93. package/apps/web/public/sheets/viewers.js +363 -0
  94. package/apps/web/public/sheets/worktree.js +50 -0
  95. package/apps/web/public/sheets.js +410 -0
  96. package/apps/web/public/signin.js +57 -0
  97. package/apps/web/public/slots.js +208 -0
  98. package/apps/web/public/store.js +1760 -0
  99. package/apps/web/public/style.css +18625 -0
  100. package/apps/web/public/subagents-board.js +879 -0
  101. package/apps/web/public/subagents.js +273 -0
  102. package/apps/web/public/sw.js +169 -0
  103. package/apps/web/public/taps.js +26 -0
  104. package/apps/web/public/theme-surface.d.ts +4 -0
  105. package/apps/web/public/theme-surface.js +266 -0
  106. package/apps/web/public/theme.js +845 -0
  107. package/apps/web/public/themes/lantern/colors.toml +25 -0
  108. package/apps/web/public/themes/lantern/direction.css +60 -0
  109. package/apps/web/public/themes/lantern/frame.css +254 -0
  110. package/apps/web/public/themes/lantern/theme.css +10 -0
  111. package/apps/web/public/themes/lantern/theme.json +7 -0
  112. package/apps/web/public/themes/pocket/theme.css +189 -0
  113. package/apps/web/public/themes/pocket/theme.json +6 -0
  114. package/apps/web/public/themes.js +556 -0
  115. package/apps/web/public/transcript.js +3348 -0
  116. package/apps/web/public/trust.js +295 -0
  117. package/apps/web/public/turns.js +507 -0
  118. package/apps/web/public/ui.js +1910 -0
  119. package/apps/web/public/voice.js +345 -0
  120. package/apps/web/server.mjs +774 -0
  121. package/package.json +43 -4
  122. package/packages/cli/src/bom-pi.mjs +452 -0
  123. package/packages/cli/templates/blank.factory.json +7 -0
  124. package/packages/cli/templates/dev.factory.json +11 -0
  125. package/packages/cli/templates/docs.factory.json +12 -0
  126. package/packages/cli/templates/ops.factory.json +14 -0
  127. package/packages/cli/templates/triage.factory.json +10 -0
  128. package/packages/core/src/daemon.mjs +2047 -0
  129. package/packages/core/src/limit-gate.mjs +192 -0
  130. package/packages/core/src/rpc-client.mjs +66 -0
  131. package/systemd/README.md +11 -0
@@ -0,0 +1,216 @@
1
+ // Keys that extensions give the message boxes (`pocket.composerKey`): the session's box and PiP's. What modules added
2
+ // comes from `extension-ui.js` (`setBoxKeys`), so the boxes need not import it: no imports, so Node tests it.
3
+
4
+ const APPLE = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform ?? "");
5
+
6
+ /** The modifiers a key may name, and the event's flag for each. `Mod` is ⌘ on Apple's systems, Ctrl elsewhere. */
7
+ const MODIFIERS = {
8
+ ctrl: "ctrlKey",
9
+ control: "ctrlKey",
10
+ alt: "altKey",
11
+ option: "altKey",
12
+ shift: "shiftKey",
13
+ meta: "metaKey",
14
+ cmd: "metaKey",
15
+ command: "metaKey",
16
+ };
17
+
18
+ /** The named keys, by their lowercase name (and a few short ones), as `KeyboardEvent.key` names them. */
19
+ const NAMED = Object.fromEntries(
20
+ [
21
+ "Backspace",
22
+ "Delete",
23
+ "Enter",
24
+ "Tab",
25
+ "Escape",
26
+ "ArrowUp",
27
+ "ArrowDown",
28
+ "ArrowLeft",
29
+ "ArrowRight",
30
+ "Home",
31
+ "End",
32
+ "PageUp",
33
+ "PageDown",
34
+ "Insert",
35
+ ...Array.from({ length: 12 }, (_, index) => `F${index + 1}`),
36
+ ].map((name) => [name.toLowerCase(), name]),
37
+ );
38
+
39
+ Object.assign(NAMED, {
40
+ esc: "Escape",
41
+ del: "Delete",
42
+ return: "Enter",
43
+ space: " ",
44
+ up: "ArrowUp",
45
+ down: "ArrowDown",
46
+ left: "ArrowLeft",
47
+ right: "ArrowRight",
48
+ });
49
+
50
+ /**
51
+ * One key as `"Ctrl+W"`, `"Alt+Backspace"`, or `"Mod+Shift+K"`: modifiers, then a character or a named key, joined by
52
+ * `+`. Null when it is not one.
53
+ */
54
+ export function parseKey(text, apple = APPLE) {
55
+ if (typeof text !== "string") {
56
+ return null;
57
+ }
58
+
59
+ // A last part of "+" itself: "Ctrl++".
60
+ const parts = text.endsWith("++") ? [...text.slice(0, -2).split("+"), "+"] : text.split("+");
61
+ const last = parts.pop().trim();
62
+ const key = { ctrlKey: false, altKey: false, shiftKey: false, metaKey: false, key: "" };
63
+
64
+ for (const part of parts) {
65
+ const name = part.trim().toLowerCase();
66
+ const flag = name === "mod" ? (apple ? "metaKey" : "ctrlKey") : MODIFIERS[name];
67
+
68
+ if (flag === undefined || key[flag]) {
69
+ return null;
70
+ }
71
+
72
+ key[flag] = true;
73
+ }
74
+
75
+ if ([...last].length === 1) {
76
+ key.key = last.toLowerCase();
77
+ } else if (NAMED[last.toLowerCase()] !== undefined) {
78
+ key.key = NAMED[last.toLowerCase()];
79
+ } else {
80
+ return null;
81
+ }
82
+
83
+ return key;
84
+ }
85
+
86
+ /** A spec's `keys`, one or a list of up to 8, parsed: null when one is not a key. */
87
+ export function parseKeys(keys, apple = APPLE) {
88
+ const list = typeof keys === "string" ? [keys] : keys;
89
+
90
+ if (!Array.isArray(list) || list.length === 0 || list.length > 8) {
91
+ return null;
92
+ }
93
+
94
+ const parsed = list.map((each) => parseKey(each, apple));
95
+
96
+ return parsed.includes(null) ? null : parsed;
97
+ }
98
+
99
+ /**
100
+ * Whether a keydown is this key: the same modifiers, and the same character or named key. A letter or a digit also
101
+ * matches by where it is on the keyboard (`code`) while Alt is down, since Option on a Mac types another character.
102
+ */
103
+ export function matchesKey(key, event) {
104
+ if (
105
+ event.ctrlKey !== key.ctrlKey ||
106
+ event.altKey !== key.altKey ||
107
+ event.shiftKey !== key.shiftKey ||
108
+ event.metaKey !== key.metaKey
109
+ ) {
110
+ return false;
111
+ }
112
+
113
+ if (key.key.length > 1) {
114
+ return event.key === key.key;
115
+ }
116
+
117
+ if (event.key?.toLowerCase() === key.key) {
118
+ return true;
119
+ }
120
+
121
+ const code = /^[a-z]$/.test(key.key)
122
+ ? `Key${key.key.toUpperCase()}`
123
+ : /^\d$/.test(key.key)
124
+ ? `Digit${key.key}`
125
+ : null;
126
+
127
+ return event.altKey && code !== null && event.code === code;
128
+ }
129
+
130
+ /** A spec's `keys` as the Keyboard shortcuts sheet writes them: "Ctrl W or Alt Backspace". */
131
+ export function keysLabel(keys) {
132
+ const list = typeof keys === "string" ? [keys] : keys;
133
+
134
+ return list
135
+ .map((each) =>
136
+ (each.endsWith("++") ? [...each.slice(0, -2).split("+"), "+"] : each.split("+"))
137
+ .map((part) => part.trim())
138
+ .map((part) => (part.length === 1 ? part.toUpperCase() : part))
139
+ .join(" "),
140
+ )
141
+ .join(" or ");
142
+ }
143
+
144
+ /** The most text `set` puts into a box. */
145
+ const SET_MAX = 1_000_000;
146
+
147
+ /**
148
+ * What a module's `run` gets: the box's text and selection when the key came, and `set`, which writes new text and
149
+ * puts the caret (or a selection) through the box's own editing, so its draft is kept. `where` is `"session"` or
150
+ * `"pip"`.
151
+ */
152
+ export function keyBox(element, where, write) {
153
+ return Object.freeze({
154
+ where,
155
+ text: element.value,
156
+ start: element.selectionStart,
157
+ end: element.selectionEnd,
158
+ set(text, start = text?.length, end = start) {
159
+ if (typeof text !== "string" || text.length > SET_MAX) {
160
+ throw new Error(`box.set: give it text, up to ${SET_MAX} characters`);
161
+ }
162
+
163
+ const at = (value) =>
164
+ Math.max(0, Math.min(text.length, Number.isInteger(value) ? value : text.length));
165
+ const from = at(start);
166
+
167
+ write(text, from, Math.max(from, at(end)));
168
+ },
169
+ });
170
+ }
171
+
172
+ /** What modules added: `{ keys, label, module, run, failed }` for each, in the order the server lists the modules. */
173
+ let source = () => [];
174
+
175
+ /** Set by `extension-ui.js`, once. */
176
+ export function setBoxKeys(list) {
177
+ source = list;
178
+ }
179
+
180
+ /**
181
+ * Give a keydown in a message box to the first module's key that it is. `box` is what the module's `run` gets: the
182
+ * box's text, its selection, and `set`. True when a module took the key: the box then does nothing more with it.
183
+ */
184
+ export function boxKey(event, box) {
185
+ if (event.isComposing || event.keyCode === 229) {
186
+ return false;
187
+ }
188
+
189
+ for (const each of source()) {
190
+ if (!each.keys.some((key) => matchesKey(key, event))) {
191
+ continue;
192
+ }
193
+
194
+ try {
195
+ const result = each.run(box);
196
+
197
+ // An async run takes the key: it must say so before the browser acts on it.
198
+ if (result instanceof Promise) {
199
+ result.catch(each.failed);
200
+ }
201
+
202
+ return result !== false;
203
+ } catch (error) {
204
+ each.failed(error);
205
+
206
+ return false;
207
+ }
208
+ }
209
+
210
+ return false;
211
+ }
212
+
213
+ /** The modules' keys, for the Keyboard shortcuts sheet: `[keys, label]` rows. */
214
+ export function boxKeyRows() {
215
+ return source().map((each) => [keysLabel(each.keysText), `${each.label} (${each.module})`]);
216
+ }