@fps-games/editor 0.2.0-beta.3 → 0.2.0-beta.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 (116) hide show
  1. package/dist/agent-bridge/capabilities/editor-state.d.ts.map +1 -1
  2. package/dist/agent-bridge/capabilities/editor-state.js +26 -17
  3. package/dist/agent-bridge/capabilities/editor-state.js.map +1 -1
  4. package/dist/agent-bridge/capabilities/prefabs.d.ts.map +1 -1
  5. package/dist/agent-bridge/capabilities/prefabs.js +61 -13
  6. package/dist/agent-bridge/capabilities/prefabs.js.map +1 -1
  7. package/dist/agent-bridge/capabilities/scene-objects.d.ts +1 -1
  8. package/dist/agent-bridge/capabilities/scene-objects.d.ts.map +1 -1
  9. package/dist/agent-bridge/capabilities/scene-objects.js +110 -25
  10. package/dist/agent-bridge/capabilities/scene-objects.js.map +1 -1
  11. package/dist/agent-bridge/capabilities/selection.d.ts.map +1 -1
  12. package/dist/agent-bridge/capabilities/selection.js +8 -5
  13. package/dist/agent-bridge/capabilities/selection.js.map +1 -1
  14. package/dist/agent-bridge/capabilities/shadows.d.ts.map +1 -1
  15. package/dist/agent-bridge/capabilities/shadows.js +11 -2
  16. package/dist/agent-bridge/capabilities/shadows.js.map +1 -1
  17. package/dist/agent-bridge/capabilities/transform.d.ts.map +1 -1
  18. package/dist/agent-bridge/capabilities/transform.js +6 -4
  19. package/dist/agent-bridge/capabilities/transform.js.map +1 -1
  20. package/dist/agent-bridge/capabilities/viewport.d.ts.map +1 -1
  21. package/dist/agent-bridge/capabilities/viewport.js +79 -47
  22. package/dist/agent-bridge/capabilities/viewport.js.map +1 -1
  23. package/dist/agent-bridge/shared.d.ts +8 -3
  24. package/dist/agent-bridge/shared.d.ts.map +1 -1
  25. package/dist/agent-bridge/shared.js +32 -0
  26. package/dist/agent-bridge/shared.js.map +1 -1
  27. package/dist/build-info.json +34 -34
  28. package/dist/local-editor-agent-actions.d.ts.map +1 -1
  29. package/dist/local-editor-agent-actions.js +9 -5
  30. package/dist/local-editor-agent-actions.js.map +1 -1
  31. package/dist/local-editor-harness.d.ts.map +1 -1
  32. package/dist/local-editor-harness.js +264 -41
  33. package/dist/local-editor-harness.js.map +1 -1
  34. package/node_modules/@fps-games/babylon-renderer/package.json +7 -7
  35. package/node_modules/@fps-games/editor-babylon/package.json +5 -5
  36. package/node_modules/@fps-games/editor-browser/dist/index.d.ts +3 -1
  37. package/node_modules/@fps-games/editor-browser/dist/index.d.ts.map +1 -1
  38. package/node_modules/@fps-games/editor-browser/dist/index.js +2 -0
  39. package/node_modules/@fps-games/editor-browser/dist/index.js.map +1 -1
  40. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts +2 -1
  41. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts.map +1 -1
  42. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js +260 -94
  43. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js.map +1 -1
  44. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-projection.d.ts +7 -0
  45. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-projection.d.ts.map +1 -0
  46. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-projection.js +186 -0
  47. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-projection.js.map +1 -0
  48. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.d.ts +2 -2
  49. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.d.ts.map +1 -1
  50. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.js +14 -8
  51. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.js.map +1 -1
  52. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts.map +1 -1
  53. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.js +23 -7
  54. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.js.map +1 -1
  55. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts +1 -1
  56. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts.map +1 -1
  57. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js +6 -0
  58. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js.map +1 -1
  59. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.d.ts +3 -0
  60. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.d.ts.map +1 -1
  61. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.js +60 -13
  62. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.js.map +1 -1
  63. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-status-diagnostics.d.ts +24 -0
  64. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-status-diagnostics.d.ts.map +1 -0
  65. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-status-diagnostics.js +69 -0
  66. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-status-diagnostics.js.map +1 -0
  67. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts +58 -14
  68. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts.map +1 -1
  69. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.js.map +1 -1
  70. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts +1 -1
  71. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts.map +1 -1
  72. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js +196 -11
  73. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js.map +1 -1
  74. package/node_modules/@fps-games/editor-browser/package.json +4 -4
  75. package/node_modules/@fps-games/editor-core/dist/editor-session.d.ts +3 -0
  76. package/node_modules/@fps-games/editor-core/dist/editor-session.d.ts.map +1 -1
  77. package/node_modules/@fps-games/editor-core/dist/editor-session.js +9 -0
  78. package/node_modules/@fps-games/editor-core/dist/editor-session.js.map +1 -1
  79. package/node_modules/@fps-games/editor-core/package.json +6 -6
  80. package/node_modules/@fps-games/editor-forge-play/package.json +2 -2
  81. package/node_modules/@fps-games/editor-playable-sdk/package.json +6 -6
  82. package/node_modules/@fps-games/editor-protocol/package.json +2 -2
  83. package/node_modules/@fps-games/editor-tooling/package.json +3 -3
  84. package/node_modules/@fps-games/playable-assets/package.json +1 -1
  85. package/node_modules/@fps-games/playable-contracts/package.json +1 -1
  86. package/node_modules/@fps-games/playable-rendering/package.json +2 -2
  87. package/node_modules/@fps-games/playable-runtime/package.json +12 -12
  88. package/node_modules/@fps-games/playable-runtime-data/package.json +4 -4
  89. package/node_modules/@fps-games/playable-scene/package.json +2 -2
  90. package/node_modules/@fps-games/plugin-api/package.json +1 -1
  91. package/node_modules/@fps-games/plugin-assets/dist/version.d.ts +1 -1
  92. package/node_modules/@fps-games/plugin-assets/dist/version.js +1 -1
  93. package/node_modules/@fps-games/plugin-assets/dist/version.js.map +1 -1
  94. package/node_modules/@fps-games/plugin-assets/package.json +5 -5
  95. package/node_modules/@fps-games/plugin-host/package.json +2 -2
  96. package/node_modules/@fps-games/plugin-markers/dist/version.d.ts +1 -1
  97. package/node_modules/@fps-games/plugin-markers/dist/version.js +1 -1
  98. package/node_modules/@fps-games/plugin-markers/dist/version.js.map +1 -1
  99. package/node_modules/@fps-games/plugin-markers/package.json +5 -5
  100. package/node_modules/@fps-games/plugin-materials/dist/version.d.ts +1 -1
  101. package/node_modules/@fps-games/plugin-materials/dist/version.js +1 -1
  102. package/node_modules/@fps-games/plugin-materials/dist/version.js.map +1 -1
  103. package/node_modules/@fps-games/plugin-materials/package.json +5 -5
  104. package/node_modules/@fps-games/plugin-rendering/dist/version.d.ts +1 -1
  105. package/node_modules/@fps-games/plugin-rendering/dist/version.js +1 -1
  106. package/node_modules/@fps-games/plugin-rendering/dist/version.js.map +1 -1
  107. package/node_modules/@fps-games/plugin-rendering/package.json +5 -5
  108. package/node_modules/@fps-games/plugin-scene/dist/version.d.ts +1 -1
  109. package/node_modules/@fps-games/plugin-scene/dist/version.js +1 -1
  110. package/node_modules/@fps-games/plugin-scene/dist/version.js.map +1 -1
  111. package/node_modules/@fps-games/plugin-scene/package.json +5 -5
  112. package/node_modules/@fps-games/plugin-shadows/dist/version.d.ts +1 -1
  113. package/node_modules/@fps-games/plugin-shadows/dist/version.js +1 -1
  114. package/node_modules/@fps-games/plugin-shadows/dist/version.js.map +1 -1
  115. package/node_modules/@fps-games/plugin-shadows/package.json +7 -7
  116. package/package.json +19 -19
