yamlite 0.39.0 → 0.41.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 +21 -15
- package/dist/browser/chokidar.mjs +1 -1
- package/dist/browser/expose.mjs +10 -17
- package/dist/browser/fs.d.mts +5 -0
- package/dist/browser/fs.mjs +1 -1
- package/dist/cli.mjs +3 -2
- package/dist/core.d.mts +31 -14
- package/dist/core.mjs +3 -3
- package/dist/{fs-DZ4QHM93.mjs → fs-BM30qNPb.mjs} +8 -1
- package/dist/{index-OSyELQEX.d.mts → index-Bd2ctbJm.d.mts} +2 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-BMrfSYwa.mjs → src-ChJZPkg9.mjs} +376 -28
- package/dist/ui/assets/{ErdView-D3Q6HCAZ.js → ErdView-CWmAQgo6.js} +1 -1
- package/dist/ui/assets/{MarkdownField-Dh4Tn8_S.js → MarkdownField-DI3OMg7I.js} +1 -1
- package/dist/ui/assets/PageView-BsEhcE48.js +1 -0
- package/dist/ui/assets/access-DV6K5419.js +1 -0
- package/dist/ui/assets/index-emolmw-f.js +126 -0
- package/dist/ui/assets/load-BsZuQtRZ.js +2 -0
- package/dist/ui/index.html +1 -1
- package/dist/ui-embed/{ErdView-Dk-iexgy.js → ErdView-CmUxHybj.js} +2 -2
- package/dist/ui-embed/{HintPopover-D5P2UuTa.js → HintPopover-NOWaUpA_.js} +737 -721
- package/dist/ui-embed/PageView-Bptfb1IR.js +1154 -0
- package/dist/ui-embed/{activity-letLdXN4.js → activity-v3qF9H6V.js} +1 -1
- package/dist/ui-embed/embed.js +36 -36
- package/dist/ui-embed/{pageFrame-CFoU6UjD.js → pageFrame-vCls4cAs.js} +1 -1
- package/dist/{workspace-gtZ3m7LH.mjs → workspace-D7xHlBPc.mjs} +78 -6
- package/package.json +1 -1
- package/dist/ui/assets/PageView-9PohkcTy.js +0 -1
- package/dist/ui/assets/index-nxlI4YiX.js +0 -126
- package/dist/ui/assets/load-C3NfhY_i.js +0 -2
- package/dist/ui-embed/PageView-BzCYlXPg.js +0 -818
package/README.md
CHANGED
|
@@ -255,26 +255,29 @@ pages:
|
|
|
255
255
|
access: { tasks: write, people: read } # tables and views; nothing else is reachable
|
|
256
256
|
sql: false # true allows SELECT over the names in access
|
|
257
257
|
network: [] # origins the page may load scripts, styles, images and fonts from, and connect to
|
|
258
|
+
files: { .images/: read, .uploads/: write } # files the page may read (yamlite.files.read) or also write (yamlite.files.write); a folder ends in /
|
|
258
259
|
ai: true # lets the page call the host's AI model; { maxOutputTokens: 2048 } raises the default 1024 (at most 8192)
|
|
259
260
|
```
|
|
260
261
|
|
|
261
|
-
Start from [`examples/pages/kanban.html`](examples/pages/kanban.html): copy it into `.pages/`, set `TABLE`, `KEY`, `GROUP` and `TITLE` at the top, and declare it as above. [`examples/pages/summary.html`](examples/pages/summary.html) shows a page that asks AI to summarize a record.
|
|
262
|
+
Start from [`examples/pages/kanban.html`](examples/pages/kanban.html): copy it into `.pages/`, set `TABLE`, `KEY`, `GROUP` and `TITLE` at the top, and declare it as above. [`examples/pages/summary.html`](examples/pages/summary.html) shows a page that asks AI to summarize a record. [`examples/pages/gallery.html`](examples/pages/gallery.html) lists a table's `image` column and shows each file with `yamlite.files.read`.
|
|
262
263
|
|
|
263
264
|
To share a page with people who should see only that page, open it and click **Copy app link**. The link ends in `/-/apps/<name>/` and shows the page alone, with its own title and look: no sidebar, tables, SQL console, command menu or links into other records. Once there are edits, a bar at the bottom shows their count and **Send for review**; an embedding host can add its own controls at the left of that bar with the `appFooter` mount option. The part after `#` is where the page stands inside itself, which it sets with `yamlite.history`, so a reload, the back button and a copied address return there; changing it does not leave the app. It leaves the editor out of sight; it does not take it away, so anyone who removes `-/apps/<name>/` from the address can still reach the rest of the UI. With `serve`, the copied link has no token, and the login cookie is not sent when a link is opened from another site such as mail or chat: share `/-/apps/<name>/?token=…` instead, on the origin of the URL `serve` printed and with its token. `serve` is meant for trying an app out; to share one with a team, use a host that gives each viewer their own branch. An `export` has the same entry at `-/apps/<name>/` for each page it includes; open it with the trailing slash (static hosts add it), since without it the page's relative paths resolve one folder too high.
|
|
264
265
|
|
|
265
|
-
| Call
|
|
266
|
-
|
|
|
267
|
-
| `await yamlite.ready`
|
|
268
|
-
| `yamlite.rows(table, { filter, sort, search, limit, offset })`
|
|
269
|
-
| `yamlite.get(table, key)`
|
|
270
|
-
| `yamlite.create(table, key, values)` / `update(table, key, values, base)` / `remove(table, key)` | needs `write`; `update` fails with status 409, `extra.stale` (the fields) and `extra.current` (
|
|
271
|
-
| `yamlite.sql(select)`
|
|
272
|
-
| `yamlite.
|
|
273
|
-
| `yamlite.
|
|
274
|
-
| `yamlite.
|
|
275
|
-
| `yamlite.
|
|
276
|
-
| `yamlite.
|
|
277
|
-
| `yamlite.
|
|
266
|
+
| Call | Does |
|
|
267
|
+
| -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
268
|
+
| `await yamlite.ready` | `{ page, title, access, sql, network, files, readOnly, ai }`; `ai` is `{ provider, models }` when the page has `ai` and the host holds a key, else `null` |
|
|
269
|
+
| `yamlite.rows(table, { filter, sort, search, limit, offset })` | `{ rows, total }`, reads tables and views, same filters and search as the table screen; `limit` ≤ 500 |
|
|
270
|
+
| `yamlite.get(table, key)` | `{ row, file }`; tables only, a view gives 400 |
|
|
271
|
+
| `yamlite.create(table, key, values)` / `update(table, key, values, { base })` / `remove(table, key, { base })` | needs `write`; `base` is the record as the page last read it, or the fields of it the page relies on. `update` fails with status 409, `extra.stale` (the fields) and `extra.current` (the record now) if a field it saves changed since `base`; `remove` does if any field in `base` changed. Leaving `base` out skips the check |
|
|
272
|
+
| `yamlite.sql(select)` | needs `sql: true`; one SELECT over the names in `access` |
|
|
273
|
+
| `await yamlite.files.read(path)` | needs `path` to match one of the page's `files` entries (`read` or `write`) and not be a denied path; resolves to a `Blob` typed by extension (`image/png`, `image/jpeg`, `image/webp`, `image/gif`, `image/svg+xml`, `application/pdf`, `text/plain`, otherwise `application/octet-stream`), for `URL.createObjectURL`. Files on the branch or commit the viewer has open, at most 10 MB; 403 when `path` matches no entry, 404 when there is no such file, 413 over the limit |
|
|
274
|
+
| `await yamlite.files.write(path, blob, { base })` / `files.delete(path, { base })` | needs `path` to fall under a `write` entry; `write` stores a PNG, JPEG, GIF, WebP or PDF file (the bytes must match the extension, at most 10 MB), creating its folders, and resolves to `{ sha256 }`; `delete` removes the file. `base` is the `Blob` the page last got from `files.read`, the `sha256` its last `files.write` returned, or `null` when it expects no file there; when the file has changed since, the call fails with status 409 and `extra.current` (the SHA-256 of the content now; absent when the file is over 10 MB). Leaving `base` out skips the check |
|
|
275
|
+
| `yamlite.on("change", ({ tables, files }) => …)` | called after a sync changes a table or view the page can read (`tables`), or after a file under the page's `files` changes on disk (`files`, root-relative paths), whoever changed it |
|
|
276
|
+
| `yamlite.theme` / `yamlite.on("theme", ({ theme }) => …)` | the current theme (`light` or `dark`), and a call when it changes |
|
|
277
|
+
| `yamlite.ai.generate({ system, prompt, schema, model, maxOutputTokens })` | needs `ai` (a page without it gets 403); `{ text }`, or `{ object }` matching `schema` (a JSON Schema). `prompt` is a string or a list of `{ role: "user" \| "assistant", content }`; `model` is one of `ready`'s `ai.models`, the first by default; `maxOutputTokens` may lower the page's limit. Runs on the host's key, never one from the page. Fails with 503 and `extra.code: "no_key"` when the host has no key, 429 with `extra.retryAfter` (seconds) when busy, and 502 when the provider fails: `extra.provider` is the provider id and the provider's own text is in `message` |
|
|
278
|
+
| `yamlite.ai.stream({ system, prompt, model })` | the same without `schema`, as an async iterable of text deltas: `for await (const text of yamlite.ai.stream(…))`; leaving the loop early cancels the call |
|
|
279
|
+
| `yamlite.open(table, key)` | opens the record in YAMLite's own form; tables only, a view gives 400 |
|
|
280
|
+
| `yamlite.history` | where the page stands inside itself, with the `history` package's shape (`location`, `push`, `replace`, `go`, `back`, `forward`, `listen`, `createHref`) that routers take; in an app it is kept after the `#` of the address, and `back` and `go` stay within the app. `push(to, state)` and `replace(to, state)` throw for a path outside the page or longer than 2048 characters; `state` must be structured-cloneable, and comes back as `location.state` on back and forward, and as JSON after a reload |
|
|
278
281
|
|
|
279
282
|
Errors reject with `yamlite.YamliteError` (`status`, `message`, `extra`).
|
|
280
283
|
|
|
@@ -303,7 +306,10 @@ The variable and class names are part of the page API: renaming one is a breakin
|
|
|
303
306
|
- `network` is enforced with a Content Security Policy. It limits what the page loads and where it connects. Declaring an origin lets the page send data, including anything it can read through `access`, off your machine to that origin.
|
|
304
307
|
- `ai` lets the page send anything it can read through `access` to the host's AI provider, billed to the host's key.
|
|
305
308
|
- Every page, even with `network: []`, can leak data by navigating its own frame to another site with the data in the URL. YAMLite then disconnects the page, but the data has already left. Only declare pages you trust, as you would any script you run.
|
|
306
|
-
-
|
|
309
|
+
- `files` is a grant like `access`: each entry is `read` or `write`, the page can read every file under a declared folder, and anything a page can read can leave through navigation, as for records. An entry ending in `/` is a folder, any other entry one exact file; `..`, absolute paths and entries inside `.yamlite/` or naming `yamlite.yaml` are config errors, as is any level but `read` or `write`. A page cannot read YAMLite's state folder, the database (and its `-wal`, `-shm` and `-journal` files) or the config files, whatever `files` says: a broad folder entry still gets 403 for them. Symlinks are followed and must stay inside a granted path.
|
|
310
|
+
- A `write` entry lets the page add, replace and delete files under it, but only pictures and PDFs whose bytes match their extension: never HTML, SVG or anything else that could run script where the files are later served. A page cannot write YAMLite's own files, or through a symlinked file; a symlinked folder must lead to a path the page may write. Written files land in the working tree like any other edit, so **Send for review** lists them. Grant `write` only on folders that hold nothing but what the page should manage.
|
|
311
|
+
- `serve` reads the working tree, so a `files` entry also covers files git does not track, such as a local `.env` or build output. Declare folders that hold only what the page should show.
|
|
312
|
+
- In an [export](#export) pages are read-only, and `access` does not hide data: the exported `db.sqlite` is downloadable, and `sql: true` reads every exported table. Pages whose `access` names a table left out of the export are skipped with a warning. An export also copies the files a page declares into `data/files/`, each stored with a `.bin` suffix so a host serves it as a download rather than as a page; deploying the export makes them public; a file over 10 MB is skipped with a warning.
|
|
307
313
|
|
|
308
314
|
## Check
|
|
309
315
|
|
package/dist/browser/expose.mjs
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
//#region src/browser/expose.ts
|
|
2
|
+
function post(port, id, bytes) {
|
|
3
|
+
const data = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
4
|
+
port.postMessage({
|
|
5
|
+
id,
|
|
6
|
+
kind: "chunk",
|
|
7
|
+
data
|
|
8
|
+
}, [data]);
|
|
9
|
+
}
|
|
2
10
|
function expose(port, dispatch) {
|
|
3
11
|
const open = /* @__PURE__ */ new Map();
|
|
4
12
|
port.onmessage = async (e) => {
|
|
@@ -29,24 +37,13 @@ function expose(port, dispatch) {
|
|
|
29
37
|
});
|
|
30
38
|
headSent = true;
|
|
31
39
|
if (res.body) {
|
|
32
|
-
const decoder = new TextDecoder();
|
|
33
40
|
const reader = res.body.getReader();
|
|
34
41
|
ac.signal.addEventListener("abort", () => void reader.cancel(), { once: true });
|
|
35
42
|
for (;;) {
|
|
36
43
|
const { done, value } = await reader.read();
|
|
37
44
|
if (done) break;
|
|
38
|
-
port.
|
|
39
|
-
id: m.id,
|
|
40
|
-
kind: "chunk",
|
|
41
|
-
data: decoder.decode(value, { stream: true })
|
|
42
|
-
});
|
|
45
|
+
post(port, m.id, value);
|
|
43
46
|
}
|
|
44
|
-
const rest = decoder.decode();
|
|
45
|
-
if (rest) port.postMessage({
|
|
46
|
-
id: m.id,
|
|
47
|
-
kind: "chunk",
|
|
48
|
-
data: rest
|
|
49
|
-
});
|
|
50
47
|
}
|
|
51
48
|
} catch (err) {
|
|
52
49
|
if (!ac.signal.aborted && !headSent) {
|
|
@@ -56,11 +53,7 @@ function expose(port, dispatch) {
|
|
|
56
53
|
status: 500,
|
|
57
54
|
headers: [["content-type", "application/json"]]
|
|
58
55
|
});
|
|
59
|
-
port.
|
|
60
|
-
id: m.id,
|
|
61
|
-
kind: "chunk",
|
|
62
|
-
data: JSON.stringify({ error: String(err) })
|
|
63
|
-
});
|
|
56
|
+
post(port, m.id, new TextEncoder().encode(JSON.stringify({ error: String(err) })));
|
|
64
57
|
}
|
|
65
58
|
} finally {
|
|
66
59
|
open.delete(m.id);
|
package/dist/browser/fs.d.mts
CHANGED
|
@@ -24,6 +24,9 @@ export declare function statSync(p: string, opts?: {
|
|
|
24
24
|
export declare const lstatSync: typeof statSync;
|
|
25
25
|
export declare function accessSync(p: string): void;
|
|
26
26
|
export declare function realpathSync(p: string): string;
|
|
27
|
+
export declare namespace realpathSync {
|
|
28
|
+
export { realpathSync as native };
|
|
29
|
+
}
|
|
27
30
|
export declare function readFileSync(p: string, opts?: string | {
|
|
28
31
|
encoding?: string;
|
|
29
32
|
}): string | Buffer<ArrayBuffer>;
|
|
@@ -51,6 +54,7 @@ export declare function rmSync(p: string, opts?: {
|
|
|
51
54
|
}): void;
|
|
52
55
|
export declare function renameSync(from: string, to: string): void;
|
|
53
56
|
export declare function linkSync(from: string, to: string): void;
|
|
57
|
+
export declare function copyFileSync(from: string, to: string): void;
|
|
54
58
|
export declare function cpSync(from: string, to: string): void;
|
|
55
59
|
export declare function chmodSync(p: string, mode: number): void;
|
|
56
60
|
export declare function mkdtempSync(prefix: string): string;
|
|
@@ -64,6 +68,7 @@ declare const _default: {
|
|
|
64
68
|
W_OK: number;
|
|
65
69
|
X_OK: number;
|
|
66
70
|
};
|
|
71
|
+
copyFileSync: typeof copyFileSync;
|
|
67
72
|
cpSync: typeof cpSync;
|
|
68
73
|
createReadStream: typeof createReadStream;
|
|
69
74
|
existsSync: typeof existsSync;
|
package/dist/browser/fs.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as accessSync, n as chmodSync, r as constants, i as
|
|
1
|
+
export { t as accessSync, n as chmodSync, r as constants, i as copyFileSync, a as cpSync, o as createReadStream, l as default, s as existsSync, c as external, u as linkSync, d as lstatSync, f as mkdirSync, p as mkdtempSync, m as onChange, h as onRemove, g as readFileSync, _ as readdirSync, v as realpathSync, y as renameSync, b as rmSync, x as rmdirSync, S as statSync, C as unlinkSync, w as writeFileSync } from "../fs-BM30qNPb.mjs";
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { n as guide, r as envKeys, t as createWorkspace } from "./workspace-
|
|
2
|
+
import { B as check, I as createHandler, R as isLoopback, a as query, c as exportSite, i as formatTable, n as formatCsv, o as generateConfig, r as formatJson, s as init, t as open, z as loopbackHosts } from "./src-ChJZPkg9.mjs";
|
|
3
|
+
import { n as guide, r as envKeys, t as createWorkspace } from "./workspace-D7xHlBPc.mjs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { relative, resolve } from "node:path";
|
|
6
6
|
import { homedir } from "node:os";
|
|
@@ -423,6 +423,7 @@ program.command("export").description("write the web UI as a read-only static si
|
|
|
423
423
|
console.log(`${out("green", "✓")} exported ${count} to ${displayPath(r.out)}`);
|
|
424
424
|
for (const [table, warnings] of Object.entries(r.warnings)) for (const w of warnings) console.log(` ${out("yellow", "!")} ${table}: ${w}`);
|
|
425
425
|
for (const [page, reason] of Object.entries(r.skippedPages)) console.log(` ${out("yellow", "!")} page ${page} not exported: ${reason}`);
|
|
426
|
+
for (const [path, reason] of Object.entries(r.skippedFiles)) console.log(` ${out("yellow", "!")} file ${path} not exported: ${reason}`);
|
|
426
427
|
console.log(out("dim", " serve the folder over HTTP to open it; file:// does not work"));
|
|
427
428
|
});
|
|
428
429
|
program.parseAsync().catch((e) => {
|
package/dist/core.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as parseConfig, B as HistoryEntry, C as Decision, D as OpenOptions, E as DeclaredTable, F as ColumnType, G as Rec, H as IndexSpec, I as ConflictInfo, J as ViewRecord, K as SchemaChange, L as DbRow, M as Capture, N as Change, O as TableInput, P as ChangeOp, R as DbValue, S as BaseHashes, T as Config, U as PageAccess, V as HistoryPage, W as PageSpec, _ as check, a as formatCsv, b as Watcher, c as query, d as init, f as ExportOptions, g as CheckTable, h as CheckResult, i as QueryResult, j as readsFile, k as TableLocation, l as InitOptions, m as exportSite, n as open, o as formatJson, p as ExportResult, q as TableSpec, r as QueryOptions, s as formatTable, t as Yamlite, u as generateConfig, v as WatchHandlers, w as CONFIG_NAMES, x as TableResult, y as WatchOptions, z as FieldChange } from "./index-
|
|
1
|
+
import { A as parseConfig, B as HistoryEntry, C as Decision, D as OpenOptions, E as DeclaredTable, F as ColumnType, G as Rec, H as IndexSpec, I as ConflictInfo, J as ViewRecord, K as SchemaChange, L as DbRow, M as Capture, N as Change, O as TableInput, P as ChangeOp, R as DbValue, S as BaseHashes, T as Config, U as PageAccess, V as HistoryPage, W as PageSpec, _ as check, a as formatCsv, b as Watcher, c as query, d as init, f as ExportOptions, g as CheckTable, h as CheckResult, i as QueryResult, j as readsFile, k as TableLocation, l as InitOptions, m as exportSite, n as open, o as formatJson, p as ExportResult, q as TableSpec, r as QueryOptions, s as formatTable, t as Yamlite, u as generateConfig, v as WatchHandlers, w as CONFIG_NAMES, x as TableResult, y as WatchOptions, z as FieldChange } from "./index-Bd2ctbJm.mjs";
|
|
2
2
|
import { DatabaseSync } from "node:sqlite";
|
|
3
3
|
import { LanguageModel, ModelMessage } from "ai";
|
|
4
4
|
//#region src/store.d.ts
|
|
@@ -53,6 +53,22 @@ declare class Store {
|
|
|
53
53
|
dropState(table: string, key: string): void;
|
|
54
54
|
}
|
|
55
55
|
//#endregion
|
|
56
|
+
//#region src/pages/access.d.ts
|
|
57
|
+
interface PageRules {
|
|
58
|
+
name: string;
|
|
59
|
+
access: Record<string, PageAccess>;
|
|
60
|
+
sql: boolean;
|
|
61
|
+
network: string[];
|
|
62
|
+
files: Record<string, PageAccess>;
|
|
63
|
+
ai: {
|
|
64
|
+
maxOutputTokens: number;
|
|
65
|
+
} | null;
|
|
66
|
+
}
|
|
67
|
+
export declare const DENIED_FILES: string[];
|
|
68
|
+
export declare const MAX_PAGE_FILE_BYTES = 10485760;
|
|
69
|
+
export declare function normalizeFilePath(path: string): string | null;
|
|
70
|
+
export declare const fileGranted: (files: Record<string, PageAccess>, path: string) => boolean;
|
|
71
|
+
//#endregion
|
|
56
72
|
//#region src/agent/providers.d.ts
|
|
57
73
|
interface Credentials {
|
|
58
74
|
provider: string;
|
|
@@ -333,6 +349,10 @@ type ServeEvent = {
|
|
|
333
349
|
type: "page";
|
|
334
350
|
at: string;
|
|
335
351
|
pages: string[];
|
|
352
|
+
} | {
|
|
353
|
+
type: "files";
|
|
354
|
+
at: string;
|
|
355
|
+
paths: string[];
|
|
336
356
|
};
|
|
337
357
|
//#endregion
|
|
338
358
|
//#region src/serve/events.d.ts
|
|
@@ -348,6 +368,7 @@ declare class EventHub {
|
|
|
348
368
|
warnings(): Record<string, string[]>;
|
|
349
369
|
configError(): string | null;
|
|
350
370
|
pagesChanged(pages: string[]): void;
|
|
371
|
+
filesChanged(paths: string[]): void;
|
|
351
372
|
stream(signal: AbortSignal): ReadableStream<Uint8Array>;
|
|
352
373
|
close(): void;
|
|
353
374
|
private onSync;
|
|
@@ -355,17 +376,6 @@ declare class EventHub {
|
|
|
355
376
|
private send;
|
|
356
377
|
}
|
|
357
378
|
//#endregion
|
|
358
|
-
//#region src/pages/access.d.ts
|
|
359
|
-
interface PageRules {
|
|
360
|
-
name: string;
|
|
361
|
-
access: Record<string, PageAccess>;
|
|
362
|
-
sql: boolean;
|
|
363
|
-
network: string[];
|
|
364
|
-
ai: {
|
|
365
|
-
maxOutputTokens: number;
|
|
366
|
-
} | null;
|
|
367
|
-
}
|
|
368
|
-
//#endregion
|
|
369
379
|
//#region src/serve/pagesql.d.ts
|
|
370
380
|
declare class PageSql {
|
|
371
381
|
private readonly path;
|
|
@@ -393,6 +403,8 @@ interface ApiContext {
|
|
|
393
403
|
agent: AgentHost | null;
|
|
394
404
|
git: GitDriver | null;
|
|
395
405
|
reloadConfig: () => void;
|
|
406
|
+
pageFiles: WorkspaceOptions["pageFiles"] | null;
|
|
407
|
+
deniedFiles: string[];
|
|
396
408
|
}
|
|
397
409
|
//#endregion
|
|
398
410
|
//#region src/agent/tools.d.ts
|
|
@@ -513,16 +525,20 @@ interface ApiRequest {
|
|
|
513
525
|
type Handler = (req: ApiRequest) => unknown;
|
|
514
526
|
declare class Router {
|
|
515
527
|
private readonly routes;
|
|
516
|
-
add(method: string, pattern: string, handler: Handler
|
|
528
|
+
add(method: string, pattern: string, handler: Handler, opts?: {
|
|
529
|
+
maxBody?: number;
|
|
530
|
+
}): this;
|
|
517
531
|
match(method: string, pathname: string): {
|
|
518
532
|
handler: Handler;
|
|
519
533
|
params: Record<string, string>;
|
|
534
|
+
maxBody: number;
|
|
520
535
|
} | "method" | null;
|
|
521
536
|
dispatch(request: Request): Promise<Response>;
|
|
522
537
|
}
|
|
523
538
|
//#endregion
|
|
524
539
|
//#region src/serve/workspace.d.ts
|
|
525
540
|
type AiOptions = Omit<HostOptions, "tools" | "feedback" | "notes">;
|
|
541
|
+
type PageFileResult = Uint8Array<ArrayBuffer> | "missing" | "too-large" | undefined;
|
|
526
542
|
interface WorkspaceOptions {
|
|
527
543
|
root: string;
|
|
528
544
|
db?: string;
|
|
@@ -530,6 +546,7 @@ interface WorkspaceOptions {
|
|
|
530
546
|
ai?: AiOptions | null;
|
|
531
547
|
git?: GitDriver | null;
|
|
532
548
|
gh?: string | null;
|
|
549
|
+
pageFiles?: (path: string, signal: AbortSignal) => Promise<PageFileResult>;
|
|
533
550
|
}
|
|
534
551
|
interface Workspace {
|
|
535
552
|
readonly context: ApiContext;
|
|
@@ -541,4 +558,4 @@ export declare function createWorkspace(o: WorkspaceOptions): Promise<Workspace>
|
|
|
541
558
|
//#region src/git/pr.d.ts
|
|
542
559
|
export declare function templatePath(paths: readonly string[]): string | null;
|
|
543
560
|
//#endregion
|
|
544
|
-
export { type AiOptions, type ApiContext, CONFIG_NAMES, type Capture, type Change, type ChangeOp, type CheckResult, type CheckTable, type ColumnType, type Config, type ConflictInfo, type Credentials, type Decision, type DeclaredTable, type DefaultBranchFiles, type DiffResult, type ExportOptions, type ExportResult, type Extract, type Extracted, type GitDriver, type GitStatus, type GitStep, type HistoryEntry, type HistoryPage, type HistoryTarget, type IndexSpec, type InitOptions, type OpenOptions, type PageSpec, type QueryOptions, type QueryResult, type Repo, type ReviewOutcome, type ReviewRequest, type RunOptions, type SchemaChange, type StepResult, type StepRunner, type TableInput, type TableLocation, type TableResult, type TableSpec, type WatchHandlers, type WatchOptions, type Watcher, type Workspace, type WorkspaceOptions, Yamlite, check, exportSite, formatCsv, formatJson, formatTable, generateConfig, init, open, parseConfig, query, readsFile };
|
|
561
|
+
export { type AiOptions, type ApiContext, CONFIG_NAMES, type Capture, type Change, type ChangeOp, type CheckResult, type CheckTable, type ColumnType, type Config, type ConflictInfo, type Credentials, type Decision, type DeclaredTable, type DefaultBranchFiles, type DiffResult, type ExportOptions, type ExportResult, type Extract, type Extracted, type GitDriver, type GitStatus, type GitStep, type HistoryEntry, type HistoryPage, type HistoryTarget, type IndexSpec, type InitOptions, type OpenOptions, type PageFileResult, type PageSpec, type QueryOptions, type QueryResult, type Repo, type ReviewOutcome, type ReviewRequest, type RunOptions, type SchemaChange, type StepResult, type StepRunner, type TableInput, type TableLocation, type TableResult, type TableSpec, type WatchHandlers, type WatchOptions, type Watcher, type Workspace, type WorkspaceOptions, Yamlite, check, exportSite, formatCsv, formatJson, formatTable, generateConfig, init, open, parseConfig, query, readsFile };
|
package/dist/core.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { B as
|
|
2
|
-
import { t as createWorkspace } from "./workspace-
|
|
3
|
-
export { CONFIG_NAMES, HttpError, ReviewRefused, check, createWorkspace, describeChange, exportSite, fieldChanges, formatCsv, formatJson, formatTable, generateConfig, init, open, parseConfig, query, readsFile, templatePath, worthShowing };
|
|
1
|
+
import { B as check, C as describeChange, K as DENIED_FILES, L as HttpError, T as worthShowing, U as parseConfig, V as CONFIG_NAMES, W as readsFile, X as fileGranted, Z as normalizeFilePath, a as query, c as exportSite, f as ReviewRefused, h as templatePath, i as formatTable, n as formatCsv, o as generateConfig, q as MAX_PAGE_FILE_BYTES, r as formatJson, s as init, t as open, w as fieldChanges } from "./src-ChJZPkg9.mjs";
|
|
2
|
+
import { t as createWorkspace } from "./workspace-D7xHlBPc.mjs";
|
|
3
|
+
export { CONFIG_NAMES, DENIED_FILES, HttpError, MAX_PAGE_FILE_BYTES, ReviewRefused, check, createWorkspace, describeChange, exportSite, fieldChanges, fileGranted, formatCsv, formatJson, formatTable, generateConfig, init, normalizeFilePath, open, parseConfig, query, readsFile, templatePath, worthShowing };
|
|
@@ -94,6 +94,7 @@ function realpathSync(p) {
|
|
|
94
94
|
get(abs(p), "realpath");
|
|
95
95
|
return abs(p);
|
|
96
96
|
}
|
|
97
|
+
realpathSync.native = realpathSync;
|
|
97
98
|
function readFileSync(p, opts) {
|
|
98
99
|
const path = abs(p);
|
|
99
100
|
const e = get(path, "open");
|
|
@@ -199,6 +200,11 @@ function linkSync(from, to) {
|
|
|
199
200
|
tree.set(b, e);
|
|
200
201
|
emit("add", b);
|
|
201
202
|
}
|
|
203
|
+
function copyFileSync(from, to) {
|
|
204
|
+
const e = get(abs(from), "copyfile");
|
|
205
|
+
if (e.kind === "dir") fail("EISDIR", "illegal operation on a directory", "copyfile", abs(from));
|
|
206
|
+
writeFileSync(to, e.data);
|
|
207
|
+
}
|
|
202
208
|
function cpSync(from, to) {
|
|
203
209
|
const a = abs(from);
|
|
204
210
|
const b = abs(to);
|
|
@@ -230,6 +236,7 @@ var fs_default = {
|
|
|
230
236
|
accessSync,
|
|
231
237
|
chmodSync,
|
|
232
238
|
constants,
|
|
239
|
+
copyFileSync,
|
|
233
240
|
cpSync,
|
|
234
241
|
createReadStream,
|
|
235
242
|
existsSync,
|
|
@@ -248,4 +255,4 @@ var fs_default = {
|
|
|
248
255
|
writeFileSync
|
|
249
256
|
};
|
|
250
257
|
//#endregion
|
|
251
|
-
export {
|
|
258
|
+
export { unlinkSync as C, statSync as S, readdirSync as _, cpSync as a, rmSync as b, external as c, lstatSync as d, mkdirSync as f, readFileSync as g, onRemove as h, copyFileSync as i, fs_default as l, onChange as m, chmodSync as n, createReadStream as o, mkdtempSync as p, constants as r, existsSync as s, accessSync as t, linkSync as u, realpathSync as v, writeFileSync as w, rmdirSync as x, renameSync as y };
|
|
@@ -81,6 +81,7 @@ interface PageSpec {
|
|
|
81
81
|
access: Record<string, PageAccess>;
|
|
82
82
|
sql: boolean;
|
|
83
83
|
network: string[];
|
|
84
|
+
files: Record<string, PageAccess>;
|
|
84
85
|
ai: {
|
|
85
86
|
maxOutputTokens: number;
|
|
86
87
|
} | null;
|
|
@@ -268,6 +269,7 @@ interface ExportResult {
|
|
|
268
269
|
warnings: Record<string, string[]>;
|
|
269
270
|
pages: string[];
|
|
270
271
|
skippedPages: Record<string, string>;
|
|
272
|
+
skippedFiles: Record<string, string>;
|
|
271
273
|
}
|
|
272
274
|
declare function exportSite(opts: ExportOptions): Promise<ExportResult>;
|
|
273
275
|
//#endregion
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as Decision, D as OpenOptions, F as ColumnType, H as IndexSpec, I as ConflictInfo, K as SchemaChange, N as Change, O as TableInput, P as ChangeOp, W as PageSpec, _ as check, a as formatCsv, b as Watcher, c as query, d as init, f as ExportOptions, g as CheckTable, h as CheckResult, i as QueryResult, l as InitOptions, m as exportSite, n as open, o as formatJson, p as ExportResult, q as TableSpec, r as QueryOptions, s as formatTable, t as Yamlite, u as generateConfig, v as WatchHandlers, x as TableResult, y as WatchOptions } from "./index-
|
|
1
|
+
import { C as Decision, D as OpenOptions, F as ColumnType, H as IndexSpec, I as ConflictInfo, K as SchemaChange, N as Change, O as TableInput, P as ChangeOp, W as PageSpec, _ as check, a as formatCsv, b as Watcher, c as query, d as init, f as ExportOptions, g as CheckTable, h as CheckResult, i as QueryResult, l as InitOptions, m as exportSite, n as open, o as formatJson, p as ExportResult, q as TableSpec, r as QueryOptions, s as formatTable, t as Yamlite, u as generateConfig, v as WatchHandlers, x as TableResult, y as WatchOptions } from "./index-Bd2ctbJm.mjs";
|
|
2
2
|
export { type Change, type ChangeOp, type CheckResult, type CheckTable, type ColumnType, type ConflictInfo, type Decision, type ExportOptions, type ExportResult, type IndexSpec, type InitOptions, type OpenOptions, type PageSpec, type QueryOptions, type QueryResult, type SchemaChange, type TableInput, type TableResult, type TableSpec, type WatchHandlers, type WatchOptions, type Watcher, Yamlite, check, exportSite, formatCsv, formatJson, formatTable, generateConfig, init, open, query };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { B as check, c as exportSite, n as formatCsv, r as formatJson, i as formatTable, o as generateConfig, s as init, t as open, a as query } from "./src-ChJZPkg9.mjs";
|