@pillar-ai/sdk 0.1.13 → 0.1.15
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/LICENSE +21 -0
- package/README.md +46 -44
- package/dist/actions/types.d.ts +39 -3
- package/dist/api/client.d.ts +119 -16
- package/dist/api/mcp-client.d.ts +137 -87
- package/dist/cli/sync.js +72 -13
- package/dist/components/DebugPanel/DebugPanel.d.ts +25 -0
- package/dist/components/DebugPanel/index.d.ts +2 -0
- package/dist/components/DevTools/index.d.ts +5 -0
- package/dist/components/DevTools/styles.d.ts +5 -0
- package/dist/components/PagePilot/PagePilotBanner.d.ts +7 -0
- package/dist/components/PagePilot/PagePilotManager.d.ts +42 -0
- package/dist/components/PagePilot/index.d.ts +7 -0
- package/dist/components/PagePilot/styles.d.ts +6 -0
- package/dist/components/Panel/Header.d.ts +3 -5
- package/dist/components/Panel/HistoryDropdown.d.ts +10 -0
- package/dist/components/Panel/PanelContent.d.ts +1 -2
- package/dist/components/Panel/TaskButton.d.ts +4 -14
- package/dist/components/Panel/UnifiedChatInput.d.ts +5 -1
- package/dist/components/Panel/styles.d.ts +2 -2
- package/dist/components/Plan/InlinePlanView.d.ts +1 -1
- package/dist/components/Plan/PlanDocument.d.ts +18 -0
- package/dist/components/Plan/PlanStepItem.d.ts +1 -1
- package/dist/components/Plan/PlanView.d.ts +1 -1
- package/dist/components/Plan/index.d.ts +1 -0
- package/dist/components/Progress/ProgressGroup.d.ts +20 -0
- package/dist/components/Progress/ProgressRow.d.ts +9 -2
- package/dist/components/Progress/ProgressStack.d.ts +24 -0
- package/dist/components/Progress/ReasoningDisclosure.d.ts +16 -0
- package/dist/components/Progress/index.d.ts +2 -0
- package/dist/components/Views/HomeView.d.ts +3 -0
- package/dist/components/Views/ResumePrompt.d.ts +22 -0
- package/dist/components/Views/index.d.ts +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/shared/icons.d.ts +24 -0
- package/dist/components/shared/index.d.ts +1 -0
- package/dist/core/Pillar.d.ts +325 -70
- package/dist/core/config.d.ts +133 -4
- package/dist/core/events.d.ts +55 -70
- package/dist/core/plan-executor.d.ts +29 -0
- package/dist/core/plan.d.ts +6 -0
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/useDebouncedValue.d.ts +22 -0
- package/dist/hooks/useInlineCard.d.ts +35 -0
- package/dist/hooks/usePillarInstance.d.ts +30 -0
- package/dist/index.d.ts +11 -9
- package/dist/pillar.esm.js +1 -1
- package/dist/store/chat.d.ts +185 -25
- package/dist/store/index.d.ts +2 -0
- package/dist/store/pagePilot.d.ts +56 -0
- package/dist/store/session-persistence.d.ts +62 -0
- package/dist/store/suggestions.d.ts +58 -0
- package/dist/types/dom-scanner.d.ts +50 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/user-context.d.ts +32 -1
- package/dist/utils/debug.d.ts +150 -0
- package/dist/utils/dom-scanner.d.ts +70 -0
- package/dist/utils/markdown-components.d.ts +53 -0
- package/dist/utils/preact-markdown.d.ts +17 -0
- package/dist/utils/route-observer.d.ts +67 -0
- package/package.json +1 -1
- package/src/actions/types.ts +43 -2
- package/dist/utils/markdown.d.ts +0 -9
package/dist/api/mcp-client.d.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { TaskButtonData } from '../components/Panel/TaskButton';
|
|
8
8
|
import type { ResolvedConfig } from '../core/config';
|
|
9
|
-
import type { ExecutionPlan } from '../core/plan';
|
|
10
9
|
import type { UserContextItem } from '../types/user-context';
|
|
10
|
+
import { type LogEntry } from '../utils/debug';
|
|
11
11
|
import type { ArticleSummary } from './client';
|
|
12
12
|
/** MCP Tool result content */
|
|
13
13
|
interface ToolResultContent {
|
|
@@ -23,7 +23,8 @@ export interface ToolResult {
|
|
|
23
23
|
structuredContent?: {
|
|
24
24
|
sources?: ArticleSummary[];
|
|
25
25
|
actions?: ActionData[];
|
|
26
|
-
|
|
26
|
+
/** Registered actions for dynamic action tools (persisted across turns) */
|
|
27
|
+
registered_actions?: Record<string, unknown>[];
|
|
27
28
|
};
|
|
28
29
|
_meta?: {
|
|
29
30
|
conversation_id?: string;
|
|
@@ -45,6 +46,38 @@ export interface ActionData {
|
|
|
45
46
|
score: number;
|
|
46
47
|
data: Record<string, unknown>;
|
|
47
48
|
}
|
|
49
|
+
/** Action request from agent (unified for all action execution) */
|
|
50
|
+
export interface ActionRequest {
|
|
51
|
+
/** Action name to execute */
|
|
52
|
+
action_name: string;
|
|
53
|
+
/** Parameters for the action */
|
|
54
|
+
parameters: Record<string, unknown>;
|
|
55
|
+
/** Full action definition (optional, for handler lookup) */
|
|
56
|
+
action?: ActionData;
|
|
57
|
+
/** Unique ID for this specific tool invocation (for result correlation) */
|
|
58
|
+
tool_call_id?: string;
|
|
59
|
+
}
|
|
60
|
+
/** Token usage data from the agentic loop (sent after each LLM iteration) */
|
|
61
|
+
export interface TokenUsage {
|
|
62
|
+
/** Input tokens for this iteration */
|
|
63
|
+
prompt_tokens: number;
|
|
64
|
+
/** Output tokens for this iteration */
|
|
65
|
+
completion_tokens: number;
|
|
66
|
+
/** Cumulative prompt tokens across all iterations */
|
|
67
|
+
total_prompt_tokens: number;
|
|
68
|
+
/** Cumulative completion tokens across all iterations */
|
|
69
|
+
total_completion_tokens: number;
|
|
70
|
+
/** Current total tokens in context */
|
|
71
|
+
total_used: number;
|
|
72
|
+
/** Maximum context window for the model */
|
|
73
|
+
context_window: number;
|
|
74
|
+
/** Current context occupancy percentage (0-100) */
|
|
75
|
+
occupancy_pct: number;
|
|
76
|
+
/** Name of the model in use */
|
|
77
|
+
model_name: string;
|
|
78
|
+
/** Current iteration number (0-indexed) */
|
|
79
|
+
iteration: number;
|
|
80
|
+
}
|
|
48
81
|
/** Streaming callbacks for tool calls */
|
|
49
82
|
export interface StreamCallbacks {
|
|
50
83
|
/** Called for each text token */
|
|
@@ -53,29 +86,36 @@ export interface StreamCallbacks {
|
|
|
53
86
|
onSources?: (sources: ArticleSummary[]) => void;
|
|
54
87
|
/** Called when actions are available */
|
|
55
88
|
onActions?: (actions: ActionData[]) => void;
|
|
56
|
-
/** Called when
|
|
57
|
-
|
|
89
|
+
/** Called when registered actions are received (for dynamic action tools) */
|
|
90
|
+
onRegisteredActions?: (actions: Record<string, unknown>[]) => void;
|
|
58
91
|
/** Called on error */
|
|
59
92
|
onError?: (error: string) => void;
|
|
93
|
+
/** Called when conversation_started event is received (confirms conversation tracking) */
|
|
94
|
+
onConversationStarted?: (conversationId: string, assistantMessageId?: string) => void;
|
|
60
95
|
/** Called when stream is complete */
|
|
61
96
|
onComplete?: (conversationId?: string, queryLogId?: string) => void;
|
|
62
|
-
/** Called for progress updates (search, query, generating, etc.) */
|
|
97
|
+
/** Called for progress updates (search, query, generating, thinking, etc.) */
|
|
63
98
|
onProgress?: (progress: {
|
|
64
99
|
kind: string;
|
|
65
|
-
|
|
100
|
+
id?: string;
|
|
101
|
+
label?: string;
|
|
102
|
+
status?: 'active' | 'done' | 'error';
|
|
103
|
+
text?: string;
|
|
104
|
+
children?: Array<{
|
|
105
|
+
id: string;
|
|
106
|
+
label: string;
|
|
107
|
+
url?: string;
|
|
108
|
+
}>;
|
|
109
|
+
metadata?: Record<string, unknown>;
|
|
66
110
|
progress_id?: string;
|
|
67
|
-
|
|
68
|
-
sources?: Array<{
|
|
69
|
-
title: string;
|
|
70
|
-
url: string;
|
|
71
|
-
score?: number;
|
|
72
|
-
}>;
|
|
73
|
-
result_count?: number;
|
|
74
|
-
query?: string;
|
|
75
|
-
action_name?: string;
|
|
76
|
-
no_sources_used?: boolean;
|
|
77
|
-
};
|
|
111
|
+
message?: string;
|
|
78
112
|
}) => void;
|
|
113
|
+
/** Called immediately with the request ID (for cancellation support) */
|
|
114
|
+
onRequestId?: (requestId: number) => void;
|
|
115
|
+
/** Called when agent requests action execution (unified handler) */
|
|
116
|
+
onActionRequest?: (request: ActionRequest) => Promise<void>;
|
|
117
|
+
/** Called when token usage is updated (after each LLM iteration) */
|
|
118
|
+
onTokenUsage?: (usage: TokenUsage) => void;
|
|
79
119
|
}
|
|
80
120
|
/** Image for chat requests (from upload-image endpoint) */
|
|
81
121
|
export interface ChatImage {
|
|
@@ -92,7 +132,27 @@ export interface ImageUploadResponse {
|
|
|
92
132
|
export declare class MCPClient {
|
|
93
133
|
private config;
|
|
94
134
|
private requestId;
|
|
135
|
+
private _externalUserId;
|
|
95
136
|
constructor(config: ResolvedConfig);
|
|
137
|
+
/**
|
|
138
|
+
* Set the external user ID for authenticated users.
|
|
139
|
+
* Enables cross-device conversation history.
|
|
140
|
+
*/
|
|
141
|
+
setExternalUserId(userId: string): void;
|
|
142
|
+
/**
|
|
143
|
+
* Get or create a persistent visitor ID.
|
|
144
|
+
* Stored in localStorage to persist across sessions.
|
|
145
|
+
*/
|
|
146
|
+
private getVisitorId;
|
|
147
|
+
/**
|
|
148
|
+
* Get or create a session ID for MCP request correlation.
|
|
149
|
+
* Stored in sessionStorage to persist only for the current browser session.
|
|
150
|
+
*/
|
|
151
|
+
private getSessionId;
|
|
152
|
+
/**
|
|
153
|
+
* Get the current page URL for analytics tracking.
|
|
154
|
+
*/
|
|
155
|
+
private getPageUrl;
|
|
96
156
|
private get baseUrl();
|
|
97
157
|
private get headers();
|
|
98
158
|
private nextId;
|
|
@@ -132,104 +192,94 @@ export declare class MCPClient {
|
|
|
132
192
|
articleSlug?: string;
|
|
133
193
|
userContext?: UserContextItem[];
|
|
134
194
|
images?: ChatImage[];
|
|
195
|
+
history?: Array<{
|
|
196
|
+
role: 'user' | 'assistant';
|
|
197
|
+
content: string;
|
|
198
|
+
}>;
|
|
199
|
+
/** Registered actions from previous turns (for dynamic action tools) */
|
|
200
|
+
registeredActions?: Record<string, unknown>[];
|
|
135
201
|
signal?: AbortSignal;
|
|
202
|
+
/** Conversation ID - generated client-side, always provided */
|
|
203
|
+
conversationId?: string;
|
|
136
204
|
}): Promise<ToolResult>;
|
|
137
205
|
/**
|
|
138
|
-
*
|
|
206
|
+
* Cancel an active streaming request.
|
|
139
207
|
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* and updates subsequent steps if needed.
|
|
208
|
+
* Sends a notifications/cancel JSON-RPC request to the backend, which
|
|
209
|
+
* signals the StreamRegistry to stop the LLM stream and cease billing.
|
|
143
210
|
*
|
|
144
|
-
* @param
|
|
145
|
-
* @param stepId - UUID of the completed step
|
|
146
|
-
* @param result - Step execution result
|
|
147
|
-
* @returns Updated plan with all steps
|
|
211
|
+
* @param requestId - The JSON-RPC request ID of the stream to cancel
|
|
148
212
|
*/
|
|
149
|
-
|
|
150
|
-
plan: ExecutionPlan;
|
|
151
|
-
}>;
|
|
213
|
+
cancelStream(requestId: number | string): Promise<void>;
|
|
152
214
|
/**
|
|
153
|
-
*
|
|
215
|
+
* Send action result back to the agent.
|
|
154
216
|
*
|
|
155
|
-
*
|
|
217
|
+
* Called after executing a query action (returns_data=true).
|
|
218
|
+
* The result is sent to the agent for further reasoning in the ReAct loop.
|
|
156
219
|
*
|
|
157
|
-
* @param
|
|
158
|
-
* @
|
|
220
|
+
* @param actionName - The name of the action that was executed
|
|
221
|
+
* @param result - The result data to send back to the agent
|
|
222
|
+
* @param toolCallId - Unique ID for this specific tool invocation (for result correlation)
|
|
223
|
+
* @returns Promise that resolves when the result is delivered, or rejects on error
|
|
159
224
|
*/
|
|
160
|
-
|
|
161
|
-
plan: ExecutionPlan;
|
|
162
|
-
}>;
|
|
225
|
+
sendActionResult(actionName: string, result: unknown, toolCallId?: string): Promise<void>;
|
|
163
226
|
/**
|
|
164
|
-
*
|
|
227
|
+
* Send a client-side log to the server for debugging.
|
|
165
228
|
*
|
|
166
|
-
*
|
|
229
|
+
* Logs are correlated with agent sessions via the MCP session ID.
|
|
230
|
+
* Use this to forward important SDK events to server logs.
|
|
167
231
|
*
|
|
168
|
-
* @param
|
|
169
|
-
* @
|
|
232
|
+
* @param level - Log level: 'log', 'warn', or 'error'
|
|
233
|
+
* @param message - The log message
|
|
234
|
+
* @param data - Optional additional data to include
|
|
170
235
|
*/
|
|
171
|
-
|
|
172
|
-
plan: ExecutionPlan;
|
|
173
|
-
}>;
|
|
236
|
+
sendLog(level: 'log' | 'warn' | 'error', message: string, data?: unknown): Promise<void>;
|
|
174
237
|
/**
|
|
175
|
-
*
|
|
238
|
+
* Send a batch of client-side logs to the server.
|
|
176
239
|
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
240
|
+
* Logs are buffered and sent periodically (every 5 seconds by default)
|
|
241
|
+
* to reduce network requests. This method is called by the debug module.
|
|
179
242
|
*
|
|
180
|
-
* @param
|
|
181
|
-
* @returns Updated plan with executing status
|
|
243
|
+
* @param logs - Array of log entries to send
|
|
182
244
|
*/
|
|
183
|
-
|
|
184
|
-
plan: ExecutionPlan;
|
|
185
|
-
}>;
|
|
245
|
+
sendLogBatch(logs: LogEntry[]): void;
|
|
186
246
|
/**
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* Increments the retry count and resets the step to ready status.
|
|
190
|
-
* Only works if the step is retriable and hasn't exceeded max_retries.
|
|
247
|
+
* Check if a conversation has a resumable interrupted session.
|
|
191
248
|
*
|
|
192
|
-
* @param
|
|
193
|
-
* @
|
|
194
|
-
* @returns Updated plan with step reset to ready
|
|
249
|
+
* @param conversationId - The conversation UUID to check
|
|
250
|
+
* @returns Session status with resumption details, or null if not resumable
|
|
195
251
|
*/
|
|
196
|
-
|
|
197
|
-
plan: ExecutionPlan;
|
|
198
|
-
}>;
|
|
252
|
+
getConversationStatus(conversationId: string): Promise<ConversationStatus | null>;
|
|
199
253
|
/**
|
|
200
|
-
*
|
|
254
|
+
* Resume an interrupted conversation.
|
|
201
255
|
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
256
|
+
* Returns a streaming response that continues the conversation
|
|
257
|
+
* from where it was interrupted.
|
|
204
258
|
*
|
|
205
|
-
* @param
|
|
206
|
-
* @param
|
|
207
|
-
* @param
|
|
208
|
-
* @returns Updated plan with failed step
|
|
259
|
+
* @param conversationId - The conversation to resume
|
|
260
|
+
* @param userContext - Optional current page context (highlighted text, DOM snapshot, etc.)
|
|
261
|
+
* @param callbacks - Streaming callbacks
|
|
209
262
|
*/
|
|
210
|
-
|
|
211
|
-
plan: ExecutionPlan;
|
|
212
|
-
}>;
|
|
263
|
+
resumeConversation(conversationId: string, userContext: UserContextItem[] | undefined, callbacks: StreamCallbacks): Promise<void>;
|
|
213
264
|
/**
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
* @param planId - UUID of the plan
|
|
217
|
-
* @param stepId - UUID of the step to skip
|
|
218
|
-
* @returns Updated plan with skipped step and next step ready
|
|
265
|
+
* Handle events from the resume stream.
|
|
219
266
|
*/
|
|
220
|
-
|
|
221
|
-
|
|
267
|
+
private handleResumeStreamEvent;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Conversation status for session resumption.
|
|
271
|
+
*/
|
|
272
|
+
export interface ConversationStatus {
|
|
273
|
+
resumable: boolean;
|
|
274
|
+
message_id?: string;
|
|
275
|
+
elapsed_ms?: number;
|
|
276
|
+
user_message?: string;
|
|
277
|
+
partial_response?: string;
|
|
278
|
+
summary?: string;
|
|
279
|
+
accomplished?: Array<{
|
|
280
|
+
action: string;
|
|
281
|
+
result_summary: string;
|
|
222
282
|
}>;
|
|
223
|
-
/**
|
|
224
|
-
* Send action result back to the agent.
|
|
225
|
-
*
|
|
226
|
-
* Called after executing a query action (returns_data=true).
|
|
227
|
-
* The result is sent to the agent for further reasoning in the ReAct loop.
|
|
228
|
-
*
|
|
229
|
-
* @param actionName - The name of the action that was executed
|
|
230
|
-
* @param result - The result data to send back to the agent
|
|
231
|
-
*/
|
|
232
|
-
sendActionResult(actionName: string, result: unknown): void;
|
|
233
283
|
}
|
|
234
284
|
/**
|
|
235
285
|
* Convert ActionData from MCP response to TaskButtonData for UI rendering.
|
package/dist/cli/sync.js
CHANGED
|
@@ -64,9 +64,32 @@ async function loadActions(actionsPath) {
|
|
|
64
64
|
const tempDir = path.dirname(absolutePath);
|
|
65
65
|
const tempFile = path.join(tempDir, `.pillar-sync-temp-${Date.now()}.mjs`);
|
|
66
66
|
const importPath = absolutePath.replace(/\\/g, "/");
|
|
67
|
-
const extractScript = `import
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
const extractScript = `import * as module from '${importPath}';
|
|
68
|
+
|
|
69
|
+
// Resolve actions - tsx may wrap all exports in module.default
|
|
70
|
+
function resolveActions(mod) {
|
|
71
|
+
// Direct named export
|
|
72
|
+
if (mod.actions && typeof mod.actions === 'object' && !mod.actions.default) {
|
|
73
|
+
return mod.actions;
|
|
74
|
+
}
|
|
75
|
+
// Default export is the actions object directly
|
|
76
|
+
if (mod.default && typeof mod.default === 'object') {
|
|
77
|
+
// Check if default is a module namespace (has nested default or actions)
|
|
78
|
+
if (mod.default.default && typeof mod.default.default === 'object') {
|
|
79
|
+
return mod.default.default;
|
|
80
|
+
}
|
|
81
|
+
if (mod.default.actions && typeof mod.default.actions === 'object') {
|
|
82
|
+
return mod.default.actions;
|
|
83
|
+
}
|
|
84
|
+
// default is the actions object itself
|
|
85
|
+
return mod.default;
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const actions = resolveActions(module);
|
|
91
|
+
const agentGuidance = module.agentGuidance || module.default?.agentGuidance;
|
|
92
|
+
console.log(JSON.stringify({ actions, agentGuidance }));`;
|
|
70
93
|
fs.writeFileSync(tempFile, extractScript, "utf-8");
|
|
71
94
|
try {
|
|
72
95
|
const result = execSync(`npx tsx "${tempFile}"`, {
|
|
@@ -74,13 +97,15 @@ console.log(JSON.stringify(result));`;
|
|
|
74
97
|
cwd: process.cwd(),
|
|
75
98
|
stdio: ["pipe", "pipe", "pipe"]
|
|
76
99
|
});
|
|
77
|
-
const
|
|
100
|
+
const parsed = JSON.parse(result.trim());
|
|
101
|
+
const actions = parsed.actions;
|
|
102
|
+
const agentGuidance = parsed.agentGuidance;
|
|
78
103
|
if (!actions || typeof actions !== "object") {
|
|
79
104
|
throw new Error(
|
|
80
105
|
'Actions file must export an actions object as default or named export "actions"'
|
|
81
106
|
);
|
|
82
107
|
}
|
|
83
|
-
return actions;
|
|
108
|
+
return { actions, agentGuidance };
|
|
84
109
|
} finally {
|
|
85
110
|
if (fs.existsSync(tempFile)) {
|
|
86
111
|
fs.unlinkSync(tempFile);
|
|
@@ -97,19 +122,37 @@ console.log(JSON.stringify(result));`;
|
|
|
97
122
|
}
|
|
98
123
|
const fileUrl = pathToFileURL(absolutePath).href;
|
|
99
124
|
try {
|
|
125
|
+
let resolveActions2 = function(mod) {
|
|
126
|
+
if (mod.actions && typeof mod.actions === "object" && !mod.actions.default) {
|
|
127
|
+
return mod.actions;
|
|
128
|
+
}
|
|
129
|
+
if (mod.default && typeof mod.default === "object") {
|
|
130
|
+
const defaultExport = mod.default;
|
|
131
|
+
if (defaultExport.default && typeof defaultExport.default === "object") {
|
|
132
|
+
return defaultExport.default;
|
|
133
|
+
}
|
|
134
|
+
if (defaultExport.actions && typeof defaultExport.actions === "object") {
|
|
135
|
+
return defaultExport.actions;
|
|
136
|
+
}
|
|
137
|
+
return defaultExport;
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
};
|
|
141
|
+
var resolveActions = resolveActions2;
|
|
100
142
|
const module = await import(fileUrl);
|
|
101
|
-
const actions = module
|
|
143
|
+
const actions = resolveActions2(module);
|
|
144
|
+
const agentGuidance = module.agentGuidance || module.default?.agentGuidance;
|
|
102
145
|
if (!actions || typeof actions !== "object") {
|
|
103
146
|
throw new Error(
|
|
104
147
|
'Actions file must export an actions object as default or named export "actions"'
|
|
105
148
|
);
|
|
106
149
|
}
|
|
107
|
-
return actions;
|
|
150
|
+
return { actions, agentGuidance };
|
|
108
151
|
} catch (error) {
|
|
109
152
|
throw error;
|
|
110
153
|
}
|
|
111
154
|
}
|
|
112
|
-
function buildManifest(actions, platform, version, gitSha) {
|
|
155
|
+
function buildManifest(actions, platform, version, gitSha, agentGuidance) {
|
|
113
156
|
const entries = [];
|
|
114
157
|
for (const [name, definition] of Object.entries(actions)) {
|
|
115
158
|
const entry = {
|
|
@@ -127,23 +170,32 @@ function buildManifest(actions, platform, version, gitSha) {
|
|
|
127
170
|
entry.auto_run = definition.autoRun;
|
|
128
171
|
if (definition.autoComplete)
|
|
129
172
|
entry.auto_complete = definition.autoComplete;
|
|
130
|
-
if (definition.returns)
|
|
173
|
+
if (definition.returns !== void 0) {
|
|
131
174
|
entry.returns_data = definition.returns;
|
|
175
|
+
} else if (definition.type === "query") {
|
|
176
|
+
entry.returns_data = true;
|
|
177
|
+
}
|
|
132
178
|
if (definition.dataSchema)
|
|
133
179
|
entry.data_schema = definition.dataSchema;
|
|
134
180
|
if (definition.defaultData)
|
|
135
181
|
entry.default_data = definition.defaultData;
|
|
136
182
|
if (definition.requiredContext)
|
|
137
183
|
entry.required_context = definition.requiredContext;
|
|
184
|
+
if (definition.parameterExamples?.length)
|
|
185
|
+
entry.parameter_examples = definition.parameterExamples;
|
|
138
186
|
entries.push(entry);
|
|
139
187
|
}
|
|
140
|
-
|
|
188
|
+
const manifest = {
|
|
141
189
|
platform,
|
|
142
190
|
version,
|
|
143
191
|
gitSha,
|
|
144
192
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
145
193
|
actions: entries
|
|
146
194
|
};
|
|
195
|
+
if (agentGuidance) {
|
|
196
|
+
manifest.agentGuidance = agentGuidance;
|
|
197
|
+
}
|
|
198
|
+
return manifest;
|
|
147
199
|
}
|
|
148
200
|
async function pollStatus(statusUrl, secret, maxWaitSeconds = 300) {
|
|
149
201
|
const startTime = Date.now();
|
|
@@ -241,15 +293,19 @@ async function main() {
|
|
|
241
293
|
process.exit(1);
|
|
242
294
|
}
|
|
243
295
|
console.log(`[pillar-sync] Loading actions from: ${actionsPath}`);
|
|
244
|
-
let
|
|
296
|
+
let loadedModule;
|
|
245
297
|
try {
|
|
246
|
-
|
|
298
|
+
loadedModule = await loadActions(actionsPath);
|
|
247
299
|
} catch (error) {
|
|
248
300
|
console.error(`[pillar-sync] Failed to load actions:`, error);
|
|
249
301
|
process.exit(1);
|
|
250
302
|
}
|
|
303
|
+
const { actions, agentGuidance } = loadedModule;
|
|
251
304
|
const actionCount = Object.keys(actions).length;
|
|
252
305
|
console.log(`[pillar-sync] Found ${actionCount} actions`);
|
|
306
|
+
if (agentGuidance) {
|
|
307
|
+
console.log(`[pillar-sync] Found agent guidance (${agentGuidance.length} chars)`);
|
|
308
|
+
}
|
|
253
309
|
if (actionCount === 0) {
|
|
254
310
|
console.warn("[pillar-sync] No actions found. Nothing to sync.");
|
|
255
311
|
process.exit(0);
|
|
@@ -260,7 +316,7 @@ async function main() {
|
|
|
260
316
|
console.log(`[pillar-sync] Platform: ${platform}`);
|
|
261
317
|
console.log(`[pillar-sync] Version: ${version}`);
|
|
262
318
|
console.log(`[pillar-sync] Git SHA: ${gitSha || "not available"}`);
|
|
263
|
-
const manifest = buildManifest(actions, platform, version, gitSha);
|
|
319
|
+
const manifest = buildManifest(actions, platform, version, gitSha, agentGuidance);
|
|
264
320
|
if (process.env.PILLAR_DEBUG) {
|
|
265
321
|
const manifestPath = path.join(process.cwd(), "actions-manifest.json");
|
|
266
322
|
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
@@ -273,6 +329,9 @@ async function main() {
|
|
|
273
329
|
git_sha: gitSha,
|
|
274
330
|
actions: manifest.actions
|
|
275
331
|
};
|
|
332
|
+
if (agentGuidance) {
|
|
333
|
+
requestBody.agent_guidance = agentGuidance;
|
|
334
|
+
}
|
|
276
335
|
const syncUrl = `${apiUrl}/api/admin/configs/${slug}/actions/sync/?async=true`;
|
|
277
336
|
console.log(`[pillar-sync] POST ${syncUrl}`);
|
|
278
337
|
try {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug Panel Component
|
|
3
|
+
*
|
|
4
|
+
* Shows real-time SDK event timeline for debugging.
|
|
5
|
+
* Only rendered when debug: true is passed to Pillar.init()
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Source filtering (sdk, handler, network, server)
|
|
9
|
+
* - Text search filter
|
|
10
|
+
* - Color-coded log levels
|
|
11
|
+
* - Export to JSON
|
|
12
|
+
* - Drag to resize height
|
|
13
|
+
* - Auto-scroll to bottom on new logs
|
|
14
|
+
*/
|
|
15
|
+
interface DebugPanelProps {
|
|
16
|
+
/** Whether the panel is expanded */
|
|
17
|
+
expanded?: boolean;
|
|
18
|
+
/** Callback when panel is toggled */
|
|
19
|
+
onToggle?: () => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Debug Panel Component
|
|
23
|
+
*/
|
|
24
|
+
export declare function DebugPanel({ expanded, onToggle }: DebugPanelProps): import("preact").JSX.Element;
|
|
25
|
+
export default DebugPanel;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DevTools CSS Styles
|
|
3
|
+
* Styles for the DOM Scanner preview panel
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEVTOOLS_STYLES = "\n/* Pillar DevTools Styles */\n.pillar-devtools-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 99998;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n box-sizing: border-box;\n}\n\n.pillar-devtools-panel {\n background: #1e1e2e;\n border-radius: 12px;\n box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);\n max-width: 800px;\n width: 100%;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n color: #e0e0e0;\n}\n\n.pillar-devtools-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid #2d2d3d;\n background: #252535;\n}\n\n.pillar-devtools-title {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: #ffffff;\n}\n\n.pillar-devtools-badge {\n padding: 3px 8px;\n background: #6366f1;\n border-radius: 4px;\n font-size: 11px;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.pillar-devtools-close {\n padding: 6px;\n background: transparent;\n border: none;\n border-radius: 6px;\n color: #9090a0;\n cursor: pointer;\n transition: background 0.15s, color 0.15s;\n}\n\n.pillar-devtools-close:hover {\n background: #3d3d4d;\n color: #ffffff;\n}\n\n.pillar-devtools-stats {\n display: flex;\n gap: 16px;\n padding: 12px 20px;\n border-bottom: 1px solid #2d2d3d;\n background: #1a1a2a;\n flex-wrap: wrap;\n}\n\n.pillar-devtools-stat {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n}\n\n.pillar-devtools-stat-value {\n font-weight: 600;\n color: #8b5cf6;\n}\n\n.pillar-devtools-stat-label {\n color: #9090a0;\n}\n\n.pillar-devtools-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n.pillar-devtools-tree {\n font-family: 'SF Mono', Monaco, 'Inconsolata', 'Fira Code', monospace;\n font-size: 12px;\n line-height: 1.6;\n}\n\n.pillar-devtools-node {\n margin-left: 16px;\n position: relative;\n}\n\n.pillar-devtools-node::before {\n content: '';\n position: absolute;\n left: -12px;\n top: 0;\n bottom: 0;\n width: 1px;\n background: #3d3d4d;\n}\n\n.pillar-devtools-node-root {\n margin-left: 0;\n}\n\n.pillar-devtools-node-root::before {\n display: none;\n}\n\n.pillar-devtools-node-header {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n padding: 3px 0;\n cursor: pointer;\n border-radius: 4px;\n transition: background 0.1s;\n}\n\n.pillar-devtools-node-header:hover {\n background: rgba(139, 92, 246, 0.1);\n}\n\n.pillar-devtools-toggle {\n width: 16px;\n height: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #6d6d7d;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.pillar-devtools-toggle svg {\n transition: transform 0.15s;\n}\n\n.pillar-devtools-toggle--expanded svg {\n transform: rotate(90deg);\n}\n\n.pillar-devtools-tag {\n color: #f472b6;\n}\n\n.pillar-devtools-attr-name {\n color: #a78bfa;\n}\n\n.pillar-devtools-attr-value {\n color: #34d399;\n}\n\n.pillar-devtools-interactable {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n background: #6366f1;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n color: #ffffff;\n margin-left: 6px;\n}\n\n.pillar-devtools-text {\n color: #94a3b8;\n font-style: italic;\n max-width: 400px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.pillar-devtools-children {\n display: none;\n}\n\n.pillar-devtools-children--expanded {\n display: block;\n}\n\n.pillar-devtools-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 16px 20px;\n border-top: 1px solid #2d2d3d;\n background: #252535;\n}\n\n.pillar-devtools-footer-info {\n font-size: 12px;\n color: #9090a0;\n}\n\n.pillar-devtools-actions {\n display: flex;\n gap: 10px;\n}\n\n.pillar-devtools-btn {\n padding: 8px 16px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s, transform 0.1s;\n border: none;\n}\n\n.pillar-devtools-btn:active {\n transform: scale(0.98);\n}\n\n.pillar-devtools-btn--secondary {\n background: #3d3d4d;\n color: #e0e0e0;\n}\n\n.pillar-devtools-btn--secondary:hover {\n background: #4d4d5d;\n}\n\n.pillar-devtools-btn--primary {\n background: #6366f1;\n color: #ffffff;\n}\n\n.pillar-devtools-btn--primary:hover {\n background: #4f46e5;\n}\n";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page Pilot Banner Component
|
|
3
|
+
* Shows "Page being piloted by Agent" with stop button during interact_with_page actions.
|
|
4
|
+
* When a destructive action is detected, shows a confirmation variant with Allow/Deny buttons.
|
|
5
|
+
*/
|
|
6
|
+
import { h } from 'preact';
|
|
7
|
+
export declare function PagePilotBanner(): h.JSX.Element | null;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page Pilot Manager
|
|
3
|
+
* Manages the "Page being piloted by Agent" banner, rendering it outside Shadow DOM
|
|
4
|
+
* so it appears above all other content on the page.
|
|
5
|
+
*/
|
|
6
|
+
export declare class PagePilotManager {
|
|
7
|
+
private container;
|
|
8
|
+
private stylesInjected;
|
|
9
|
+
private unsubscribe;
|
|
10
|
+
private themeObserver;
|
|
11
|
+
private primaryColor;
|
|
12
|
+
/**
|
|
13
|
+
* Detect the current theme from the document
|
|
14
|
+
* Checks for .dark class (next-themes) or data-theme attribute
|
|
15
|
+
*/
|
|
16
|
+
private detectThemeFromDOM;
|
|
17
|
+
/**
|
|
18
|
+
* Apply theme mode to container element
|
|
19
|
+
*/
|
|
20
|
+
private applyTheme;
|
|
21
|
+
/**
|
|
22
|
+
* Set up observer to watch for theme changes on documentElement
|
|
23
|
+
*/
|
|
24
|
+
private setupThemeObserver;
|
|
25
|
+
/**
|
|
26
|
+
* Initialize the page pilot manager
|
|
27
|
+
* @param primaryColor - Optional primary color from theme config to override the default
|
|
28
|
+
*/
|
|
29
|
+
init(primaryColor?: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Update the primary color used by the banner
|
|
32
|
+
*/
|
|
33
|
+
setPrimaryColor(color: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Destroy the page pilot manager
|
|
36
|
+
*/
|
|
37
|
+
destroy(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Render the banner component
|
|
40
|
+
*/
|
|
41
|
+
private render;
|
|
42
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page Pilot Components
|
|
3
|
+
* Banner and manager for displaying "Page being piloted by Agent" indicator
|
|
4
|
+
*/
|
|
5
|
+
export { PagePilotBanner } from './PagePilotBanner';
|
|
6
|
+
export { PagePilotManager } from './PagePilotManager';
|
|
7
|
+
export { PAGE_PILOT_STYLES } from './styles';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page Pilot Banner CSS Styles
|
|
3
|
+
* Injected into the document head (outside Shadow DOM)
|
|
4
|
+
* Uses the same CSS variables as the Pillar panel for consistent theming
|
|
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\n/* Confirmation variant \u2014 amber/warning theme */\n._pillar-page-pilot-banner--confirm ._pillar-page-pilot-banner__content {\n background: #d97706;\n}\n\n._pillar-page-pilot-banner--confirm::before {\n border-color: #d97706;\n}\n\n._pillar-page-pilot-banner--confirm::after {\n background: #d97706;\n}\n\n._pillar-page-pilot-banner__warning-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n}\n\n._pillar-page-pilot-banner__warning-icon svg {\n width: 100%;\n height: 100%;\n}\n\n._pillar-page-pilot-banner__deny {\n display: flex;\n align-items: center;\n padding: 5px 12px;\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__deny: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__deny:active {\n transform: scale(0.97);\n}\n\n._pillar-page-pilot-banner__allow {\n display: flex;\n align-items: center;\n padding: 5px 12px;\n font-family: inherit;\n font-size: 12px;\n font-weight: 600;\n color: #d97706;\n background: #ffffff;\n border: 1px solid rgba(255, 255, 255, 0.8);\n border-radius: var(--pillar-radius-md);\n cursor: pointer;\n transition: all var(--pillar-transition-fast);\n}\n\n._pillar-page-pilot-banner__allow:hover {\n background: #fef3c7;\n}\n\n._pillar-page-pilot-banner__allow:active {\n transform: scale(0.97);\n}\n";
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Panel Header Component
|
|
3
|
-
* Navigation header with back, home, and close buttons
|
|
3
|
+
* Navigation header with back, home, history, and close buttons
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import { type ViewType } from '../../store/router';
|
|
5
|
+
import { type ViewType } from "../../store/router";
|
|
7
6
|
interface HeaderProps {
|
|
8
7
|
currentView: ViewType;
|
|
9
|
-
customTitle?: string;
|
|
10
8
|
/** Hide back and home navigation buttons */
|
|
11
9
|
hideNavigation?: boolean;
|
|
12
10
|
}
|
|
13
|
-
export declare function Header({ currentView,
|
|
11
|
+
export declare function Header({ currentView, hideNavigation }: HeaderProps): import("preact").JSX.Element;
|
|
14
12
|
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* History Dropdown Component
|
|
3
|
+
* Shows a list of past conversations grouped by day (like Cursor).
|
|
4
|
+
*/
|
|
5
|
+
import { h } from 'preact';
|
|
6
|
+
interface HistoryDropdownProps {
|
|
7
|
+
onSelectConversation: (conversationId: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function HistoryDropdown({ onSelectConversation }: HistoryDropdownProps): h.JSX.Element;
|
|
10
|
+
export {};
|