@cyber-dash-tech/revela 0.8.9 → 0.10.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.
@@ -0,0 +1,61 @@
1
+ import { existsSync } from "fs"
2
+ import { ACTIVE_PROMPT_FILE } from "../config"
3
+ import { ctx } from "../ctx"
4
+ import { seedBuiltinDesigns } from "../design/designs"
5
+ import { seedBuiltinDomains } from "../domain/domains"
6
+ import { ensureEditableDeckState } from "../edit/deck-state"
7
+ import { openUrl } from "../edit/open"
8
+ import { resolveEditableDeck, type EditableDeck } from "../edit/resolve-deck"
9
+ import { buildPrompt } from "../prompt-builder"
10
+ import { startInspectServer } from "./server"
11
+
12
+ export interface OpenInspectDeckResult {
13
+ deck: EditableDeck
14
+ url: string
15
+ source: string
16
+ stateNote: string
17
+ preflightChanged: boolean
18
+ reusedSession: boolean
19
+ openedBrowser: boolean
20
+ }
21
+
22
+ export interface OpenInspectDeckOptions {
23
+ client: any
24
+ sessionID: string
25
+ workspaceRoot: string
26
+ openBrowser?: boolean
27
+ openUrl?: (url: string) => void
28
+ }
29
+
30
+ export function openInspectDeck(target: string, options: OpenInspectDeckOptions): OpenInspectDeckResult {
31
+ const deck = resolveEditableDeck(options.workspaceRoot, target)
32
+ const preflight = ensureEditableDeckState(options.workspaceRoot, deck)
33
+
34
+ ctx.enabled = true
35
+ if (!existsSync(ACTIVE_PROMPT_FILE)) {
36
+ seedBuiltinDesigns()
37
+ seedBuiltinDomains()
38
+ buildPrompt()
39
+ }
40
+
41
+ const inspectServer = startInspectServer()
42
+ const session = inspectServer.getOrCreateSession({
43
+ client: options.client,
44
+ sessionID: options.sessionID,
45
+ workspaceRoot: options.workspaceRoot,
46
+ deck,
47
+ })
48
+ const url = `${inspectServer.baseUrl}/inspect?token=${encodeURIComponent(session.token)}`
49
+ const shouldOpen = options.openBrowser !== false
50
+ if (shouldOpen) (options.openUrl ?? openUrl)(url)
51
+
52
+ return {
53
+ deck,
54
+ url,
55
+ source: deck.source === "decks-state" ? "DECKS.json" : deck.source === "file-path" ? "file path" : "fallback path",
56
+ stateNote: preflight.changed ? "Deck state was prepared in DECKS.json for inspection." : "Deck state already points to this inspection target.",
57
+ preflightChanged: preflight.changed,
58
+ reusedSession: session.reused,
59
+ openedBrowser: shouldOpen,
60
+ }
61
+ }
@@ -0,0 +1,32 @@
1
+ import type { InspectionPromptProjection } from "../inspection-context/project"
2
+
3
+ export function buildInspectionPrompt(input: {
4
+ requestId: string
5
+ file: string
6
+ projection: InspectionPromptProjection
7
+ }): string {
8
+ return `A user selected slide content in Revela Evidence Inspector. The selection may contain one referenced element, a whole slide, or multiple referenced elements selected with Cmd/Ctrl-click.
9
+
10
+ Target file: ${input.file}
11
+ Inspection request id: ${input.requestId}
12
+
13
+ Use the structured projection below to produce the final inspector cards. This is LLM judgment with grounded boundaries: answer the selected object's purpose and source credibility only. Do not edit files. Do not mutate DECKS.json. Do not invent sources, quotes, URLs, page references, caveats, or evidence not present in the projection.
14
+
15
+ Return the result only by calling the \`revela-inspection-result\` tool with this request id. Do not answer in chat.
16
+
17
+ Required card model:
18
+ - Purpose: explain why this selected content appears here, what job it serves in the slide purpose, narrative role, deck goal, audience, or narrative brief, and why it matters.
19
+ - Source: if the selection contains a factual claim, number, comparison, conclusion, or recommendation, judge source credibility. Use not_needed for structural, transitional, or purely explanatory content that does not need evidence. Include source trace, warnings, gaps, and caveats here.
20
+
21
+ Boundaries:
22
+ - Do not hunt for problems. If it works, say it works.
23
+ - Do not recommend edits or fixes; this inspector view only explains purpose and source credibility.
24
+ - Do not turn every caveat into a problem.
25
+ - If confidence is low, use unclear or unknown instead of pretending certainty.
26
+
27
+ Projection JSON:
28
+
29
+ \`\`\`json
30
+ ${JSON.stringify(input.projection, null, 2)}
31
+ \`\`\``
32
+ }
@@ -0,0 +1,70 @@
1
+ import { hasDecksState, readDecksState, type DecksState } from "../decks-state"
2
+ import { compileInspectionContext } from "../inspection-context/compile"
3
+ import { matchInspectionElement, type InspectionElementSnapshot } from "../inspection-context/match"
4
+ import { projectInspectionMatch, type InspectionPromptProjection } from "../inspection-context/project"
5
+ import { buildDeterministicInspectionResult, type InspectionResult } from "../inspection-context/result"
6
+
7
+ export interface InspectElementResult {
8
+ requestId?: string
9
+ result: InspectionResult
10
+ }
11
+
12
+ export interface InspectElementProjectionResult {
13
+ requestId?: string
14
+ projection: InspectionPromptProjection
15
+ preprocess: InspectionResult
16
+ }
17
+
18
+ export function inspectElementInState(
19
+ state: DecksState,
20
+ snapshot: InspectionElementSnapshot,
21
+ options: { requestId?: string; staleReason?: string; slug?: string } = {},
22
+ ): InspectElementResult {
23
+ const context = compileInspectionContext(state, options.slug)
24
+ const match = matchInspectionElement(context, snapshot)
25
+ const projection = projectInspectionMatch(context, match, snapshot)
26
+ return {
27
+ requestId: options.requestId,
28
+ result: buildDeterministicInspectionResult(projection, {
29
+ requestId: options.requestId,
30
+ staleReason: options.staleReason,
31
+ }),
32
+ }
33
+ }
34
+
35
+ export function projectElementInState(
36
+ state: DecksState,
37
+ snapshot: InspectionElementSnapshot,
38
+ options: { requestId?: string; slug?: string } = {},
39
+ ): InspectElementProjectionResult {
40
+ const context = compileInspectionContext(state, options.slug)
41
+ const match = matchInspectionElement(context, snapshot)
42
+ const projection = projectInspectionMatch(context, match, snapshot)
43
+ return {
44
+ requestId: options.requestId,
45
+ projection,
46
+ preprocess: buildDeterministicInspectionResult(projection, { requestId: options.requestId }),
47
+ }
48
+ }
49
+
50
+ export function inspectWorkspaceElement(
51
+ workspaceRoot: string,
52
+ snapshot: InspectionElementSnapshot,
53
+ options: { requestId?: string; staleReason?: string; slug?: string } = {},
54
+ ): InspectElementResult {
55
+ if (!hasDecksState(workspaceRoot)) {
56
+ throw new Error("DECKS.json is required before inspection. Run /revela init first.")
57
+ }
58
+ return inspectElementInState(readDecksState(workspaceRoot), snapshot, options)
59
+ }
60
+
61
+ export function projectWorkspaceElement(
62
+ workspaceRoot: string,
63
+ snapshot: InspectionElementSnapshot,
64
+ options: { requestId?: string; slug?: string } = {},
65
+ ): InspectElementProjectionResult {
66
+ if (!hasDecksState(workspaceRoot)) {
67
+ throw new Error("DECKS.json is required before inspection. Run /revela init first.")
68
+ }
69
+ return projectElementInState(readDecksState(workspaceRoot), snapshot, options)
70
+ }
@@ -0,0 +1,86 @@
1
+ import type { InspectionPromptProjection } from "../inspection-context/project"
2
+ import type { InspectionResult } from "../inspection-context/result"
3
+
4
+ export type InspectRequestStatus = "pending" | "completed" | "failed" | "expired"
5
+
6
+ export interface PendingInspectRequest {
7
+ requestId: string
8
+ status: InspectRequestStatus
9
+ projection: InspectionPromptProjection
10
+ deckVersion: string
11
+ createdAt: number
12
+ updatedAt: number
13
+ result?: InspectionResult
14
+ error?: string
15
+ }
16
+
17
+ const REQUEST_TTL_MS = 90 * 1000
18
+ const requests = new Map<string, PendingInspectRequest>()
19
+
20
+ export function createInspectRequest(input: {
21
+ requestId: string
22
+ projection: InspectionPromptProjection
23
+ deckVersion: string
24
+ }): PendingInspectRequest {
25
+ cleanupInspectRequests()
26
+ const now = Date.now()
27
+ const request: PendingInspectRequest = {
28
+ requestId: input.requestId,
29
+ status: "pending",
30
+ projection: input.projection,
31
+ deckVersion: input.deckVersion,
32
+ createdAt: now,
33
+ updatedAt: now,
34
+ }
35
+ requests.set(input.requestId, request)
36
+ return request
37
+ }
38
+
39
+ export function getInspectRequest(requestId: string): PendingInspectRequest | undefined {
40
+ cleanupInspectRequests()
41
+ const request = requests.get(requestId)
42
+ if (!request) return undefined
43
+ if (request.status === "pending" && Date.now() - request.createdAt > REQUEST_TTL_MS) {
44
+ request.status = "expired"
45
+ request.error = "Inspection timed out before the LLM submitted a result."
46
+ request.updatedAt = Date.now()
47
+ }
48
+ return request
49
+ }
50
+
51
+ export function completeInspectRequest(requestId: string, result: InspectionResult): PendingInspectRequest {
52
+ const request = getInspectRequest(requestId)
53
+ if (!request) throw new Error(`Unknown inspection request: ${requestId}`)
54
+ if (request.status !== "pending") throw new Error(`Inspection request is not pending: ${request.status}`)
55
+ request.status = "completed"
56
+ request.result = { ...result, requestId }
57
+ request.updatedAt = Date.now()
58
+ return request
59
+ }
60
+
61
+ export function failInspectRequest(requestId: string, error: string): PendingInspectRequest | undefined {
62
+ const request = getInspectRequest(requestId)
63
+ if (!request || request.status !== "pending") return request
64
+ request.status = "failed"
65
+ request.error = error
66
+ request.updatedAt = Date.now()
67
+ return request
68
+ }
69
+
70
+ export function cleanupInspectRequests(now = Date.now()): void {
71
+ for (const [requestId, request] of requests) {
72
+ if (request.status === "pending" && now - request.createdAt > REQUEST_TTL_MS) {
73
+ request.status = "expired"
74
+ request.error = "Inspection timed out before the LLM submitted a result."
75
+ request.updatedAt = now
76
+ continue
77
+ }
78
+ if (request.status !== "pending" && now - request.updatedAt > REQUEST_TTL_MS) {
79
+ requests.delete(requestId)
80
+ }
81
+ }
82
+ }
83
+
84
+ export function clearInspectRequestsForTests(): void {
85
+ requests.clear()
86
+ }