sealkeep 0.7.0 → 0.7.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,28 @@
3
3
  Notable changes, by published version. Sealkeep is pre-1.0: minor versions
4
4
  may change behavior, and say so here when they do.
5
5
 
6
+ ## 0.7.2 — 2026-08-20
7
+
8
+ - Sharing is findable: the vault view offers **Share…** beside Restore. The
9
+ bundle is minted by the agent, not the browser — building one re-wraps the
10
+ archive key under a passcode, which needs the recovery phrase this API
11
+ deliberately never touches, the same reason Restore hands over a command.
12
+ - `docs/sharing-b2c-b2b.md` records the split: what the one-person hand-off
13
+ does today (verified end to end), and what a company sharing a project on its
14
+ own storage actually costs to build.
15
+
16
+ ## 0.7.1 — 2026-08-20
17
+
18
+ The dashboard and the account panel are one design system again.
19
+
20
+ - `design-system/tokens.css` is the single source; `npm run tokens` injects it
21
+ into both surfaces and `--check` fails on drift, with the suite enforcing it.
22
+ - The rule it encodes: monospace is what a machine said — a size, a path, a
23
+ state, a command — and sans is what we said. The dashboard had been running
24
+ every sentence in monospace because `--sans` was aliased to `--mono`, so its
25
+ option descriptions and standing notes read as terminal output. They read as
26
+ English now; every number, path and identifier is untouched.
27
+
6
28
  ## 0.7.0 — 2026-08-20
7
29
 
8
30
  Two reviews — does each section deserve to exist, and can a person finish the
@@ -22,11 +22,23 @@
22
22
  field on it is always, only, encrypted material.
23
23
  --------------------------------------------------------------------- */
24
24
  :root{
25
- --paper:#f4f4f3; --card:#fbfbfa; --ink:#111316; --soft:#5e646c; --rule:#dadcde;
26
- --seal:#101a3d; --seal-ink:#96a6e0; --live:#2a3fb0; --warn:#8c3220; --warn-bg:#f4e6e2;
27
- --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,"Helvetica Neue",sans-serif;
28
- --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,"DejaVu Sans Mono",Consolas,monospace;
29
- --gut:2.6rem;
25
+ /* @tokens:start — generated from design-system/tokens.css, do not edit here */
26
+ --paper: #f4f4f3;
27
+ --card: #fbfbfa;
28
+ --ink: #111316;
29
+ --soft: #5e646c;
30
+ --rule: #dadcde;
31
+ --seal: #101a3d;
32
+ --seal-ink: #96a6e0;
33
+ --live: #2a3fb0;
34
+ --warn: #8c3220;
35
+ --warn-bg: #f4e6e2;
36
+ --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, "Helvetica Neue", sans-serif;
37
+ --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, "DejaVu Sans Mono", Consolas, monospace;
38
+ /* @tokens:end */
39
+
40
+ /* Layout constant for this page's spine; not part of the shared palette. */
41
+ --gut: 2.6rem;
30
42
  }
