pmx-canvas 0.1.29 → 0.1.31
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/CHANGELOG.md +219 -0
- package/Readme.md +20 -10
- package/dist/canvas/global.css +51 -56
- package/dist/canvas/index.js +80 -163
- package/dist/canvas/surface-theme.css +142 -0
- package/dist/json-render/index.js +103 -103
- package/dist/types/client/nodes/HtmlNode.d.ts +0 -7
- package/dist/types/client/nodes/ax-node-actions.d.ts +18 -0
- package/dist/types/client/nodes/surface-url.d.ts +22 -0
- package/dist/types/client/state/attention-bridge.d.ts +3 -0
- package/dist/types/client/state/intent-bridge.d.ts +17 -0
- package/dist/types/json-render/renderer/index.d.ts +2 -0
- package/dist/types/json-render/schema.d.ts +2 -0
- package/dist/types/json-render/server.d.ts +2 -0
- package/dist/types/mcp/canvas-access.d.ts +47 -0
- package/dist/types/server/ax-interaction.d.ts +210 -0
- package/dist/types/server/ax-state.d.ts +67 -1
- package/dist/types/server/canvas-db.d.ts +4 -0
- package/dist/types/server/canvas-serialization.d.ts +2 -0
- package/dist/types/server/canvas-state.d.ts +54 -2
- package/dist/types/server/html-surface.d.ts +46 -0
- package/dist/types/server/index.d.ts +63 -5
- package/dist/types/server/mutation-history.d.ts +1 -1
- package/dist/types/server/placement.d.ts +1 -1
- package/dist/types/server/server.d.ts +12 -0
- package/dist/types/shared/surface.d.ts +19 -0
- package/docs/cli.md +30 -0
- package/docs/http-api.md +55 -0
- package/docs/mcp.md +40 -2
- package/docs/node-types.md +26 -0
- package/docs/plans/plan-004-pmx-ax-primitives.md +623 -394
- package/docs/sdk.md +23 -1
- package/package.json +2 -2
- package/skills/pmx-canvas/SKILL.md +107 -9
- package/src/cli/agent.ts +177 -0
- package/src/cli/index.ts +8 -1
- package/src/client/canvas/CanvasNode.tsx +8 -4
- package/src/client/canvas/DockedNode.tsx +38 -38
- package/src/client/canvas/ExpandedNodeOverlay.tsx +12 -0
- package/src/client/nodes/ContextNode.tsx +17 -0
- package/src/client/nodes/ExtAppFrame.tsx +40 -3
- package/src/client/nodes/FileNode.tsx +26 -0
- package/src/client/nodes/HtmlNode.tsx +60 -188
- package/src/client/nodes/McpAppNode.tsx +47 -2
- package/src/client/nodes/StatusNode.tsx +20 -0
- package/src/client/nodes/ax-node-actions.ts +39 -0
- package/src/client/nodes/surface-url.ts +48 -0
- package/src/client/state/attention-bridge.ts +5 -0
- package/src/client/state/intent-bridge.ts +33 -0
- package/src/client/theme/global.css +51 -56
- package/src/client/theme/surface-theme.css +142 -0
- package/src/json-render/renderer/index.tsx +31 -0
- package/src/json-render/schema.ts +4 -0
- package/src/json-render/server.ts +13 -0
- package/src/mcp/canvas-access.ts +198 -1
- package/src/mcp/server.ts +232 -2
- package/src/server/ax-context.ts +3 -0
- package/src/server/ax-interaction.ts +549 -0
- package/src/server/ax-state.ts +188 -2
- package/src/server/canvas-db.ts +20 -0
- package/src/server/canvas-operations.ts +11 -0
- package/src/server/canvas-serialization.ts +9 -0
- package/src/server/canvas-state.ts +201 -26
- package/src/server/html-surface.ts +190 -0
- package/src/server/index.ts +122 -7
- package/src/server/mutation-history.ts +5 -0
- package/src/server/placement.ts +5 -1
- package/src/server/server.ts +360 -0
- package/src/shared/surface.ts +38 -0
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import type { CanvasNodeState } from '../types';
|
|
2
|
-
export declare function createHtmlNodeSrcDocForTest(userHtml: string, options: {
|
|
3
|
-
theme: string;
|
|
4
|
-
themeCss: string;
|
|
5
|
-
themeToken?: string;
|
|
6
|
-
presentation?: boolean;
|
|
7
|
-
presentationExitToken?: string;
|
|
8
|
-
}): string;
|
|
9
2
|
export declare function shouldShowPresentationControls(node: CanvasNodeState): boolean;
|
|
10
3
|
export declare function HtmlNode({ node, expanded, presentation, presentationExitToken, autoFocus, }: {
|
|
11
4
|
node: CanvasNodeState;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CanvasNodeState } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Submit a native-node AX interaction (plan-004 Phase 2) and surface the outcome
|
|
4
|
+
* as a transient toast. Inline node controls call this; the server enforces the
|
|
5
|
+
* node's capabilities, so a denied interaction simply shows an error toast.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runNodeAxInteraction(node: CanvasNodeState, type: string, payload: Record<string, unknown> | undefined, successTitle: string): Promise<void>;
|
|
8
|
+
/** Shared style for the small inline AX action button on native nodes. */
|
|
9
|
+
export declare const axNodeActionButtonStyle: {
|
|
10
|
+
readonly padding: "3px 8px";
|
|
11
|
+
readonly fontSize: "10px";
|
|
12
|
+
readonly background: "var(--c-accent-12)";
|
|
13
|
+
readonly border: "1px solid var(--c-accent-25)";
|
|
14
|
+
readonly borderRadius: "4px";
|
|
15
|
+
readonly color: "var(--c-text-soft)";
|
|
16
|
+
readonly cursor: "pointer";
|
|
17
|
+
readonly flexShrink: 0;
|
|
18
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CanvasNodeState } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Stable content hash (djb2) used to cache-bust the surface iframe `src` when a
|
|
4
|
+
* node's HTML changes. The server always serves current state, but a same `src`
|
|
5
|
+
* string won't reload the iframe on its own — bumping `?v=` does.
|
|
6
|
+
*/
|
|
7
|
+
export declare function surfaceContentHash(input: string): string;
|
|
8
|
+
export interface SurfaceUrlOptions {
|
|
9
|
+
theme?: string;
|
|
10
|
+
themeToken?: string;
|
|
11
|
+
present?: boolean;
|
|
12
|
+
presentToken?: string;
|
|
13
|
+
v?: string;
|
|
14
|
+
/** Nonce authorizing iframe → parent AX emits (html bridge). */
|
|
15
|
+
axToken?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Build the stable per-node surface URL (/api/canvas/surface/:id) the iframe and "Open as site" both use. */
|
|
18
|
+
export declare function nodeSurfaceUrl(nodeId: string, opts?: SurfaceUrlOptions): string;
|
|
19
|
+
/** Whether a node can be opened as a standalone site (shared with the server). */
|
|
20
|
+
export declare function canOpenAsSite(node: CanvasNodeState): boolean;
|
|
21
|
+
/** Open the node's surface in a new browser tab. */
|
|
22
|
+
export declare function openNodeAsSite(node: CanvasNodeState): void;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { type SseMessage } from '../../shared/semantic-attention.js';
|
|
2
|
+
import { type AttentionTone } from './attention-store';
|
|
3
|
+
/** Show a transient toast from arbitrary client code (e.g. AX action feedback). */
|
|
4
|
+
export declare function showToast(tone: AttentionTone, title: string, detail?: string, nodeIds?: string[]): void;
|
|
2
5
|
export declare function resetAttentionBridge(): void;
|
|
3
6
|
export declare function syncAttentionFromSse(message: SseMessage): void;
|
|
@@ -111,6 +111,23 @@ export declare function removeNodeFromClient(id: string): Promise<{
|
|
|
111
111
|
ok: boolean;
|
|
112
112
|
removed?: string;
|
|
113
113
|
}>;
|
|
114
|
+
export interface AxInteractionRequest {
|
|
115
|
+
type: string;
|
|
116
|
+
sourceNodeId: string;
|
|
117
|
+
payload?: Record<string, unknown>;
|
|
118
|
+
sourceSurface?: 'native-node' | 'json-render' | 'html-node' | 'mcp-app' | 'adapter';
|
|
119
|
+
}
|
|
120
|
+
export interface AxInteractionResponse {
|
|
121
|
+
ok: boolean;
|
|
122
|
+
type?: string;
|
|
123
|
+
sourceNodeId?: string;
|
|
124
|
+
primitive?: unknown;
|
|
125
|
+
status?: number;
|
|
126
|
+
code?: string;
|
|
127
|
+
error?: string;
|
|
128
|
+
}
|
|
129
|
+
/** Submit a capability-gated AX interaction from a native node control. */
|
|
130
|
+
export declare function submitAxInteractionFromClient(input: AxInteractionRequest): Promise<AxInteractionResponse>;
|
|
114
131
|
/** Commit the current viewport to the authoritative server state. */
|
|
115
132
|
export declare function updateViewportFromClient(viewport: {
|
|
116
133
|
x: number;
|
|
@@ -6,6 +6,7 @@ export declare const schema: import("@json-render/core").Schema<{
|
|
|
6
6
|
props: import("@json-render/core").SchemaType<"propsOf", string>;
|
|
7
7
|
children: import("@json-render/core").SchemaType<"array", import("@json-render/core").SchemaType<"string", unknown>>;
|
|
8
8
|
visible: import("@json-render/core").SchemaType<"any", unknown>;
|
|
9
|
+
on: import("@json-render/core").SchemaType<"any", unknown>;
|
|
9
10
|
}>>;
|
|
10
11
|
}>;
|
|
11
12
|
catalog: import("@json-render/core").SchemaType<"object", {
|
|
@@ -29,6 +30,7 @@ export declare const elementTreeSchema: import("@json-render/core").Schema<{
|
|
|
29
30
|
props: import("@json-render/core").SchemaType<"propsOf", string>;
|
|
30
31
|
children: import("@json-render/core").SchemaType<"array", import("@json-render/core").SchemaType<"string", unknown>>;
|
|
31
32
|
visible: import("@json-render/core").SchemaType<"any", unknown>;
|
|
33
|
+
on: import("@json-render/core").SchemaType<"any", unknown>;
|
|
32
34
|
}>>;
|
|
33
35
|
}>;
|
|
34
36
|
catalog: import("@json-render/core").SchemaType<"object", {
|
|
@@ -29,6 +29,22 @@ type SetAxFocusResult = ReturnType<PmxCanvas['setAxFocus']>;
|
|
|
29
29
|
type RecordAxEventInput = Parameters<PmxCanvas['recordAxEvent']>[0];
|
|
30
30
|
type RecordAxEventResult = ReturnType<PmxCanvas['recordAxEvent']>;
|
|
31
31
|
type SendSteeringResult = ReturnType<PmxCanvas['sendSteering']>;
|
|
32
|
+
type SubmitAxInteractionInput = Parameters<PmxCanvas['submitAxInteraction']>[0];
|
|
33
|
+
type SubmitAxInteractionResult = ReturnType<PmxCanvas['submitAxInteraction']>;
|
|
34
|
+
type GetPendingSteeringResult = ReturnType<PmxCanvas['getPendingSteering']>;
|
|
35
|
+
type ListElicitationsResult = ReturnType<PmxCanvas['listElicitations']>;
|
|
36
|
+
type RequestElicitationInput = Parameters<PmxCanvas['requestElicitation']>[0];
|
|
37
|
+
type RequestElicitationResult = ReturnType<PmxCanvas['requestElicitation']>;
|
|
38
|
+
type RespondElicitationResult = ReturnType<PmxCanvas['respondElicitation']>;
|
|
39
|
+
type ListModeRequestsResult = ReturnType<PmxCanvas['listModeRequests']>;
|
|
40
|
+
type RequestModeInput = Parameters<PmxCanvas['requestMode']>[0];
|
|
41
|
+
type RequestModeResult = ReturnType<PmxCanvas['requestMode']>;
|
|
42
|
+
type ResolveModeRequestResult = ReturnType<PmxCanvas['resolveModeRequest']>;
|
|
43
|
+
type GetCommandRegistryResult = ReturnType<PmxCanvas['getCommandRegistry']>;
|
|
44
|
+
type InvokeCommandResult = ReturnType<PmxCanvas['invokeCommand']>;
|
|
45
|
+
type GetPolicyResult = ReturnType<PmxCanvas['getPolicy']>;
|
|
46
|
+
type SetPolicyInput = Parameters<PmxCanvas['setPolicy']>[0];
|
|
47
|
+
type SetPolicyResult = ReturnType<PmxCanvas['setPolicy']>;
|
|
32
48
|
type GetAxTimelineQuery = Parameters<PmxCanvas['getAxTimeline']>[0];
|
|
33
49
|
type GetAxTimelineResult = ReturnType<PmxCanvas['getAxTimeline']>;
|
|
34
50
|
type AddWorkItemInput = Parameters<PmxCanvas['addWorkItem']>[0];
|
|
@@ -139,6 +155,37 @@ export interface CanvasAccess {
|
|
|
139
155
|
reportHostCapability(input: unknown, options?: {
|
|
140
156
|
source?: PmxAxSource;
|
|
141
157
|
}): Promise<ReportHostCapabilityResult>;
|
|
158
|
+
submitAxInteraction(input: SubmitAxInteractionInput, options?: {
|
|
159
|
+
source?: PmxAxSource;
|
|
160
|
+
}): Promise<SubmitAxInteractionResult>;
|
|
161
|
+
getPendingSteering(options?: {
|
|
162
|
+
consumer?: string;
|
|
163
|
+
limit?: number;
|
|
164
|
+
}): Promise<GetPendingSteeringResult>;
|
|
165
|
+
markSteeringDelivered(id: string): Promise<boolean>;
|
|
166
|
+
listElicitations(): Promise<ListElicitationsResult>;
|
|
167
|
+
requestElicitation(input: RequestElicitationInput, options?: {
|
|
168
|
+
source?: PmxAxSource;
|
|
169
|
+
}): Promise<RequestElicitationResult>;
|
|
170
|
+
respondElicitation(id: string, response: Record<string, unknown>, options?: {
|
|
171
|
+
source?: PmxAxSource;
|
|
172
|
+
}): Promise<RespondElicitationResult>;
|
|
173
|
+
listModeRequests(): Promise<ListModeRequestsResult>;
|
|
174
|
+
requestMode(input: RequestModeInput, options?: {
|
|
175
|
+
source?: PmxAxSource;
|
|
176
|
+
}): Promise<RequestModeResult>;
|
|
177
|
+
resolveModeRequest(id: string, decision: 'approved' | 'rejected', options?: {
|
|
178
|
+
resolution?: string;
|
|
179
|
+
source?: PmxAxSource;
|
|
180
|
+
}): Promise<ResolveModeRequestResult>;
|
|
181
|
+
getCommandRegistry(): Promise<GetCommandRegistryResult>;
|
|
182
|
+
invokeCommand(name: string, args?: Record<string, unknown> | null, options?: {
|
|
183
|
+
source?: PmxAxSource;
|
|
184
|
+
}): Promise<InvokeCommandResult>;
|
|
185
|
+
getPolicy(): Promise<GetPolicyResult>;
|
|
186
|
+
setPolicy(patch: SetPolicyInput, options?: {
|
|
187
|
+
source?: PmxAxSource;
|
|
188
|
+
}): Promise<SetPolicyResult>;
|
|
142
189
|
clear(): Promise<void>;
|
|
143
190
|
search(query: string): Promise<SearchResult>;
|
|
144
191
|
undo(): Promise<UndoRedoResult>;
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PMX-AX node interaction core (plan-004 Phase 1).
|
|
3
|
+
*
|
|
4
|
+
* One normalized envelope + capability model for node-originated AX interactions.
|
|
5
|
+
* Eligible nodes emit a validated `PmxAxInteraction`; this module checks the
|
|
6
|
+
* node's capabilities and payload, then maps the interaction onto the EXISTING
|
|
7
|
+
* AX operations (work items, evidence, approvals, review, focus, steering,
|
|
8
|
+
* events). It is host-agnostic and transport-agnostic — the same envelope backs
|
|
9
|
+
* native node events, json-render actions, the sandboxed HTML bridge, MCP apps,
|
|
10
|
+
* and host adapters (later phases).
|
|
11
|
+
*
|
|
12
|
+
* Decoupling: this module never imports the canvas-state singleton at runtime.
|
|
13
|
+
* The dispatcher takes the manager via dependency injection (structural
|
|
14
|
+
* `AxInteractionManager`), so it stays pure and unit-testable and introduces no
|
|
15
|
+
* import cycle (canvas-state → canvas-provenance must not pull this in).
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
import type { CanvasNodeState } from './canvas-state.js';
|
|
19
|
+
import type { CanvasNodeType } from './canvas-provenance.js';
|
|
20
|
+
import type { PmxAxApprovalGate, PmxAxElicitation, PmxAxEvent, PmxAxEventKind, PmxAxEvidence, PmxAxEvidenceKind, PmxAxFocusState, PmxAxMode, PmxAxModeRequest, PmxAxReviewAnchorType, PmxAxReviewAnnotation, PmxAxReviewKind, PmxAxReviewRegion, PmxAxReviewSeverity, PmxAxSource, PmxAxSteeringMessage, PmxAxWorkItem, PmxAxWorkItemStatus } from './ax-state.js';
|
|
21
|
+
export declare const AX_INTERACTION_TYPES: readonly ["ax.event.record", "ax.steer", "ax.work.create", "ax.work.update", "ax.evidence.add", "ax.approval.request", "ax.approval.resolve", "ax.review.add", "ax.focus.set", "ax.command.invoke", "ax.elicitation.request", "ax.mode.request"];
|
|
22
|
+
export type AxInteractionType = (typeof AX_INTERACTION_TYPES)[number];
|
|
23
|
+
export type AxDeliveryMode = 'record-only' | 'notify-agent' | 'send-to-agent';
|
|
24
|
+
export interface NodeAxCapabilities {
|
|
25
|
+
enabled: boolean;
|
|
26
|
+
/** Interaction types this node may emit. Also the per-node override ceiling. */
|
|
27
|
+
allowed: AxInteractionType[];
|
|
28
|
+
/** Subset of `allowed` that should route through an approval gate (later phases). */
|
|
29
|
+
requiresApproval: AxInteractionType[];
|
|
30
|
+
delivery: AxDeliveryMode;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Server-side default (and per-node ceiling) capabilities per node type, from the
|
|
34
|
+
* plan's node capability matrix. `html`/`html-primitive`, `mcp-app`, and the
|
|
35
|
+
* internal `prompt`/`response` types default to disabled (opt-in / later phases);
|
|
36
|
+
* a node can anchor AX state but only eligible types may EMIT interactions.
|
|
37
|
+
*/
|
|
38
|
+
export declare const DEFAULT_NODE_AX_CAPABILITIES: Record<CanvasNodeType, NodeAxCapabilities>;
|
|
39
|
+
/** Validate caller-supplied per-node `data.axCapabilities` into a partial override. */
|
|
40
|
+
export declare function normalizeNodeAxCapabilities(value: unknown): Partial<NodeAxCapabilities> | null;
|
|
41
|
+
/**
|
|
42
|
+
* Effective capabilities for a node: the type default merged with the node's own
|
|
43
|
+
* `data.axCapabilities`. A per-node override can toggle `enabled` and NARROW
|
|
44
|
+
* `allowed`, but never grant a type beyond the type's ceiling (security: a
|
|
45
|
+
* pasted/generated node cannot escalate itself).
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveNodeAxCapabilities(node: CanvasNodeState): NodeAxCapabilities;
|
|
48
|
+
declare const InteractionEnvelopeSchema: z.ZodObject<{
|
|
49
|
+
type: z.ZodEnum<{
|
|
50
|
+
"ax.event.record": "ax.event.record";
|
|
51
|
+
"ax.steer": "ax.steer";
|
|
52
|
+
"ax.work.create": "ax.work.create";
|
|
53
|
+
"ax.work.update": "ax.work.update";
|
|
54
|
+
"ax.evidence.add": "ax.evidence.add";
|
|
55
|
+
"ax.approval.request": "ax.approval.request";
|
|
56
|
+
"ax.approval.resolve": "ax.approval.resolve";
|
|
57
|
+
"ax.review.add": "ax.review.add";
|
|
58
|
+
"ax.focus.set": "ax.focus.set";
|
|
59
|
+
"ax.command.invoke": "ax.command.invoke";
|
|
60
|
+
"ax.elicitation.request": "ax.elicitation.request";
|
|
61
|
+
"ax.mode.request": "ax.mode.request";
|
|
62
|
+
}>;
|
|
63
|
+
sourceNodeId: z.ZodString;
|
|
64
|
+
sourceSurface: z.ZodOptional<z.ZodEnum<{
|
|
65
|
+
"mcp-app": "mcp-app";
|
|
66
|
+
"json-render": "json-render";
|
|
67
|
+
"native-node": "native-node";
|
|
68
|
+
"html-node": "html-node";
|
|
69
|
+
adapter: "adapter";
|
|
70
|
+
}>>;
|
|
71
|
+
actor: z.ZodOptional<z.ZodObject<{
|
|
72
|
+
kind: z.ZodEnum<{
|
|
73
|
+
agent: "agent";
|
|
74
|
+
system: "system";
|
|
75
|
+
human: "human";
|
|
76
|
+
}>;
|
|
77
|
+
id: z.ZodOptional<z.ZodString>;
|
|
78
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
79
|
+
}, z.core.$strip>>;
|
|
80
|
+
payload: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
81
|
+
correlationId: z.ZodOptional<z.ZodString>;
|
|
82
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
83
|
+
}, z.core.$strip>;
|
|
84
|
+
export type PmxAxInteraction = z.infer<typeof InteractionEnvelopeSchema>;
|
|
85
|
+
/** Caller-facing interaction input (payload optional; validated on apply). */
|
|
86
|
+
export interface AxInteractionInput {
|
|
87
|
+
type: AxInteractionType;
|
|
88
|
+
sourceNodeId: string;
|
|
89
|
+
sourceSurface?: PmxAxInteraction['sourceSurface'];
|
|
90
|
+
actor?: PmxAxInteraction['actor'];
|
|
91
|
+
payload?: Record<string, unknown>;
|
|
92
|
+
correlationId?: string;
|
|
93
|
+
metadata?: Record<string, unknown>;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Structural subset of CanvasStateManager that interaction dispatch needs.
|
|
97
|
+
* Injected so this module stays free of a runtime canvas-state import.
|
|
98
|
+
*/
|
|
99
|
+
export interface AxInteractionManager {
|
|
100
|
+
getNode(id: string): CanvasNodeState | undefined;
|
|
101
|
+
recordAxEvent(input: {
|
|
102
|
+
kind: PmxAxEventKind;
|
|
103
|
+
summary: string;
|
|
104
|
+
detail?: string | null;
|
|
105
|
+
nodeIds?: string[];
|
|
106
|
+
data?: Record<string, unknown> | null;
|
|
107
|
+
}, options?: {
|
|
108
|
+
source?: PmxAxSource;
|
|
109
|
+
}): PmxAxEvent;
|
|
110
|
+
recordSteeringMessage(message: string, options?: {
|
|
111
|
+
source?: PmxAxSource;
|
|
112
|
+
}): PmxAxSteeringMessage;
|
|
113
|
+
addWorkItem(input: {
|
|
114
|
+
title: string;
|
|
115
|
+
status?: PmxAxWorkItemStatus;
|
|
116
|
+
detail?: string | null;
|
|
117
|
+
nodeIds?: string[];
|
|
118
|
+
}, options?: {
|
|
119
|
+
source?: PmxAxSource;
|
|
120
|
+
}): PmxAxWorkItem;
|
|
121
|
+
updateWorkItem(id: string, patch: {
|
|
122
|
+
title?: string;
|
|
123
|
+
status?: PmxAxWorkItemStatus;
|
|
124
|
+
detail?: string | null;
|
|
125
|
+
nodeIds?: string[];
|
|
126
|
+
}, options?: {
|
|
127
|
+
source?: PmxAxSource;
|
|
128
|
+
}): PmxAxWorkItem | null;
|
|
129
|
+
addEvidence(input: {
|
|
130
|
+
kind: PmxAxEvidenceKind;
|
|
131
|
+
title: string;
|
|
132
|
+
body?: string | null;
|
|
133
|
+
ref?: string | null;
|
|
134
|
+
nodeIds?: string[];
|
|
135
|
+
data?: Record<string, unknown> | null;
|
|
136
|
+
}, options?: {
|
|
137
|
+
source?: PmxAxSource;
|
|
138
|
+
}): PmxAxEvidence;
|
|
139
|
+
requestApproval(input: {
|
|
140
|
+
title: string;
|
|
141
|
+
detail?: string | null;
|
|
142
|
+
action?: string | null;
|
|
143
|
+
nodeIds?: string[];
|
|
144
|
+
}, options?: {
|
|
145
|
+
source?: PmxAxSource;
|
|
146
|
+
}): PmxAxApprovalGate;
|
|
147
|
+
resolveApproval(id: string, decision: 'approved' | 'rejected', options?: {
|
|
148
|
+
resolution?: string;
|
|
149
|
+
source?: PmxAxSource;
|
|
150
|
+
}): PmxAxApprovalGate | null;
|
|
151
|
+
addReviewAnnotation(input: {
|
|
152
|
+
body: string;
|
|
153
|
+
kind?: PmxAxReviewKind;
|
|
154
|
+
severity?: PmxAxReviewSeverity;
|
|
155
|
+
anchorType?: PmxAxReviewAnchorType;
|
|
156
|
+
nodeId?: string | null;
|
|
157
|
+
file?: string | null;
|
|
158
|
+
region?: PmxAxReviewRegion | null;
|
|
159
|
+
author?: string | null;
|
|
160
|
+
}, options?: {
|
|
161
|
+
source?: PmxAxSource;
|
|
162
|
+
}): PmxAxReviewAnnotation | null;
|
|
163
|
+
setAxFocus(nodeIds: string[], options?: {
|
|
164
|
+
source?: PmxAxSource;
|
|
165
|
+
}): PmxAxFocusState;
|
|
166
|
+
requestElicitation(input: {
|
|
167
|
+
prompt: string;
|
|
168
|
+
fields?: string[];
|
|
169
|
+
nodeIds?: string[];
|
|
170
|
+
}, options?: {
|
|
171
|
+
source?: PmxAxSource;
|
|
172
|
+
}): PmxAxElicitation;
|
|
173
|
+
requestMode(input: {
|
|
174
|
+
mode: PmxAxMode;
|
|
175
|
+
reason?: string | null;
|
|
176
|
+
nodeIds?: string[];
|
|
177
|
+
}, options?: {
|
|
178
|
+
source?: PmxAxSource;
|
|
179
|
+
}): PmxAxModeRequest;
|
|
180
|
+
invokeCommand(name: string, args?: Record<string, unknown> | null, options?: {
|
|
181
|
+
source?: PmxAxSource;
|
|
182
|
+
}): PmxAxEvent | null;
|
|
183
|
+
}
|
|
184
|
+
export interface AxInteractionEvent {
|
|
185
|
+
event: string;
|
|
186
|
+
payload: Record<string, unknown>;
|
|
187
|
+
}
|
|
188
|
+
export type AxInteractionPublicResult = {
|
|
189
|
+
ok: true;
|
|
190
|
+
type: AxInteractionType;
|
|
191
|
+
sourceNodeId: string;
|
|
192
|
+
primitive: unknown;
|
|
193
|
+
} | {
|
|
194
|
+
ok: false;
|
|
195
|
+
status: number;
|
|
196
|
+
code: string;
|
|
197
|
+
error: string;
|
|
198
|
+
};
|
|
199
|
+
export interface AxInteractionResult {
|
|
200
|
+
result: AxInteractionPublicResult;
|
|
201
|
+
events: AxInteractionEvent[];
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Validate + execute a node-originated AX interaction. Returns the public result
|
|
205
|
+
* plus the SSE events the caller should emit (accepted/rejected outcome + the
|
|
206
|
+
* underlying AX state event). Never throws on bad input — returns an `ok: false`
|
|
207
|
+
* result with an appropriate HTTP-ish status.
|
|
208
|
+
*/
|
|
209
|
+
export declare function applyAxInteraction(manager: AxInteractionManager, rawBody: unknown, source: PmxAxSource): AxInteractionResult;
|
|
210
|
+
export {};
|
|
@@ -7,7 +7,7 @@ export interface PmxAxFocusState {
|
|
|
7
7
|
updatedAt: string | null;
|
|
8
8
|
source: PmxAxSource | null;
|
|
9
9
|
}
|
|
10
|
-
export type PmxAxEventKind = 'prompt' | 'assistant-message' | 'tool-start' | 'tool-result' | 'failure' | 'approval' | 'steering';
|
|
10
|
+
export type PmxAxEventKind = 'prompt' | 'assistant-message' | 'tool-start' | 'tool-result' | 'failure' | 'approval' | 'steering' | 'command';
|
|
11
11
|
export type PmxAxEvidenceKind = 'logs' | 'tool-result' | 'screenshot' | 'file' | 'diff' | 'test-output';
|
|
12
12
|
export type PmxAxWorkItemStatus = 'todo' | 'in-progress' | 'blocked' | 'done' | 'cancelled';
|
|
13
13
|
export type PmxAxApprovalStatus = 'pending' | 'approved' | 'rejected';
|
|
@@ -122,6 +122,9 @@ export interface PmxAxState {
|
|
|
122
122
|
workItems: PmxAxWorkItem[];
|
|
123
123
|
approvalGates: PmxAxApprovalGate[];
|
|
124
124
|
reviewAnnotations: PmxAxReviewAnnotation[];
|
|
125
|
+
elicitations: PmxAxElicitation[];
|
|
126
|
+
modeRequests: PmxAxModeRequest[];
|
|
127
|
+
policy: PmxAxPolicy;
|
|
125
128
|
}
|
|
126
129
|
export interface PmxAxPinnedContext {
|
|
127
130
|
preamble: string;
|
|
@@ -144,12 +147,72 @@ export interface PmxAxContext {
|
|
|
144
147
|
workItems: PmxAxWorkItem[];
|
|
145
148
|
approvalGates: PmxAxApprovalGate[];
|
|
146
149
|
reviewAnnotations: PmxAxReviewAnnotation[];
|
|
150
|
+
elicitations: PmxAxElicitation[];
|
|
151
|
+
modeRequests: PmxAxModeRequest[];
|
|
152
|
+
policy: PmxAxPolicy;
|
|
147
153
|
timeline: PmxAxTimelineSummary;
|
|
148
154
|
host: PmxAxHostCapability | null;
|
|
149
155
|
}
|
|
156
|
+
export interface PmxAxCommandDescriptor {
|
|
157
|
+
name: string;
|
|
158
|
+
description: string;
|
|
159
|
+
}
|
|
160
|
+
export declare const AX_COMMAND_REGISTRY: Record<string, PmxAxCommandDescriptor>;
|
|
161
|
+
export declare function isAxCommand(name: unknown): name is string;
|
|
162
|
+
export declare function listAxCommands(): PmxAxCommandDescriptor[];
|
|
163
|
+
export interface PmxAxPolicy {
|
|
164
|
+
tools: {
|
|
165
|
+
allowed: string[];
|
|
166
|
+
excluded: string[];
|
|
167
|
+
approvalRequired: string[];
|
|
168
|
+
};
|
|
169
|
+
prompt: {
|
|
170
|
+
systemAppend: string | null;
|
|
171
|
+
mode: string | null;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
export declare function createEmptyAxPolicy(): PmxAxPolicy;
|
|
175
|
+
export declare function normalizeAxPolicy(input: unknown): PmxAxPolicy;
|
|
150
176
|
export declare function isAxEventKind(value: unknown): value is PmxAxEventKind;
|
|
151
177
|
export declare function isAxEvidenceKind(value: unknown): value is PmxAxEvidenceKind;
|
|
152
178
|
export declare function createEmptyAxFocusState(): PmxAxFocusState;
|
|
179
|
+
export type PmxAxElicitationStatus = 'pending' | 'answered' | 'cancelled';
|
|
180
|
+
export interface PmxAxElicitation {
|
|
181
|
+
id: string;
|
|
182
|
+
prompt: string;
|
|
183
|
+
fields: string[];
|
|
184
|
+
status: PmxAxElicitationStatus;
|
|
185
|
+
response: Record<string, unknown> | null;
|
|
186
|
+
nodeIds: string[];
|
|
187
|
+
createdAt: string;
|
|
188
|
+
resolvedAt: string | null;
|
|
189
|
+
source: PmxAxSource | null;
|
|
190
|
+
}
|
|
191
|
+
export declare function normalizeAxElicitation(input: unknown, validNodeIds?: Set<string>): PmxAxElicitation | null;
|
|
192
|
+
export declare function createAxElicitation(input: {
|
|
193
|
+
prompt: string;
|
|
194
|
+
fields?: string[];
|
|
195
|
+
nodeIds?: string[];
|
|
196
|
+
}, source: PmxAxSource | null, validNodeIds?: Set<string>): PmxAxElicitation;
|
|
197
|
+
export type PmxAxMode = 'plan' | 'execute' | 'autonomous';
|
|
198
|
+
export type PmxAxModeRequestStatus = 'pending' | 'approved' | 'rejected';
|
|
199
|
+
export interface PmxAxModeRequest {
|
|
200
|
+
id: string;
|
|
201
|
+
mode: PmxAxMode;
|
|
202
|
+
reason: string | null;
|
|
203
|
+
status: PmxAxModeRequestStatus;
|
|
204
|
+
nodeIds: string[];
|
|
205
|
+
createdAt: string;
|
|
206
|
+
resolvedAt: string | null;
|
|
207
|
+
resolution: string | null;
|
|
208
|
+
source: PmxAxSource | null;
|
|
209
|
+
}
|
|
210
|
+
export declare function normalizeAxModeRequest(input: unknown, validNodeIds?: Set<string>): PmxAxModeRequest | null;
|
|
211
|
+
export declare function createAxModeRequest(input: {
|
|
212
|
+
mode: PmxAxMode;
|
|
213
|
+
reason?: string | null;
|
|
214
|
+
nodeIds?: string[];
|
|
215
|
+
}, source: PmxAxSource | null, validNodeIds?: Set<string>): PmxAxModeRequest;
|
|
153
216
|
export declare function createEmptyAxState(): PmxAxState;
|
|
154
217
|
export declare function createEmptyAxHostCapability(): PmxAxHostCapability;
|
|
155
218
|
export declare function normalizeAxFocusState(input: unknown, validNodeIds?: Set<string>): PmxAxFocusState;
|
|
@@ -207,6 +270,9 @@ export declare function buildAxContext(input: {
|
|
|
207
270
|
workItems: PmxAxWorkItem[];
|
|
208
271
|
approvalGates: PmxAxApprovalGate[];
|
|
209
272
|
reviewAnnotations: PmxAxReviewAnnotation[];
|
|
273
|
+
elicitations: PmxAxElicitation[];
|
|
274
|
+
modeRequests: PmxAxModeRequest[];
|
|
275
|
+
policy: PmxAxPolicy;
|
|
210
276
|
timeline: PmxAxTimelineSummary;
|
|
211
277
|
host: PmxAxHostCapability | null;
|
|
212
278
|
}): PmxAxContext;
|
|
@@ -49,6 +49,10 @@ export declare function loadAxEvidenceFromDB(db: Database, q?: AxTimelineQuery):
|
|
|
49
49
|
export declare function loadAxSteeringFromDB(db: Database, q?: AxTimelineQuery & {
|
|
50
50
|
onlyPending?: boolean;
|
|
51
51
|
}): PmxAxSteeringMessage[];
|
|
52
|
+
export declare function loadPendingAxSteeringFromDB(db: Database, options?: {
|
|
53
|
+
consumer?: string;
|
|
54
|
+
limit?: number;
|
|
55
|
+
}): PmxAxSteeringMessage[];
|
|
52
56
|
export declare function loadAxTimelineSummaryFromDB(db: Database): PmxAxTimelineSummary;
|
|
53
57
|
export declare function upsertAxHostCapabilityToDB(db: Database, cap: PmxAxHostCapability): void;
|
|
54
58
|
export declare function loadAxHostCapabilityFromDB(db: Database): PmxAxHostCapability | null;
|
|
@@ -6,6 +6,7 @@ export interface SerializedCanvasNode extends CanvasNodeState {
|
|
|
6
6
|
content: string | null;
|
|
7
7
|
path: string | null;
|
|
8
8
|
url: string | null;
|
|
9
|
+
surfaceUrl: string | null;
|
|
9
10
|
provenance: CanvasNodeProvenance | null;
|
|
10
11
|
}
|
|
11
12
|
export interface SerializedCanvasLayout extends Omit<CanvasLayout, 'nodes'> {
|
|
@@ -33,6 +34,7 @@ export interface CanvasAnnotationContextSummary {
|
|
|
33
34
|
export declare function getCanvasNodeKind(node: CanvasNodeState, data: Record<string, unknown>): string;
|
|
34
35
|
export declare function getCanvasNodeTitle(node: CanvasNodeState): string | null;
|
|
35
36
|
export declare function getCanvasNodeContent(node: CanvasNodeState): string | null;
|
|
37
|
+
export declare function getCanvasNodeSurfaceUrl(node: CanvasNodeState, data: Record<string, unknown>): string | null;
|
|
36
38
|
export declare function serializeCanvasNode(node: CanvasNodeState): SerializedCanvasNode;
|
|
37
39
|
export declare function serializeCanvasNodeForAgent(node: CanvasNodeState): SerializedCanvasNode;
|
|
38
40
|
export declare function serializeCanvasNodeCompact(node: CanvasNodeState): SerializedCanvasNode;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Legacy `.pmx-canvas/state.json` is auto-migrated on first boot.
|
|
11
11
|
*/
|
|
12
12
|
import { type PersistedCanvasState, type CanvasTheme, type AxTimelineQuery } from './canvas-db.js';
|
|
13
|
-
import { type PmxAxFocusState, type PmxAxSource, type PmxAxState, type PmxAxWorkItem, type PmxAxWorkItemStatus, type PmxAxApprovalGate, type PmxAxReviewAnnotation, type PmxAxReviewKind, type PmxAxReviewSeverity, type PmxAxReviewStatus, type PmxAxReviewAnchorType, type PmxAxReviewRegion, type PmxAxEvent, type PmxAxEventKind, type PmxAxEvidence, type PmxAxEvidenceKind, type PmxAxSteeringMessage, type PmxAxHostCapability, type PmxAxTimelineSummary } from './ax-state.js';
|
|
13
|
+
import { type PmxAxElicitation, type PmxAxModeRequest, type PmxAxMode, type PmxAxCommandDescriptor, type PmxAxPolicy, type PmxAxFocusState, type PmxAxSource, type PmxAxState, type PmxAxWorkItem, type PmxAxWorkItemStatus, type PmxAxApprovalGate, type PmxAxReviewAnnotation, type PmxAxReviewKind, type PmxAxReviewSeverity, type PmxAxReviewStatus, type PmxAxReviewAnchorType, type PmxAxReviewRegion, type PmxAxEvent, type PmxAxEventKind, type PmxAxEvidence, type PmxAxEvidenceKind, type PmxAxSteeringMessage, type PmxAxHostCapability, type PmxAxTimelineSummary } from './ax-state.js';
|
|
14
14
|
export declare const PMX_CANVAS_DIR = ".pmx-canvas";
|
|
15
15
|
export interface PersistedBlobRef {
|
|
16
16
|
__pmxCanvasBlob: 'v1';
|
|
@@ -122,7 +122,7 @@ export interface CanvasNodeUpdate {
|
|
|
122
122
|
}
|
|
123
123
|
export type CanvasChangeType = 'pins' | 'nodes' | 'ax' | 'ax-timeline';
|
|
124
124
|
export interface MutationRecordInfo {
|
|
125
|
-
operationType: 'addNode' | 'updateNode' | 'removeNode' | 'addEdge' | 'removeEdge' | 'addAnnotation' | 'removeAnnotation' | 'clear' | 'restoreSnapshot' | 'setPins' | 'setAxFocus' | 'addWorkItem' | 'updateWorkItem' | 'requestApproval' | 'resolveApproval' | 'addReviewAnnotation' | 'updateReviewAnnotation' | 'arrange' | 'batch' | 'groupNodes' | 'ungroupNodes' | 'viewport';
|
|
125
|
+
operationType: 'addNode' | 'updateNode' | 'removeNode' | 'addEdge' | 'removeEdge' | 'addAnnotation' | 'removeAnnotation' | 'clear' | 'restoreSnapshot' | 'setPins' | 'setAxFocus' | 'addWorkItem' | 'updateWorkItem' | 'requestApproval' | 'resolveApproval' | 'addReviewAnnotation' | 'updateReviewAnnotation' | 'requestElicitation' | 'respondElicitation' | 'requestMode' | 'resolveModeRequest' | 'setPolicy' | 'arrange' | 'batch' | 'groupNodes' | 'ungroupNodes' | 'viewport';
|
|
126
126
|
description: string;
|
|
127
127
|
forward: () => void;
|
|
128
128
|
inverse: () => void;
|
|
@@ -199,6 +199,13 @@ declare class CanvasStateManager {
|
|
|
199
199
|
private emptyPersistedState;
|
|
200
200
|
/** Load canvas state from SQLite (or legacy JSON fallback). Call once on server startup. */
|
|
201
201
|
loadFromDisk(options?: LoadFromDiskOptions): boolean;
|
|
202
|
+
/**
|
|
203
|
+
* Whether this workspace's canvas DB already holds saved state. Used to gate
|
|
204
|
+
* brand-new-workspace seeding (e.g. the default docked status/context widgets)
|
|
205
|
+
* so we never add nodes to a canvas that already has content. Reflects the
|
|
206
|
+
* pre-run persisted flag until the next save.
|
|
207
|
+
*/
|
|
208
|
+
hasPersistedState(): boolean;
|
|
202
209
|
/** Debounced save — coalesces rapid mutations into a single write. */
|
|
203
210
|
private scheduleSave;
|
|
204
211
|
flushToDisk(): void;
|
|
@@ -316,6 +323,42 @@ declare class CanvasStateManager {
|
|
|
316
323
|
source?: PmxAxSource;
|
|
317
324
|
}): PmxAxReviewAnnotation | null;
|
|
318
325
|
getHostCapability(): PmxAxHostCapability | null;
|
|
326
|
+
getElicitations(): PmxAxElicitation[];
|
|
327
|
+
requestElicitation(input: {
|
|
328
|
+
prompt: string;
|
|
329
|
+
fields?: string[];
|
|
330
|
+
nodeIds?: string[];
|
|
331
|
+
}, options?: {
|
|
332
|
+
source?: PmxAxSource;
|
|
333
|
+
}): PmxAxElicitation;
|
|
334
|
+
respondElicitation(id: string, response: Record<string, unknown>, options?: {
|
|
335
|
+
source?: PmxAxSource;
|
|
336
|
+
}): PmxAxElicitation | null;
|
|
337
|
+
getModeRequests(): PmxAxModeRequest[];
|
|
338
|
+
requestMode(input: {
|
|
339
|
+
mode: PmxAxMode;
|
|
340
|
+
reason?: string | null;
|
|
341
|
+
nodeIds?: string[];
|
|
342
|
+
}, options?: {
|
|
343
|
+
source?: PmxAxSource;
|
|
344
|
+
}): PmxAxModeRequest;
|
|
345
|
+
resolveModeRequest(id: string, decision: 'approved' | 'rejected', options?: {
|
|
346
|
+
resolution?: string;
|
|
347
|
+
source?: PmxAxSource;
|
|
348
|
+
}): PmxAxModeRequest | null;
|
|
349
|
+
getCommandRegistry(): PmxAxCommandDescriptor[];
|
|
350
|
+
/** Invoke a registry-gated PMX command intent — records a timeline event (no execution). */
|
|
351
|
+
invokeCommand(name: string, args?: Record<string, unknown> | null, options?: {
|
|
352
|
+
source?: PmxAxSource;
|
|
353
|
+
}): PmxAxEvent | null;
|
|
354
|
+
getPolicy(): PmxAxPolicy;
|
|
355
|
+
/** Merge a declarative tool/prompt policy patch (canvas-bound, snapshotted). */
|
|
356
|
+
setPolicy(patch: {
|
|
357
|
+
tools?: Partial<PmxAxPolicy['tools']>;
|
|
358
|
+
prompt?: Partial<PmxAxPolicy['prompt']>;
|
|
359
|
+
}, _options?: {
|
|
360
|
+
source?: PmxAxSource;
|
|
361
|
+
}): PmxAxPolicy;
|
|
319
362
|
setHostCapability(input: unknown, _options?: {
|
|
320
363
|
source?: PmxAxSource;
|
|
321
364
|
}): PmxAxHostCapability;
|
|
@@ -347,6 +390,15 @@ declare class CanvasStateManager {
|
|
|
347
390
|
getAxSteering(q?: AxTimelineQuery & {
|
|
348
391
|
onlyPending?: boolean;
|
|
349
392
|
}): PmxAxSteeringMessage[];
|
|
393
|
+
/**
|
|
394
|
+
* Undelivered steering for a consumer (Phase 4 delivery). Excludes messages
|
|
395
|
+
* whose source equals the consumer to prevent delivery loops (e.g. Copilot
|
|
396
|
+
* should not be handed back steering it originated).
|
|
397
|
+
*/
|
|
398
|
+
getPendingSteering(options?: {
|
|
399
|
+
consumer?: string;
|
|
400
|
+
limit?: number;
|
|
401
|
+
}): PmxAxSteeringMessage[];
|
|
350
402
|
getAxTimelineSummary(): PmxAxTimelineSummary;
|
|
351
403
|
getAxTimeline(q?: AxTimelineQuery): {
|
|
352
404
|
events: PmxAxEvent[];
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side builder for an `html` node's standalone surface document.
|
|
3
|
+
*
|
|
4
|
+
* This is the canonical wrapper that used to live in the client (HtmlNode's
|
|
5
|
+
* `buildSrcDoc`). It now lives on the server so a single document definition
|
|
6
|
+
* backs BOTH the in-canvas iframe and the "Open as site" tab — the iframe and
|
|
7
|
+
* the standalone tab load the exact same URL (/api/canvas/surface/:nodeId), so
|
|
8
|
+
* there is one render path and no content fork.
|
|
9
|
+
*
|
|
10
|
+
* Theming: instead of inlining a token `<style>` block, the document links the
|
|
11
|
+
* same-origin `/canvas/surface-theme.css` stylesheet and selects a palette via
|
|
12
|
+
* the `<html data-theme="...">` attribute. A sandboxed (opaque-origin) document
|
|
13
|
+
* can still load this same-origin stylesheet, and live theme switching works by
|
|
14
|
+
* toggling the attribute (the theme bridge below) — no CSS payload over
|
|
15
|
+
* postMessage required.
|
|
16
|
+
*/
|
|
17
|
+
export type SurfaceTheme = 'dark' | 'light' | 'high-contrast';
|
|
18
|
+
/** Path the surface document links for its theme tokens (served from dist/canvas). */
|
|
19
|
+
export declare const SURFACE_THEME_STYLESHEET = "/canvas/surface-theme.css";
|
|
20
|
+
/** CSP sandbox tokens for an `html`/`html-primitive` surface — scripts only, opaque origin. */
|
|
21
|
+
export declare const HTML_SURFACE_SANDBOX = "allow-scripts";
|
|
22
|
+
export declare function normalizeSurfaceTheme(value: string | null | undefined): SurfaceTheme;
|
|
23
|
+
export interface HtmlSurfaceOptions {
|
|
24
|
+
theme: SurfaceTheme;
|
|
25
|
+
/**
|
|
26
|
+
* Tab/document title. Injected as `<title>` only when the author HTML does not
|
|
27
|
+
* already declare one, so a standalone "Open as site" tab shows the node title
|
|
28
|
+
* instead of falling back to the raw URL.
|
|
29
|
+
*/
|
|
30
|
+
title?: string;
|
|
31
|
+
/** Client nonce that authorizes parent → iframe theme-update messages. */
|
|
32
|
+
themeToken?: string;
|
|
33
|
+
presentation?: boolean;
|
|
34
|
+
presentationExitToken?: string;
|
|
35
|
+
/** Inject window.PMX_AX.emit (only when the node's AX capabilities are enabled). */
|
|
36
|
+
axBridge?: boolean;
|
|
37
|
+
/** Nonce authorizing iframe → parent AX emits; embedded in the bridge. */
|
|
38
|
+
axToken?: string;
|
|
39
|
+
/** Node id stamped on emitted interactions. */
|
|
40
|
+
nodeId?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Wrap author HTML into a complete, themed standalone document. Accepts either a
|
|
44
|
+
* full HTML document (injects into its `<head>`) or a fragment (wraps it).
|
|
45
|
+
*/
|
|
46
|
+
export declare function buildHtmlSurfaceDocument(userHtml: string, options: HtmlSurfaceOptions): string;
|