openvibers/openvibe.locker Commits
Add llms-full.txt (#7)
Changes
nnew file mode 100644@@@ -0,0 +1,32 @@++# OpenVibe.Locker++++> Private files, password logins and expiring Sends. Seal and open only on your device with openvibe-sdk/locker. The service stores opaque locker.envelope.v1 ciphertext in OpenVibe.Media's private locker namespace.++++## Pages++++### OpenVibe.Locker++++URL: https://openvibe.locker/++++Keep it yours. A private place for your files, locked on your device before they leave it. Drive keeps files and folders encrypted on your device and shares them with the people you choose. Sends are a file or a note with a time limit and an optional download limit. The key stays after # in a Send link and is never sent to OpenVibe.++++OpenVibe stores encrypted bytes and can see only the owner, the padded size and the time. If you lose your password (or your locker passphrase and recovery kit), nobody can open your items, including OpenVibe.++++### Locked items on OpenVibe++++URL: https://openvibe.locker/docs++++A people lock opens with the keys of the people on its list. A password lock opens with its password. A link lock opens with a key after #. The same Locker envelope works across OpenVibe.++++Drive uses people locks. Sends use link locks, expire in 1 hour to 30 days, and can have a download limit. Names, types, true sizes and contents are inside the envelope. Recipients can keep what they open.++++Lock a file for an @name with the Locker SDK (openvibe-sdk/locker) and the Network key directory: include your own key before uploading to Drive, then use the Share API to add the recipient. For large files use sealStream and openStream, and discard a download if final verification fails.++++## Machine-readable++++- OpenAPI 3.1: https://openvibe.locker/openapi.json++- Agent descriptor: https://openvibe.locker/.well-known/agent.json++- llms.txt: https://openvibe.locker/llms.txt++- Source, payload format and streaming examples: https://github.com/OpenVibers/OpenVibe.Locker++- Locker SDK: https://github.com/OpenVibers/OpenVibe.SDK/blob/main/docs/locker.md++- Sharing SDK: https://github.com/OpenVibers/OpenVibe.SDK/blob/main/docs/share.md@@@ -7,6 +7,7 @@ Never send plaintext, filenames, passwords, recovery words, private keys or a Se- [Locked items on OpenVibe](/docs)- [Passwords](/passwords)- [OpenAPI](/openapi.json)++- [Full text for language models](/llms-full.txt)- [Source, payload format and streaming examples](https://github.com/OpenVibers/OpenVibe.Locker)- [Locker SDK](https://github.com/OpenVibers/OpenVibe.SDK/blob/main/docs/locker.md)- [Sharing SDK](https://github.com/OpenVibers/OpenVibe.SDK/blob/main/docs/share.md)@@@ -10,6 +10,23 @@ const create = async (sealed, send = false, extra = '') => {const body = await r.json(); assert.equal(r.status, 201, JSON.stringify(body)); return body;};++test('llms.txt and llms-full.txt describe the public pages', async () => {++ const llms = await t.request('GET', '/llms.txt', { user: null });++ assert.equal(llms.status, 200);++ assert.match(llms.headers.get('content-type'), /^text\/plain/);++ assert.match(await llms.text(), /\(\/llms-full\.txt\)/, 'llms.txt names the full text');++ const full = await t.request('GET', '/llms-full.txt', { user: null });++ assert.equal(full.status, 200);++ assert.match(full.headers.get('content-type'), /^text\/plain/);++ const text = await full.text();++ assert.ok(text.startsWith('# OpenVibe.Locker\n'), 'llms-full.txt opens with the site heading');++ assert.ok(text.length > 500, `llms-full.txt carries the pages (${text.length} characters)`);++ for (const url of ['https://openvibe.locker/', 'https://openvibe.locker/docs', 'https://openvibe.locker/openapi.json', 'https://openvibe.locker/.well-known/agent.json']) {++ assert.ok(text.includes(url), `llms-full.txt names ${url}`);++ }++ assert.ok(!text.includes('/passwords'), 'no signed-in page is in the full text');++});++test('password login items use people locks and remain opaque in storage', async () => {const secret = JSON.stringify({ version: 1, site: 'https://example.test', username: 'alice', password: 'secret-password', totp: '', notes: '' });const encrypted = await locker.seal(secret, { lock: 'people', keys: [{ subject: { type: 'user', id: SUBJECT }, publicKey: t.people.get(SUBJECT).ecdhPublic }] });
new file mode 100644
new file mode 100644
@@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
+# OpenVibe.Locker
+
+> Private files, password logins and expiring Sends. Seal and open only on your device with openvibe-sdk/locker. The service stores opaque locker.envelope.v1 ciphertext in OpenVibe.Media's private locker namespace.
+
+## Pages
+
+### OpenVibe.Locker
+
+URL: https://openvibe.locker/
+
+Keep it yours. A private place for your files, locked on your device before they leave it. Drive keeps files and folders encrypted on your device and shares them with the people you choose. Sends are a file or a note with a time limit and an optional download limit. The key stays after # in a Send link and is never sent to OpenVibe.
+
+OpenVibe stores encrypted bytes and can see only the owner, the padded size and the time. If you lose your password (or your locker passphrase and recovery kit), nobody can open your items, including OpenVibe.
+
+### Locked items on OpenVibe
+
+URL: https://openvibe.locker/docs
+
+A people lock opens with the keys of the people on its list. A password lock opens with its password. A link lock opens with a key after #. The same Locker envelope works across OpenVibe.
+
+Drive uses people locks. Sends use link locks, expire in 1 hour to 30 days, and can have a download limit. Names, types, true sizes and contents are inside the envelope. Recipients can keep what they open.
+
+Lock a file for an @name with the Locker SDK (openvibe-sdk/locker) and the Network key directory: include your own key before uploading to Drive, then use the Share API to add the recipient. For large files use sealStream and openStream, and discard a download if final verification fails.
+
+## Machine-readable
+
+- OpenAPI 3.1: https://openvibe.locker/openapi.json
+- Agent descriptor: https://openvibe.locker/.well-known/agent.json
+- llms.txt: https://openvibe.locker/llms.txt
+- Source, payload format and streaming examples: https://github.com/OpenVibers/OpenVibe.Locker
+- Locker SDK: https://github.com/OpenVibers/OpenVibe.SDK/blob/main/docs/locker.md
+- Sharing SDK: https://github.com/OpenVibers/OpenVibe.SDK/blob/main/docs/share.md
@@ -7,6 +7,7 @@ Never send plaintext, filenames, passwords, recovery words, private keys or a Se
@@ -7,6 +7,7 @@ Never send plaintext, filenames, passwords, recovery words, private keys or a Se
- [Locked items on OpenVibe](/docs)
- [Locked items on OpenVibe](/docs)
- [Passwords](/passwords)
- [Passwords](/passwords)
- [OpenAPI](/openapi.json)
- [OpenAPI](/openapi.json)
+- [Full text for language models](/llms-full.txt)
- [Source, payload format and streaming examples](https://github.com/OpenVibers/OpenVibe.Locker)
- [Source, payload format and streaming examples](https://github.com/OpenVibers/OpenVibe.Locker)
- [Locker SDK](https://github.com/OpenVibers/OpenVibe.SDK/blob/main/docs/locker.md)
- [Locker SDK](https://github.com/OpenVibers/OpenVibe.SDK/blob/main/docs/locker.md)
- [Sharing SDK](https://github.com/OpenVibers/OpenVibe.SDK/blob/main/docs/share.md)
- [Sharing SDK](https://github.com/OpenVibers/OpenVibe.SDK/blob/main/docs/share.md)
@@ -10,6 +10,23 @@ const create = async (sealed, send = false, extra = '') => {
@@ -10,6 +10,23 @@ const create = async (sealed, send = false, extra = '') => {
const body = await r.json(); assert.equal(r.status, 201, JSON.stringify(body)); return body;
const body = await r.json(); assert.equal(r.status, 201, JSON.stringify(body)); return body;
};
};
+test('llms.txt and llms-full.txt describe the public pages', async () => {
+ const llms = await t.request('GET', '/llms.txt', { user: null });
+ assert.equal(llms.status, 200);
+ assert.match(llms.headers.get('content-type'), /^text\/plain/);
+ assert.match(await llms.text(), /\(\/llms-full\.txt\)/, 'llms.txt names the full text');
+ const full = await t.request('GET', '/llms-full.txt', { user: null });
+ assert.equal(full.status, 200);
+ assert.match(full.headers.get('content-type'), /^text\/plain/);
+ const text = await full.text();
+ assert.ok(text.startsWith('# OpenVibe.Locker\n'), 'llms-full.txt opens with the site heading');
+ assert.ok(text.length > 500, `llms-full.txt carries the pages (${text.length} characters)`);
+ for (const url of ['https://openvibe.locker/', 'https://openvibe.locker/docs', 'https://openvibe.locker/openapi.json', 'https://openvibe.locker/.well-known/agent.json']) {
+ assert.ok(text.includes(url), `llms-full.txt names ${url}`);
+ }
+ assert.ok(!text.includes('/passwords'), 'no signed-in page is in the full text');
+});
+
test('password login items use people locks and remain opaque in storage', async () => {
test('password login items use people locks and remain opaque in storage', async () => {
const secret = JSON.stringify({ version: 1, site: 'https://example.test', username: 'alice', password: 'secret-password', totp: '', notes: '' });
const secret = JSON.stringify({ version: 1, site: 'https://example.test', username: 'alice', password: 'secret-password', totp: '', notes: '' });
const encrypted = await locker.seal(secret, { lock: 'people', keys: [{ subject: { type: 'user', id: SUBJECT }, publicKey: t.people.get(SUBJECT).ecdhPublic }] });
const encrypted = await locker.seal(secret, { lock: 'people', keys: [{ subject: { type: 'user', id: SUBJECT }, publicKey: t.people.get(SUBJECT).ecdhPublic }] });