@pillar-ai/sdk 0.1.19 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/definitions/analytics.d.ts +18 -0
- package/dist/actions/definitions/content.d.ts +40 -0
- package/dist/actions/definitions/index.d.ts +26 -0
- package/dist/actions/definitions/navigation.d.ts +65 -0
- package/dist/actions/definitions/settings.d.ts +162 -0
- package/dist/actions/definitions/sources.d.ts +44 -0
- package/dist/actions/definitions/support.d.ts +15 -0
- package/dist/actions/definitions/team.d.ts +120 -0
- package/dist/api/ag-ui-adapter.d.ts +76 -0
- package/dist/api/ag-ui-bridge.d.ts +49 -0
- package/dist/api/ag-ui-client.d.ts +102 -0
- package/dist/api/ag-ui-handler.d.ts +89 -0
- package/dist/api/mcp-client.d.ts +46 -24
- package/dist/cli/sync.js +253 -174
- package/dist/components/Button/FloatingButton.d.ts +46 -0
- package/dist/components/PagePilot/styles.d.ts +1 -1
- package/dist/components/Panel/TabNavigation.d.ts +16 -0
- package/dist/components/Panel/styles.d.ts +1 -1
- package/dist/components/Progress/AGUIProgress.d.ts +15 -0
- package/dist/components/Progress/ErrorRow.d.ts +12 -0
- package/dist/components/Progress/index.d.ts +1 -0
- package/dist/components/Tooltips/Tooltip.d.ts +46 -0
- package/dist/components/Tooltips/TooltipManager.d.ts +41 -0
- package/dist/components/Tooltips/index.d.ts +6 -0
- package/dist/components/Tooltips/styles.d.ts +5 -0
- package/dist/components/Views/ArticleChatView.d.ts +10 -0
- package/dist/components/Views/ArticleView.d.ts +10 -0
- package/dist/components/Views/CategoryView.d.ts +11 -0
- package/dist/components/Views/HelpCenterArticles.d.ts +17 -0
- package/dist/components/Views/SearchView.d.ts +10 -0
- package/dist/components/Views/SupportView.d.ts +15 -0
- package/dist/components/shared/ArticleCard.d.ts +17 -0
- package/dist/components/shared/CategoryCard.d.ts +17 -0
- package/dist/content/extensions/AccordionNode.d.ts +10 -0
- package/dist/content/extensions/CalloutNode.d.ts +11 -0
- package/dist/content/extensions/index.d.ts +5 -0
- package/dist/content/index.d.ts +5 -0
- package/dist/content/renderer.d.ts +24 -0
- package/dist/core/Pillar.d.ts +85 -28
- package/dist/core/config.d.ts +1 -1
- package/dist/core/events.d.ts +7 -1
- package/dist/index.d.ts +2 -2
- package/dist/pillar.esm.js +1 -1
- package/dist/store/chat.d.ts +12 -0
- package/dist/store/tooltips.d.ts +21 -0
- package/dist/tools/index.d.ts +27 -0
- package/dist/tools/registry.d.ts +106 -0
- package/dist/tools/types.d.ts +564 -0
- package/dist/utils/helpdesk.d.ts +33 -0
- package/dist/utils/markdown.d.ts +9 -0
- package/dist/utils/resilient-fetch.d.ts +25 -0
- package/package.json +12 -3
- package/src/actions/types.ts +0 -524
package/dist/cli/sync.js
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import * as fs from "fs";
|
|
5
5
|
import * as path from "path";
|
|
6
6
|
import { execSync } from "child_process";
|
|
7
|
-
import { pathToFileURL } from "url";
|
|
8
7
|
var DEFAULT_API_URL = "https://help-api.trypillar.com";
|
|
9
8
|
var LOCAL_API_URL = "http://localhost:8003";
|
|
10
9
|
function parseArgs(args) {
|
|
@@ -26,14 +25,16 @@ function parseArgs(args) {
|
|
|
26
25
|
}
|
|
27
26
|
function printUsage() {
|
|
28
27
|
console.log(`
|
|
29
|
-
Pillar
|
|
28
|
+
Pillar Tool Sync CLI
|
|
29
|
+
|
|
30
|
+
Scans for usePillarTool/defineTool calls and syncs to the Pillar backend.
|
|
31
|
+
Also supports legacy usePillarAction/defineAction calls.
|
|
30
32
|
|
|
31
33
|
Usage:
|
|
32
|
-
npx pillar-sync --
|
|
34
|
+
npx pillar-sync --scan <dir> [--local]
|
|
33
35
|
|
|
34
36
|
Arguments:
|
|
35
|
-
--
|
|
36
|
-
Supports .ts, .js, .mjs files
|
|
37
|
+
--scan <dir> Directory to scan for usePillarTool/defineTool calls
|
|
37
38
|
--local Use localhost:8003 as the API URL (for local development)
|
|
38
39
|
--help Show this help message
|
|
39
40
|
|
|
@@ -46,157 +47,13 @@ Environment Variables:
|
|
|
46
47
|
GIT_SHA Git commit SHA for traceability
|
|
47
48
|
|
|
48
49
|
Examples:
|
|
49
|
-
#
|
|
50
|
-
PILLAR_SLUG=my-app PILLAR_SECRET=xxx npx pillar-sync --
|
|
50
|
+
# Scan and sync tools
|
|
51
|
+
PILLAR_SLUG=my-app PILLAR_SECRET=xxx npx pillar-sync --scan ./src
|
|
51
52
|
|
|
52
53
|
# Local development
|
|
53
|
-
PILLAR_SLUG=my-app PILLAR_SECRET=xxx npx pillar-sync --
|
|
54
|
+
PILLAR_SLUG=my-app PILLAR_SECRET=xxx npx pillar-sync --scan ./src --local
|
|
54
55
|
`);
|
|
55
56
|
}
|
|
56
|
-
async function loadActions(actionsPath) {
|
|
57
|
-
const absolutePath = path.resolve(process.cwd(), actionsPath);
|
|
58
|
-
if (!fs.existsSync(absolutePath)) {
|
|
59
|
-
throw new Error(`Actions file not found: ${absolutePath}`);
|
|
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
|
-
}
|
|
123
|
-
const fileUrl = pathToFileURL(absolutePath).href;
|
|
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;
|
|
142
|
-
const module = await import(fileUrl);
|
|
143
|
-
const actions = resolveActions2(module);
|
|
144
|
-
const agentGuidance = module.agentGuidance || module.default?.agentGuidance;
|
|
145
|
-
if (!actions || typeof actions !== "object") {
|
|
146
|
-
throw new Error(
|
|
147
|
-
'Actions file must export an actions object as default or named export "actions"'
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
return { actions, agentGuidance };
|
|
151
|
-
} catch (error) {
|
|
152
|
-
throw error;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
function buildManifest(actions, platform, version, gitSha, agentGuidance) {
|
|
156
|
-
const entries = [];
|
|
157
|
-
for (const [name, definition] of Object.entries(actions)) {
|
|
158
|
-
const entry = {
|
|
159
|
-
name,
|
|
160
|
-
description: definition.description,
|
|
161
|
-
type: definition.type
|
|
162
|
-
};
|
|
163
|
-
if (definition.examples?.length)
|
|
164
|
-
entry.examples = definition.examples;
|
|
165
|
-
if (definition.path)
|
|
166
|
-
entry.path = definition.path;
|
|
167
|
-
if (definition.externalUrl)
|
|
168
|
-
entry.external_url = definition.externalUrl;
|
|
169
|
-
if (definition.autoRun)
|
|
170
|
-
entry.auto_run = definition.autoRun;
|
|
171
|
-
if (definition.autoComplete)
|
|
172
|
-
entry.auto_complete = definition.autoComplete;
|
|
173
|
-
if (definition.returns !== void 0) {
|
|
174
|
-
entry.returns_data = definition.returns;
|
|
175
|
-
} else if (definition.type === "query") {
|
|
176
|
-
entry.returns_data = true;
|
|
177
|
-
}
|
|
178
|
-
if (definition.dataSchema)
|
|
179
|
-
entry.data_schema = definition.dataSchema;
|
|
180
|
-
if (definition.defaultData)
|
|
181
|
-
entry.default_data = definition.defaultData;
|
|
182
|
-
if (definition.requiredContext)
|
|
183
|
-
entry.required_context = definition.requiredContext;
|
|
184
|
-
if (definition.parameterExamples?.length)
|
|
185
|
-
entry.parameter_examples = definition.parameterExamples;
|
|
186
|
-
entries.push(entry);
|
|
187
|
-
}
|
|
188
|
-
const manifest = {
|
|
189
|
-
platform,
|
|
190
|
-
version,
|
|
191
|
-
gitSha,
|
|
192
|
-
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
193
|
-
actions: entries
|
|
194
|
-
};
|
|
195
|
-
if (agentGuidance) {
|
|
196
|
-
manifest.agentGuidance = agentGuidance;
|
|
197
|
-
}
|
|
198
|
-
return manifest;
|
|
199
|
-
}
|
|
200
57
|
async function pollStatus(statusUrl, secret, maxWaitSeconds = 300) {
|
|
201
58
|
const startTime = Date.now();
|
|
202
59
|
let lastProgress = { processed: 0, total: 0 };
|
|
@@ -262,15 +119,244 @@ function getGitSha() {
|
|
|
262
119
|
return void 0;
|
|
263
120
|
}
|
|
264
121
|
}
|
|
122
|
+
function globFiles(dir, extensions) {
|
|
123
|
+
const results = [];
|
|
124
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
125
|
+
for (const entry of entries) {
|
|
126
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".next") {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const fullPath = path.join(dir, entry.name);
|
|
130
|
+
if (entry.isDirectory()) {
|
|
131
|
+
results.push(...globFiles(fullPath, extensions));
|
|
132
|
+
} else if (extensions.some((ext) => entry.name.endsWith(ext))) {
|
|
133
|
+
results.push(fullPath);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return results;
|
|
137
|
+
}
|
|
138
|
+
function evaluateNode(node, ts) {
|
|
139
|
+
const n = node;
|
|
140
|
+
if (ts.isStringLiteral(n)) {
|
|
141
|
+
return n.text;
|
|
142
|
+
}
|
|
143
|
+
if (ts.isNoSubstitutionTemplateLiteral(n)) {
|
|
144
|
+
return n.text;
|
|
145
|
+
}
|
|
146
|
+
if (ts.isNumericLiteral(n)) {
|
|
147
|
+
return Number(n.text);
|
|
148
|
+
}
|
|
149
|
+
if (n.kind === ts.SyntaxKind.TrueKeyword)
|
|
150
|
+
return true;
|
|
151
|
+
if (n.kind === ts.SyntaxKind.FalseKeyword)
|
|
152
|
+
return false;
|
|
153
|
+
if (n.kind === ts.SyntaxKind.NullKeyword)
|
|
154
|
+
return null;
|
|
155
|
+
if (ts.isPrefixUnaryExpression(n)) {
|
|
156
|
+
const expr = n;
|
|
157
|
+
if (expr.operator === ts.SyntaxKind.MinusToken) {
|
|
158
|
+
const operand = evaluateNode(expr.operand, ts);
|
|
159
|
+
if (typeof operand === "number")
|
|
160
|
+
return -operand;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (ts.isArrayLiteralExpression(n)) {
|
|
164
|
+
const arr = n;
|
|
165
|
+
const result = [];
|
|
166
|
+
for (const elem of arr.elements) {
|
|
167
|
+
const val = evaluateNode(elem, ts);
|
|
168
|
+
if (val === void 0)
|
|
169
|
+
return void 0;
|
|
170
|
+
result.push(val);
|
|
171
|
+
}
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
if (ts.isObjectLiteralExpression(n)) {
|
|
175
|
+
const obj = n;
|
|
176
|
+
const result = {};
|
|
177
|
+
for (const prop of obj.properties) {
|
|
178
|
+
if (ts.isPropertyAssignment(prop)) {
|
|
179
|
+
const key = prop.name ? ts.isIdentifier(prop.name) ? prop.name.text : ts.isStringLiteral(prop.name) ? prop.name.text : void 0 : void 0;
|
|
180
|
+
if (!key)
|
|
181
|
+
continue;
|
|
182
|
+
const val = evaluateNode(prop.initializer, ts);
|
|
183
|
+
if (val !== void 0) {
|
|
184
|
+
result[key] = val;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (ts.isShorthandPropertyAssignment(prop)) {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
if (ts.isAsExpression(n)) {
|
|
194
|
+
return evaluateNode(n.expression, ts);
|
|
195
|
+
}
|
|
196
|
+
if (ts.isParenthesizedExpression(n)) {
|
|
197
|
+
return evaluateNode(n.expression, ts);
|
|
198
|
+
}
|
|
199
|
+
if (ts.isBinaryExpression(n)) {
|
|
200
|
+
const bin = n;
|
|
201
|
+
if (bin.operatorToken.kind === ts.SyntaxKind.PlusToken) {
|
|
202
|
+
const left = evaluateNode(bin.left, ts);
|
|
203
|
+
const right = evaluateNode(bin.right, ts);
|
|
204
|
+
if (typeof left === "string" && typeof right === "string") {
|
|
205
|
+
return left + right;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return void 0;
|
|
210
|
+
}
|
|
211
|
+
async function scanTools(scanDir) {
|
|
212
|
+
const absoluteDir = path.resolve(process.cwd(), scanDir);
|
|
213
|
+
if (!fs.existsSync(absoluteDir)) {
|
|
214
|
+
throw new Error(`Scan directory not found: ${absoluteDir}`);
|
|
215
|
+
}
|
|
216
|
+
let ts;
|
|
217
|
+
try {
|
|
218
|
+
ts = await import("typescript");
|
|
219
|
+
} catch {
|
|
220
|
+
try {
|
|
221
|
+
const { createRequire } = await import("module");
|
|
222
|
+
const require2 = createRequire(path.join(process.cwd(), "node_modules", "_placeholder.js"));
|
|
223
|
+
ts = require2("typescript");
|
|
224
|
+
} catch {
|
|
225
|
+
console.error("[pillar-sync] TypeScript is required for --scan mode.");
|
|
226
|
+
console.error("[pillar-sync] Install it: npm install -D typescript");
|
|
227
|
+
process.exit(1);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const files = globFiles(absoluteDir, [".ts", ".tsx", ".js", ".jsx", ".mjs"]);
|
|
231
|
+
console.log(`[pillar-sync] Scanning ${files.length} files in ${scanDir}`);
|
|
232
|
+
const PATTERNS = ["defineTool", "usePillarTool", "defineAction", "usePillarAction"];
|
|
233
|
+
const candidateFiles = files.filter((file) => {
|
|
234
|
+
const content = fs.readFileSync(file, "utf-8");
|
|
235
|
+
return PATTERNS.some((p) => content.includes(p));
|
|
236
|
+
});
|
|
237
|
+
console.log(`[pillar-sync] Found ${candidateFiles.length} files with tool definitions`);
|
|
238
|
+
const tools = [];
|
|
239
|
+
for (const filePath of candidateFiles) {
|
|
240
|
+
let visit2 = function(node) {
|
|
241
|
+
if (ts.isCallExpression(node)) {
|
|
242
|
+
const callee = node.expression;
|
|
243
|
+
let isTargetCall = false;
|
|
244
|
+
if (ts.isIdentifier(callee)) {
|
|
245
|
+
isTargetCall = PATTERNS.includes(callee.text);
|
|
246
|
+
} else if (ts.isPropertyAccessExpression(callee)) {
|
|
247
|
+
isTargetCall = callee.name.text === "defineTool" || callee.name.text === "defineAction";
|
|
248
|
+
}
|
|
249
|
+
if (isTargetCall && node.arguments.length > 0) {
|
|
250
|
+
const arg = node.arguments[0];
|
|
251
|
+
const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
|
|
252
|
+
const relativePath = path.relative(process.cwd(), filePath);
|
|
253
|
+
const processToolObject = (obj, line) => {
|
|
254
|
+
if (obj && typeof obj.name === "string" && typeof obj.description === "string") {
|
|
255
|
+
let toolType = obj.type;
|
|
256
|
+
if (toolType === "trigger_action") {
|
|
257
|
+
toolType = "trigger_tool";
|
|
258
|
+
}
|
|
259
|
+
tools.push({
|
|
260
|
+
name: obj.name,
|
|
261
|
+
description: obj.description,
|
|
262
|
+
type: toolType,
|
|
263
|
+
inputSchema: obj.inputSchema,
|
|
264
|
+
examples: obj.examples,
|
|
265
|
+
autoRun: obj.autoRun,
|
|
266
|
+
autoComplete: obj.autoComplete,
|
|
267
|
+
sourceFile: relativePath,
|
|
268
|
+
line
|
|
269
|
+
});
|
|
270
|
+
console.log(`[pillar-sync] ${obj.name} (${relativePath}:${line})`);
|
|
271
|
+
} else if (obj) {
|
|
272
|
+
console.warn(
|
|
273
|
+
`[pillar-sync] \u26A0 Skipping tool at ${relativePath}:${line} \u2014 missing name or description`
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
if (ts.isObjectLiteralExpression(arg)) {
|
|
278
|
+
const obj = evaluateNode(arg, ts);
|
|
279
|
+
processToolObject(obj, lineNumber);
|
|
280
|
+
} else if (ts.isArrayLiteralExpression(arg)) {
|
|
281
|
+
for (const element of arg.elements) {
|
|
282
|
+
if (ts.isObjectLiteralExpression(element)) {
|
|
283
|
+
const elementLine = sourceFile.getLineAndCharacterOfPosition(element.getStart()).line + 1;
|
|
284
|
+
const obj = evaluateNode(element, ts);
|
|
285
|
+
processToolObject(obj, elementLine);
|
|
286
|
+
} else {
|
|
287
|
+
const elementLine = sourceFile.getLineAndCharacterOfPosition(element.getStart()).line + 1;
|
|
288
|
+
console.warn(
|
|
289
|
+
`[pillar-sync] \u26A0 Skipping tool at ${relativePath}:${elementLine} \u2014 array element is not an inline object literal`
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
} else {
|
|
294
|
+
console.warn(
|
|
295
|
+
`[pillar-sync] \u26A0 Skipping tool at ${relativePath}:${lineNumber} \u2014 argument is not an inline object literal or array (variable reference can't be resolved statically)`
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
ts.forEachChild(node, visit2);
|
|
301
|
+
};
|
|
302
|
+
var visit = visit2;
|
|
303
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
304
|
+
const sourceFile = ts.createSourceFile(
|
|
305
|
+
filePath,
|
|
306
|
+
content,
|
|
307
|
+
ts.ScriptTarget.Latest,
|
|
308
|
+
true,
|
|
309
|
+
// setParentNodes
|
|
310
|
+
filePath.endsWith(".tsx") ? ts.ScriptKind.TSX : filePath.endsWith(".jsx") ? ts.ScriptKind.JSX : /\.m?js$/.test(filePath) ? ts.ScriptKind.JS : ts.ScriptKind.TS
|
|
311
|
+
);
|
|
312
|
+
visit2(sourceFile);
|
|
313
|
+
}
|
|
314
|
+
return tools;
|
|
315
|
+
}
|
|
316
|
+
function normalizeTypeForBackend(type) {
|
|
317
|
+
if (type === "trigger_tool") {
|
|
318
|
+
return "trigger_action";
|
|
319
|
+
}
|
|
320
|
+
return type || "trigger_action";
|
|
321
|
+
}
|
|
322
|
+
function buildManifestFromScan(tools, platform, version, gitSha) {
|
|
323
|
+
const entries = [];
|
|
324
|
+
for (const tool of tools) {
|
|
325
|
+
const entry = {
|
|
326
|
+
name: tool.name,
|
|
327
|
+
description: tool.description,
|
|
328
|
+
// Normalize trigger_tool → trigger_action for backend API compatibility
|
|
329
|
+
type: normalizeTypeForBackend(tool.type)
|
|
330
|
+
};
|
|
331
|
+
if (tool.examples?.length)
|
|
332
|
+
entry.examples = tool.examples;
|
|
333
|
+
if (tool.autoRun)
|
|
334
|
+
entry.auto_run = tool.autoRun;
|
|
335
|
+
if (tool.autoComplete !== void 0)
|
|
336
|
+
entry.auto_complete = tool.autoComplete;
|
|
337
|
+
entry.returns_data = true;
|
|
338
|
+
if (tool.inputSchema)
|
|
339
|
+
entry.data_schema = tool.inputSchema;
|
|
340
|
+
entries.push(entry);
|
|
341
|
+
}
|
|
342
|
+
return {
|
|
343
|
+
platform,
|
|
344
|
+
version,
|
|
345
|
+
gitSha,
|
|
346
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
347
|
+
actions: entries
|
|
348
|
+
// Keep 'actions' key for backend API compatibility
|
|
349
|
+
};
|
|
350
|
+
}
|
|
265
351
|
async function main() {
|
|
266
352
|
const args = parseArgs(process.argv.slice(2));
|
|
267
353
|
if (args.help) {
|
|
268
354
|
printUsage();
|
|
269
355
|
process.exit(0);
|
|
270
356
|
}
|
|
271
|
-
const
|
|
272
|
-
if (!
|
|
273
|
-
console.error("[pillar-sync] Missing required --
|
|
357
|
+
const scanDir = args.scan;
|
|
358
|
+
if (!scanDir) {
|
|
359
|
+
console.error("[pillar-sync] Missing required argument: --scan <dir>");
|
|
274
360
|
console.error("");
|
|
275
361
|
printUsage();
|
|
276
362
|
process.exit(1);
|
|
@@ -292,31 +378,27 @@ async function main() {
|
|
|
292
378
|
console.error("Get these from the Pillar admin: Actions \u2192 Configure Sync");
|
|
293
379
|
process.exit(1);
|
|
294
380
|
}
|
|
295
|
-
|
|
296
|
-
|
|
381
|
+
const platform = process.env.PILLAR_PLATFORM || "web";
|
|
382
|
+
const version = process.env.PILLAR_VERSION || getPackageVersion();
|
|
383
|
+
const gitSha = process.env.GIT_SHA || getGitSha();
|
|
384
|
+
console.log(`[pillar-sync] Scanning for tools in: ${scanDir}`);
|
|
385
|
+
let scannedTools;
|
|
297
386
|
try {
|
|
298
|
-
|
|
387
|
+
scannedTools = await scanTools(scanDir);
|
|
299
388
|
} catch (error) {
|
|
300
|
-
console.error(`[pillar-sync] Failed to
|
|
389
|
+
console.error(`[pillar-sync] Failed to scan tools:`, error);
|
|
301
390
|
process.exit(1);
|
|
302
391
|
}
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
console.log(`[pillar-sync] Found agent guidance (${agentGuidance.length} chars)`);
|
|
308
|
-
}
|
|
309
|
-
if (actionCount === 0) {
|
|
310
|
-
console.warn("[pillar-sync] No actions found. Nothing to sync.");
|
|
392
|
+
const toolCount = scannedTools.length;
|
|
393
|
+
console.log(`[pillar-sync] Found ${toolCount} tools`);
|
|
394
|
+
if (toolCount === 0) {
|
|
395
|
+
console.warn("[pillar-sync] No tools found. Nothing to sync.");
|
|
311
396
|
process.exit(0);
|
|
312
397
|
}
|
|
313
|
-
const
|
|
314
|
-
const version = process.env.PILLAR_VERSION || getPackageVersion();
|
|
315
|
-
const gitSha = process.env.GIT_SHA || getGitSha();
|
|
398
|
+
const manifest = buildManifestFromScan(scannedTools, platform, version, gitSha);
|
|
316
399
|
console.log(`[pillar-sync] Platform: ${platform}`);
|
|
317
400
|
console.log(`[pillar-sync] Version: ${version}`);
|
|
318
401
|
console.log(`[pillar-sync] Git SHA: ${gitSha || "not available"}`);
|
|
319
|
-
const manifest = buildManifest(actions, platform, version, gitSha, agentGuidance);
|
|
320
402
|
if (process.env.PILLAR_DEBUG) {
|
|
321
403
|
const manifestPath = path.join(process.cwd(), "actions-manifest.json");
|
|
322
404
|
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
@@ -329,9 +411,6 @@ async function main() {
|
|
|
329
411
|
git_sha: gitSha,
|
|
330
412
|
actions: manifest.actions
|
|
331
413
|
};
|
|
332
|
-
if (agentGuidance) {
|
|
333
|
-
requestBody.agent_guidance = agentGuidance;
|
|
334
|
-
}
|
|
335
414
|
const syncUrl = `${apiUrl}/api/admin/configs/${slug}/actions/sync/?async=true`;
|
|
336
415
|
console.log(`[pillar-sync] POST ${syncUrl}`);
|
|
337
416
|
try {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Floating Help Button Component
|
|
3
|
+
* A floating action button that opens the help panel
|
|
4
|
+
*/
|
|
5
|
+
import type { ResolvedConfig, FloatingButtonPosition } from '../../core/config';
|
|
6
|
+
/**
|
|
7
|
+
* FloatingButton class that manages the button lifecycle
|
|
8
|
+
* Uses Preact for rendering but maintains imperative control
|
|
9
|
+
*/
|
|
10
|
+
export declare class FloatingButton {
|
|
11
|
+
private config;
|
|
12
|
+
private onClick;
|
|
13
|
+
private container;
|
|
14
|
+
private stylesInjected;
|
|
15
|
+
private _isHidden;
|
|
16
|
+
constructor(config: ResolvedConfig, onClick: () => void);
|
|
17
|
+
/**
|
|
18
|
+
* Initialize the floating button
|
|
19
|
+
*/
|
|
20
|
+
init(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Set the open state (to update icon when panel opens)
|
|
23
|
+
*/
|
|
24
|
+
setOpen(_isOpen: boolean): void;
|
|
25
|
+
/**
|
|
26
|
+
* Show the button
|
|
27
|
+
*/
|
|
28
|
+
show(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Hide the button
|
|
31
|
+
*/
|
|
32
|
+
hide(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Update button position
|
|
35
|
+
*/
|
|
36
|
+
setPosition(position: FloatingButtonPosition): void;
|
|
37
|
+
/**
|
|
38
|
+
* Update button label
|
|
39
|
+
*/
|
|
40
|
+
setLabel(label: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* Destroy the button
|
|
43
|
+
*/
|
|
44
|
+
destroy(): void;
|
|
45
|
+
private render;
|
|
46
|
+
}
|
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* Injected into the document head (outside Shadow DOM)
|
|
4
4
|
* Uses the same CSS variables as the Pillar panel for consistent theming
|
|
5
5
|
*/
|
|
6
|
-
export declare const PAGE_PILOT_STYLES = "\n/* Pillar Page Pilot Banner Styles */\n\n/* Define CSS variables at the container level (same as panel) */\n#pillar-page-pilot-container {\n /* Core colors - Light mode (default) */\n --pillar-primary: #2563eb;\n --pillar-primary-hover: #1d4ed8;\n --pillar-bg: #ffffff;\n --pillar-bg-secondary: #f9fafb;\n --pillar-text: #1a1a1a;\n --pillar-text-secondary: #374151;\n --pillar-border: #e5e7eb;\n --pillar-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n --pillar-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n --pillar-radius-lg: 8px;\n --pillar-radius-md: 6px;\n --pillar-transition-fast: 0.15s ease;\n}\n\n/* Dark mode - Auto-detect from system preference */\n@media (prefers-color-scheme: dark) {\n #pillar-page-pilot-container:not([data-theme=\"light\"]) {\n --pillar-primary: #3b82f6;\n --pillar-primary-hover: #60a5fa;\n --pillar-bg: #1a1a1a;\n --pillar-bg-secondary: #262626;\n --pillar-text: #f5f5f5;\n --pillar-text-secondary: #e5e5e5;\n --pillar-border: #404040;\n --pillar-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);\n }\n}\n\n/* Dark mode - Manual override via html class or data attribute */\nhtml.dark #pillar-page-pilot-container,\n[data-theme=\"dark\"] #pillar-page-pilot-container,\n#pillar-page-pilot-container[data-theme=\"dark\"] {\n --pillar-primary: #3b82f6;\n --pillar-primary-hover: #60a5fa;\n --pillar-bg: #1a1a1a;\n --pillar-bg-secondary: #262626;\n --pillar-text: #f5f5f5;\n --pillar-text-secondary: #e5e5e5;\n --pillar-border: #404040;\n --pillar-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);\n}\n\n@keyframes pillar-pulse {\n 0%, 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.6;\n transform: scale(1.1);\n }\n}\n\n@keyframes pillar-banner-fade-in {\n from {\n opacity: 0;\n transform: translateY(-100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n._pillar-page-pilot-banner {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n z-index: 99999;\n font-family: var(--pillar-font-family);\n display: flex;\n justify-content: center;\n pointer-events: none;\n animation: pillar-banner-fade-in 0.2s ease-out;\n}\n\n/* Viewport outline \u2014 3px border on left, right, bottom; top handled by tab shape */\n._pillar-page-pilot-banner::before {\n content: '';\n position: fixed;\n inset: 0;\n border: 3px solid var(--pillar-primary);\n border-top: none;\n pointer-events: none;\n z-index: 99998;\n}\n\n/* Top border segments on either side of the tab */\n._pillar-page-pilot-banner::after {\n content: '';\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--pillar-primary);\n pointer-events: none;\n z-index: 99997;\n}\n\n._pillar-page-pilot-banner__content {\n position: relative;\n z-index: 99999;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 20px;\n background: var(--pillar-primary);\n color: #ffffff;\n border-bottom-left-radius: var(--pillar-radius-lg);\n border-bottom-right-radius: var(--pillar-radius-lg);\n pointer-events: auto;\n}\n\n._pillar-page-pilot-banner__indicator {\n width: 8px;\n height: 8px;\n background: #ffffff;\n border-radius: 50%;\n animation: pillar-pulse 1.5s ease-in-out infinite;\n flex-shrink: 0;\n}\n\n._pillar-page-pilot-banner__text {\n font-size: 13px;\n font-weight: 500;\n color: #ffffff;\n white-space: nowrap;\n}\n\n._pillar-page-pilot-banner__stop {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 5px 10px;\n margin-left: 4px;\n font-family: inherit;\n font-size: 12px;\n font-weight: 500;\n color: #ffffff;\n background: rgba(255, 255, 255, 0.15);\n border: 1px solid rgba(255, 255, 255, 0.3);\n border-radius: var(--pillar-radius-md);\n cursor: pointer;\n transition: all var(--pillar-transition-fast);\n}\n\n._pillar-page-pilot-banner__stop:hover {\n background: rgba(255, 255, 255, 0.25);\n border-color: rgba(255, 255, 255, 0.5);\n}\n\n._pillar-page-pilot-banner__stop:active {\n transform: scale(0.97);\n}\n\n._pillar-page-pilot-banner__stop-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n}\n\n._pillar-page-pilot-banner__stop-icon svg {\n width: 100%;\n height: 100%;\n}\n
|
|
6
|
+
export declare const PAGE_PILOT_STYLES = "\n/* Pillar Page Pilot Banner Styles */\n\n/* Define CSS variables at the container level (same as panel) */\n#pillar-page-pilot-container {\n /* Core colors - Light mode (default) */\n --pillar-primary: #2563eb;\n --pillar-primary-hover: #1d4ed8;\n --pillar-bg: #ffffff;\n --pillar-bg-secondary: #f9fafb;\n --pillar-text: #1a1a1a;\n --pillar-text-secondary: #374151;\n --pillar-border: #e5e7eb;\n --pillar-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n --pillar-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n --pillar-radius-lg: 8px;\n --pillar-radius-md: 6px;\n --pillar-transition-fast: 0.15s ease;\n}\n\n/* Dark mode - Auto-detect from system preference */\n@media (prefers-color-scheme: dark) {\n #pillar-page-pilot-container:not([data-theme=\"light\"]) {\n --pillar-primary: #3b82f6;\n --pillar-primary-hover: #60a5fa;\n --pillar-bg: #1a1a1a;\n --pillar-bg-secondary: #262626;\n --pillar-text: #f5f5f5;\n --pillar-text-secondary: #e5e5e5;\n --pillar-border: #404040;\n --pillar-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);\n }\n}\n\n/* Dark mode - Manual override via html class or data attribute */\nhtml.dark #pillar-page-pilot-container,\n[data-theme=\"dark\"] #pillar-page-pilot-container,\n#pillar-page-pilot-container[data-theme=\"dark\"] {\n --pillar-primary: #3b82f6;\n --pillar-primary-hover: #60a5fa;\n --pillar-bg: #1a1a1a;\n --pillar-bg-secondary: #262626;\n --pillar-text: #f5f5f5;\n --pillar-text-secondary: #e5e5e5;\n --pillar-border: #404040;\n --pillar-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);\n}\n\n@keyframes pillar-pulse {\n 0%, 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.6;\n transform: scale(1.1);\n }\n}\n\n@keyframes pillar-banner-fade-in {\n from {\n opacity: 0;\n transform: translateY(-100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n._pillar-page-pilot-banner {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n z-index: 99999;\n font-family: var(--pillar-font-family);\n display: flex;\n justify-content: center;\n pointer-events: none;\n animation: pillar-banner-fade-in 0.2s ease-out;\n}\n\n/* Viewport outline \u2014 3px border on left, right, bottom; top handled by tab shape */\n._pillar-page-pilot-banner::before {\n content: '';\n position: fixed;\n inset: 0;\n border: 3px solid var(--pillar-primary);\n border-top: none;\n pointer-events: none;\n z-index: 99998;\n}\n\n/* Top border segments on either side of the tab */\n._pillar-page-pilot-banner::after {\n content: '';\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: var(--pillar-primary);\n pointer-events: none;\n z-index: 99997;\n}\n\n._pillar-page-pilot-banner__content {\n position: relative;\n z-index: 99999;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 20px;\n background: var(--pillar-primary);\n color: #ffffff;\n border-bottom-left-radius: var(--pillar-radius-lg);\n border-bottom-right-radius: var(--pillar-radius-lg);\n pointer-events: auto;\n}\n\n._pillar-page-pilot-banner__indicator {\n width: 8px;\n height: 8px;\n background: #ffffff;\n border-radius: 50%;\n animation: pillar-pulse 1.5s ease-in-out infinite;\n flex-shrink: 0;\n}\n\n._pillar-page-pilot-banner__text {\n font-size: 13px;\n font-weight: 500;\n color: #ffffff;\n white-space: nowrap;\n}\n\n._pillar-page-pilot-banner__stop {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 5px 10px;\n margin-left: 4px;\n font-family: inherit;\n font-size: 12px;\n font-weight: 500;\n color: #ffffff;\n background: rgba(255, 255, 255, 0.15);\n border: 1px solid rgba(255, 255, 255, 0.3);\n border-radius: var(--pillar-radius-md);\n cursor: pointer;\n transition: all var(--pillar-transition-fast);\n}\n\n._pillar-page-pilot-banner__stop:hover {\n background: rgba(255, 255, 255, 0.25);\n border-color: rgba(255, 255, 255, 0.5);\n}\n\n._pillar-page-pilot-banner__stop:active {\n transform: scale(0.97);\n}\n\n._pillar-page-pilot-banner__stop-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n}\n\n._pillar-page-pilot-banner__stop-icon svg {\n width: 100%;\n height: 100%;\n}\n";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tab Navigation Component
|
|
3
|
+
* Vertical tabs on the right edge of the panel for switching between Assistant and Support
|
|
4
|
+
*/
|
|
5
|
+
import { h } from 'preact';
|
|
6
|
+
import type { ResolvedSupportConfig } from '../../core/config';
|
|
7
|
+
interface TabNavigationProps {
|
|
8
|
+
supportConfig: ResolvedSupportConfig;
|
|
9
|
+
}
|
|
10
|
+
export declare function TabNavigation({ supportConfig }: TabNavigationProps): h.JSX.Element;
|
|
11
|
+
/**
|
|
12
|
+
* CSS Styles for Tab Navigation
|
|
13
|
+
* Should be appended to PANEL_STYLES
|
|
14
|
+
*/
|
|
15
|
+
export declare const TAB_NAVIGATION_STYLES = "\n/* ============================================================================\n Panel Wrapper (for tab layout)\n Horizontal flex container with main content + tab nav\n ============================================================================ */\n\n._pillar-panel-wrapper {\n display: flex;\n flex-direction: row;\n height: 100%;\n overflow: hidden;\n}\n\n._pillar-panel-wrapper > ._pillar-panel-ui {\n flex: 1;\n min-width: 0;\n}\n\n.pillar-panel-wrapper {}\n\n/* ============================================================================\n Tab Navigation\n Vertical tabs on the right edge of the panel\n ============================================================================ */\n\n._pillar-tab-nav {\n display: flex;\n flex-direction: column;\n width: 48px;\n min-width: 48px;\n background: var(--pillar-bg-secondary);\n border-left: 1px solid var(--pillar-border);\n padding: var(--pillar-spacing-sm) 0;\n gap: var(--pillar-spacing-xs);\n}\n\n._pillar-tab {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 2px;\n padding: var(--pillar-spacing-sm) var(--pillar-spacing-xs);\n margin: 0 var(--pillar-spacing-xs);\n border: none;\n border-radius: var(--pillar-radius-md);\n background: transparent;\n color: var(--pillar-text-muted);\n cursor: pointer;\n transition: all var(--pillar-transition-fast);\n position: relative;\n}\n\n._pillar-tab:hover {\n background: var(--pillar-bg-tertiary);\n color: var(--pillar-text);\n}\n\n._pillar-tab--active {\n background: var(--pillar-primary-light);\n color: var(--pillar-primary);\n}\n\n._pillar-tab--active:hover {\n background: var(--pillar-primary-light-hover);\n color: var(--pillar-primary);\n}\n\n._pillar-tab-icon {\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n._pillar-tab-icon svg {\n width: 100%;\n height: 100%;\n}\n\n._pillar-tab-label {\n font-size: 9px;\n font-weight: 500;\n text-align: center;\n line-height: 1.2;\n max-width: 40px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Public override classes */\n.pillar-tab-nav {}\n.pillar-tab {}\n.pillar-tab-icon {}\n.pillar-tab-label {}\n";
|
|
16
|
+
export {};
|