vde-open 0.1.9 → 0.1.11
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 +22 -6
- package/dist/cli.js +11 -16
- package/dist/daemon.js +2 -2
- package/dist/{html-static-BDV6MgA7.js → html-static-C_wwQAJx.js} +67 -0
- package/dist/{main-DwpMMOjm.js → main-BH6i8EXC.js} +92 -176
- package/dist/{print-Cfa1Ytrj.js → print-vae7mHCU.js} +1 -1
- package/dist/{render-BX3arVZj.js → render-BJa4uW0H.js} +1 -1
- package/dist/{search-index-B7DqaWh6.js → search-index-BoGly_y4.js} +12 -14
- package/dist/web/assets/index-CVYtIVot.js +163 -0
- package/dist/web/assets/index-_RRuuJtK.css +2 -0
- package/dist/web/index.html +2 -2
- package/dist/workers/parse-worker.js +3 -3
- package/dist/workers/search-worker.js +1 -1
- package/docs/agent-usage.md +1 -0
- package/package.json +3 -2
- package/skills/vde-open/SKILL.md +5 -3
- package/dist/web/assets/index-Cnw68UWf.css +0 -2
- package/dist/web/assets/index-DIyamSNh.js +0 -163
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as roleAllowed, N as __commonJSMin, P as __toESM, S as isValidLogicalPath, _ as classifyLink, b as encodeLogicalPath, d as analyzeDocument, g as assetTypeOf, u as ParseLimitError, v as classifyReference, x as hasHiddenSegment, y as dirnameOfLogicalPath } from "./html-static-
|
|
2
|
-
import { $ as literal, A as successEnvelope, B as readParamsSchema, C as VdeError, D as ExitCode, E as isVdeError, F as htmlModeChangeParamsSchema, G as sha256Schema, H as reorderParamsSchema, I as htmlModeSchema, J as watchRuleSchema, K as sourceKindSchema, L as linkOpenParamsSchema, M as closeParamsSchema, N as documentFormatSchema, P as documentIdSchema, Q as boolean, R as listParamsSchema, S as validateAnswers, U as revisionSchema, V as renderGrantParamsSchema, W as searchParamsSchema, X as _enum, Y as LIMITS, Z as array, _ as feedbackWaitParamsSchema, a as uniqueTokens, at as canonicalJson, b as submissionSchema, c as feedbackAckParamsSchema, d as feedbackDraftParamsSchema, et as number, f as feedbackForgetParamsSchema, g as feedbackSubmitParamsSchema, h as feedbackStatusSchema, i as codePointLength, it as ZodError, j as assetRecordSchema, k as errorEnvelope, l as feedbackCancelParamsSchema, m as feedbackListParamsSchema, n as batchesOf, nt as strictObject, o as answersSchema, p as feedbackIdParamsSchema, q as sourceStateSchema, r as partsOf, rt as string, s as cancellationSchema, tt as record, u as feedbackCreateParamsSchema, v as questionnaireSchema, w as exitCodeForError, x as utf8Length, y as requestIdSchema, z as openParamsSchema } from "./search-index-
|
|
3
|
-
import { n as scanReferences, r as extractTitle } from "./render-
|
|
1
|
+
import { C as roleAllowed, N as __commonJSMin, P as __toESM, S as isValidLogicalPath, _ as classifyLink, b as encodeLogicalPath, d as analyzeDocument, g as assetTypeOf, u as ParseLimitError, v as classifyReference, x as hasHiddenSegment, y as dirnameOfLogicalPath } from "./html-static-C_wwQAJx.js";
|
|
2
|
+
import { $ as literal, A as successEnvelope, B as readParamsSchema, C as VdeError, D as ExitCode, E as isVdeError, F as htmlModeChangeParamsSchema, G as sha256Schema, H as reorderParamsSchema, I as htmlModeSchema, J as watchRuleSchema, K as sourceKindSchema, L as linkOpenParamsSchema, M as closeParamsSchema, N as documentFormatSchema, P as documentIdSchema, Q as boolean, R as listParamsSchema, S as validateAnswers, U as revisionSchema, V as renderGrantParamsSchema, W as searchParamsSchema, X as _enum, Y as LIMITS, Z as array, _ as feedbackWaitParamsSchema, a as uniqueTokens, at as canonicalJson, b as submissionSchema, c as feedbackAckParamsSchema, d as feedbackDraftParamsSchema, et as number, f as feedbackForgetParamsSchema, g as feedbackSubmitParamsSchema, h as feedbackStatusSchema, i as codePointLength, it as ZodError, j as assetRecordSchema, k as errorEnvelope, l as feedbackCancelParamsSchema, m as feedbackListParamsSchema, n as batchesOf, nt as strictObject, o as answersSchema, p as feedbackIdParamsSchema, q as sourceStateSchema, r as partsOf, rt as string, s as cancellationSchema, tt as record, u as feedbackCreateParamsSchema, v as questionnaireSchema, w as exitCodeForError, x as utf8Length, y as requestIdSchema, z as openParamsSchema } from "./search-index-BoGly_y4.js";
|
|
3
|
+
import { n as scanReferences, r as extractTitle } from "./render-BJa4uW0H.js";
|
|
4
4
|
import { n as measureHeap, t as collectGarbage } from "./heap-C3qHm7SE.js";
|
|
5
5
|
import { accessSync, constants, existsSync, stat, statSync, unwatchFile, watch, watchFile } from "node:fs";
|
|
6
6
|
import { appendFile, chmod, link, lstat, mkdir, mkdtemp, open, readFile, readdir, readlink, realpath, rename, rm, rmdir, stat as stat$1, writeFile } from "node:fs/promises";
|
|
@@ -154,7 +154,7 @@ function parseStrictJson(text) {
|
|
|
154
154
|
}
|
|
155
155
|
//#endregion
|
|
156
156
|
//#region package.json
|
|
157
|
-
var version = "0.1.
|
|
157
|
+
var version = "0.1.11";
|
|
158
158
|
//#endregion
|
|
159
159
|
//#region src/documents/cursor.ts
|
|
160
160
|
function invalidCursor(reason) {
|
|
@@ -283,7 +283,7 @@ function decodeSource(bytes, label) {
|
|
|
283
283
|
throw invalid(label, "invalid-utf8");
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
-
async function readSourceFile(path) {
|
|
286
|
+
async function readSourceFile(path, format = "markdown") {
|
|
287
287
|
let canonicalPath;
|
|
288
288
|
try {
|
|
289
289
|
canonicalPath = await realpath(path);
|
|
@@ -317,7 +317,7 @@ async function readSourceFile(path) {
|
|
|
317
317
|
return {
|
|
318
318
|
canonicalPath,
|
|
319
319
|
bytes,
|
|
320
|
-
text: decodeSource(bytes, path),
|
|
320
|
+
text: format === "image" ? "" : decodeSource(bytes, path),
|
|
321
321
|
signature: statSignature(after)
|
|
322
322
|
};
|
|
323
323
|
} finally {
|
|
@@ -3387,7 +3387,10 @@ const FORMAT_BY_EXTENSION = /* @__PURE__ */ new Map([
|
|
|
3387
3387
|
[".htm", "html"]
|
|
3388
3388
|
]);
|
|
3389
3389
|
function formatOfPath(path) {
|
|
3390
|
-
|
|
3390
|
+
const document = FORMAT_BY_EXTENSION.get(extname(path).toLowerCase());
|
|
3391
|
+
if (document) return document;
|
|
3392
|
+
const asset = assetTypeOf(path);
|
|
3393
|
+
return asset?.role === "image" || asset?.role === "svg" ? "image" : null;
|
|
3391
3394
|
}
|
|
3392
3395
|
function compareText(a, b) {
|
|
3393
3396
|
return a < b ? -1 : a > b ? 1 : 0;
|
|
@@ -4086,6 +4089,7 @@ const ANALYSIS_CACHE_BYTES = 33554432;
|
|
|
4086
4089
|
const MISSING_RETRY_MS = 1e3;
|
|
4087
4090
|
const MISSING_RETRY_INTERVAL_MS = 100;
|
|
4088
4091
|
function profileOf(format) {
|
|
4092
|
+
if (format === "image") return "image-v1";
|
|
4089
4093
|
return format === "markdown" ? MARKDOWN_PARSER_PROFILE : HTML_STATIC_PARSER_PROFILE;
|
|
4090
4094
|
}
|
|
4091
4095
|
function toSummary(record, order, searchState = "excluded", pendingRequestIds = [], interactiveAllowed = false, repository = null) {
|
|
@@ -4290,6 +4294,20 @@ var DocumentService = class {
|
|
|
4290
4294
|
});
|
|
4291
4295
|
documentLogicalPath = fromRoot.split(sep).join("/");
|
|
4292
4296
|
}
|
|
4297
|
+
if (source.format === "image") {
|
|
4298
|
+
const type = assetTypeOf(documentLogicalPath);
|
|
4299
|
+
if (type?.role !== "image" && type?.role !== "svg") throw new VdeError("E_UNSUPPORTED_FORMAT", "The file extension is not an image format.");
|
|
4300
|
+
if (extraAssets.length > 0) throw new VdeError("E_INVALID_ARGUMENT", "--asset is not available for standalone images.");
|
|
4301
|
+
return {
|
|
4302
|
+
...source,
|
|
4303
|
+
assetsRoot,
|
|
4304
|
+
extraAssets: [],
|
|
4305
|
+
documentLogicalPath,
|
|
4306
|
+
assets: [],
|
|
4307
|
+
trackedFiles: [],
|
|
4308
|
+
assetScanFailed: false
|
|
4309
|
+
};
|
|
4310
|
+
}
|
|
4293
4311
|
let assetScanFailed = false;
|
|
4294
4312
|
const manifest = await buildManifest({
|
|
4295
4313
|
format: source.format,
|
|
@@ -4598,7 +4616,7 @@ var DocumentService = class {
|
|
|
4598
4616
|
for (const [canonicalPath, { candidate, format }] of resolved.unique) {
|
|
4599
4617
|
let loaded;
|
|
4600
4618
|
try {
|
|
4601
|
-
loaded = await this.#readSource(candidate.absolutePath);
|
|
4619
|
+
loaded = await this.#readSource(candidate.absolutePath, format);
|
|
4602
4620
|
} catch (error) {
|
|
4603
4621
|
if (!(error instanceof VdeError)) throw error;
|
|
4604
4622
|
problems.push({
|
|
@@ -4699,7 +4717,7 @@ var DocumentService = class {
|
|
|
4699
4717
|
sha256
|
|
4700
4718
|
}))
|
|
4701
4719
|
});
|
|
4702
|
-
const title = options.title ?? extractTitle(item.text, item.format) ?? item.fallbackTitle;
|
|
4720
|
+
const title = options.title ?? (item.format === "image" ? null : extractTitle(item.text, item.format)) ?? item.fallbackTitle;
|
|
4703
4721
|
const revisionRecord = {
|
|
4704
4722
|
revision,
|
|
4705
4723
|
format: item.format,
|
|
@@ -4869,6 +4887,10 @@ var DocumentService = class {
|
|
|
4869
4887
|
sectionId = payload["sectionId"];
|
|
4870
4888
|
}
|
|
4871
4889
|
const entry = this.#requireRevision(record, revision);
|
|
4890
|
+
if (entry.format === "image") throw new VdeError("E_UNSUPPORTED_FORMAT", "Images have no text source, outline, or sections.", {
|
|
4891
|
+
documentId: record.documentId,
|
|
4892
|
+
format: "image"
|
|
4893
|
+
});
|
|
4872
4894
|
if (mode === "outline") return this.#readOutline(record, entry, params.maxBytes, offset ?? 0);
|
|
4873
4895
|
if (mode === "section") return this.#readSection(record, entry, sectionId ?? "", params.maxBytes, offset ?? 0);
|
|
4874
4896
|
const source = await this.#store.readBlob(entry.sourceSha256);
|
|
@@ -5245,7 +5267,12 @@ var DocumentService = class {
|
|
|
5245
5267
|
let failure = "error";
|
|
5246
5268
|
const deadline = Date.now() + MISSING_RETRY_MS;
|
|
5247
5269
|
for (;;) try {
|
|
5248
|
-
|
|
5270
|
+
const format = this.#store.payload.documents[documentId]?.format;
|
|
5271
|
+
if (format === void 0) return {
|
|
5272
|
+
changed: false,
|
|
5273
|
+
signature: null
|
|
5274
|
+
};
|
|
5275
|
+
loaded = await this.#readSource(canonicalPath, format);
|
|
5249
5276
|
break;
|
|
5250
5277
|
} catch (error) {
|
|
5251
5278
|
if (!(error instanceof VdeError)) throw error;
|
|
@@ -5362,7 +5389,7 @@ var DocumentService = class {
|
|
|
5362
5389
|
if (isOpenPath(before, path) || rule.suppressedPaths.includes(path)) continue;
|
|
5363
5390
|
let loaded;
|
|
5364
5391
|
try {
|
|
5365
|
-
loaded = await this.#readSource(path);
|
|
5392
|
+
loaded = await this.#readSource(path, format);
|
|
5366
5393
|
} catch (error) {
|
|
5367
5394
|
if (error instanceof VdeError) continue;
|
|
5368
5395
|
throw error;
|
|
@@ -5825,6 +5852,7 @@ function createPdfService(options) {
|
|
|
5825
5852
|
const run = async (documentId, revision, signal) => {
|
|
5826
5853
|
const started = Date.now();
|
|
5827
5854
|
const { record, entry } = documents.describeRevision(documentId, revision);
|
|
5855
|
+
if (entry.format === "image") throw new VdeError("E_UNSUPPORTED_FORMAT", "PDF export is available for Markdown and HTML.");
|
|
5828
5856
|
const source = (await store.readBlob(entry.sourceSha256)).toString("utf8");
|
|
5829
5857
|
const slot = randomBytes(16).toString("hex");
|
|
5830
5858
|
let assets = entry.assets.filter((asset) => asset.role === "image" || asset.role === "svg");
|
|
@@ -6900,12 +6928,9 @@ function decodeUtf8(bytes) {
|
|
|
6900
6928
|
}
|
|
6901
6929
|
}
|
|
6902
6930
|
function createRenderService(options) {
|
|
6903
|
-
const { store, documents,
|
|
6931
|
+
const { store, documents, parse } = options;
|
|
6904
6932
|
const grants = /* @__PURE__ */ new Map();
|
|
6905
6933
|
const snapshots = /* @__PURE__ */ new Map();
|
|
6906
|
-
sessions.onAnyRevoke((sessionId) => {
|
|
6907
|
-
for (const [key, grant] of grants) if (grant.sessionId === sessionId) grants.delete(key);
|
|
6908
|
-
});
|
|
6909
6934
|
const snapshotOf = async (documentId, revision, mode = "static", withSdk = false) => {
|
|
6910
6935
|
const { record, entry } = documents.describeRevision(documentId, revision);
|
|
6911
6936
|
const cacheKey = `${entry.revision}\n${entry.documentLogicalPath}\n${mode}\n${String(withSdk)}`;
|
|
@@ -6919,6 +6944,28 @@ function createRenderService(options) {
|
|
|
6919
6944
|
snapshot: cached
|
|
6920
6945
|
};
|
|
6921
6946
|
}
|
|
6947
|
+
if (entry.format === "image") {
|
|
6948
|
+
const type = assetTypeOf(entry.documentLogicalPath);
|
|
6949
|
+
if (type?.role !== "image" && type?.role !== "svg") throw new VdeError("E_UNSUPPORTED_FORMAT", "The file extension is not an image format.");
|
|
6950
|
+
return {
|
|
6951
|
+
record,
|
|
6952
|
+
entry,
|
|
6953
|
+
snapshot: {
|
|
6954
|
+
format: "image",
|
|
6955
|
+
documentLogicalPath: entry.documentLogicalPath,
|
|
6956
|
+
hasDocument: true,
|
|
6957
|
+
files: /* @__PURE__ */ new Map([[entry.documentLogicalPath, {
|
|
6958
|
+
kind: "blob",
|
|
6959
|
+
sha256: entry.sourceSha256,
|
|
6960
|
+
...type
|
|
6961
|
+
}]]),
|
|
6962
|
+
assets: [],
|
|
6963
|
+
links: [],
|
|
6964
|
+
diagnostics: [],
|
|
6965
|
+
headingTargets: []
|
|
6966
|
+
}
|
|
6967
|
+
};
|
|
6968
|
+
}
|
|
6922
6969
|
const source = (await store.readBlob(entry.sourceSha256)).toString("utf8");
|
|
6923
6970
|
const stylesheets = [];
|
|
6924
6971
|
for (const asset of entry.assets) {
|
|
@@ -7004,14 +7051,13 @@ function createRenderService(options) {
|
|
|
7004
7051
|
const liveGrant = (key) => {
|
|
7005
7052
|
const grant = grants.get(key);
|
|
7006
7053
|
if (!grant) return null;
|
|
7007
|
-
|
|
7008
|
-
if (!sessions.isActiveId(grant.sessionId) || !record?.isOpen || documents.openEpoch(grant.documentId) !== grant.openEpoch || grant.mode === "interactive" && documents.interactiveGeneration(grant.documentId) !== grant.permission) {
|
|
7054
|
+
if (!documents.state.documents[grant.documentId]?.isOpen || documents.openEpoch(grant.documentId) !== grant.openEpoch || grant.mode === "interactive" && documents.interactiveGeneration(grant.documentId) !== grant.permission) {
|
|
7009
7055
|
grants.delete(key);
|
|
7010
7056
|
return null;
|
|
7011
7057
|
}
|
|
7012
7058
|
return grant;
|
|
7013
7059
|
};
|
|
7014
|
-
const issue = async (
|
|
7060
|
+
const issue = async (params, context) => {
|
|
7015
7061
|
const interactive = params.mode === "interactive";
|
|
7016
7062
|
const permissionOf = () => {
|
|
7017
7063
|
if (!interactive) return null;
|
|
@@ -7054,7 +7100,6 @@ function createRenderService(options) {
|
|
|
7054
7100
|
}
|
|
7055
7101
|
const key = randomBytes(32).toString("base64url");
|
|
7056
7102
|
grants.set(key, {
|
|
7057
|
-
sessionId,
|
|
7058
7103
|
documentId: record.documentId,
|
|
7059
7104
|
openEpoch,
|
|
7060
7105
|
revision: entry.revision,
|
|
@@ -7064,8 +7109,11 @@ function createRenderService(options) {
|
|
|
7064
7109
|
bridge,
|
|
7065
7110
|
missing: /* @__PURE__ */ new Set()
|
|
7066
7111
|
});
|
|
7067
|
-
|
|
7068
|
-
|
|
7112
|
+
while (grants.size > LIMITS.renderGrants) {
|
|
7113
|
+
const oldest = grants.keys().next().value;
|
|
7114
|
+
if (oldest === void 0) break;
|
|
7115
|
+
grants.delete(oldest);
|
|
7116
|
+
}
|
|
7069
7117
|
const filesBaseUrl = `${options.previewOrigin()}/r/${key}/files/`;
|
|
7070
7118
|
return {
|
|
7071
7119
|
grant: key,
|
|
@@ -7100,14 +7148,14 @@ function createRenderService(options) {
|
|
|
7100
7148
|
snapshots: snapshots.size
|
|
7101
7149
|
};
|
|
7102
7150
|
},
|
|
7103
|
-
async createGrant(
|
|
7151
|
+
async createGrant(rawParams, context) {
|
|
7104
7152
|
const params = renderGrantParamsSchema.parse(rawParams);
|
|
7105
|
-
return issue(
|
|
7153
|
+
return issue({
|
|
7106
7154
|
...params,
|
|
7107
7155
|
requestId: null
|
|
7108
7156
|
}, context);
|
|
7109
7157
|
},
|
|
7110
|
-
async createGrantForRequest(
|
|
7158
|
+
async createGrantForRequest(requestId, context) {
|
|
7111
7159
|
const request = Object.hasOwn(store.payload.feedbackRequests, requestId) ? store.payload.feedbackRequests[requestId] : void 0;
|
|
7112
7160
|
if (!request) throw new VdeError("E_REQUEST_NOT_FOUND", "The question was not found.", { requestId });
|
|
7113
7161
|
if (request.status !== "pending") throw new VdeError("E_REQUEST_NOT_PENDING", "The question is not pending.", {
|
|
@@ -7115,16 +7163,16 @@ function createRenderService(options) {
|
|
|
7115
7163
|
status: request.status
|
|
7116
7164
|
});
|
|
7117
7165
|
const interactive = request.renderMode === "interactive" && documents.interactiveAllowed(request.documentId);
|
|
7118
|
-
return issue(
|
|
7166
|
+
return issue({
|
|
7119
7167
|
documentId: request.documentId,
|
|
7120
7168
|
revision: request.revision,
|
|
7121
7169
|
mode: interactive ? "interactive" : "static",
|
|
7122
7170
|
requestId: interactive ? request.requestId : null
|
|
7123
7171
|
}, context);
|
|
7124
7172
|
},
|
|
7125
|
-
bridgeOf(
|
|
7173
|
+
bridgeOf(key) {
|
|
7126
7174
|
const grant = liveGrant(key);
|
|
7127
|
-
if (!grant?.bridge
|
|
7175
|
+
if (!grant?.bridge) return null;
|
|
7128
7176
|
if (store.payload.feedbackRequests[grant.bridge.requestId]?.status !== "pending") return null;
|
|
7129
7177
|
return {
|
|
7130
7178
|
requestId: grant.bridge.requestId,
|
|
@@ -7132,9 +7180,9 @@ function createRenderService(options) {
|
|
|
7132
7180
|
revision: grant.revision
|
|
7133
7181
|
};
|
|
7134
7182
|
},
|
|
7135
|
-
release(
|
|
7183
|
+
release(keys) {
|
|
7136
7184
|
let released = 0;
|
|
7137
|
-
for (const key of keys) if (grants.
|
|
7185
|
+
for (const key of keys) if (grants.delete(key)) released += 1;
|
|
7138
7186
|
return released;
|
|
7139
7187
|
},
|
|
7140
7188
|
async resolve(key, logicalPath) {
|
|
@@ -7162,9 +7210,9 @@ function createRenderService(options) {
|
|
|
7162
7210
|
mode: grant.mode
|
|
7163
7211
|
};
|
|
7164
7212
|
},
|
|
7165
|
-
missingOf(
|
|
7213
|
+
missingOf(key) {
|
|
7166
7214
|
const grant = liveGrant(key);
|
|
7167
|
-
if (!grant
|
|
7215
|
+
if (!grant) return [];
|
|
7168
7216
|
return [...grant.missing];
|
|
7169
7217
|
},
|
|
7170
7218
|
pruneClosed() {
|
|
@@ -7471,7 +7519,7 @@ function createSearchService(options) {
|
|
|
7471
7519
|
if (indexed.get(documentId) === attempt) indexed.delete(documentId);
|
|
7472
7520
|
};
|
|
7473
7521
|
try {
|
|
7474
|
-
const text = (await store.readBlob(entry.sourceSha256)).toString("utf8");
|
|
7522
|
+
const text = entry.format === "image" ? "" : (await store.readBlob(entry.sourceSha256)).toString("utf8");
|
|
7475
7523
|
const { sections } = await analyzeOnce(entry.format, text);
|
|
7476
7524
|
if (!current()) {
|
|
7477
7525
|
await giveUp(false);
|
|
@@ -11016,7 +11064,7 @@ function createEventQueue(options) {
|
|
|
11016
11064
|
if (pending === 0) progressAt = now();
|
|
11017
11065
|
pending += 1;
|
|
11018
11066
|
writes = writes.then(() => {
|
|
11019
|
-
if (stopped
|
|
11067
|
+
if (stopped) return void 0;
|
|
11020
11068
|
return write();
|
|
11021
11069
|
}).then(() => {
|
|
11022
11070
|
progressAt = now();
|
|
@@ -11216,27 +11264,9 @@ async function startManagementServer(deps, options = {}) {
|
|
|
11216
11264
|
if (Number(c.req.header("content-length") ?? "0") > 0 && !(c.req.header("content-type") ?? "").startsWith("application/json")) return fail(c, new VdeError("E_INVALID_ARGUMENT", "The body must be sent as JSON."));
|
|
11217
11265
|
}
|
|
11218
11266
|
if (deps.isStopping()) return fail(c, new VdeError("E_DAEMON_STOPPING", "The daemon is stopping."));
|
|
11219
|
-
if (c.req.path === `${API_PREFIX}/sessions/bootstrap` && method === "POST") return next();
|
|
11220
|
-
const authorization = c.req.header("authorization") ?? "";
|
|
11221
|
-
const token = authorization.startsWith("Bearer ") ? authorization.slice(7) : "";
|
|
11222
|
-
if (token === "" || !deps.sessions.authenticate(token)) return fail(c, new VdeError("E_UNAUTHORIZED", "Authentication is required. Open again from the CLI."));
|
|
11223
|
-
c.set("token", token);
|
|
11224
11267
|
return next();
|
|
11225
11268
|
});
|
|
11226
11269
|
const api = new Hono();
|
|
11227
|
-
api.post("/sessions/bootstrap", async (c) => {
|
|
11228
|
-
const body = strictObject({ ticket: string().min(1).max(256) }).parse(await c.req.json());
|
|
11229
|
-
const token = deps.sessions.exchange(body.ticket);
|
|
11230
|
-
if (!token) return fail(c, new VdeError("E_UNAUTHORIZED", "This URL has already been used or has expired."));
|
|
11231
|
-
return c.json(successEnvelope({
|
|
11232
|
-
token,
|
|
11233
|
-
idleTimeoutSeconds: LIMITS.sessionIdleMs / 1e3
|
|
11234
|
-
}, { command: "sessions.bootstrap" }));
|
|
11235
|
-
});
|
|
11236
|
-
api.delete("/session", (c) => {
|
|
11237
|
-
deps.sessions.revoke(c.get("token"));
|
|
11238
|
-
return c.json(successEnvelope({ revoked: true }, { command: "session.delete" }));
|
|
11239
|
-
});
|
|
11240
11270
|
api.get("/status", (c) => {
|
|
11241
11271
|
const state = deps.documents.state;
|
|
11242
11272
|
const status = {
|
|
@@ -11322,28 +11352,27 @@ async function startManagementServer(deps, options = {}) {
|
|
|
11322
11352
|
});
|
|
11323
11353
|
api.post("/feedback/:id/render-grants", async (c) => {
|
|
11324
11354
|
const requestId = requestIdSchema.parse(c.req.param("id"));
|
|
11325
|
-
const result = await deps.render.createGrantForRequest(
|
|
11355
|
+
const result = await deps.render.createGrantForRequest(requestId, { origin: c.req.header("origin") ?? origin });
|
|
11326
11356
|
return c.json(successEnvelope(result, {
|
|
11327
11357
|
command: "feedback.render-grant",
|
|
11328
11358
|
catalogVersion: deps.documents.state.catalogVersion
|
|
11329
11359
|
}));
|
|
11330
11360
|
});
|
|
11331
|
-
const bridgeOf = (
|
|
11332
|
-
const found = typeof grant === "string" ? deps.render.bridgeOf(
|
|
11361
|
+
const bridgeOf = (grant) => {
|
|
11362
|
+
const found = typeof grant === "string" ? deps.render.bridgeOf(grant) : null;
|
|
11333
11363
|
if (!found) throw new VdeError("E_RENDER_GRANT_INVALID", "The render grant has expired, so draft answers from the HTML are not accepted.");
|
|
11334
11364
|
return found;
|
|
11335
11365
|
};
|
|
11336
11366
|
api.post("/render-grants/bridge/ready", async (c) => {
|
|
11337
11367
|
const body = strictObject({ grant: string().min(1).max(128) }).parse(await c.req.json());
|
|
11338
|
-
const { requestId } = bridgeOf(
|
|
11368
|
+
const { requestId } = bridgeOf(body.grant);
|
|
11339
11369
|
return ok(c, "render-grants.bridge-ready", deps.feedback.getForUi(requestId));
|
|
11340
11370
|
});
|
|
11341
11371
|
api.put("/render-grants/bridge/draft", async (c) => {
|
|
11342
11372
|
const { grant, ...draft } = parseAnswersBody(await c.req.text());
|
|
11343
|
-
const
|
|
11344
|
-
const { requestId } = bridgeOf(token, grant);
|
|
11373
|
+
const { requestId } = bridgeOf(grant);
|
|
11345
11374
|
return ok(c, "render-grants.bridge-draft", await deps.feedback.updateDraft(requestId, draft, { authorize: () => {
|
|
11346
|
-
if (bridgeOf(
|
|
11375
|
+
if (bridgeOf(grant).requestId !== requestId) throw new VdeError("E_RENDER_GRANT_INVALID", "The render grant has changed.");
|
|
11347
11376
|
} }));
|
|
11348
11377
|
});
|
|
11349
11378
|
api.post("/feedback/:id/submit", async (c) => ok(c, "feedback.submit", await deps.feedback.submit(requestIdSchema.parse(c.req.param("id")), await c.req.json())));
|
|
@@ -11356,7 +11385,7 @@ async function startManagementServer(deps, options = {}) {
|
|
|
11356
11385
|
revision: string().optional(),
|
|
11357
11386
|
mode: string().optional()
|
|
11358
11387
|
}).parse(await c.req.json());
|
|
11359
|
-
const result = await deps.render.createGrant(
|
|
11388
|
+
const result = await deps.render.createGrant({
|
|
11360
11389
|
documentId: c.req.param("id"),
|
|
11361
11390
|
...body
|
|
11362
11391
|
}, { origin: c.req.header("origin") ?? origin });
|
|
@@ -11367,7 +11396,7 @@ async function startManagementServer(deps, options = {}) {
|
|
|
11367
11396
|
});
|
|
11368
11397
|
api.post("/render-grants/missing", async (c) => {
|
|
11369
11398
|
const body = strictObject({ grant: string().min(1).max(128) }).parse(await c.req.json());
|
|
11370
|
-
const missing = deps.render.missingOf(
|
|
11399
|
+
const missing = deps.render.missingOf(body.grant);
|
|
11371
11400
|
return c.json(successEnvelope({ missing }, { command: "render-grants.missing" }));
|
|
11372
11401
|
});
|
|
11373
11402
|
api.post("/documents/:id/html-mode", async (c) => {
|
|
@@ -11379,7 +11408,7 @@ async function startManagementServer(deps, options = {}) {
|
|
|
11379
11408
|
});
|
|
11380
11409
|
api.post("/render-grants/release", async (c) => {
|
|
11381
11410
|
const body = strictObject({ grants: array(string().min(1).max(128)).max(256) }).parse(await c.req.json());
|
|
11382
|
-
const released = deps.render.release(
|
|
11411
|
+
const released = deps.render.release(body.grants);
|
|
11383
11412
|
return c.json(successEnvelope({ released }, { command: "render-grants.release" }));
|
|
11384
11413
|
});
|
|
11385
11414
|
api.post("/documents/:id/links/:linkId/open", async (c) => {
|
|
@@ -11408,7 +11437,6 @@ async function startManagementServer(deps, options = {}) {
|
|
|
11408
11437
|
closed = true;
|
|
11409
11438
|
wake();
|
|
11410
11439
|
};
|
|
11411
|
-
const token = c.get("token");
|
|
11412
11440
|
const queue = createEventQueue({
|
|
11413
11441
|
writeEvent: (event) => stream.writeSSE({
|
|
11414
11442
|
event: event.type,
|
|
@@ -11416,11 +11444,6 @@ async function startManagementServer(deps, options = {}) {
|
|
|
11416
11444
|
data: JSON.stringify(event)
|
|
11417
11445
|
}),
|
|
11418
11446
|
writeHeartbeat: () => stream.write(": heartbeat\n\n"),
|
|
11419
|
-
beforeWrite: () => {
|
|
11420
|
-
if (deps.sessions.isActive(token)) return true;
|
|
11421
|
-
drop();
|
|
11422
|
-
return false;
|
|
11423
|
-
},
|
|
11424
11447
|
onError: finish
|
|
11425
11448
|
});
|
|
11426
11449
|
const drop = () => {
|
|
@@ -11431,7 +11454,6 @@ async function startManagementServer(deps, options = {}) {
|
|
|
11431
11454
|
};
|
|
11432
11455
|
streams.set(finish, queue);
|
|
11433
11456
|
stream.onAbort(finish);
|
|
11434
|
-
const stopWatchingSession = deps.sessions.onRevoke(token, drop);
|
|
11435
11457
|
const send = (event) => {
|
|
11436
11458
|
if (!closed) queue.send(event);
|
|
11437
11459
|
};
|
|
@@ -11443,10 +11465,6 @@ async function startManagementServer(deps, options = {}) {
|
|
|
11443
11465
|
});
|
|
11444
11466
|
const unsubscribe = deps.events.subscribe(send);
|
|
11445
11467
|
const heartbeat = setInterval(() => {
|
|
11446
|
-
if (!deps.sessions.isActive(token)) {
|
|
11447
|
-
drop();
|
|
11448
|
-
return;
|
|
11449
|
-
}
|
|
11450
11468
|
if (queue.stalledFor() >= (deps.stallMs ?? LIMITS.sseStallMs)) {
|
|
11451
11469
|
drop();
|
|
11452
11470
|
return;
|
|
@@ -11457,7 +11475,6 @@ async function startManagementServer(deps, options = {}) {
|
|
|
11457
11475
|
await done;
|
|
11458
11476
|
} finally {
|
|
11459
11477
|
clearInterval(heartbeat);
|
|
11460
|
-
stopWatchingSession();
|
|
11461
11478
|
unsubscribe();
|
|
11462
11479
|
await queue.settled();
|
|
11463
11480
|
streams.delete(finish);
|
|
@@ -11864,99 +11881,6 @@ async function startIpcServer(options) {
|
|
|
11864
11881
|
};
|
|
11865
11882
|
}
|
|
11866
11883
|
//#endregion
|
|
11867
|
-
//#region src/server/session-service.ts
|
|
11868
|
-
function digest(secret) {
|
|
11869
|
-
return createHash("sha256").update(secret).digest("hex");
|
|
11870
|
-
}
|
|
11871
|
-
function newSecret() {
|
|
11872
|
-
return randomBytes(32).toString("base64url");
|
|
11873
|
-
}
|
|
11874
|
-
function createSessionService(now = Date.now) {
|
|
11875
|
-
const tickets = /* @__PURE__ */ new Map();
|
|
11876
|
-
const sessions = /* @__PURE__ */ new Map();
|
|
11877
|
-
const revokeListeners = /* @__PURE__ */ new Map();
|
|
11878
|
-
const anyRevokeListeners = /* @__PURE__ */ new Set();
|
|
11879
|
-
const drop = (key) => {
|
|
11880
|
-
if (!sessions.delete(key)) return;
|
|
11881
|
-
const listeners = revokeListeners.get(key);
|
|
11882
|
-
revokeListeners.delete(key);
|
|
11883
|
-
if (listeners) for (const listener of listeners) listener();
|
|
11884
|
-
for (const listener of anyRevokeListeners) listener(key);
|
|
11885
|
-
};
|
|
11886
|
-
const isActiveKey = (key) => {
|
|
11887
|
-
const lastUsedAt = sessions.get(key);
|
|
11888
|
-
if (lastUsedAt === void 0) return false;
|
|
11889
|
-
if (lastUsedAt + LIMITS.sessionIdleMs < now()) {
|
|
11890
|
-
drop(key);
|
|
11891
|
-
return false;
|
|
11892
|
-
}
|
|
11893
|
-
return true;
|
|
11894
|
-
};
|
|
11895
|
-
const sweep = () => {
|
|
11896
|
-
const current = now();
|
|
11897
|
-
for (const [key, expiresAt] of tickets) if (expiresAt < current) tickets.delete(key);
|
|
11898
|
-
for (const [key, lastUsedAt] of sessions) if (lastUsedAt + LIMITS.sessionIdleMs < current) drop(key);
|
|
11899
|
-
};
|
|
11900
|
-
return {
|
|
11901
|
-
retainedCounts() {
|
|
11902
|
-
let listeners = 0;
|
|
11903
|
-
for (const set of revokeListeners.values()) listeners += set.size;
|
|
11904
|
-
return {
|
|
11905
|
-
tickets: tickets.size,
|
|
11906
|
-
sessions: sessions.size,
|
|
11907
|
-
revokeListeners: listeners,
|
|
11908
|
-
anyRevokeListeners: anyRevokeListeners.size
|
|
11909
|
-
};
|
|
11910
|
-
},
|
|
11911
|
-
createBootstrapTicket() {
|
|
11912
|
-
sweep();
|
|
11913
|
-
const ticket = newSecret();
|
|
11914
|
-
tickets.set(digest(ticket), now() + LIMITS.bootstrapTicketTtlMs);
|
|
11915
|
-
return ticket;
|
|
11916
|
-
},
|
|
11917
|
-
exchange(ticket) {
|
|
11918
|
-
sweep();
|
|
11919
|
-
const key = digest(ticket);
|
|
11920
|
-
const expiresAt = tickets.get(key);
|
|
11921
|
-
tickets.delete(key);
|
|
11922
|
-
if (expiresAt === void 0 || expiresAt < now()) return null;
|
|
11923
|
-
const token = newSecret();
|
|
11924
|
-
sessions.set(digest(token), now());
|
|
11925
|
-
return token;
|
|
11926
|
-
},
|
|
11927
|
-
authenticate(token) {
|
|
11928
|
-
const key = digest(token);
|
|
11929
|
-
const lastUsedAt = sessions.get(key);
|
|
11930
|
-
if (lastUsedAt === void 0) return false;
|
|
11931
|
-
if (lastUsedAt + LIMITS.sessionIdleMs < now()) {
|
|
11932
|
-
drop(key);
|
|
11933
|
-
return false;
|
|
11934
|
-
}
|
|
11935
|
-
sessions.set(key, now());
|
|
11936
|
-
return true;
|
|
11937
|
-
},
|
|
11938
|
-
isActive: (token) => isActiveKey(digest(token)),
|
|
11939
|
-
idOf: digest,
|
|
11940
|
-
isActiveId: isActiveKey,
|
|
11941
|
-
onAnyRevoke(listener) {
|
|
11942
|
-
anyRevokeListeners.add(listener);
|
|
11943
|
-
},
|
|
11944
|
-
revoke(token) {
|
|
11945
|
-
drop(digest(token));
|
|
11946
|
-
},
|
|
11947
|
-
onRevoke(token, listener) {
|
|
11948
|
-
const key = digest(token);
|
|
11949
|
-
const listeners = revokeListeners.get(key) ?? /* @__PURE__ */ new Set();
|
|
11950
|
-
revokeListeners.set(key, listeners);
|
|
11951
|
-
listeners.add(listener);
|
|
11952
|
-
return () => {
|
|
11953
|
-
listeners.delete(listener);
|
|
11954
|
-
if (listeners.size === 0 && revokeListeners.get(key) === listeners) revokeListeners.delete(key);
|
|
11955
|
-
};
|
|
11956
|
-
}
|
|
11957
|
-
};
|
|
11958
|
-
}
|
|
11959
|
-
//#endregion
|
|
11960
11884
|
//#region ../../node_modules/.pnpm/readdirp@5.1.1/node_modules/readdirp/index.js
|
|
11961
11885
|
const EntryTypes = {
|
|
11962
11886
|
FILE_TYPE: "files",
|
|
@@ -14342,7 +14266,6 @@ async function startDaemon(options) {
|
|
|
14342
14266
|
emit
|
|
14343
14267
|
});
|
|
14344
14268
|
const answering = feedback;
|
|
14345
|
-
const sessions = createSessionService();
|
|
14346
14269
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
14347
14270
|
const devOrigin = isSourceRun ? environment.env["VDE_OPEN_DEV_UI_ORIGIN"] ?? null : null;
|
|
14348
14271
|
let managementOrigin = null;
|
|
@@ -14350,7 +14273,6 @@ async function startDaemon(options) {
|
|
|
14350
14273
|
const render = createRenderService({
|
|
14351
14274
|
store: openedStore,
|
|
14352
14275
|
documents,
|
|
14353
|
-
sessions,
|
|
14354
14276
|
parse: parser,
|
|
14355
14277
|
previewOrigin: () => previewOrigin,
|
|
14356
14278
|
onMissing: (documentId) => emit({
|
|
@@ -14379,7 +14301,6 @@ async function startDaemon(options) {
|
|
|
14379
14301
|
daemonId,
|
|
14380
14302
|
version,
|
|
14381
14303
|
documents,
|
|
14382
|
-
sessions,
|
|
14383
14304
|
events,
|
|
14384
14305
|
render,
|
|
14385
14306
|
search: searching,
|
|
@@ -14441,8 +14362,7 @@ async function startDaemon(options) {
|
|
|
14441
14362
|
documents: documents.retainedCounts(),
|
|
14442
14363
|
search: search?.retainedCounts() ?? {},
|
|
14443
14364
|
render: render.retainedCounts(),
|
|
14444
|
-
feedback: answering.retainedCounts()
|
|
14445
|
-
sessions: sessions.retainedCounts()
|
|
14365
|
+
feedback: answering.retainedCounts()
|
|
14446
14366
|
},
|
|
14447
14367
|
workers,
|
|
14448
14368
|
activeResources,
|
|
@@ -14486,11 +14406,7 @@ async function startDaemon(options) {
|
|
|
14486
14406
|
const result = await documents.removeWatchRule(params);
|
|
14487
14407
|
watching.sync();
|
|
14488
14408
|
return result;
|
|
14489
|
-
}
|
|
14490
|
-
"ui.bootstrap": () => ({ data: {
|
|
14491
|
-
bootstrapUrl: `${uiUrl}#bootstrap=${sessions.createBootstrapTicket()}`,
|
|
14492
|
-
uiUrl
|
|
14493
|
-
} })
|
|
14409
|
+
}
|
|
14494
14410
|
};
|
|
14495
14411
|
ipc = await startIpcServer({
|
|
14496
14412
|
socketPath: location.socketPath,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as escapeAttr, D as defaultTreeAdapter, E as serialize, M as footnoteReferenceId, O as NS, T as parseFragment, c as renderedLinkOf, h as parseMarkdownDocument, i as transformStaticHtml, j as escapeHtml$2, k as parseMarkdown, l as MARKDOWN_PARSE_OPTIONS, n as resolveAssetUrl, o as transformCss, s as localImagePath, t as DiagnosticLog, w as parse, y as dirnameOfLogicalPath } from "./html-static-
|
|
1
|
+
import { A as escapeAttr, D as defaultTreeAdapter, E as serialize, M as footnoteReferenceId, O as NS, T as parseFragment, c as renderedLinkOf, h as parseMarkdownDocument, i as transformStaticHtml, j as escapeHtml$2, k as parseMarkdown, l as MARKDOWN_PARSE_OPTIONS, n as resolveAssetUrl, o as transformCss, s as localImagePath, t as DiagnosticLog, w as parse, y as dirnameOfLogicalPath } from "./html-static-C_wwQAJx.js";
|
|
2
2
|
//#region ../../node_modules/.pnpm/@tanstack+markdown@1.0.0_react@19.3.0/node_modules/@tanstack/markdown/dist/html.js
|
|
3
3
|
function renderHtml(input, options = {}) {
|
|
4
4
|
return (typeof input === "string" ? parseMarkdown(input, options) : input).children.map((node) => renderBlock(node, options)).join("\n");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as classifyLink, a as scanCssReferences, f as assertWithinLimits, i as transformStaticHtml, k as parseMarkdown, l as MARKDOWN_PARSE_OPTIONS, m as markdownUrlTransform, n as resolveAssetUrl, o as transformCss, p as inlineText$1, r as scanHtmlReferences, t as DiagnosticLog, w as parse, y as dirnameOfLogicalPath } from "./html-static-
|
|
1
|
+
import { _ as classifyLink, a as scanCssReferences, f as assertWithinLimits, i as transformStaticHtml, k as parseMarkdown, l as MARKDOWN_PARSE_OPTIONS, m as markdownUrlTransform, n as resolveAssetUrl, o as transformCss, p as inlineText$1, r as scanHtmlReferences, t as DiagnosticLog, w as parse, y as dirnameOfLogicalPath } from "./html-static-C_wwQAJx.js";
|
|
2
2
|
//#region ../../packages/document/src/title.ts
|
|
3
3
|
const TITLE_SCAN_CHARS = 65536;
|
|
4
4
|
const MAX_TITLE_LENGTH = 160;
|
|
@@ -5601,8 +5601,6 @@ const LIMITS = {
|
|
|
5601
5601
|
printRenderTimeoutMs: 1e4,
|
|
5602
5602
|
pdfExportTimeoutMs: 6e4,
|
|
5603
5603
|
watchDebounceMs: 200,
|
|
5604
|
-
bootstrapTicketTtlMs: 6e4,
|
|
5605
|
-
sessionIdleMs: 432e5,
|
|
5606
5604
|
sseHeartbeatMs: 15e3,
|
|
5607
5605
|
ssePendingEvents: 256,
|
|
5608
5606
|
sseStallMs: 6e4,
|
|
@@ -5610,7 +5608,7 @@ const LIMITS = {
|
|
|
5610
5608
|
documentAssetBytes: 100 * MiB,
|
|
5611
5609
|
documentAssets: 500,
|
|
5612
5610
|
cssReferenceDepth: 8,
|
|
5613
|
-
|
|
5611
|
+
renderGrants: 64,
|
|
5614
5612
|
searchLimitDefault: 5,
|
|
5615
5613
|
searchLimitMax: 50,
|
|
5616
5614
|
searchQueryCodePoints: 512,
|
|
@@ -5634,7 +5632,11 @@ const LIMITS = {
|
|
|
5634
5632
|
const documentIdSchema = string().regex(/^doc_[0-9a-f-]{36}$/);
|
|
5635
5633
|
const revisionSchema = string().regex(/^rev_[0-9a-f]{64}$/);
|
|
5636
5634
|
const sha256Schema = string().regex(/^[0-9a-f]{64}$/);
|
|
5637
|
-
const documentFormatSchema = _enum([
|
|
5635
|
+
const documentFormatSchema = _enum([
|
|
5636
|
+
"markdown",
|
|
5637
|
+
"html",
|
|
5638
|
+
"image"
|
|
5639
|
+
]);
|
|
5638
5640
|
const sourceKindSchema = _enum([
|
|
5639
5641
|
"file",
|
|
5640
5642
|
"stdin",
|
|
@@ -5876,14 +5878,6 @@ strictObject({
|
|
|
5876
5878
|
openDocuments: number().int().nonnegative(),
|
|
5877
5879
|
previewOrigin: string()
|
|
5878
5880
|
});
|
|
5879
|
-
strictObject({
|
|
5880
|
-
bootstrapUrl: string(),
|
|
5881
|
-
uiUrl: string()
|
|
5882
|
-
});
|
|
5883
|
-
strictObject({
|
|
5884
|
-
token: string(),
|
|
5885
|
-
idleTimeoutSeconds: number().int().positive()
|
|
5886
|
-
});
|
|
5887
5881
|
const renderGrantParamsSchema = strictObject({
|
|
5888
5882
|
documentId: documentIdSchema,
|
|
5889
5883
|
revision: revisionSchema.optional(),
|
|
@@ -5974,7 +5968,11 @@ const searchHitSchema = strictObject({
|
|
|
5974
5968
|
]),
|
|
5975
5969
|
score: number(),
|
|
5976
5970
|
sourceRange: sourceRangeSchema.nullable(),
|
|
5977
|
-
extraction: _enum([
|
|
5971
|
+
extraction: _enum([
|
|
5972
|
+
"markdown",
|
|
5973
|
+
"static-html",
|
|
5974
|
+
"image"
|
|
5975
|
+
])
|
|
5978
5976
|
});
|
|
5979
5977
|
strictObject({
|
|
5980
5978
|
query: string(),
|
|
@@ -8862,7 +8860,7 @@ var SearchIndex = class {
|
|
|
8862
8860
|
matchKind: kind,
|
|
8863
8861
|
score: Math.round(score * 1e3) / 1e3,
|
|
8864
8862
|
sourceRange: null,
|
|
8865
|
-
extraction: meta.format === "markdown" ? "markdown" : "static-html"
|
|
8863
|
+
extraction: meta.format === "image" ? "image" : meta.format === "markdown" ? "markdown" : "static-html"
|
|
8866
8864
|
});
|
|
8867
8865
|
}
|
|
8868
8866
|
return hits;
|