@@ -1 +1 @@
1
- {"version":3,"file":"editor-state.d.ts","sourceRoot":"","sources":["../../../src/agent-bridge/capabilities/editor-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAGL,KAAK,gDAAgD,EACrD,KAAK,kCAAkC,EACxC,MAAM,cAAc,CAAC;AAKtB,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAK/E,wBAAgB,uCAAuC,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAC/E,KAAK,EAAE,kCAAkC,CAAC,SAAS,EAAE,MAAM,CAAC,EAC5D,OAAO,EAAE,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7D,UAAU,EAAE,gDAAgD,CAAC,SAAS,CAAC,GACtE,iCAAiC,CASnC"}
1
+ {"version":3,"file":"editor-state.d.ts","sourceRoot":"","sources":["../../../src/agent-bridge/capabilities/editor-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAIL,KAAK,gDAAgD,EACrD,KAAK,kCAAkC,EACxC,MAAM,cAAc,CAAC;AAKtB,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAK/E,wBAAgB,uCAAuC,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAC/E,KAAK,EAAE,kCAAkC,CAAC,SAAS,EAAE,MAAM,CAAC,EAC5D,OAAO,EAAE,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7D,UAAU,EAAE,gDAAgD,CAAC,SAAS,CAAC,GACtE,iCAAiC,CASnC"}
@@ -1,11 +1,11 @@
1
- import { cloneAgentBridgeSelection, EMPTY_EDITOR_SELECTION, } from '../shared.js';
1
+ import { cloneAgentBridgeSelection, getAgentBridgeSafeSceneHierarchy, getAgentBridgeSafeSceneSelection, } from '../shared.js';
2
2
  import { createAgentBridgeSceneObject, listAgentBridgeSceneObjects, } from './scene-objects.js';
3
3
  const AGENT_BRIDGE_SNAPSHOT_DEFAULT_OBJECT_LIMIT = 100;
4
4
  const AGENT_BRIDGE_SNAPSHOT_MAX_OBJECT_LIMIT = 500;
5
5
  export function createLocalEditorAgentBridgeStateSource(state, options, operations) {
6
6
  return {
7
7
  getSnapshot(input) {
8
- return createAgentBridgeEditorSnapshot(state, options, input);
8
+ return createAgentBridgeEditorSnapshot(state, options, input, operations);
9
9
  },
10
10
  getState(input) {
11
11
  return createAgentBridgeEditorState(state, options, input.objectId, operations);
@@ -15,11 +15,12 @@ export function createLocalEditorAgentBridgeStateSource(state, options, operatio
15
15
  function createAgentBridgeEditorState(state, options, objectId, operations) {
16
16
  const sessionState = state.session?.getState({ cloneDocuments: false }) ?? null;
17
17
  const document = sessionState?.workingDocument ?? null;
18
+ const safeSelection = getAgentBridgeSafeSceneSelection(operations);
18
19
  const requestedObjectId = typeof objectId === 'string' && objectId.trim()
19
20
  ? objectId.trim()
20
- : sessionState?.selection.activeId ?? undefined;
21
+ : safeSelection.activeId ?? undefined;
21
22
  const object = document && requestedObjectId
22
- ? createAgentBridgeSceneObject(state, options, document, requestedObjectId, operations.getHierarchy())
23
+ ? createAgentBridgeSceneObject(state, options, document, requestedObjectId, getAgentBridgeSafeSceneHierarchy(operations))
23
24
  : null;
24
25
  return {
25
26
  mode: state.mode,
@@ -28,16 +29,17 @@ function createAgentBridgeEditorState(state, options, objectId, operations) {
28
29
  statusDetails: state.statusDetails,
29
30
  dirty: sessionState?.dirty,
30
31
  busy: state.busy,
31
- selection: cloneAgentBridgeSelection(sessionState?.selection ?? EMPTY_EDITOR_SELECTION),
32
+ selection: cloneAgentBridgeSelection(safeSelection),
32
33
  object,
33
- diagnostics: createAgentBridgeStateDiagnostics(state),
34
+ diagnostics: createAgentBridgeStateDiagnostics(state, operations),
34
35
  };
35
36
  }
36
- function createAgentBridgeEditorSnapshot(state, options, input) {
37
+ function createAgentBridgeEditorSnapshot(state, options, input, operations) {
37
38
  const sessionState = state.session?.getState({ cloneDocuments: false }) ?? null;
38
39
  const document = sessionState?.workingDocument ?? null;
40
+ const safeSelection = getAgentBridgeSafeSceneSelection(operations);
39
41
  const objects = state.mode === 'editor' && document
40
- ? listAgentBridgeSceneObjects(state, options, document, input.includeUnselectable === true)
42
+ ? listAgentBridgeSceneObjects(state, options, document, input.includeUnselectable === true, operations)
41
43
  : [];
42
44
  const snapshot = {
43
45
  mode: state.mode,
@@ -45,7 +47,7 @@ function createAgentBridgeEditorSnapshot(state, options, input) {
45
47
  dirty: sessionState?.dirty ?? false,
46
48
  status: state.status,
47
49
  statusTone: state.statusTone,
48
- selection: cloneAgentBridgeSelection(sessionState?.selection ?? EMPTY_EDITOR_SELECTION),
50
+ selection: cloneAgentBridgeSelection(safeSelection),
49
51
  objectCount: objects.length,
50
52
  };
51
53
  if (input.includeObjects === true) {
@@ -53,14 +55,21 @@ function createAgentBridgeEditorSnapshot(state, options, input) {
53
55
  }
54
56
  return snapshot;
55
57
  }
56
- function createAgentBridgeStateDiagnostics(state) {
57
- if (state.statusTone !== 'error' && state.statusTone !== 'warning')
58
- return [];
59
- return [{
60
- severity: state.statusTone,
61
- source: 'editor',
62
- message: state.statusDetails || state.status,
63
- }];
58
+ function createAgentBridgeStateDiagnostics(state, operations) {
59
+ return operations.getStatusDiagnostics().map(diagnostic => ({
60
+ severity: diagnostic.severity,
61
+ source: diagnostic.source,
62
+ code: diagnostic.code,
63
+ message: diagnostic.message,
64
+ ...(diagnostic.rowId ? { objectId: diagnostic.rowId } : {}),
65
+ details: {
66
+ ...(diagnostic.scopeId ? { scopeId: diagnostic.scopeId } : {}),
67
+ ...(diagnostic.targetId ? { targetId: diagnostic.targetId } : {}),
68
+ ...(diagnostic.documentRevision != null ? { documentRevision: diagnostic.documentRevision } : {}),
69
+ ...(diagnostic.projectionRevision != null ? { projectionRevision: diagnostic.projectionRevision } : {}),
70
+ ...(diagnostic.details ?? {}),
71
+ },
72
+ }));
64
73
  }
65
74
  function normalizeAgentBridgeSnapshotObjectLimit(value) {
66
75
  if (value === undefined)
@@ -1 +1 @@
1
- {"version":3,"file":"editor-state.js","sourceRoot":"","sources":["../../../src/agent-bridge/capabilities/editor-state.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n EditorAgentBridgeEditorSnapshot,\n EditorAgentBridgeEditorSnapshotGetInput,\n EditorAgentBridgeEditorState,\n} from '@fps-games/editor-protocol';\nimport type { LocalEditorAgentBridgeStateSource } from '../source-types.js';\nimport {\n cloneAgentBridgeSelection,\n EMPTY_EDITOR_SELECTION,\n type LocalEditorAgentBridgeCapabilitySourceOperations,\n type LocalEditorAgentBridgeHarnessState,\n} from '../shared.js';\nimport {\n createAgentBridgeSceneObject,\n listAgentBridgeSceneObjects,\n} from './scene-objects.js';\nimport type { LocalEditorHarnessOptions } from '../../local-editor-harness.js';\n\nconst AGENT_BRIDGE_SNAPSHOT_DEFAULT_OBJECT_LIMIT = 100;\nconst AGENT_BRIDGE_SNAPSHOT_MAX_OBJECT_LIMIT = 500;\n\nexport function createLocalEditorAgentBridgeStateSource<TDocument, TPatch, TAsset>(\n state: LocalEditorAgentBridgeHarnessState<TDocument, TPatch>,\n options: LocalEditorHarnessOptions<TDocument, TPatch, TAsset>,\n operations: LocalEditorAgentBridgeCapabilitySourceOperations<TDocument>,\n): LocalEditorAgentBridgeStateSource {\n return {\n getSnapshot(input) {\n return createAgentBridgeEditorSnapshot(state, options, input);\n },\n getState(input) {\n return createAgentBridgeEditorState(state, options, input.objectId, operations);\n },\n };\n}\n\nfunction createAgentBridgeEditorState<TDocument, TPatch, TAsset>(\n state: LocalEditorAgentBridgeHarnessState<TDocument, TPatch>,\n options: LocalEditorHarnessOptions<TDocument, TPatch, TAsset>,\n objectId: string | undefined,\n operations: LocalEditorAgentBridgeCapabilitySourceOperations<TDocument>,\n): EditorAgentBridgeEditorState {\n const sessionState = state.session?.getState({ cloneDocuments: false }) ?? null;\n const document = sessionState?.workingDocument ?? null;\n const requestedObjectId = typeof objectId === 'string' && objectId.trim()\n ? objectId.trim()\n : sessionState?.selection.activeId ?? undefined;\n const object = document && requestedObjectId\n ? createAgentBridgeSceneObject(state, options, document, requestedObjectId, operations.getHierarchy())\n : null;\n return {\n mode: state.mode,\n status: state.status,\n statusTone: state.statusTone,\n statusDetails: state.statusDetails,\n dirty: sessionState?.dirty,\n busy: state.busy,\n selection: cloneAgentBridgeSelection(sessionState?.selection ?? EMPTY_EDITOR_SELECTION),\n object,\n diagnostics: createAgentBridgeStateDiagnostics(state),\n };\n}\n\nfunction createAgentBridgeEditorSnapshot<TDocument, TPatch, TAsset>(\n state: LocalEditorAgentBridgeHarnessState<TDocument, TPatch>,\n options: LocalEditorHarnessOptions<TDocument, TPatch, TAsset>,\n input: EditorAgentBridgeEditorSnapshotGetInput,\n): EditorAgentBridgeEditorSnapshot {\n const sessionState = state.session?.getState({ cloneDocuments: false }) ?? null;\n const document = sessionState?.workingDocument ?? null;\n const objects = state.mode === 'editor' && document\n ? listAgentBridgeSceneObjects(state, options, document, input.includeUnselectable === true)\n : [];\n const snapshot: EditorAgentBridgeEditorSnapshot = {\n mode: state.mode,\n busy: state.busy,\n dirty: sessionState?.dirty ?? false,\n status: state.status,\n statusTone: state.statusTone,\n selection: cloneAgentBridgeSelection(sessionState?.selection ?? EMPTY_EDITOR_SELECTION),\n objectCount: objects.length,\n };\n if (input.includeObjects === true) {\n snapshot.objects = objects.slice(0, normalizeAgentBridgeSnapshotObjectLimit(input.objectLimit));\n }\n return snapshot;\n}\n\nfunction createAgentBridgeStateDiagnostics<TDocument, TPatch>(\n state: LocalEditorAgentBridgeHarnessState<TDocument, TPatch>,\n): EditorAgentBridgeEditorState['diagnostics'] {\n if (state.statusTone !== 'error' && state.statusTone !== 'warning') return [];\n return [{\n severity: state.statusTone,\n source: 'editor',\n message: state.statusDetails || state.status,\n }];\n}\n\nfunction normalizeAgentBridgeSnapshotObjectLimit(value: unknown): number {\n if (value === undefined) return AGENT_BRIDGE_SNAPSHOT_DEFAULT_OBJECT_LIMIT;\n if (typeof value !== 'number' || !Number.isFinite(value)) return AGENT_BRIDGE_SNAPSHOT_DEFAULT_OBJECT_LIMIT;\n return Math.max(0, Math.min(AGENT_BRIDGE_SNAPSHOT_MAX_OBJECT_LIMIT, Math.floor(value)));\n}\n"]}
1
+ {"version":3,"file":"editor-state.js","sourceRoot":"","sources":["../../../src/agent-bridge/capabilities/editor-state.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n EditorAgentBridgeEditorSnapshot,\n EditorAgentBridgeEditorSnapshotGetInput,\n EditorAgentBridgeEditorState,\n} from '@fps-games/editor-protocol';\nimport type { LocalEditorAgentBridgeStateSource } from '../source-types.js';\nimport {\n cloneAgentBridgeSelection,\n getAgentBridgeSafeSceneHierarchy,\n getAgentBridgeSafeSceneSelection,\n type LocalEditorAgentBridgeCapabilitySourceOperations,\n type LocalEditorAgentBridgeHarnessState,\n} from '../shared.js';\nimport {\n createAgentBridgeSceneObject,\n listAgentBridgeSceneObjects,\n} from './scene-objects.js';\nimport type { LocalEditorHarnessOptions } from '../../local-editor-harness.js';\n\nconst AGENT_BRIDGE_SNAPSHOT_DEFAULT_OBJECT_LIMIT = 100;\nconst AGENT_BRIDGE_SNAPSHOT_MAX_OBJECT_LIMIT = 500;\n\nexport function createLocalEditorAgentBridgeStateSource<TDocument, TPatch, TAsset>(\n state: LocalEditorAgentBridgeHarnessState<TDocument, TPatch>,\n options: LocalEditorHarnessOptions<TDocument, TPatch, TAsset>,\n operations: LocalEditorAgentBridgeCapabilitySourceOperations<TDocument>,\n): LocalEditorAgentBridgeStateSource {\n return {\n getSnapshot(input) {\n return createAgentBridgeEditorSnapshot(state, options, input, operations);\n },\n getState(input) {\n return createAgentBridgeEditorState(state, options, input.objectId, operations);\n },\n };\n}\n\nfunction createAgentBridgeEditorState<TDocument, TPatch, TAsset>(\n state: LocalEditorAgentBridgeHarnessState<TDocument, TPatch>,\n options: LocalEditorHarnessOptions<TDocument, TPatch, TAsset>,\n objectId: string | undefined,\n operations: LocalEditorAgentBridgeCapabilitySourceOperations<TDocument>,\n): EditorAgentBridgeEditorState {\n const sessionState = state.session?.getState({ cloneDocuments: false }) ?? null;\n const document = sessionState?.workingDocument ?? null;\n const safeSelection = getAgentBridgeSafeSceneSelection(operations);\n const requestedObjectId = typeof objectId === 'string' && objectId.trim()\n ? objectId.trim()\n : safeSelection.activeId ?? undefined;\n const object = document && requestedObjectId\n ? createAgentBridgeSceneObject(\n state,\n options,\n document,\n requestedObjectId,\n getAgentBridgeSafeSceneHierarchy(operations),\n )\n : null;\n return {\n mode: state.mode,\n status: state.status,\n statusTone: state.statusTone,\n statusDetails: state.statusDetails,\n dirty: sessionState?.dirty,\n busy: state.busy,\n selection: cloneAgentBridgeSelection(safeSelection),\n object,\n diagnostics: createAgentBridgeStateDiagnostics(state, operations),\n };\n}\n\nfunction createAgentBridgeEditorSnapshot<TDocument, TPatch, TAsset>(\n state: LocalEditorAgentBridgeHarnessState<TDocument, TPatch>,\n options: LocalEditorHarnessOptions<TDocument, TPatch, TAsset>,\n input: EditorAgentBridgeEditorSnapshotGetInput,\n operations: LocalEditorAgentBridgeCapabilitySourceOperations<TDocument>,\n): EditorAgentBridgeEditorSnapshot {\n const sessionState = state.session?.getState({ cloneDocuments: false }) ?? null;\n const document = sessionState?.workingDocument ?? null;\n const safeSelection = getAgentBridgeSafeSceneSelection(operations);\n const objects = state.mode === 'editor' && document\n ? listAgentBridgeSceneObjects(state, options, document, input.includeUnselectable === true, operations)\n : [];\n const snapshot: EditorAgentBridgeEditorSnapshot = {\n mode: state.mode,\n busy: state.busy,\n dirty: sessionState?.dirty ?? false,\n status: state.status,\n statusTone: state.statusTone,\n selection: cloneAgentBridgeSelection(safeSelection),\n objectCount: objects.length,\n };\n if (input.includeObjects === true) {\n snapshot.objects = objects.slice(0, normalizeAgentBridgeSnapshotObjectLimit(input.objectLimit));\n }\n return snapshot;\n}\n\nfunction createAgentBridgeStateDiagnostics<TDocument, TPatch>(\n state: LocalEditorAgentBridgeHarnessState<TDocument, TPatch>,\n operations: LocalEditorAgentBridgeCapabilitySourceOperations<TDocument>,\n): EditorAgentBridgeEditorState['diagnostics'] {\n return operations.getStatusDiagnostics().map(diagnostic => ({\n severity: diagnostic.severity,\n source: diagnostic.source,\n code: diagnostic.code,\n message: diagnostic.message,\n ...(diagnostic.rowId ? { objectId: diagnostic.rowId } : {}),\n details: {\n ...(diagnostic.scopeId ? { scopeId: diagnostic.scopeId } : {}),\n ...(diagnostic.targetId ? { targetId: diagnostic.targetId } : {}),\n ...(diagnostic.documentRevision != null ? { documentRevision: diagnostic.documentRevision } : {}),\n ...(diagnostic.projectionRevision != null ? { projectionRevision: diagnostic.projectionRevision } : {}),\n ...(diagnostic.details ?? {}),\n },\n }));\n}\n\nfunction normalizeAgentBridgeSnapshotObjectLimit(value: unknown): number {\n if (value === undefined) return AGENT_BRIDGE_SNAPSHOT_DEFAULT_OBJECT_LIMIT;\n if (typeof value !== 'number' || !Number.isFinite(value)) return AGENT_BRIDGE_SNAPSHOT_DEFAULT_OBJECT_LIMIT;\n return Math.max(0, Math.min(AGENT_BRIDGE_SNAPSHOT_MAX_OBJECT_LIMIT, Math.floor(value)));\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"prefabs.d.ts","sourceRoot":"","sources":["../../../src/agent-bridge/capabilities/prefabs.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAE/E,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAEL,KAAK,gDAAgD,EAErD,KAAK,kCAAkC,EACxC,MAAM,cAAc,CAAC;AAgBtB,wBAAgB,wCAAwC,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAChF,KAAK,EAAE,kCAAkC,CAAC,SAAS,EAAE,MAAM,CAAC,EAC5D,OAAO,EAAE,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7D,QAAQ,EAAE,MAAM,IAAI,EACpB,UAAU,EAAE,gDAAgD,CAAC,SAAS,CAAC,GACtE,kCAAkC,CAiWpC"}
1
+ {"version":3,"file":"prefabs.d.ts","sourceRoot":"","sources":["../../../src/agent-bridge/capabilities/prefabs.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAE/E,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAEL,KAAK,gDAAgD,EAErD,KAAK,kCAAkC,EACxC,MAAM,cAAc,CAAC;AAgBtB,wBAAgB,wCAAwC,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAChF,KAAK,EAAE,kCAAkC,CAAC,SAAS,EAAE,MAAM,CAAC,EAC5D,OAAO,EAAE,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7D,QAAQ,EAAE,MAAM,IAAI,EACpB,UAAU,EAAE,gDAAgD,CAAC,SAAS,CAAC,GACtE,kCAAkC,CAmYpC"}
@@ -104,7 +104,7 @@ export function createLocalEditorAgentBridgePrefabSource(state, options, renderU
104
104
  if (!details || !isRequestedPrefabStage(details.stage, input.assetId)) {
105
105
  return createLocalEditorAgentBridgeFailure(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_SCENE_GET, createPrefabStageUnavailableMessage(input.assetId), { code: 'prefab.stageNotOpen', details: { assetId: input.assetId } });
106
106
  }
107
- return createPrefabSceneOutput(details);
107
+ return createSafePrefabSceneOutput(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_SCENE_GET, details, operations);
108
108
  },
109
109
  selectNode(input) {
110
110
  const nodeId = normalizePrefabNodeId(input.nodeId);
@@ -112,7 +112,9 @@ export function createLocalEditorAgentBridgePrefabSource(state, options, renderU
112
112
  if (!details || !nodeId) {
113
113
  return createLocalEditorAgentBridgeFailure(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_NODE_SELECT, nodeId ? 'Prefab stage is not open.' : 'Prefab node id is required.', { code: nodeId ? 'prefab.stageNotOpen' : 'prefab.invalidInput', details: { nodeId: input.nodeId } });
114
114
  }
115
- const scene = createPrefabSceneOutput(details);
115
+ const scene = createSafePrefabSceneOutput(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_NODE_SELECT, details, operations);
116
+ if ('ok' in scene)
117
+ return scene;
116
118
  const node = scene.nodes.find(candidate => candidate.nodeId === nodeId) ?? null;
117
119
  if (!node) {
118
120
  return createLocalEditorAgentBridgeFailure(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_NODE_SELECT, `Prefab node not found: ${nodeId}`, { code: 'prefab.nodeNotFound', details: { assetId: details.stage.assetId, nodeId } });
@@ -121,7 +123,9 @@ export function createLocalEditorAgentBridgePrefabSource(state, options, renderU
121
123
  if (changed)
122
124
  renderUi();
123
125
  const nextDetails = operations.getPrefabStageDetails() ?? details;
124
- const nextScene = createPrefabSceneOutput(nextDetails);
126
+ const nextScene = createSafePrefabSceneOutput(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_NODE_SELECT, nextDetails, operations);
127
+ if ('ok' in nextScene)
128
+ return nextScene;
125
129
  const selectedNode = nextScene.nodes.find(candidate => candidate.nodeId === nodeId) ?? node;
126
130
  return {
127
131
  stage: nextScene.stage,
@@ -138,7 +142,9 @@ export function createLocalEditorAgentBridgePrefabSource(state, options, renderU
138
142
  ? 'Prefab stage is not open.'
139
143
  : `Asset not found: ${assetId || '(empty)'}`, { code: !details ? 'prefab.stageNotOpen' : 'asset.notFound', details: { assetId } });
140
144
  }
141
- const beforeScene = createPrefabSceneOutput(details);
145
+ const beforeScene = createSafePrefabSceneOutput(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_NODE_CREATE_FROM_ASSET, details, operations);
146
+ if ('ok' in beforeScene)
147
+ return beforeScene;
142
148
  const parentNodeId = resolvePrefabMutationParentNodeId(input.parentNodeId, beforeScene);
143
149
  const action = {
144
150
  actionId: 'asset.add-to-current-prefab',
@@ -163,7 +169,9 @@ export function createLocalEditorAgentBridgePrefabSource(state, options, renderU
163
169
  if (!details) {
164
170
  return createLocalEditorAgentBridgeFailure(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_NODE_CREATE_GROUP, 'Prefab stage is not open.', { code: 'prefab.stageNotOpen' });
165
171
  }
166
- const beforeScene = createPrefabSceneOutput(details);
172
+ const beforeScene = createSafePrefabSceneOutput(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_NODE_CREATE_GROUP, details, operations);
173
+ if ('ok' in beforeScene)
174
+ return beforeScene;
167
175
  const parentNodeId = resolvePrefabMutationParentNodeId(input.parentNodeId, beforeScene);
168
176
  const action = {
169
177
  actionId: 'prefab.node.createGroup',
@@ -186,7 +194,9 @@ export function createLocalEditorAgentBridgePrefabSource(state, options, renderU
186
194
  if (!details) {
187
195
  return createLocalEditorAgentBridgeFailure(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_NODE_CREATE_PRIMITIVE, 'Prefab stage is not open.', { code: 'prefab.stageNotOpen' });
188
196
  }
189
- const beforeScene = createPrefabSceneOutput(details);
197
+ const beforeScene = createSafePrefabSceneOutput(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_NODE_CREATE_PRIMITIVE, details, operations);
198
+ if ('ok' in beforeScene)
199
+ return beforeScene;
190
200
  const parentNodeId = resolvePrefabMutationParentNodeId(input.parentNodeId, beforeScene);
191
201
  const action = {
192
202
  actionId: 'prefab.node.createPrimitive',
@@ -211,7 +221,9 @@ export function createLocalEditorAgentBridgePrefabSource(state, options, renderU
211
221
  if (!details || !nodeId) {
212
222
  return createLocalEditorAgentBridgeFailure(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_NODE_SET_TRANSFORM, nodeId ? 'Prefab stage is not open.' : 'Prefab node id is required.', { code: nodeId ? 'prefab.stageNotOpen' : 'prefab.invalidInput', details: { nodeId: input.nodeId } });
213
223
  }
214
- const beforeScene = createPrefabSceneOutput(details);
224
+ const beforeScene = createSafePrefabSceneOutput(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_NODE_SET_TRANSFORM, details, operations);
225
+ if ('ok' in beforeScene)
226
+ return beforeScene;
215
227
  const node = beforeScene.nodes.find(candidate => candidate.nodeId === nodeId) ?? null;
216
228
  if (!node) {
217
229
  return createLocalEditorAgentBridgeFailure(EDITOR_AGENT_BRIDGE_CAPABILITY_ID.PREFAB_NODE_SET_TRANSFORM, `Prefab node not found: ${nodeId}`, { code: 'prefab.nodeNotFound', details: { assetId: details.stage.assetId, nodeId } });
@@ -381,12 +393,42 @@ function isRequestedPrefabStage(stage, assetId) {
381
393
  const normalized = normalizeAgentBridgeString(assetId);
382
394
  return !normalized || stage.assetId === normalized || stage.browserAssetId === normalized;
383
395
  }
384
- function createPrefabSceneOutput(details) {
385
- const nodes = listPrefabSceneNodes(details.structureItems);
396
+ function createSafePrefabSceneOutput(capabilityId, details, operations) {
397
+ const projection = operations.getHierarchyProjection();
398
+ const expectedScopeId = `prefab-stage:${details.stage.assetId}`;
399
+ if (!projection
400
+ || projection.scopeKind !== 'prefab-stage'
401
+ || projection.scopeId !== expectedScopeId) {
402
+ return createLocalEditorAgentBridgeFailure(capabilityId, 'Prefab Hierarchy projection is unavailable or does not match the active Prefab Stage.', {
403
+ code: 'prefab.hierarchyProjectionUnavailable',
404
+ details: {
405
+ assetId: details.stage.assetId,
406
+ expectedScopeId,
407
+ actualScopeId: projection?.scopeId,
408
+ actualScopeKind: projection?.scopeKind,
409
+ },
410
+ });
411
+ }
412
+ const safeNodeIds = new Set(projection.targets.map(target => target.targetId));
413
+ for (const node of projection.nodes) {
414
+ if (node.sourceKind !== 'root')
415
+ continue;
416
+ const rootNodeId = normalizePrefabNodeId(node.id);
417
+ if (rootNodeId)
418
+ safeNodeIds.add(rootNodeId);
419
+ }
420
+ return createPrefabSceneOutput(details, safeNodeIds);
421
+ }
422
+ function createPrefabSceneOutput(details, safeNodeIds) {
423
+ const nodes = listPrefabSceneNodes(details.structureItems)
424
+ .filter(node => safeNodeIds.has(node.nodeId));
386
425
  const rootNodeId = nodes.find(node => node.kind === 'root')?.nodeId
387
426
  ?? nodes.find(node => !node.parentNodeId)?.nodeId
388
427
  ?? PREFAB_ROOT_NODE_ID;
389
- const selectedNodeId = getSelectedPrefabNodeId(details.stage.selectedItemId);
428
+ const rawSelectedNodeId = getSelectedPrefabNodeId(details.stage.selectedItemId);
429
+ const selectedNodeId = rawSelectedNodeId && safeNodeIds.has(rawSelectedNodeId)
430
+ ? rawSelectedNodeId
431
+ : null;
390
432
  return {
391
433
  stage: details.stage,
392
434
  rootNodeId,
@@ -531,7 +573,9 @@ function runNodeIdMutation(input) {
531
573
  details: { nodeId: input.nodeId, parentNodeId: input.parentNodeId },
532
574
  });
533
575
  }
534
- const beforeScene = createPrefabSceneOutput(details);
576
+ const beforeScene = createSafePrefabSceneOutput(input.capabilityId, details, input.operations);
577
+ if ('ok' in beforeScene)
578
+ return beforeScene;
535
579
  const node = beforeScene.nodes.find(candidate => candidate.nodeId === nodeId) ?? null;
536
580
  if (!node) {
537
581
  return createLocalEditorAgentBridgeFailure(input.capabilityId, `Prefab node not found: ${nodeId}`, { code: 'prefab.nodeNotFound', details: { assetId: details.stage.assetId, nodeId } });
@@ -618,7 +662,9 @@ function runPrefabNodeMutation(input) {
618
662
  if (!afterDetails) {
619
663
  return createLocalEditorAgentBridgeFailure(input.capabilityId, 'Prefab mutation completed, but Prefab stage is no longer open.', { code: 'prefab.stageClosed' });
620
664
  }
621
- const afterScene = createPrefabSceneOutput(afterDetails);
665
+ const afterScene = createSafePrefabSceneOutput(input.capabilityId, afterDetails, input.operations);
666
+ if ('ok' in afterScene)
667
+ return afterScene;
622
668
  const beforeNodeIds = new Set(input.beforeScene.nodes.map(node => node.nodeId));
623
669
  const afterNodeIds = new Set(afterScene.nodes.map(node => node.nodeId));
624
670
  const createdNodeId = afterScene.nodes.find(node => !beforeNodeIds.has(node.nodeId))?.nodeId;
@@ -654,7 +700,9 @@ function resolvePrefabAssetForInspection(capabilityId, state, options, operation
654
700
  result: createLocalEditorAgentBridgeFailure(capabilityId, 'Prefab stage is not open.', { code: 'prefab.stageNotOpen' }),
655
701
  };
656
702
  }
657
- const scene = createPrefabSceneOutput(details);
703
+ const scene = createSafePrefabSceneOutput(capabilityId, details, operations);
704
+ if ('ok' in scene)
705
+ return { ok: false, result: scene };
658
706
  const nodeId = normalizePrefabNodeId(input.nodeId) || scene.selectedNodeId || '';
659
707
  const node = nodeId ? scene.nodes.find(candidate => candidate.nodeId === nodeId) ?? null : null;
660
708
  const assetId = normalizeAgentBridgeString(input.assetId)