@energy8platform/golem 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +14 -0
  2. package/dist/editor.css +3 -4
  3. package/dist/editor.js +108 -61
  4. package/dist/lib/cli.js +101 -70
  5. package/dist/lib/cli.js.map +4 -4
  6. package/dist/lib/e8/agent.d.ts +35 -0
  7. package/dist/lib/e8/host.d.ts +22 -0
  8. package/dist/lib/e8/node.d.ts +66 -0
  9. package/dist/lib/e8/runtime.d.ts +10 -0
  10. package/dist/lib/e8/schema.d.ts +3 -0
  11. package/dist/lib/e8/types.d.ts +80 -0
  12. package/dist/lib/e8-agent.js +6781 -0
  13. package/dist/lib/e8-agent.js.map +7 -0
  14. package/dist/lib/e8-client.js +116 -0
  15. package/dist/lib/e8-host.js +6929 -0
  16. package/dist/lib/e8-host.js.map +7 -0
  17. package/dist/lib/e8-runtime.js +2024 -0
  18. package/dist/lib/e8-runtime.js.map +7 -0
  19. package/dist/lib/e8-schema.js +7 -0
  20. package/dist/lib/e8-schema.js.map +7 -0
  21. package/dist/lib/editor/api.d.ts +1 -0
  22. package/dist/lib/editor/embed.d.ts +9 -0
  23. package/dist/lib/editor/server.d.ts +23 -1
  24. package/dist/lib/editor/store.d.ts +2 -0
  25. package/dist/lib/editor/timeline.d.ts +15 -0
  26. package/dist/lib/editor-entry.d.ts +1 -1
  27. package/dist/lib/editor-entry.js +102 -70
  28. package/dist/lib/editor-entry.js.map +4 -4
  29. package/dist/lib/rig-import-layers.d.ts +2 -0
  30. package/dist/lib/rig-version.d.ts +12 -0
  31. package/dist/lib/tool-schema.d.ts +3 -0
  32. package/dist/lib/tools.d.ts +2 -0
  33. package/dist/lib/tools.js +49 -10
  34. package/dist/lib/tools.js.map +4 -4
  35. package/editor.html +2 -2
  36. package/package.json +38 -3
  37. package/skills/e8-golem/SKILL.md +71 -0
  38. package/skills/golem-symbol-animation/SKILL.md +87 -0
  39. package/skills/golem-symbol-animation/agents/openai.yaml +4 -0
  40. package/skills/golem-symbol-animation/references/facial-controls.md +48 -0
  41. package/skills/golem-symbol-animation/references/game-engine-integration.md +133 -0
  42. package/skills/golem-symbol-animation/references/golem-authoring.md +138 -0
  43. package/skills/golem-symbol-animation/references/interactive-editor.md +17 -0
  44. package/skills/golem-symbol-animation/references/motion-craft.md +113 -0
  45. package/skills/golem-symbol-animation/references/packed-delivery.md +88 -0
  46. package/skills/golem-symbol-animation/references/quantitative-qa.md +106 -0
  47. package/skills/golem-symbol-animation/references/spine-rive-study.md +87 -0
  48. package/skills/golem-symbol-animation/scripts/atlas_parts.py +87 -0
  49. package/skills/golem-symbol-animation/scripts/check_package.py +71 -0
  50. package/skills/golem-symbol-animation/scripts/image_gates.py +143 -0
  51. package/skills/golem-symbol-cutting/SKILL.md +70 -0
  52. package/skills/golem-symbol-cutting/agents/openai.yaml +4 -0
  53. package/skills/golem-symbol-cutting/assets/h1/h1.atlas.png +0 -0
  54. package/skills/golem-symbol-cutting/assets/h1/h1.png +0 -0
  55. package/skills/golem-symbol-cutting/references/cutting-workflow.md +92 -0
  56. package/skills/golem-symbol-cutting/references/facial-layers.md +44 -0
  57. package/skills/golem-symbol-cutting/references/generation-workflow.md +109 -0
  58. package/skills/golem-symbol-cutting/references/golem-handoff.md +62 -0
  59. package/skills/golem-symbol-cutting/references/h1-example.md +46 -0
  60. package/skills/golem-symbol-cutting/references/hybrid-workflow.md +119 -0
  61. package/skills/golem-symbol-cutting/references/registration-and-motion.md +89 -0
  62. package/skills/golem-symbol-cutting/references/spine-rive-construction.md +73 -0
  63. package/skills/golem-symbol-cutting/scripts/atlas_parts.py +87 -0
  64. package/skills/golem-symbol-cutting/scripts/hybrid_parts.py +279 -0
