Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
61036ed
core: author_scene — a whole three.js design handed over as a payload…
wass08 Oct 16, 2026
0c5daea
mcp: author_scene — compile and store the items, write the conversion…
wass08 Oct 16, 2026
934ab39
core: verify_scene reads hosted items through their host, lets stacke…
wass08 Oct 17, 2026
ff17a77
skill + wiki: author_scene — convert a design written as three.js in …
wass08 Oct 17, 2026
4c76a4c
core: a preview colour for every textured material; author_scene's me…
wass08 Oct 17, 2026
8033010
core: author_scene is MCP-first, outside the shared contract list unt…
wass08 Oct 17, 2026
75abaca
core: author_scene salts a replacement's ids so a payload written ove…
wass08 Oct 17, 2026
a430fa8
core: author_scene after the acceptance runs — lights on the asset, a…
wass08 Oct 17, 2026
0123c8e
core: author_scene takes opening types, styles and modules, exact col…
wass08 Oct 19, 2026
c23e1da
mcp: author_scene compiles an opening's module and keeps hex colours …
wass08 Oct 19, 2026
dda3765
skill + wiki: author_scene's opening types and styles, face colours, …
wass08 Oct 19, 2026
3784dae
core: a slab lying on a wall's top is its cap, never its support
wass08 Oct 19, 2026
0e01f89
geometry-script: bake the back face of double- and back-sided materials
wass08 Oct 19, 2026
4f1b897
core: a new door's handle hangs opposite its hinges
wass08 Oct 19, 2026
c4fefb2
core: pin what a room-edge push keeps on a painted wall
wass08 Oct 19, 2026
64bb180
core: author_scene reads each wall's room side from the plan instead …
wass08 Oct 19, 2026
a2fba24
core: author_scene's replacement salt probes a level id, so the same …
wass08 Oct 19, 2026
a7b3710
core + mcp: author_scene keeps a wall item's distance from the face, …
wass08 Oct 19, 2026
dce1532
rooms: a floor finish built by a script for the room's floor, rebuilt…
wass08 Oct 19, 2026
8f58f32
core + mcp: author_scene writes a wall's skirting and a room's floor …
wass08 Oct 19, 2026
a81c101
walls: a face finish built by a script for exactly one face, rebuilt …
wass08 Oct 19, 2026
a3dbe7d
core + mcp: author_scene writes wall face scripts from a wall's faceL…
wass08 Oct 19, 2026
01578cd
geometry-script: Pascal cuts a floor or face script's build to its re…
wass08 Oct 19, 2026
db03714
geometry-script + author_scene: Pascal measures how much of a floor o…
wass08 Oct 19, 2026
f87c929
core + mcp: author_scene keeps authored glass, glow and surface on ex…
wass08 Oct 19, 2026
e52c6e1
core: add_object's floor-plate rule from main covers rugs, so the nam…
wass08 Oct 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 53 additions & 1 deletion packages/core/src/agent-operations/add-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
generateId,
ItemNode,
type SlabNode,
type WallFace,
} from '../schema'
import { achievedChanges } from './achieved'
import { targetLevel } from './level-target'
Expand Down Expand Up @@ -616,11 +617,62 @@ export function scriptedFieldRefusal(node: AnyNode, data: Record<string, unknown
return `${node.id} is built from a script, so ${fields.join(', ')} ${fields.length === 1 ? 'comes' : 'come'} from it: rebuild it with ${tool} with nodeId and params (get_source shows them); nothing was changed.`
}

/** What `get_source` reads: a scripted node, a room's floor script, or a wall face's script. */
export type ScriptReadable = Pick<ScriptedNode, 'name' | 'source'> & {
id: string
type: ScriptedNode['type'] | 'zone' | 'wall'
/** The wall face whose script it is. */
face?: WallFace
}

/**
* The script `get_source` reads at `nodeId`: an authored object's, a room's floor script by its
* zone id, or a wall's face script (`face`, which a wall with one scripted face may leave out).
*/
export function readableScript(
nodes: Record<string, AnyNode>,
nodeId: string,
face?: WallFace,
): ScriptReadable {
const node = nodes[nodeId]
if (node?.type === 'wall') {
const faces = (['a', 'b'] as const).filter((side) => node.finishScripts?.[side])
const read = face ?? (faces.length === 1 ? faces[0] : undefined)
if (!faces.length)
refuse('not_authored', `${node.name || nodeId} has no face script.`, { id: nodeId })
if (!read)
refuse(
'face_required',
`Both faces of ${node.name || nodeId} have a script: name the face, a or b.`,
{
id: nodeId,
faces,
},
)
const source = node.finishScripts?.[read]
if (!source)
refuse(
'not_authored',
`Face ${read} of ${node.name || nodeId} has no script; face ${faces[0]} has.`,
{
id: nodeId,
faces,
},
)
return { id: node.id, type: 'wall', name: node.name, source, face: read }
}
if (node?.type !== 'zone') return authoredObject(nodes, nodeId)
if (!node.floor?.script)
refuse('not_authored', `${node.name || nodeId} has no floor script.`, { id: nodeId })
return { id: node.id, type: 'zone', name: node.name, source: node.floor.script }
}

/** What `get_source` answers once the host has the module's text. */
export function readSourceResult(node: ScriptedNode, code: string) {
export function readSourceResult(node: ScriptReadable, code: string) {
return {
nodeId: node.id,
type: node.type,
...(node.face ? { face: node.face } : {}),
name: node.name,
language: node.source.language,
code,
Expand Down
Loading
Loading