@profullstack/readm3 0.4.0 → 0.6.0
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/README.md +98 -0
- package/dist/account.d.ts +27 -0
- package/dist/account.d.ts.map +1 -0
- package/dist/account.js +59 -0
- package/dist/account.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -2
- package/dist/cli.js.map +1 -1
- package/dist/cloud-cli.d.ts +1 -1
- package/dist/cloud-cli.d.ts.map +1 -1
- package/dist/cloud-cli.js +33 -1
- package/dist/cloud-cli.js.map +1 -1
- package/dist/cloud-client.d.ts +6 -1
- package/dist/cloud-client.d.ts.map +1 -1
- package/dist/cloud-client.js +17 -15
- package/dist/cloud-client.js.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +26 -4
- package/dist/mcp.js.map +1 -1
- package/dist/settings-sync.d.ts +15 -0
- package/dist/settings-sync.d.ts.map +1 -0
- package/dist/settings-sync.js +79 -0
- package/dist/settings-sync.js.map +1 -0
- package/dist/sync-cli.d.ts +3 -0
- package/dist/sync-cli.d.ts.map +1 -0
- package/dist/sync-cli.js +166 -0
- package/dist/sync-cli.js.map +1 -0
- package/dist/sync-schema.d.ts +37 -0
- package/dist/sync-schema.d.ts.map +1 -0
- package/dist/sync-schema.js +63 -0
- package/dist/sync-schema.js.map +1 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -246,6 +246,24 @@ The REST API is at `/api/v1`, with all operations also available through
|
|
|
246
246
|
`POST /api/v1/actions` and `readm3 cloud OPERATION --args JSON`.
|
|
247
247
|
Full permissions, accounts, CLI, API, and MCP documentation: https://readm3.com/sharing.
|
|
248
248
|
|
|
249
|
+
### Private links without an account
|
|
250
|
+
|
|
251
|
+
```sh
|
|
252
|
+
readm3 paste notes.md # prints https://readm3.com/p/<token>
|
|
253
|
+
cat notes.md | readm3 paste --expires 1d --title "Standup"
|
|
254
|
+
readm3 paste get URL --raw
|
|
255
|
+
readm3 paste delete URL
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
A paste is a Markdown file behind a secret link. No sign-in, no account: anyone with
|
|
259
|
+
the link can read it, nobody can list or search for it, and only the hash of the
|
|
260
|
+
secret is stored, so the link cannot be shown again. The Share button in the web
|
|
261
|
+
reader makes one when you are signed out. Pastes expire after seven days by default
|
|
262
|
+
(1h, 1d, 7d or 30d), are limited to 256 KB, and can be deleted by anyone holding the
|
|
263
|
+
link. The same three calls are `POST /api/v1/pastes`, `GET /api/v1/pastes/<token>` and
|
|
264
|
+
`DELETE /api/v1/pastes/<token>`, and the `paste_create`, `paste_get` and
|
|
265
|
+
`paste_delete` MCP tools.
|
|
266
|
+
|
|
249
267
|
## Web reader
|
|
250
268
|
|
|
251
269
|
Open https://readm3.com/viewer for the same two-pane Markdown reader in your browser.
|
|
@@ -259,6 +277,12 @@ Press `/` to filter, `e` to edit, `Escape` to return to reading, and `?` for sho
|
|
|
259
277
|
on this device; originals on disk are never overwritten. Reopening a file adds a copy
|
|
260
278
|
so an existing draft is preserved. Clearing browser site data removes the workspace.
|
|
261
279
|
|
|
280
|
+
A link can open a document too: `https://readm3.com/viewer?url=https://host/doc.md`
|
|
281
|
+
fetches that raw Markdown URL into the workspace, so a site that publishes plain
|
|
282
|
+
Markdown can put a "render this" link on every page. The host must allow
|
|
283
|
+
cross-origin reads (`Access-Control-Allow-Origin: *`); when the fetch fails, the
|
|
284
|
+
Open URL dialog opens with the address and the reason filled in.
|
|
285
|
+
|
|
262
286
|
Install through your browser’s app menu, or Share → Add to Home Screen on iOS.
|
|
263
287
|
After the first visit, the application and saved workspace work offline. Remote URLs
|
|
264
288
|
need a connection and a host that permits browser access (CORS); files are fetched
|
|
@@ -354,6 +378,80 @@ bun run test:server # auth, roles, version history, persistence, CLI and MCP
|
|
|
354
378
|
bun run test:site # local/offline reader plus browser sharing and admin workflows
|
|
355
379
|
```
|
|
356
380
|
|
|
381
|
+
## Workspace and settings sync
|
|
382
|
+
|
|
383
|
+
Sign in with verified email at `/account`, then create a personal API token in `/admin`. The PWA's **Sync** button saves or loads
|
|
384
|
+
your local Markdown workspace and reader preferences on that same account. Shared
|
|
385
|
+
documents continue to use their own document permissions and version history.
|
|
386
|
+
Local files are uploaded only when you choose **Save to account**, `readm3 save`,
|
|
387
|
+
or a sharing action. Sync requires a connection; the local reader still works offline.
|
|
388
|
+
|
|
389
|
+
The CLI, document commands, and MCP use one credential file, `cloud.json`, under
|
|
390
|
+
`$XDG_CONFIG_HOME/readm3` (normally `~/.config/readm3`). It is written with mode
|
|
391
|
+
0600. Login verifies the account; logout removes the local credential. Revoke a token
|
|
392
|
+
in `/admin` to invalidate remote copies. Tokens can also be created and revoked from the account page.
|
|
393
|
+
|
|
394
|
+
```sh
|
|
395
|
+
readm3 login --token-stdin # paste a token, then Ctrl+D
|
|
396
|
+
readm3 whoami
|
|
397
|
+
readm3 settings --theme nord --flavor github
|
|
398
|
+
readm3 save ./notes # explicitly import and save Markdown
|
|
399
|
+
readm3 sync status
|
|
400
|
+
readm3 sync revisions
|
|
401
|
+
readm3 load --dry-run # inspect the incoming changes
|
|
402
|
+
readm3 load ./downloaded-notes # load and export into a new directory
|
|
403
|
+
readm3 load --force # replace local conflicts, with backups
|
|
404
|
+
readm3 logout
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
For self-hosting, set `READM3_URL` to the server origin, or set `READM3_API_URL` to
|
|
408
|
+
its API base such as `http://127.0.0.1:3000/api/v1`. `READM3_TOKEN` supplies a token
|
|
409
|
+
without writing it to disk. `READM3_CONFIG_DIR` selects an isolated client directory.
|
|
410
|
+
HTTPS is required except on localhost. A saved token is never sent to a different
|
|
411
|
+
server merely because an environment variable changed.
|
|
412
|
+
|
|
413
|
+
Sync uses `@profullstack/synconfig`, the same package used by moshcode. Only
|
|
414
|
+
`settings.json` (theme and flavor) and `workspace.json` (the explicitly imported
|
|
415
|
+
workspace) are allowed. Credentials, local revision markers, and backups are excluded.
|
|
416
|
+
Running `save` without a path saves those local files; it does not scan the current
|
|
417
|
+
directory. Running `load` without an output directory updates those files, and loaded
|
|
418
|
+
preferences apply to subsequent terminal reader invocations.
|
|
419
|
+
|
|
420
|
+
Each account keeps ten revisions. Saves carry the last loaded revision and reject
|
|
421
|
+
concurrent changes; a new device starts at revision 0. Loads refuse to replace
|
|
422
|
+
conflicting local edits, including on a device that has never synced. `--force`
|
|
423
|
+
explicitly overrides a conflict. Replaced local files receive numbered `.bak-NNN`
|
|
424
|
+
backups. Browser replacements receive backups in IndexedDB, accessible through
|
|
425
|
+
**Sync → Local backups** for download or restoration. Clearing browser site data
|
|
426
|
+
also removes those local backups. Sync supports the browser's workspace limits:
|
|
427
|
+
1,000 Markdown files, 4 MB per file, and 20 MB of source in total.
|
|
428
|
+
|
|
429
|
+
The authenticated API exposes:
|
|
430
|
+
|
|
431
|
+
| Endpoint | Purpose |
|
|
432
|
+
| --- | --- |
|
|
433
|
+
| `GET /api/v1/me` | Current account; `user: null` when signed out |
|
|
434
|
+
| `GET /api/v1/settings` | Latest snapshot, digest, and revision; 404 when empty |
|
|
435
|
+
| `PUT /api/v1/settings` | Save `{ snapshot, ifRevision }`; 409 on a conflict |
|
|
436
|
+
| `GET /api/v1/settings/revisions` | The last ten revision summaries |
|
|
437
|
+
|
|
438
|
+
`/api/v1/synconfig` is an alias for the settings endpoints. A snapshot is
|
|
439
|
+
`{ version: 1, host, app, files: { "settings.json": { content: "{...}" } } }`.
|
|
440
|
+
`workspace.json` uses `{ name, active, documents: [{ path, source }] }` inside its
|
|
441
|
+
JSON content string. Send `ifRevision: 0` for a first save, the revision last loaded
|
|
442
|
+
for subsequent saves, or `null` for an explicitly forced save. API callers use
|
|
443
|
+
`Authorization: Bearer TOKEN`; browser callers use the same account's HTTP-only
|
|
444
|
+
session cookie and same-origin requests. Account responses are never cached offline.
|
|
445
|
+
|
|
446
|
+
Start MCP with `readm3 mcp`. Alongside the document and organization tools, it exposes
|
|
447
|
+
`settings_get`, `settings_save`, and `settings_revisions`. `settings_save` requires
|
|
448
|
+
a nonnegative `ifRevision` and uses the same validation and conflict checks as the API.
|
|
449
|
+
|
|
450
|
+
Run `bun run test:server` for account/sync integration checks and `bun run test:site`
|
|
451
|
+
for browser checks. The server needs Bun and a persistent `READM3_DB` SQLite path;
|
|
452
|
+
in the container this defaults to `/data/readm3.sqlite`, so mount persistent storage
|
|
453
|
+
at `/data`. Set `READM3_URL` to the public origin for browser origin checks.
|
|
454
|
+
|
|
357
455
|
## License
|
|
358
456
|
|
|
359
457
|
MIT.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface AccountUser {
|
|
2
|
+
id: string;
|
|
3
|
+
username: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
}
|
|
6
|
+
export interface Credentials {
|
|
7
|
+
api: string;
|
|
8
|
+
token: string;
|
|
9
|
+
user: AccountUser;
|
|
10
|
+
expiresAt?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const configDir: () => string;
|
|
13
|
+
export declare function apiUrl(value?: string): string;
|
|
14
|
+
export declare function writeConfig(name: string, value: unknown, root?: string): void;
|
|
15
|
+
export declare function storedCredentials(root?: string): Credentials | undefined;
|
|
16
|
+
export declare class ApiError extends Error {
|
|
17
|
+
status: number;
|
|
18
|
+
body: Record<string, unknown>;
|
|
19
|
+
constructor(status: number, message: string, body: Record<string, unknown>);
|
|
20
|
+
}
|
|
21
|
+
export declare function accountClient(options: {
|
|
22
|
+
api: string;
|
|
23
|
+
token?: string;
|
|
24
|
+
fetchImpl?: typeof fetch;
|
|
25
|
+
}): <T = Record<string, unknown>>(path: string, method?: string, body?: unknown) => Promise<T>;
|
|
26
|
+
export declare function credentials(root?: string): Promise<Credentials>;
|
|
27
|
+
//# sourceMappingURL=account.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE;AAClF,MAAM,WAAW,WAAW;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;AAClG,eAAO,MAAM,SAAS,cAAmH,CAAC;AAC1I,wBAAgB,MAAM,CAAC,KAAK,SAAgJ,GAAG,MAAM,CAIpL;AACD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,SAAc,QAO3E;AACD,wBAAgB,iBAAiB,CAAC,IAAI,SAAc,GAAG,WAAW,GAAG,SAAS,CAK7E;AACD,qBAAa,QAAS,SAAQ,KAAK;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAClB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAC3E;AACD,wBAAgB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAE,IAEhE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,MAAM,EAAE,eAAc,EAAE,OAAO,OAAO,KAAG,OAAO,CAAC,CAAC,CAAC,CAUrH;AACD,wBAAsB,WAAW,CAAC,IAAI,SAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAU1E"}
|
package/dist/account.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
export const configDir = () => process.env.READM3_CONFIG_DIR || join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), "readm3");
|
|
5
|
+
export function apiUrl(value = process.env.READM3_API_URL || (process.env.READM3_URL ? `${process.env.READM3_URL.replace(/\/+$/, "")}/api/v1` : "https://readm3.com/api/v1")) {
|
|
6
|
+
const url = new URL(value);
|
|
7
|
+
if (url.username || url.password || url.search || url.hash || !(url.protocol === "https:" || (url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname))))
|
|
8
|
+
throw new Error("Use an HTTPS API URL (HTTP is allowed on localhost).");
|
|
9
|
+
return url.href.replace(/\/+$/, "");
|
|
10
|
+
}
|
|
11
|
+
export function writeConfig(name, value, root = configDir()) {
|
|
12
|
+
mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
13
|
+
const path = join(root, name);
|
|
14
|
+
const temp = `${path}.${process.pid}.${crypto.randomUUID()}.tmp`;
|
|
15
|
+
writeFileSync(temp, JSON.stringify(value, null, 2) + "\n", { mode: 0o600 });
|
|
16
|
+
renameSync(temp, path);
|
|
17
|
+
chmodSync(path, 0o600);
|
|
18
|
+
}
|
|
19
|
+
export function storedCredentials(root = configDir()) {
|
|
20
|
+
const path = join(root, "cloud.json");
|
|
21
|
+
if (!existsSync(path))
|
|
22
|
+
return;
|
|
23
|
+
const value = JSON.parse(readFileSync(path, "utf8"));
|
|
24
|
+
return { ...value, api: apiUrl(value.api || (value.url ? `${value.url}/api/v1` : undefined)) };
|
|
25
|
+
}
|
|
26
|
+
export class ApiError extends Error {
|
|
27
|
+
status;
|
|
28
|
+
body;
|
|
29
|
+
constructor(status, message, body) { super(message); this.status = status; this.body = body; }
|
|
30
|
+
}
|
|
31
|
+
export function accountClient(options) {
|
|
32
|
+
const base = apiUrl(options.api);
|
|
33
|
+
return async function request(path, method = "GET", body) {
|
|
34
|
+
const response = await (options.fetchImpl || fetch)(`${base}${path}`, {
|
|
35
|
+
method, redirect: "error", signal: AbortSignal.timeout(30_000),
|
|
36
|
+
headers: { accept: "application/json", ...(options.token ? { authorization: `Bearer ${options.token}` } : {}), ...(body === undefined ? {} : { "content-type": "application/json" }) },
|
|
37
|
+
...(body === undefined ? {} : { body: JSON.stringify(body) }),
|
|
38
|
+
});
|
|
39
|
+
const data = await response.json();
|
|
40
|
+
if (!response.ok)
|
|
41
|
+
throw new ApiError(response.status, String(data.error || `HTTP ${response.status}`), data);
|
|
42
|
+
return data;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export async function credentials(root = configDir()) {
|
|
46
|
+
const saved = storedCredentials(root);
|
|
47
|
+
const token = process.env.READM3_TOKEN || saved?.token;
|
|
48
|
+
if (!token)
|
|
49
|
+
throw new Error("Sign in with `readm3 login` first, or set READM3_TOKEN and READM3_API_URL.");
|
|
50
|
+
// Never send a saved token to a different server because an environment variable changed.
|
|
51
|
+
const api = apiUrl(process.env.READM3_API_URL || (process.env.READM3_URL ? `${process.env.READM3_URL.replace(/\/+$/, "")}/api/v1` : saved?.api));
|
|
52
|
+
if (!process.env.READM3_TOKEN && saved && api !== saved.api)
|
|
53
|
+
throw new Error("The API changed. Sign in to this server first.");
|
|
54
|
+
const { user } = await accountClient({ api, token })("/me");
|
|
55
|
+
if (!user)
|
|
56
|
+
throw new Error("Session expired or revoked. Run `readm3 login`.");
|
|
57
|
+
return { api, token, user };
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ColorMode } from "./print.ts";
|
|
2
2
|
import { type ViewerOptions } from "./viewer.ts";
|
|
3
|
-
export declare const VERSION = "0.
|
|
3
|
+
export declare const VERSION = "0.6.0";
|
|
4
4
|
/** The help text, exported so a test can hold it to the flags it documents. */
|
|
5
5
|
export declare const USAGE: string;
|
|
6
6
|
export interface ParsedArgs extends ViewerOptions {
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAQA,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAO,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAGtD,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,+EAA+E;AAC/E,eAAO,MAAM,KAAK,QA2CH,CAAC;AAEhB,MAAM,WAAW,UAAW,SAAQ,aAAa;IAC/C,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,SAAS,CAAC;IACjB,uDAAuD;IACvD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAID,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA6GpD;AAED,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAQA,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAO,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAGtD,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,+EAA+E;AAC/E,eAAO,MAAM,KAAK,QA2CH,CAAC;AAEhB,MAAM,WAAW,UAAW,SAAQ,aAAa;IAC/C,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,SAAS,CAAC;IACjB,uDAAuD;IACvD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAID,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA6GpD;AAED,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDhF"}
|
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ import { FLAVORS, isFlavor } from "./flavors.js";
|
|
|
9
9
|
import { printDocument, COLOR_MODES } from "./print.js";
|
|
10
10
|
import { run } from "./viewer.js";
|
|
11
11
|
import { isCloudCommand, cloudMain, CLOUD_USAGE } from "./cloud-cli.js";
|
|
12
|
-
export const VERSION = "0.
|
|
12
|
+
export const VERSION = "0.6.0";
|
|
13
13
|
/** The help text, exported so a test can hold it to the flags it documents. */
|
|
14
14
|
export const USAGE = `readm3 — a terminal markdown reader and editor
|
|
15
15
|
|
|
@@ -171,6 +171,9 @@ export function parseArgs(argv) {
|
|
|
171
171
|
return parsed;
|
|
172
172
|
}
|
|
173
173
|
export async function main(argv = process.argv.slice(2)) {
|
|
174
|
+
const { accountCommand } = await import("./sync-cli.js");
|
|
175
|
+
if (await accountCommand(argv))
|
|
176
|
+
return;
|
|
174
177
|
if (isCloudCommand(argv[0])) {
|
|
175
178
|
await cloudMain(argv);
|
|
176
179
|
return;
|
|
@@ -188,7 +191,8 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
188
191
|
throw error;
|
|
189
192
|
}
|
|
190
193
|
if (args.help) {
|
|
191
|
-
|
|
194
|
+
const { ACCOUNT_USAGE } = await import("./sync-cli.js");
|
|
195
|
+
process.stdout.write(USAGE + "\n" + ACCOUNT_USAGE);
|
|
192
196
|
return;
|
|
193
197
|
}
|
|
194
198
|
if (args.version) {
|
|
@@ -196,6 +200,10 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
196
200
|
return;
|
|
197
201
|
}
|
|
198
202
|
if (args.print) {
|
|
203
|
+
const { localSettings } = await import("./settings-sync.js");
|
|
204
|
+
const settings = localSettings();
|
|
205
|
+
args.theme ??= settings.theme;
|
|
206
|
+
args.flavor ??= settings.flavor;
|
|
199
207
|
printDocument({
|
|
200
208
|
path: args.open,
|
|
201
209
|
width: args.sidebar,
|
|
@@ -211,6 +219,10 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
211
219
|
process.exitCode = 1;
|
|
212
220
|
return;
|
|
213
221
|
}
|
|
222
|
+
const { localSettings } = await import("./settings-sync.js");
|
|
223
|
+
const settings = localSettings();
|
|
224
|
+
args.theme ??= settings.theme;
|
|
225
|
+
args.flavor ??= settings.flavor;
|
|
214
226
|
await run(args);
|
|
215
227
|
}
|
|
216
228
|
// Running the source directly (`bun src/cli.ts`, `node src/cli.ts`) should start
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/cloud-cli.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const CLOUD_USAGE = "Shared Markdown\n readm3 login --token-stdin Save a personal API token securely\n readm3 logout Remove the local token\n readm3 share FILE --org ID [--role view|edit]\n readm3 docs list [--org ID] [--search TEXT] [--limit N] [--offset N]\n readm3 docs get ID [--raw]\n readm3 docs create FILE --org ID [--title NAME]\n readm3 docs update ID FILE --base VERSION\n readm3 docs delete ID\n readm3 docs history ID\n readm3 docs restore ID --version VERSION --base CURRENT\n readm3 docs share ID [--role view|edit] [--version VERSION]\n readm3 docs revoke ID --share SHARE_ID\n readm3 docs transfer ID --username USERNAME\n readm3 shared get URL [--raw]\n readm3 shared update URL FILE --base VERSION\n readm3 orgs list | create --name NAME | update ID --name NAME | delete ID\n readm3 teams list --org ID | create --org ID --name NAME\n readm3 members list --org ID\n readm3 cloud OPERATION --args '{\"key\":\"value\"}'\n readm3 mcp Start the stdio MCP server\n\nFILE may be - for stdin. --raw prints Markdown; other results are JSON.\nREADM3_URL selects a self-hosted server; READM3_TOKEN supplies an API token.\nView links cannot write. Edit links can save versions. Owners administer files.\nUse readm3 cloud for the full API, including team membership and permissions.\n";
|
|
1
|
+
export declare const CLOUD_USAGE = "Shared Markdown\n readm3 login --token-stdin Save a personal API token securely\n readm3 logout Remove the local token\n readm3 share FILE --org ID [--role view|edit]\n readm3 docs list [--org ID] [--search TEXT] [--limit N] [--offset N]\n readm3 docs get ID [--raw]\n readm3 docs create FILE --org ID [--title NAME]\n readm3 docs update ID FILE --base VERSION\n readm3 docs delete ID\n readm3 docs history ID\n readm3 docs restore ID --version VERSION --base CURRENT\n readm3 docs share ID [--role view|edit] [--version VERSION]\n readm3 docs revoke ID --share SHARE_ID\n readm3 docs transfer ID --username USERNAME\n readm3 shared get URL [--raw]\n readm3 paste [FILE] [--title NAME] [--expires 1h|1d|7d|30d]\n Private link, no account; prints the URL\n readm3 paste get URL [--raw] | delete URL\n readm3 shared update URL FILE --base VERSION\n readm3 orgs list | create --name NAME | update ID --name NAME | delete ID\n readm3 teams list --org ID | create --org ID --name NAME\n readm3 members list --org ID\n readm3 cloud OPERATION --args '{\"key\":\"value\"}'\n readm3 mcp Start the stdio MCP server\n\nFILE may be - for stdin. --raw prints Markdown; other results are JSON.\nREADM3_URL selects a self-hosted server; READM3_TOKEN supplies an API token.\nView links cannot write. Edit links can save versions. Owners administer files.\nUse readm3 cloud for the full API, including team membership and permissions.\n";
|
|
2
2
|
export declare function isCloudCommand(command: string | undefined): boolean;
|
|
3
3
|
export declare function cloudMain(argv: string[]): Promise<void>;
|
|
4
4
|
//# sourceMappingURL=cloud-cli.d.ts.map
|
package/dist/cloud-cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-cli.d.ts","sourceRoot":"","sources":["../src/cloud-cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloud-cli.d.ts","sourceRoot":"","sources":["../src/cloud-cli.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,WAAW,mhDA6BvB,CAAC;AAcF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,WAEzD;AACD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,iBA4K7C"}
|
package/dist/cloud-cli.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { pasteLocation } from "./cloud-client.js";
|
|
1
2
|
import { readFileSync } from "node:fs";
|
|
2
3
|
import { basename } from "node:path";
|
|
3
4
|
import { cloudAction, cloudConfig, cloudRequest, clearCloudConfig, saveCloudConfig, sharedLocation, } from "./cloud-client.js";
|
|
@@ -16,6 +17,9 @@ export const CLOUD_USAGE = `Shared Markdown
|
|
|
16
17
|
readm3 docs revoke ID --share SHARE_ID
|
|
17
18
|
readm3 docs transfer ID --username USERNAME
|
|
18
19
|
readm3 shared get URL [--raw]
|
|
20
|
+
readm3 paste [FILE] [--title NAME] [--expires 1h|1d|7d|30d]
|
|
21
|
+
Private link, no account; prints the URL
|
|
22
|
+
readm3 paste get URL [--raw] | delete URL
|
|
19
23
|
readm3 shared update URL FILE --base VERSION
|
|
20
24
|
readm3 orgs list | create --name NAME | update ID --name NAME | delete ID
|
|
21
25
|
readm3 teams list --org ID | create --org ID --name NAME
|
|
@@ -34,6 +38,7 @@ const commands = new Set([
|
|
|
34
38
|
"share",
|
|
35
39
|
"docs",
|
|
36
40
|
"shared",
|
|
41
|
+
"paste",
|
|
37
42
|
"orgs",
|
|
38
43
|
"teams",
|
|
39
44
|
"members",
|
|
@@ -86,12 +91,39 @@ export async function cloudMain(argv) {
|
|
|
86
91
|
const token = readFileSync(0, "utf8").trim();
|
|
87
92
|
if (!token)
|
|
88
93
|
throw new Error("No token supplied.");
|
|
89
|
-
const config =
|
|
94
|
+
const config = cloudConfig(token);
|
|
90
95
|
const user = await cloudAction("account_me", {}, config);
|
|
91
96
|
saveCloudConfig(config);
|
|
92
97
|
output({ signedIn: true, user });
|
|
93
98
|
return;
|
|
94
99
|
}
|
|
100
|
+
if (command === "paste") {
|
|
101
|
+
if (positional[0] === "get" || positional[0] === "delete") {
|
|
102
|
+
if (!positional[1])
|
|
103
|
+
throw new Error("A paste URL is required.");
|
|
104
|
+
const { token, config } = pasteLocation(positional[1]);
|
|
105
|
+
if (positional[0] === "delete") {
|
|
106
|
+
await cloudRequest(`pastes/${token}`, "DELETE", undefined, config);
|
|
107
|
+
output({ deleted: true });
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const paste = await cloudRequest(`pastes/${token}`, "GET", undefined, config);
|
|
111
|
+
if (flags.raw)
|
|
112
|
+
process.stdout.write(paste.source);
|
|
113
|
+
else
|
|
114
|
+
output(paste);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (!positional[0] && process.stdin.isTTY)
|
|
118
|
+
throw new Error("Give a Markdown file, or pipe one in.");
|
|
119
|
+
const source = fileSource(positional[0] ?? "-");
|
|
120
|
+
const paste = await cloudRequest("pastes", "POST", { source, title: flags.title, expiresIn: flags.expires }, cloudConfig());
|
|
121
|
+
if (flags.json)
|
|
122
|
+
output(paste);
|
|
123
|
+
else
|
|
124
|
+
process.stdout.write(paste.url + "\n");
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
95
127
|
if (command === "logout") {
|
|
96
128
|
clearCloudConfig();
|
|
97
129
|
output({
|
package/dist/cloud-cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-cli.js","sourceRoot":"","sources":["../src/cloud-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EACL,WAAW,EACX,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,MAAM,CAAC,MAAM,WAAW,GAAG
|
|
1
|
+
{"version":3,"file":"cloud-cli.js","sourceRoot":"","sources":["../src/cloud-cli.ts"],"names":[],"mappings":"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"}
|
package/dist/cloud-client.d.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
export interface CloudConfig {
|
|
2
2
|
url: string;
|
|
3
|
+
api?: string;
|
|
3
4
|
token?: string;
|
|
4
5
|
}
|
|
5
|
-
export declare function cloudConfig(): CloudConfig;
|
|
6
|
+
export declare function cloudConfig(tokenOverride?: string): CloudConfig;
|
|
6
7
|
export declare function saveCloudConfig(config: CloudConfig): void;
|
|
7
8
|
export declare function clearCloudConfig(): void;
|
|
8
9
|
export declare function cloudRequest<T = unknown>(path: string, method?: string, body?: unknown, config?: CloudConfig): Promise<T>;
|
|
9
10
|
export declare function cloudAction<T = unknown>(operation: string, args?: Record<string, unknown>, config?: CloudConfig): Promise<T>;
|
|
11
|
+
export declare function pasteLocation(value: string): {
|
|
12
|
+
token: string;
|
|
13
|
+
config: CloudConfig;
|
|
14
|
+
};
|
|
10
15
|
export declare function sharedLocation(value: string): {
|
|
11
16
|
token: string;
|
|
12
17
|
config: CloudConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-client.d.ts","sourceRoot":"","sources":["../src/cloud-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloud-client.d.ts","sourceRoot":"","sources":["../src/cloud-client.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,wBAAgB,WAAW,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,WAAW,CAiB/D;AACD,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,QAElD;AACD,wBAAgB,gBAAgB,SAG/B;AACD,wBAAsB,YAAY,CAAC,CAAC,GAAG,OAAO,EAC5C,IAAI,EAAE,MAAM,EACZ,MAAM,SAAQ,EACd,IAAI,CAAC,EAAE,OAAO,EACd,MAAM,cAAgB,GACrB,OAAO,CAAC,CAAC,CAAC,CAcZ;AACD,wBAAsB,WAAW,CAAC,CAAC,GAAG,OAAO,EAC3C,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAClC,MAAM,cAAgB,GACrB,OAAO,CAAC,CAAC,CAAC,CAMZ;AACD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;CACrB,CAMA;AACD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;CACrB,CAMA"}
|
package/dist/cloud-client.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { readFileSync,
|
|
2
|
-
import { homedir } from "node:os";
|
|
1
|
+
import { readFileSync, existsSync, unlinkSync, } from "node:fs";
|
|
3
2
|
import { join } from "node:path";
|
|
4
|
-
|
|
5
|
-
export function cloudConfig() {
|
|
3
|
+
import { apiUrl, configDir, writeConfig } from "./account.js";
|
|
4
|
+
export function cloudConfig(tokenOverride) {
|
|
6
5
|
let saved = {};
|
|
7
6
|
try {
|
|
8
7
|
saved = JSON.parse(readFileSync(join(configDir(), "cloud.json"), "utf8"));
|
|
@@ -13,18 +12,14 @@ export function cloudConfig() {
|
|
|
13
12
|
const url = (process.env.READM3_URL ||
|
|
14
13
|
saved.url ||
|
|
15
14
|
"https://readm3.com").replace(/\/$/, "");
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return { url: parsed.origin, token: process.env.READM3_TOKEN || saved.token };
|
|
15
|
+
const api = apiUrl(process.env.READM3_API_URL || (process.env.READM3_URL ? `${url}/api/v1` : saved.api || `${url}/api/v1`));
|
|
16
|
+
const parsed = new URL(api);
|
|
17
|
+
if (saved.token && !tokenOverride && !process.env.READM3_TOKEN && (saved.api || saved.url) && api !== apiUrl(saved.api || `${saved.url}/api/v1`))
|
|
18
|
+
throw new Error("The server changed. Sign in to this server first.");
|
|
19
|
+
return { url: parsed.origin, api, token: tokenOverride || process.env.READM3_TOKEN || saved.token };
|
|
22
20
|
}
|
|
23
21
|
export function saveCloudConfig(config) {
|
|
24
|
-
|
|
25
|
-
const path = join(configDir(), "cloud.json");
|
|
26
|
-
writeFileSync(path, JSON.stringify(config) + "\n", { mode: 0o600 });
|
|
27
|
-
chmodSync(path, 0o600);
|
|
22
|
+
writeConfig("cloud.json", config);
|
|
28
23
|
}
|
|
29
24
|
export function clearCloudConfig() {
|
|
30
25
|
const path = join(configDir(), "cloud.json");
|
|
@@ -32,7 +27,7 @@ export function clearCloudConfig() {
|
|
|
32
27
|
unlinkSync(path);
|
|
33
28
|
}
|
|
34
29
|
export async function cloudRequest(path, method = "GET", body, config = cloudConfig()) {
|
|
35
|
-
const response = await fetch(`${config.url}/api/v1/${path}`, {
|
|
30
|
+
const response = await fetch(`${config.api || `${config.url}/api/v1`}/${path}`, {
|
|
36
31
|
method,
|
|
37
32
|
headers: {
|
|
38
33
|
...(config.token ? { authorization: `Bearer ${config.token}` } : {}),
|
|
@@ -52,6 +47,13 @@ export async function cloudAction(operation, args = {}, config = cloudConfig())
|
|
|
52
47
|
throw new Error("Sign in at readm3.com/admin, create an API token, and run readm3 login --token-stdin (or set READM3_TOKEN).");
|
|
53
48
|
return cloudRequest("actions", "POST", { operation, args }, config);
|
|
54
49
|
}
|
|
50
|
+
export function pasteLocation(value) {
|
|
51
|
+
const url = new URL(value);
|
|
52
|
+
const match = url.pathname.match(/^\/p\/([\w-]{43})$/);
|
|
53
|
+
if (!match || !["https:", "http:"].includes(url.protocol))
|
|
54
|
+
throw new Error("Use a readm3 paste URL (…/p/<token>).");
|
|
55
|
+
return { token: match[1], config: { url: url.origin } };
|
|
56
|
+
}
|
|
55
57
|
export function sharedLocation(value) {
|
|
56
58
|
const url = new URL(value);
|
|
57
59
|
const match = url.pathname.match(/^\/s\/([\w-]{43})$/);
|
package/dist/cloud-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-client.js","sourceRoot":"","sources":["../src/cloud-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"cloud-client.js","sourceRoot":"","sources":["../src/cloud-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,UAAU,EACV,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAM9D,MAAM,UAAU,WAAW,CAAC,aAAsB;IAChD,IAAI,KAAK,GAAyB,EAAE,CAAC;IACrC,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5E,CAAC;IAAC,MAAM,CAAC;QACP,wCAAwC;IAC1C,CAAC;IACD,MAAM,GAAG,GAAG,CACV,OAAO,CAAC,GAAG,CAAC,UAAU;QACtB,KAAK,CAAC,GAAG;QACT,oBAAoB,CACrB,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACrB,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC;IAC5H,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,GAAG,SAAS,CAAC;QAC9I,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;AACtG,CAAC;AACD,MAAM,UAAU,eAAe,CAAC,MAAmB;IACjD,WAAW,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AACD,MAAM,UAAU,gBAAgB;IAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,YAAY,CAAC,CAAC;IAC7C,IAAI,UAAU,CAAC,IAAI,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,MAAM,GAAG,KAAK,EACd,IAAc,EACd,MAAM,GAAG,WAAW,EAAE;IAEtB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,GAAG,SAAS,IAAI,IAAI,EAAE,EAAE;QAC9E,MAAM;QACN,OAAO,EAAE;YACP,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;SACtE;QACD,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAC3D,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;QAClC,QAAQ,EAAE,OAAO;KAClB,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAC;IAC5D,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5E,OAAO,KAAU,CAAC;AACpB,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,SAAiB,EACjB,OAAgC,EAAE,EAClC,MAAM,GAAG,WAAW,EAAE;IAEtB,IAAI,CAAC,MAAM,CAAC,KAAK;QACf,MAAM,IAAI,KAAK,CACb,6GAA6G,CAC9G,CAAC;IACJ,OAAO,YAAY,CAAI,SAAS,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;AACzE,CAAC;AACD,MAAM,UAAU,aAAa,CAAC,KAAa;IAIzC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACvD,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;AAC3D,CAAC;AACD,MAAM,UAAU,cAAc,CAAC,KAAa;IAI1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACvD,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;AAC1D,CAAC"}
|
package/dist/mcp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAsQA,wBAAsB,MAAM,kBAgE3B"}
|
package/dist/mcp.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
3
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
4
|
-
import { cloudAction, cloudRequest, sharedLocation } from "./cloud-client.js";
|
|
4
|
+
import { cloudAction, cloudRequest, pasteLocation, sharedLocation } from "./cloud-client.js";
|
|
5
5
|
const string = { type: "string" };
|
|
6
6
|
const role = { type: "string", enum: ["view", "edit"] };
|
|
7
7
|
const definitions = [
|
|
8
|
+
["paste_create", "Create an anonymous paste: a Markdown document behind a secret link, no account needed. Expires after 7 days by default (1h, 1d, 7d or 30d), 256 KB at most. Returns the URL; keep it, the server cannot show it again.", { source: string, title: string, expiresIn: { type: "string", enum: ["1h", "1d", "7d", "30d"] } }, ["source"]],
|
|
9
|
+
["paste_get", "Read an anonymous paste by its URL.", { url: string }, ["url"]],
|
|
10
|
+
["paste_delete", "Delete an anonymous paste by its URL. The link stops working for everyone.", { url: string }, ["url"]],
|
|
11
|
+
["settings_get", "Read the verified account's latest settings and Markdown workspace snapshot, including its revision.", {}, []],
|
|
12
|
+
["settings_save", "Save settings.json and workspace.json. Use the revision from settings_get, or 0 for a first save. Stale saves are rejected.", {
|
|
13
|
+
snapshot: { type: "object", properties: { version: { type: "integer", const: 1 }, files: { type: "object", description: "Only settings.json and workspace.json, each containing a JSON string in its content property." } }, required: ["version", "files"] },
|
|
14
|
+
ifRevision: { type: "integer", minimum: 0 },
|
|
15
|
+
}, ["snapshot", "ifRevision"]],
|
|
16
|
+
["settings_revisions", "List the verified account's last ten sync revisions.", {}, []],
|
|
8
17
|
["account_me", "Show the authenticated readm3 user.", {}, []],
|
|
9
18
|
["organizations_list", "List organizations you belong to.", {}, []],
|
|
10
19
|
[
|
|
@@ -249,7 +258,7 @@ const definitions = [
|
|
|
249
258
|
],
|
|
250
259
|
];
|
|
251
260
|
export async function runMcp() {
|
|
252
|
-
const server = new Server({ name: "readm3", version: "0.
|
|
261
|
+
const server = new Server({ name: "readm3", version: "0.6.0" }, { capabilities: { tools: {} } });
|
|
253
262
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
254
263
|
tools: definitions.map(([name, description, properties, required]) => ({
|
|
255
264
|
name,
|
|
@@ -261,7 +270,7 @@ export async function runMcp() {
|
|
|
261
270
|
additionalProperties: false,
|
|
262
271
|
},
|
|
263
272
|
annotations: {
|
|
264
|
-
readOnlyHint: /_(list|get|me|users)$/.test(name),
|
|
273
|
+
readOnlyHint: /_(list|get|me|users|revisions)$/.test(name),
|
|
265
274
|
destructiveHint: /_(delete|remove|revoke|transfer)$/.test(name),
|
|
266
275
|
openWorldHint: true,
|
|
267
276
|
},
|
|
@@ -274,7 +283,20 @@ export async function runMcp() {
|
|
|
274
283
|
if (!definitions.some(([operation]) => operation === name))
|
|
275
284
|
throw new Error("Unknown tool.");
|
|
276
285
|
let result;
|
|
277
|
-
if (name.startsWith("
|
|
286
|
+
if (name.startsWith("settings_")) {
|
|
287
|
+
if (name === "settings_save" && (!Number.isSafeInteger(args.ifRevision) || Number(args.ifRevision) < 0 || !args.snapshot))
|
|
288
|
+
throw new Error("snapshot and a nonnegative ifRevision are required.");
|
|
289
|
+
result = await cloudRequest(name === "settings_revisions" ? "settings/revisions" : "settings", name === "settings_save" ? "PUT" : "GET", name === "settings_save" ? { snapshot: args.snapshot, ifRevision: args.ifRevision } : undefined);
|
|
290
|
+
}
|
|
291
|
+
else if (name.startsWith("paste_")) {
|
|
292
|
+
if (name === "paste_create")
|
|
293
|
+
result = await cloudRequest("pastes", "POST", { source: args.source, title: args.title, expiresIn: args.expiresIn });
|
|
294
|
+
else {
|
|
295
|
+
const { token, config } = pasteLocation(String(args.url));
|
|
296
|
+
result = await cloudRequest(`pastes/${token}`, name === "paste_delete" ? "DELETE" : "GET", undefined, config);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
else if (name.startsWith("shared_")) {
|
|
278
300
|
const { token, config } = sharedLocation(String(args.url));
|
|
279
301
|
result = await cloudRequest(`shared/${token}`, name === "shared_update" ? "PATCH" : "GET", name === "shared_update"
|
|
280
302
|
? { source: args.source, baseVersion: args.baseVersion }
|
package/dist/mcp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type SyncContext } from "@profullstack/synconfig";
|
|
2
|
+
export declare function syncContext(rootDir?: string): Promise<SyncContext>;
|
|
3
|
+
export declare function saveSettings(ctx: SyncContext, options?: {
|
|
4
|
+
force?: boolean;
|
|
5
|
+
}): Promise<import("@profullstack/synconfig").SaveResult>;
|
|
6
|
+
export declare function loadSettings(ctx: SyncContext, options?: {
|
|
7
|
+
force?: boolean;
|
|
8
|
+
dryRun?: boolean;
|
|
9
|
+
}): Promise<import("@profullstack/synconfig").LoadResult>;
|
|
10
|
+
export declare function syncStatus(ctx: SyncContext): Promise<import("@profullstack/synconfig").StatusResult>;
|
|
11
|
+
export declare function localSettings(root?: string): {
|
|
12
|
+
theme?: string;
|
|
13
|
+
flavor?: import("./flavors.ts").Flavor;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=settings-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-sync.d.ts","sourceRoot":"","sources":["../src/settings-sync.ts"],"names":[],"mappings":"AAIA,OAAO,EAA8E,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAYvI,wBAAsB,WAAW,CAAC,OAAO,SAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAgB7E;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,yDASrF;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,yDAavG;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,WAAW,2DAIhD;AAED,wBAAgB,aAAa,CAAC,IAAI,SAAc;YAKN,MAAM;aAAW,OAAO,cAAc,EAAE,MAAM;EACvF"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, lstatSync, readFileSync } from "node:fs";
|
|
3
|
+
import { hostname } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { collectSnapshot, createClient, digestFiles, load, loadMarker, save, status } from "@profullstack/synconfig";
|
|
6
|
+
import { configDir, credentials } from "./account.js";
|
|
7
|
+
import { SYNC_FILES, SYNC_POLICY, validateSyncFiles } from "./sync-schema.js";
|
|
8
|
+
function checkLocalFiles(ctx) {
|
|
9
|
+
for (const name of [...SYNC_FILES, ctx.markerName || "sync.json"]) {
|
|
10
|
+
const path = join(ctx.rootDir, name);
|
|
11
|
+
try {
|
|
12
|
+
if (!lstatSync(path).isFile())
|
|
13
|
+
throw new Error(`Sync needs a regular file: ${name}`);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (error.code !== "ENOENT")
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export async function syncContext(rootDir = configDir()) {
|
|
22
|
+
const account = await credentials(rootDir);
|
|
23
|
+
const identity = createHash("sha256").update(`${account.api}\0${account.user.id}`).digest("hex");
|
|
24
|
+
const client = createClient({ baseUrl: account.api, path: "/settings", token: account.token, fetchImpl: ((input, init) => fetch(input, { ...init, redirect: "error" })) });
|
|
25
|
+
return { rootDir, policy: SYNC_POLICY, api: `${account.api}#${account.user.id}`, markerName: `sync-${identity}.json`, host: hostname(), app: "readm3 0.6.0", client: {
|
|
26
|
+
...client,
|
|
27
|
+
async get() {
|
|
28
|
+
const latest = await client.get();
|
|
29
|
+
if (latest) {
|
|
30
|
+
validateSyncFiles(latest.snapshot.files);
|
|
31
|
+
if (digestFiles(latest.snapshot.files) !== latest.digest)
|
|
32
|
+
throw new Error("Snapshot digest does not match its contents.");
|
|
33
|
+
}
|
|
34
|
+
return latest;
|
|
35
|
+
},
|
|
36
|
+
put: (snapshot, revision) => client.put(snapshot, revision),
|
|
37
|
+
} };
|
|
38
|
+
}
|
|
39
|
+
export async function saveSettings(ctx, options = {}) {
|
|
40
|
+
checkLocalFiles(ctx);
|
|
41
|
+
const { snapshot, skipped } = collectSnapshot(ctx.rootDir, ctx.policy, { host: ctx.host, app: ctx.app });
|
|
42
|
+
if (skipped.length)
|
|
43
|
+
throw new Error(`Cannot save an incomplete snapshot: ${skipped.map((entry) => entry.path).join(", ")}`);
|
|
44
|
+
validateSyncFiles(snapshot.files);
|
|
45
|
+
// synconfig uses null for a missing marker. readm3 requires an explicit force
|
|
46
|
+
// to replace an account copy the current device has never loaded.
|
|
47
|
+
const guarded = { ...ctx, client: { ...ctx.client, put: (body, revision) => ctx.client.put(body, options.force ? null : revision ?? 0) } };
|
|
48
|
+
return save(guarded, options);
|
|
49
|
+
}
|
|
50
|
+
export async function loadSettings(ctx, options = {}) {
|
|
51
|
+
checkLocalFiles(ctx);
|
|
52
|
+
const latest = await ctx.client.get();
|
|
53
|
+
ctx = { ...ctx, client: { ...ctx.client, get: async () => latest } };
|
|
54
|
+
const plan = await load(ctx, { dryRun: true });
|
|
55
|
+
if (options.dryRun)
|
|
56
|
+
return plan;
|
|
57
|
+
// A first load also needs protection: the package has no baseline to detect
|
|
58
|
+
// local edits yet. Force still creates the package's numbered backups.
|
|
59
|
+
if (!loadMarker(ctx.rootDir, ctx.markerName) && !options.force) {
|
|
60
|
+
const existing = plan.plan.filter((item) => item.status === "changed");
|
|
61
|
+
if (existing.length)
|
|
62
|
+
return { ...plan, status: "local_changes", drifted: existing.map((item) => item.path) };
|
|
63
|
+
}
|
|
64
|
+
return load(ctx, options);
|
|
65
|
+
}
|
|
66
|
+
export async function syncStatus(ctx) {
|
|
67
|
+
// Do not let the package's status helper hide an authentication/network error.
|
|
68
|
+
const latest = await ctx.client.get();
|
|
69
|
+
return status({ ...ctx, client: { ...ctx.client, get: async () => latest } });
|
|
70
|
+
}
|
|
71
|
+
export function localSettings(root = configDir()) {
|
|
72
|
+
const path = join(root, "settings.json");
|
|
73
|
+
if (!existsSync(path))
|
|
74
|
+
return {};
|
|
75
|
+
const content = readFileSync(path, "utf8");
|
|
76
|
+
validateSyncFiles({ "settings.json": { content } });
|
|
77
|
+
return JSON.parse(content);
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=settings-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-sync.js","sourceRoot":"","sources":["../src/settings-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const ACCOUNT_USAGE = "Account and sync commands\n readm3 whoami Show the verified account\n readm3 settings [--theme NAME] [--flavor NAME]\n readm3 save [file-or-directory] [--force]\n readm3 load [output-directory] [--dry-run] [--force]\n readm3 sync [status | save | load | revisions]\n\nSave includes settings.json and the last imported workspace.json only.\nGiving save a path imports its Markdown files. Load optionally writes them to\nan output directory, backing up replaced files. --force explicitly resolves a\nconflict. Credentials are stored separately and never synced.\nREADM3_API_URL, READM3_TOKEN and READM3_CONFIG_DIR override local defaults.\n";
|
|
2
|
+
export declare function accountCommand(argv: string[]): Promise<boolean>;
|
|
3
|
+
//# sourceMappingURL=sync-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-cli.d.ts","sourceRoot":"","sources":["../src/sync-cli.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,aAAa,gqBAYzB,CAAC;AAyCF,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CA+DrE"}
|
package/dist/sync-cli.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { existsSync, lstatSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
3
|
+
import { applyFiles, planApply } from "@profullstack/synconfig";
|
|
4
|
+
import { configDir, credentials, writeConfig } from "./account.js";
|
|
5
|
+
import { loadSettings, localSettings, saveSettings, syncContext, syncStatus } from "./settings-sync.js";
|
|
6
|
+
import { validateWorkspace } from "./sync-schema.js";
|
|
7
|
+
import { files, scan } from "./tree.js";
|
|
8
|
+
import { isFlavor } from "./flavors.js";
|
|
9
|
+
import { themeList } from "@profullstack/hqtui";
|
|
10
|
+
export const ACCOUNT_USAGE = `Account and sync commands
|
|
11
|
+
readm3 whoami Show the verified account
|
|
12
|
+
readm3 settings [--theme NAME] [--flavor NAME]
|
|
13
|
+
readm3 save [file-or-directory] [--force]
|
|
14
|
+
readm3 load [output-directory] [--dry-run] [--force]
|
|
15
|
+
readm3 sync [status | save | load | revisions]
|
|
16
|
+
|
|
17
|
+
Save includes settings.json and the last imported workspace.json only.
|
|
18
|
+
Giving save a path imports its Markdown files. Load optionally writes them to
|
|
19
|
+
an output directory, backing up replaced files. --force explicitly resolves a
|
|
20
|
+
conflict. Credentials are stored separately and never synced.
|
|
21
|
+
READM3_API_URL, READM3_TOKEN and READM3_CONFIG_DIR override local defaults.
|
|
22
|
+
`;
|
|
23
|
+
function importWorkspace(target) {
|
|
24
|
+
const path = resolve(target);
|
|
25
|
+
const directory = statSync(path).isDirectory();
|
|
26
|
+
const root = directory ? path : dirname(path);
|
|
27
|
+
const paths = directory ? files(scan(root)).map((entry) => entry.path) : [path];
|
|
28
|
+
let bytes = 0;
|
|
29
|
+
const documents = paths.map((file) => {
|
|
30
|
+
const size = statSync(file).size;
|
|
31
|
+
bytes += size;
|
|
32
|
+
if (size > 4 * 1024 * 1024 || bytes > 20 * 1024 * 1024)
|
|
33
|
+
throw new Error("Workspace limit: 4 MB per file and 20 MB total.");
|
|
34
|
+
return { path: relative(root, file).split(sep).join("/"), source: readFileSync(file, "utf8") };
|
|
35
|
+
});
|
|
36
|
+
return validateWorkspace({ name: basename(root), documents, active: documents[0]?.path });
|
|
37
|
+
}
|
|
38
|
+
function exportWorkspace(ws, output, force, dryRun) {
|
|
39
|
+
const root = resolve(output);
|
|
40
|
+
const data = Object.fromEntries(ws.documents.map((doc) => [doc.path, { content: doc.source }]));
|
|
41
|
+
// The library writes relative paths; reject symlink parents before handing it
|
|
42
|
+
// any workspace paths, so a remote document cannot escape the chosen folder.
|
|
43
|
+
for (const path of Object.keys(data)) {
|
|
44
|
+
let current = join(root, path);
|
|
45
|
+
while (true) {
|
|
46
|
+
try {
|
|
47
|
+
if (lstatSync(current).isSymbolicLink())
|
|
48
|
+
throw new Error(`Refusing a symlink in output path: ${current}`);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (error.code !== "ENOENT")
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
if (current === root)
|
|
55
|
+
break;
|
|
56
|
+
const parent = dirname(current);
|
|
57
|
+
if (parent === current)
|
|
58
|
+
break;
|
|
59
|
+
current = parent;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const plan = planApply(root, data);
|
|
63
|
+
if (dryRun)
|
|
64
|
+
return { plan };
|
|
65
|
+
if (!force && plan.some((entry) => entry.status === "changed"))
|
|
66
|
+
throw new Error("Output files differ. Use a new directory, or --force to replace them with numbered backups.");
|
|
67
|
+
const backups = [];
|
|
68
|
+
const written = applyFiles(root, data, plan, { onBackup: (path, backup) => backups.push({ path, backup }) });
|
|
69
|
+
return { written, backups };
|
|
70
|
+
}
|
|
71
|
+
export async function accountCommand(argv) {
|
|
72
|
+
const commands = ["whoami", "settings", "save", "load", "sync"];
|
|
73
|
+
if (!commands.includes(argv[0] || ""))
|
|
74
|
+
return false;
|
|
75
|
+
let [command, ...args] = argv;
|
|
76
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
77
|
+
process.stdout.write(ACCOUNT_USAGE);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
if (command === "sync")
|
|
81
|
+
command = args[0] && !args[0].startsWith("-") ? args.shift() : "status";
|
|
82
|
+
const options = {};
|
|
83
|
+
const positional = [];
|
|
84
|
+
for (let i = 0; i < args.length; i++) {
|
|
85
|
+
if (["--force", "--dry-run"].includes(args[i]))
|
|
86
|
+
options[args[i].slice(2)] = true;
|
|
87
|
+
else if (["--theme", "--flavor"].includes(args[i])) {
|
|
88
|
+
if (!args[i + 1] || args[i + 1].startsWith("--"))
|
|
89
|
+
throw new Error(`${args[i]} needs a value.`);
|
|
90
|
+
options[args[i].slice(2)] = args[++i];
|
|
91
|
+
}
|
|
92
|
+
else if (args[i].startsWith("-"))
|
|
93
|
+
throw new Error(`Unknown option: ${args[i]}`);
|
|
94
|
+
else
|
|
95
|
+
positional.push(args[i]);
|
|
96
|
+
}
|
|
97
|
+
if (positional.length > 1 || (positional.length && !["save", "load"].includes(command)))
|
|
98
|
+
throw new Error("Unexpected positional argument. Run `readm3 sync --help`.");
|
|
99
|
+
const allowed = { settings: ["theme", "flavor"], save: ["force"], load: ["force", "dry-run"] };
|
|
100
|
+
for (const option of Object.keys(options))
|
|
101
|
+
if (!(allowed[command] || []).includes(option))
|
|
102
|
+
throw new Error(`--${option} is not supported by ${command}.`);
|
|
103
|
+
let result;
|
|
104
|
+
switch (command) {
|
|
105
|
+
case "whoami": {
|
|
106
|
+
const account = await credentials();
|
|
107
|
+
result = { user: account.user, api: account.api };
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case "settings": {
|
|
111
|
+
const settings = localSettings();
|
|
112
|
+
if (typeof options.theme === "string") {
|
|
113
|
+
if (!themeList.some((theme) => theme.name === options.theme))
|
|
114
|
+
throw new Error("Unknown theme.");
|
|
115
|
+
settings.theme = options.theme;
|
|
116
|
+
}
|
|
117
|
+
if (typeof options.flavor === "string") {
|
|
118
|
+
if (!isFlavor(options.flavor))
|
|
119
|
+
throw new Error("Unknown flavor.");
|
|
120
|
+
settings.flavor = options.flavor;
|
|
121
|
+
}
|
|
122
|
+
if (options.theme || options.flavor)
|
|
123
|
+
writeConfig("settings.json", settings);
|
|
124
|
+
result = settings;
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
case "save": {
|
|
128
|
+
const ctx = await syncContext();
|
|
129
|
+
if (positional[0])
|
|
130
|
+
writeConfig("workspace.json", importWorkspace(positional[0]));
|
|
131
|
+
if (!existsSync(join(configDir(), "settings.json")))
|
|
132
|
+
writeConfig("settings.json", {});
|
|
133
|
+
result = await saveSettings(ctx, { force: Boolean(options.force) });
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case "load": {
|
|
137
|
+
const ctx = await syncContext();
|
|
138
|
+
const latest = await ctx.client.get();
|
|
139
|
+
const fixed = { ...ctx, client: { ...ctx.client, get: async () => latest } };
|
|
140
|
+
const ws = latest?.snapshot.files["workspace.json"];
|
|
141
|
+
// Check output paths before updating the local marker or config files.
|
|
142
|
+
if (positional[0] && ws) {
|
|
143
|
+
const plan = exportWorkspace(validateWorkspace(JSON.parse(ws.content)), positional[0], Boolean(options.force), true);
|
|
144
|
+
if (!options.force && !options["dry-run"] && plan.plan.some((entry) => entry.status === "changed"))
|
|
145
|
+
throw new Error("Output files differ. Use a new directory or --force (with backups).");
|
|
146
|
+
}
|
|
147
|
+
const loaded = await loadSettings(fixed, { force: Boolean(options.force), dryRun: Boolean(options["dry-run"]) });
|
|
148
|
+
result = loaded;
|
|
149
|
+
if (positional[0] && ws && ["loaded", "same", "planned"].includes(loaded.status))
|
|
150
|
+
result = { ...loaded, output: exportWorkspace(validateWorkspace(JSON.parse(ws.content)), positional[0], Boolean(options.force), Boolean(options["dry-run"])) };
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
case "status":
|
|
154
|
+
result = await syncStatus(await syncContext());
|
|
155
|
+
break;
|
|
156
|
+
case "revisions":
|
|
157
|
+
result = await (await syncContext()).client.revisions();
|
|
158
|
+
break;
|
|
159
|
+
default: throw new Error(`Unknown sync command: ${command}`);
|
|
160
|
+
}
|
|
161
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
162
|
+
if (result && typeof result === "object" && "status" in result && ["conflict", "local_changes", "newer"].includes(String(result.status)))
|
|
163
|
+
process.exitCode = 1;
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=sync-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-cli.js","sourceRoot":"","sources":["../src/sync-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Browser-safe account data contract. Only these two files may be synced. */
|
|
2
|
+
import { type Flavor } from "./flavors.ts";
|
|
3
|
+
export interface WorkspaceDocument {
|
|
4
|
+
path: string;
|
|
5
|
+
source: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SyncedWorkspace {
|
|
8
|
+
documents: WorkspaceDocument[];
|
|
9
|
+
active: string;
|
|
10
|
+
name: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ReaderSettings {
|
|
13
|
+
theme?: string;
|
|
14
|
+
flavor?: Flavor;
|
|
15
|
+
}
|
|
16
|
+
export declare const SYNC_LIMITS: {
|
|
17
|
+
maxFileBytes: number;
|
|
18
|
+
maxTotalBytes: number;
|
|
19
|
+
maxFiles: number;
|
|
20
|
+
};
|
|
21
|
+
export declare const SYNC_FILES: readonly ["settings.json", "workspace.json"];
|
|
22
|
+
export declare const SYNC_POLICY: {
|
|
23
|
+
maxFileBytes: number;
|
|
24
|
+
maxTotalBytes: number;
|
|
25
|
+
maxFiles: number;
|
|
26
|
+
files: {
|
|
27
|
+
path: "settings.json" | "workspace.json";
|
|
28
|
+
json: boolean;
|
|
29
|
+
}[];
|
|
30
|
+
never: string[];
|
|
31
|
+
};
|
|
32
|
+
export declare function validateSettings(value: unknown): ReaderSettings;
|
|
33
|
+
export declare function validateWorkspace(value: unknown): SyncedWorkspace;
|
|
34
|
+
export declare function validateSyncFiles(files: Record<string, {
|
|
35
|
+
content: string;
|
|
36
|
+
}>): void;
|
|
37
|
+
//# sourceMappingURL=sync-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-schema.d.ts","sourceRoot":"","sources":["../src/sync-schema.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,OAAO,EAAY,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACnE,MAAM,WAAW,eAAe;IAAG,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AACjG,MAAM,WAAW,cAAc;IAAG,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE;AACnE,eAAO,MAAM,WAAW;;;;CAAmF,CAAC;AAC5G,eAAO,MAAM,UAAU,8CAA+C,CAAC;AACvE,eAAO,MAAM,WAAW;;;;;;;;;CAIvB,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAO/D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAmBjE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAOlF"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/** Browser-safe account data contract. Only these two files may be synced. */
|
|
2
|
+
import { isFlavor } from "./flavors.js";
|
|
3
|
+
export const SYNC_LIMITS = { maxFileBytes: 32 * 1024 * 1024, maxTotalBytes: 33 * 1024 * 1024, maxFiles: 2 };
|
|
4
|
+
export const SYNC_FILES = ["settings.json", "workspace.json"];
|
|
5
|
+
export const SYNC_POLICY = {
|
|
6
|
+
files: SYNC_FILES.map((path) => ({ path, json: true })),
|
|
7
|
+
never: ["account.json", "cloud.json", "sync.json"],
|
|
8
|
+
...SYNC_LIMITS,
|
|
9
|
+
};
|
|
10
|
+
export function validateSettings(value) {
|
|
11
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
12
|
+
throw new Error("Settings must be an object.");
|
|
13
|
+
const settings = value;
|
|
14
|
+
if (Object.keys(settings).some((key) => !["theme", "flavor"].includes(key)))
|
|
15
|
+
throw new Error("Only theme and flavor can be synced as settings.");
|
|
16
|
+
if (settings.theme !== undefined && (typeof settings.theme !== "string" || !/^[a-z0-9-]{1,40}$/.test(settings.theme)))
|
|
17
|
+
throw new Error("Invalid theme.");
|
|
18
|
+
if (settings.flavor !== undefined && !isFlavor(settings.flavor))
|
|
19
|
+
throw new Error("Invalid Markdown flavor.");
|
|
20
|
+
return settings;
|
|
21
|
+
}
|
|
22
|
+
export function validateWorkspace(value) {
|
|
23
|
+
if (!value || typeof value !== "object")
|
|
24
|
+
throw new Error("Workspace must be an object.");
|
|
25
|
+
const ws = value;
|
|
26
|
+
if (Object.keys(ws).some((key) => !["name", "active", "documents"].includes(key)))
|
|
27
|
+
throw new Error("Workspace can only contain name, active and documents.");
|
|
28
|
+
if (typeof ws.name !== "string" || ws.name.length > 200 || !Array.isArray(ws.documents) || !ws.documents.length || ws.documents.length > 1000)
|
|
29
|
+
throw new Error("Workspace needs a name and 1–1,000 Markdown files.");
|
|
30
|
+
const paths = new Set();
|
|
31
|
+
let total = 0;
|
|
32
|
+
const encoder = new TextEncoder();
|
|
33
|
+
for (const doc of ws.documents) {
|
|
34
|
+
if (!doc || typeof doc.path !== "string" || doc.path.length > 1024 || /[\\\x00-\x1f:]/.test(doc.path) || doc.path.split("/").some((p) => !p || p.startsWith(".")) || !/\.(md|markdown|mdown|mkd|mdx)$/i.test(doc.path) || paths.has(doc.path))
|
|
35
|
+
throw new Error("Workspace contains an invalid or duplicate Markdown path.");
|
|
36
|
+
if (typeof doc.source !== "string")
|
|
37
|
+
throw new Error("Markdown source must be text.");
|
|
38
|
+
if (Object.keys(doc).some((key) => !["path", "source"].includes(key)))
|
|
39
|
+
throw new Error("Documents can only contain path and source.");
|
|
40
|
+
const bytes = encoder.encode(doc.source).length;
|
|
41
|
+
total += bytes;
|
|
42
|
+
if (bytes > 4 * 1024 * 1024 || total > 20 * 1024 * 1024)
|
|
43
|
+
throw new Error("Workspace limit: 4 MB per file and 20 MB total.");
|
|
44
|
+
paths.add(doc.path);
|
|
45
|
+
}
|
|
46
|
+
if (!paths.has(ws.active))
|
|
47
|
+
throw new Error("The active document is missing.");
|
|
48
|
+
return ws;
|
|
49
|
+
}
|
|
50
|
+
export function validateSyncFiles(files) {
|
|
51
|
+
for (const [path, file] of Object.entries(files)) {
|
|
52
|
+
if (!SYNC_FILES.includes(path))
|
|
53
|
+
throw new Error(`File is not syncable: ${path}`);
|
|
54
|
+
if (!file || typeof file.content !== "string")
|
|
55
|
+
throw new Error(`${path}: content must be text.`);
|
|
56
|
+
const value = JSON.parse(file.content);
|
|
57
|
+
if (path === "settings.json")
|
|
58
|
+
validateSettings(value);
|
|
59
|
+
else
|
|
60
|
+
validateWorkspace(value);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=sync-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-schema.js","sourceRoot":"","sources":["../src/sync-schema.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@profullstack/readm3",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Markdown editing and sharing for people and teams. Web/PWA, CLI, API and MCP with version history, view/edit links, and a terminal reader.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
46
46
|
"@profullstack/hqtui": "^0.5.0",
|
|
47
|
+
"@profullstack/synconfig": "^0.1.3",
|
|
47
48
|
"marked": "^18.0.11"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|