@@ -28,5 +28,7 @@ export interface LayerSpec {
28
28
  blend?: "normal" | "add" | "multiply" | "screen";
29
29
  }
30
30
  export declare function pngSize(buf: Buffer): [number, number];
31
+ /** `file`, named by a sidecar inside `dir` (layers.json, a Spine atlas), leaves `dir`: absolute or climbing out. */
32
+ export declare function outsideDir(dir: string, file: string): boolean;
31
33
  export declare function importLayers(doc: Doc, dir: string, relPrefix?: string): Promise<Doc>;
32
34
  export {};
@@ -0,0 +1,12 @@
1
+ import { type ToolResult } from "./rig-api";
2
+ /** `mtimeMs:size` of the file, or "missing" */
3
+ export declare function rigVersion(abs: string): Promise<string>;
4
+ /**
5
+ * callTool with the rig's version just before and just after, both read inside the rig's queue, so no other writer in
6
+ * this process lands between them. `args.path` must be absolute; a call without one reads "missing" twice.
7
+ */
8
+ export declare function callToolVersioned(name: string, args: Record<string, unknown>): Promise<{
9
+ result: ToolResult;
10
+ before: string;
11
+ after: string;
12
+ }>;
@@ -0,0 +1,3 @@
1
+ import type { ToolDef } from "./rig-api";
2
+ /** draft-07, every ref inlined, no `$schema` key — the tool's own strict zod object, so unknown keys stay refused */
3
+ export declare function jsonSchemaOf(tool: ToolDef): Record<string, unknown>;
@@ -1,2 +1,4 @@
1
1
  /** `@energy8platform/golem/tools` — the tool registry (node): MCP, CLI and the editor call the same list. */
2
2
  export { tools, callTool, closeTools, type ToolDef, type ToolResult } from "./rig-api";
3
+ export { rigVersion, callToolVersioned } from "./rig-version";
4
+ export { jsonSchemaOf } from "./tool-schema";
package/dist/lib/tools.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/rig-api.ts
2
2
  import { z as z3 } from "zod";
3
3
  import { readFile as readFile9, writeFile as writeFile7, stat as stat2, mkdir as mkdir6, readdir as readdir4 } from "node:fs/promises";
4
- import { dirname as dirname8, join as join9, relative as relative2, isAbsolute } from "node:path";
4
+ import { dirname as dirname8, join as join9, relative as relative3, isAbsolute as isAbsolute2 } from "node:path";
5
5
 
6
6
  // src/rig-io.ts
7
7
  import { mkdir, rename, rm, writeFile } from "node:fs/promises";
@@ -24,8 +24,10 @@ var saveJson = (path, value) => saveBytes(path, JSON.stringify(value, null, 2));
24
24
  // src/rig-queue.ts
25
25
  import { AsyncLocalStorage } from "node:async_hooks";
26
26
  import { resolve } from "node:path";
