opencroc 1.8.2 → 1.8.4

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 (45) hide show
  1. package/README.md +383 -417
  2. package/package.json +1 -1
  3. package/dist/web/index.html +0 -12
  4. package/dist/web/public/botreview/char_0.png +0 -0
  5. package/dist/web/public/botreview/char_1.png +0 -0
  6. package/dist/web/public/botreview/char_2.png +0 -0
  7. package/dist/web/public/botreview/coffee-machine.gif +0 -0
  8. package/dist/web/public/botreview/server.gif +0 -0
  9. package/dist/web/public/botreview/walls.png +0 -0
  10. package/dist/web/public/star/desk-v3.webp +0 -0
  11. package/dist/web/public/star/office_bg_small.webp +0 -0
  12. package/dist/web/public/star/star-idle-v5.png +0 -0
  13. package/dist/web/public/star/star-working-spritesheet-grid.webp +0 -0
  14. package/dist/web/src/app/AppLayout.tsx +0 -34
  15. package/dist/web/src/app/AppRouter.tsx +0 -46
  16. package/dist/web/src/app/bootstrap.tsx +0 -22
  17. package/dist/web/src/app/routes.tsx +0 -52
  18. package/dist/web/src/features/office/runtime/index.ts +0 -1
  19. package/dist/web/src/features/office/runtime/mount.ts +0 -809
  20. package/dist/web/src/features/pixel/runtime/index.ts +0 -1
  21. package/dist/web/src/features/pixel/runtime/mount.ts +0 -728
  22. package/dist/web/src/features/studio/runtime/index.ts +0 -1
  23. package/dist/web/src/features/studio/runtime/mount.ts +0 -664
  24. package/dist/web/src/features/three/engine/index.ts +0 -1
  25. package/dist/web/src/main.tsx +0 -7
  26. package/dist/web/src/pages/office/index.ts +0 -1
  27. package/dist/web/src/pages/office/page.tsx +0 -283
  28. package/dist/web/src/pages/pixel/index.ts +0 -1
  29. package/dist/web/src/pages/pixel/page.tsx +0 -564
  30. package/dist/web/src/pages/studio/index.ts +0 -1
  31. package/dist/web/src/pages/studio/page.tsx +0 -446
  32. package/dist/web/src/runtime/agents.ts +0 -738
  33. package/dist/web/src/runtime/camera.ts +0 -132
  34. package/dist/web/src/runtime/dataviz.ts +0 -312
  35. package/dist/web/src/runtime/effects.ts +0 -482
  36. package/dist/web/src/runtime/engine.ts +0 -528
  37. package/dist/web/src/runtime/office.ts +0 -932
  38. package/dist/web/src/runtime/state.ts +0 -37
  39. package/dist/web/src/runtime/ui.ts +0 -388
  40. package/dist/web/src/shared/assets.ts +0 -4
  41. package/dist/web/src/shared/navigation.ts +0 -47
  42. package/dist/web/src/styles/app-layout.css +0 -19
  43. package/dist/web/src/styles/office.css +0 -268
  44. package/dist/web/tsconfig.json +0 -28
  45. package/dist/web/vite.config.ts +0 -93
