@markbrutx/promptbook-viewer 0.1.0 → 0.3.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/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/server/api.d.ts +4 -5
- package/dist/server/api.d.ts.map +1 -1
- package/dist/server/api.js +49 -12
- package/dist/server/api.js.map +1 -1
- package/dist/server/book-source.d.ts +24 -0
- package/dist/server/book-source.d.ts.map +1 -1
- package/dist/server/book-source.js +39 -0
- package/dist/server/book-source.js.map +1 -1
- package/dist/server/server.d.ts +1 -1
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +21 -8
- package/dist/server/server.js.map +1 -1
- package/dist/server/workspace.d.ts +13 -0
- package/dist/server/workspace.d.ts.map +1 -0
- package/dist/server/workspace.js +55 -0
- package/dist/server/workspace.js.map +1 -0
- package/dist/shared/types.d.ts +9 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/web/assets/index-BCBuW76o.css +1 -0
- package/dist/web/assets/index-BwIAKPNq.js +51 -0
- package/dist/web/favicon.png +0 -0
- package/dist/web/index.html +3 -2
- package/dist/web/promptbook-logo.png +0 -0
- package/package.json +19 -2
- package/src/index.ts +2 -0
- package/src/server/api.ts +57 -18
- package/src/server/book-source.ts +67 -0
- package/src/server/server.ts +22 -9
- package/src/server/workspace.ts +64 -0
- package/src/shared/types.ts +11 -0
- package/src/web/App.tsx +91 -28
- package/src/web/api.ts +26 -10
- package/src/web/components/Sidebar.tsx +37 -0
- package/src/web/index.html +1 -0
- package/src/web/public/favicon.png +0 -0
- package/src/web/public/promptbook-logo.png +0 -0
- package/src/web/styles.css +35 -0
- package/src/web/types.ts +2 -0
- package/dist/web/assets/index-B2Wxtb-f.css +0 -1
- package/dist/web/assets/index-C8f_6lr_.js +0 -51
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export type { AnnotateInput, AnnotationStore } from "./server/annotations.js";
|
|
|
2
2
|
export { createAnnotationStore } from "./server/annotations.js";
|
|
3
3
|
export type { Viewer, ViewerOptions } from "./server/server.js";
|
|
4
4
|
export { startViewer } from "./server/server.js";
|
|
5
|
-
export type { AnnotateRequest, Annotation, AnnotationsResponse, BookResponse, CompositionSummary, FragmentSummary, LintResponse, ResolveResponse, RuleSummary, Segment, UsedInReference, UsedInResponse, VariantSummary, } from "./shared/types.js";
|
|
5
|
+
export type { AnnotateRequest, Annotation, AnnotationsResponse, BookResponse, BooksResponse, CompositionSummary, FragmentSummary, LintResponse, ResolveResponse, RuleSummary, Segment, UsedInReference, UsedInResponse, VariantSummary, WorkspaceBook, } from "./shared/types.js";
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EACV,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,eAAe,EACf,WAAW,EACX,OAAO,EACP,eAAe,EACf,cAAc,EACd,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EACV,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,eAAe,EACf,WAAW,EACX,OAAO,EACP,eAAe,EACf,cAAc,EACd,cAAc,EACd,aAAa,GACd,MAAM,mBAAmB,CAAC"}
|
package/dist/server/api.d.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
-
import type {
|
|
2
|
+
import type { WorkspaceSource } from "./book-source.js";
|
|
3
3
|
export interface RequestHandlerOptions {
|
|
4
|
-
|
|
5
|
-
promptsDir: string;
|
|
4
|
+
workspace: WorkspaceSource;
|
|
6
5
|
/** Directory of the built web bundle (dist/web). */
|
|
7
6
|
webRoot: string;
|
|
8
7
|
}
|
|
9
8
|
/** A request handler plus the hook the folder watcher uses to push reloads. */
|
|
10
9
|
export interface RequestHandler {
|
|
11
10
|
handle(req: IncomingMessage, res: ServerResponse): void;
|
|
12
|
-
/** Invalidate
|
|
13
|
-
notifyReload(): void;
|
|
11
|
+
/** Invalidate a changed book (or all) and notify clients to refetch. */
|
|
12
|
+
notifyReload(book?: string): void;
|
|
14
13
|
}
|
|
15
14
|
export declare function createRequestHandler(options: RequestHandlerOptions): RequestHandler;
|
|
16
15
|
//# sourceMappingURL=api.d.ts.map
|
package/dist/server/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/server/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIjE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/server/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIjE,OAAO,KAAK,EAAgB,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAStE,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,eAAe,CAAC;IAC3B,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,CAAC;IACxD,wEAAwE;IACxE,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AA2DD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,cAAc,CAuHnF"}
|
package/dist/server/api.js
CHANGED
|
@@ -52,46 +52,82 @@ function asAnnotateRequest(body) {
|
|
|
52
52
|
}
|
|
53
53
|
return input;
|
|
54
54
|
}
|
|
55
|
+
const EMPTY_BOOK = { compositions: [], codePrompts: [], fragments: [], warnings: [] };
|
|
55
56
|
export function createRequestHandler(options) {
|
|
56
|
-
const {
|
|
57
|
+
const { workspace, webRoot } = options;
|
|
57
58
|
const sseClients = new Set();
|
|
58
|
-
const
|
|
59
|
+
const annotationStores = new Map();
|
|
60
|
+
/** Per-book annotation queue, keyed by directory; bookless roots write at root. */
|
|
61
|
+
const annotationsFor = async (bookName) => {
|
|
62
|
+
const resolved = await workspace.resolve(bookName);
|
|
63
|
+
const dir = resolved?.book.dir ?? workspace.root;
|
|
64
|
+
let store = annotationStores.get(dir);
|
|
65
|
+
if (store === undefined) {
|
|
66
|
+
store = createAnnotationStore(dir);
|
|
67
|
+
annotationStores.set(dir, store);
|
|
68
|
+
}
|
|
69
|
+
return store;
|
|
70
|
+
};
|
|
71
|
+
/** Resolve the active book or throw a 400-worthy error when the workspace is empty. */
|
|
72
|
+
const requireBook = async (bookName) => {
|
|
73
|
+
const resolved = await workspace.resolve(bookName);
|
|
74
|
+
if (resolved === undefined) {
|
|
75
|
+
throw new Error("no book found in the workspace");
|
|
76
|
+
}
|
|
77
|
+
return resolved;
|
|
78
|
+
};
|
|
59
79
|
const handle = async (req, res) => {
|
|
60
80
|
const url = new URL(req.url ?? "/", "http://localhost");
|
|
61
81
|
const path = url.pathname;
|
|
62
82
|
const method = req.method ?? "GET";
|
|
83
|
+
const bookName = url.searchParams.get("book") ?? undefined;
|
|
63
84
|
try {
|
|
85
|
+
if (path === "/api/books" && method === "GET") {
|
|
86
|
+
sendJson(res, 200, { books: await workspace.books() });
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
64
89
|
if (path === "/api/book" && method === "GET") {
|
|
65
|
-
|
|
90
|
+
const resolved = await workspace.resolve(bookName);
|
|
91
|
+
if (resolved === undefined) {
|
|
92
|
+
sendJson(res, 200, EMPTY_BOOK);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
sendJson(res, 200, buildBookResponse(resolved.folder, resolved.book.dir));
|
|
66
96
|
return;
|
|
67
97
|
}
|
|
68
98
|
if (path === "/api/resolve" && method === "POST") {
|
|
69
99
|
const { prompt, context } = asResolveRequest(await readJsonBody(req));
|
|
70
|
-
|
|
100
|
+
const { folder } = await requireBook(bookName);
|
|
101
|
+
sendJson(res, 200, buildResolveResponse(folder, prompt, context));
|
|
71
102
|
return;
|
|
72
103
|
}
|
|
73
104
|
if (path === "/api/lint" && method === "POST") {
|
|
74
105
|
const { prompt, context } = asResolveRequest(await readJsonBody(req));
|
|
75
|
-
|
|
106
|
+
const { folder } = await requireBook(bookName);
|
|
107
|
+
sendJson(res, 200, buildLintResponse(folder, prompt, context));
|
|
76
108
|
return;
|
|
77
109
|
}
|
|
78
110
|
if (path.startsWith("/api/used-in/") && method === "GET") {
|
|
79
111
|
const id = decodeURIComponent(path.slice("/api/used-in/".length));
|
|
80
|
-
|
|
112
|
+
const { folder } = await requireBook(bookName);
|
|
113
|
+
sendJson(res, 200, buildUsedInResponse(folder, id));
|
|
81
114
|
return;
|
|
82
115
|
}
|
|
83
116
|
if (path === "/api/annotate" && method === "POST") {
|
|
84
|
-
const
|
|
117
|
+
const store = await annotationsFor(bookName);
|
|
118
|
+
const annotation = await store.append(asAnnotateRequest(await readJsonBody(req)));
|
|
85
119
|
sendJson(res, 200, annotation);
|
|
86
120
|
return;
|
|
87
121
|
}
|
|
88
122
|
if (path === "/api/annotations" && method === "GET") {
|
|
89
|
-
|
|
123
|
+
const store = await annotationsFor(bookName);
|
|
124
|
+
sendJson(res, 200, { annotations: await store.list() });
|
|
90
125
|
return;
|
|
91
126
|
}
|
|
92
127
|
if (path.startsWith("/api/annotations/") && method === "DELETE") {
|
|
93
128
|
const id = decodeURIComponent(path.slice("/api/annotations/".length));
|
|
94
|
-
const
|
|
129
|
+
const store = await annotationsFor(bookName);
|
|
130
|
+
const removed = await store.remove(id);
|
|
95
131
|
sendJson(res, removed ? 200 : 404, { id, removed });
|
|
96
132
|
return;
|
|
97
133
|
}
|
|
@@ -123,10 +159,11 @@ export function createRequestHandler(options) {
|
|
|
123
159
|
handle(req, res) {
|
|
124
160
|
void handle(req, res);
|
|
125
161
|
},
|
|
126
|
-
notifyReload() {
|
|
127
|
-
|
|
162
|
+
notifyReload(book) {
|
|
163
|
+
workspace.invalidate(book);
|
|
164
|
+
const data = book !== undefined ? JSON.stringify({ book }) : "{}";
|
|
128
165
|
for (const client of sseClients) {
|
|
129
|
-
client.write(
|
|
166
|
+
client.write(`event: reload\ndata: ${data}\n\n`);
|
|
130
167
|
}
|
|
131
168
|
},
|
|
132
169
|
};
|
package/dist/server/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/server/api.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/server/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Fixture, FsAdapter, PromptBook } from "@markbrutx/promptbook-core";
|
|
2
|
+
import { type Book } from "./workspace.js";
|
|
2
3
|
/** A loaded prompts folder plus the fixtures that supply named variants. */
|
|
3
4
|
export interface LoadedFolder {
|
|
4
5
|
book: PromptBook;
|
|
@@ -17,4 +18,27 @@ export interface BookSource {
|
|
|
17
18
|
invalidate(): void;
|
|
18
19
|
}
|
|
19
20
|
export declare function createBookSource(promptsDir: string, fs?: FsAdapter): BookSource;
|
|
21
|
+
/** A book resolved for a request: its identity plus its loaded folder. */
|
|
22
|
+
export interface ResolvedBook {
|
|
23
|
+
book: Book;
|
|
24
|
+
folder: LoadedFolder;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Caches a {@link BookSource} per book across a whole workspace, discovering the
|
|
28
|
+
* books under the root lazily. One viewer serves every book through a single
|
|
29
|
+
* switcher: `books()` lists them, `resolve(name)` loads one (defaulting to the
|
|
30
|
+
* first), and `invalidate(name)` drops one book's cache while always re-scanning
|
|
31
|
+
* the book set (so a new folder appears without a restart).
|
|
32
|
+
*/
|
|
33
|
+
export interface WorkspaceSource {
|
|
34
|
+
/** Root the workspace was discovered from (annotation fallback when bookless). */
|
|
35
|
+
root: string;
|
|
36
|
+
/** Discovered books (name + dir), re-scanned after {@link invalidate}. */
|
|
37
|
+
books(): Promise<Book[]>;
|
|
38
|
+
/** Load a book by name, or the first book when the name is missing/unknown. */
|
|
39
|
+
resolve(name?: string): Promise<ResolvedBook | undefined>;
|
|
40
|
+
/** Drop one book's cache (or none) and re-scan the book set. */
|
|
41
|
+
invalidate(name?: string): void;
|
|
42
|
+
}
|
|
43
|
+
export declare function createWorkspaceSource(root: string, fs?: FsAdapter): WorkspaceSource;
|
|
20
44
|
//# sourceMappingURL=book-source.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"book-source.d.ts","sourceRoot":"","sources":["../../src/server/book-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"book-source.d.ts","sourceRoot":"","sources":["../../src/server/book-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAEjF,OAAO,EAAE,KAAK,IAAI,EAAsB,MAAM,gBAAgB,CAAC;AAE/D,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,sEAAsE;IACtE,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7B,oEAAoE;IACpE,UAAU,IAAI,IAAI,CAAC;CACpB;AAWD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,SAAS,GAAG,UAAU,CAsB/E;AAED,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzB,+EAA+E;IAC/E,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IAC1D,gEAAgE;IAChE,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,SAAS,GAAG,eAAe,CAwCnF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { loadFixtures, loadPrompts } from "@markbrutx/promptbook-core";
|
|
2
|
+
import { loadWorkspaceBooks } from "./workspace.js";
|
|
2
3
|
/** Fixtures are optional: a folder without a `fixtures/` dir simply has none. */
|
|
3
4
|
async function safeLoadFixtures(promptsDir, fs) {
|
|
4
5
|
try {
|
|
@@ -29,4 +30,42 @@ export function createBookSource(promptsDir, fs) {
|
|
|
29
30
|
},
|
|
30
31
|
};
|
|
31
32
|
}
|
|
33
|
+
export function createWorkspaceSource(root, fs) {
|
|
34
|
+
let bookList;
|
|
35
|
+
const sources = new Map();
|
|
36
|
+
const discover = () => {
|
|
37
|
+
if (bookList === undefined) {
|
|
38
|
+
bookList = loadWorkspaceBooks(root, fs);
|
|
39
|
+
}
|
|
40
|
+
return bookList;
|
|
41
|
+
};
|
|
42
|
+
const sourceFor = (book) => {
|
|
43
|
+
let source = sources.get(book.name);
|
|
44
|
+
if (source === undefined) {
|
|
45
|
+
source = createBookSource(book.dir, fs);
|
|
46
|
+
sources.set(book.name, source);
|
|
47
|
+
}
|
|
48
|
+
return source;
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
root,
|
|
52
|
+
books() {
|
|
53
|
+
return discover();
|
|
54
|
+
},
|
|
55
|
+
async resolve(name) {
|
|
56
|
+
const books = await discover();
|
|
57
|
+
if (books.length === 0) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
const book = books.find((b) => b.name === name) ?? books[0];
|
|
61
|
+
return { book, folder: await sourceFor(book).get() };
|
|
62
|
+
},
|
|
63
|
+
invalidate(name) {
|
|
64
|
+
bookList = undefined;
|
|
65
|
+
if (name !== undefined) {
|
|
66
|
+
sources.get(name)?.invalidate();
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
32
71
|
//# sourceMappingURL=book-source.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"book-source.js","sourceRoot":"","sources":["../../src/server/book-source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"book-source.js","sourceRoot":"","sources":["../../src/server/book-source.ts"],"names":[],"mappings":"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"}
|
package/dist/server/server.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FsAdapter } from "@markbrutx/promptbook-core";
|
|
2
2
|
export interface ViewerOptions {
|
|
3
|
-
/**
|
|
3
|
+
/** Workspace root (a single book, or a folder of sibling books). */
|
|
4
4
|
promptsDir: string;
|
|
5
5
|
/** Port to listen on; 0 (default) picks a free port. */
|
|
6
6
|
port?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAI5D,MAAM,WAAW,aAAa;IAC5B,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,6EAA6E;IAC7E,EAAE,CAAC,EAAE,SAAS,CAAC;CAChB;AAED,sEAAsE;AACtE,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAgDD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BzE"}
|
package/dist/server/server.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { watch } from "node:fs";
|
|
3
3
|
import { createServer } from "node:http";
|
|
4
|
+
import { sep } from "node:path";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
5
6
|
import { createRequestHandler } from "./api.js";
|
|
6
|
-
import {
|
|
7
|
+
import { createWorkspaceSource } from "./book-source.js";
|
|
7
8
|
/** Best-effort: open `url` in the OS default browser; never throws. */
|
|
8
9
|
function openBrowser(url) {
|
|
9
10
|
const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
@@ -20,15 +21,27 @@ function openBrowser(url) {
|
|
|
20
21
|
// opening a browser is a convenience, not a requirement
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
|
-
/**
|
|
24
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Watch the workspace root and call `onChange` (debounced) with the changed
|
|
26
|
+
* book. A change path's first segment names its top-level book; when several
|
|
27
|
+
* books or unknown paths change in one window, `undefined` is passed so the
|
|
28
|
+
* client refetches the active book regardless.
|
|
29
|
+
*/
|
|
30
|
+
function watchFolder(rootDir, onChange) {
|
|
25
31
|
try {
|
|
26
32
|
let timer;
|
|
27
|
-
|
|
33
|
+
let changed = new Set();
|
|
34
|
+
const watcher = watch(rootDir, { recursive: true }, (_event, filename) => {
|
|
35
|
+
const name = typeof filename === "string" && filename.length > 0 ? filename : undefined;
|
|
36
|
+
changed.add(name === undefined ? undefined : name.split(sep)[0]);
|
|
28
37
|
if (timer !== undefined) {
|
|
29
38
|
clearTimeout(timer);
|
|
30
39
|
}
|
|
31
|
-
timer = setTimeout(
|
|
40
|
+
timer = setTimeout(() => {
|
|
41
|
+
const books = [...changed];
|
|
42
|
+
changed = new Set();
|
|
43
|
+
onChange(books.length === 1 ? books[0] : undefined);
|
|
44
|
+
}, 50);
|
|
32
45
|
});
|
|
33
46
|
watcher.on("error", () => { });
|
|
34
47
|
return watcher;
|
|
@@ -45,8 +58,8 @@ function watchFolder(promptsDir, onChange) {
|
|
|
45
58
|
export async function startViewer(options) {
|
|
46
59
|
const { promptsDir, port = 0, open = false, fs } = options;
|
|
47
60
|
const webRoot = fileURLToPath(new URL("../web", import.meta.url));
|
|
48
|
-
const
|
|
49
|
-
const handler = createRequestHandler({
|
|
61
|
+
const workspace = createWorkspaceSource(promptsDir, fs);
|
|
62
|
+
const handler = createRequestHandler({ workspace, webRoot });
|
|
50
63
|
const server = createServer((req, res) => handler.handle(req, res));
|
|
51
64
|
await new Promise((resolve, reject) => {
|
|
52
65
|
server.once("error", reject);
|
|
@@ -55,7 +68,7 @@ export async function startViewer(options) {
|
|
|
55
68
|
const address = server.address();
|
|
56
69
|
const boundPort = typeof address === "object" && address !== null ? address.port : port;
|
|
57
70
|
const url = `http://localhost:${boundPort}`;
|
|
58
|
-
const watcher = watchFolder(promptsDir, () => handler.notifyReload());
|
|
71
|
+
const watcher = watchFolder(promptsDir, (book) => handler.notifyReload(book));
|
|
59
72
|
if (open) {
|
|
60
73
|
openBrowser(url);
|
|
61
74
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAkB,KAAK,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FsAdapter } from "@markbrutx/promptbook-core";
|
|
2
|
+
/** A discovered prompts book: its folder name and absolute directory. */
|
|
3
|
+
export interface Book {
|
|
4
|
+
name: string;
|
|
5
|
+
dir: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Read a workspace from `rootDir`. When the root is itself a book it is the only
|
|
9
|
+
* book (back-compat single-book view, named after the folder); otherwise the
|
|
10
|
+
* root is a workspace of its sub-books.
|
|
11
|
+
*/
|
|
12
|
+
export declare function loadWorkspaceBooks(rootDir: string, fs?: FsAdapter): Promise<Book[]>;
|
|
13
|
+
//# sourceMappingURL=workspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/server/workspace.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAG5D,yEAAyE;AACzE,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AA6CD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,GAAE,SAAoB,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAKnG"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { basename, join } from "node:path";
|
|
2
|
+
import { nodeFs } from "@markbrutx/promptbook-core";
|
|
3
|
+
/** Folder names that are book internals or noise, never workspace sub-books. */
|
|
4
|
+
const NON_BOOK_DIRS = new Set(["node_modules", "fragments", "rules", "code-prompts"]);
|
|
5
|
+
/** Markers that make a folder a loadable book (a config or a loadable form). */
|
|
6
|
+
const BOOK_MARKERS = ["promptbook.json", "rules", "code-prompts"];
|
|
7
|
+
/** True when `dir` looks like a prompts book (has a config or a loadable form). */
|
|
8
|
+
async function isBook(fs, dir) {
|
|
9
|
+
let entries;
|
|
10
|
+
try {
|
|
11
|
+
entries = await fs.readDir(dir);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return BOOK_MARKERS.some((marker) => entries.includes(marker));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Find the books directly under `rootDir`: each non-internal subfolder that is
|
|
20
|
+
* itself a book. One level deep, sorted by name. This mirrors the CLI's
|
|
21
|
+
* discovery (kept as a server-local copy so the viewer never depends on the
|
|
22
|
+
* CLI), so `view` and `ls --all` see the same workspace.
|
|
23
|
+
*/
|
|
24
|
+
async function discoverBooks(rootDir, fs = nodeFs()) {
|
|
25
|
+
let entries;
|
|
26
|
+
try {
|
|
27
|
+
entries = await fs.readDir(rootDir);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
const books = [];
|
|
33
|
+
for (const name of [...entries].sort()) {
|
|
34
|
+
if (name.startsWith(".") || name.startsWith("_") || NON_BOOK_DIRS.has(name)) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const dir = join(rootDir, name);
|
|
38
|
+
if (await isBook(fs, dir)) {
|
|
39
|
+
books.push({ name, dir });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return books;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Read a workspace from `rootDir`. When the root is itself a book it is the only
|
|
46
|
+
* book (back-compat single-book view, named after the folder); otherwise the
|
|
47
|
+
* root is a workspace of its sub-books.
|
|
48
|
+
*/
|
|
49
|
+
export async function loadWorkspaceBooks(rootDir, fs = nodeFs()) {
|
|
50
|
+
if (await isBook(fs, rootDir)) {
|
|
51
|
+
return [{ name: basename(rootDir), dir: rootDir }];
|
|
52
|
+
}
|
|
53
|
+
return discoverBooks(rootDir, fs);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/server/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAQpD,gFAAgF;AAChF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;AAEtF,gFAAgF;AAChF,MAAM,YAAY,GAAG,CAAC,iBAAiB,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;AAElE,mFAAmF;AACnF,KAAK,UAAU,MAAM,CAAC,EAAa,EAAE,GAAW;IAC9C,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,EAAE,GAAc,MAAM,EAAE;IACpE,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,KAAK,GAAW,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5E,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAChC,IAAI,MAAM,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAe,EAAE,EAAE,GAAc,MAAM,EAAE;IAChF,IAAI,MAAM,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC"}
|
package/dist/shared/types.d.ts
CHANGED
|
@@ -52,6 +52,15 @@ export interface CodePromptSummary {
|
|
|
52
52
|
samples: CodePromptSampleSummary[];
|
|
53
53
|
sourceFile: string;
|
|
54
54
|
}
|
|
55
|
+
/** One book in the workspace, as `GET /api/books` lists it. */
|
|
56
|
+
export interface WorkspaceBook {
|
|
57
|
+
name: string;
|
|
58
|
+
dir: string;
|
|
59
|
+
}
|
|
60
|
+
/** Response of `GET /api/books`: the switcher menu. */
|
|
61
|
+
export interface BooksResponse {
|
|
62
|
+
books: WorkspaceBook[];
|
|
63
|
+
}
|
|
55
64
|
/** Response of `GET /api/book`. */
|
|
56
65
|
export interface BookResponse {
|
|
57
66
|
compositions: CompositionSummary[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EACV,UAAU,EACV,OAAO,EACP,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,KAAK,EACL,IAAI,EACL,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,0EAA0E;AAC1E,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,oDAAoD;AACpD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED,0DAA0D;AAC1D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,kFAAkF;AAClF,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,mEAAmE;AACnE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,uBAAuB,EAAE,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,mCAAmC;AACnC,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,kBAAkB,EAAE,CAAC;IACnC,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,gFAAgF;AAChF,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,iEAAiE;AACjE,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,uCAAuC;AACvC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,oCAAoC;AACpC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,kFAAkF;AAClF,KAAK,UAAU,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAE5C,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,0CAA0C;AAC1C,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED,6CAA6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,0CAA0C;AAC1C,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--bg: #fff;--panel: #f6f8fa;--border: #e1e4e8;--text: #1f2328;--muted: #6e7781;--accent: #4f46e5;--warn: #b35900;font-family:system-ui,-apple-system,Segoe UI,sans-serif;font-size:14px;color:var(--text)}*{box-sizing:border-box}body{margin:0;background:var(--bg)}.layout{display:grid;grid-template-columns:260px minmax(0,1fr) 380px;height:100vh}.sidebar{border-right:1px solid var(--border);overflow-y:auto;padding:12px;background:var(--panel)}.sidebar-brand{display:flex;flex-direction:column;gap:10px;padding:4px 4px 12px;border-bottom:1px solid var(--border);margin-bottom:4px}.sidebar-logo{width:168px;max-width:80%;height:auto;display:block;margin:8px auto 4px}.book-switcher{display:flex;align-items:center;gap:6px}.book-switcher-label{font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted)}.sidebar-title{font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin:16px 0 6px}.tree{list-style:none;margin:0;padding-left:12px}.tree-folder,.tree-composition{cursor:pointer;font-weight:600;padding:2px 0}.tree-item,.link{display:inline-flex;align-items:center;gap:6px;width:100%;text-align:left;background:none;border:none;padding:3px 6px;border-radius:5px;color:var(--text);cursor:pointer;font:inherit}.tree-item:hover{background:#eaeef2}.tree-item.active{background:var(--accent);color:#fff}.link{width:auto;color:var(--accent);padding:0;text-decoration:underline}.swatch{width:10px;height:10px;border-radius:2px;flex:none}.canvas{overflow-y:auto;padding:20px 24px}.canvas-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:12px}.canvas-title{font-size:18px;margin:0;display:flex;align-items:center;gap:8px}.legend{list-style:none;display:flex;flex-wrap:wrap;gap:10px;padding:0;margin:0 0 14px;font-size:12px;color:var(--muted)}.legend li{display:inline-flex;align-items:center;gap:5px}.prompt{display:flex;flex-direction:column;gap:14px}.segment{position:relative;margin:0;padding:16px 12px 12px;border-radius:6px;border:1px solid var(--border);white-space:pre-wrap;word-break:break-word;font-family:ui-monospace,SF Mono,Menlo,monospace;font-size:13px;line-height:1.5}.segment-tag{position:absolute;top:0;right:0;font-size:10px;padding:1px 6px;background:#0000000f;border-bottom-left-radius:6px;font-family:system-ui,sans-serif;color:var(--muted)}.rail{border-left:1px solid var(--border);overflow-y:auto;padding:16px;background:var(--panel)}.rail section,.addons section{margin-bottom:18px}.rail h3,.addons h3{font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin:0 0 8px}.rail h4{margin:12px 0 4px;font-size:12px}select,input{width:100%;padding:4px 6px;border:1px solid var(--border);border-radius:5px;font:inherit;background:#fff}.book-switcher select{flex:1;width:auto}.control-row{display:grid;grid-template-columns:90px 1fr;align-items:center;gap:8px;margin-bottom:6px}.control-key{font-family:ui-monospace,monospace;font-size:12px;color:var(--muted)}.control-add{display:grid;grid-template-columns:1fr auto;gap:6px;margin-top:6px}.control-add button{border:1px solid var(--border);border-radius:5px;background:#fff;cursor:pointer;padding:0 10px}.rules,.findings,.warnings,.used-list{list-style:none;margin:0;padding:0}.rules li{padding:4px 0;border-bottom:1px solid var(--border);font-size:12px}.rules li.skipped{color:var(--muted)}.rule-mark{margin-right:6px}.rule-action{font-weight:600;margin-right:6px}.rule-effect{font-family:ui-monospace,monospace;margin-top:2px}.rule-reason{color:var(--muted);margin-top:2px}.order{font-family:ui-monospace,monospace;font-size:12px;word-break:break-word}.finding{display:flex;flex-wrap:wrap;gap:6px;align-items:baseline;padding:5px 0;border-bottom:1px solid var(--border);font-size:12px}.finding-sev{text-transform:uppercase;font-size:10px;font-weight:700;padding:1px 5px;border-radius:4px;background:#eaeef2}.finding.error .finding-sev{background:#ffd7d5;color:#a40e26}.finding.warning .finding-sev{background:#fff1c2;color:var(--warn)}.finding-rule{font-family:ui-monospace,monospace;color:var(--muted)}.diff-body{margin:8px 0 0;font-family:ui-monospace,monospace;font-size:12px;border:1px solid var(--border);border-radius:6px;overflow-x:auto;background:#fff}.diff-row{padding:0 8px;white-space:pre-wrap}.diff-row.add{background:#e6ffec}.diff-row.remove{background:#ffebe9}.diff-mark{display:inline-block;width:12px;color:var(--muted)}.annot-mark{background:#fff3b0;border-bottom:2px solid var(--warn);border-radius:2px;padding:0 1px}.annot-popover{position:fixed;z-index:20;width:280px;padding:10px;background:#fff;border:1px solid var(--border);border-radius:8px;box-shadow:0 8px 24px #00000029}.annot-popover textarea{width:100%;min-height:64px;resize:vertical;margin:6px 0}.annot-actions{display:flex;justify-content:flex-end;gap:10px;align-items:center}.annot-actions button[type=button]:last-child{border:1px solid var(--border);border-radius:5px;background:var(--accent);color:#fff;padding:4px 12px;cursor:pointer}.annot-actions button[disabled]{opacity:.5;cursor:default}.annot-quote{margin:0;font-style:italic;color:var(--muted);font-size:12px;word-break:break-word}.annot-list{list-style:none;margin:0;padding:0}.annot-list li{padding:8px 0;border-bottom:1px solid var(--border)}.annot-comment{margin:4px 0;font-size:13px;word-break:break-word}.annot-meta{display:flex;justify-content:space-between;align-items:center;gap:8px;font-size:12px}.badge{font-size:12px;padding:2px 8px;border-radius:999px;background:#eaeef2;white-space:nowrap}.badge-code{font-size:10px;text-transform:uppercase;letter-spacing:.06em;background:#2b2b40;color:#fff}.code-tabs{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}.code-tab{font:inherit;font-size:12px;padding:3px 10px;border-radius:999px;border:1px solid var(--border);background:var(--panel);color:var(--text);cursor:pointer}.code-tab.active{background:var(--accent);border-color:var(--accent)}.code-diff{margin-top:18px}.tokens{font-size:20px;font-weight:600;margin:0}.muted{color:var(--muted)}.warn{color:var(--warn)}.used-list li{padding:3px 0}
|