Initial Brokkr scaffold
This commit is contained in:
commit
16adc98447
16 changed files with 675 additions and 0 deletions
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
target/
|
||||
.brokkr/
|
||||
.brokkr-smoke/
|
||||
*.user
|
||||
*.suo
|
||||
Library/
|
||||
Temp/
|
||||
Obj/
|
||||
Build/
|
||||
Builds/
|
||||
Logs/
|
||||
UserSettings/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
114
Cargo.lock
generated
Normal file
114
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||
|
||||
[[package]]
|
||||
name = "brokkr-daemon"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.150"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"brokkr-daemon"
|
||||
]
|
||||
|
||||
44
README.md
Normal file
44
README.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Brokkr
|
||||
|
||||
Brokkr is the GameCult creative-tool broker daemon: a CultMesh service that lets
|
||||
Unity, Blender, and future editor runtimes expose their live authoring surfaces
|
||||
to the Verse without pretending those runtimes are the same machine.
|
||||
|
||||
The name earns its keep twice. Brokkr is the dwarf at the forge bellows in the
|
||||
Eddic treasure contest, holding the work steady while the artifact takes shape.
|
||||
Brokkr is also the broker: the daemon that routes typed editor observations,
|
||||
capabilities, commands, and Eve/CultUI surfaces between tool runtimes and the
|
||||
Verse.
|
||||
|
||||
## Authority
|
||||
|
||||
- Brokkr owns the broker contract, provider advertisement, routing policy, and
|
||||
typed command receipts.
|
||||
- Unity owns Unity editor truth: scenes, assets, selection, play mode, imports,
|
||||
build settings, and editor-side side effects.
|
||||
- Blender owns Blender editor truth: scenes, objects, assets, operators, add-ons,
|
||||
render settings, and editor-side side effects.
|
||||
- Eve owns rendering of Brokkr surfaces.
|
||||
- Odin owns discovery of Brokkr as a Verse provider.
|
||||
- CultCache owns durable `.cc` witnesses and command receipts.
|
||||
|
||||
Plugins are adapters. They do not own Verse state. They connect their host editor
|
||||
to Brokkr, publish editor observations, and execute admitted commands from the
|
||||
broker.
|
||||
|
||||
## Surfaces
|
||||
|
||||
- `surfaces/unity/Packages/com.gamecult.brokkr`: Unity editor package scaffold.
|
||||
- `surfaces/blender/brokkr_bridge`: Blender add-on scaffold.
|
||||
- `brokkr-daemon`: Rust daemon skeleton that emits Brokkr's provider
|
||||
advertisement and command policy.
|
||||
|
||||
## First Smoke
|
||||
|
||||
```powershell
|
||||
cargo run -p brokkr-daemon -- provider
|
||||
```
|
||||
|
||||
The first smoke prints the typed provider advertisement. That is deliberately
|
||||
small: discovery shape first, live sockets second.
|
||||
|
||||
11
brokkr-daemon/Cargo.toml
Normal file
11
brokkr-daemon/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "brokkr-daemon"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
||||
170
brokkr-daemon/src/main.rs
Normal file
170
brokkr-daemon/src/main.rs
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
use anyhow::Result;
|
||||
use serde::Serialize;
|
||||
|
||||
const PROVIDER_SCHEMA: &str = "gamecult.brokkr.provider_advertisement.v0";
|
||||
const PROVIDER_ID: &str = "brokkr.creative_tool_broker";
|
||||
const CULTMESH_BASE_URI: &str = "cultmesh://brokkr";
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct ProviderAdvertisement {
|
||||
schema: &'static str,
|
||||
provider: ProviderIdentity,
|
||||
authority: Authority,
|
||||
transports: Vec<Transport>,
|
||||
tool_surfaces: Vec<ToolSurface>,
|
||||
eve_surfaces: Vec<EveSurface>,
|
||||
command_policy: CommandPolicy,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct ProviderIdentity {
|
||||
id: &'static str,
|
||||
title: &'static str,
|
||||
description: &'static str,
|
||||
version: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Authority {
|
||||
owner: &'static str,
|
||||
role: &'static str,
|
||||
state_owner: &'static str,
|
||||
presentation_owner: &'static str,
|
||||
discovery_owner: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Transport {
|
||||
kind: &'static str,
|
||||
base_uri: &'static str,
|
||||
status: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct ToolSurface {
|
||||
id: &'static str,
|
||||
title: &'static str,
|
||||
tool_kind: &'static str,
|
||||
adapter: &'static str,
|
||||
capabilities: Vec<&'static str>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct EveSurface {
|
||||
id: &'static str,
|
||||
title: &'static str,
|
||||
cult_mesh_uri: &'static str,
|
||||
schema: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct CommandPolicy {
|
||||
mode: &'static str,
|
||||
envelope_schema: &'static str,
|
||||
receipt_schema: &'static str,
|
||||
notes: Vec<&'static str>,
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let command = std::env::args()
|
||||
.nth(1)
|
||||
.unwrap_or_else(|| "provider".to_string());
|
||||
|
||||
match command.as_str() {
|
||||
"provider" => print_provider(),
|
||||
"smoke" => print_provider(),
|
||||
_ => {
|
||||
eprintln!("usage: brokkr-daemon [provider|smoke]");
|
||||
std::process::exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_provider() -> Result<()> {
|
||||
let advertisement = build_provider_advertisement();
|
||||
println!("{}", serde_json::to_string_pretty(&advertisement)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_provider_advertisement() -> ProviderAdvertisement {
|
||||
ProviderAdvertisement {
|
||||
schema: PROVIDER_SCHEMA,
|
||||
provider: ProviderIdentity {
|
||||
id: PROVIDER_ID,
|
||||
title: "Brokkr",
|
||||
description: "GameCult creative-tool broker for Unity, Blender, and future editor runtimes.",
|
||||
version: env!("CARGO_PKG_VERSION"),
|
||||
},
|
||||
authority: Authority {
|
||||
owner: "Brokkr",
|
||||
role: "CultMesh broker for creative editor observations, command admission, receipts, and Eve/CultUI projection.",
|
||||
state_owner: "Brokkr typed CultCache witnesses; host editors own host-local scene and asset truth.",
|
||||
presentation_owner: "Eve/CultUI lowers Brokkr surfaces without owning editor truth.",
|
||||
discovery_owner: "Odin discovers Brokkr through CultMesh provider advertisements.",
|
||||
},
|
||||
transports: vec![Transport {
|
||||
kind: "cultmesh",
|
||||
base_uri: CULTMESH_BASE_URI,
|
||||
status: "scaffold",
|
||||
}],
|
||||
tool_surfaces: vec![
|
||||
ToolSurface {
|
||||
id: "brokkr.unity_editor",
|
||||
title: "Unity Editor",
|
||||
tool_kind: "unity-editor",
|
||||
adapter: "surfaces/unity/Packages/com.gamecult.brokkr",
|
||||
capabilities: shared_capabilities(),
|
||||
},
|
||||
ToolSurface {
|
||||
id: "brokkr.blender_editor",
|
||||
title: "Blender Editor",
|
||||
tool_kind: "blender-editor",
|
||||
adapter: "surfaces/blender/brokkr_bridge",
|
||||
capabilities: shared_capabilities(),
|
||||
},
|
||||
],
|
||||
eve_surfaces: vec![
|
||||
EveSurface {
|
||||
id: "brokkr.eve.tool_broker.v0",
|
||||
title: "Creative Tool Broker",
|
||||
cult_mesh_uri: "cultmesh://brokkr/eve/tool-broker",
|
||||
schema: "gamecult.eve.surface.v1",
|
||||
},
|
||||
EveSurface {
|
||||
id: "brokkr.eve.command_receipts.v0",
|
||||
title: "Command Receipts",
|
||||
cult_mesh_uri: "cultmesh://brokkr/eve/command-receipts",
|
||||
schema: "gamecult.eve.surface.v1",
|
||||
},
|
||||
],
|
||||
command_policy: CommandPolicy {
|
||||
mode: "policy-gated",
|
||||
envelope_schema: "gamecult.brokkr.command_request.v0",
|
||||
receipt_schema: "gamecult.brokkr.command_receipt.v0",
|
||||
notes: vec![
|
||||
"Plugins are adapters and do not own Verse provider truth.",
|
||||
"All host mutations must produce command receipts.",
|
||||
"Unity and Blender commands share one envelope shape.",
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn shared_capabilities() -> Vec<&'static str> {
|
||||
vec![
|
||||
"host.status.read",
|
||||
"scene.tree.read",
|
||||
"selection.read",
|
||||
"asset.catalog.read",
|
||||
"command.palette.read",
|
||||
"command.execute",
|
||||
"receipt.read",
|
||||
]
|
||||
}
|
||||
86
docs/architecture.md
Normal file
86
docs/architecture.md
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
# Brokkr Architecture
|
||||
|
||||
## Objective
|
||||
|
||||
Expose creative editor runtimes to the Verse through one coherent CultMesh broker
|
||||
daemon, beginning with Unity and Blender plugin surfaces.
|
||||
|
||||
## Current Mechanism
|
||||
|
||||
Brokkr starts as a Rust daemon skeleton that can emit a provider advertisement.
|
||||
Unity and Blender each have a thin plugin scaffold with host-local metadata and
|
||||
connection settings. The live transport is intentionally not claimed yet; the
|
||||
first contract establishes owner, inputs, outputs, command policy, and surface
|
||||
names.
|
||||
|
||||
## Invariants
|
||||
|
||||
- Editor hosts keep editor truth. Brokkr never becomes the canonical scene,
|
||||
asset, object, import, or build database.
|
||||
- Brokkr owns Verse-facing broker identity, command admission, routing receipts,
|
||||
and durable witness publication.
|
||||
- Unity and Blender commands share the same command envelope and receipt shape.
|
||||
- Eve/CultUI surfaces are projections over Brokkr/provider state and host
|
||||
observations, not separate dashboards with their own truth.
|
||||
- JSON is tolerated only as a schema/debug/export boundary. Durable state should
|
||||
become CultCache `.cc` witnesses as the runtime grows.
|
||||
|
||||
## Intended Change
|
||||
|
||||
The Unity idea is widened into a general creative-tool broker: Unity and Blender
|
||||
are peers behind one broker contract. Tool-specific plugins stay boring and
|
||||
replaceable. Brokkr becomes the stable Verse organ.
|
||||
|
||||
## Cut Line
|
||||
|
||||
Do not build separate Unity and Blender Verse providers unless a future invariant
|
||||
proves they need independent authority. Do not give plugins their own discovery
|
||||
truth, command policy, or dashboard summaries. They delegate to Brokkr.
|
||||
|
||||
## Owner Map
|
||||
|
||||
Owner: Brokkr owns tool-to-Verse brokerage.
|
||||
|
||||
Inputs:
|
||||
|
||||
- Host observations from Unity and Blender plugins.
|
||||
- Operator commands admitted through Brokkr's command policy.
|
||||
- Odin discovery queries.
|
||||
- Eve/CultUI surface requests.
|
||||
- CultCache witness stores.
|
||||
|
||||
Outputs:
|
||||
|
||||
- `gamecult.brokkr.provider_advertisement.v0`
|
||||
- `gamecult.brokkr.tool_host_snapshot.v0`
|
||||
- `gamecult.brokkr.command_request.v0`
|
||||
- `gamecult.brokkr.command_receipt.v0`
|
||||
- Eve/CultUI surface documents for host status, selection, assets, scene/object
|
||||
trees, command palette, and receipt history.
|
||||
|
||||
Derived State:
|
||||
|
||||
- Unity package settings are adapter configuration, not Verse authority.
|
||||
- Blender add-on preferences are adapter configuration, not Verse authority.
|
||||
- Editor selection and scene summaries are observations until command receipts
|
||||
confirm an accepted mutation.
|
||||
|
||||
Forbidden Writers:
|
||||
|
||||
- Unity editor callbacks cannot write Verse provider truth directly.
|
||||
- Blender operators cannot write Verse provider truth directly.
|
||||
- Eve renderers cannot admit commands directly to editor hosts.
|
||||
- Odin discovery records cannot decide command permissions.
|
||||
|
||||
Shared Paths:
|
||||
|
||||
- Unity commands, Blender commands, programmatic commands, UI-triggered commands,
|
||||
and replayed command receipts must use the same command envelope.
|
||||
- Host snapshots from all tools must carry host id, tool kind, project path,
|
||||
observed-at timestamp, capabilities, and authority owner.
|
||||
|
||||
Deletion Line:
|
||||
|
||||
If a plugin grows its own command policy, provider advertisement, or durable
|
||||
state ledger, cut it back into an adapter and move the authority into Brokkr.
|
||||
|
||||
27
docs/provider-contract.md
Normal file
27
docs/provider-contract.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Brokkr Provider Contract
|
||||
|
||||
Provider id: `brokkr.creative_tool_broker`
|
||||
|
||||
CultMesh base URI: `cultmesh://brokkr`
|
||||
|
||||
Primary Eve surface id: `brokkr.eve.tool_broker.v0`
|
||||
|
||||
## Tool Kinds
|
||||
|
||||
- `unity-editor`
|
||||
- `blender-editor`
|
||||
|
||||
## Capability Families
|
||||
|
||||
- `host.status.read`
|
||||
- `scene.tree.read`
|
||||
- `selection.read`
|
||||
- `asset.catalog.read`
|
||||
- `command.palette.read`
|
||||
- `command.execute`
|
||||
- `receipt.read`
|
||||
|
||||
The scaffold advertises command execution as policy-gated. No host command
|
||||
should execute unless the host plugin recognizes the command family and Brokkr
|
||||
has issued a command request with a receipt id.
|
||||
|
||||
17
schemas/brokkr-provider-advertisement.v0.schema.json
Normal file
17
schemas/brokkr-provider-advertisement.v0.schema.json
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "gamecult.brokkr.provider_advertisement.v0",
|
||||
"title": "Brokkr Provider Advertisement",
|
||||
"type": "object",
|
||||
"required": ["schema", "provider", "authority", "transports", "toolSurfaces", "eveSurfaces", "commandPolicy"],
|
||||
"properties": {
|
||||
"schema": { "const": "gamecult.brokkr.provider_advertisement.v0" },
|
||||
"provider": { "type": "object" },
|
||||
"authority": { "type": "object" },
|
||||
"transports": { "type": "array" },
|
||||
"toolSurfaces": { "type": "array" },
|
||||
"eveSurfaces": { "type": "array" },
|
||||
"commandPolicy": { "type": "object" }
|
||||
}
|
||||
}
|
||||
|
||||
80
surfaces/blender/brokkr_bridge/__init__.py
Normal file
80
surfaces/blender/brokkr_bridge/__init__.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
bl_info = {
|
||||
"name": "Brokkr",
|
||||
"author": "GameCult",
|
||||
"version": (0, 1, 0),
|
||||
"blender": (4, 0, 0),
|
||||
"location": "View3D > Sidebar > Brokkr",
|
||||
"description": "Blender adapter for the Brokkr CultMesh creative-tool broker.",
|
||||
"category": "System",
|
||||
}
|
||||
|
||||
import bpy
|
||||
|
||||
PROVIDER_ID = "brokkr.blender_editor"
|
||||
TOOL_KIND = "blender-editor"
|
||||
DEFAULT_BROKER_URI = "cultmesh://brokkr"
|
||||
|
||||
|
||||
class BrokkrPreferences(bpy.types.AddonPreferences):
|
||||
bl_idname = __name__
|
||||
|
||||
broker_uri: bpy.props.StringProperty(
|
||||
name="Broker URI",
|
||||
default=DEFAULT_BROKER_URI,
|
||||
description="CultMesh broker URI for Brokkr",
|
||||
)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.prop(self, "broker_uri")
|
||||
|
||||
|
||||
class BROKKR_PT_status(bpy.types.Panel):
|
||||
bl_label = "Brokkr"
|
||||
bl_idname = "BROKKR_PT_status"
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_region_type = "UI"
|
||||
bl_category = "Brokkr"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
prefs = context.preferences.addons[__name__].preferences
|
||||
layout.label(text=f"Provider: {PROVIDER_ID}")
|
||||
layout.label(text=f"Tool Kind: {TOOL_KIND}")
|
||||
layout.label(text=f"Broker: {prefs.broker_uri}")
|
||||
layout.operator("brokkr.capture_snapshot")
|
||||
|
||||
|
||||
class BROKKR_OT_capture_snapshot(bpy.types.Operator):
|
||||
bl_idname = "brokkr.capture_snapshot"
|
||||
bl_label = "Capture Host Snapshot"
|
||||
bl_description = "Scaffold command: report the current Blender host snapshot to the console"
|
||||
|
||||
def execute(self, context):
|
||||
snapshot = {
|
||||
"schema": "gamecult.brokkr.tool_host_snapshot.v0",
|
||||
"providerId": PROVIDER_ID,
|
||||
"toolKind": TOOL_KIND,
|
||||
"projectPath": bpy.data.filepath,
|
||||
"scene": context.scene.name if context.scene else "",
|
||||
}
|
||||
print(f"Brokkr snapshot scaffold: {snapshot}")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
classes = (
|
||||
BrokkrPreferences,
|
||||
BROKKR_PT_status,
|
||||
BROKKR_OT_capture_snapshot,
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
|
||||
def unregister():
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
|
||||
10
surfaces/blender/docs/install.md
Normal file
10
surfaces/blender/docs/install.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Blender Add-on Scaffold
|
||||
|
||||
Install `surfaces/blender/brokkr_bridge` as a Blender add-on directory during
|
||||
local development.
|
||||
|
||||
The scaffold adds a Brokkr panel to the 3D View sidebar. It does not open a live
|
||||
transport yet. Its first job is to preserve the adapter boundary: Blender emits
|
||||
host snapshots and executes admitted Brokkr commands; Brokkr owns Verse-facing
|
||||
broker state and receipts.
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
using UnityEditor;
|
||||
|
||||
namespace GameCult.Brokkr.Editor
|
||||
{
|
||||
internal static class BrokkrSettings
|
||||
{
|
||||
internal const string ProviderId = "brokkr.unity_editor";
|
||||
internal const string ToolKind = "unity-editor";
|
||||
internal const string DefaultBrokerUri = "cultmesh://brokkr";
|
||||
|
||||
internal static string BrokerUri
|
||||
{
|
||||
get => EditorPrefs.GetString("GameCult.Brokkr.BrokerUri", DefaultBrokerUri);
|
||||
set => EditorPrefs.SetString("GameCult.Brokkr.BrokerUri", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameCult.Brokkr.Editor
|
||||
{
|
||||
public sealed class BrokkrWindow : EditorWindow
|
||||
{
|
||||
private string brokerUri = BrokkrSettings.DefaultBrokerUri;
|
||||
|
||||
[MenuItem("GameCult/Brokkr")]
|
||||
public static void Open()
|
||||
{
|
||||
GetWindow<BrokkrWindow>("Brokkr");
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
brokerUri = BrokkrSettings.BrokerUri;
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
EditorGUILayout.LabelField("Provider", BrokkrSettings.ProviderId);
|
||||
EditorGUILayout.LabelField("Tool Kind", BrokkrSettings.ToolKind);
|
||||
brokerUri = EditorGUILayout.TextField("Broker URI", brokerUri);
|
||||
|
||||
if (GUILayout.Button("Save Settings"))
|
||||
{
|
||||
BrokkrSettings.BrokerUri = brokerUri;
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.HelpBox(
|
||||
"Scaffold only: this adapter should publish Unity editor observations to Brokkr and execute admitted broker commands with receipts.",
|
||||
MessageType.Info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
|
||||
namespace GameCult.Brokkr
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class BrokkrHostSnapshot
|
||||
{
|
||||
public string schema = "gamecult.brokkr.tool_host_snapshot.v0";
|
||||
public string providerId = "brokkr.unity_editor";
|
||||
public string toolKind = "unity-editor";
|
||||
public string projectPath = "";
|
||||
public string observedAt = "";
|
||||
}
|
||||
}
|
||||
|
||||
11
surfaces/unity/Packages/com.gamecult.brokkr/package.json
Normal file
11
surfaces/unity/Packages/com.gamecult.brokkr/package.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "com.gamecult.brokkr",
|
||||
"version": "0.1.0",
|
||||
"displayName": "Brokkr",
|
||||
"description": "Unity Editor adapter for the Brokkr CultMesh creative-tool broker.",
|
||||
"unity": "2022.3",
|
||||
"author": {
|
||||
"name": "GameCult"
|
||||
}
|
||||
}
|
||||
|
||||
12
tools/check.ps1
Normal file
12
tools/check.ps1
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
$ErrorActionPreference = "Stop"
|
||||
|
||||
Push-Location (Split-Path -Parent $PSScriptRoot)
|
||||
try {
|
||||
cargo fmt --check
|
||||
cargo test --workspace
|
||||
cargo run -p brokkr-daemon -- provider | Out-Null
|
||||
}
|
||||
finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
Loading…
Reference in a new issue