@pillar-ai/sdk 0.1.8 → 0.1.14

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.
Files changed (58) hide show
  1. package/README.md +118 -60
  2. package/dist/actions/index.d.ts +1 -1
  3. package/dist/actions/registry.d.ts +15 -27
  4. package/dist/actions/types.d.ts +20 -8
  5. package/dist/api/client.d.ts +91 -5
  6. package/dist/api/mcp-client.d.ts +105 -79
  7. package/dist/cli/sync.d.ts +0 -1
  8. package/dist/cli/sync.js +102 -14
  9. package/dist/components/DebugPanel/DebugPanel.d.ts +25 -0
  10. package/dist/components/DebugPanel/index.d.ts +2 -0
  11. package/dist/components/DevTools/index.d.ts +5 -0
  12. package/dist/components/DevTools/styles.d.ts +5 -0
  13. package/dist/components/Panel/Header.d.ts +1 -1
  14. package/dist/components/Panel/HistoryDropdown.d.ts +10 -0
  15. package/dist/components/Panel/Panel.d.ts +1 -0
  16. package/dist/components/Panel/TaskButton.d.ts +4 -14
  17. package/dist/components/Panel/styles.d.ts +1 -1
  18. package/dist/components/Plan/InlinePlanView.d.ts +1 -1
  19. package/dist/components/Plan/PlanDocument.d.ts +18 -0
  20. package/dist/components/Plan/PlanStepItem.d.ts +1 -1
  21. package/dist/components/Plan/PlanView.d.ts +1 -1
  22. package/dist/components/Plan/index.d.ts +1 -0
  23. package/dist/components/Progress/ProgressRow.d.ts +16 -0
  24. package/dist/components/Progress/ProgressStack.d.ts +15 -0
  25. package/dist/components/Progress/ReasoningDisclosure.d.ts +20 -0
  26. package/dist/components/Progress/index.d.ts +3 -0
  27. package/dist/components/Views/HomeView.d.ts +3 -0
  28. package/dist/components/Views/ResumePrompt.d.ts +22 -0
  29. package/dist/components/Views/index.d.ts +1 -0
  30. package/dist/components/index.d.ts +1 -0
  31. package/dist/components/shared/icons.d.ts +24 -0
  32. package/dist/components/shared/index.d.ts +1 -0
  33. package/dist/core/Pillar.d.ts +318 -80
  34. package/dist/core/config.d.ts +141 -3
  35. package/dist/core/events.d.ts +55 -70
  36. package/dist/core/plan-executor.d.ts +29 -0
  37. package/dist/core/plan.d.ts +6 -0
  38. package/dist/hooks/index.d.ts +5 -0
  39. package/dist/hooks/useDebouncedValue.d.ts +22 -0
  40. package/dist/hooks/useInlineCard.d.ts +35 -0
  41. package/dist/hooks/usePillarInstance.d.ts +30 -0
  42. package/dist/index.d.ts +14 -12
  43. package/dist/pillar.esm.js +1 -1
  44. package/dist/store/chat.d.ts +102 -4
  45. package/dist/store/index.d.ts +1 -0
  46. package/dist/store/session-persistence.d.ts +62 -0
  47. package/dist/store/suggestions.d.ts +58 -0
  48. package/dist/types/dom-scanner.d.ts +46 -0
  49. package/dist/types/index.d.ts +1 -0
  50. package/dist/types/user-context.d.ts +32 -1
  51. package/dist/utils/debug.d.ts +150 -0
  52. package/dist/utils/dom-scanner.d.ts +44 -0
  53. package/dist/utils/markdown-components.d.ts +53 -0
  54. package/dist/utils/preact-markdown.d.ts +17 -0
  55. package/dist/utils/route-observer.d.ts +67 -0
  56. package/package.json +1 -1
  57. package/src/actions/types.ts +21 -7
  58. package/dist/utils/markdown.d.ts +0 -9
@@ -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
- plan?: ExecutionPlan;
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,17 @@ 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
+ }
48
60
  /** Streaming callbacks for tool calls */