31
43
  @media(prefers-color-scheme:dark){:root{
32
44
  --paper:#0d0f11; --card:#14171a; --ink:#e7e9ec; --soft:#8d949c; --rule:#24282d;
@@ -741,7 +753,7 @@ sealkeep open 08424eb6… ./session.jsonl \
741
753
  <div class="card">
742
754
  <span class="eyebrow">What gets uploaded</span>
743
755
  <h2>Your upload rules</h2>
744
- <p class="msg" style="margin:.1rem 0 .6rem">Saved to your account — every machine you connect follows these, the same way routing rules do.</p>
756
+ <p class="why" style="margin:.1rem 0 .8rem">Saved to your account — every machine you connect follows these, the same way routing rules do.</p>
745
757
  <p>Everything you do not choose here stays local and is never uploaded.</p>
746
758
  <p class="empty" id="r-note" style="margin-bottom:.9rem">Enforced on your machine, before a session is read or sealed. Anything held back is never uploaded, so this is a rule about what leaves — not a filter we apply after it arrives.</p>
747
759
  <div class="rules">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sealkeep",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "type": "module",
5
5
  "description": "Sealkeep by SPALA AI \u2014 your AI coding-agent history, sealed, searchable, and shared across your machines.",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -41,7 +41,8 @@
41
41
  "build:site": "node tools/build-site.mjs",
42
42
  "bundle:site": "node tools/build-site.mjs && cd dist/site && zip -q -X ../site.zip index.html && cd - >/dev/null && echo \"dist/site.zip ready ($(wc -c < dist/site.zip) bytes)\"",
43
43
  "acceptance": "node scripts/acceptance.mjs",
44
- "acceptance:managed": "node scripts/acceptance.mjs --managed"
44
+ "acceptance:managed": "node scripts/acceptance.mjs --managed",
45
+ "tokens": "node scripts/sync-tokens.mjs"
45
46
  },
46
47
  "devDependencies": {
47
48
  "@types/node": "^22.10.2",
package/web/app.js CHANGED
@@ -410,6 +410,36 @@ function renderQueue(queue, retention) {
410
410
  * command, filled in, so "how do I get this back" is a paste instead of a
411
411
  * manual.
412
412
  */
413
+ /**
414
+ * Sharing, offered where the archives are. The bundle itself is made by the
415
+ * agent, not by this page: building one re-wraps the archive key under a
416
+ * passcode, which needs the recovery phrase, and this API deliberately never
417
+ * touches it — the same reason Restore hands over a command instead of a file.
418
+ * What the page can do is make the feature findable and get the command right,
419
+ * including the destination and the warning that the passcode travels
420
+ * separately.
421
+ */
422
+ function shareButton(archive) {
423
+ const hand = document.createElement("button");
424
+ hand.type = "button";
425
+ hand.className = "action";
426
+ hand.textContent = "Share…";
427
+ hand.title = "Copies the command that seals this session into a bundle only a passcode opens";
428
+ hand.onclick = async () => {
429
+ const name = (archive.path || archive.id).split("/").pop().replace(/\.jsonl$/, "");
430
+ const command = `sealkeep share ${archive.id} --out ~/Desktop/${name}.vlshare`;
431
+ try {
432
+ await navigator.clipboard.writeText(command);
433
+ hand.textContent = "Command copied";
434
+ setStatus("Run it in a terminal — it prints a passcode. Send the bundle and the passcode by different routes; neither opens anything alone.", "");
435
+ } catch {
436
+ hand.textContent = command;
437
+ }
438
+ setTimeout(() => { hand.textContent = "Share…"; }, 6000);
439
+ };
440
+ return hand;
441
+ }
442
+
413
443
  function restoreButton(archive) {
414
444
  const hand = document.createElement("button");
415
445
  hand.type = "button";
@@ -625,7 +655,7 @@ function renderArchives(archives, retention) {
625
655
  }
626
656
 
627
657
  const act = row.insertCell();
628
- act.append(restoreButton(archive));
658
+ act.append(restoreButton(archive), shareButton(archive));
629
659
 
630
660
  // "Is my backup really there?" — asked of the storage, right now, not of
631
661
  // our own records. The answer arrives as a sentence on the status line
package/web/style.css CHANGED
@@ -10,12 +10,7 @@
10
10
  */
11
11
 
12
12
  :root {
13
- /* Vaultline design system — the ten tokens from site/index.html, the source
14
- of truth (see design-system/README.md). The older dashboard names below are
15
- kept as aliases so existing rules resolve to the system's colours without a
16
- full rename. The page is achromatic: the ONE saturated block is ciphertext
17
- (--seal); --live marks what is interactive or currently true; --warn is
18
- rationed to where inaction loses data. */
13
+ /* @tokens:start — generated from design-system/tokens.css, do not edit here */
19
14
  --paper: #f4f4f3;
20
15
  --card: #fbfbfa;
21
16
  --ink: #111316;
@@ -26,14 +21,17 @@
26
21
  --live: #2a3fb0;
27
22
  --warn: #8c3220;
28
23
  --warn-bg: #f4e6e2;
29
-
24
+ --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, "Helvetica Neue", sans-serif;
30
25
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, "DejaVu Sans Mono", Consolas, monospace;
31
- /* One typeface: monospace, including display sizes. --sans is aliased to it so
32
- any rule still asking for a second face complies instead of breaking the
33
- rule the whole system is built on. */
34
- --sans: var(--mono);
26
+ /* @tokens:end */
35
27
 
36
- /* Compatibility aliases: prior dashboard rules reference these names. */
28
+ /* Surface-local aliases: older dashboard rules ask for these names, and they
29
+ resolve to the system's colours rather than a second palette. Kept outside
30
+ the generated block on purpose — the token file describes the design
31
+ system, this describes one surface's history. */
32
+ /* Layout constants for this surface, not part of the shared palette. */
33
+ --rail: 264px;
34
+ --gap: 20px;
37
35
  --panel: var(--card);
38
36
  --rule-soft: #e6e7e9;
39
37
  --text: var(--ink);
@@ -43,17 +41,8 @@
43
41
  --verified: var(--live);
44
42
  --held: var(--soft);
45
43
  --alert: var(--warn);
46
- /* Were dark-navy fills for the old rail; now the solid-ink fill the system
47
- uses for a filled control. Lazy substitution keeps them theme-correct. */
48
44
  --ink-2: var(--ink);
49
45
  --ink-3: var(--soft);
50
- /* Rail is now part of the light page, not a dark slab. These name faint
51
- surfaces used for nav hover/active and glyphs. */
52
- --rail-active: #ecedf0;
53
- --rail-glyph: #9aa0a8;
54
-
55
- --rail: 264px;
56
- --gap: 20px;
57
46
  }
58
47
 
59
48
  /* ── Dark ─────────────────────────────────────────────── */
@@ -176,7 +165,9 @@ nav button .count { margin-left: auto; font-size: 11.5px; color: var(--soft); }
176
165
  margin-top: auto;
177
166
  border-top: 1px solid var(--rule);
178
167
  padding: 18px 12px 0;
179
- font-family: var(--mono);
168
+ /* Prose, so it reads as prose. Mono is reserved for what a machine said —
169
+ a size, a path, a state, a command — and this is us explaining the page. */
170
+ font-family: var(--sans);
180
171
  font-size: 12px;
181
172
  color: var(--soft);
182
173
  line-height: 1.65;