feat: integrate continuous building via Project Genie simulation#75
feat: integrate continuous building via Project Genie simulation#75Igor Holt (igor-holt) wants to merge 2 commits into
Conversation
- Modified `scripts/genesis.cjs` to output generated components to `yennefer-observatory/src/components/mutations` instead of `generated` so they can be picked up by the frontend via `import.meta.glob`. - Added logic in `scripts/genesis.cjs` to fallback to `../logs/genesis_journal.jsonl` if the target journal directory cannot be created. - Updated `consultTheVisionary`'s `mutations` list with Project Genie inspired directives. - Updated `generateEvolutionComponent` to parse these new directives and render `landscape` and `makerspace` simulation environments. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| 🔵 In progress View logs |
yennefer | eef8912 | Commit Preview URL | Apr 20 2026, 08:31 AM |
There was a problem hiding this comment.
Code Review
This pull request introduces 'GenieWorld' environment mutations, such as dynamic landscapes and makerspace simulations, and refactors the component generation logic to support custom Three.js animations and additional meshes. Feedback was provided to improve the robustness of directory creation and mutation selection logic. Additionally, there are suggestions to optimize the performance of procedural landscape animations by avoiding frequent CPU-to-GPU buffer uploads and to simplify the string construction for library imports.
| if (!fs.existsSync(path.dirname(PATHS.journal))) { | ||
| try { | ||
| fs.mkdirSync(path.dirname(PATHS.journal), { recursive: true }); | ||
| } catch (err) { | ||
| PATHS.journal = path.join(__dirname, '../logs/genesis_journal.jsonl'); | ||
| if (!fs.existsSync(path.dirname(PATHS.journal))) { | ||
| fs.mkdirSync(path.dirname(PATHS.journal), { recursive: true }); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
The directory creation logic is redundant and lacks robustness. fs.mkdirSync with { recursive: true } handles existing directories automatically, making the fs.existsSync check unnecessary. Additionally, the fallback path creation in the catch block is not protected by its own error handling, which could lead to an unhandled exception if the fallback location is also unwritable. It is also recommended to ensure the PATHS.body directory exists, as it has been moved to a new location.
try {
fs.mkdirSync(path.dirname(PATHS.journal), { recursive: true });
} catch (err) {
PATHS.journal = path.join(__dirname, '../logs/genesis_journal.jsonl');
try {
fs.mkdirSync(path.dirname(PATHS.journal), { recursive: true });
} catch (e) {
// Fallback failed, script will likely fail on write
}
}
try {
fs.mkdirSync(PATHS.body, { recursive: true });
} catch (e) {}
| const idx = isGenieSim | ||
| ? Math.floor(Math.random() * 2) + (mutations.length - 2) | ||
| : Math.floor(Date.now() / 1000) % mutations.length; |
There was a problem hiding this comment.
The selection logic for Genie simulations is fragile as it assumes the target mutations are always the last two elements of the array. This will break if the array order changes or if new mutations are added. A more resilient approach would be to filter the mutations based on their content.
const genieIndices = mutations.map((m, i) => (m.content.includes("landscape") || m.content.includes("makerspace") ? i : -1)).filter(i => i !== -1);
const idx = isGenieSim && genieIndices.length > 0
? genieIndices[Math.floor(Math.random() * genieIndices.length)]
: Math.floor(Date.now() / 1000) % mutations.length;
| customLogic = ` | ||
| // Project Genie Landscape Simulation | ||
| const positions = meshRef.current.geometry.attributes.position; | ||
| for (let i = 0; i < positions.count; i++) { | ||
| const x = positions.getX(i); | ||
| const y = positions.getY(i); | ||
| const z = Math.sin(x * 2 + state.clock.elapsedTime) * 0.5 + Math.cos(y * 2 + state.clock.elapsedTime) * 0.5; | ||
| positions.setZ(i, z * Math.min(1, balance * 2)); | ||
| } | ||
| positions.needsUpdate = true; | ||
| meshRef.current.rotation.x = -Math.PI / 2; | ||
| meshRef.current.rotation.z += 0.001; | ||
| `; |
There was a problem hiding this comment.
This animation logic has performance and efficiency issues. Updating geometry attributes (positions.setZ) and setting needsUpdate = true inside useFrame forces a CPU-to-GPU buffer upload every frame, which is expensive. For procedural landscapes, a vertex shader is preferred. Additionally, setting rotation.x to a constant value every frame is redundant; this should be set once on the mesh component's initial props.
| const isDreiImportNeeded = material.includes('MeshDistortMaterial') || material.includes('MeshWobbleMaterial'); | ||
| importedDrei = isDreiImportNeeded ? `import { ${material.includes('MeshDistortMaterial') ? 'MeshDistortMaterial' : ''}${material.includes('MeshDistortMaterial') && material.includes('MeshWobbleMaterial') ? ', ' : ''}${material.includes('MeshWobbleMaterial') ? 'MeshWobbleMaterial' : ''} } from '@react-three/drei'` : ''; |
There was a problem hiding this comment.
The logic for constructing the importedDrei string is difficult to read and maintain. Using an array to collect imports and joining them with a comma is a cleaner and more robust approach.
const imports = [];
if (material.includes('MeshDistortMaterial')) imports.push('MeshDistortMaterial');
if (material.includes('MeshWobbleMaterial')) imports.push('MeshWobbleMaterial');
importedDrei = imports.length > 0 ? `import { ${imports.join(', ')} } from '@react-three/drei'` : '';
There was a problem hiding this comment.
Code Review
This pull request updates the genesis.cjs script to support 'GenieWorld' simulations by adding new mutation types for landscapes and makerspaces. It also introduces environment-specific path handling for journal logs and refactors the React Three Fiber component generation to support custom logic and additional meshes. Feedback was provided to improve the robustness of the directory creation logic, make the mutation selection more dynamic to avoid fragile indexing, and simplify the string construction for library imports.
| if (!fs.existsSync(path.dirname(PATHS.journal))) { | ||
| try { | ||
| fs.mkdirSync(path.dirname(PATHS.journal), { recursive: true }); | ||
| } catch (err) { | ||
| PATHS.journal = path.join(__dirname, '../logs/genesis_journal.jsonl'); | ||
| if (!fs.existsSync(path.dirname(PATHS.journal))) { | ||
| fs.mkdirSync(path.dirname(PATHS.journal), { recursive: true }); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
The directory creation logic is redundant and slightly fragile. fs.mkdirSync with the { recursive: true } option already handles existing directories gracefully, making the fs.existsSync check unnecessary. Additionally, the fallback logic can be streamlined to avoid nested checks and redundant calls.
try {
fs.mkdirSync(path.dirname(PATHS.journal), { recursive: true });
} catch (err) {
PATHS.journal = path.join(__dirname, '../logs/genesis_journal.jsonl');
fs.mkdirSync(path.dirname(PATHS.journal), { recursive: true });
}
| const idx = isGenieSim | ||
| ? Math.floor(Math.random() * 2) + (mutations.length - 2) | ||
| : Math.floor(Date.now() / 1000) % mutations.length; |
There was a problem hiding this comment.
The logic for selecting Genie-specific mutations is fragile as it relies on them being the last two elements in the mutations array. If the array is expanded or reordered in the future, this logic will likely pick incorrect mutations for the simulation. It is better to dynamically identify the relevant indices.
const genieIndices = mutations.map((m, i) => (m.content.includes("landscape") || m.content.includes("makerspace")) ? i : -1).filter(i => i !== -1);
const idx = isGenieSim && genieIndices.length > 0
? genieIndices[Math.floor(Math.random() * genieIndices.length)]
: Math.floor(Date.now() / 1000) % mutations.length;
| const isDreiImportNeeded = material.includes('MeshDistortMaterial') || material.includes('MeshWobbleMaterial'); | ||
| importedDrei = isDreiImportNeeded ? `import { ${material.includes('MeshDistortMaterial') ? 'MeshDistortMaterial' : ''}${material.includes('MeshDistortMaterial') && material.includes('MeshWobbleMaterial') ? ', ' : ''}${material.includes('MeshWobbleMaterial') ? 'MeshWobbleMaterial' : ''} } from '@react-three/drei'` : ''; |
There was a problem hiding this comment.
The string construction for importedDrei is brittle and difficult to maintain due to the nested ternary operators and manual comma handling. Using an array to collect required imports and joining them is a much cleaner and more robust approach.
const imports = [
material.includes('MeshDistortMaterial') && 'MeshDistortMaterial',
material.includes('MeshWobbleMaterial') && 'MeshWobbleMaterial'
].filter(Boolean);
importedDrei = imports.length > 0 ? `import { ${imports.join(', ')} } from '@react-three/drei'` : '';
…endency The Cloudflare Workers CI build was failing due to an ERESOLVE error related to a conflicting typescript peer dependency in `react-scripts`. This commit updates `wrangler.toml` to add `--legacy-peer-deps` to the frontend `npm install` build command, allowing the build to bypass the conflict and compile successfully. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This PR integrates features inspired by Project Genie to enable live, continuous building of the Yennefer Observatory environment.
Changes included:
scripts/genesis.cjsto output generated evolution components toyennefer-observatory/src/components/mutationsso they can be imported dynamically byObservatory.jsx.generateEvolutionComponentlogic to generate these new environments dynamically with procedural React Three Fiber logic based on the text prompt directives./home/yenn/.PR created automatically by Jules for task 18433125047180788734 started by Igor Holt (@igor-holt)