@@ -1,132 +0,0 @@
1
- /* ═══════════════════════════════════════════════════════════════════════════════
2
- OpenCroc Studio 3D — Camera Controller
3
- Orbit controls, fly-to transitions, auto-rotate
4
- ~1000 lines
5
- ═══════════════════════════════════════════════════════════════════════════════ */
6
-
7
- import * as THREE from 'three';
8
- import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
9
-
10
- /* ═══════════════════════════════════════════════════════════════════════════════
11
- Camera Presets
12
- ═══════════════════════════════════════════════════════════════════════════════ */
13
- const PRESETS = {
14
- office: {
15
- position: new THREE.Vector3(18, 14, 18),
16
- target: new THREE.Vector3(0, 2, 0),
17
- },
18
- graph: {
19
- position: new THREE.Vector3(0, 25, 0.1),
20
- target: new THREE.Vector3(0, 0, 0),
21
- },
22
- closeup: {
23
- position: new THREE.Vector3(5, 4, 8),
24
- target: new THREE.Vector3(0, 2, 0),
25
- },
26
- overview: {
27
- position: new THREE.Vector3(30, 20, 30),
28
- target: new THREE.Vector3(0, 0, 0),
29
- },
30
- };
31
-
32
- /* ═══════════════════════════════════════════════════════════════════════════════
33
- CameraController
34
- ═══════════════════════════════════════════════════════════════════════════════ */
35
- export class CameraController {
36
- constructor(canvas, camera, scene) {
37
- this.camera = camera;
38
- this.scene = scene;
39
- scene.userData.camera = camera; // Store ref for CSS2D renderer
40
-
41
- // Orbit controls
42
- this.controls = new OrbitControls(camera, canvas);
43
- this.controls.enableDamping = true;
44
- this.controls.dampingFactor = 0.08;
45
- this.controls.enablePan = true;
46
- this.controls.panSpeed = 0.8;
47
- this.controls.rotateSpeed = 0.6;
48
- this.controls.zoomSpeed = 1.2;
49
- this.controls.minDistance = 3;
50
- this.controls.maxDistance = 60;
51
- this.controls.maxPolarAngle = Math.PI * 0.48;
52
- this.controls.minPolarAngle = Math.PI * 0.05;
53
- this.controls.target.set(0, 2, 0);
54
- this.controls.autoRotate = true;
55
- this.controls.autoRotateSpeed = 0.3;
56
-
57
- // Fly-to animation state
58
- this._flying = false;
59
- this._flyStart = { pos: new THREE.Vector3(), tgt: new THREE.Vector3() };
60
- this._flyEnd = { pos: new THREE.Vector3(), tgt: new THREE.Vector3() };
61
- this._flyProgress = 0;
62
- this._flyDuration = 1.5;
63
- }
64
-
65
- /** Update each frame */
66
- update(dt) {
67
- if (this._flying) {
68
- this._flyProgress += dt / this._flyDuration;
69
- if (this._flyProgress >= 1) {
70
- this._flyProgress = 1;
71
- this._flying = false;
72
- }
73
-
74
- // Smooth easing (ease-out-expo)
75
- const t = 1 - Math.pow(1 - this._flyProgress, 3);
76
-
77
- this.camera.position.lerpVectors(this._flyStart.pos, this._flyEnd.pos, t);
78
- this.controls.target.lerpVectors(this._flyStart.tgt, this._flyEnd.tgt, t);
79
- }
80
-
81
- this.controls.update();
82
- }
83
-
84
- /** Fly to a named preset or custom position */
85
- flyTo(presetOrTarget, duration = 1.5) {
86
- let target;
87
- if (typeof presetOrTarget === 'string') {
88
- target = PRESETS[presetOrTarget];
89
- if (!target) return;
90
- } else {
91
- target = presetOrTarget;
92
- }
93
-
94
- this._flyStart.pos.copy(this.camera.position);
95
- this._flyStart.tgt.copy(this.controls.target);
96
- this._flyEnd.pos.copy(target.position);
97
- this._flyEnd.tgt.copy(target.target);
98
- this._flyProgress = 0;
99
- this._flyDuration = duration;
100
- this._flying = true;
101
- }
102
-
103
- /** Fly to a specific module in the graph */
104
- flyToModule(x, z) {
105
- this.flyTo({
106
- position: new THREE.Vector3(x + 8, 10, z + 8),
107
- target: new THREE.Vector3(x, 1, z),
108
- });
109
- }
110
-
111
- /** Enable/disable auto rotation */
112
- enableAutoRotate() {
113
- this.controls.autoRotate = true;
114
- this.controls.autoRotateSpeed = 0.3;
115
- }
116
-
117
- disableAutoRotate() {
118
- this.controls.autoRotate = false;
119
- }
120
-
121
- /** Get the raw controls for external use */
122
- getControls() {
123
- return this.controls;
124
- }
125
-
126
- dispose() {
127
- this.controls?.dispose?.();
128
- if (this.scene?.userData?.camera === this.camera) {
129
- delete this.scene.userData.camera;
130
- }
131
- }
132
- }
@@ -1,312 +0,0 @@
1
- /* ═══════════════════════════════════════════════════════════════════════════════
2
- OpenCroc Studio 3D — Data Visualization
3
- 3D graph layout, holographic display
4
- ~2000 lines
5
- ═══════════════════════════════════════════════════════════════════════════════ */
6
-
7
- import * as THREE from 'three';
8
-
9
- function disposeObject3D(object) {
10
- object?.traverse?.((child) => {
11
- child.geometry?.dispose?.();
12
- if (Array.isArray(child.material)) {
13
- child.material.forEach((material) => material?.dispose?.());
14
- } else {
15
- child.material?.dispose?.();
16
- }
17
- });
18
- }
19
-
20
- /* ─── Color Map per module ─────────────────────────────────────────────────── */
21
- const MOD_COLORS = [
22
- 0x34d399, 0x60a5fa, 0xa78bfa, 0xf472b6, 0xfbbf24,
23
- 0x22d3ee, 0xf87171, 0x4ade80, 0x818cf8, 0xfb923c,
24
- 0x38bdf8, 0xc084fc, 0xa3e635, 0xe879f9, 0x2dd4bf,
25
- ];
26
-
27
- function modColor(idx) {
28
- return MOD_COLORS[idx % MOD_COLORS.length];
29
- }
30
-
31
- /* ═══════════════════════════════════════════════════════════════════════════════
32
- GraphViz — 3D Force-directed graph from node/edge data
33
- ═══════════════════════════════════════════════════════════════════════════════ */
34
- export class GraphViz {
35
- constructor(scene) {
36
- this.scene = scene;
37
- this.group = new THREE.Group();
38
- this.group.name = 'graph-viz';
39
- this.group.position.set(0, 8, 0); // Float above office
40
- this.group.visible = false; // Hidden by default (shown via view switch)
41
- scene.add(this.group);
42
-
43
- this._nodes = new Map(); // id → mesh
44
- this._edges = []; // line meshes
45
- this._modules = new Map(); // module → { center, color }
46
- }
47
-
48
- /** Update from backend graph data */
49
- update(graphData) {
50
- if (!graphData || !graphData.nodes) return;
51
-
52
- // Clear existing
53
- while (this.group.children.length > 0) {
54
- const child = this.group.children[0];
55
- this.group.remove(child);
56
- if (child.geometry) child.geometry.dispose();
57
- if (child.material) child.material.dispose();
58
- }
59
- this._nodes.clear();
60
- this._edges = [];
61
- this._modules.clear();
62
-
63
- const { nodes, edges } = graphData;
64
- if (!nodes.length) return;
65
-
66
- // Group nodes by module
67
- const moduleMap = new Map();
68
- nodes.forEach(n => {
69
- const mod = n.module || 'default';
70
- if (!moduleMap.has(mod)) moduleMap.set(mod, []);
71
- moduleMap.get(mod).push(n);
72
- });
73
-
74
- // Layout modules in a circle
75
- const moduleList = [...moduleMap.keys()];
76
- const moduleRadius = Math.max(4, moduleList.length * 1.2);
77
-
78
- moduleList.forEach((mod, mi) => {
79
- const angle = (mi / moduleList.length) * Math.PI * 2;
80
- const mx = Math.cos(angle) * moduleRadius;
81
- const mz = Math.sin(angle) * moduleRadius;
82
- const color = modColor(mi);
83
-
84
- this._modules.set(mod, { x: mx, z: mz, color, idx: mi });
85
-
86
- // Module sphere (ghostly cluster indicator)
87
- const clusterGeo = new THREE.SphereGeometry(1.2, 16, 16);
88
- const clusterMat = new THREE.MeshBasicMaterial({
89
- color, transparent: true, opacity: 0.08, wireframe: true,
90
- });
91
- const cluster = new THREE.Mesh(clusterGeo, clusterMat);
92
- cluster.position.set(mx, 0, mz);
93
- this.group.add(cluster);
94
-
95
- // Layout nodes within module cluster
96
- const moduleNodes = moduleMap.get(mod);
97
- moduleNodes.forEach((n, ni) => {
98
- const nodeAngle = (ni / moduleNodes.length) * Math.PI * 2;
99
- const nr = Math.min(moduleNodes.length * 0.15, 0.9);
100
- const nx = mx + Math.cos(nodeAngle) * nr;
101
- const nz = mz + Math.sin(nodeAngle) * nr;
102
- const ny = Math.sin(ni * 0.5) * 0.3;
103
-
104
- // Node sphere
105
- const nodeGeo = new THREE.SphereGeometry(0.08, 8, 8);
106
- const nodeMat = new THREE.MeshStandardMaterial({
107
- color, emissive: color, emissiveIntensity: 0.3,
108
- roughness: 0.3, metalness: 0.5,
109
- });
110
- const nodeMesh = new THREE.Mesh(nodeGeo, nodeMat);
111
- nodeMesh.position.set(nx, ny, nz);
112
- this.group.add(nodeMesh);
113
- this._nodes.set(n.id, { mesh: nodeMesh, data: n, x: nx, y: ny, z: nz });
114
- });
115
- });
116
-
117
- // Edges
118
- if (edges) {
119
- edges.forEach(e => {
120
- const from = this._nodes.get(e.from || e.source);
121
- const to = this._nodes.get(e.to || e.target);
122
- if (!from || !to) return;
123
-
124
- const points = [
125
- new THREE.Vector3(from.x, from.y, from.z),
126
- new THREE.Vector3(to.x, to.y, to.z),
127
- ];
128
- const lineGeo = new THREE.BufferGeometry().setFromPoints(points);
129
- const lineMat = new THREE.LineBasicMaterial({
130
- color: 0x475569, transparent: true, opacity: 0.3,
131
- });
132
- const line = new THREE.Line(lineGeo, lineMat);
133
- this.group.add(line);
134
- this._edges.push(line);
135
- });
136
- }
137
- }
138
-
139
- /** Show/hide the graph */
140
- show() { this.group.visible = true; }
141
- hide() { this.group.visible = false; }
142
-
143
- dispose() {
144
- this.scene.remove(this.group);
145
- disposeObject3D(this.group);
146
- this._nodes.clear();
147
- this._edges = [];
148
- this._modules.clear();
149
- }
150
- }
151
-
152
- /* ═══════════════════════════════════════════════════════════════════════════════
153
- HologramDisplay — Central floating data display
154
- ═══════════════════════════════════════════════════════════════════════════════ */
155
- export class HologramDisplay {
156
- constructor(scene) {
157
- this.scene = scene;
158
- this.group = new THREE.Group();
159
- this.group.name = 'hologram';
160
- this.group.position.set(0, 2.0, 0);
161
- scene.add(this.group);
162
-
163
- this._time = 0;
164
- this._build();
165
- }
166
-
167
- _build() {
168
- /* ── Main sphere (wireframe data globe) ──────────────────────────────── */
169
- const sphereGeo = new THREE.IcosahedronGeometry(1.0, 2);
170
- const sphereMat = new THREE.MeshBasicMaterial({
171
- color: 0x34d399, wireframe: true, transparent: true, opacity: 0.2,
172
- });
173
- this.sphere = new THREE.Mesh(sphereGeo, sphereMat);
174
- this.group.add(this.sphere);
175
-
176
- /* ── Inner sphere ────────────────────────────────────────────────────── */
177
- const innerGeo = new THREE.IcosahedronGeometry(0.6, 1);
178
- const innerMat = new THREE.MeshBasicMaterial({
179
- color: 0x60a5fa, wireframe: true, transparent: true, opacity: 0.15,
180
- });
181
- this.innerSphere = new THREE.Mesh(innerGeo, innerMat);
182
- this.group.add(this.innerSphere);
183
-
184
- /* ── Core glow ───────────────────────────────────────────────────────── */
185
- const coreGeo = new THREE.SphereGeometry(0.15, 16, 16);
186
- const coreMat = new THREE.MeshBasicMaterial({
187
- color: 0x34d399, transparent: true, opacity: 0.6,
188
- });
189
- this.core = new THREE.Mesh(coreGeo, coreMat);
190
- this.group.add(this.core);
191
-
192
- /* ── Orbiting rings ──────────────────────────────────────────────────── */
193
- const ring1Geo = new THREE.TorusGeometry(1.3, 0.01, 8, 48);
194
- const ring1Mat = new THREE.MeshBasicMaterial({
195
- color: 0x34d399, transparent: true, opacity: 0.3,
196
- });
197
- this.ring1 = new THREE.Mesh(ring1Geo, ring1Mat);
198
- this.ring1.rotation.x = Math.PI / 3;
199
- this.group.add(this.ring1);
200
-
201
- const ring2Geo = new THREE.TorusGeometry(1.5, 0.008, 8, 48);
202
- const ring2Mat = new THREE.MeshBasicMaterial({
203
- color: 0x60a5fa, transparent: true, opacity: 0.2,
204
- });
205
- this.ring2 = new THREE.Mesh(ring2Geo, ring2Mat);
206
- this.ring2.rotation.x = Math.PI / 2;
207
- this.ring2.rotation.z = Math.PI / 4;
208
- this.group.add(this.ring2);
209
-
210
- const ring3Geo = new THREE.TorusGeometry(1.1, 0.008, 8, 48);
211
- const ring3Mat = new THREE.MeshBasicMaterial({
212
- color: 0xa78bfa, transparent: true, opacity: 0.2,
213
- });
214
- this.ring3 = new THREE.Mesh(ring3Geo, ring3Mat);
215
- this.ring3.rotation.x = -Math.PI / 4;
216
- this.ring3.rotation.y = Math.PI / 3;
217
- this.group.add(this.ring3);
218
-
219
- /* ── Floating data points ────────────────────────────────────────────── */
220
- const dataCount = 60;
221
- const dataPositions = new Float32Array(dataCount * 3);
222
- const dataSizes = new Float32Array(dataCount);
223
- const dataColors = new Float32Array(dataCount * 3);
224
-
225
- const palette = [
226
- new THREE.Color(0x34d399), new THREE.Color(0x60a5fa),
227
- new THREE.Color(0xa78bfa), new THREE.Color(0x22d3ee),
228
- ];
229
-
230
- for (let i = 0; i < dataCount; i++) {
231
- const r = 0.8 + Math.random() * 0.5;
232
- const theta = Math.random() * Math.PI * 2;
233
- const phi = Math.random() * Math.PI;
234
- dataPositions[i * 3] = r * Math.sin(phi) * Math.cos(theta);
235
- dataPositions[i * 3 + 1] = r * Math.cos(phi);
236
- dataPositions[i * 3 + 2] = r * Math.sin(phi) * Math.sin(theta);
237
- dataSizes[i] = 0.03 + Math.random() * 0.04;
238
- const c = palette[Math.floor(Math.random() * palette.length)];
239
- dataColors[i * 3] = c.r;
240
- dataColors[i * 3 + 1] = c.g;
241
- dataColors[i * 3 + 2] = c.b;
242
- }
243
-
244
- const dataGeo = new THREE.BufferGeometry();
245
- dataGeo.setAttribute('position', new THREE.BufferAttribute(dataPositions, 3));
246
- dataGeo.setAttribute('color', new THREE.BufferAttribute(dataColors, 3));
247
-
248
- const dataMat = new THREE.PointsMaterial({
249
- size: 0.04, transparent: true, opacity: 0.6,
250
- vertexColors: true, blending: THREE.AdditiveBlending, depthWrite: false,
251
- });
252
-
253
- this.dataPoints = new THREE.Points(dataGeo, dataMat);
254
- this.group.add(this.dataPoints);
255
-
256
- /* ── Hologram point light ────────────────────────────────────────────── */
257
- const holoLight = new THREE.PointLight(0x34d399, 1.0, 8, 2);
258
- holoLight.position.set(0, 0.5, 0);
259
- this.group.add(holoLight);
260
- this.holoLight = holoLight;
261
-
262
- /* ── Scan line effect ────────────────────────────────────────────────── */
263
- const scanGeo = new THREE.PlaneGeometry(2.5, 0.02);
264
- const scanMat = new THREE.MeshBasicMaterial({
265
- color: 0x34d399, transparent: true, opacity: 0.3, side: THREE.DoubleSide,
266
- });
267
- this.scanLine = new THREE.Mesh(scanGeo, scanMat);
268
- this.group.add(this.scanLine);
269
- }
270
-
271
- /** Update each frame */
272
- update(dt, graphData) {
273
- this._time += dt;
274
-
275
- // Rotate elements
276
- this.sphere.rotation.y += dt * 0.15;
277
- this.sphere.rotation.x += dt * 0.05;
278
- this.innerSphere.rotation.y -= dt * 0.2;
279
- this.innerSphere.rotation.z += dt * 0.1;
280
- this.ring1.rotation.y += dt * 0.3;
281
- this.ring2.rotation.y -= dt * 0.2;
282
- this.ring3.rotation.z += dt * 0.25;
283
-
284
- // Core pulse
285
- const pulse = 0.8 + 0.2 * Math.sin(this._time * 3);
286
- this.core.scale.setScalar(pulse);
287
- this.core.material.opacity = 0.4 + 0.3 * Math.sin(this._time * 2);
288
-
289
- // Data points rotation
290
- this.dataPoints.rotation.y += dt * 0.1;
291
-
292
- // Scan line sweeping
293
- this.scanLine.position.y = Math.sin(this._time * 1.0) * 1.2;
294
- this.scanLine.material.opacity = 0.15 + 0.15 * Math.abs(Math.sin(this._time));
295
-
296
- // Light intensity pulse
297
- this.holoLight.intensity = 0.6 + 0.4 * Math.sin(this._time * 2);
298
-
299
- // Update sphere opacity based on data amount
300
- if (graphData && graphData.nodes) {
301
- const nodeCount = graphData.nodes.length;
302
- const t = Math.min(nodeCount / 100, 1);
303
- this.sphere.material.opacity = 0.1 + t * 0.2;
304
- this.innerSphere.material.opacity = 0.08 + t * 0.15;
305
- }
306
- }
307
-
308
- dispose() {
309
- this.scene.remove(this.group);
310
- disposeObject3D(this.group);
311
- }
312
- }