sealkeep 0.5.0 → 0.5.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/CHANGELOG.md +12 -0
- package/dist/site/index.html +23 -2
- package/dist/site.zip +0 -0
- package/package.json +2 -2
- package/web/app.js +11 -1
- package/web/index.html +4 -3
- package/web/retention.html +1 -0
- package/web/sessions.html +1 -0
- package/web/setup.html +11 -10
- package/web/setup.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
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.5.1 — 2026-08-19
|
|
7
|
+
|
|
8
|
+
The first release that lives entirely at its new addresses.
|
|
9
|
+
|
|
10
|
+
- Dashboard: the token gate probes once instead of eight times, so a first
|
|
11
|
+
visit no longer floods the console with 401s; every page carries the seal
|
|
12
|
+
favicon; panel and sign-in links point at sealkeep.spala.ai.
|
|
13
|
+
- Setup and token help name the real data folders — `~/.sealkeep`, or
|
|
14
|
+
`~/.vaultline` for vaults created before the rename.
|
|
15
|
+
- Google sign-in survives the old-domain bounce: the interim redirect at the
|
|
16
|
+
previous address forwards the OAuth code instead of dropping it.
|
|
17
|
+
|
|
6
18
|
## 0.5.0 — 2026-08-18
|
|
7
19
|
|
|
8
20
|
**Vaultline is now Sealkeep** (by SPALA AI) — the old name is used by several
|
package/dist/site/index.html
CHANGED
|
@@ -337,7 +337,7 @@
|
|
|
337
337
|
|
|
338
338
|
<section>
|
|
339
339
|
<h2>What it does</h2>
|
|
340
|
-
<p class="sub">
|
|
340
|
+
<p class="sub">Five things, and it does them without ever seeing your work.</p>
|
|
341
341
|
|
|
342
342
|
<div class="row-item duo">
|
|
343
343
|
<div class="human">
|
|
@@ -365,6 +365,25 @@
|
|
|
365
365
|
</div>
|
|
366
366
|
<div class="machine"><div class="ev">ChaCha20-Poly1305 · per-archive key<br>key wrapped to your 24-word phrase<br><b>server sees ciphertext only</b></div></div>
|
|
367
367
|
</div>
|
|
368
|
+
|
|
369
|
+
<div class="row-item duo">
|
|
370
|
+
<div class="human">
|
|
371
|
+
<span class="mark">Remember</span>
|
|
372
|
+
<h3>One memory across every machine</h3>
|
|
373
|
+
<p>The sealed index syncs beside your archives, so the laptop finds what the desktop sealed. Your agents search it too, over MCP — a collective memory of the project, not a folder on one disk.</p>
|
|
374
|
+
</div>
|
|
375
|
+
<div class="machine"><div class="ev">$ sealkeep search "why we forked the retry logic"<br><b>1 session</b> · sealed on your other machine<br>restore ✓ <b>byte-identical</b></div></div>
|
|
376
|
+
</div>
|
|
377
|
+
|
|
378
|
+
<div class="row-item duo">
|
|
379
|
+
<div class="human">
|
|
380
|
+
<span class="mark">Drive</span>
|
|
381
|
+
<h3>The Drive space you never use</h3>
|
|
382
|
+
<p>Point your agent history at the Google Drive storage you already pay for. One consent connects it; everything is sealed before upload, so Drive holds ciphertext. Cap it, pin projects to it, and let the rest go to managed cloud.</p>
|
|
383
|
+
</div>
|
|
384
|
+
<div class="machine"><div class="ev">$ sealkeep storage targets add gdrive --max-gb 50<br>connected · folder <b>Sealkeep</b> · cap 50 GB<br>project big-refactor → Drive · rest → cloud</div></div>
|
|
385
|
+
</div>
|
|
386
|
+
|
|
368
387
|
</section>
|
|
369
388
|
|
|
370
389
|
<section id="plans">
|
|
@@ -711,7 +730,9 @@ sealkeep open 08424eb6… ./session.jsonl \
|
|
|
711
730
|
|
|
712
731
|
<script>
|
|
713
732
|
const $ = (id) => document.getElementById(id);
|
|
714
|
-
const API = "
|
|
733
|
+
const API = location.hostname === "shared.spala.ai"
|
|
734
|
+
? "/p04946/api"
|
|
735
|
+
: "https://shared.spala.ai/p04946/api";
|
|
715
736
|
// sessionStorage, not localStorage: a bearer token should die with the tab
|
|
716
737
|
// rather than rest on disk.
|
|
717
738
|
const TOKEN = "vaultline.token";
|
package/dist/site.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sealkeep",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
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",
|
|
@@ -62,4 +62,4 @@
|
|
|
62
62
|
"sessions"
|
|
63
63
|
],
|
|
64
64
|
"homepage": "https://sealkeep.spala.ai"
|
|
65
|
-
}
|
|
65
|
+
}
|
package/web/app.js
CHANGED
|
@@ -1361,7 +1361,17 @@ async function guard(action) {
|
|
|
1361
1361
|
async function start() {
|
|
1362
1362
|
// No token in hand is not yet a reason to gate: a browser that has been here
|
|
1363
1363
|
// before holds the HttpOnly cookie, which the server accepts and this page
|
|
1364
|
-
// cannot see.
|
|
1364
|
+
// cannot see. But discovering that costs one request, not eight — probe
|
|
1365
|
+
// /v1/status alone, and only fan out the full refresh once it answers. The
|
|
1366
|
+
// browser prints every 401 to the console no matter what we do; one line on
|
|
1367
|
+
// a first visit is honest, eight looked like a malfunction.
|
|
1368
|
+
const probe = await fetch("/v1/status", {
|
|
1369
|
+
headers: { authorization: `Bearer ${token ?? ""}` }
|
|
1370
|
+
}).catch(() => null);
|
|
1371
|
+
if (!probe || probe.status === 401) {
|
|
1372
|
+
showGate(token ? "That token was not accepted." : undefined);
|
|
1373
|
+
return;
|
|
1374
|
+
}
|
|
1365
1375
|
await guard(refresh);
|
|
1366
1376
|
// Land on the view named in the URL (e.g. arriving at index.html#settings from
|
|
1367
1377
|
// the Sessions page), not always Overview.
|
package/web/index.html
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
6
|
<meta name="referrer" content="no-referrer">
|
|
7
7
|
<title>Sealkeep</title>
|
|
8
|
+
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 16 16%22%3E%3Ctext x=%228%22 y=%2213%22 font-size=%2214%22 text-anchor=%22middle%22%3E%E2%8C%91%3C/text%3E%3C/svg%3E">
|
|
8
9
|
<link rel="stylesheet" href="./style.css">
|
|
9
10
|
<style>
|
|
10
11
|
/* Memory pool: the project column. The name answers "which repo", the dim
|
|
@@ -108,7 +109,7 @@
|
|
|
108
109
|
|
|
109
110
|
<section id="gate" class="panel gate pad" hidden>
|
|
110
111
|
<h3>Local token required</h3>
|
|
111
|
-
<p class="note">This browser has not been given its key yet. Paste the token from <code id="token-path"
|
|
112
|
+
<p class="note">This browser has not been given its key yet. Paste the token from <code id="token-path">local-api-token</code> in your Sealkeep data folder (<code>~/.sealkeep</code>, or <code>~/.vaultline</code> for older vaults) — a local file, so nothing here is sent anywhere. The browser <code>sealkeep ui</code> opened is signed in already.</p>
|
|
112
113
|
<form id="token-form">
|
|
113
114
|
<input id="token-input" type="password" autocomplete="off" spellcheck="false" placeholder="local API token" aria-label="Local API token">
|
|
114
115
|
<button type="submit" class="action">Connect</button>
|
|
@@ -172,7 +173,7 @@
|
|
|
172
173
|
where work in motion belongs. -->
|
|
173
174
|
<div class="panel" id="archives-panel"></div>
|
|
174
175
|
<div class="panel pad" style="margin-top:var(--gap)">
|
|
175
|
-
<p class="note"><b>If this machine is lost:</b> your recovery phrase plus <code>
|
|
176
|
+
<p class="note"><b>If this machine is lost:</b> your recovery phrase plus <code>sealkeep cloud login</code> on any machine reaches every copy in managed storage. The phrase is the only key — no copy anywhere can be opened without it.</p>
|
|
176
177
|
</div>
|
|
177
178
|
</section>
|
|
178
179
|
|
|
@@ -264,7 +265,7 @@
|
|
|
264
265
|
|
|
265
266
|
<h2>Account</h2>
|
|
266
267
|
<div class="panel pad">
|
|
267
|
-
<p class="note">Set from <a id="set-panel-link" href="https://
|
|
268
|
+
<p class="note">Set from <a id="set-panel-link" href="https://sealkeep.spala.ai" target="_blank" rel="noopener">the account panel</a>, not here — these apply to every machine on the account, and this machine only mirrors them.</p>
|
|
268
269
|
<div class="metrics">
|
|
269
270
|
<div class="metric"><h3>What leaves this machine</h3><b id="set-sync-mode" class="small">–</b><small id="set-sync-source"></small></div>
|
|
270
271
|
<div class="metric"><h3>Plan</h3><b id="set-plan" class="small">–</b><small> </small></div>
|
package/web/retention.html
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<title>Free up disk — rules · Sealkeep</title>
|
|
6
|
+
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 16 16%22%3E%3Ctext x=%228%22 y=%2213%22 font-size=%2214%22 text-anchor=%22middle%22%3E%E2%8C%91%3C/text%3E%3C/svg%3E">
|
|
6
7
|
<meta name="referrer" content="no-referrer">
|
|
7
8
|
</head>
|
|
8
9
|
<body>
|
package/web/sessions.html
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<title>Sealkeep — memory pool</title>
|
|
6
|
+
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 16 16%22%3E%3Ctext x=%228%22 y=%2213%22 font-size=%2214%22 text-anchor=%22middle%22%3E%E2%8C%91%3C/text%3E%3C/svg%3E">
|
|
6
7
|
<meta name="referrer" content="no-referrer">
|
|
7
8
|
</head>
|
|
8
9
|
<body>
|
package/web/setup.html
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
6
|
<meta name="referrer" content="no-referrer">
|
|
7
7
|
<title>Sealkeep — first run</title>
|
|
8
|
+
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 16 16%22%3E%3Ctext x=%228%22 y=%2213%22 font-size=%2214%22 text-anchor=%22middle%22%3E%E2%8C%91%3C/text%3E%3C/svg%3E">
|
|
8
9
|
<link rel="stylesheet" href="./style.css">
|
|
9
10
|
</head>
|
|
10
11
|
<body>
|
|
@@ -175,8 +176,8 @@
|
|
|
175
176
|
<!-- Both links name a tab, not just the section, so nobody lands on the
|
|
176
177
|
page and has to work out which half they were sent for. -->
|
|
177
178
|
<div class="actions">
|
|
178
|
-
<a class="action primary" href="https://
|
|
179
|
-
<a class="action" href="https://
|
|
179
|
+
<a class="action primary" href="https://sealkeep.spala.ai/#signup" target="_blank" rel="noreferrer noopener">Create an account</a>
|
|
180
|
+
<a class="action" href="https://sealkeep.spala.ai/#signin" target="_blank" rel="noreferrer noopener">I already have one — sign in</a>
|
|
180
181
|
</div>
|
|
181
182
|
<p class="note">The pairing code is single use, and it is not your recovery phrase.</p>
|
|
182
183
|
<div class="actions">
|
|
@@ -194,12 +195,12 @@
|
|
|
194
195
|
<div class="row">
|
|
195
196
|
<div class="field">
|
|
196
197
|
<label for="f-bucket">Bucket name</label>
|
|
197
|
-
<input id="f-bucket" name="bucket" type="text" autocomplete="off" spellcheck="false" placeholder="my-
|
|
198
|
+
<input id="f-bucket" name="bucket" type="text" autocomplete="off" spellcheck="false" placeholder="my-sealkeep-archives">
|
|
198
199
|
<p class="note error" id="e-bucket" hidden></p>
|
|
199
200
|
</div>
|
|
200
201
|
<div class="field">
|
|
201
202
|
<label for="f-prefix">Folder inside it</label>
|
|
202
|
-
<input id="f-prefix" name="prefix" type="text" autocomplete="off" spellcheck="false" value="
|
|
203
|
+
<input id="f-prefix" name="prefix" type="text" autocomplete="off" spellcheck="false" value="sealkeep">
|
|
203
204
|
<p class="note error" id="e-prefix" hidden></p>
|
|
204
205
|
</div>
|
|
205
206
|
</div>
|
|
@@ -372,16 +373,16 @@
|
|
|
372
373
|
<!-- Shown instead of a blank page when the machine cannot answer. -->
|
|
373
374
|
<!-- The token lives in sessionStorage, which belongs to one browser. Opening
|
|
374
375
|
this address in a second one arrives with nothing, and telling that person
|
|
375
|
-
to "run
|
|
376
|
+
to "run sealkeep ui" is both a terminal instruction and the wrong one:
|
|
376
377
|
it would open their default browser, not the one they are looking at. So
|
|
377
378
|
the page offers the way in that works from here. -->
|
|
378
379
|
<section class="screen" id="screen-gate" hidden>
|
|
379
380
|
<header>
|
|
380
381
|
<h1>Sign this browser in</h1>
|
|
381
|
-
<p class="lede">Sealkeep is running on this machine — this browser just has not been given its key yet. That happens automatically in whichever browser <code>
|
|
382
|
+
<p class="lede">Sealkeep is running on this machine — this browser just has not been given its key yet. That happens automatically in whichever browser <code>sealkeep ui</code> opened.</p>
|
|
382
383
|
</header>
|
|
383
384
|
<div class="panel pad">
|
|
384
|
-
<p class="note">Paste the token from <code id="gate-token-path"
|
|
385
|
+
<p class="note">Paste the token from <code id="gate-token-path">local-api-token</code> in your Sealkeep data folder (<code>~/.sealkeep</code>, or <code>~/.vaultline</code> for older vaults). It is a local file; nothing here is sent anywhere.</p>
|
|
385
386
|
<form id="gate-form">
|
|
386
387
|
<div class="field">
|
|
387
388
|
<label for="gate-token">Local API token</label>
|
|
@@ -390,7 +391,7 @@
|
|
|
390
391
|
<div class="actions"><button type="submit" class="action primary">Connect this browser</button></div>
|
|
391
392
|
</form>
|
|
392
393
|
<p class="note error" id="gate-error" hidden></p>
|
|
393
|
-
<p class="note">On macOS or Linux: <code>cat ~/.
|
|
394
|
+
<p class="note">On macOS or Linux: <code>cat ~/.sealkeep/local-api-token</code> (older vaults: <code>~/.vaultline</code>)</p>
|
|
394
395
|
</div>
|
|
395
396
|
</section>
|
|
396
397
|
|
|
@@ -401,8 +402,8 @@
|
|
|
401
402
|
</header>
|
|
402
403
|
<div class="panel pad callout">
|
|
403
404
|
<h3>What to do instead</h3>
|
|
404
|
-
<p>Update to a build that has the setup endpoints: <code>npm i -g
|
|
405
|
-
<p>Or set the same things up from a terminal — the wizard is a second way in, never the only one: <code>
|
|
405
|
+
<p>Update to a build that has the setup endpoints: <code>npm i -g sealkeep@latest</code>, then run <code>sealkeep</code> again.</p>
|
|
406
|
+
<p>Or set the same things up from a terminal — the wizard is a second way in, never the only one: <code>sealkeep setup</code>, <code>sealkeep storage configure</code>.</p>
|
|
406
407
|
<p>Already have a vault? The <a href="./index.html">dashboard</a> works regardless.</p>
|
|
407
408
|
</div>
|
|
408
409
|
</section>
|
package/web/setup.js
CHANGED
|
@@ -654,7 +654,7 @@ async function boot() {
|
|
|
654
654
|
// here" ticked above a fully drawn R2 form.
|
|
655
655
|
draft.intent = intentFor(draft.providerId);
|
|
656
656
|
draft.storage.bucket = state.storage.bucket ?? "";
|
|
657
|
-
draft.storage.prefix = state.storage.prefix ?? "
|
|
657
|
+
draft.storage.prefix = state.storage.prefix ?? "sealkeep";
|
|
658
658
|
}
|
|
659
659
|
} catch (error) {
|
|
660
660
|
if (error.missing) {
|