@t3lnet/sceneforge 1.0.9 → 1.0.10
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 +57 -0
- package/cli/cli.js +6 -0
- package/cli/commands/context.js +791 -0
- package/context/context-builder.ts +318 -0
- package/context/index.ts +52 -0
- package/context/template-loader.ts +161 -0
- package/context/templates/base/actions-reference.md +299 -0
- package/context/templates/base/cli-reference.md +236 -0
- package/context/templates/base/project-overview.md +58 -0
- package/context/templates/base/selectors-guide.md +233 -0
- package/context/templates/base/yaml-schema.md +210 -0
- package/context/templates/skills/balance-timing.md +136 -0
- package/context/templates/skills/debug-selector.md +193 -0
- package/context/templates/skills/generate-actions.md +94 -0
- package/context/templates/skills/optimize-demo.md +218 -0
- package/context/templates/skills/review-demo-yaml.md +164 -0
- package/context/templates/skills/write-step-script.md +136 -0
- package/context/templates/stages/stage1-actions.md +236 -0
- package/context/templates/stages/stage2-scripts.md +197 -0
- package/context/templates/stages/stage3-balancing.md +229 -0
- package/context/templates/stages/stage4-rebalancing.md +228 -0
- package/context/tests/context-builder.test.ts +237 -0
- package/context/tests/template-loader.test.ts +181 -0
- package/context/tests/tool-formatter.test.ts +198 -0
- package/context/tool-formatter.ts +189 -0
- package/dist/index.cjs +416 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +182 -1
- package/dist/index.d.ts +182 -1
- package/dist/index.js +391 -11
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -34,7 +34,10 @@ var index_exports = {};
|
|
|
34
34
|
__export(index_exports, {
|
|
35
35
|
DEMO_SCHEMA_VERSION: () => DEMO_SCHEMA_VERSION,
|
|
36
36
|
ScriptGenerator: () => ScriptGenerator,
|
|
37
|
+
TOOL_CONFIGS: () => TOOL_CONFIGS,
|
|
37
38
|
VoiceSynthesizer: () => VoiceSynthesizer,
|
|
39
|
+
buildContext: () => buildContext,
|
|
40
|
+
composeTemplates: () => composeTemplates,
|
|
38
41
|
createClickAction: () => createClickAction,
|
|
39
42
|
createDragAction: () => createDragAction,
|
|
40
43
|
createEmptyDemo: () => createEmptyDemo,
|
|
@@ -53,15 +56,35 @@ __export(index_exports, {
|
|
|
53
56
|
demoDefinitionSchema: () => demoDefinitionSchema,
|
|
54
57
|
demoHover: () => demoHover,
|
|
55
58
|
demoType: () => demoType,
|
|
59
|
+
deployContext: () => deployContext,
|
|
56
60
|
discoverDemos: () => discoverDemos,
|
|
61
|
+
formatForTool: () => formatForTool,
|
|
62
|
+
formatStageName: () => formatStageName,
|
|
57
63
|
formatValidationError: () => formatValidationError,
|
|
58
64
|
generateTimingManifest: () => generateTimingManifest,
|
|
65
|
+
getOutputPath: () => getOutputPath,
|
|
66
|
+
getSkill: () => getSkill,
|
|
67
|
+
getSplitOutputPaths: () => getSplitOutputPaths,
|
|
68
|
+
getStageFileName: () => getStageFileName,
|
|
69
|
+
getSupportedTools: () => getSupportedTools,
|
|
70
|
+
getToolConfig: () => getToolConfig,
|
|
71
|
+
hasTemplates: () => hasTemplates,
|
|
59
72
|
highlightElement: () => highlightElement,
|
|
60
73
|
injectCursorOverlay: () => injectCursorOverlay,
|
|
74
|
+
interpolateVariables: () => interpolateVariables,
|
|
75
|
+
isValidFormat: () => isValidFormat,
|
|
76
|
+
isValidTool: () => isValidTool,
|
|
77
|
+
listDeployedContext: () => listDeployedContext,
|
|
78
|
+
listSkills: () => listSkills,
|
|
79
|
+
listTemplates: () => listTemplates,
|
|
61
80
|
loadDemoDefinition: () => loadDemoDefinition,
|
|
81
|
+
loadTemplate: () => loadTemplate,
|
|
82
|
+
loadTemplatesByCategory: () => loadTemplatesByCategory,
|
|
62
83
|
moveCursorTo: () => moveCursorTo,
|
|
63
84
|
parseDemoDefinition: () => parseDemoDefinition,
|
|
64
85
|
parseFromYAML: () => parseFromYAML,
|
|
86
|
+
previewContext: () => previewContext,
|
|
87
|
+
removeContext: () => removeContext,
|
|
65
88
|
removeCursorOverlay: () => removeCursorOverlay,
|
|
66
89
|
resolvePath: () => resolvePath,
|
|
67
90
|
resolveTarget: () => resolveTarget,
|
|
@@ -69,6 +92,7 @@ __export(index_exports, {
|
|
|
69
92
|
runDemoFromFile: () => runDemoFromFile,
|
|
70
93
|
safeParseDemoDefinition: () => safeParseDemoDefinition,
|
|
71
94
|
serializeToYAML: () => serializeToYAML,
|
|
95
|
+
templateExists: () => templateExists,
|
|
72
96
|
triggerClickRipple: () => triggerClickRipple,
|
|
73
97
|
validateDemoDefinition: () => validateDemoDefinition
|
|
74
98
|
});
|
|
@@ -252,8 +276,8 @@ function formatValidationError(error) {
|
|
|
252
276
|
}
|
|
253
277
|
const issues = error.issues;
|
|
254
278
|
return issues.map((issue) => {
|
|
255
|
-
const
|
|
256
|
-
return `${
|
|
279
|
+
const path7 = issue.path.length ? issue.path.join(".") : "root";
|
|
280
|
+
return `${path7}: ${issue.message}`;
|
|
257
281
|
}).join("; ");
|
|
258
282
|
}
|
|
259
283
|
function parseDemoDefinition(input) {
|
|
@@ -383,7 +407,7 @@ function createEmptyStep(id) {
|
|
|
383
407
|
};
|
|
384
408
|
}
|
|
385
409
|
var SECRET_PATTERN = /\$\{(ENV|SECRET):([A-Za-z0-9_]+)\}/g;
|
|
386
|
-
function resolveSecrets(value, resolver,
|
|
410
|
+
function resolveSecrets(value, resolver, path7 = "root") {
|
|
387
411
|
if (typeof value === "string") {
|
|
388
412
|
if (!SECRET_PATTERN.test(value)) {
|
|
389
413
|
return value;
|
|
@@ -392,20 +416,20 @@ function resolveSecrets(value, resolver, path5 = "root") {
|
|
|
392
416
|
return value.replace(SECRET_PATTERN, (_match, _type, key) => {
|
|
393
417
|
const resolved = resolver(key);
|
|
394
418
|
if (resolved === void 0) {
|
|
395
|
-
throw new Error(`Missing secret for ${key} at ${
|
|
419
|
+
throw new Error(`Missing secret for ${key} at ${path7}`);
|
|
396
420
|
}
|
|
397
421
|
return resolved;
|
|
398
422
|
});
|
|
399
423
|
}
|
|
400
424
|
if (Array.isArray(value)) {
|
|
401
425
|
return value.map(
|
|
402
|
-
(entry, index) => resolveSecrets(entry, resolver, `${
|
|
426
|
+
(entry, index) => resolveSecrets(entry, resolver, `${path7}[${index}]`)
|
|
403
427
|
);
|
|
404
428
|
}
|
|
405
429
|
if (value && typeof value === "object") {
|
|
406
430
|
const result = {};
|
|
407
431
|
for (const [key, entry] of Object.entries(value)) {
|
|
408
|
-
result[key] = resolveSecrets(entry, resolver, `${
|
|
432
|
+
result[key] = resolveSecrets(entry, resolver, `${path7}.${key}`);
|
|
409
433
|
}
|
|
410
434
|
return result;
|
|
411
435
|
}
|
|
@@ -484,10 +508,10 @@ function createTypeAction(selector, text) {
|
|
|
484
508
|
text
|
|
485
509
|
};
|
|
486
510
|
}
|
|
487
|
-
function createNavigateAction(
|
|
511
|
+
function createNavigateAction(path7) {
|
|
488
512
|
return {
|
|
489
513
|
action: "navigate",
|
|
490
|
-
path:
|
|
514
|
+
path: path7
|
|
491
515
|
};
|
|
492
516
|
}
|
|
493
517
|
function createWaitAction(duration) {
|
|
@@ -911,7 +935,7 @@ function runCommand(command, args, options = {}) {
|
|
|
911
935
|
cwd,
|
|
912
936
|
maxOutputBytes = DEFAULT_MAX_OUTPUT_BYTES
|
|
913
937
|
} = options;
|
|
914
|
-
return new Promise((
|
|
938
|
+
return new Promise((resolve3, reject) => {
|
|
915
939
|
const child = (0, import_child_process.spawn)(command, args, { stdio, cwd });
|
|
916
940
|
let stdout = "";
|
|
917
941
|
let stderr = "";
|
|
@@ -930,7 +954,7 @@ function runCommand(command, args, options = {}) {
|
|
|
930
954
|
});
|
|
931
955
|
child.on("close", (code) => {
|
|
932
956
|
if (code === 0) {
|
|
933
|
-
|
|
957
|
+
resolve3({ stdout, stderr });
|
|
934
958
|
return;
|
|
935
959
|
}
|
|
936
960
|
const error = new Error(`${command} exited with code ${code}`);
|
|
@@ -961,7 +985,7 @@ async function probeMediaDurationMs(filePath) {
|
|
|
961
985
|
return null;
|
|
962
986
|
}
|
|
963
987
|
function sleep(ms) {
|
|
964
|
-
return new Promise((
|
|
988
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
965
989
|
}
|
|
966
990
|
function getStatusCode(error) {
|
|
967
991
|
if (!error || typeof error !== "object") return void 0;
|
|
@@ -2457,11 +2481,371 @@ async function discoverDemos(demoDir) {
|
|
|
2457
2481
|
const files = await fs4.readdir(demoDir);
|
|
2458
2482
|
return files.filter((f) => f.endsWith(".yaml") || f.endsWith(".yml")).map((f) => path4.join(demoDir, f));
|
|
2459
2483
|
}
|
|
2484
|
+
|
|
2485
|
+
// context/template-loader.ts
|
|
2486
|
+
var fs5 = __toESM(require("fs/promises"), 1);
|
|
2487
|
+
var path5 = __toESM(require("path"), 1);
|
|
2488
|
+
var import_url = require("url");
|
|
2489
|
+
var import_meta = {};
|
|
2490
|
+
var __filename = (0, import_url.fileURLToPath)(import_meta.url);
|
|
2491
|
+
var __dirname = path5.dirname(__filename);
|
|
2492
|
+
function getTemplatesDir() {
|
|
2493
|
+
return path5.join(__dirname, "templates");
|
|
2494
|
+
}
|
|
2495
|
+
async function loadTemplate(category, name) {
|
|
2496
|
+
const templatesDir = getTemplatesDir();
|
|
2497
|
+
const filePath = path5.join(templatesDir, category, `${name}.md`);
|
|
2498
|
+
try {
|
|
2499
|
+
const content = await fs5.readFile(filePath, "utf-8");
|
|
2500
|
+
return { name, content, category };
|
|
2501
|
+
} catch (error) {
|
|
2502
|
+
throw new Error(`Failed to load template ${category}/${name}: ${error}`);
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
async function loadTemplatesByCategory(category) {
|
|
2506
|
+
const templatesDir = getTemplatesDir();
|
|
2507
|
+
const categoryDir = path5.join(templatesDir, category);
|
|
2508
|
+
try {
|
|
2509
|
+
const files = await fs5.readdir(categoryDir);
|
|
2510
|
+
const templates = [];
|
|
2511
|
+
for (const file of files) {
|
|
2512
|
+
if (file.endsWith(".md")) {
|
|
2513
|
+
const name = file.replace(/\.md$/, "");
|
|
2514
|
+
const template = await loadTemplate(category, name);
|
|
2515
|
+
templates.push(template);
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
return templates;
|
|
2519
|
+
} catch (error) {
|
|
2520
|
+
throw new Error(`Failed to load templates from ${category}: ${error}`);
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2523
|
+
function interpolateVariables(content, variables) {
|
|
2524
|
+
return content.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
|
2525
|
+
const value = variables[key];
|
|
2526
|
+
if (value === void 0) {
|
|
2527
|
+
return match;
|
|
2528
|
+
}
|
|
2529
|
+
return String(value);
|
|
2530
|
+
});
|
|
2531
|
+
}
|
|
2532
|
+
function composeTemplates(templates, options) {
|
|
2533
|
+
const { separator = "\n\n---\n\n", includeHeaders = false } = options ?? {};
|
|
2534
|
+
return templates.map((template) => {
|
|
2535
|
+
if (includeHeaders) {
|
|
2536
|
+
return `<!-- Template: ${template.category}/${template.name} -->
|
|
2537
|
+
|
|
2538
|
+
${template.content}`;
|
|
2539
|
+
}
|
|
2540
|
+
return template.content;
|
|
2541
|
+
}).join(separator);
|
|
2542
|
+
}
|
|
2543
|
+
async function listTemplates() {
|
|
2544
|
+
const templatesDir = getTemplatesDir();
|
|
2545
|
+
const result = {
|
|
2546
|
+
base: [],
|
|
2547
|
+
stages: [],
|
|
2548
|
+
skills: []
|
|
2549
|
+
};
|
|
2550
|
+
for (const category of ["base", "stages", "skills"]) {
|
|
2551
|
+
const categoryDir = path5.join(templatesDir, category);
|
|
2552
|
+
try {
|
|
2553
|
+
const files = await fs5.readdir(categoryDir);
|
|
2554
|
+
result[category] = files.filter((f) => f.endsWith(".md")).map((f) => f.replace(/\.md$/, ""));
|
|
2555
|
+
} catch {
|
|
2556
|
+
result[category] = [];
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
return result;
|
|
2560
|
+
}
|
|
2561
|
+
async function templateExists(category, name) {
|
|
2562
|
+
const templatesDir = getTemplatesDir();
|
|
2563
|
+
const filePath = path5.join(templatesDir, category, `${name}.md`);
|
|
2564
|
+
try {
|
|
2565
|
+
await fs5.access(filePath);
|
|
2566
|
+
return true;
|
|
2567
|
+
} catch {
|
|
2568
|
+
return false;
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
// context/tool-formatter.ts
|
|
2573
|
+
var TOOL_CONFIGS = {
|
|
2574
|
+
cursor: {
|
|
2575
|
+
name: "Cursor",
|
|
2576
|
+
description: "Cursor AI IDE with .cursorrules support",
|
|
2577
|
+
combinedFile: ".cursorrules",
|
|
2578
|
+
splitDir: ".cursor/rules",
|
|
2579
|
+
splitFilePrefix: "",
|
|
2580
|
+
fileExtension: ".md",
|
|
2581
|
+
supportsSkills: true
|
|
2582
|
+
},
|
|
2583
|
+
copilot: {
|
|
2584
|
+
name: "GitHub Copilot",
|
|
2585
|
+
description: "GitHub Copilot with instructions file",
|
|
2586
|
+
combinedFile: ".github/copilot-instructions.md",
|
|
2587
|
+
splitDir: ".github/copilot",
|
|
2588
|
+
splitFilePrefix: "",
|
|
2589
|
+
fileExtension: ".md",
|
|
2590
|
+
supportsSkills: false
|
|
2591
|
+
},
|
|
2592
|
+
claude: {
|
|
2593
|
+
name: "Claude Code",
|
|
2594
|
+
description: "Claude Code CLI with CLAUDE.md support",
|
|
2595
|
+
combinedFile: "CLAUDE.md",
|
|
2596
|
+
splitDir: ".claude/rules",
|
|
2597
|
+
splitFilePrefix: "",
|
|
2598
|
+
fileExtension: ".md",
|
|
2599
|
+
supportsSkills: true
|
|
2600
|
+
},
|
|
2601
|
+
codex: {
|
|
2602
|
+
name: "Codex",
|
|
2603
|
+
description: "OpenAI Codex with AGENTS.md support",
|
|
2604
|
+
combinedFile: "AGENTS.md",
|
|
2605
|
+
splitDir: ".codex",
|
|
2606
|
+
splitFilePrefix: "",
|
|
2607
|
+
fileExtension: ".md",
|
|
2608
|
+
supportsSkills: false
|
|
2609
|
+
}
|
|
2610
|
+
};
|
|
2611
|
+
function getSupportedTools() {
|
|
2612
|
+
return Object.keys(TOOL_CONFIGS);
|
|
2613
|
+
}
|
|
2614
|
+
function getToolConfig(tool) {
|
|
2615
|
+
return TOOL_CONFIGS[tool];
|
|
2616
|
+
}
|
|
2617
|
+
function formatForTool(tool, content, options) {
|
|
2618
|
+
const config = TOOL_CONFIGS[tool];
|
|
2619
|
+
const { stage, includeToolHeader = true } = options ?? {};
|
|
2620
|
+
const lines = [];
|
|
2621
|
+
if (includeToolHeader) {
|
|
2622
|
+
lines.push(`# SceneForge LLM Context`);
|
|
2623
|
+
lines.push(``);
|
|
2624
|
+
lines.push(`> Generated for ${config.name}`);
|
|
2625
|
+
if (stage) {
|
|
2626
|
+
lines.push(`> Stage: ${stage}`);
|
|
2627
|
+
}
|
|
2628
|
+
lines.push(``);
|
|
2629
|
+
lines.push(`---`);
|
|
2630
|
+
lines.push(``);
|
|
2631
|
+
}
|
|
2632
|
+
lines.push(content);
|
|
2633
|
+
return lines.join("\n");
|
|
2634
|
+
}
|
|
2635
|
+
function getOutputPath(tool, format, outputDir, stageName) {
|
|
2636
|
+
const config = TOOL_CONFIGS[tool];
|
|
2637
|
+
if (format === "combined") {
|
|
2638
|
+
return `${outputDir}/${config.combinedFile}`;
|
|
2639
|
+
}
|
|
2640
|
+
const fileName = stageName ? `${config.splitFilePrefix}${stageName}${config.fileExtension}` : `${config.splitFilePrefix}main${config.fileExtension}`;
|
|
2641
|
+
return `${outputDir}/${config.splitDir}/${fileName}`;
|
|
2642
|
+
}
|
|
2643
|
+
function getSplitOutputPaths(tool, outputDir, stageNames) {
|
|
2644
|
+
return stageNames.map((stage) => getOutputPath(tool, "split", outputDir, stage));
|
|
2645
|
+
}
|
|
2646
|
+
function formatStageName(stage) {
|
|
2647
|
+
const stageMap = {
|
|
2648
|
+
actions: "Stage 1: Action Generation",
|
|
2649
|
+
scripts: "Stage 2: Script Writing",
|
|
2650
|
+
balance: "Stage 3: Step Balancing",
|
|
2651
|
+
rebalance: "Stage 4: Rebalancing"
|
|
2652
|
+
};
|
|
2653
|
+
return stageMap[stage] ?? stage;
|
|
2654
|
+
}
|
|
2655
|
+
function getStageFileName(stage) {
|
|
2656
|
+
const stageFileMap = {
|
|
2657
|
+
actions: "stage1-actions",
|
|
2658
|
+
scripts: "stage2-scripts",
|
|
2659
|
+
balance: "stage3-balancing",
|
|
2660
|
+
rebalance: "stage4-rebalancing"
|
|
2661
|
+
};
|
|
2662
|
+
return stageFileMap[stage] ?? stage;
|
|
2663
|
+
}
|
|
2664
|
+
function isValidTool(tool) {
|
|
2665
|
+
return tool in TOOL_CONFIGS;
|
|
2666
|
+
}
|
|
2667
|
+
function isValidFormat(format) {
|
|
2668
|
+
return format === "combined" || format === "split";
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
// context/context-builder.ts
|
|
2672
|
+
var fs6 = __toESM(require("fs/promises"), 1);
|
|
2673
|
+
var path6 = __toESM(require("path"), 1);
|
|
2674
|
+
async function buildContext(tool, stage, variables) {
|
|
2675
|
+
const templates = [];
|
|
2676
|
+
const baseTemplates = await loadTemplatesByCategory("base");
|
|
2677
|
+
templates.push(...baseTemplates);
|
|
2678
|
+
if (stage === "all") {
|
|
2679
|
+
const stageTemplates = await loadTemplatesByCategory("stages");
|
|
2680
|
+
templates.push(...stageTemplates);
|
|
2681
|
+
} else {
|
|
2682
|
+
const stageFileName = getStageFileName(stage);
|
|
2683
|
+
try {
|
|
2684
|
+
const stageTemplate = await loadTemplate("stages", stageFileName);
|
|
2685
|
+
templates.push(stageTemplate);
|
|
2686
|
+
} catch {
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
let content = composeTemplates(templates, {
|
|
2690
|
+
separator: "\n\n---\n\n",
|
|
2691
|
+
includeHeaders: false
|
|
2692
|
+
});
|
|
2693
|
+
if (variables) {
|
|
2694
|
+
content = interpolateVariables(content, variables);
|
|
2695
|
+
}
|
|
2696
|
+
const stageName = stage === "all" ? void 0 : formatStageName(stage);
|
|
2697
|
+
return formatForTool(tool, content, { stage: stageName });
|
|
2698
|
+
}
|
|
2699
|
+
async function deployContext(options) {
|
|
2700
|
+
const { target, stage, format, outputDir, variables } = options;
|
|
2701
|
+
const results = [];
|
|
2702
|
+
const tools = target === "all" ? getSupportedTools() : [target];
|
|
2703
|
+
const stages = stage === "all" ? ["actions", "scripts", "balance", "rebalance"] : [stage];
|
|
2704
|
+
for (const tool of tools) {
|
|
2705
|
+
if (format === "combined") {
|
|
2706
|
+
try {
|
|
2707
|
+
const content = await buildContext(tool, "all", variables);
|
|
2708
|
+
const filePath = getOutputPath(tool, format, outputDir);
|
|
2709
|
+
const absolutePath = path6.resolve(filePath);
|
|
2710
|
+
await fs6.mkdir(path6.dirname(absolutePath), { recursive: true });
|
|
2711
|
+
await fs6.writeFile(absolutePath, content, "utf-8");
|
|
2712
|
+
results.push({
|
|
2713
|
+
tool,
|
|
2714
|
+
filePath: absolutePath,
|
|
2715
|
+
created: true
|
|
2716
|
+
});
|
|
2717
|
+
} catch (error) {
|
|
2718
|
+
results.push({
|
|
2719
|
+
tool,
|
|
2720
|
+
filePath: getOutputPath(tool, format, outputDir),
|
|
2721
|
+
created: false,
|
|
2722
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2723
|
+
});
|
|
2724
|
+
}
|
|
2725
|
+
} else {
|
|
2726
|
+
for (const stg of stages) {
|
|
2727
|
+
try {
|
|
2728
|
+
const content = await buildContext(tool, stg, variables);
|
|
2729
|
+
const stageName = getStageFileName(stg);
|
|
2730
|
+
const filePath = getOutputPath(tool, format, outputDir, stageName);
|
|
2731
|
+
const absolutePath = path6.resolve(filePath);
|
|
2732
|
+
await fs6.mkdir(path6.dirname(absolutePath), { recursive: true });
|
|
2733
|
+
await fs6.writeFile(absolutePath, content, "utf-8");
|
|
2734
|
+
results.push({
|
|
2735
|
+
tool,
|
|
2736
|
+
filePath: absolutePath,
|
|
2737
|
+
stage: stg,
|
|
2738
|
+
created: true
|
|
2739
|
+
});
|
|
2740
|
+
} catch (error) {
|
|
2741
|
+
results.push({
|
|
2742
|
+
tool,
|
|
2743
|
+
filePath: getOutputPath(tool, format, outputDir, stg),
|
|
2744
|
+
stage: stg,
|
|
2745
|
+
created: false,
|
|
2746
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2747
|
+
});
|
|
2748
|
+
}
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
return results;
|
|
2753
|
+
}
|
|
2754
|
+
async function previewContext(tool, stage, variables) {
|
|
2755
|
+
const content = await buildContext(tool, stage, variables);
|
|
2756
|
+
return {
|
|
2757
|
+
tool,
|
|
2758
|
+
stage: stage === "all" ? void 0 : stage,
|
|
2759
|
+
content
|
|
2760
|
+
};
|
|
2761
|
+
}
|
|
2762
|
+
async function listDeployedContext(outputDir) {
|
|
2763
|
+
const tools = getSupportedTools();
|
|
2764
|
+
const files = [];
|
|
2765
|
+
for (const tool of tools) {
|
|
2766
|
+
const config = getToolConfig(tool);
|
|
2767
|
+
const combinedPath = path6.join(outputDir, config.combinedFile);
|
|
2768
|
+
try {
|
|
2769
|
+
await fs6.access(combinedPath);
|
|
2770
|
+
files.push({ tool, path: combinedPath, exists: true });
|
|
2771
|
+
} catch {
|
|
2772
|
+
files.push({ tool, path: combinedPath, exists: false });
|
|
2773
|
+
}
|
|
2774
|
+
const splitDir = path6.join(outputDir, config.splitDir);
|
|
2775
|
+
try {
|
|
2776
|
+
const splitFiles = await fs6.readdir(splitDir);
|
|
2777
|
+
for (const file of splitFiles) {
|
|
2778
|
+
if (file.endsWith(config.fileExtension)) {
|
|
2779
|
+
files.push({
|
|
2780
|
+
tool,
|
|
2781
|
+
path: path6.join(splitDir, file),
|
|
2782
|
+
exists: true
|
|
2783
|
+
});
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
} catch {
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2789
|
+
return { files };
|
|
2790
|
+
}
|
|
2791
|
+
async function removeContext(outputDir, target) {
|
|
2792
|
+
const tools = target === "all" ? getSupportedTools() : [target];
|
|
2793
|
+
const results = [];
|
|
2794
|
+
for (const tool of tools) {
|
|
2795
|
+
const config = getToolConfig(tool);
|
|
2796
|
+
const combinedPath = path6.join(outputDir, config.combinedFile);
|
|
2797
|
+
try {
|
|
2798
|
+
await fs6.unlink(combinedPath);
|
|
2799
|
+
results.push({ path: combinedPath, removed: true });
|
|
2800
|
+
} catch (error) {
|
|
2801
|
+
if (error.code !== "ENOENT") {
|
|
2802
|
+
results.push({
|
|
2803
|
+
path: combinedPath,
|
|
2804
|
+
removed: false,
|
|
2805
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2806
|
+
});
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
const splitDir = path6.join(outputDir, config.splitDir);
|
|
2810
|
+
try {
|
|
2811
|
+
await fs6.rm(splitDir, { recursive: true });
|
|
2812
|
+
results.push({ path: splitDir, removed: true });
|
|
2813
|
+
} catch (error) {
|
|
2814
|
+
if (error.code !== "ENOENT") {
|
|
2815
|
+
results.push({
|
|
2816
|
+
path: splitDir,
|
|
2817
|
+
removed: false,
|
|
2818
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2819
|
+
});
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2823
|
+
return results;
|
|
2824
|
+
}
|
|
2825
|
+
async function getSkill(name) {
|
|
2826
|
+
try {
|
|
2827
|
+
const template = await loadTemplate("skills", name);
|
|
2828
|
+
return { name: template.name, content: template.content };
|
|
2829
|
+
} catch {
|
|
2830
|
+
return null;
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2833
|
+
async function listSkills() {
|
|
2834
|
+
const templates = await listTemplates();
|
|
2835
|
+
return templates.skills;
|
|
2836
|
+
}
|
|
2837
|
+
async function hasTemplates() {
|
|
2838
|
+
const templates = await listTemplates();
|
|
2839
|
+
return templates.base.length > 0;
|
|
2840
|
+
}
|
|
2460
2841
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2461
2842
|
0 && (module.exports = {
|
|
2462
2843
|
DEMO_SCHEMA_VERSION,
|
|
2463
2844
|
ScriptGenerator,
|
|
2845
|
+
TOOL_CONFIGS,
|
|
2464
2846
|
VoiceSynthesizer,
|
|
2847
|
+
buildContext,
|
|
2848
|
+
composeTemplates,
|
|
2465
2849
|
createClickAction,
|
|
2466
2850
|
createDragAction,
|
|
2467
2851
|
createEmptyDemo,
|
|
@@ -2480,15 +2864,35 @@ async function discoverDemos(demoDir) {
|
|
|
2480
2864
|
demoDefinitionSchema,
|
|
2481
2865
|
demoHover,
|
|
2482
2866
|
demoType,
|
|
2867
|
+
deployContext,
|
|
2483
2868
|
discoverDemos,
|
|
2869
|
+
formatForTool,
|
|
2870
|
+
formatStageName,
|
|
2484
2871
|
formatValidationError,
|
|
2485
2872
|
generateTimingManifest,
|
|
2873
|
+
getOutputPath,
|
|
2874
|
+
getSkill,
|
|
2875
|
+
getSplitOutputPaths,
|
|
2876
|
+
getStageFileName,
|
|
2877
|
+
getSupportedTools,
|
|
2878
|
+
getToolConfig,
|
|
2879
|
+
hasTemplates,
|
|
2486
2880
|
highlightElement,
|
|
2487
2881
|
injectCursorOverlay,
|
|
2882
|
+
interpolateVariables,
|
|
2883
|
+
isValidFormat,
|
|
2884
|
+
isValidTool,
|
|
2885
|
+
listDeployedContext,
|
|
2886
|
+
listSkills,
|
|
2887
|
+
listTemplates,
|
|
2488
2888
|
loadDemoDefinition,
|
|
2889
|
+
loadTemplate,
|
|
2890
|
+
loadTemplatesByCategory,
|
|
2489
2891
|
moveCursorTo,
|
|
2490
2892
|
parseDemoDefinition,
|
|
2491
2893
|
parseFromYAML,
|
|
2894
|
+
previewContext,
|
|
2895
|
+
removeContext,
|
|
2492
2896
|
removeCursorOverlay,
|
|
2493
2897
|
resolvePath,
|
|
2494
2898
|
resolveTarget,
|
|
@@ -2496,6 +2900,7 @@ async function discoverDemos(demoDir) {
|
|
|
2496
2900
|
runDemoFromFile,
|
|
2497
2901
|
safeParseDemoDefinition,
|
|
2498
2902
|
serializeToYAML,
|
|
2903
|
+
templateExists,
|
|
2499
2904
|
triggerClickRipple,
|
|
2500
2905
|
validateDemoDefinition
|
|
2501
2906
|
});
|