@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.
- package/README.md +118 -60
- package/dist/actions/index.d.ts +1 -1
- package/dist/actions/registry.d.ts +15 -27
- package/dist/actions/types.d.ts +20 -8
- package/dist/api/client.d.ts +91 -5
- package/dist/api/mcp-client.d.ts +105 -79
- package/dist/cli/sync.d.ts +0 -1
- package/dist/cli/sync.js +102 -14
- 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/Panel/Header.d.ts +1 -1
- package/dist/components/Panel/HistoryDropdown.d.ts +10 -0
- package/dist/components/Panel/Panel.d.ts +1 -0
- package/dist/components/Panel/TaskButton.d.ts +4 -14
- package/dist/components/Panel/styles.d.ts +1 -1
- 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/ProgressRow.d.ts +16 -0
- package/dist/components/Progress/ProgressStack.d.ts +15 -0
- package/dist/components/Progress/ReasoningDisclosure.d.ts +20 -0
- package/dist/components/Progress/index.d.ts +3 -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 +318 -80
- package/dist/core/config.d.ts +141 -3
- 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 +14 -12
- package/dist/pillar.esm.js +1 -1
- package/dist/store/chat.d.ts +102 -4
- package/dist/store/index.d.ts +1 -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 +46 -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 +44 -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 +21 -7
- 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,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
|
|
57
|
-
|
|
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
|
-
*
|
|
179
|
+
* Send action result back to the agent.
|
|
127
180
|
*
|
|
128
|
-
* Called
|
|
129
|
-
*
|
|
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
|
|
133
|
-
* @param
|
|
134
|
-
* @param
|
|
135
|
-
* @returns
|
|
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
|
-
|
|
138
|
-
plan: ExecutionPlan;
|
|
139
|
-
}>;
|
|
189
|
+
sendActionResult(actionName: string, result: unknown, toolCallId?: string): Promise<void>;
|
|
140
190
|
/**
|
|
141
|
-
*
|
|
191
|
+
* Send a client-side log to the server for debugging.
|
|
142
192
|
*
|
|
143
|
-
*
|
|
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
|
|
146
|
-
* @
|
|
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
|
-
|
|
149
|
-
plan: ExecutionPlan;
|
|
150
|
-
}>;
|
|
200
|
+
sendLog(level: 'log' | 'warn' | 'error', message: string, data?: unknown): Promise<void>;
|
|
151
201
|
/**
|
|
152
|
-
*
|
|
202
|
+
* Send a batch of client-side logs to the server.
|
|
153
203
|
*
|
|
154
|
-
*
|
|
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
|
|
157
|
-
* @returns Plan with all steps
|
|
207
|
+
* @param logs - Array of log entries to send
|
|
158
208
|
*/
|
|
159
|
-
|
|
160
|
-
plan: ExecutionPlan;
|
|
161
|
-
}>;
|
|
209
|
+
sendLogBatch(logs: LogEntry[]): void;
|
|
162
210
|
/**
|
|
163
|
-
*
|
|
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
|
|
169
|
-
* @returns
|
|
213
|
+
* @param conversationId - The conversation UUID to check
|
|
214
|
+
* @returns Session status with resumption details, or null if not resumable
|
|
170
215
|
*/
|
|
171
|
-
|
|
172
|
-
plan: ExecutionPlan;
|
|
173
|
-
}>;
|
|
216
|
+
getConversationStatus(conversationId: string): Promise<ConversationStatus | null>;
|
|
174
217
|
/**
|
|
175
|
-
*
|
|
218
|
+
* Resume an interrupted conversation.
|
|
176
219
|
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
220
|
+
* Returns a streaming response that continues the conversation
|
|
221
|
+
* from where it was interrupted.
|
|
179
222
|
*
|
|
180
|
-
* @param
|
|
181
|
-
* @param
|
|
182
|
-
* @
|
|
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
|
-
|
|
199
|
-
plan: ExecutionPlan;
|
|
200
|
-
}>;
|
|
227
|
+
resumeConversation(conversationId: string, userContext: Record<string, unknown> | undefined, callbacks: StreamCallbacks): Promise<void>;
|
|
201
228
|
/**
|
|
202
|
-
*
|
|
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
|
-
|
|
209
|
-
|
|
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.
|
package/dist/cli/sync.d.ts
CHANGED
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
|
|
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
|
-
|
|
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
|
|
294
|
+
let loadedModule;
|
|
214
295
|
try {
|
|
215
|
-
|
|
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,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,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 {};
|
|
@@ -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
|
-
*
|
|
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 {};
|