@pillar-ai/sdk 0.1.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/README.md +129 -0
- 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 +33 -0
- package/dist/actions/registry.d.ts +110 -0
- package/dist/actions/types.d.ts +388 -0
- package/dist/api/client.d.ts +186 -0
- package/dist/api/mcp-client.d.ts +226 -0
- package/dist/button/FloatingButton.d.ts +44 -0
- package/dist/cli/sync.d.ts +2 -0
- package/dist/components/Button/EdgeTrigger.d.ts +78 -0
- package/dist/components/Button/FloatingButton.d.ts +46 -0
- package/dist/components/Button/index.d.ts +5 -0
- package/dist/components/Cards/ConfirmActionCard.d.ts +23 -0
- package/dist/components/Cards/index.d.ts +6 -0
- package/dist/components/Panel/ChatInput.d.ts +5 -0
- package/dist/components/Panel/ContextTag.d.ts +18 -0
- package/dist/components/Panel/Header.d.ts +14 -0
- package/dist/components/Panel/Panel.d.ts +104 -0
- package/dist/components/Panel/PanelContent.d.ts +6 -0
- package/dist/components/Panel/TaskButton.d.ts +59 -0
- package/dist/components/Panel/UnifiedChatInput.d.ts +23 -0
- package/dist/components/Panel/WorkflowChecklist.d.ts +9 -0
- package/dist/components/Panel/index.d.ts +13 -0
- package/dist/components/Panel/styles.d.ts +20 -0
- package/dist/components/Plan/InlinePlanView.d.ts +24 -0
- package/dist/components/Plan/PlanStepItem.d.ts +18 -0
- package/dist/components/Plan/PlanView.d.ts +10 -0
- package/dist/components/Plan/index.d.ts +8 -0
- package/dist/components/TextSelection/TextSelectionManager.d.ts +34 -0
- package/dist/components/TextSelection/TextSelectionPopover.d.ts +14 -0
- package/dist/components/TextSelection/index.d.ts +6 -0
- package/dist/components/TextSelection/styles.d.ts +5 -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 +9 -0
- package/dist/components/Views/ArticleView.d.ts +10 -0
- package/dist/components/Views/CategoryView.d.ts +11 -0
- package/dist/components/Views/ChatView.d.ts +5 -0
- package/dist/components/Views/DeveloperView.d.ts +6 -0
- package/dist/components/Views/HomeView.d.ts +5 -0
- package/dist/components/Views/SearchView.d.ts +10 -0
- package/dist/components/Views/index.d.ts +5 -0
- package/dist/components/context.d.ts +21 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/components/shared/ArticleCard.d.ts +17 -0
- package/dist/components/shared/CategoryCard.d.ts +17 -0
- package/dist/components/shared/Empty.d.ts +11 -0
- package/dist/components/shared/Loading.d.ts +6 -0
- package/dist/components/shared/MessageInputArea.d.ts +19 -0
- package/dist/components/shared/QuestionChip.d.ts +14 -0
- package/dist/components/shared/index.d.ts +7 -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 +454 -0
- package/dist/core/config.d.ts +253 -0
- package/dist/core/context.d.ts +71 -0
- package/dist/core/events.d.ts +228 -0
- package/dist/core/plan-executor.d.ts +101 -0
- package/dist/core/plan.d.ts +155 -0
- package/dist/core/workflow.d.ts +89 -0
- package/dist/index.d.ts +32 -0
- package/dist/panel/Panel.d.ts +53 -0
- package/dist/panel/PanelUI.d.ts +43 -0
- package/dist/panel/components/ArticleCard.d.ts +10 -0
- package/dist/panel/components/CategoryCard.d.ts +10 -0
- package/dist/panel/components/ChatInput.d.ts +36 -0
- package/dist/panel/components/Header.d.ts +16 -0
- package/dist/panel/components/SearchInput.d.ts +11 -0
- package/dist/panel/styles.d.ts +5 -0
- package/dist/panel/views/ArticleView.d.ts +21 -0
- package/dist/panel/views/CategoryView.d.ts +20 -0
- package/dist/panel/views/ChatView.d.ts +30 -0
- package/dist/panel/views/HomeView.d.ts +18 -0
- package/dist/panel/views/SearchView.d.ts +22 -0
- package/dist/pillar.esm.js +10338 -0
- package/dist/pillar.esm.js.map +1 -0
- package/dist/pillar.js +10362 -0
- package/dist/pillar.js.map +1 -0
- package/dist/pillar.min.js +2 -0
- package/dist/pillar.min.js.map +1 -0
- package/dist/store/chat.d.ts +85 -0
- package/dist/store/context.d.ts +46 -0
- package/dist/store/developer.d.ts +19 -0
- package/dist/store/index.d.ts +10 -0
- package/dist/store/panel.d.ts +43 -0
- package/dist/store/plan-persistence.d.ts +47 -0
- package/dist/store/plan.d.ts +45 -0
- package/dist/store/router.d.ts +18 -0
- package/dist/store/tooltips.d.ts +21 -0
- package/dist/store/workflow.d.ts +48 -0
- package/dist/tooltips/Tooltip.d.ts +63 -0
- package/dist/tooltips/TooltipManager.d.ts +42 -0
- package/dist/tooltips/styles.d.ts +5 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/user-context.d.ts +29 -0
- package/dist/utils/dom.d.ts +46 -0
- package/dist/utils/markdown.d.ts +9 -0
- package/dist/utils/positioning.d.ts +52 -0
- package/dist/utils/urlParams.d.ts +27 -0
- package/package.json +86 -0
- package/src/actions/types.ts +468 -0
- package/src/cli/sync.ts +477 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution Plan Types
|
|
3
|
+
*
|
|
4
|
+
* Types for server-generated multi-step execution plans. These types
|
|
5
|
+
* match the backend ExecutionPlan and ExecutionStep model `to_dict()` output.
|
|
6
|
+
*
|
|
7
|
+
* Plans are created by the ReAct agent when it determines that a user's
|
|
8
|
+
* request requires multiple sequential actions. The plan is persisted
|
|
9
|
+
* server-side and streamed to the client for execution.
|
|
10
|
+
*
|
|
11
|
+
* @see backend/apps/mcp/models/execution_plan.py
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Plan status values from PlanStatus enum.
|
|
15
|
+
* Matches backend PlanStatus.choices.
|
|
16
|
+
*/
|
|
17
|
+
export type PlanStatus = 'planning' | 'ready' | 'executing' | 'awaiting_start' | 'awaiting_input' | 'awaiting_result' | 'completed' | 'failed' | 'cancelled';
|
|
18
|
+
/**
|
|
19
|
+
* Step status values from StepStatus enum.
|
|
20
|
+
* Matches backend StepStatus.choices.
|
|
21
|
+
*/
|
|
22
|
+
export type StepStatus = 'pending' | 'ready' | 'awaiting_confirmation' | 'executing' | 'awaiting_result' | 'completed' | 'skipped' | 'failed';
|
|
23
|
+
/**
|
|
24
|
+
* Execution location for a step.
|
|
25
|
+
*/
|
|
26
|
+
export type ExecutionLocation = 'client' | 'server';
|
|
27
|
+
/**
|
|
28
|
+
* A multi-step execution plan.
|
|
29
|
+
* Matches ExecutionPlan.to_dict() output.
|
|
30
|
+
*/
|
|
31
|
+
export interface ExecutionPlan {
|
|
32
|
+
/** UUID string */
|
|
33
|
+
id: string;
|
|
34
|
+
/** Interpreted goal statement */
|
|
35
|
+
goal: string;
|
|
36
|
+
/** Original user query */
|
|
37
|
+
query: string;
|
|
38
|
+
/** Current plan status */
|
|
39
|
+
status: PlanStatus;
|
|
40
|
+
/** If true, plan starts executing immediately. If false, user must click Start. */
|
|
41
|
+
auto_execute: boolean;
|
|
42
|
+
/** Total number of steps in the plan */
|
|
43
|
+
total_steps: number;
|
|
44
|
+
/** Number of completed steps */
|
|
45
|
+
completed_steps: number;
|
|
46
|
+
/** Minutes before plan is considered timed out */
|
|
47
|
+
timeout_minutes: number;
|
|
48
|
+
/** All steps in the plan */
|
|
49
|
+
steps: ExecutionStep[];
|
|
50
|
+
/** When the plan was created (ISO timestamp) */
|
|
51
|
+
created_at: string | null;
|
|
52
|
+
/** When the plan completed (ISO timestamp) */
|
|
53
|
+
completed_at: string | null;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A single step in an execution plan.
|
|
57
|
+
* Matches ExecutionStep.to_dict() output.
|
|
58
|
+
*/
|
|
59
|
+
export interface ExecutionStep {
|
|
60
|
+
/** UUID string */
|
|
61
|
+
id: string;
|
|
62
|
+
/** Step order (0-indexed) */
|
|
63
|
+
index: number;
|
|
64
|
+
/** Human-readable step description */
|
|
65
|
+
description: string;
|
|
66
|
+
/** Name of the action to execute */
|
|
67
|
+
action_name: string;
|
|
68
|
+
/** Data payload for the action */
|
|
69
|
+
action_data: Record<string, unknown>;
|
|
70
|
+
/** Where this step executes (client or server) */
|
|
71
|
+
execution_location: ExecutionLocation;
|
|
72
|
+
/** If true, pause for user confirmation before executing */
|
|
73
|
+
requires_user_confirmation: boolean;
|
|
74
|
+
/** If true, client must send result back to server */
|
|
75
|
+
requires_result_feedback: boolean;
|
|
76
|
+
/** Execute immediately without user clicking */
|
|
77
|
+
auto_run: boolean;
|
|
78
|
+
/** Mark complete immediately after execution */
|
|
79
|
+
auto_complete: boolean;
|
|
80
|
+
/** Custom card type for confirmation UI */
|
|
81
|
+
confirmation_card_type: string;
|
|
82
|
+
/** Configuration for the confirmation card */
|
|
83
|
+
confirmation_card_config: Record<string, unknown>;
|
|
84
|
+
/** List of step UUIDs this step depends on */
|
|
85
|
+
depends_on: string[];
|
|
86
|
+
/** Current step status */
|
|
87
|
+
status: StepStatus;
|
|
88
|
+
/** Result data from step execution */
|
|
89
|
+
result: unknown | null;
|
|
90
|
+
/** Error message if step failed */
|
|
91
|
+
error_message: string;
|
|
92
|
+
/** Number of retry attempts made */
|
|
93
|
+
retry_count: number;
|
|
94
|
+
/** Maximum retry attempts allowed */
|
|
95
|
+
max_retries: number;
|
|
96
|
+
/** Whether this step can be retried on failure */
|
|
97
|
+
is_retriable: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* @deprecated LLM now generates contextual guidance in the response text instead.
|
|
100
|
+
* This field is no longer populated by the backend.
|
|
101
|
+
*/
|
|
102
|
+
awaiting_instruction?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Plan-related events emitted by the SDK.
|
|
106
|
+
*/
|
|
107
|
+
export interface PlanEvents {
|
|
108
|
+
/** Plan execution has started */
|
|
109
|
+
'plan:start': ExecutionPlan;
|
|
110
|
+
/** A step has become active (started executing) */
|
|
111
|
+
'plan:step:active': {
|
|
112
|
+
plan: ExecutionPlan;
|
|
113
|
+
step: ExecutionStep;
|
|
114
|
+
};
|
|
115
|
+
/** A step is awaiting user confirmation */
|
|
116
|
+
'plan:step:confirm': {
|
|
117
|
+
plan: ExecutionPlan;
|
|
118
|
+
step: ExecutionStep;
|
|
119
|
+
};
|
|
120
|
+
/** A step has completed (success or failure) */
|
|
121
|
+
'plan:step:complete': {
|
|
122
|
+
plan: ExecutionPlan;
|
|
123
|
+
step: ExecutionStep;
|
|
124
|
+
success: boolean;
|
|
125
|
+
};
|
|
126
|
+
/** A step was skipped by the user */
|
|
127
|
+
'plan:step:skip': {
|
|
128
|
+
plan: ExecutionPlan;
|
|
129
|
+
step: ExecutionStep;
|
|
130
|
+
};
|
|
131
|
+
/** A step has failed (includes retry info) */
|
|
132
|
+
'plan:step:failed': {
|
|
133
|
+
plan: ExecutionPlan;
|
|
134
|
+
step: ExecutionStep;
|
|
135
|
+
error: Error;
|
|
136
|
+
canRetry: boolean;
|
|
137
|
+
};
|
|
138
|
+
/** A step is being retried */
|
|
139
|
+
'plan:step:retry': {
|
|
140
|
+
plan: ExecutionPlan;
|
|
141
|
+
step: ExecutionStep;
|
|
142
|
+
retryCount: number;
|
|
143
|
+
};
|
|
144
|
+
/** Plan was updated (e.g., after server analysis) */
|
|
145
|
+
'plan:updated': ExecutionPlan;
|
|
146
|
+
/** All steps complete, plan finished */
|
|
147
|
+
'plan:complete': ExecutionPlan;
|
|
148
|
+
/** Plan was cancelled by the user */
|
|
149
|
+
'plan:cancel': ExecutionPlan;
|
|
150
|
+
/** An error occurred during plan execution */
|
|
151
|
+
'plan:error': {
|
|
152
|
+
plan: ExecutionPlan;
|
|
153
|
+
error: Error;
|
|
154
|
+
};
|
|
155
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Types
|
|
3
|
+
*
|
|
4
|
+
* Types for dynamic workflow composition - multi-step sequences
|
|
5
|
+
* composed from atomic ActionTasks at runtime.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Status of a workflow step
|
|
9
|
+
*/
|
|
10
|
+
export type WorkflowStepStatus = 'pending' | 'awaiting_initiation' | 'active' | 'completed' | 'skipped' | 'failed';
|
|
11
|
+
/**
|
|
12
|
+
* A single step in a workflow
|
|
13
|
+
*/
|
|
14
|
+
export interface WorkflowStep {
|
|
15
|
+
/** Step index in the workflow */
|
|
16
|
+
index: number;
|
|
17
|
+
/** Database ID of the ActionTask */
|
|
18
|
+
task_id?: string;
|
|
19
|
+
/** Task identifier */
|
|
20
|
+
task_name: string;
|
|
21
|
+
/** Task type for built-in handling */
|
|
22
|
+
task_type: 'navigate' | 'open_modal' | 'fill_form' | 'trigger_action' | 'copy_text' | 'external_link' | 'start_tutorial';
|
|
23
|
+
/** Human-readable label */
|
|
24
|
+
label: string;
|
|
25
|
+
/** Task description */
|
|
26
|
+
description?: string;
|
|
27
|
+
/** Helpful note for the user */
|
|
28
|
+
note?: string;
|
|
29
|
+
/** Data payload for this step */
|
|
30
|
+
data: Record<string, unknown>;
|
|
31
|
+
/** Current step status */
|
|
32
|
+
status: WorkflowStepStatus;
|
|
33
|
+
/**
|
|
34
|
+
* If true, action executes immediately without user clicking.
|
|
35
|
+
* If false, shows button and waits for user interaction.
|
|
36
|
+
* Used for safe, reversible actions like navigation.
|
|
37
|
+
*/
|
|
38
|
+
auto_run: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* If true, step completes immediately after execution without
|
|
41
|
+
* waiting for host app confirmation.
|
|
42
|
+
* Used for simple navigations and clipboard operations.
|
|
43
|
+
*/
|
|
44
|
+
auto_complete: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A workflow composed of multiple steps
|
|
48
|
+
*/
|
|
49
|
+
export interface Workflow {
|
|
50
|
+
/** Unique workflow ID for this session (ephemeral) */
|
|
51
|
+
id: string;
|
|
52
|
+
/** Human-readable title */
|
|
53
|
+
title: string;
|
|
54
|
+
/** Workflow description */
|
|
55
|
+
description?: string;
|
|
56
|
+
/** Ordered steps */
|
|
57
|
+
steps: WorkflowStep[];
|
|
58
|
+
/** Total number of steps */
|
|
59
|
+
total_steps: number;
|
|
60
|
+
/** Currently active step index */
|
|
61
|
+
current_step: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Events emitted during workflow execution
|
|
65
|
+
*/
|
|
66
|
+
export interface WorkflowEvents {
|
|
67
|
+
/** Workflow has started */
|
|
68
|
+
'workflow:start': Workflow;
|
|
69
|
+
/** A step has become active (started executing) */
|
|
70
|
+
'workflow:step:active': {
|
|
71
|
+
workflow: Workflow;
|
|
72
|
+
step: WorkflowStep;
|
|
73
|
+
};
|
|
74
|
+
/** A step has completed (success or failure) */
|
|
75
|
+
'workflow:step:complete': {
|
|
76
|
+
workflow: Workflow;
|
|
77
|
+
step: WorkflowStep;
|
|
78
|
+
success: boolean;
|
|
79
|
+
};
|
|
80
|
+
/** A step was skipped by the user */
|
|
81
|
+
'workflow:step:skip': {
|
|
82
|
+
workflow: Workflow;
|
|
83
|
+
step: WorkflowStep;
|
|
84
|
+
};
|
|
85
|
+
/** All steps complete, workflow finished */
|
|
86
|
+
'workflow:complete': Workflow;
|
|
87
|
+
/** Workflow was cancelled by the user */
|
|
88
|
+
'workflow:cancel': Workflow;
|
|
89
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pillar SDK - Embedded Help for Your Application
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* // Script tag usage
|
|
6
|
+
* <script src="https://cdn.trypillar.com/sdk/pillar.min.js"></script>
|
|
7
|
+
* <script>
|
|
8
|
+
* Pillar.init({
|
|
9
|
+
* helpCenter: 'your-help-center',
|
|
10
|
+
* publicKey: 'pk_live_xxx',
|
|
11
|
+
* });
|
|
12
|
+
* </script>
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* // ES Module usage
|
|
16
|
+
* import { Pillar } from '@pillar-ai/sdk';
|
|
17
|
+
*
|
|
18
|
+
* await Pillar.init({
|
|
19
|
+
* helpCenter: 'your-help-center',
|
|
20
|
+
* publicKey: 'pk_live_xxx',
|
|
21
|
+
* });
|
|
22
|
+
*/
|
|
23
|
+
export { Pillar, type PillarState } from './core/Pillar';
|
|
24
|
+
export { EventEmitter, type PillarEvents, type TaskExecutePayload, type CardRenderer, type CardCallbacks } from './core/events';
|
|
25
|
+
export { type PillarConfig, type ResolvedConfig, type ResolvedPanelConfig, type PanelConfig, type FloatingButtonConfig, type TooltipsConfig, type UrlParamsConfig, type TextSelectionConfig, type UserContext, type PanelPosition, type PanelMode, type FloatingButtonPosition, type FloatingButtonStyle, type TooltipTrigger, type TooltipPosition, type ThemeMode, type ThemeColors, type ThemeConfig, type ResolvedThemeConfig, type SidebarTabConfig, DEFAULT_SIDEBAR_TABS, } from './core/config';
|
|
26
|
+
export { type ProductContext, type UserProfile, type Suggestion, type AssistantContext, } from './core/context';
|
|
27
|
+
export { type PlanStatus, type StepStatus, type ExecutionLocation, type ExecutionPlan, type ExecutionStep, type PlanEvents, } from './core/plan';
|
|
28
|
+
export { defineActions, setClientInfo, getClientInfo, getHandler, getActionDefinition, hasAction, getActionNames, getManifest, clearRegistry, getActionCount, type ActionType, type ActionDataSchema, type ActionDefinition, type ActionDefinitions, type ActionManifest, type ActionManifestEntry, type ClientInfo, type Platform, type SyncActionDefinition, type SyncActionDefinitions, type ActionTypeDataMap, type NavigateActionData, type TriggerActionData, type InlineUIData, type ExternalLinkData, type CopyTextData, type ActionDataType, type ActionNames, type TypedTaskHandler, type TypedOnTask, type TypedPillarMethods, } from './actions';
|
|
29
|
+
export { APIClient, type TooltipData, type ArticleData, type ArticleSummary, type ChatMessage, type ChatResponse, type ProgressEvent, } from './api/client';
|
|
30
|
+
export { type ChatImage, type ImageUploadResponse, } from './api/mcp-client';
|
|
31
|
+
import { Pillar } from './core/Pillar';
|
|
32
|
+
export default Pillar;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Help Panel Container
|
|
3
|
+
* Shadow DOM container for the help panel
|
|
4
|
+
*/
|
|
5
|
+
import type { EventEmitter } from '../core/events';
|
|
6
|
+
import type { ResolvedConfig } from '../core/config';
|
|
7
|
+
import type { APIClient } from '../api/client';
|
|
8
|
+
export declare class Panel {
|
|
9
|
+
private config;
|
|
10
|
+
private api;
|
|
11
|
+
private events;
|
|
12
|
+
private host;
|
|
13
|
+
private shadow;
|
|
14
|
+
private backdrop;
|
|
15
|
+
private panelElement;
|
|
16
|
+
private panelUI;
|
|
17
|
+
private _isOpen;
|
|
18
|
+
constructor(config: ResolvedConfig, api: APIClient, events: EventEmitter);
|
|
19
|
+
/**
|
|
20
|
+
* Whether the panel is currently open
|
|
21
|
+
*/
|
|
22
|
+
get isOpen(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Initialize the panel
|
|
25
|
+
*/
|
|
26
|
+
init(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Open the panel
|
|
29
|
+
*/
|
|
30
|
+
open(options?: {
|
|
31
|
+
view?: string;
|
|
32
|
+
article?: string;
|
|
33
|
+
search?: string;
|
|
34
|
+
}): void;
|
|
35
|
+
/**
|
|
36
|
+
* Close the panel
|
|
37
|
+
*/
|
|
38
|
+
close(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Navigate to a specific view
|
|
41
|
+
*/
|
|
42
|
+
navigate(view: string, params?: Record<string, string>): void;
|
|
43
|
+
/**
|
|
44
|
+
* Destroy the panel
|
|
45
|
+
*/
|
|
46
|
+
destroy(): void;
|
|
47
|
+
private createHost;
|
|
48
|
+
private createBackdrop;
|
|
49
|
+
private createPanel;
|
|
50
|
+
private bindEvents;
|
|
51
|
+
private handleKeyDown;
|
|
52
|
+
private setupFocusTrap;
|
|
53
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Panel UI Controller
|
|
3
|
+
* Manages panel navigation and view rendering with persistent chat input
|
|
4
|
+
*/
|
|
5
|
+
import type { EventEmitter } from '../core/events';
|
|
6
|
+
import type { APIClient } from '../api/client';
|
|
7
|
+
export type ViewType = 'home' | 'article' | 'search' | 'category';
|
|
8
|
+
export interface PanelUIOptions {
|
|
9
|
+
api: APIClient;
|
|
10
|
+
events: EventEmitter;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
}
|
|
13
|
+
export declare class PanelUI {
|
|
14
|
+
private options;
|
|
15
|
+
private container;
|
|
16
|
+
private header;
|
|
17
|
+
private content;
|
|
18
|
+
private chatInput;
|
|
19
|
+
private homeView;
|
|
20
|
+
private articleView;
|
|
21
|
+
private searchView;
|
|
22
|
+
private categoryView;
|
|
23
|
+
private viewStack;
|
|
24
|
+
private currentView;
|
|
25
|
+
constructor(options: PanelUIOptions);
|
|
26
|
+
render(): HTMLElement;
|
|
27
|
+
/**
|
|
28
|
+
* Show the initial view when panel opens for the first time
|
|
29
|
+
* or when no view is currently displayed
|
|
30
|
+
*/
|
|
31
|
+
showInitialView(): void;
|
|
32
|
+
navigate(view: ViewType, params?: Record<string, string>): void;
|
|
33
|
+
goBack(): void;
|
|
34
|
+
reset(): void;
|
|
35
|
+
private renderView;
|
|
36
|
+
private renderHomeView;
|
|
37
|
+
private renderArticleView;
|
|
38
|
+
private renderSearchView;
|
|
39
|
+
private renderCategoryView;
|
|
40
|
+
private updateHeader;
|
|
41
|
+
private destroyCurrentView;
|
|
42
|
+
destroy(): void;
|
|
43
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Article Card Component
|
|
3
|
+
*/
|
|
4
|
+
import type { ArticleSummary } from '../../api/client';
|
|
5
|
+
export interface ArticleCardOptions {
|
|
6
|
+
article: ArticleSummary;
|
|
7
|
+
onClick: (article: ArticleSummary) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function createArticleCard(options: ArticleCardOptions): HTMLElement;
|
|
10
|
+
export declare function createArticleList(articles: ArticleSummary[], onClick: (article: ArticleSummary) => void): HTMLElement;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Category Card Component
|
|
3
|
+
*/
|
|
4
|
+
import type { CategoryData } from '../../api/client';
|
|
5
|
+
export interface CategoryCardOptions {
|
|
6
|
+
category: CategoryData;
|
|
7
|
+
onClick: (category: CategoryData) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function createCategoryCard(options: CategoryCardOptions): HTMLElement;
|
|
10
|
+
export declare function createCategoryList(categories: CategoryData[], onClick: (category: CategoryData) => void): HTMLElement;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat Input Component
|
|
3
|
+
* Persistent chat input with message display area
|
|
4
|
+
*/
|
|
5
|
+
import type { APIClient, ArticleSummary } from '../../api/client';
|
|
6
|
+
export interface ChatInputOptions {
|
|
7
|
+
api: APIClient;
|
|
8
|
+
onArticleClick: (article: ArticleSummary) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare class ChatInput {
|
|
11
|
+
private options;
|
|
12
|
+
private element;
|
|
13
|
+
private messagesContainer;
|
|
14
|
+
private inputElement;
|
|
15
|
+
private sendButton;
|
|
16
|
+
private messages;
|
|
17
|
+
private isLoading;
|
|
18
|
+
private isExpanded;
|
|
19
|
+
constructor(options: ChatInputOptions);
|
|
20
|
+
render(): HTMLElement;
|
|
21
|
+
private createInputArea;
|
|
22
|
+
private handleSend;
|
|
23
|
+
private expand;
|
|
24
|
+
private addWelcomeMessage;
|
|
25
|
+
private addMessage;
|
|
26
|
+
private createAssistantMessageElement;
|
|
27
|
+
private createSourcesElement;
|
|
28
|
+
private formatMessageContent;
|
|
29
|
+
private setLoading;
|
|
30
|
+
private scrollToBottom;
|
|
31
|
+
/**
|
|
32
|
+
* Reset the chat state
|
|
33
|
+
*/
|
|
34
|
+
reset(): void;
|
|
35
|
+
destroy(): void;
|
|
36
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Panel Header Component
|
|
3
|
+
* Displays title, back button, home button, and close button
|
|
4
|
+
*/
|
|
5
|
+
export interface HeaderOptions {
|
|
6
|
+
title: string;
|
|
7
|
+
showBack?: boolean;
|
|
8
|
+
showHome?: boolean;
|
|
9
|
+
onBack?: () => void;
|
|
10
|
+
onHome?: () => void;
|
|
11
|
+
onClose?: () => void;
|
|
12
|
+
}
|
|
13
|
+
export declare function createHeader(options: HeaderOptions): HTMLElement;
|
|
14
|
+
export declare function updateHeaderTitle(header: HTMLElement, title: string): void;
|
|
15
|
+
export declare function setBackButtonVisible(header: HTMLElement, visible: boolean): void;
|
|
16
|
+
export declare function setHomeButtonVisible(header: HTMLElement, visible: boolean): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search Input Component
|
|
3
|
+
*/
|
|
4
|
+
export interface SearchInputOptions {
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
onSearch: (query: string) => void;
|
|
7
|
+
debounceMs?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function createSearchInput(options: SearchInputOptions): HTMLElement;
|
|
10
|
+
export declare function setSearchValue(container: HTMLElement, value: string): void;
|
|
11
|
+
export declare function focusSearch(container: HTMLElement): void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Panel CSS Styles
|
|
3
|
+
* Complete styling for the help panel (injected into Shadow DOM)
|
|
4
|
+
*/
|
|
5
|
+
export declare const PANEL_STYLES = "\n/* Reset and base styles */\n*, *::before, *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\n:host {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: #1a1a1a;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* Panel Container */\n.pillar-panel {\n position: fixed;\n top: 0;\n bottom: 0;\n width: var(--pillar-panel-width, 380px);\n max-width: 100vw;\n background: #ffffff;\n box-shadow: -4px 0 20px rgba(0, 0, 0, 0.1);\n display: flex;\n flex-direction: column;\n z-index: 99999;\n transform: translateX(100%);\n transition: transform 0.3s ease;\n}\n\n.pillar-panel--right {\n right: 0;\n}\n\n.pillar-panel--left {\n left: 0;\n box-shadow: 4px 0 20px rgba(0, 0, 0, 0.1);\n transform: translateX(-100%);\n}\n\n.pillar-panel--open {\n transform: translateX(0);\n}\n\n/* Panel UI - Main layout */\n.pillar-panel-ui {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n\n/* Backdrop */\n.pillar-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.3);\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n z-index: 99998;\n}\n\n.pillar-backdrop--visible {\n opacity: 1;\n visibility: visible;\n}\n\n/* Header */\n.pillar-panel__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid #e5e7eb;\n flex-shrink: 0;\n}\n\n.pillar-panel__header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.pillar-panel__back-btn,\n.pillar-panel__home-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n color: #6b7280;\n background: none;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: color 0.15s ease, background 0.15s ease;\n}\n\n.pillar-panel__back-btn:hover,\n.pillar-panel__home-btn:hover {\n color: #1a1a1a;\n background: #f3f4f6;\n}\n\n.pillar-panel__back-btn svg,\n.pillar-panel__home-btn svg {\n width: 20px;\n height: 20px;\n}\n\n.pillar-panel__title {\n font-size: 16px;\n font-weight: 600;\n color: #1a1a1a;\n}\n\n.pillar-panel__close-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n color: #6b7280;\n background: none;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: color 0.15s ease, background 0.15s ease;\n}\n\n.pillar-panel__close-btn:hover {\n color: #1a1a1a;\n background: #f3f4f6;\n}\n\n.pillar-panel__close-btn svg {\n width: 20px;\n height: 20px;\n}\n\n/* Content area */\n.pillar-panel__content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n}\n\n/* Search Input */\n.pillar-search {\n position: relative;\n padding: 16px 20px;\n}\n\n.pillar-search__input {\n width: 100%;\n padding: 10px 12px 10px 40px;\n font-size: 14px;\n color: #1a1a1a;\n background: #f9fafb;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n outline: none;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.pillar-search__input:focus {\n border-color: #2563eb;\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n}\n\n.pillar-search__input::placeholder {\n color: #9ca3af;\n}\n\n.pillar-search__icon {\n position: absolute;\n left: 32px;\n top: 50%;\n transform: translateY(-50%);\n width: 18px;\n height: 18px;\n color: #9ca3af;\n pointer-events: none;\n}\n\n/* Category Card */\n.pillar-category-card {\n display: flex;\n align-items: flex-start;\n gap: 14px;\n padding: 16px 20px;\n border-bottom: 1px solid #f3f4f6;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.pillar-category-card:hover {\n background: #f9fafb;\n}\n\n.pillar-category-card__icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: #eff6ff;\n border-radius: 10px;\n color: #2563eb;\n flex-shrink: 0;\n}\n\n.pillar-category-card__icon svg {\n width: 20px;\n height: 20px;\n}\n\n.pillar-category-card__content {\n flex: 1;\n min-width: 0;\n}\n\n.pillar-category-card__title {\n font-size: 15px;\n font-weight: 500;\n color: #1a1a1a;\n margin-bottom: 2px;\n}\n\n.pillar-category-card__description {\n font-size: 13px;\n color: #6b7280;\n}\n\n.pillar-category-card__count {\n font-size: 12px;\n color: #9ca3af;\n margin-top: 4px;\n}\n\n/* Article Card */\n.pillar-article-card {\n display: block;\n padding: 16px 20px;\n border-bottom: 1px solid #f3f4f6;\n cursor: pointer;\n transition: background 0.15s ease;\n text-decoration: none;\n color: inherit;\n}\n\n.pillar-article-card:hover {\n background: #f9fafb;\n}\n\n.pillar-article-card__title {\n font-size: 15px;\n font-weight: 500;\n color: #1a1a1a;\n margin-bottom: 4px;\n}\n\n.pillar-article-card__excerpt {\n font-size: 13px;\n color: #6b7280;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.pillar-article-card__meta {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n font-size: 12px;\n color: #9ca3af;\n}\n\n/* Article Content */\n.pillar-article {\n padding: 20px;\n}\n\n.pillar-article__title {\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n margin-bottom: 16px;\n}\n\n.pillar-article__content {\n font-size: 15px;\n line-height: 1.7;\n color: #374151;\n}\n\n.pillar-article__content h1,\n.pillar-article__content h2,\n.pillar-article__content h3,\n.pillar-article__content h4 {\n color: #1a1a1a;\n margin: 24px 0 12px;\n font-weight: 600;\n}\n\n.pillar-article__content h2 {\n font-size: 18px;\n}\n\n.pillar-article__content h3 {\n font-size: 16px;\n}\n\n.pillar-article__content p {\n margin: 0 0 16px;\n}\n\n.pillar-article__content ul,\n.pillar-article__content ol {\n margin: 0 0 16px;\n padding-left: 24px;\n}\n\n.pillar-article__content li {\n margin-bottom: 8px;\n}\n\n.pillar-article__content a {\n color: #2563eb;\n text-decoration: none;\n}\n\n.pillar-article__content a:hover {\n text-decoration: underline;\n}\n\n.pillar-article__content code {\n padding: 2px 6px;\n font-size: 13px;\n background: #f3f4f6;\n border-radius: 4px;\n font-family: 'SF Mono', Consolas, monospace;\n}\n\n.pillar-article__content pre {\n padding: 16px;\n margin: 0 0 16px;\n background: #1a1a1a;\n border-radius: 8px;\n overflow-x: auto;\n}\n\n.pillar-article__content pre code {\n padding: 0;\n background: none;\n color: #e5e7eb;\n}\n\n.pillar-article__content img {\n max-width: 100%;\n height: auto;\n border-radius: 8px;\n margin: 16px 0;\n}\n\n/* ============================================================================\n Persistent Chat Input (bottom of panel)\n ============================================================================ */\n\n.pillar-chat-input-container {\n flex-shrink: 0;\n border-top: 1px solid #e5e7eb;\n background: #ffffff;\n display: flex;\n flex-direction: column;\n max-height: 50%;\n transition: max-height 0.3s ease;\n}\n\n.pillar-chat-input-container--expanded {\n max-height: 60%;\n}\n\n/* Messages area */\n.pillar-chat-input__messages {\n flex: 1;\n overflow-y: auto;\n padding: 0;\n max-height: 0;\n transition: max-height 0.3s ease, padding 0.3s ease;\n}\n\n.pillar-chat-input-container--expanded .pillar-chat-input__messages {\n max-height: 300px;\n padding: 16px 20px;\n}\n\n.pillar-chat-input__message {\n margin-bottom: 12px;\n}\n\n.pillar-chat-input__message--user {\n text-align: right;\n}\n\n.pillar-chat-input__message-content {\n display: inline-block;\n max-width: 85%;\n padding: 10px 14px;\n border-radius: 16px;\n font-size: 14px;\n line-height: 1.5;\n}\n\n.pillar-chat-input__message--user .pillar-chat-input__message-content {\n background: #2563eb;\n color: #ffffff;\n border-bottom-right-radius: 4px;\n}\n\n.pillar-chat-input__message--assistant .pillar-chat-input__message-content {\n background: #f3f4f6;\n color: #1a1a1a;\n border-bottom-left-radius: 4px;\n}\n\n.pillar-chat-input__sources {\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid #e5e7eb;\n}\n\n.pillar-chat-input__sources-title {\n font-size: 11px;\n font-weight: 500;\n color: #6b7280;\n margin-bottom: 6px;\n}\n\n.pillar-chat-input__source {\n display: block;\n padding: 6px 10px;\n margin-bottom: 4px;\n font-size: 12px;\n color: #2563eb;\n background: #eff6ff;\n border-radius: 6px;\n text-decoration: none;\n cursor: pointer;\n}\n\n.pillar-chat-input__source:hover {\n background: #dbeafe;\n}\n\n/* Input area */\n.pillar-chat-input__area {\n padding: 12px 16px;\n}\n\n.pillar-chat-input__wrapper {\n display: flex;\n gap: 8px;\n align-items: flex-end;\n}\n\n.pillar-chat-input__input {\n flex: 1;\n padding: 10px 14px;\n font-size: 14px;\n font-family: inherit;\n color: #1a1a1a;\n background: #f9fafb;\n border: 1px solid #e5e7eb;\n border-radius: 20px;\n outline: none;\n resize: none;\n min-height: 40px;\n max-height: 120px;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.pillar-chat-input__input:focus {\n border-color: #2563eb;\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n}\n\n.pillar-chat-input__input::placeholder {\n color: #9ca3af;\n}\n\n.pillar-chat-input__send-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n padding: 0;\n color: #ffffff;\n background: #2563eb;\n border: none;\n border-radius: 20px;\n cursor: pointer;\n flex-shrink: 0;\n transition: background 0.15s ease;\n}\n\n.pillar-chat-input__send-btn:hover:not(:disabled) {\n background: #1d4ed8;\n}\n\n.pillar-chat-input__send-btn:disabled {\n background: #9ca3af;\n cursor: not-allowed;\n}\n\n.pillar-chat-input__send-btn svg {\n width: 18px;\n height: 18px;\n}\n\n/* ============================================================================\n Legacy Chat View (for backwards compatibility)\n ============================================================================ */\n\n.pillar-chat {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.pillar-chat__messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n.pillar-chat__message {\n margin-bottom: 16px;\n}\n\n.pillar-chat__message--user {\n text-align: right;\n}\n\n.pillar-chat__message-content {\n display: inline-block;\n max-width: 85%;\n padding: 12px 16px;\n border-radius: 16px;\n font-size: 14px;\n line-height: 1.5;\n}\n\n.pillar-chat__message--user .pillar-chat__message-content {\n background: #2563eb;\n color: #ffffff;\n border-bottom-right-radius: 4px;\n}\n\n.pillar-chat__message--assistant .pillar-chat__message-content {\n background: #f3f4f6;\n color: #1a1a1a;\n border-bottom-left-radius: 4px;\n}\n\n.pillar-chat__sources {\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid #e5e7eb;\n}\n\n.pillar-chat__sources-title {\n font-size: 12px;\n font-weight: 500;\n color: #6b7280;\n margin-bottom: 8px;\n}\n\n.pillar-chat__source {\n display: block;\n padding: 8px 12px;\n margin-bottom: 4px;\n font-size: 13px;\n color: #2563eb;\n background: #eff6ff;\n border-radius: 6px;\n text-decoration: none;\n cursor: pointer;\n}\n\n.pillar-chat__source:hover {\n background: #dbeafe;\n}\n\n.pillar-chat__input-area {\n padding: 16px 20px;\n border-top: 1px solid #e5e7eb;\n background: #ffffff;\n}\n\n.pillar-chat__input-wrapper {\n display: flex;\n gap: 8px;\n}\n\n.pillar-chat__input {\n flex: 1;\n padding: 10px 14px;\n font-size: 14px;\n color: #1a1a1a;\n background: #f9fafb;\n border: 1px solid #e5e7eb;\n border-radius: 20px;\n outline: none;\n resize: none;\n min-height: 40px;\n max-height: 120px;\n}\n\n.pillar-chat__input:focus {\n border-color: #2563eb;\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n}\n\n.pillar-chat__send-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n padding: 0;\n color: #ffffff;\n background: #2563eb;\n border: none;\n border-radius: 20px;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.pillar-chat__send-btn:hover:not(:disabled) {\n background: #1d4ed8;\n}\n\n.pillar-chat__send-btn:disabled {\n background: #9ca3af;\n cursor: not-allowed;\n}\n\n.pillar-chat__send-btn svg {\n width: 18px;\n height: 18px;\n}\n\n/* Loading states */\n.pillar-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: #6b7280;\n}\n\n.pillar-loading__spinner {\n width: 24px;\n height: 24px;\n border: 2px solid #e5e7eb;\n border-top-color: #2563eb;\n border-radius: 50%;\n animation: pillar-spin 0.8s linear infinite;\n}\n\n@keyframes pillar-spin {\n to { transform: rotate(360deg); }\n}\n\n/* Empty states */\n.pillar-empty {\n padding: 40px 20px;\n text-align: center;\n color: #6b7280;\n}\n\n.pillar-empty__icon {\n width: 48px;\n height: 48px;\n margin: 0 auto 16px;\n color: #d1d5db;\n}\n\n.pillar-empty__title {\n font-size: 16px;\n font-weight: 500;\n color: #1a1a1a;\n margin-bottom: 4px;\n}\n\n.pillar-empty__description {\n font-size: 14px;\n}\n\n/* Section titles */\n.pillar-section-title {\n padding: 12px 20px 8px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #6b7280;\n}\n\n/* Chat entry button (legacy - kept for backwards compatibility) */\n.pillar-chat-entry {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 16px 20px;\n padding: 14px 16px;\n background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);\n border: none;\n border-radius: 12px;\n cursor: pointer;\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n}\n\n.pillar-chat-entry:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);\n}\n\n.pillar-chat-entry__icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 10px;\n color: #ffffff;\n}\n\n.pillar-chat-entry__icon svg {\n width: 20px;\n height: 20px;\n}\n\n.pillar-chat-entry__content {\n flex: 1;\n text-align: left;\n}\n\n.pillar-chat-entry__title {\n font-size: 15px;\n font-weight: 600;\n color: #ffffff;\n margin-bottom: 2px;\n}\n\n.pillar-chat-entry__description {\n font-size: 13px;\n color: rgba(255, 255, 255, 0.8);\n}\n\n/* Scrollbar styling */\n.pillar-panel__content::-webkit-scrollbar,\n.pillar-chat__messages::-webkit-scrollbar,\n.pillar-chat-input__messages::-webkit-scrollbar {\n width: 6px;\n}\n\n.pillar-panel__content::-webkit-scrollbar-track,\n.pillar-chat__messages::-webkit-scrollbar-track,\n.pillar-chat-input__messages::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.pillar-panel__content::-webkit-scrollbar-thumb,\n.pillar-chat__messages::-webkit-scrollbar-thumb,\n.pillar-chat-input__messages::-webkit-scrollbar-thumb {\n background: #d1d5db;\n border-radius: 3px;\n}\n\n.pillar-panel__content::-webkit-scrollbar-thumb:hover,\n.pillar-chat__messages::-webkit-scrollbar-thumb:hover,\n.pillar-chat-input__messages::-webkit-scrollbar-thumb:hover {\n background: #9ca3af;\n}\n\n/* Home view */\n.pillar-home-view {\n padding-bottom: 16px;\n}\n";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Article View
|
|
3
|
+
* Displays article content using TipTap for rendering
|
|
4
|
+
*/
|
|
5
|
+
import type { APIClient, ArticleSummary } from '../../api/client';
|
|
6
|
+
export interface ArticleViewOptions {
|
|
7
|
+
api: APIClient;
|
|
8
|
+
onArticleClick: (article: ArticleSummary) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare class ArticleView {
|
|
11
|
+
private options;
|
|
12
|
+
private element;
|
|
13
|
+
private currentSlug;
|
|
14
|
+
constructor(options: ArticleViewOptions);
|
|
15
|
+
render(slug: string): Promise<HTMLElement>;
|
|
16
|
+
private loadArticle;
|
|
17
|
+
private createArticleElement;
|
|
18
|
+
private createRelatedArticles;
|
|
19
|
+
getTitle(): string;
|
|
20
|
+
destroy(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Category View
|
|
3
|
+
* Displays articles within a category
|
|
4
|
+
*/
|
|
5
|
+
import type { APIClient, CategoryData, ArticleSummary } from '../../api/client';
|
|
6
|
+
export interface CategoryViewOptions {
|
|
7
|
+
api: APIClient;
|
|
8
|
+
onArticleClick: (article: ArticleSummary) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare class CategoryView {
|
|
11
|
+
private options;
|
|
12
|
+
private element;
|
|
13
|
+
private currentCategory;
|
|
14
|
+
constructor(options: CategoryViewOptions);
|
|
15
|
+
render(category: CategoryData): Promise<HTMLElement>;
|
|
16
|
+
private createCategoryHeader;
|
|
17
|
+
private loadArticles;
|
|
18
|
+
getTitle(): string;
|
|
19
|
+
destroy(): void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat View
|
|
3
|
+
* AI chat interface with streaming responses
|
|
4
|
+
*/
|
|
5
|
+
import type { APIClient, ArticleSummary } from '../../api/client';
|
|
6
|
+
export interface ChatViewOptions {
|
|
7
|
+
api: APIClient;
|
|
8
|
+
onArticleClick: (article: ArticleSummary) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare class ChatView {
|
|
11
|
+
private options;
|
|
12
|
+
private element;
|
|
13
|
+
private messagesContainer;
|
|
14
|
+
private inputElement;
|
|
15
|
+
private sendButton;
|
|
16
|
+
private messages;
|
|
17
|
+
private isLoading;
|
|
18
|
+
constructor(options: ChatViewOptions);
|
|
19
|
+
render(): HTMLElement;
|
|
20
|
+
private createInputArea;
|
|
21
|
+
private addWelcomeMessage;
|
|
22
|
+
private handleSend;
|
|
23
|
+
private addMessage;
|
|
24
|
+
private createAssistantMessageElement;
|
|
25
|
+
private createSourcesElement;
|
|
26
|
+
private formatMessageContent;
|
|
27
|
+
private setLoading;
|
|
28
|
+
private scrollToBottom;
|
|
29
|
+
destroy(): void;
|
|
30
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Home View
|
|
3
|
+
* Default panel view with categories list
|
|
4
|
+
*/
|
|
5
|
+
import type { APIClient, CategoryData } from '../../api/client';
|
|
6
|
+
export interface HomeViewOptions {
|
|
7
|
+
api: APIClient;
|
|
8
|
+
onCategoryClick: (category: CategoryData) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare class HomeView {
|
|
11
|
+
private options;
|
|
12
|
+
private element;
|
|
13
|
+
private categoriesLoaded;
|
|
14
|
+
constructor(options: HomeViewOptions);
|
|
15
|
+
render(): HTMLElement;
|
|
16
|
+
private loadCategories;
|
|
17
|
+
destroy(): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search View
|
|
3
|
+
* Search results display
|
|
4
|
+
*/
|
|
5
|
+
import type { APIClient, ArticleSummary } from '../../api/client';
|
|
6
|
+
export interface SearchViewOptions {
|
|
7
|
+
api: APIClient;
|
|
8
|
+
onArticleClick: (article: ArticleSummary) => void;
|
|
9
|
+
initialQuery?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class SearchView {
|
|
12
|
+
private options;
|
|
13
|
+
private element;
|
|
14
|
+
private resultsContainer;
|
|
15
|
+
private currentQuery;
|
|
16
|
+
constructor(options: SearchViewOptions);
|
|
17
|
+
render(): HTMLElement;
|
|
18
|
+
private handleSearch;
|
|
19
|
+
private showEmptyState;
|
|
20
|
+
private showNoResults;
|
|
21
|
+
destroy(): void;
|
|
22
|
+
}
|