27
- var pending = /* @__PURE__ */ new Map();
28
- var active = new AsyncLocalStorage();
27
+ var { pending, active } = globalThis[Symbol.for("golem.rigQueue")] ??= {
28
+ pending: /* @__PURE__ */ new Map(),
29
+ active: new AsyncLocalStorage()
30
+ };
29
31
  async function withRigQueue(path, op) {
30
32
  const key = resolve(path);
31
33
  const held = active.getStore();
@@ -2001,8 +2003,9 @@ function createDoc(name, width, height, notes) {
2001
2003
  function createSymbol(name, asset, margin = 0.15, notes) {
2002
2004
  const mx = Math.ceil(asset.width * margin), my = Math.ceil(asset.height * margin);
2003
2005
  const width = asset.width + 2 * mx, height = asset.height + 2 * my;
2004
- const fromFile = asset.src.replace(/^.*\//, "").replace(/\.[^.]+$/, "").toLowerCase().replace(/[^a-z0-9_]/g, "_").replace(/^[^a-z]+/, "");
2005
- const id = asset.id ?? (fromFile || name);
2006
+ const stem = asset.src.replace(/^.*\//, "").replace(/\.[^.]+$/, "").toLowerCase().replace(/[^a-z0-9_]/g, "_");
2007
+ const fromFile = stem.replace(/^[^a-z]+/, "") || (stem ? `symbol_${stem}` : "");
2008
+ const id = asset.id ?? (ID_RE.test(fromFile) ? fromFile : ID_RE.test(name) ? name : "symbol");
2006
2009
  let doc = createDoc(name, width, height, notes);
2007
2010
  doc = { ...doc, bones: [{ ...doc.bones[0], transform: { ...doc.bones[0].transform, x: width / 2, y: height - my } }] };
2008
2011
  doc = { ...doc, assets: [RigSchema.shape.assets.element.parse({ id, src: asset.src, width: asset.width, height: asset.height })] };
@@ -2758,7 +2761,7 @@ function setGoal(doc, bone, x, y, opts) {
2758
2761
 
2759
2762
  // src/rig-import-layers.ts
2760
2763
  import { readdir, readFile } from "node:fs/promises";
2761
- import { join as join2, basename as basename2 } from "node:path";
2764
+ import { join as join2, basename as basename2, isAbsolute, relative, sep } from "node:path";
2762
2765
  var DEFAULT_PARENT = {
2763
2766
  head: "neck",
2764
2767
  neck: "torso",
@@ -2784,6 +2787,10 @@ function pngSize(buf) {
2784
2787
  if (buf.readUInt32BE(12) !== 1229472850) throw new Error("not a PNG (IHDR missing)");
2785
2788
  return [buf.readUInt32BE(16), buf.readUInt32BE(20)];
2786
2789
  }
2790
+ function outsideDir(dir, file) {
2791
+ const r = relative(dir, join2(dir, file));
2792
+ return isAbsolute(file) || r === ".." || r.startsWith(".." + sep);
2793
+ }
2787
2794
  async function importLayers(doc, dir, relPrefix = "layers") {
2788
2795
  let specs;
2789
2796
  try {
@@ -2796,6 +2803,7 @@ async function importLayers(doc, dir, relPrefix = "layers") {
2796
2803
  let next = doc;
2797
2804
  const parsed = [];
2798
2805
  for (const s of specs) {
2806
+ if (outsideDir(dir, s.file)) throw new Error(`layers.json file "${s.file}" is outside the layers folder (${dir})`);
2799
2807
  const buf = await readFile(join2(dir, s.file));
2800
2808
  const [w, h] = pngSize(buf);
2801
2809
  const m = basename2(s.file, ".png").match(/^(?:(\d+)_)?(.+)$/);
@@ -4052,7 +4060,7 @@ async function buildAtlas(doc, assetsDir, outDir, opts = {}) {
4052
4060
 
4053
4061
  // src/spine-import.ts
4054
4062
  import { readFile as readFile7, stat, writeFile as writeFile5 } from "node:fs/promises";
4055
- import { basename as basename4, dirname as dirname6, extname, join as join8, relative } from "node:path";
4063
+ import { basename as basename4, dirname as dirname6, extname, join as join8, relative as relative2 } from "node:path";
4056
4064
 
4057
4065
  // src/ktx2.ts
4058
4066
  import { readFile as readFile6 } from "node:fs/promises";
@@ -4858,6 +4866,7 @@ async function importSpineProject(opts) {
4858
4866
  const rigDir = dirname6(opts.rigPath);
4859
4867
  const pagePaths = /* @__PURE__ */ new Map();
4860
4868
  for (const page2 of pages) {
4869
+ if (!opts.image && outsideDir(dirname6(atlasPath), page2.name)) throw new Error(`atlas page "${page2.name}" is outside the atlas folder (${dirname6(atlasPath)})`);
4861
4870
  const pageStem = join8(dirname6(atlasPath), page2.name.replace(/\.[a-z0-9]+$/i, ""));
4862
4871
  const imagePath = opts.image ?? await firstExisting([join8(dirname6(atlasPath), page2.name), pageStem + ".png", pageStem + ".ktx2", ...pages.length === 1 ? [stem + ".png", stem + ".ktx2"] : []], `atlas page image ${page2.name}`);
4863
4872
  let pngPath = imagePath;
@@ -4870,7 +4879,7 @@ async function importSpineProject(opts) {
4870
4879
  }
4871
4880
  pagePaths.set(page2.name, pngPath);
4872
4881
  }
4873
- const pageImage = (page2) => relative(rigDir, pagePaths.get(page2)).split("\\").join("/");
4882
+ const pageImage = (page2) => relative2(rigDir, pagePaths.get(page2)).split("\\").join("/");
4874
4883
  const name = opts.name ?? basename4(stem);
4875
4884
  const imagePaths = [...pagePaths.values()];
4876
4885
  return { ...importSpine(json, atlasText, { name, skin: opts.skin, pageImage, margin: opts.margin, notes: opts.notes }), imagePath: imagePaths[0], imagePaths };
@@ -5563,8 +5572,8 @@ async function load(path) {
5563
5572
  }
5564
5573
  var save = (path, doc) => saveJson(path, doc);
5565
5574
  var exists2 = (p) => stat2(p).then(() => true, () => false);
5566
- var resolveFrom = (rigPath, p) => isAbsolute(p) ? p : join9(dirname8(rigPath), p);
5567
- var srcFor = (rigPath, file) => relative2(dirname8(rigPath), file).split("\\").join("/");
5575
+ var resolveFrom = (rigPath, p) => isAbsolute2(p) ? p : join9(dirname8(rigPath), p);
5576
+ var srcFor = (rigPath, file) => relative3(dirname8(rigPath), file).split("\\").join("/");
5568
5577
  var libraryFor = (rigPath, lib) => lib ? resolveFrom(rigPath, lib) : join9(dirname8(rigPath), "presets.json");
5569
5578
  async function pngInfo(rigPath, file) {
5570
5579
  const abs = resolveFrom(rigPath, file);
@@ -6588,9 +6597,39 @@ tool(
6588
6597
  }
6589
6598
  }
6590
6599
  );
6600
+
6601
+ // src/rig-version.ts
6602
+ import { stat as stat3 } from "node:fs/promises";
6603
+ async function rigVersion(abs) {
6604
+ try {
6605
+ const s = await stat3(abs);
6606
+ return `${s.mtimeMs}:${s.size}`;
6607
+ } catch {
6608
+ return "missing";
6609
+ }
6610
+ }
6611
+ async function callToolVersioned(name, args) {
6612
+ const path = typeof args.path === "string" ? args.path : void 0;
6613
+ if (!path) return { result: await callTool(name, args), before: "missing", after: "missing" };
6614
+ return withRigQueue(path, async () => {
6615
+ const before = await rigVersion(path);
6616
+ const result = await callTool(name, args);
6617
+ return { result, before, after: await rigVersion(path) };
6618
+ });
6619
+ }
6620
+
6621
+ // src/tool-schema.ts
6622
+ import { zodToJsonSchema } from "zod-to-json-schema";
6623
+ function jsonSchemaOf(tool2) {
6624
+ const { $schema: _drop, ...schema } = zodToJsonSchema(tool2.input, { $refStrategy: "none" });
6625
+ return schema;
6626
+ }
6591
6627
  export {
6592
6628
  callTool,
6629
+ callToolVersioned,
6593
6630
  closeTools,
6631
+ jsonSchemaOf,
6632
+ rigVersion,
6594
6633
  tools
6595
6634
  };
6596
6635
  //# sourceMappingURL=tools.js.map