@pillar-ai/sdk 0.1.28 → 0.1.30
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/actions/definitions/analytics.d.ts +18 -0
- package/dist/actions/definitions/content.d.ts +40 -0
- package/dist/actions/definitions/index.d.ts +26 -0
- package/dist/actions/definitions/navigation.d.ts +65 -0
- package/dist/actions/definitions/settings.d.ts +162 -0
- package/dist/actions/definitions/sources.d.ts +44 -0
- package/dist/actions/definitions/support.d.ts +15 -0
- package/dist/actions/definitions/team.d.ts +120 -0
- package/dist/actions/index.d.ts +1 -1
- package/dist/actions/types.d.ts +0 -89
- package/dist/api/ag-ui-adapter.d.ts +76 -0
- package/dist/api/ag-ui-bridge.d.ts +49 -0
- package/dist/api/ag-ui-client.d.ts +102 -0
- package/dist/api/ag-ui-handler.d.ts +89 -0
- package/dist/api/client.d.ts +2 -0
- package/dist/cli/sync.js +15 -3
- package/dist/components/Button/EdgeTrigger.d.ts +5 -0
- package/dist/components/Button/FloatingButton.d.ts +46 -0
- package/dist/components/PagePilot/styles.d.ts +1 -1
- package/dist/components/Panel/Panel.d.ts +5 -0
- package/dist/components/Panel/TabNavigation.d.ts +16 -0
- package/dist/components/Panel/styles.d.ts +1 -1
- package/dist/components/Progress/AGUIProgress.d.ts +15 -0
- package/dist/components/Tooltips/Tooltip.d.ts +46 -0
- package/dist/components/Tooltips/TooltipManager.d.ts +41 -0
- package/dist/components/Tooltips/index.d.ts +6 -0
- package/dist/components/Tooltips/styles.d.ts +5 -0
- package/dist/components/Views/ArticleChatView.d.ts +10 -0
- package/dist/components/Views/ArticleView.d.ts +10 -0
- package/dist/components/Views/CategoryView.d.ts +11 -0
- package/dist/components/Views/HelpCenterArticles.d.ts +17 -0
- package/dist/components/Views/SearchView.d.ts +10 -0
- package/dist/components/Views/SupportView.d.ts +15 -0
- package/dist/components/context.d.ts +6 -2
- package/dist/components/index.d.ts +0 -1
- package/dist/components/shared/ArticleCard.d.ts +17 -0
- package/dist/components/shared/CategoryCard.d.ts +17 -0
- package/dist/content/extensions/AccordionNode.d.ts +10 -0
- package/dist/content/extensions/CalloutNode.d.ts +11 -0
- package/dist/content/extensions/index.d.ts +5 -0
- package/dist/content/index.d.ts +5 -0
- package/dist/content/renderer.d.ts +24 -0
- package/dist/core/Pillar.d.ts +0 -1
- package/dist/core/config.d.ts +48 -0
- package/dist/pillar.esm.js +1 -1
- package/dist/store/suggestions.d.ts +1 -1
- package/dist/store/tooltips.d.ts +21 -0
- package/dist/tools/types.d.ts +29 -14
- package/dist/utils/helpdesk.d.ts +33 -0
- package/dist/utils/markdown.d.ts +9 -0
- package/dist/utils/normalize-tool-result.d.ts +10 -0
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AG-UI Bridge
|
|
3
|
+
*
|
|
4
|
+
* Temporary bridge that converts Phase 1's JSON-RPC wrapped AG-UI events
|
|
5
|
+
* to native AG-UI events. This allows the SDK to use AG-UI patterns while
|
|
6
|
+
* the backend still uses JSON-RPC transport.
|
|
7
|
+
*
|
|
8
|
+
* Will be removed after Phase 3 (pure AG-UI transport).
|
|
9
|
+
*/
|
|
10
|
+
import type { AGUIEvent } from '@ag-ui/core';
|
|
11
|
+
/**
|
|
12
|
+
* Unwrap an AG-UI event from a JSON-RPC notification.
|
|
13
|
+
*
|
|
14
|
+
* Phase 1 backend wraps AG-UI events like this:
|
|
15
|
+
* {
|
|
16
|
+
* "jsonrpc": "2.0",
|
|
17
|
+
* "method": "notifications/progress",
|
|
18
|
+
* "params": {
|
|
19
|
+
* "ag_ui_event": { "type": "RUN_STARTED", ... }
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* @param jsonRpcEvent - The JSON-RPC notification from the backend
|
|
24
|
+
* @returns The unwrapped AG-UI event, or null if not an AG-UI event
|
|
25
|
+
*/
|
|
26
|
+
export declare function unwrapAGUIEvent(jsonRpcEvent: unknown): AGUIEvent | null;
|
|
27
|
+
/**
|
|
28
|
+
* Check if a JSON-RPC event contains an AG-UI event.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isAGUIWrappedEvent(jsonRpcEvent: unknown): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Convert legacy MCP progress events to AG-UI events.
|
|
33
|
+
*
|
|
34
|
+
* This is for backwards compatibility during the transition.
|
|
35
|
+
* Converts old-style progress events to AG-UI events.
|
|
36
|
+
*
|
|
37
|
+
* @param legacyEvent - The legacy MCP progress event
|
|
38
|
+
* @returns An array of AG-UI events (may be multiple for some conversions)
|
|
39
|
+
*/
|
|
40
|
+
export declare function convertLegacyProgressToAGUI(legacyEvent: Record<string, unknown>): AGUIEvent[];
|
|
41
|
+
/**
|
|
42
|
+
* Process a raw SSE event and extract AG-UI events.
|
|
43
|
+
*
|
|
44
|
+
* Handles both new AG-UI wrapped events and legacy progress events.
|
|
45
|
+
*
|
|
46
|
+
* @param rawEvent - The parsed JSON from an SSE data line
|
|
47
|
+
* @returns An array of AG-UI events
|
|
48
|
+
*/
|
|
49
|
+
export declare function processSSEEvent(rawEvent: unknown): AGUIEvent[];
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AG-UI Protocol Client for Pillar SDK
|
|
3
|
+
*
|
|
4
|
+
* Implements the AG-UI specification for streaming agent interactions.
|
|
5
|
+
* Uses the @ag-ui/client HttpAgent for transport.
|
|
6
|
+
*
|
|
7
|
+
* Copyright (C) 2025 Pillar Team
|
|
8
|
+
*/
|
|
9
|
+
import type { ResolvedConfig } from '../core/config';
|
|
10
|
+
export interface AGUIStreamCallbacks {
|
|
11
|
+
/** Called when run starts */
|
|
12
|
+
onRunStarted?: (runId: string) => void;
|
|
13
|
+
/** Called when run completes successfully */
|
|
14
|
+
onRunFinished?: () => void;
|
|
15
|
+
/** Called on error */
|
|
16
|
+
onError?: (error: Error) => void;
|
|
17
|
+
/** Called when a step starts */
|
|
18
|
+
onStepStarted?: (stepName: string) => void;
|
|
19
|
+
/** Called when a step finishes */
|
|
20
|
+
onStepFinished?: (stepName: string) => void;
|
|
21
|
+
/** Called for text message streaming */
|
|
22
|
+
onTextContent?: (messageId: string, delta: string) => void;
|
|
23
|
+
/** Called when text message completes */
|
|
24
|
+
onTextComplete?: (messageId: string, fullContent: string) => void;
|
|
25
|
+
/** Called when tool call starts (for UI display) */
|
|
26
|
+
onToolCallStart?: (toolCallId: string, toolName: string) => void;
|
|
27
|
+
/** Called with tool call arguments */
|
|
28
|
+
onToolCallArgs?: (toolCallId: string, argsJson: string) => void;
|
|
29
|
+
/** Called when tool call completes */
|
|
30
|
+
onToolCallEnd?: (toolCallId: string) => void;
|
|
31
|
+
/** Called when tool result is available */
|
|
32
|
+
onToolCallResult?: (toolCallId: string, result: string) => void;
|
|
33
|
+
/** Called for state delta events (sources, actions, plan) */
|
|
34
|
+
onStateDelta?: (delta: unknown[]) => void;
|
|
35
|
+
/** Called for state snapshots */
|
|
36
|
+
onStateSnapshot?: (state: unknown) => void;
|
|
37
|
+
}
|
|
38
|
+
export interface ClientTool {
|
|
39
|
+
name: string;
|
|
40
|
+
description: string;
|
|
41
|
+
parameters: Record<string, unknown>;
|
|
42
|
+
/** Handler function - called when agent requests this tool */
|
|
43
|
+
handler?: (args: Record<string, unknown>) => Promise<unknown>;
|
|
44
|
+
}
|
|
45
|
+
export declare class AGUIClient {
|
|
46
|
+
private config;
|
|
47
|
+
private agent;
|
|
48
|
+
private currentRunId;
|
|
49
|
+
private currentThreadId;
|
|
50
|
+
private messageAccumulators;
|
|
51
|
+
private toolArgAccumulators;
|
|
52
|
+
private toolCallNames;
|
|
53
|
+
private registeredTools;
|
|
54
|
+
constructor(config: ResolvedConfig);
|
|
55
|
+
/**
|
|
56
|
+
* Get or create a persistent thread ID for this session.
|
|
57
|
+
*/
|
|
58
|
+
private getOrCreateThreadId;
|
|
59
|
+
private getBrowserLanguage;
|
|
60
|
+
/**
|
|
61
|
+
* Register a client-side tool that can be called by the agent.
|
|
62
|
+
*/
|
|
63
|
+
registerTool(tool: ClientTool): void;
|
|
64
|
+
/**
|
|
65
|
+
* Unregister a client-side tool.
|
|
66
|
+
*/
|
|
67
|
+
unregisterTool(toolName: string): void;
|
|
68
|
+
/**
|
|
69
|
+
* Send a message and stream the agent's response.
|
|
70
|
+
*/
|
|
71
|
+
chat(message: string, callbacks: AGUIStreamCallbacks, options?: {
|
|
72
|
+
history?: Array<{
|
|
73
|
+
role: 'user' | 'assistant';
|
|
74
|
+
content: string;
|
|
75
|
+
}>;
|
|
76
|
+
userContext?: Array<{
|
|
77
|
+
type: string;
|
|
78
|
+
[key: string]: unknown;
|
|
79
|
+
}>;
|
|
80
|
+
signal?: AbortSignal;
|
|
81
|
+
}): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Execute a client-side tool if registered.
|
|
84
|
+
*/
|
|
85
|
+
private maybeExecuteClientTool;
|
|
86
|
+
/**
|
|
87
|
+
* Send tool execution result back to the server.
|
|
88
|
+
*/
|
|
89
|
+
sendToolResult(toolCallId: string, result: unknown, error?: string): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Start a new conversation thread.
|
|
92
|
+
*/
|
|
93
|
+
newThread(): string;
|
|
94
|
+
/**
|
|
95
|
+
* Get current thread ID.
|
|
96
|
+
*/
|
|
97
|
+
get threadId(): string;
|
|
98
|
+
/**
|
|
99
|
+
* Get current run ID.
|
|
100
|
+
*/
|
|
101
|
+
get runId(): string | null;
|
|
102
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AG-UI Event Handler
|
|
3
|
+
*
|
|
4
|
+
* Processes AG-UI protocol events and maintains UI state.
|
|
5
|
+
* Replaces the complex JSON-RPC parsing in mcp-client.ts.
|
|
6
|
+
*/
|
|
7
|
+
import type { AGUIEvent } from '@ag-ui/core';
|
|
8
|
+
/** A streaming text message being accumulated */
|
|
9
|
+
export interface StreamingMessage {
|
|
10
|
+
id: string;
|
|
11
|
+
role: 'user' | 'assistant';
|
|
12
|
+
content: string;
|
|
13
|
+
complete: boolean;
|
|
14
|
+
/** Which step this message belongs to (for thinking vs response) */
|
|
15
|
+
stepName?: string;
|
|
16
|
+
}
|
|
17
|
+
/** A tool call being tracked */
|
|
18
|
+
export interface ToolCallState {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
args: string;
|
|
22
|
+
result?: unknown;
|
|
23
|
+
complete: boolean;
|
|
24
|
+
/** True if this tool executes on the client (query action) */
|
|
25
|
+
isClientSide?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** State delta data (sources, actions, plan, etc.) */
|
|
28
|
+
export interface StateDeltaData {
|
|
29
|
+
type: string;
|
|
30
|
+
data: unknown;
|
|
31
|
+
timestamp: number;
|
|
32
|
+
}
|
|
33
|
+
/** Complete AG-UI state */
|
|
34
|
+
export interface AGUIState {
|
|
35
|
+
/** Current run ID */
|
|
36
|
+
runId: string | null;
|
|
37
|
+
/** Thread ID (replaces conversation_id) */
|
|
38
|
+
threadId: string | null;
|
|
39
|
+
/** Current step name (e.g., "reasoning", "tool_execution") */
|
|
40
|
+
currentStep: string | null;
|
|
41
|
+
/** Streaming messages keyed by message ID */
|
|
42
|
+
messages: Map<string, StreamingMessage>;
|
|
43
|
+
/** Tool calls keyed by tool call ID */
|
|
44
|
+
toolCalls: Map<string, ToolCallState>;
|
|
45
|
+
/** State deltas received (sources, actions, plans) */
|
|
46
|
+
stateDeltas: StateDeltaData[];
|
|
47
|
+
/** Whether the run is complete */
|
|
48
|
+
isComplete: boolean;
|
|
49
|
+
/** Error if run failed */
|
|
50
|
+
error: Error | null;
|
|
51
|
+
}
|
|
52
|
+
export interface AGUIHandlerCallbacks {
|
|
53
|
+
/** Called whenever state changes */
|
|
54
|
+
onStateChange: (state: AGUIState) => void;
|
|
55
|
+
/** Called when an error occurs */
|
|
56
|
+
onError: (error: Error) => void;
|
|
57
|
+
/** Called when run completes successfully */
|
|
58
|
+
onComplete: () => void;
|
|
59
|
+
/** Called when a client-side tool needs execution */
|
|
60
|
+
onClientToolCall?: (toolCall: ToolCallState) => Promise<unknown>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Create an AG-UI event handler.
|
|
64
|
+
*
|
|
65
|
+
* Returns an object with a handleEvent method that processes
|
|
66
|
+
* AG-UI events and updates internal state.
|
|
67
|
+
*/
|
|
68
|
+
export declare function createAGUIHandler(callbacks: AGUIHandlerCallbacks): {
|
|
69
|
+
handleEvent: (event: AGUIEvent) => Promise<void>;
|
|
70
|
+
reset: () => void;
|
|
71
|
+
getState: () => AGUIState;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Register a tool as client-side.
|
|
75
|
+
* Called when the SDK registers an action with returns: true.
|
|
76
|
+
*/
|
|
77
|
+
export declare function registerClientSideTool(toolName: string): void;
|
|
78
|
+
/**
|
|
79
|
+
* Unregister a client-side tool.
|
|
80
|
+
*/
|
|
81
|
+
export declare function unregisterClientSideTool(toolName: string): void;
|
|
82
|
+
/**
|
|
83
|
+
* Check if a tool executes on the client side.
|
|
84
|
+
*/
|
|
85
|
+
export declare function isClientSideTool(toolName: string): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Get all registered client-side tools.
|
|
88
|
+
*/
|
|
89
|
+
export declare function getClientSideTools(): string[];
|
package/dist/api/client.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ export interface SuggestedQuestion {
|
|
|
25
25
|
text: string;
|
|
26
26
|
/** If true, this is an admin-configured suggestion that should rank first */
|
|
27
27
|
manual?: boolean;
|
|
28
|
+
/** Path pattern for filtering (e.g., "/pricing", "/blog/*", "/docs/**") */
|
|
29
|
+
pathPattern?: string;
|
|
28
30
|
}
|
|
29
31
|
export interface ChatResponse {
|
|
30
32
|
message: string;
|
package/dist/cli/sync.js
CHANGED
|
@@ -263,12 +263,21 @@ async function scanTools(scanDir) {
|
|
|
263
263
|
const arg = node.arguments[0];
|
|
264
264
|
const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
|
|
265
265
|
const relativePath = path.relative(process.cwd(), filePath);
|
|
266
|
-
const
|
|
266
|
+
const hasAstProperty = (astNode, propName) => astNode.properties.some(
|
|
267
|
+
(p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === propName
|
|
268
|
+
);
|
|
269
|
+
const processToolObject = (obj, line, astNode) => {
|
|
267
270
|
if (obj && typeof obj.name === "string" && typeof obj.description === "string") {
|
|
268
271
|
let toolType = obj.type;
|
|
269
272
|
if (toolType === "trigger_action") {
|
|
270
273
|
toolType = "trigger_tool";
|
|
271
274
|
}
|
|
275
|
+
const hasExecute = astNode ? hasAstProperty(astNode, "execute") : false;
|
|
276
|
+
if (hasExecute && !obj.outputSchema) {
|
|
277
|
+
console.warn(
|
|
278
|
+
`[pillar-sync] \u26A0 Tool "${obj.name}" has execute but no outputSchema (${relativePath}:${line})`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
272
281
|
tools.push({
|
|
273
282
|
name: obj.name,
|
|
274
283
|
description: obj.description,
|
|
@@ -279,6 +288,7 @@ async function scanTools(scanDir) {
|
|
|
279
288
|
examples: obj.examples,
|
|
280
289
|
autoRun: obj.autoRun,
|
|
281
290
|
autoComplete: obj.autoComplete,
|
|
291
|
+
requiredContext: obj.requiredContext,
|
|
282
292
|
sourceFile: relativePath,
|
|
283
293
|
line
|
|
284
294
|
});
|
|
@@ -291,13 +301,13 @@ async function scanTools(scanDir) {
|
|
|
291
301
|
};
|
|
292
302
|
if (ts.isObjectLiteralExpression(arg)) {
|
|
293
303
|
const obj = evaluateNode(arg, ts);
|
|
294
|
-
processToolObject(obj, lineNumber);
|
|
304
|
+
processToolObject(obj, lineNumber, arg);
|
|
295
305
|
} else if (ts.isArrayLiteralExpression(arg)) {
|
|
296
306
|
for (const element of arg.elements) {
|
|
297
307
|
if (ts.isObjectLiteralExpression(element)) {
|
|
298
308
|
const elementLine = sourceFile.getLineAndCharacterOfPosition(element.getStart()).line + 1;
|
|
299
309
|
const obj = evaluateNode(element, ts);
|
|
300
|
-
processToolObject(obj, elementLine);
|
|
310
|
+
processToolObject(obj, elementLine, element);
|
|
301
311
|
} else {
|
|
302
312
|
const elementLine = sourceFile.getLineAndCharacterOfPosition(element.getStart()).line + 1;
|
|
303
313
|
console.warn(
|
|
@@ -390,6 +400,8 @@ function buildManifestFromScan(tools, platform, version, gitSha, agentGuidance)
|
|
|
390
400
|
entry.data_schema = tool.inputSchema;
|
|
391
401
|
if (tool.outputSchema)
|
|
392
402
|
entry.output_schema = tool.outputSchema;
|
|
403
|
+
if (tool.requiredContext)
|
|
404
|
+
entry.required_context = tool.requiredContext;
|
|
393
405
|
entries.push(entry);
|
|
394
406
|
}
|
|
395
407
|
const manifest = {
|
|
@@ -58,6 +58,11 @@ export declare class EdgeTrigger {
|
|
|
58
58
|
* Initialize the edge trigger
|
|
59
59
|
*/
|
|
60
60
|
init(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Resolve the push target element from config.
|
|
63
|
+
* Returns the configured element or falls back to document.documentElement.
|
|
64
|
+
*/
|
|
65
|
+
private getPushTargetElement;
|
|
61
66
|
/**
|
|
62
67
|
* Apply padding to reserve space for trigger + panel (when open in push mode)
|
|
63
68
|
* In hover mode, only reserve trigger width even when panel is open
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Floating Help Button Component
|
|
3
|
+
* A floating action button that opens the help panel
|
|
4
|
+
*/
|
|
5
|
+
import type { ResolvedConfig, FloatingButtonPosition } from '../../core/config';
|
|
6
|
+
/**
|
|
7
|
+
* FloatingButton class that manages the button lifecycle
|
|
8
|
+
* Uses Preact for rendering but maintains imperative control
|
|
9
|
+
*/
|
|
10
|
+
export declare class FloatingButton {
|
|
11
|
+
private config;
|
|
12
|
+
private onClick;
|
|
13
|
+
private container;
|
|
14
|
+
private stylesInjected;
|
|
15
|
+
private _isHidden;
|
|
16
|
+
constructor(config: ResolvedConfig, onClick: () => void);
|
|
17
|
+
/**
|
|
18
|
+
* Initialize the floating button
|
|
19
|
+
*/
|
|
20
|
+
init(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Set the open state (to update icon when panel opens)
|
|
23
|
+
*/
|
|
24
|
+
setOpen(_isOpen: boolean): void;
|
|
25
|
+
/**
|
|
26
|
+
* Show the button
|
|
27
|
+
*/
|
|
28
|
+
show(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Hide the button
|
|
31
|
+
*/
|
|
32
|
+
hide(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Update button position
|
|
35
|
+
*/
|
|
36
|
+
setPosition(position: FloatingButtonPosition): void;
|
|
37
|
+
/**
|
|
38
|
+
* Update button label
|
|
39
|
+
*/
|
|
40
|
+
setLabel(label: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* Destroy the button
|
|
43
|
+
*/
|
|
44
|
+
destroy(): void;
|
|
45
|
+
private render;
|
|
46
|
+
}
|
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* Injected into the document head (outside Shadow DOM)
|
|
4
4
|
* Uses the same CSS variables as the Pillar panel for consistent theming
|
|
5
5
|
*/
|
|
6
|
-
export declare const PAGE_PILOT_STYLES = "\n/* Pillar Page Pilot Banner Styles */\n\n/* Define CSS variables at the container level (same as panel) */\n#pillar-page-pilot-container {\n /* Core colors - Light mode (default) */\n --pillar-primary: #2563eb;\n --pillar-primary-hover: #1d4ed8;\n --pillar-bg: #ffffff;\n --pillar-bg-secondary: #f9fafb;\n --pillar-text: #1a1a1a;\n --pillar-text-secondary: #374151;\n --pillar-border: #e5e7eb;\n --pillar-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n --pillar-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n --pillar-radius-lg: 8px;\n --pillar-radius-md: 6px;\n --pillar-transition-fast: 0.15s ease;\n}\n\n/* Dark mode - Auto-detect from system preference */\n@media (prefers-color-scheme: dark) {\n #pillar-page-pilot-container:not([data-theme=\"light\"]) {\n --pillar-primary: #3b82f6;\n --pillar-primary-hover: #60a5fa;\n --pillar-bg: #1a1a1a;\n --pillar-bg-secondary: #262626;\n --pillar-text: #f5f5f5;\n --pillar-text-secondary: #e5e5e5;\n --pillar-border: #404040;\n --pillar-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);\n }\n}\n\n/* Dark mode - Manual override via html class or data attribute */\nhtml.dark #pillar-page-pilot-container,\n[data-theme=\"dark\"] #pillar-page-pilot-container,\n#pillar-page-pilot-container[data-theme=\"dark\"] {\n --pillar-primary: #3b82f6;\n --pillar-primary-hover: #60a5fa;\n --pillar-bg: #1a1a1a;\n --pillar-bg-secondary: #262626;\n --pillar-text: #f5f5f5;\n --pillar-text-secondary: #e5e5e5;\n --pillar-border: #404040;\n --pillar-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);\n}\n\n@keyframes pillar-pulse {\n 0%, 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.6;\n transform: scale(1.1);\n }\n}\n\n@keyframes pillar-banner-fade-in {\n from {\n opacity: 0;\n transform: translateY(-100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n._pillar-page-pilot-banner {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n z-index: 99999;\n font-family: var(--pillar-font-family);\n display: flex;\n justify-content: center;\n pointer-events: none;\n animation: pillar-banner-fade-in 0.2s ease-out;\n}\n\n/* Viewport outline \u2014 3px border on left, right, bottom; top handled by tab shape */\n._pillar-page-pilot-banner::before {\n content: '';\n position: fixed;\n inset: 0;\n border: 3px solid var(--pillar-primary);\n border-top: none;\n pointer-events: none;\n z-index: 99998;\n}\n\n/* Top border segments on either side of the tab */\n._pillar-page-pilot-banner::after {\n content: '';\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--pillar-primary);\n pointer-events: none;\n z-index: 99997;\n}\n\n._pillar-page-pilot-banner__content {\n position: relative;\n z-index: 99999;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 20px;\n background: var(--pillar-primary);\n color: #ffffff;\n border-bottom-left-radius: var(--pillar-radius-lg);\n border-bottom-right-radius: var(--pillar-radius-lg);\n pointer-events: auto;\n}\n\n._pillar-page-pilot-banner__indicator {\n width: 8px;\n height: 8px;\n background: #ffffff;\n border-radius: 50%;\n animation: pillar-pulse 1.5s ease-in-out infinite;\n flex-shrink: 0;\n}\n\n._pillar-page-pilot-banner__text {\n font-size: 13px;\n font-weight: 500;\n color: #ffffff;\n white-space: nowrap;\n}\n\n._pillar-page-pilot-banner__stop {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 5px 10px;\n margin-left: 4px;\n font-family: inherit;\n font-size: 12px;\n font-weight: 500;\n color: #ffffff;\n background: rgba(255, 255, 255, 0.15);\n border: 1px solid rgba(255, 255, 255, 0.3);\n border-radius: var(--pillar-radius-md);\n cursor: pointer;\n transition: all var(--pillar-transition-fast);\n}\n\n._pillar-page-pilot-banner__stop:hover {\n background: rgba(255, 255, 255, 0.25);\n border-color: rgba(255, 255, 255, 0.5);\n}\n\n._pillar-page-pilot-banner__stop:active {\n transform: scale(0.97);\n}\n\n._pillar-page-pilot-banner__stop-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n}\n\n._pillar-page-pilot-banner__stop-icon svg {\n width: 100%;\n height: 100%;\n}\n
|
|
6
|
+
export declare const PAGE_PILOT_STYLES = "\n/* Pillar Page Pilot Banner Styles */\n\n/* Define CSS variables at the container level (same as panel) */\n#pillar-page-pilot-container {\n /* Core colors - Light mode (default) */\n --pillar-primary: #2563eb;\n --pillar-primary-hover: #1d4ed8;\n --pillar-bg: #ffffff;\n --pillar-bg-secondary: #f9fafb;\n --pillar-text: #1a1a1a;\n --pillar-text-secondary: #374151;\n --pillar-border: #e5e7eb;\n --pillar-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n --pillar-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n --pillar-radius-lg: 8px;\n --pillar-radius-md: 6px;\n --pillar-transition-fast: 0.15s ease;\n}\n\n/* Dark mode - Auto-detect from system preference */\n@media (prefers-color-scheme: dark) {\n #pillar-page-pilot-container:not([data-theme=\"light\"]) {\n --pillar-primary: #3b82f6;\n --pillar-primary-hover: #60a5fa;\n --pillar-bg: #1a1a1a;\n --pillar-bg-secondary: #262626;\n --pillar-text: #f5f5f5;\n --pillar-text-secondary: #e5e5e5;\n --pillar-border: #404040;\n --pillar-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);\n }\n}\n\n/* Dark mode - Manual override via html class or data attribute */\nhtml.dark #pillar-page-pilot-container,\n[data-theme=\"dark\"] #pillar-page-pilot-container,\n#pillar-page-pilot-container[data-theme=\"dark\"] {\n --pillar-primary: #3b82f6;\n --pillar-primary-hover: #60a5fa;\n --pillar-bg: #1a1a1a;\n --pillar-bg-secondary: #262626;\n --pillar-text: #f5f5f5;\n --pillar-text-secondary: #e5e5e5;\n --pillar-border: #404040;\n --pillar-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);\n}\n\n@keyframes pillar-pulse {\n 0%, 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.6;\n transform: scale(1.1);\n }\n}\n\n@keyframes pillar-banner-fade-in {\n from {\n opacity: 0;\n transform: translateY(-100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n._pillar-page-pilot-banner {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n z-index: 99999;\n font-family: var(--pillar-font-family);\n display: flex;\n justify-content: center;\n pointer-events: none;\n animation: pillar-banner-fade-in 0.2s ease-out;\n}\n\n/* Viewport outline \u2014 3px border on left, right, bottom; top handled by tab shape */\n._pillar-page-pilot-banner::before {\n content: '';\n position: fixed;\n inset: 0;\n border: 3px solid var(--pillar-primary);\n border-top: none;\n pointer-events: none;\n z-index: 99998;\n}\n\n/* Top border segments on either side of the tab */\n._pillar-page-pilot-banner::after {\n content: '';\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--pillar-primary);\n pointer-events: none;\n z-index: 99997;\n}\n\n._pillar-page-pilot-banner__content {\n position: relative;\n z-index: 99999;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 20px;\n background: var(--pillar-primary);\n color: #ffffff;\n border-bottom-left-radius: var(--pillar-radius-lg);\n border-bottom-right-radius: var(--pillar-radius-lg);\n pointer-events: auto;\n}\n\n._pillar-page-pilot-banner__indicator {\n width: 8px;\n height: 8px;\n background: #ffffff;\n border-radius: 50%;\n animation: pillar-pulse 1.5s ease-in-out infinite;\n flex-shrink: 0;\n}\n\n._pillar-page-pilot-banner__text {\n font-size: 13px;\n font-weight: 500;\n color: #ffffff;\n white-space: nowrap;\n}\n\n._pillar-page-pilot-banner__stop {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 5px 10px;\n margin-left: 4px;\n font-family: inherit;\n font-size: 12px;\n font-weight: 500;\n color: #ffffff;\n background: rgba(255, 255, 255, 0.15);\n border: 1px solid rgba(255, 255, 255, 0.3);\n border-radius: var(--pillar-radius-md);\n cursor: pointer;\n transition: all var(--pillar-transition-fast);\n}\n\n._pillar-page-pilot-banner__stop:hover {\n background: rgba(255, 255, 255, 0.25);\n border-color: rgba(255, 255, 255, 0.5);\n}\n\n._pillar-page-pilot-banner__stop:active {\n transform: scale(0.97);\n}\n\n._pillar-page-pilot-banner__stop-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n}\n\n._pillar-page-pilot-banner__stop-icon svg {\n width: 100%;\n height: 100%;\n}\n";
|
|
@@ -81,6 +81,11 @@ export declare class Panel {
|
|
|
81
81
|
* inline styles too (class-based overrides lose to inline specificity).
|
|
82
82
|
*/
|
|
83
83
|
private setBackdropVisible;
|
|
84
|
+
/**
|
|
85
|
+
* Resolve the push target element from config.
|
|
86
|
+
* Returns the configured element or falls back to document.documentElement.
|
|
87
|
+
*/
|
|
88
|
+
private getPushTargetElement;
|
|
84
89
|
private applyPushModeStyles;
|
|
85
90
|
private removePushModeStyles;
|
|
86
91
|
/**
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tab Navigation Component
|
|
3
|
+
* Vertical tabs on the right edge of the panel for switching between Assistant and Support
|
|
4
|
+
*/
|
|
5
|
+
import { h } from 'preact';
|
|
6
|
+
import type { ResolvedSupportConfig } from '../../core/config';
|
|
7
|
+
interface TabNavigationProps {
|
|
8
|
+
supportConfig: ResolvedSupportConfig;
|
|
9
|
+
}
|
|
10
|
+
export declare function TabNavigation({ supportConfig }: TabNavigationProps): h.JSX.Element;
|
|
11
|
+
/**
|
|
12
|
+
* CSS Styles for Tab Navigation
|
|
13
|
+
* Should be appended to PANEL_STYLES
|
|
14
|
+
*/
|
|
15
|
+
export declare const TAB_NAVIGATION_STYLES = "\n/* ============================================================================\n Panel Wrapper (for tab layout)\n Horizontal flex container with main content + tab nav\n ============================================================================ */\n\n._pillar-panel-wrapper {\n display: flex;\n flex-direction: row;\n height: 100%;\n overflow: hidden;\n}\n\n._pillar-panel-wrapper > ._pillar-panel-ui {\n flex: 1;\n min-width: 0;\n}\n\n.pillar-panel-wrapper {}\n\n/* ============================================================================\n Tab Navigation\n Vertical tabs on the right edge of the panel\n ============================================================================ */\n\n._pillar-tab-nav {\n display: flex;\n flex-direction: column;\n width: 48px;\n min-width: 48px;\n background: var(--pillar-bg-secondary);\n border-left: 1px solid var(--pillar-border);\n padding: var(--pillar-spacing-sm) 0;\n gap: var(--pillar-spacing-xs);\n}\n\n._pillar-tab {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 2px;\n padding: var(--pillar-spacing-sm) var(--pillar-spacing-xs);\n margin: 0 var(--pillar-spacing-xs);\n border: none;\n border-radius: var(--pillar-radius-md);\n background: transparent;\n color: var(--pillar-text-muted);\n cursor: pointer;\n transition: all var(--pillar-transition-fast);\n position: relative;\n}\n\n._pillar-tab:hover {\n background: var(--pillar-bg-tertiary);\n color: var(--pillar-text);\n}\n\n._pillar-tab--active {\n background: var(--pillar-primary-light);\n color: var(--pillar-primary);\n}\n\n._pillar-tab--active:hover {\n background: var(--pillar-primary-light-hover);\n color: var(--pillar-primary);\n}\n\n._pillar-tab-icon {\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n._pillar-tab-icon svg {\n width: 100%;\n height: 100%;\n}\n\n._pillar-tab-label {\n font-size: 9px;\n font-weight: 500;\n text-align: center;\n line-height: 1.2;\n max-width: 40px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Public override classes */\n.pillar-tab-nav {}\n.pillar-tab {}\n.pillar-tab-icon {}\n.pillar-tab-label {}\n";
|
|
16
|
+
export {};
|