@t3lnet/sceneforge 1.0.12 → 1.0.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/dist/index.js CHANGED
@@ -2387,13 +2387,27 @@ async function discoverDemos(demoDir) {
2387
2387
  }
2388
2388
 
2389
2389
  // context/template-loader.ts
2390
+ import { existsSync } from "fs";
2390
2391
  import * as fs5 from "fs/promises";
2391
2392
  import * as path5 from "path";
2392
2393
  import { fileURLToPath } from "url";
2393
2394
  var __filename = fileURLToPath(import.meta.url);
2394
2395
  var __dirname = path5.dirname(__filename);
2395
2396
  function getTemplatesDir() {
2396
- return path5.join(__dirname, "templates");
2397
+ const candidates = [
2398
+ // Standard dist layout: dist/templates/{base,stages,skills}
2399
+ path5.join(__dirname, "templates"),
2400
+ // Nested layout if templates were copied into an existing dist/templates
2401
+ path5.join(__dirname, "templates", "templates"),
2402
+ // Source layout when templates are shipped under context/templates
2403
+ path5.join(__dirname, "..", "context", "templates")
2404
+ ];
2405
+ for (const candidate of candidates) {
2406
+ if (existsSync(path5.join(candidate, "base"))) {
2407
+ return candidate;
2408
+ }
2409
+ }
2410
+ return candidates[0];
2397
2411
  }
2398
2412
  async function loadTemplate(category, name) {
2399
2413
  const templatesDir = getTemplatesDir();
@@ -2420,7 +2434,9 @@ async function loadTemplatesByCategory(category) {
2420
2434
  }
2421
2435
  return templates;
2422
2436
  } catch (error) {
2423
- throw new Error(`Failed to load templates from ${category}: ${error}`);
2437
+ throw new Error(
2438
+ `Failed to load templates from ${category} in ${templatesDir}: ${error}`
2439
+ );
2424
2440
  }
2425
2441
  }
2426
2442
  function interpolateVariables(content, variables) {
@@ -2574,6 +2590,42 @@ function isValidFormat(format) {
2574
2590
  // context/context-builder.ts
2575
2591
  import * as fs6 from "fs/promises";
2576
2592
  import * as path6 from "path";
2593
+ var SCENEFORGE_START_MARKER = "<!-- SCENEFORGE_CONTEXT_START -->";
2594
+ var SCENEFORGE_END_MARKER = "<!-- SCENEFORGE_CONTEXT_END -->";
2595
+ function wrapWithMarkers(content) {
2596
+ return `${SCENEFORGE_START_MARKER}
2597
+ ${content}
2598
+ ${SCENEFORGE_END_MARKER}`;
2599
+ }
2600
+ async function mergeWithExisting(filePath, newContent) {
2601
+ const wrappedContent = wrapWithMarkers(newContent);
2602
+ try {
2603
+ const existingContent = await fs6.readFile(filePath, "utf-8");
2604
+ const startIndex = existingContent.indexOf(SCENEFORGE_START_MARKER);
2605
+ const endIndex = existingContent.indexOf(SCENEFORGE_END_MARKER);
2606
+ if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
2607
+ const beforeSection = existingContent.slice(0, startIndex);
2608
+ const afterSection = existingContent.slice(
2609
+ endIndex + SCENEFORGE_END_MARKER.length
2610
+ );
2611
+ return {
2612
+ content: beforeSection + wrappedContent + afterSection,
2613
+ merged: true
2614
+ };
2615
+ } else {
2616
+ const separator = existingContent.trim().endsWith("-->") ? "\n\n" : "\n\n---\n\n";
2617
+ return {
2618
+ content: existingContent.trimEnd() + separator + wrappedContent + "\n",
2619
+ merged: true
2620
+ };
2621
+ }
2622
+ } catch (error) {
2623
+ if (error.code === "ENOENT") {
2624
+ return { content: wrappedContent, merged: false };
2625
+ }
2626
+ throw error;
2627
+ }
2628
+ }
2577
2629
  async function buildContext(tool, stage, variables) {
2578
2630
  const templates = [];
2579
2631
  const baseTemplates = await loadTemplatesByCategory("base");
@@ -2611,12 +2663,20 @@ async function deployContext(options) {
2611
2663
  const filePath = getOutputPath(tool, format, outputDir);
2612
2664
  const absolutePath = path6.resolve(filePath);
2613
2665
  await fs6.mkdir(path6.dirname(absolutePath), { recursive: true });
2614
- await fs6.writeFile(absolutePath, content, "utf-8");
2666
+ const { content: finalContent, merged } = await mergeWithExisting(
2667
+ absolutePath,
2668
+ content
2669
+ );
2670
+ await fs6.writeFile(absolutePath, finalContent, "utf-8");
2615
2671
  results.push({
2616
2672
  tool,
2617
2673
  filePath: absolutePath,
2618
- created: true
2674
+ created: true,
2675
+ skipped: false
2619
2676
  });
2677
+ if (merged) {
2678
+ console.log(` [merged] ${path6.relative(outputDir, absolutePath)}`);
2679
+ }
2620
2680
  } catch (error) {
2621
2681
  results.push({
2622
2682
  tool,
@@ -2633,13 +2693,21 @@ async function deployContext(options) {
2633
2693
  const filePath = getOutputPath(tool, format, outputDir, stageName);
2634
2694
  const absolutePath = path6.resolve(filePath);
2635
2695
  await fs6.mkdir(path6.dirname(absolutePath), { recursive: true });
2636
- await fs6.writeFile(absolutePath, content, "utf-8");
2696
+ const { content: finalContent, merged } = await mergeWithExisting(
2697
+ absolutePath,
2698
+ content
2699
+ );
2700
+ await fs6.writeFile(absolutePath, finalContent, "utf-8");
2637
2701
  results.push({
2638
2702
  tool,
2639
2703
  filePath: absolutePath,
2640
2704
  stage: stg,
2641
- created: true
2705
+ created: true,
2706
+ skipped: false
2642
2707
  });
2708
+ if (merged) {
2709
+ console.log(` [merged] ${path6.relative(outputDir, absolutePath)}`);
2710
+ }
2643
2711
  } catch (error) {
2644
2712
  results.push({
2645
2713
  tool,