49
61
  export interface StreamCallbacks {
50
62
  /** Called for each text token */
@@ -53,17 +65,32 @@ export interface StreamCallbacks {
53
65
  onSources?: (sources: ArticleSummary[]) => void;
54
66
  /** Called when actions are available */
55
67
  onActions?: (actions: ActionData[]) => void;
56
- /** Called when a plan is created (from plan.created event) */
57
- onPlan?: (plan: ExecutionPlan) => void;
68
+ /** Called when registered actions are received (for dynamic action tools) */
69
+ onRegisteredActions?: (actions: Record<string, unknown>[]) => void;
58
70
  /** Called on error */
59
71
  onError?: (error: string) => void;
72
+ /** Called when conversation_started event is received (early conversation_id) */
73
+ onConversationStarted?: (conversationId: string, messageId?: string) => void;
60
74
  /** Called when stream is complete */
61
75
  onComplete?: (conversationId?: string, queryLogId?: string) => void;
62
- /** Called for progress updates */
76
+ /** Called for progress updates (search, query, generating, thinking, etc.) */
63
77
  onProgress?: (progress: {
64
78
  kind: string;
79
+ id?: string;
80
+ label?: string;
81
+ status?: 'active' | 'done' | 'error';
82
+ text?: string;
83
+ children?: Array<{
84
+ id: string;
85
+ label: string;
86
+ url?: string;
87
+ }>;
88
+ metadata?: Record<string, unknown>;
89
+ progress_id?: string;
65
90
  message?: string;
66
91
  }) => void;
92
+ /** Called when agent requests action execution (unified handler) */
93
+ onActionRequest?: (request: ActionRequest) => Promise<void>;
67
94
  }
68
95
  /** Image for chat requests (from upload-image endpoint) */
69
96
  export interface ChatImage {
@@ -80,7 +107,27 @@ export interface ImageUploadResponse {
80
107
  export declare class MCPClient {
81
108
  private config;
82
109
  private requestId;
110
+ private _externalUserId;
83
111
  constructor(config: ResolvedConfig);
112
+ /**
113
+ * Set the external user ID for authenticated users.
114
+ * Enables cross-device conversation history.
115
+ */
116
+ setExternalUserId(userId: string): void;
117
+ /**
118
+ * Get or create a persistent visitor ID.
119
+ * Stored in localStorage to persist across sessions.
120
+ */
121
+ private getVisitorId;
122
+ /**
123
+ * Get or create a session ID for MCP request correlation.
124
+ * Stored in sessionStorage to persist only for the current browser session.
125
+ */
126
+ private getSessionId;
127
+ /**
128
+ * Get the current page URL for analytics tracking.
129
+ */
130
+ private getPageUrl;
84
131
  private get baseUrl();
85
132
  private get headers();
86
133
  private nextId;
@@ -120,104 +167,83 @@ export declare class MCPClient {
120
167
  articleSlug?: string;
121
168
  userContext?: UserContextItem[];
122
169
  images?: ChatImage[];
170
+ history?: Array<{
171
+ role: 'user' | 'assistant';
172
+ content: string;
173
+ }>;
174
+ /** Registered actions from previous turns (for dynamic action tools) */
175
+ registeredActions?: Record<string, unknown>[];
123
176
  signal?: AbortSignal;
124
177
  }): Promise<ToolResult>;
125
178
  /**
126
- * Continue plan execution after receiving step result.
179
+ * Send action result back to the agent.
127
180
  *
128
- * Called by the SDK after executing a step that has
129
- * requires_result_feedback=true. The server analyzes the result
130
- * and updates subsequent steps if needed.
181
+ * Called after executing a query action (returns_data=true).
182
+ * The result is sent to the agent for further reasoning in the ReAct loop.
131
183
  *
132
- * @param planId - UUID of the plan
133
- * @param stepId - UUID of the completed step
134
- * @param result - Step execution result
135
- * @returns Updated plan with all steps
184
+ * @param actionName - The name of the action that was executed
185
+ * @param result - The result data to send back to the agent
186
+ * @param toolCallId - Unique ID for this specific tool invocation (for result correlation)
187
+ * @returns Promise that resolves when the result is delivered, or rejects on error
136
188
  */
137
- continuePlan(planId: string, stepId: string, result: unknown): Promise<{
138
- plan: ExecutionPlan;
139
- }>;
189
+ sendActionResult(actionName: string, result: unknown, toolCallId?: string): Promise<void>;
140
190
  /**
141
- * Cancel an in-progress plan.
191
+ * Send a client-side log to the server for debugging.
142
192
  *
143
- * Marks the plan as cancelled and skips any pending steps.
193
+ * Logs are correlated with agent sessions via the MCP session ID.
194
+ * Use this to forward important SDK events to server logs.
144
195
  *
145
- * @param planId - UUID of the plan to cancel
146
- * @returns Updated plan with cancelled status
196
+ * @param level - Log level: 'log', 'warn', or 'error'
197
+ * @param message - The log message
198
+ * @param data - Optional additional data to include
147
199
  */
148
- cancelPlan(planId: string): Promise<{
149
- plan: ExecutionPlan;
150
- }>;
200
+ sendLog(level: 'log' | 'warn' | 'error', message: string, data?: unknown): Promise<void>;
151
201
  /**
152
- * Get current state of a plan.
202
+ * Send a batch of client-side logs to the server.
153
203
  *
154
- * Returns the plan and all its steps with current statuses.
204
+ * Logs are buffered and sent periodically (every 5 seconds by default)
205
+ * to reduce network requests. This method is called by the debug module.
155
206
  *
156
- * @param planId - UUID of the plan
157
- * @returns Plan with all steps
207
+ * @param logs - Array of log entries to send
158
208
  */
159
- getPlan(planId: string): Promise<{
160
- plan: ExecutionPlan;
161
- }>;
209
+ sendLogBatch(logs: LogEntry[]): void;
162
210
  /**
163
- * Start a plan that was waiting for user confirmation.
164
- *
165
- * For plans with auto_execute=false, the user must explicitly
166
- * start execution by calling this method.
211
+ * Check if a conversation has a resumable interrupted session.
167
212
  *
168
- * @param planId - UUID of the plan to start
169
- * @returns Updated plan with executing status
213
+ * @param conversationId - The conversation UUID to check
214
+ * @returns Session status with resumption details, or null if not resumable
170
215
  */
171
- startPlan(planId: string): Promise<{
172
- plan: ExecutionPlan;
173
- }>;
216
+ getConversationStatus(conversationId: string): Promise<ConversationStatus | null>;
174
217
  /**
175
- * Retry a failed step.
218
+ * Resume an interrupted conversation.
176
219
  *
177
- * Increments the retry count and resets the step to ready status.
178
- * Only works if the step is retriable and hasn't exceeded max_retries.
220
+ * Returns a streaming response that continues the conversation
221
+ * from where it was interrupted.
179
222
  *
180
- * @param planId - UUID of the plan
181
- * @param stepId - UUID of the step to retry
182
- * @returns Updated plan with step reset to ready
183
- */
184
- retryStep(planId: string, stepId: string): Promise<{
185
- plan: ExecutionPlan;
186
- }>;
187
- /**
188
- * Mark a step as failed.
189
- *
190
- * Records the error and determines if the plan should also fail
191
- * (if step is not retriable or out of retries).
192
- *
193
- * @param planId - UUID of the plan
194
- * @param stepId - UUID of the failed step
195
- * @param errorMessage - Optional error message
196
- * @returns Updated plan with failed step
223
+ * @param conversationId - The conversation to resume
224
+ * @param userContext - Optional current page context
225
+ * @param callbacks - Streaming callbacks
197
226
  */
198
- failStep(planId: string, stepId: string, errorMessage?: string): Promise<{
199
- plan: ExecutionPlan;
200
- }>;
227
+ resumeConversation(conversationId: string, userContext: Record<string, unknown> | undefined, callbacks: StreamCallbacks): Promise<void>;
201
228
  /**
202
- * Skip a step and advance to the next one.
203
- *
204
- * @param planId - UUID of the plan
205
- * @param stepId - UUID of the step to skip
206
- * @returns Updated plan with skipped step and next step ready
229
+ * Handle events from the resume stream.
207
230
  */
208
- skipStep(planId: string, stepId: string): Promise<{
209
- plan: ExecutionPlan;
231
+ private handleResumeStreamEvent;
232
+ }
233
+ /**
234
+ * Conversation status for session resumption.
235
+ */
236
+ export interface ConversationStatus {
237
+ resumable: boolean;
238
+ message_id?: string;
239
+ elapsed_ms?: number;
240
+ user_message?: string;
241
+ partial_response?: string;
242
+ summary?: string;
243
+ accomplished?: Array<{
244
+ action: string;
245
+ result_summary: string;
210
246
  }>;
211
- /**
212
- * Send action result back to the agent.
213
- *
214
- * Called after executing a query action (returns_data=true).
215
- * The result is sent to the agent for further reasoning in the ReAct loop.
216
- *
217
- * @param actionName - The name of the action that was executed
218
- * @param result - The result data to send back to the agent
219
- */
220
- sendActionResult(actionName: string, result: unknown): void;
221
247
  }
222
248
  /**
223
249
  * Convert ActionData from MCP response to TaskButtonData for UI rendering.
@@ -1,2 +1 @@
1
- #!/usr/bin/env node
2
1
  export {};
package/dist/cli/sync.js CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- #!/usr/bin/env node
3
2
 
4
3
  // src/cli/sync.ts
5
4
  import * as fs from "fs";
@@ -59,26 +58,101 @@ async function loadActions(actionsPath) {
59
58
  if (!fs.existsSync(absolutePath)) {
60
59
  throw new Error(`Actions file not found: ${absolutePath}`);
61
60
  }
61
+ const isTypeScript = absolutePath.endsWith(".ts") || absolutePath.endsWith(".tsx");
62
+ if (isTypeScript) {
63
+ try {
64
+ const tempDir = path.dirname(absolutePath);
65
+ const tempFile = path.join(tempDir, `.pillar-sync-temp-${Date.now()}.mjs`);
66
+ const importPath = absolutePath.replace(/\\/g, "/");
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 }));`;
93
+ fs.writeFileSync(tempFile, extractScript, "utf-8");
94
+ try {
95
+ const result = execSync(`npx tsx "${tempFile}"`, {
96
+ encoding: "utf-8",
97
+ cwd: process.cwd(),
98
+ stdio: ["pipe", "pipe", "pipe"]
99
+ });
100
+ const parsed = JSON.parse(result.trim());
101
+ const actions = parsed.actions;
102
+ const agentGuidance = parsed.agentGuidance;
103
+ if (!actions || typeof actions !== "object") {
104
+ throw new Error(
105
+ 'Actions file must export an actions object as default or named export "actions"'
106
+ );
107
+ }
108
+ return { actions, agentGuidance };
109
+ } finally {
110
+ if (fs.existsSync(tempFile)) {
111
+ fs.unlinkSync(tempFile);
112
+ }
113
+ }
114
+ } catch (error) {
115
+ if (error instanceof Error && error.message.includes("tsx")) {
116
+ console.error("[pillar-sync] TypeScript files require tsx.");
117
+ console.error("[pillar-sync] Make sure tsx is installed: npm install -D tsx");
118
+ console.error("[pillar-sync] Then run: npx pillar-sync --actions ./actions.ts");
119
+ }
120
+ throw error;
121
+ }
122
+ }
62
123
  const fileUrl = pathToFileURL(absolutePath).href;
63
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;
64
142
  const module = await import(fileUrl);
65
- const actions = module.default || module.actions;
143
+ const actions = resolveActions2(module);
144
+ const agentGuidance = module.agentGuidance || module.default?.agentGuidance;
66
145
  if (!actions || typeof actions !== "object") {
67
146
  throw new Error(
68
147
  'Actions file must export an actions object as default or named export "actions"'
69
148
  );
70
149
  }
71
- return actions;
150
+ return { actions, agentGuidance };
72
151
  } catch (error) {
73
- if (error instanceof Error && error.message.includes("Unknown file extension")) {
74
- console.error("[pillar-sync] TypeScript files require tsx.");
75
- console.error("[pillar-sync] Make sure tsx is installed: npm install -D tsx");
76
- console.error("[pillar-sync] Then run: npx pillar-sync --actions ./actions.ts");
77
- }
78
152
  throw error;
79
153
  }
80
154
  }
81
- function buildManifest(actions, platform, version, gitSha) {
155
+ function buildManifest(actions, platform, version, gitSha, agentGuidance) {
82
156
  const entries = [];
83
157
  for (const [name, definition] of Object.entries(actions)) {
84
158
  const entry = {
@@ -96,8 +170,11 @@ function buildManifest(actions, platform, version, gitSha) {
96
170
  entry.auto_run = definition.autoRun;
97
171
  if (definition.autoComplete)
98
172
  entry.auto_complete = definition.autoComplete;
99
- if (definition.returns)
173
+ if (definition.returns !== void 0) {
100
174
  entry.returns_data = definition.returns;
175
+ } else if (definition.type === "query") {
176
+ entry.returns_data = true;
177
+ }
101
178
  if (definition.dataSchema)
102
179
  entry.data_schema = definition.dataSchema;
103
180
  if (definition.defaultData)
@@ -106,13 +183,17 @@ function buildManifest(actions, platform, version, gitSha) {
106
183
  entry.required_context = definition.requiredContext;
107
184
  entries.push(entry);
108
185
  }
109
- return {
186
+ const manifest = {
110
187
  platform,
111
188
  version,
112
189
  gitSha,
113
190
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
114
191
  actions: entries
115
192
  };
193
+ if (agentGuidance) {
194
+ manifest.agentGuidance = agentGuidance;
195
+ }
196
+ return manifest;
116
197
  }
117
198
  async function pollStatus(statusUrl, secret, maxWaitSeconds = 300) {
118
199
  const startTime = Date.now();
@@ -210,15 +291,19 @@ async function main() {
210
291
  process.exit(1);
211
292
  }
212
293
  console.log(`[pillar-sync] Loading actions from: ${actionsPath}`);
213
- let actions;
294
+ let loadedModule;
214
295
  try {
215
- actions = await loadActions(actionsPath);
296
+ loadedModule = await loadActions(actionsPath);
216
297
  } catch (error) {
217
298
  console.error(`[pillar-sync] Failed to load actions:`, error);
218
299
  process.exit(1);
219
300
  }
301
+ const { actions, agentGuidance } = loadedModule;
220
302
  const actionCount = Object.keys(actions).length;
221
303
  console.log(`[pillar-sync] Found ${actionCount} actions`);
304
+ if (agentGuidance) {
305
+ console.log(`[pillar-sync] Found agent guidance (${agentGuidance.length} chars)`);
306
+ }
222
307
  if (actionCount === 0) {
223
308
  console.warn("[pillar-sync] No actions found. Nothing to sync.");
224
309
  process.exit(0);
@@ -229,7 +314,7 @@ async function main() {
229
314
  console.log(`[pillar-sync] Platform: ${platform}`);
230
315
  console.log(`[pillar-sync] Version: ${version}`);
231
316
  console.log(`[pillar-sync] Git SHA: ${gitSha || "not available"}`);
232
- const manifest = buildManifest(actions, platform, version, gitSha);
317
+ const manifest = buildManifest(actions, platform, version, gitSha, agentGuidance);
233
318
  if (process.env.PILLAR_DEBUG) {
234
319
  const manifestPath = path.join(process.cwd(), "actions-manifest.json");
235
320
  fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
@@ -242,6 +327,9 @@ async function main() {
242
327
  git_sha: gitSha,
243
328
  actions: manifest.actions
244
329
  };
330
+ if (agentGuidance) {
331
+ requestBody.agent_guidance = agentGuidance;
332
+ }
245
333
  const syncUrl = `${apiUrl}/api/admin/configs/${slug}/actions/sync/?async=true`;
246
334
  console.log(`[pillar-sync] POST ${syncUrl}`);
247
335
  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,2 @@
1
+ export { DebugPanel } from './DebugPanel';
2
+ export { default } from './DebugPanel';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * DevTools Components
3
+ * Development tools for debugging and previewing Pillar SDK features
4
+ */
5
+ export { DEVTOOLS_STYLES } from './styles';
@@ -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";
@@ -1,6 +1,6 @@
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
5
  import { h } from 'preact';
6
6
  import { type ViewType } from '../../store/router';
@@ -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 {};
@@ -38,6 +38,7 @@ export declare class Panel {
38
38
  */
39
39
  open(options?: {
40
40
  view?: string;
41
+ search?: string;
41
42
  focusInput?: boolean;
42
43
  }): void;
43
44
  /**
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * Renders a task action button in chat responses.
5
5
  * When clicked, triggers the task execution via the Pillar SDK.
6
+ * For inline_ui actions, clicking toggles a confirmation card below the button.
6
7
  *
7
8
  * Presentation (label, icon) is derived from task name and type.
8
9
  * The server only sends: name, task_type, data.
@@ -25,16 +26,6 @@ export interface TaskButtonData {
25
26
  autoRun?: boolean;
26
27
  /** If true, action completes without waiting for host confirmation */
27
28
  autoComplete?: boolean;
28
- /** @deprecated SDK now derives label from name */
29
- label?: string;
30
- /** @deprecated SDK now derives icon from taskType */
31
- icon?: string;
32
- /** @deprecated Use default variant */
33
- buttonVariant?: 'default' | 'primary' | 'secondary' | 'outline' | 'ghost';
34
- /** @deprecated Included in data.path */
35
- path?: string;
36
- /** @deprecated Included in data.url */
37
- externalUrl?: string;
38
29
  }
39
30
  interface TaskButtonProps {
40
31
  task: TaskButtonData;
@@ -43,9 +34,8 @@ interface TaskButtonProps {
43
34
  /**
44
35
  * Create a TaskButton element.
45
36
  *
46
- * Presentation is derived:
47
- * - Label: from task.label (legacy) or derived from task.name
48
- * - Icon: from task.icon (legacy) or derived from task.taskType
37
+ * Presentation is derived from task.name and task.taskType.
38
+ * For inline_ui actions, clicking toggles a confirmation card below the button.
49
39
  */
50
40
  export declare function createTaskButton(props: TaskButtonProps): HTMLButtonElement;
51
41
  /**
@@ -55,5 +45,5 @@ export declare function createTaskButtonGroup(tasks: TaskButtonData[]): HTMLDivE
55
45
  /**
56
46
  * CSS styles for TaskButton (to be added to PANEL_STYLES).
57
47
  */
58
- export declare const TASK_BUTTON_STYLES = "\n/* Task Button Component */\n.pillar-task-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px;\n font-size: 13px;\n font-weight: 500;\n font-family: inherit;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n text-decoration: none;\n}\n\n.pillar-task-btn__icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.pillar-task-btn__icon svg {\n width: 16px;\n height: 16px;\n}\n\n.pillar-task-btn__label {\n white-space: nowrap;\n}\n\n/* Primary variant (default) */\n.pillar-task-btn--primary {\n background: #2563eb;\n color: #ffffff;\n border-color: #2563eb;\n}\n\n.pillar-task-btn--primary:hover {\n background: #1d4ed8;\n border-color: #1d4ed8;\n}\n\n/* Default variant */\n.pillar-task-btn--default {\n background: #f3f4f6;\n color: #1a1a1a;\n border-color: #e5e7eb;\n}\n\n.pillar-task-btn--default:hover {\n background: #e5e7eb;\n}\n\n/* Secondary variant */\n.pillar-task-btn--secondary {\n background: #eff6ff;\n color: #2563eb;\n border-color: #dbeafe;\n}\n\n.pillar-task-btn--secondary:hover {\n background: #dbeafe;\n}\n\n/* Outline variant */\n.pillar-task-btn--outline {\n background: transparent;\n color: #2563eb;\n border-color: #2563eb;\n}\n\n.pillar-task-btn--outline:hover {\n background: #eff6ff;\n}\n\n/* Ghost variant */\n.pillar-task-btn--ghost {\n background: transparent;\n color: #6b7280;\n border-color: transparent;\n}\n\n.pillar-task-btn--ghost:hover {\n background: #f3f4f6;\n color: #1a1a1a;\n}\n\n/* Task button group */\n.pillar-task-btn-group {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n margin-top: 12px;\n}\n\n/* Task suggestion card in chat */\n.pillar-task-suggestion {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: #f9fafb;\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n margin-top: 12px;\n}\n\n.pillar-task-suggestion__header {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #6b7280;\n}\n\n.pillar-task-suggestion__header svg {\n width: 14px;\n height: 14px;\n}\n\n.pillar-task-suggestion__description {\n font-size: 13px;\n color: #374151;\n}\n";
48
+ export declare const TASK_BUTTON_STYLES = "\n/* Task Button Component */\n.pillar-task-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px;\n font-size: 13px;\n font-weight: 500;\n font-family: inherit;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n text-decoration: none;\n}\n\n.pillar-task-btn__icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.pillar-task-btn__icon svg {\n width: 16px;\n height: 16px;\n}\n\n.pillar-task-btn__label {\n white-space: nowrap;\n}\n\n/* Primary variant (default) */\n.pillar-task-btn--primary {\n background: #2563eb;\n color: #ffffff;\n border-color: #2563eb;\n}\n\n.pillar-task-btn--primary:hover {\n background: #1d4ed8;\n border-color: #1d4ed8;\n}\n\n/* Default variant */\n.pillar-task-btn--default {\n background: #f3f4f6;\n color: #1a1a1a;\n border-color: #e5e7eb;\n}\n\n.pillar-task-btn--default:hover {\n background: #e5e7eb;\n}\n\n/* Secondary variant */\n.pillar-task-btn--secondary {\n background: #eff6ff;\n color: #2563eb;\n border-color: #dbeafe;\n}\n\n.pillar-task-btn--secondary:hover {\n background: #dbeafe;\n}\n\n/* Outline variant */\n.pillar-task-btn--outline {\n background: transparent;\n color: #2563eb;\n border-color: #2563eb;\n}\n\n.pillar-task-btn--outline:hover {\n background: #eff6ff;\n}\n\n/* Ghost variant */\n.pillar-task-btn--ghost {\n background: transparent;\n color: #6b7280;\n border-color: transparent;\n}\n\n.pillar-task-btn--ghost:hover {\n background: #f3f4f6;\n color: #1a1a1a;\n}\n\n/* Active state for inline_ui buttons with expanded card */\n.pillar-task-btn--active {\n background: #1d4ed8;\n border-color: #1d4ed8;\n}\n\n/* Task button group */\n.pillar-task-btn-group {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n margin-top: 12px;\n}\n\n/* Inline card container for inline_ui actions */\n.pillar-task-btn-inline-card {\n margin-top: 12px;\n animation: pillar-slide-down 0.15s ease-out;\n}\n\n@keyframes pillar-slide-down {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Task suggestion card in chat */\n.pillar-task-suggestion {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 12px;\n background: #f9fafb;\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n margin-top: 12px;\n}\n\n.pillar-task-suggestion__header {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #6b7280;\n}\n\n.pillar-task-suggestion__header svg {\n width: 14px;\n height: 14px;\n}\n\n.pillar-task-suggestion__description {\n font-size: 13px;\n color: #374151;\n}\n";
59
49
  export {};