@tiinex/app 0.1.1

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 (580) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +31 -0
  3. package/README.md +26 -0
  4. package/docs/CONSUMER-CONTRACT.md +65 -0
  5. package/package.json +94 -0
  6. package/src/acceptance/knownScenarios.case.mjs +48 -0
  7. package/src/acceptance/knownScenarios.js +89 -0
  8. package/src/acceptance/postV423CanonicalTransitionProductVerticalSlice.case.mjs +774 -0
  9. package/src/acceptance/postV437M0ETimePortalProductParityClosure.case.mjs +51 -0
  10. package/src/acceptance/postV447M0FGithubSocialPublicationProductIntegration.case.mjs +33 -0
  11. package/src/acceptance/postV450M0ProductAcceptanceHardening.case.mjs +82 -0
  12. package/src/acceptance/postV470SchemaReadingContractMaterializationIdentitySourceCoalescingAuthorityCorrection.case.mjs +236 -0
  13. package/src/acceptance/recoveryAcceptance.case.mjs +196 -0
  14. package/src/adapters/adapter.definition.schema.json +33 -0
  15. package/src/adapters/archive/archive.adapter.case.mjs +212 -0
  16. package/src/adapters/export/export.adapter.js +79 -0
  17. package/src/adapters/git-native/git-native.adapter.js +43 -0
  18. package/src/adapters/github/github.adapter.case.mjs +843 -0
  19. package/src/adapters/github/github.adapter.js +395 -0
  20. package/src/adapters/github/github.issueEmbedded.js +262 -0
  21. package/src/adapters/github/github.issueMirror.js +309 -0
  22. package/src/adapters/github/github.issueSnapshot.js +475 -0
  23. package/src/adapters/github/github.issueSurface.js +188 -0
  24. package/src/adapters/github/github.issueTransport.js +237 -0
  25. package/src/adapters/github/github.publicationRead.js +24 -0
  26. package/src/adapters/github/github.readTransport.js +18 -0
  27. package/src/adapters/github/github.repoDiscovery.js +222 -0
  28. package/src/adapters/github/github.repoMirror.js +255 -0
  29. package/src/adapters/github/github.repoProxy.js +276 -0
  30. package/src/adapters/github/github.repoSurface.js +60 -0
  31. package/src/adapters/github/github.transportDiagnostics.js +68 -0
  32. package/src/adapters/local/local.adapter.case.mjs +72 -0
  33. package/src/adapters/local/local.adapter.js +188 -0
  34. package/src/adapters/registry.js +35 -0
  35. package/src/adapters/static/static.adapter.js +84 -0
  36. package/src/app/App.js +1 -0
  37. package/src/app/TiinexApp.jsx +822 -0
  38. package/src/app/appShell.views.jsx +58 -0
  39. package/src/app/artifactAuthoringCapability.js +49 -0
  40. package/src/app/boot/bootApp.js +19 -0
  41. package/src/app/boot/environment.js +1 -0
  42. package/src/app/canonicalAuthoringValues.js +4 -0
  43. package/src/app/canonicalCreationProductController.js +57 -0
  44. package/src/app/canonicalCreationProductSettlement.case.mjs +10 -0
  45. package/src/app/canonicalCreationProductSettlement.js +11 -0
  46. package/src/app/canonicalReferenceLocalCreateCommand.js +210 -0
  47. package/src/app/canonicalReferenceTargets.js +73 -0
  48. package/src/app/canonicalTransitionLocalCreateCommand.js +217 -0
  49. package/src/app/defaultWorkspaceStart.case.mjs +39 -0
  50. package/src/app/defaultWorkspaceStart.js +65 -0
  51. package/src/app/defaultWorkspaceStartCommand.js +55 -0
  52. package/src/app/durableLocalMutationPolicy.js +21 -0
  53. package/src/app/githubMaterializationSummary.js +69 -0
  54. package/src/app/githubProgress.js +25 -0
  55. package/src/app/githubSourceInput.js +47 -0
  56. package/src/app/githubSourceMaterializationCommand.js +97 -0
  57. package/src/app/githubSourceOperation.js +226 -0
  58. package/src/app/governanceDialogData.js +27 -0
  59. package/src/app/handoffPackageImportCommand.js +182 -0
  60. package/src/app/historyAuthority.js +53 -0
  61. package/src/app/initialWorkspaceBootstrapOperation.js +105 -0
  62. package/src/app/lineageCommand.js +118 -0
  63. package/src/app/lineageSourceRecovery.js +339 -0
  64. package/src/app/localDraftMutationCommand.js +174 -0
  65. package/src/app/localMaterialCommand.js +124 -0
  66. package/src/app/nodeGraphVerse.case.mjs +111 -0
  67. package/src/app/persistenceOwnership.js +92 -0
  68. package/src/app/productStateBoundary.js +7 -0
  69. package/src/app/providers/AppProviders.js +1 -0
  70. package/src/app/providers/LocaleProvider.js +1 -0
  71. package/src/app/providers/SchemaRegistryProvider.js +1 -0
  72. package/src/app/providers/WorkspaceProvider.js +1 -0
  73. package/src/app/publicTarget.js +251 -0
  74. package/src/app/publicTargetRestoreCommand.js +149 -0
  75. package/src/app/recordUi.cache.js +35 -0
  76. package/src/app/recordUi.js +11 -0
  77. package/src/app/routes/RouteSurface.js +1 -0
  78. package/src/app/routes/routes.js +1 -0
  79. package/src/app/runtimeState.js +54 -0
  80. package/src/app/schemaCurrentDeclaration.js +69 -0
  81. package/src/app/schemaFactoryLocalCreateCommand.js +101 -0
  82. package/src/app/schemaFactoryViewerProof.case.mjs +134 -0
  83. package/src/app/schemaFactoryViewerProof.js +20 -0
  84. package/src/app/schemaNavigationCommand.js +285 -0
  85. package/src/app/schemaNavigationMaterialization.js +171 -0
  86. package/src/app/schemaNavigationRuntimeCatalog.js +25 -0
  87. package/src/app/schemaNavigationState.js +66 -0
  88. package/src/app/schemaReadingContractQualification.js +91 -0
  89. package/src/app/schemaSourceRecovery.js +373 -0
  90. package/src/app/scrollPersistence.js +30 -0
  91. package/src/app/semanticOperationHistory.js +18 -0
  92. package/src/app/shareActionCommand.js +55 -0
  93. package/src/app/shareProjection.js +190 -0
  94. package/src/app/shell/AppShell.js +1 -0
  95. package/src/app/shell/Header.js +1 -0
  96. package/src/app/shell/Navigation.js +1 -0
  97. package/src/app/shell/SurfaceSwitcher.js +1 -0
  98. package/src/app/sourceTransportRefresh.js +176 -0
  99. package/src/app/startupOwnership.js +40 -0
  100. package/src/app/startupPresentation.case.mjs +34 -0
  101. package/src/app/startupPresentation.js +33 -0
  102. package/src/app/startupPresentation.views.jsx +21 -0
  103. package/src/app/startupRenderPhase.js +9 -0
  104. package/src/app/startupWorkspaceCommand.js +62 -0
  105. package/src/app/startupWorkspaceConfigApplication.js +49 -0
  106. package/src/app/statePersistenceScheduler.js +106 -0
  107. package/src/app/tiinexAppConfigPlan.js +108 -0
  108. package/src/app/tiinexAppConfigSource.js +349 -0
  109. package/src/app/tiinexAppStartupSource.js +79 -0
  110. package/src/app/tiinexHostedWorkspaceConventions.js +572 -0
  111. package/src/app/timePortalHistoricalRead.js +114 -0
  112. package/src/app/timePortalSnapshotResolution.js +53 -0
  113. package/src/app/urlMaterialCommand.js +24 -0
  114. package/src/app/useCanonicalPlacementSelectionOptions.js +9 -0
  115. package/src/app/useCanonicalReferenceSelectionOptions.js +8 -0
  116. package/src/app/useLocalMaterialIntake.js +68 -0
  117. package/src/app/useTimePortalProductController.jsx +111 -0
  118. package/src/app/useWorkspaceEntrypointIntake.js +77 -0
  119. package/src/app/useWorkspaceSelectionProductController.jsx +21 -0
  120. package/src/app/viewState.js +35 -0
  121. package/src/app/viewport.js +21 -0
  122. package/src/app/visualDormancy.js +286 -0
  123. package/src/app/workspaceContinuityNotices.js +32 -0
  124. package/src/app/workspaceDisplayCounts.js +9 -0
  125. package/src/app/workspaceEntrypointIntakeCommand.js +87 -0
  126. package/src/app/workspaceEntrypointProductRouting.case.mjs +20 -0
  127. package/src/app/workspaceExportCommand.js +21 -0
  128. package/src/app/workspaceExportDownload.js +23 -0
  129. package/src/app/workspaceExportExecutionCommand.js +10 -0
  130. package/src/app/workspaceGithubPublication.js +237 -0
  131. package/src/app/workspaceHandoffExport.js +56 -0
  132. package/src/app/workspaceHomeTarget.js +9 -0
  133. package/src/app/workspaceMulticolumn.js +113 -0
  134. package/src/app/workspaceNavigationParity.case.mjs +110 -0
  135. package/src/app/workspaceOpenProgress.js +26 -0
  136. package/src/app/workspacePlacementOptions.js +46 -0
  137. package/src/app/workspaceRecordActions.js +158 -0
  138. package/src/app/workspaceScopedInteraction.js +68 -0
  139. package/src/app/workspaceSelectionOriginContext.js +29 -0
  140. package/src/app/workspaceSelectionSession.js +54 -0
  141. package/src/app/workspaceSourceCloseCommand.js +25 -0
  142. package/src/app/workspaceSpineProductRouting.case.mjs +22 -0
  143. package/src/app/workspaceStartupTransition.js +32 -0
  144. package/src/app/workspaceWindow.js +85 -0
  145. package/src/artifacts/artifact.fixture.js +1 -0
  146. package/src/artifacts/artifact.identity.js +6 -0
  147. package/src/artifacts/artifact.identityAggregation.js +218 -0
  148. package/src/artifacts/artifact.model.js +2 -0
  149. package/src/artifacts/artifact.parse.case.mjs +196 -0
  150. package/src/artifacts/artifact.participantIndex.js +189 -0
  151. package/src/artifacts/fixtures/evidence.trace.md +50 -0
  152. package/src/artifacts/fixtures/topic.trace.md +33 -0
  153. package/src/artifacts/fixtures/unknown-schema.trace.md +25 -0
  154. package/src/audit/audit.findings.js +1 -0
  155. package/src/audit/audit.model.js +2 -0
  156. package/src/audit/audit.plan.js +13 -0
  157. package/src/audit/audit.report.js +12 -0
  158. package/src/audit/audit.severity.js +1 -0
  159. package/src/audit/audit.traverse.js +119 -0
  160. package/src/audit/integrity/auditIntegrity.checks.js +1 -0
  161. package/src/audit/integrity/auditIntegrity.compare.js +1 -0
  162. package/src/audit/lineage/auditLineage.load.js +1 -0
  163. package/src/audit/lineage/auditLineage.plan.js +1 -0
  164. package/src/audit/lineage/auditLineage.resolve.js +12 -0
  165. package/src/audit/sources/auditSources.boundaries.js +1 -0
  166. package/src/audit/sources/auditSources.checks.js +1 -0
  167. package/src/audit/validation/auditValidation.recheck.js +1 -0
  168. package/src/audit/validation/auditValidation.run.js +1 -0
  169. package/src/build.identity.js +15 -0
  170. package/src/commands/command.vocabulary.js +14 -0
  171. package/src/conformance/conformance.fixtures.js +151 -0
  172. package/src/conformance/conformance.run.js +238 -0
  173. package/src/data/applicationDataStore.js +23 -0
  174. package/src/data/companionAccess.js +35 -0
  175. package/src/diagnostics/events.js +1 -0
  176. package/src/diagnostics/invariant.js +1 -0
  177. package/src/diagnostics/schemaBindingChecks.js +1 -0
  178. package/src/diagnostics/schemaModuleChecks.js +1 -0
  179. package/src/diagnostics/sourceBoundaryChecks.js +5 -0
  180. package/src/diagnostics/sourceTransport.report.js +190 -0
  181. package/src/discovery/discovery.controls.js +7 -0
  182. package/src/export/export.plan.js +182 -0
  183. package/src/export/handoff.plan.js +50 -0
  184. package/src/export/package.builder.case.mjs +97 -0
  185. package/src/export/package.controlTopology.case.mjs +130 -0
  186. package/src/export/package.zip.case.mjs +33 -0
  187. package/src/graph/artifactGraph.model.js +344 -0
  188. package/src/graph/artifactGraph.project.js +139 -0
  189. package/src/graph/artifactGraph.worker.js +10 -0
  190. package/src/i18n/i18n.keys.js +1 -0
  191. package/src/i18n/i18n.provider.js +1 -0
  192. package/src/i18n/i18n.resolve.js +5 -0
  193. package/src/i18n/locales/en/common.json +4 -0
  194. package/src/i18n/locales/en/schemas/evidence.json +3 -0
  195. package/src/i18n/locales/en/schemas/presentation-surface.json +3 -0
  196. package/src/i18n/locales/en/schemas/preservation.json +3 -0
  197. package/src/i18n/locales/en/schemas/root.json +3 -0
  198. package/src/i18n/locales/en/schemas/schema-module.json +3 -0
  199. package/src/i18n/locales/en/schemas/topic.json +3 -0
  200. package/src/i18n/locales/en/surfaces/audit.json +3 -0
  201. package/src/i18n/locales/en/surfaces/create.json +3 -0
  202. package/src/i18n/locales/en/surfaces/detail.json +3 -0
  203. package/src/i18n/locales/en/surfaces/display-options.json +3 -0
  204. package/src/i18n/locales/en/surfaces/edit.json +3 -0
  205. package/src/i18n/locales/en/surfaces/feed.json +3 -0
  206. package/src/i18n/locales/en/surfaces/lineage.json +3 -0
  207. package/src/i18n/locales/en/surfaces/preview.json +3 -0
  208. package/src/i18n/locales/en/surfaces/share.json +3 -0
  209. package/src/i18n/locales/en/surfaces/source-settings.json +3 -0
  210. package/src/i18n/locales/en/surfaces/tree.json +3 -0
  211. package/src/i18n/locales/sv/common.json +4 -0
  212. package/src/i18n/locales/sv/schemas/evidence.json +3 -0
  213. package/src/i18n/locales/sv/schemas/presentation-surface.json +3 -0
  214. package/src/i18n/locales/sv/schemas/preservation.json +3 -0
  215. package/src/i18n/locales/sv/schemas/root.json +3 -0
  216. package/src/i18n/locales/sv/schemas/schema-module.json +3 -0
  217. package/src/i18n/locales/sv/schemas/topic.json +3 -0
  218. package/src/i18n/locales/sv/surfaces/audit.json +3 -0
  219. package/src/i18n/locales/sv/surfaces/create.json +3 -0
  220. package/src/i18n/locales/sv/surfaces/detail.json +3 -0
  221. package/src/i18n/locales/sv/surfaces/display-options.json +3 -0
  222. package/src/i18n/locales/sv/surfaces/edit.json +3 -0
  223. package/src/i18n/locales/sv/surfaces/feed.json +3 -0
  224. package/src/i18n/locales/sv/surfaces/lineage.json +3 -0
  225. package/src/i18n/locales/sv/surfaces/preview.json +3 -0
  226. package/src/i18n/locales/sv/surfaces/share.json +3 -0
  227. package/src/i18n/locales/sv/surfaces/source-settings.json +3 -0
  228. package/src/i18n/locales/sv/surfaces/tree.json +3 -0
  229. package/src/index.js +10 -0
  230. package/src/integrity/integrity.testFixture.js +9 -0
  231. package/src/interaction/interaction.spine.js +12 -0
  232. package/src/lineage/lineage.audit.js +1 -0
  233. package/src/lineage/lineage.edges.js +1 -0
  234. package/src/main.js +319 -0
  235. package/src/main.jsx +34 -0
  236. package/src/multiverse/multiverse.model.js +10 -0
  237. package/src/parity/poc.m1ParityScenarios.js +42 -0
  238. package/src/parity/poc.parityLedger.js +261 -0
  239. package/src/publication/publication.githubSocialContract.case.mjs +247 -0
  240. package/src/publication/publication.preflight.case.mjs +64 -0
  241. package/src/react/TiinexApplication.jsx +39 -0
  242. package/src/react/VerseHost.jsx +29 -0
  243. package/src/react/applicationDataContext.jsx +30 -0
  244. package/src/react.js +2 -0
  245. package/src/readers/modes/audit.reader.js +1 -0
  246. package/src/readers/modes/detail.reader.js +1 -0
  247. package/src/readers/modes/handover.reader.js +1 -0
  248. package/src/readers/modes/mobile.reader.js +1 -0
  249. package/src/readers/modes/print.reader.js +1 -0
  250. package/src/readers/modes/scan.reader.js +1 -0
  251. package/src/readers/reader.model.js +1 -0
  252. package/src/readers/reader.resolve.js +2 -0
  253. package/src/reingest/reingest.plan.case.mjs +65 -0
  254. package/src/runtime.js +54 -0
  255. package/src/schemas/README.md +99 -0
  256. package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.md +614 -0
  257. package/src/schemas/coordination/project/tiinex.project.v1.schema.md +311 -0
  258. package/src/schemas/core/decision/tiinex.decision.v1.schema.md +227 -0
  259. package/src/schemas/core/evidence/tiinex.evidence.v1.schema.md +318 -0
  260. package/src/schemas/core/feedback/tiinex.feedback.v1.schema.md +243 -0
  261. package/src/schemas/core/interpretation/.transitions/evidence-to-interpretation-transition-definition.trace.md +102 -0
  262. package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.md +308 -0
  263. package/src/schemas/core/preservation/tiinex.preservation.v1.schema.md +312 -0
  264. package/src/schemas/core/relation/.generation/reference-relation-generation-authority.trace.md +185 -0
  265. package/src/schemas/core/relation/.transitions/topic-references-task-transition-definition.trace.md +119 -0
  266. package/src/schemas/core/relation/tiinex.relation.v1.schema.md +240 -0
  267. package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.md +550 -0
  268. package/src/schemas/core/signal/tiinex.signal.v1.schema.md +239 -0
  269. package/src/schemas/core/task/.transitions/create-task-transition-definition.trace.md +93 -0
  270. package/src/schemas/core/task/.transitions/topic-to-task-transition-definition.trace.md +102 -0
  271. package/src/schemas/core/task/task-semantic-package.trace.md +53 -0
  272. package/src/schemas/core/task/tiinex.task.v1-transitions.trace.md +33 -0
  273. package/src/schemas/core/task/tiinex.task.v1.authoring.js +65 -0
  274. package/src/schemas/core/task/tiinex.task.v1.schema.md +229 -0
  275. package/src/schemas/core/topic/.transitions/create-topic-transition-definition.trace.md +93 -0
  276. package/src/schemas/core/topic/tiinex.topic.v1-transitions.trace.md +33 -0
  277. package/src/schemas/core/topic/tiinex.topic.v1.schema.md +197 -0
  278. package/src/schemas/core/topic/topic-semantic-package.trace.md +53 -0
  279. package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.md +240 -0
  280. package/src/schemas/discovery/tiinex.discovery.v1.schema.md +294 -0
  281. package/src/schemas/manifest.json +367 -0
  282. package/src/schemas/origins.js +46 -0
  283. package/src/schemas/party/organization/tiinex.party.organization.v1.schema.md +290 -0
  284. package/src/schemas/party/role/tiinex.party.role.v1.schema.md +298 -0
  285. package/src/schemas/party/tiinex.party.v1.schema.js +14 -0
  286. package/src/schemas/party/tiinex.party.v1.schema.json +23 -0
  287. package/src/schemas/party/tiinex.party.v1.schema.md +311 -0
  288. package/src/schemas/party/tiinex.party.v1.schema.runtime.json +2033 -0
  289. package/src/schemas/party/tiinex.party.v1.schema.source.js +9 -0
  290. package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.md +476 -0
  291. package/src/schemas/reduction/tiinex.reduction.v1.schema.md +248 -0
  292. package/src/schemas/schema/module/tiinex.schema.module.v1.schema.md +465 -0
  293. package/src/schemas/schema.companionContract.case.mjs +259 -0
  294. package/src/schemas/schema.factory.case.mjs +256 -0
  295. package/src/schemas/schema.factory.viewerProjection.js +183 -0
  296. package/src/schemas/schemaMarkdownCatalog.js +19 -0
  297. package/src/schemas/tiinex.root.v1.schema.md +865 -0
  298. package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.md +309 -0
  299. package/src/schemas/validation/method/tiinex.validation.method.v1.schema.md +280 -0
  300. package/src/schemas/validation/report/tiinex.validation.report.v1.schema.md +300 -0
  301. package/src/schemas/workspace/tiinex.workspace.v1.schema.md +486 -0
  302. package/src/schemas/workspace/workspace.add.views.jsx +327 -0
  303. package/src/schemas/workspace/workspace.audit.views.jsx +160 -0
  304. package/src/schemas/workspace/workspace.auditBadge.views.jsx +98 -0
  305. package/src/schemas/workspace/workspace.canonicalReferenceDialog.views.jsx +63 -0
  306. package/src/schemas/workspace/workspace.canonicalTaskDialog.views.jsx +169 -0
  307. package/src/schemas/workspace/workspace.cardActions.js +9 -0
  308. package/src/schemas/workspace/workspace.cards.views.jsx +146 -0
  309. package/src/schemas/workspace/workspace.chrome.views.jsx +299 -0
  310. package/src/schemas/workspace/workspace.continuationDialog.views.jsx +80 -0
  311. package/src/schemas/workspace/workspace.discovery.views.jsx +63 -0
  312. package/src/schemas/workspace/workspace.discoveryRenderWindow.js +56 -0
  313. package/src/schemas/workspace/workspace.displayOptions.views.jsx +114 -0
  314. package/src/schemas/workspace/workspace.entrypointChoice.views.jsx +30 -0
  315. package/src/schemas/workspace/workspace.exportDialog.controller.jsx +40 -0
  316. package/src/schemas/workspace/workspace.exportDialog.views.jsx +142 -0
  317. package/src/schemas/workspace/workspace.governance.views.jsx +45 -0
  318. package/src/schemas/workspace/workspace.graph.views.jsx +134 -0
  319. package/src/schemas/workspace/workspace.lineage.views.jsx +307 -0
  320. package/src/schemas/workspace/workspace.read.views.jsx +105 -0
  321. package/src/schemas/workspace/workspace.recordActionButton.views.jsx +35 -0
  322. package/src/schemas/workspace/workspace.recordDialogs.views.jsx +257 -0
  323. package/src/schemas/workspace/workspace.selection.views.jsx +14 -0
  324. package/src/schemas/workspace/workspace.sourceReceipt.views.jsx +40 -0
  325. package/src/schemas/workspace/workspace.timePortal.views.jsx +56 -0
  326. package/src/schemas/workspace/workspace.tree.views.jsx +107 -0
  327. package/src/schemas/workspace/workspace.viewFormatting.js +172 -0
  328. package/src/schemas/workspace/workspace.views.jsx +210 -0
  329. package/src/source-settings/sourceSettings.model.js +7 -0
  330. package/src/sources/draft/draft.source.js +1 -0
  331. package/src/sources/github/github.loader.js +204 -0
  332. package/src/sources/github/github.permalink.js +1 -0
  333. package/src/sources/github/github.source.js +1 -0
  334. package/src/sources/github/github.transport.case.mjs +237 -0
  335. package/src/sources/github/github.transport.js +472 -0
  336. package/src/sources/local/local.source.js +1 -0
  337. package/src/sources/source.assetReferences.js +109 -0
  338. package/src/sources/source.boundaries.js +24 -0
  339. package/src/sources/source.identity.js +56 -0
  340. package/src/sources/source.model.case.mjs +26 -0
  341. package/src/sources/source.model.js +56 -0
  342. package/src/sources/source.presenter.js +66 -0
  343. package/src/sources/source.resolve.js +11 -0
  344. package/src/sources/static/static.source.js +1 -0
  345. package/src/sources/transport.policy.case.mjs +39 -0
  346. package/src/sources/transport.policy.js +81 -0
  347. package/src/storage/storage.policy.js +79 -0
  348. package/src/styles/app.css +8699 -0
  349. package/src/styles/responsive.css +10 -0
  350. package/src/styles/theme.css +4 -0
  351. package/src/styles/tokens.css +30 -0
  352. package/src/surfaces/audit/AuditSurface.js +1 -0
  353. package/src/surfaces/audit/audit.model.js +1 -0
  354. package/src/surfaces/audit/audit.render.js +1 -0
  355. package/src/surfaces/contracts.js +45 -0
  356. package/src/surfaces/create/CreateSurface.js +1 -0
  357. package/src/surfaces/create/create.model.js +1 -0
  358. package/src/surfaces/create/create.render.js +1 -0
  359. package/src/surfaces/detail/DetailSurface.js +1 -0
  360. package/src/surfaces/detail/detail.model.js +1 -0
  361. package/src/surfaces/detail/detail.render.js +1 -0
  362. package/src/surfaces/display-options/DisplayOptionsSurface.js +1 -0
  363. package/src/surfaces/display-options/displayOptions.model.js +1 -0
  364. package/src/surfaces/display-options/displayOptions.render.js +1 -0
  365. package/src/surfaces/edit/EditSurface.js +1 -0
  366. package/src/surfaces/edit/edit.model.js +1 -0
  367. package/src/surfaces/edit/edit.render.js +1 -0
  368. package/src/surfaces/feed/FeedSurface.js +1 -0
  369. package/src/surfaces/feed/feed.model.js +1 -0
  370. package/src/surfaces/feed/feed.render.js +1 -0
  371. package/src/surfaces/lineage/LineageSurface.js +1 -0
  372. package/src/surfaces/lineage/lineage.model.js +1 -0
  373. package/src/surfaces/lineage/lineage.render.js +1 -0
  374. package/src/surfaces/preview/PreviewSurface.js +1 -0
  375. package/src/surfaces/preview/preview.model.js +1 -0
  376. package/src/surfaces/preview/preview.render.js +1 -0
  377. package/src/surfaces/registry.js +58 -0
  378. package/src/surfaces/share/ShareSurface.js +1 -0
  379. package/src/surfaces/share/share.model.js +1 -0
  380. package/src/surfaces/share/share.render.js +1 -0
  381. package/src/surfaces/source-settings/SourceSettingsSurface.js +1 -0
  382. package/src/surfaces/source-settings/sourceSettings.model.js +1 -0
  383. package/src/surfaces/source-settings/sourceSettings.render.js +1 -0
  384. package/src/surfaces/surfaceContext.js +1 -0
  385. package/src/surfaces/tree/TreeSurface.js +1 -0
  386. package/src/surfaces/tree/tree.model.js +1 -0
  387. package/src/surfaces/tree/tree.render.js +1 -0
  388. package/src/tooling/portable/adapters/cli/cli.common-output.case.mjs +153 -0
  389. package/src/tooling/portable/adapters/cli/cli.handoff-sibling-allocation.case.mjs +52 -0
  390. package/src/tooling/portable/adapters/cli/cli.run.case.mjs +372 -0
  391. package/src/tooling/portable/adapters/cli/cli.summaryProjection.case.mjs +46 -0
  392. package/src/tooling/portable/audit/audit.capability.case.mjs +45 -0
  393. package/src/tooling/portable/fixtures/legacy-artifacts/collaboration/dogfood/001-tiinex-development-dogfood-collaboration-model.trace.fixture.txt +37 -0
  394. package/src/tooling/portable/fixtures/legacy-artifacts/handoff/tooling/001-v480-tooling-workflow-schema-enablement-handoff.trace.fixture.txt +108 -0
  395. package/src/tooling/portable/fixtures/legacy-artifacts/handoff/tooling/002-v481-tooling-recipient-relative-handoff-material-closure-planner-foundation-handoff.trace.fixture.txt +130 -0
  396. package/src/tooling/portable/fixtures/legacy-artifacts/loom/role/001-loom-role.trace.fixture.txt +61 -0
  397. package/src/tooling/portable/fixtures/legacy-artifacts/sigma/role/001-1-sigma-role.trace.fixture.txt +61 -0
  398. package/src/tooling/portable/fixtures/legacy-artifacts/tooling/dogfood/001-1-1-1-1-1-1-1-site-tooling-v474-loaded-parent-identity-evidence-closure-result.trace.fixture.txt +48 -0
  399. package/src/tooling/portable/fixtures/legacy-artifacts/tooling/dogfood/001-1-1-1-1-1-1-site-tooling-v474-loaded-parent-identity-evidence-closure.trace.fixture.txt +48 -0
  400. package/src/tooling/portable/fixtures/legacy-artifacts/tooling/dogfood/001-1-1-1-1-1-site-tooling-v473-portable-parent-authority-coherence-metadata-fidelity-closure-result.trace.fixture.txt +48 -0
  401. package/src/tooling/portable/fixtures/legacy-artifacts/tooling/dogfood/001-1-1-1-1-site-tooling-v473-portable-parent-authority-coherence-metadata-fidelity-closure.trace.fixture.txt +48 -0
  402. package/src/tooling/portable/fixtures/legacy-artifacts/tooling/dogfood/001-1-1-1-site-tooling-v472-portable-exact-authoring-fidelity-closure-result.trace.fixture.txt +48 -0
  403. package/src/tooling/portable/fixtures/legacy-artifacts/tooling/dogfood/001-1-1-site-tooling-v472-portable-exact-authoring-fidelity-closure.trace.fixture.txt +48 -0
  404. package/src/tooling/portable/fixtures/legacy-artifacts/tooling/dogfood/001-1-site-tooling-v471-portable-lineage-authoring-closure-result.trace.fixture.txt +48 -0
  405. package/src/tooling/portable/fixtures/legacy-artifacts/tooling/dogfood/001-site-tooling-v471-portable-lineage-authoring-closure.trace.fixture.txt +39 -0
  406. package/src/tooling/portable/fixtures/legacy-artifacts/tooling/dogfood/002-1-v475-canonical-artifact-envelope-reference-integrity-validation.trace.fixture.txt +43 -0
  407. package/src/tooling/portable/fixtures/legacy-artifacts/tooling/dogfood/003-1-v476-canonical-authority-binding-integrity-method-lineage-alloca.trace.fixture.txt +42 -0
  408. package/src/tooling/portable/fixtures/legacy-artifacts/tooling/dogfood/027-handoff-package-workspace-archive-and-control-plane-minimality-audit.trace.fixture.txt +56 -0
  409. package/src/tooling/portable/fixtures/legacyArtifactFixtures.mjs +34 -0
  410. package/src/tooling/portable/grounding/grounding.capsule.case.mjs +65 -0
  411. package/src/tooling/portable/grounding/grounding.readiness.case.mjs +543 -0
  412. package/src/tooling/portable/grounding/grounding.semanticIntegration.case.mjs +131 -0
  413. package/src/tooling/portable/handoff/boundedWorkspaceRepresentation.case.mjs +103 -0
  414. package/src/tooling/portable/handoff/carrierLineage.fixedWidth.case.mjs +97 -0
  415. package/src/tooling/portable/handoff/coldStartQualification.case.mjs +293 -0
  416. package/src/tooling/portable/handoff/fixtures/027-invalid-audit-result.fixture.txt +192 -0
  417. package/src/tooling/portable/handoff/fixtures/027-invalid-return-handoff.fixture.txt +92 -0
  418. package/src/tooling/portable/handoff/fixtures/cold-start-qualification.v1.examples.json +60 -0
  419. package/src/tooling/portable/handoff/handoff.manufacture.case.mjs +293 -0
  420. package/src/tooling/portable/handoff/materialClosure.case.mjs +727 -0
  421. package/src/tooling/portable/handoff/multiRootManufacture.case.mjs +615 -0
  422. package/src/tooling/portable/handoff/operatorBridgeCore.case.mjs +205 -0
  423. package/src/tooling/portable/handoff/workspaceLandingPlan.case.mjs +143 -0
  424. package/src/tooling/portable/input/node.input.case.mjs +293 -0
  425. package/src/tooling/portable/lifecycle/lifecycle.readiness.case.mjs +179 -0
  426. package/src/tooling/portable/lineage/fixtures/lineage.integrity.repair-projection.v1.examples.json +605 -0
  427. package/src/tooling/portable/lineage/lineage.integrity.shared-capability.case.mjs +37 -0
  428. package/src/tooling/portable/lineage/publicationProviderReceipt.fixture.mjs +50 -0
  429. package/src/tooling/portable/package/fixtures/reference-relation-generation-authority.trace.md +84 -0
  430. package/src/tooling/portable/package/fixtures/tiinex.root.v1.package-authority.contract-fixture.md +64 -0
  431. package/src/tooling/portable/package/fixtures/tiinex.schema.generation.v1.generation-binding.contract-fixture.md +140 -0
  432. package/src/tooling/portable/package/fixtures/tiinex.schema.transition.companion.v1.contract-fixture.md +73 -0
  433. package/src/tooling/portable/package/fixtures/tiinex.semantic.package.v1.contract-fixture.md +147 -0
  434. package/src/tooling/portable/package/fixtures/tiinex.transition.definition.v1.package-contract-fixture.md +77 -0
  435. package/src/tooling/portable/providers/schema.providers.genericity.case.mjs +31 -0
  436. package/src/tooling/portable/reduction/reduction.preflight.case.mjs +298 -0
  437. package/src/tooling/portable/schema/fixtures/evidence-preservation-body.inheritance-record-fixture.md +65 -0
  438. package/src/tooling/portable/schema/fixtures/tiinex.portal.time.v1.contract-fixture.md +294 -0
  439. package/src/tooling/portable/schema/fixtures/tiinex.root.v1.contract-fixture.md +584 -0
  440. package/src/tooling/portable/schema/fixtures/tiinex.root.v1.machine-shape.contract-fixture.md +44 -0
  441. package/src/tooling/portable/schema/fixtures/tiinex.root.v1.ordinary-target.contract-fixture.md +630 -0
  442. package/src/tooling/portable/schema/fixtures/tiinex.schema.contract.v1.repeated-record.contract-fixture.md +69 -0
  443. package/src/tooling/portable/schema/fixtures/tiinex.schema.generation.v1.repeated-record.contract-fixture.md +98 -0
  444. package/src/tooling/portable/schema/fixtures/tiinex.schema.inheritance.v1.repeated-record.contract-fixture.md +58 -0
  445. package/src/tooling/portable/schema/fixtures/tiinex.task.v1.contract-fixture.md +165 -0
  446. package/src/tooling/portable/schema/fixtures/tiinex.transition.definition.v1.contract-fixture.md +744 -0
  447. package/src/tooling/portable/schema/fixtures/tiinex.transition.definition.v1.field-domain.contract-fixture.md +319 -0
  448. package/src/transitions/canonical-schema-cache/053d46ce082d4ec261b82abc44ecca403d61e240/tiinex.relation.v1.schema.md +240 -0
  449. package/src/transitions/canonical-schema-cache/053d46ce082d4ec261b82abc44ecca403d61e240/tiinex.schema.contract.v1.schema.md +391 -0
  450. package/src/transitions/canonical-schema-cache/053d46ce082d4ec261b82abc44ecca403d61e240/tiinex.schema.generation.v1.schema.md +379 -0
  451. package/src/transitions/canonical-schema-cache/053d46ce082d4ec261b82abc44ecca403d61e240/tiinex.schema.transition.companion.v1.schema.md +265 -0
  452. package/src/transitions/canonical-schema-cache/053d46ce082d4ec261b82abc44ecca403d61e240/tiinex.semantic.package.v1.schema.md +402 -0
  453. package/src/transitions/canonical-schema-cache/52ecdea0a75893882ce282214d155f70e1309c2a/tiinex.topic.v1.schema.md +197 -0
  454. package/src/transitions/canonical-schema-cache/d69b8ff55a56b8cb9282b8684db6a938a4435b94/tiinex.root.v1.schema.md +797 -0
  455. package/src/transitions/canonical-schema-cache/d69b8ff55a56b8cb9282b8684db6a938a4435b94/tiinex.transition.definition.v1.schema.md +1062 -0
  456. package/src/transitions/canonicalTransition.packageContracts.js +22 -0
  457. package/src/transitions/canonicalTransition.productDefaults.js +105 -0
  458. package/src/transitions/canonicalTransition.schemaCache.case.mjs +45 -0
  459. package/src/transitions/canonicalTransition.schemaCache.js +81 -0
  460. package/src/transitions/canonicalTransition.semanticPackage.js +146 -0
  461. package/src/transitions/record.transitions.case.mjs +88 -0
  462. package/src/transitions/transition.authorityRepresentation.js +55 -0
  463. package/src/transitions/transition.availabilityPlanner.js +376 -0
  464. package/src/transitions/transition.availabilitySemantics.js +150 -0
  465. package/src/transitions/transition.definitionReadProjection.js +107 -0
  466. package/src/transitions/transition.definitionRegistry.js +355 -0
  467. package/src/transitions/transition.definitionRegistryAggregation.js +21 -0
  468. package/src/transitions/transition.definitions.js +46 -0
  469. package/src/transitions/transition.explicitGenerationPlanner.js +58 -0
  470. package/src/transitions/transition.generationInputPlanner.js +19 -0
  471. package/src/transitions/transition.interpretationMaterializer.js +2 -0
  472. package/src/transitions/transition.invocationBindingPacket.js +52 -0
  473. package/src/transitions/transition.invocationBindingPlanner.js +467 -0
  474. package/src/transitions/transition.legacyShorthand.js +133 -0
  475. package/src/transitions/transition.localArtifactMaterializers.js +16 -0
  476. package/src/transitions/transition.localCreateCapability.js +111 -0
  477. package/src/transitions/transition.outputMaterializationPlanner.js +336 -0
  478. package/src/transitions/transition.parentReference.js +90 -0
  479. package/src/transitions/transition.presentation.js +43 -0
  480. package/src/transitions/transition.productPreparation.js +377 -0
  481. package/src/transitions/transition.productPresentation.browser.js +28 -0
  482. package/src/transitions/transition.productPresentation.js +55 -0
  483. package/src/transitions/transition.referenceCreateCapability.js +119 -0
  484. package/src/transitions/transition.referenceTarget.js +50 -0
  485. package/src/transitions/transition.relationMaterializer.js +2 -0
  486. package/src/transitions/transition.resultSemantics.js +453 -0
  487. package/src/transitions/transition.taskMaterializer.js +2 -0
  488. package/src/transitions/transition.topicMaterializer.js +2 -0
  489. package/src/transitions/transition.validate.case.mjs +58 -0
  490. package/src/ui/cards/ArtifactCard.js +1 -0
  491. package/src/ui/cards/SchemaCard.js +1 -0
  492. package/src/ui/cards/SourceCard.js +1 -0
  493. package/src/ui/dialog.presenter.js +24 -0
  494. package/src/ui/feedback/DegradedNotice.js +1 -0
  495. package/src/ui/feedback/EmptyState.js +1 -0
  496. package/src/ui/feedback/ValidationNotice.js +1 -0
  497. package/src/ui/forms/FormRenderer.js +1 -0
  498. package/src/ui/forms/fields/MarkdownField.js +1 -0
  499. package/src/ui/forms/fields/SelectField.js +1 -0
  500. package/src/ui/forms/fields/SourcePickerField.js +1 -0
  501. package/src/ui/forms/fields/TextField.js +1 -0
  502. package/src/ui/icon.paths.js +37 -0
  503. package/src/ui/layout/Panel.js +1 -0
  504. package/src/ui/layout/ResponsiveFrame.js +1 -0
  505. package/src/ui/layout/SplitView.js +1 -0
  506. package/src/ui/layout/Stack.js +1 -0
  507. package/src/ui/panels/DetailPanel.js +1 -0
  508. package/src/ui/panels/LineagePanel.js +1 -0
  509. package/src/ui/panels/SourcePanel.js +1 -0
  510. package/src/ui/primitives/Badge.js +1 -0
  511. package/src/ui/primitives/Badge.jsx +5 -0
  512. package/src/ui/primitives/Button.js +1 -0
  513. package/src/ui/primitives/Button.jsx +12 -0
  514. package/src/ui/primitives/Card.js +1 -0
  515. package/src/ui/primitives/Field.js +1 -0
  516. package/src/ui/primitives/Field.jsx +21 -0
  517. package/src/ui/primitives/Icon.jsx +90 -0
  518. package/src/ui/primitives/Modal.jsx +27 -0
  519. package/src/validation/i18n.js +37 -0
  520. package/src/validation/validateArtifact.case.mjs +41 -0
  521. package/src/verses/column/ColumnVerse.js +1 -0
  522. package/src/verses/column/column.model.js +6 -0
  523. package/src/verses/column/column.project.js +7 -0
  524. package/src/verses/context.js +26 -0
  525. package/src/verses/contracts.js +1 -0
  526. package/src/verses/hostRegistry.js +47 -0
  527. package/src/verses/registry.js +22 -0
  528. package/src/verses/universe.model.js +8 -0
  529. package/src/verses/universe.presenter.js +8 -0
  530. package/src/verses/universe.project.js +12 -0
  531. package/src/viewer.js +34 -0
  532. package/src/workspace.model.js +5 -0
  533. package/src/workspaces/workspace.actions.js +1 -0
  534. package/src/workspaces/workspace.artifactActions.js +56 -0
  535. package/src/workspaces/workspace.auditView.js +153 -0
  536. package/src/workspaces/workspace.candidates.js +149 -0
  537. package/src/workspaces/workspace.config.js +153 -0
  538. package/src/workspaces/workspace.configuredSource.js +68 -0
  539. package/src/workspaces/workspace.discoveryProgress.js +34 -0
  540. package/src/workspaces/workspace.discoveryView.js +386 -0
  541. package/src/workspaces/workspace.displayFilters.js +63 -0
  542. package/src/workspaces/workspace.displayOptions.js +58 -0
  543. package/src/workspaces/workspace.emptyStateCopy.js +24 -0
  544. package/src/workspaces/workspace.entrypointLifecycle.js +131 -0
  545. package/src/workspaces/workspace.entrypointViewIntent.js +83 -0
  546. package/src/workspaces/workspace.entrypoints.js +157 -0
  547. package/src/workspaces/workspace.feedSort.js +152 -0
  548. package/src/workspaces/workspace.import.js +212 -0
  549. package/src/workspaces/workspace.importConflicts.js +200 -0
  550. package/src/workspaces/workspace.importLifecycle.case.mjs +103 -0
  551. package/src/workspaces/workspace.lifecycle.case.mjs +353 -0
  552. package/src/workspaces/workspace.lifecycle.js +357 -0
  553. package/src/workspaces/workspace.lineageView.js +244 -0
  554. package/src/workspaces/workspace.localSourceLifecycle.js +91 -0
  555. package/src/workspaces/workspace.materialLedger.js +110 -0
  556. package/src/workspaces/workspace.materialReconciliation.case.mjs +164 -0
  557. package/src/workspaces/workspace.materialReconciliation.js +390 -0
  558. package/src/workspaces/workspace.memberIdentity.js +140 -0
  559. package/src/workspaces/workspace.model.js +2 -0
  560. package/src/workspaces/workspace.navigation.js +20 -0
  561. package/src/workspaces/workspace.openSemantics.js +33 -0
  562. package/src/workspaces/workspace.pathTree.js +132 -0
  563. package/src/workspaces/workspace.persistence.case.mjs +271 -0
  564. package/src/workspaces/workspace.persistence.js +469 -0
  565. package/src/workspaces/workspace.persistenceCache.js +41 -0
  566. package/src/workspaces/workspace.persistenceClear.js +45 -0
  567. package/src/workspaces/workspace.persistencePresentation.js +93 -0
  568. package/src/workspaces/workspace.persistenceRecovery.js +147 -0
  569. package/src/workspaces/workspace.persistenceRouteCache.js +82 -0
  570. package/src/workspaces/workspace.publicationReceipts.case.mjs +36 -0
  571. package/src/workspaces/workspace.publicationReceipts.js +56 -0
  572. package/src/workspaces/workspace.recoverabilityView.js +264 -0
  573. package/src/workspaces/workspace.route.js +432 -0
  574. package/src/workspaces/workspace.runtimeCanonical.js +18 -0
  575. package/src/workspaces/workspace.sourceMaterial.js +71 -0
  576. package/src/workspaces/workspace.sourceRecordPath.js +5 -0
  577. package/src/workspaces/workspace.sourceRecords.js +75 -0
  578. package/src/workspaces/workspace.store.js +3 -0
  579. package/src/workspaces/workspace.summary.js +116 -0
  580. package/src/workspaces/workspace.timePortal.js +137 -0
@@ -0,0 +1,257 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { Badge } from '../../ui/primitives/Badge.jsx';
3
+ import { Button } from '../../ui/primitives/Button.jsx';
4
+ import { TextareaField, TextField } from '../../ui/primitives/Field.jsx';
5
+ import { Modal } from '../../ui/primitives/Modal.jsx';
6
+ import { createRecordActionResult, RecordActionKind } from '@tiinex/core/actions/record.actions.js';
7
+ import { createReferenceDraft } from '@tiinex/core/transitions/record.transitions.js';
8
+ import { isTransitionAction } from '../../transitions/transition.presentation.js';
9
+ import { isCanonicalTransitionProductAction } from '../../transitions/transition.productPresentation.js';
10
+ import { ContinuationDialog, TransitionValidationNotice } from './workspace.continuationDialog.views.jsx';
11
+ import { CanonicalAuthoringDialog } from './workspace.canonicalTaskDialog.views.jsx';
12
+ import { CanonicalReferenceDialog } from './workspace.canonicalReferenceDialog.views.jsx';
13
+ import { SchemaReadView } from './workspace.read.views.jsx';
14
+ import { recordDisplayPath, recordLifecycleBadge, recordSchemaBadge } from './workspace.viewFormatting.js';
15
+ import { readCanonicalTaskAuthoringValues, renderCanonicalTaskEditMarkdown } from '../core/task/tiinex.task.v1.authoring.js';
16
+
17
+
18
+ export function RecordDetailDialog({ record, onDismiss, onLineage, onShare }) {
19
+ const source = record?.source || {};
20
+ const displayPath = recordDisplayPath(record || {});
21
+ const isSourceBacked = Boolean(source.adapterId && source.adapterId !== 'local');
22
+ const historical = Boolean(record?.historicalSnapshot?.materializedCommit || record?.sourceMode === 'source-backed-historical');
23
+ return (
24
+ <Modal title={record?.title || 'Artifact'} onDismiss={onDismiss} className="tx-dialog-record-detail">
25
+ <div className="tx-record-detail tx-record-read-detail">
26
+ <div className="tx-card-badges">
27
+ {recordLifecycleBadge(record) ? <Badge title="Lifecycle/publication state">{recordLifecycleBadge(record)}</Badge> : null}
28
+ {record?.status ? <Badge title="Record status">{record.status}</Badge> : null}
29
+ <Badge>{recordSchemaBadge(record)}</Badge>
30
+ <Badge>{historical ? 'historical source snapshot' : isSourceBacked ? 'source-backed' : 'local/session'}</Badge>
31
+ </div>
32
+ <DeferredSchemaReadView record={record} />
33
+ <details className="tx-record-provenance-details">
34
+ <summary>Provenance / envelope</summary>
35
+ <dl className="tx-record-meta">
36
+ <div><dt>Boundary</dt><dd>{isSourceBacked ? (source.boundary || 'Explicit source boundary') : 'Browser-local session material; no GitHub provenance inferred.'}</dd></div>
37
+ {displayPath ? <div><dt>Path</dt><dd>{displayPath}</dd></div> : null}
38
+ {source.label ? <div><dt>Source</dt><dd>{source.label}</dd></div> : null}
39
+ {source.adapterId ? <div><dt>Adapter</dt><dd>{source.adapterId} · {source.sourceKind || source.kind || 'source'}</dd></div> : null}
40
+ {record?.envelopeSchemaId ? <div><dt>Envelope</dt><dd>{record.envelopeSchemaId}</dd></div> : null}
41
+ {record?.schemaId ? <div><dt>Current schema</dt><dd>{record.schemaId}</dd></div> : null}
42
+ {record?.currentCreatedAt ? <div><dt>Current created</dt><dd>{record.currentCreatedAt}</dd></div> : null}
43
+ {record?.parentSchemaId ? <div><dt>Parent schema</dt><dd>{record.parentSchemaId}</dd></div> : null}
44
+ {record?.trace ? <div><dt>Trace</dt><dd>{record.trace}</dd></div> : null}
45
+ {record?.origin ? <div><dt>Origin</dt><dd>{record.origin}</dd></div> : null}
46
+ {record?.rootDisclosure ? <div><dt>Root fallback</dt><dd>{record.rootDisclosure}</dd></div> : null}
47
+ </dl>
48
+ </details>
49
+ {!record?.markdown ? <p className="tx-muted">{record?.materialAvailability === 'material-unavailable' ? 'Material is unavailable in this route/session shell; source boundary and path are preserved.' : 'No embedded Markdown body is available for this record.'}</p> : null}
50
+ <div className="tx-dialog-actions">
51
+ <Button variant="ghost" onClick={onDismiss}>Close</Button>
52
+ {onLineage && !historical ? <Button variant="ghost" icon="lineage" onClick={onLineage}>Lineage</Button> : null}
53
+ {onShare && !historical ? <Button variant="primary" icon="shareNodes" onClick={onShare}>Share artifact</Button> : null}
54
+ </div>
55
+ </div>
56
+ </Modal>
57
+ );
58
+ }
59
+
60
+ function DeferredSchemaReadView({ record }) {
61
+ const [ready, setReady] = useState(false);
62
+ useEffect(() => {
63
+ setReady(false);
64
+ const raf = requestAnimationFrame(() => setReady(true));
65
+ return () => cancelAnimationFrame(raf);
66
+ }, [record?.id]);
67
+ if (!ready) {
68
+ return (
69
+ <section className="tx-schema-read-view tx-schema-read-deferred" aria-label="Artifact read view loading">
70
+ <div className="tx-schema-read-skeleton"><strong>{record?.title || 'Artifact'}</strong><span>Opening read view…</span></div>
71
+ </section>
72
+ );
73
+ }
74
+ return <SchemaReadView record={record} />;
75
+ }
76
+
77
+ export function RecordMarkdownDialog({ record, onDismiss }) {
78
+ return (
79
+ <Modal title={`Markdown · ${record?.title || 'Artifact'}`} onDismiss={onDismiss} className="tx-dialog-record-markdown">
80
+ <div className="tx-record-detail">
81
+ <div className="tx-card-badges">
82
+ <Badge>{record?.kind || 'artifact'}</Badge>
83
+ <Badge>{recordDisplayPath(record || {}) || 'no path'}</Badge>
84
+ </div>
85
+ {record?.markdown ? <pre className="tx-record-markdown-preview tx-full-markdown-preview">{String(record.markdown)}</pre> : <p className="tx-muted">Markdown is not available in this route/session shell. Source boundary and path are preserved.</p>}
86
+ <div className="tx-dialog-actions">
87
+ <Button variant="ghost" onClick={onDismiss}>Close</Button>
88
+ </div>
89
+ </div>
90
+ </Modal>
91
+ );
92
+ }
93
+
94
+ export function RecordActionDialog({ record, action, schemaRegistry, workspaceId = '', workspaceRecords = [], referenceTargets = [], placementTargets = [], selectionSession = null, selectionResult = null, onBeginSelection, onSelectionConsumed, onDismiss, onShare, onCreateTransition, onCreateCanonicalTransition, onCreateCanonicalReference, onUpdateLocalDraft }) {
95
+ const actionId = action?.id || action;
96
+ if (isCanonicalTransitionProductAction(action)) {
97
+ if (action?.referenceCapability?.state === 'qualified') return <CanonicalReferenceDialog record={record} action={action} workspaceId={workspaceId} targets={referenceTargets} selectionSession={selectionSession} selectionResult={selectionResult} onBeginSelection={onBeginSelection} onSelectionConsumed={onSelectionConsumed} onDismiss={onDismiss} onCreate={onCreateCanonicalReference} />;
98
+ return <CanonicalAuthoringDialog record={record} action={action} workspaceId={workspaceId} placementTargets={placementTargets} selectionSession={selectionSession} selectionResult={selectionResult} onBeginSelection={onBeginSelection} onSelectionConsumed={onSelectionConsumed} onDismiss={onDismiss} onCreate={onCreateCanonicalTransition} />;
99
+ }
100
+ if (isTransitionAction(action)) {
101
+ return <ContinuationDialog record={record} schemaRegistry={schemaRegistry} transitionDefinition={action.transitionDefinition} workspaceRecords={workspaceRecords} onDismiss={onDismiss} onCreateTransition={onCreateTransition} />;
102
+ }
103
+ if (actionId === RecordActionKind.continue) {
104
+ return <ContinuationDialog record={record} schemaRegistry={schemaRegistry} workspaceRecords={workspaceRecords} onDismiss={onDismiss} onCreateTransition={onCreateTransition} />;
105
+ }
106
+ if (actionId === RecordActionKind.markdown) {
107
+ return <RecordMarkdownDialog record={record} onDismiss={onDismiss} />;
108
+ }
109
+ if (actionId === RecordActionKind.editLocal) {
110
+ return <LocalDraftEditDialog record={record} onDismiss={onDismiss} onUpdate={onUpdateLocalDraft} />;
111
+ }
112
+ if (actionId === RecordActionKind.reference) {
113
+ const draft = createReferenceDraft(record);
114
+ const result = createRecordActionResult(record, actionId);
115
+ return (
116
+ <Modal title="Preserve evidence leaf" onDismiss={onDismiss}>
117
+ <div className="tx-record-action-result">
118
+ <div className="tx-card-badges">
119
+ <Badge>{draft.schema}</Badge>
120
+ <Badge>{draft.kind}</Badge>
121
+ <Badge>{draft.transition.parentBoundary}</Badge>
122
+ </div>
123
+ <p className="tx-muted">Creates a browser-local Evidence draft from the selected record. This is not the old cross-artifact Reference relation; no source provenance is inferred.</p>
124
+ <TransitionValidationNotice validation={draft.validation} />
125
+ <pre className="tx-record-markdown-preview">{draft.markdown}</pre>
126
+ <div className="tx-dialog-actions">
127
+ <Button variant="ghost" onClick={onDismiss}>Close</Button>
128
+ <Button variant="ghost" icon="shareNodes" onClick={() => onShare?.(record)}>Share parent artifact</Button>
129
+ <Button variant="primary" icon="reference" onClick={() => onCreateTransition?.(record, draft)}>Create evidence</Button>
130
+ </div>
131
+ {result ? <p className="tx-muted tx-action-caption">Evidence preservation capsule remains available for handoff copy: {result.intent}.</p> : null}
132
+ </div>
133
+ </Modal>
134
+ );
135
+ }
136
+ const result = createRecordActionResult(record, actionId);
137
+ if (!result) return null;
138
+ return (
139
+ <Modal title={result.title || 'Record action'} onDismiss={onDismiss}>
140
+ <div className="tx-record-action-result">
141
+ <div className="tx-card-badges">
142
+ <Badge>{result.schema}</Badge>
143
+ <Badge>{result.intent}</Badge>
144
+ <Badge>{result.sourceBoundary}</Badge>
145
+ </div>
146
+ <p className="tx-muted">This is a concrete Tiinex action result, not a decorative button. Copy it into a handoff, prompt, issue, or future builder.</p>
147
+ <pre className="tx-record-markdown-preview">{result.text}</pre>
148
+ <div className="tx-dialog-actions">
149
+ <Button variant="ghost" onClick={onDismiss}>Close</Button>
150
+ <Button variant="primary" icon="shareNodes" onClick={() => onShare?.(record)}>Share artifact</Button>
151
+ </div>
152
+ </div>
153
+ </Modal>
154
+ );
155
+ }
156
+
157
+
158
+ function LocalDraftEditDialog({ record, onDismiss, onUpdate }) {
159
+ const taskAuthoring = readCanonicalTaskAuthoringValues(record?.markdown || '');
160
+ const schemaAware = record?.schemaId === 'tiinex.task.v1' && record?.sourceMode === 'local-transition-canonical' && taskAuthoring.qualified;
161
+ const [markdown, setMarkdown] = useState(() => String(record?.markdown || ''));
162
+ const [taskValues, setTaskValues] = useState(() => ({ ...(taskAuthoring.values || {}) }));
163
+ const [error, setError] = useState('');
164
+ function setTaskValue(name, value) { setTaskValues((current) => ({ ...current, [name]: value })); }
165
+ async function submit(event) {
166
+ event.preventDefault();
167
+ let candidateMarkdown = markdown;
168
+ if (schemaAware) {
169
+ const rendered = renderCanonicalTaskEditMarkdown(record?.markdown || '', taskValues);
170
+ if (rendered.state !== 'rendered') return setError('Complete every required Task field before saving.');
171
+ candidateMarkdown = rendered.markdown;
172
+ } else if (!String(markdown || '').trim()) return setError('Draft Markdown is required.');
173
+ setError('');
174
+ const result = await onUpdate?.(record, candidateMarkdown);
175
+ if (result?.ok === false) setError(result.notice || 'Local draft could not be updated.');
176
+ }
177
+ return (
178
+ <Modal title={`Edit ${record?.title || 'local draft'}`} onDismiss={onDismiss} initialFocus={schemaAware ? 'localDraftTask-Summary' : 'localDraftMarkdown'}>
179
+ <form className="tx-form" onSubmit={submit} data-form="local-draft-edit-form">
180
+ {schemaAware ? taskAuthoring.requiredInputs.map((name, index) => name === 'Summary'
181
+ ? <TextField key={name} id={`localDraftTask-${name}`} label="Task title" value={taskValues[name] || ''} onChange={(value) => setTaskValue(name, value)} required autoFocus={index === 0} />
182
+ : <TextareaField key={name} id={`localDraftTask-${name}`} label={name} value={taskValues[name] || ''} onChange={(value) => setTaskValue(name, value)} rows={3} required />)
183
+ : <TextareaField id="localDraftMarkdown" label="Artifact Markdown" value={markdown} onChange={setMarkdown} rows={18} required autoFocus />}
184
+ <p className="tx-muted">{schemaAware ? 'Edits the canonical Task through its schema-owned authoring fields. The existing local mutation command still preserves Current Schema, Parent continuity, record identity, path, source boundary, Created At, and refreshes verified self-integrity.' : 'Edits this browser-local compatibility draft in place. Current Schema, Parent continuity, record identity, path, source boundary, and Created At remain fixed; the exact schema validator must accept the edited artifact before it is saved.'}</p>
185
+ {error ? <p className="tx-form-error" role="alert">{error}</p> : null}
186
+ <div className="tx-dialog-actions">
187
+ <Button type="button" variant="ghost" onClick={onDismiss}>Cancel</Button>
188
+ <Button type="submit" variant="primary" icon="edit">Save local draft</Button>
189
+ </div>
190
+ </form>
191
+ </Modal>
192
+ );
193
+ }
194
+
195
+
196
+ export function CreateWorkspaceDialog({ error, onSubmit, onDismiss }) {
197
+ const [name, setName] = useState('');
198
+ function submit(event) {
199
+ event.preventDefault();
200
+ onSubmit(name);
201
+ }
202
+ return (
203
+ <Modal title="Create workspace" onDismiss={onDismiss} initialFocus="workspaceName">
204
+ <form className="tx-form" onSubmit={submit} data-form="create-workspace-form">
205
+ <TextField
206
+ id="workspaceName"
207
+ name="workspaceName"
208
+ label="Workspace name"
209
+ value={name}
210
+ onChange={setName}
211
+ required
212
+ error={error}
213
+ autoFocus
214
+ />
215
+ <p className="tx-muted">Local/session. No GitHub provenance inferred.</p>
216
+ <div className="tx-dialog-actions">
217
+ <Button type="button" variant="ghost" onClick={onDismiss}>Cancel</Button>
218
+ <Button type="submit" variant="primary" icon="create">Create</Button>
219
+ </div>
220
+ </form>
221
+ </Modal>
222
+ );
223
+ }
224
+
225
+ export function RenameWorkspaceDialog({ workspace, onDismiss, onSubmit }) {
226
+ const [name, setName] = useState(workspace?.title || workspace?.name || '');
227
+ const [error, setError] = useState('');
228
+ function submit(event) {
229
+ event.preventDefault();
230
+ const ok = onSubmit?.(name);
231
+ if (ok === false) setError('Workspace name is required.');
232
+ }
233
+ return (
234
+ <Modal title="Rename workspace" onDismiss={onDismiss} initialFocus="workspaceRenameName">
235
+ <form className="tx-form" onSubmit={submit} data-form="rename-workspace-form">
236
+ <TextField id="workspaceRenameName" label="Workspace name" value={name} onChange={setName} required error={error} autoFocus />
237
+ <p className="tx-muted">Renaming changes the local workspace label only. Source boundaries and loaded material stay untouched.</p>
238
+ <div className="tx-dialog-actions">
239
+ <Button type="button" variant="ghost" onClick={onDismiss}>Cancel</Button>
240
+ <Button type="submit" variant="primary" icon="edit">Save name</Button>
241
+ </div>
242
+ </form>
243
+ </Modal>
244
+ );
245
+ }
246
+
247
+ export function CloseWorkspaceDialog({ workspace, onDismiss, onConfirm }) {
248
+ return (
249
+ <Modal title={`Close ${workspace.title || workspace.name}?`} onDismiss={onDismiss}>
250
+ <p className="tx-muted">Removes this browser session workspace. Source files are not deleted.</p>
251
+ <div className="tx-dialog-actions">
252
+ <Button variant="ghost" onClick={onDismiss}>Cancel</Button>
253
+ <Button variant="danger" icon="close" onClick={onConfirm}>Close workspace</Button>
254
+ </div>
255
+ </Modal>
256
+ );
257
+ }
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { Button } from '../../ui/primitives/Button.jsx';
3
+
4
+ export function WorkspaceSelectionSurface({ session = null, onCancel }) {
5
+ return (
6
+ <section className="tx-workspace-selection-surface tx-workspace-selection-banner" data-selection-role={session?.role || ''} aria-label={session?.title || 'Workspace selection'}>
7
+ <div>
8
+ <strong>{session?.title || 'Choose in workspace'}</strong>
9
+ <p>{session?.guidance || 'Choose one caller-qualified candidate from the workspace surface. Existing workspace context remains visible while selection is active.'}</p>
10
+ </div>
11
+ <Button type="button" variant="ghost" icon="close" onClick={onCancel}>Cancel selection</Button>
12
+ </section>
13
+ );
14
+ }
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import { materialLedgerReceiptSummary } from './workspace.viewFormatting.js';
3
+
4
+ export function SourceReceiptDetails({ latest }) {
5
+ const surfaces = latest?.diagnostics?.surfaces || latest?.diagnostics?.sourcePlan?.surfaces || null;
6
+ const outcome = latest?.diagnostics?.transportOutcome || null;
7
+ const materialLedger = latest?.diagnostics?.materialLedgerReceipt || latest?.diagnostics?.materialLedger || null;
8
+ if (!surfaces && !outcome && !materialLedger) return null;
9
+ const rows = [];
10
+ const pushSurface = (key, label) => {
11
+ const item = surfaces?.[key];
12
+ if (!item?.requested && !item?.attempted && !Number(item?.loaded || 0) && !item?.deferred && !item?.unavailable) return;
13
+ const bits = [];
14
+ if (item.requested) bits.push('requested');
15
+ if (item.attempted) bits.push('attempted');
16
+ if (Number(item.discovered || 0)) bits.push(`${Number(item.discovered || 0)} discovered`);
17
+ if (Number(item.requestedCount || 0) && key !== 'repoFiles') bits.push(`${Number(item.requestedCount || 0)} targets`);
18
+ if (Number(item.loaded || 0)) bits.push(`${Number(item.loaded || 0)} loaded`);
19
+ if (Number(item.failed || 0)) bits.push(`${Number(item.failed || 0)} failed`);
20
+ const surfaceTiers = Array.isArray(item.transportTiers) && item.transportTiers.length ? item.transportTiers.join(' + ') : String(item.transportTier || '').trim();
21
+ if (surfaceTiers) bits.push(`via ${surfaceTiers}`);
22
+ if (item.deferred) bits.push('deferred');
23
+ if (item.unavailable) bits.push('unavailable');
24
+ if (item.skipped) bits.push('skipped');
25
+ rows.push({ key, label, text: bits.join(' · ') || 'no result' });
26
+ };
27
+ pushSurface('repoFiles', 'Repo files');
28
+ pushSurface('explicitFiles', 'Explicit files');
29
+ pushSurface('issueSnapshots', 'Issue snapshots');
30
+ const attempted = Array.isArray(outcome?.attemptedTiers) ? outcome.attemptedTiers.join(' → ') : '';
31
+ const winning = Array.isArray(outcome?.winningTiers) ? outcome.winningTiers.join(' + ') : '';
32
+ return (
33
+ <div className="tx-source-receipt-details" aria-label="Source receipt details">
34
+ {rows.map((row) => <span key={row.key}><strong>{row.label}</strong><small>{row.text}</small></span>)}
35
+ {materialLedger ? <span><strong>Material</strong><small>{materialLedgerReceiptSummary(materialLedger)}</small></span> : null}
36
+ {outcome ? <span><strong>Transport</strong><small>{attempted ? `attempted ${attempted}` : 'attempted tiers unavailable'}{winning ? ` · used ${winning}` : ''}</small></span> : null}
37
+ </div>
38
+ );
39
+ }
40
+
@@ -0,0 +1,56 @@
1
+ import React, { useState } from 'react';
2
+ import { Button } from '../../ui/primitives/Button.jsx';
3
+ import { Modal } from '../../ui/primitives/Modal.jsx';
4
+ import { timePortalIntentLabel } from '../../workspaces/workspace.timePortal.js';
5
+
6
+ export function TimePortalResolveDialog({ timePortal = null, sources = [], busy = false, error = '', onResolve, onDismiss }) {
7
+ const initialSourceId = String(timePortal?.sourceId || (sources.length === 1 ? sources[0]?.id : '') || '');
8
+ const [sourceId, setSourceId] = useState(initialSourceId);
9
+ const [snapshotInput, setSnapshotInput] = useState(String(timePortal?.snapshotInput || timePortal?.snapshot?.inputTarget || ''));
10
+ function submit(event) {
11
+ event.preventDefault();
12
+ onResolve?.({ sourceId, snapshotInput });
13
+ }
14
+ return (
15
+ <Modal title="Resolve source snapshot" onDismiss={onDismiss} initialFocus="timePortalSnapshotInput" className="tx-dialog-time-portal-resolve">
16
+ <form className="tx-form tx-time-portal-resolve-form" onSubmit={submit}>
17
+ <p><strong>TIME PORTAL</strong></p>
18
+ <p className="tx-muted">Time intent is not a commit selector. Paste an explicit GitHub commit/tree URL, exact SHA, branch, or tag. Named refs resolve once to an immutable commit before review.</p>
19
+ {sources.length > 1 ? (
20
+ <label className="tx-select-field"><span>Configured source</span><select value={sourceId} onChange={(event) => setSourceId(event.target.value)}><option value="">Choose source…</option>{sources.map((source) => <option key={source.id} value={source.id}>{source.label} · {source.repository}</option>)}</select></label>
21
+ ) : sources.length === 1 ? <p className="tx-muted">Source: <strong>{sources[0].label}</strong> · {sources[0].repository}</p> : <p className="tx-muted">No GitHub repository source is configured for this workspace.</p>}
22
+ <label className="tx-field"><span>GitHub snapshot target</span><input id="timePortalSnapshotInput" value={snapshotInput} onChange={(event) => setSnapshotInput(event.target.value)} placeholder="https://github.com/Tiinex/docs/tree/&lt;sha&gt; or explicit ref" autoComplete="off" /></label>
23
+ <p className="tx-muted">Intent: {timePortalIntentLabel(timePortal)}</p>
24
+ {error ? <p role="alert" className="tx-error">{error}</p> : null}
25
+ <div className="tx-dialog-actions"><Button type="button" variant="ghost" onClick={onDismiss}>Cancel</Button><Button type="submit" variant="primary" disabled={busy || !sources.length || !snapshotInput.trim()}>{busy ? 'Resolving…' : 'Resolve source snapshot'}</Button></div>
26
+ </form>
27
+ </Modal>
28
+ );
29
+ }
30
+
31
+ export function TimePortalCompactMarker({ timePortal = null }) {
32
+ const exact = String(timePortal?.snapshot?.materializedCommit || '').trim();
33
+ const exactLabel = exact ? `Historical snapshot ${exact}` : 'Historical snapshot';
34
+ const shortCommit = exact ? exact.slice(0, 10) : 'snapshot';
35
+ return (
36
+ <div className="tx-time-portal-compact-marker" role="status" aria-label={exactLabel} title={exactLabel}>
37
+ <strong>Historical</strong>
38
+ <code>{shortCommit}</code>
39
+ </div>
40
+ );
41
+ }
42
+
43
+ export function TimePortalBanner({ timePortal = null, readModel = null, onLoadSnapshot, onReturnLatest }) {
44
+ if (!timePortal) return null;
45
+ const snapshot = timePortal.snapshot || null;
46
+ const exact = snapshot?.materializedCommit || '';
47
+ const state = snapshot ? (readModel?.state || 'not-loaded') : 'unresolved';
48
+ const title = snapshot ? 'Historical snapshot selected' : 'Time Portal intent unresolved';
49
+ return (
50
+ <section className="tx-time-portal-banner" role="status" aria-label="Time Portal historical review" data-time-portal-state={state}>
51
+ <div><strong>{title}</strong><span>{timePortalIntentLabel(timePortal)}</span></div>
52
+ {snapshot ? <div className="tx-time-portal-identity"><span>Source {snapshot.repository}</span><code title={exact}>{exact}</code><span>{readModel?.cacheState === 'cache' ? 'Loaded from cached snapshot bytes; source was not revalidated this session' : state === 'loaded' ? 'Loaded read-only snapshot' : state === 'degraded' ? 'Historical snapshot loaded with diagnostics' : state === 'unavailable' ? 'Snapshot unavailable' : 'Snapshot bytes not loaded in this session'}</span></div> : <p className="tx-muted">Begin/End expresses review intent only. Resolve an explicit source snapshot before historical material is shown.</p>}
53
+ <div className="tx-time-portal-actions">{snapshot && (!readModel || ['unavailable','failed'].includes(readModel.state)) ? <Button type="button" variant="primary" onClick={onLoadSnapshot}>Load snapshot</Button> : null}<Button type="button" variant="ghost" onClick={onReturnLatest}>Return to latest</Button></div>
54
+ </section>
55
+ );
56
+ }
@@ -0,0 +1,107 @@
1
+ import React, { useMemo } from 'react';
2
+ import { Badge } from '../../ui/primitives/Badge.jsx';
3
+ import { Icon } from '../../ui/primitives/Icon.jsx';
4
+ import { buildWorkspacePathTree } from '../../workspaces/workspace.pathTree.js';
5
+ import { AuditStatusBadge } from './workspace.auditBadge.views.jsx';
6
+ import { recordLifecycleBadge } from './workspace.viewFormatting.js';
7
+ import { WORKSPACE_RECORD_PRIMARY_INTENT, workspaceRecordPrimaryIntent, workspaceRecordPrimaryLabel } from '../../workspaces/workspace.navigation.js';
8
+
9
+ export function WorkspaceTreeState({ workspace, query = '', records, assets = [], auditById = new Map(), expandedFolders = [], onToggleTreeFolder, onOpenRecord, onFocusRecordLineage, onOpenAsset, readOnly = false, selectionActive = false, selectionCandidates = [], onSelectCandidate }) {
10
+ query = String(query || '').trim();
11
+ const rootLabel = `Visible tree · ${workspace.title || workspace.name || 'workspace'}`;
12
+ const tree = useMemo(() => buildWorkspacePathTree({
13
+ records,
14
+ assets,
15
+ rootLabel,
16
+ query
17
+ }), [records, assets, rootLabel, query]);
18
+ const selectionByRecordId = useMemo(() => new Map((Array.isArray(selectionCandidates) ? selectionCandidates : []).filter((item) => String(item?.workspaceId || '') === String(workspace?.id || '') && item?.id).map((item) => [String(item.id), item])), [selectionCandidates, workspace?.id]);
19
+ const selectionByFolderPath = useMemo(() => new Map((Array.isArray(selectionCandidates) ? selectionCandidates : []).filter((item) => String(item?.workspaceId || '') === String(workspace?.id || '') && item?.kind === 'folder' && item?.path).map((item) => [String(item.path), item])), [selectionCandidates, workspace?.id]);
20
+ const expandedSet = useMemo(() => new Set(Array.isArray(expandedFolders) ? expandedFolders : []), [expandedFolders]);
21
+ return (
22
+ <div className="tx-workspace-tree-state tx-path-tree-state" role="tree" aria-label="Workspace path tree">
23
+ <div className="tx-tree-root tx-path-tree-root">
24
+ <span><Icon name="tree" /> {tree.rootLabel}</span>
25
+ <TreeCountBadges counts={tree.counts} />
26
+ </div>
27
+ {tree.folders.map((folder) => (
28
+ <TreeFolder key={folder.path || folder.name} folder={folder} query={query} expandedSet={expandedSet} onToggleFolder={onToggleTreeFolder} auditById={auditById} onOpenRecord={onOpenRecord} onFocusRecordLineage={onFocusRecordLineage} onOpenAsset={onOpenAsset} readOnly={readOnly} selectionActive={selectionActive} selectionByRecordId={selectionByRecordId} selectionByFolderPath={selectionByFolderPath} onSelectCandidate={onSelectCandidate} />
29
+ ))}
30
+ {tree.items.map((item) => (
31
+ <TreeLeafItem key={item.id || item.path} item={item} auditById={auditById} onOpenRecord={onOpenRecord} onFocusRecordLineage={onFocusRecordLineage} onOpenAsset={onOpenAsset} readOnly={readOnly} selectionActive={selectionActive} selectionCandidate={selectionByRecordId.get(String(item.source?.id || '')) || null} onSelectCandidate={onSelectCandidate} />
32
+ ))}
33
+ {tree.empty ? <p className="tx-tree-empty">No loaded artifacts or assets yet. Source and workspace boundaries remain visible.</p> : null}
34
+ </div>
35
+ );
36
+ }
37
+
38
+ function TreeFolder({ folder, query, expandedSet = new Set(), onToggleFolder, auditById = new Map(), onOpenRecord, onFocusRecordLineage, onOpenAsset, readOnly = false, selectionActive = false, selectionByRecordId = new Map(), selectionByFolderPath = new Map(), onSelectCandidate }) {
39
+ const open = Boolean(query) || expandedSet.has(folder.path || folder.name || '');
40
+ const folderCandidate = selectionByFolderPath.get(String(folder.path || '')) || null;
41
+ return (
42
+ <details className="tx-tree-folder" open={open} role="group" data-tree-folder-path={folder.path || folder.name || ''} onToggle={(event) => { if (event.currentTarget === event.target && !query) onToggleFolder?.(folder.path || folder.name || '', event.currentTarget.open); }}>
43
+ <summary className="tx-tree-folder-summary" role="treeitem" aria-label={`Folder ${folder.name}`}>
44
+ <span className="tx-tree-folder-name"><Icon name="folderOpen" /> {folder.name}</span>
45
+ <TreeCountBadges counts={folder.counts} />
46
+ </summary>
47
+ {selectionActive && folderCandidate ? <button type="button" className="tx-tree-folder-select" onClick={() => onSelectCandidate?.(folderCandidate)}>Select folder</button> : null}
48
+ <div className="tx-tree-folder-children">
49
+ {folder.folders.map((child) => (
50
+ <TreeFolder key={child.path || child.name} folder={child} query={query} expandedSet={expandedSet} onToggleFolder={onToggleFolder} auditById={auditById} onOpenRecord={onOpenRecord} onFocusRecordLineage={onFocusRecordLineage} onOpenAsset={onOpenAsset} readOnly={readOnly} selectionActive={selectionActive} selectionByRecordId={selectionByRecordId} selectionByFolderPath={selectionByFolderPath} onSelectCandidate={onSelectCandidate} />
51
+ ))}
52
+ {folder.items.map((item) => (
53
+ <TreeLeafItem key={item.id || item.path} item={item} auditById={auditById} onOpenRecord={onOpenRecord} onFocusRecordLineage={onFocusRecordLineage} onOpenAsset={onOpenAsset} readOnly={readOnly} selectionActive={selectionActive} selectionCandidate={selectionByRecordId.get(String(item.source?.id || '')) || null} onSelectCandidate={onSelectCandidate} />
54
+ ))}
55
+ </div>
56
+ </details>
57
+ );
58
+ }
59
+
60
+ function TreeLeafItem({ item, auditById = new Map(), onOpenRecord, onFocusRecordLineage, onOpenAsset, readOnly = false, selectionActive = false, selectionCandidate = null, onSelectCandidate }) {
61
+ if (item.type === 'asset') {
62
+ return (
63
+ <button type="button" className="tx-tree-record-row tx-tree-asset-row tx-tree-leaf-row" role="treeitem" onClick={() => onOpenAsset?.(item.source.id || item.source.path)} title={item.path || ''}>
64
+ <span><Icon name="asset" /> {item.name || item.title || 'Asset'}</span>
65
+ <Badge>{item.source.previewState || item.kind || 'asset'}</Badge>
66
+ </button>
67
+ );
68
+ }
69
+ const auditItem = auditById.get(item.source.id);
70
+ const primaryIntent = workspaceRecordPrimaryIntent({ surface: 'tree', selectionActive, selectionCandidate });
71
+ const openPrimary = () => {
72
+ if (primaryIntent === WORKSPACE_RECORD_PRIMARY_INTENT.select) return onSelectCandidate?.(selectionCandidate);
73
+ if (primaryIntent === WORKSPACE_RECORD_PRIMARY_INTENT.unavailable) return undefined;
74
+ return onOpenRecord?.(item.source.id);
75
+ };
76
+ return (
77
+ <div className="tx-tree-record-row tx-tree-leaf-row" role="treeitem" title={item.path || ''}>
78
+ <button type="button" className="tx-tree-row-main" onClick={openPrimary} aria-label={workspaceRecordPrimaryLabel({ intent: primaryIntent, title: item.name || item.title || 'artifact' })}>
79
+ <span><Icon name="open" /> {item.name || item.title || 'Untitled'}</span>
80
+ </button>
81
+ <span className="tx-tree-row-badges">
82
+ <AuditStatusBadge record={item.source} item={auditItem} />
83
+ {recordLifecycleBadge(item.source) ? <Badge title="Lifecycle/publication state">{recordLifecycleBadge(item.source)}</Badge> : null}
84
+ <Badge>{item.source.kind || item.kind || 'artifact'}</Badge>
85
+ {!readOnly && !selectionActive ? <button type="button" className="tx-tree-row-action" onClick={() => onFocusRecordLineage?.(item.source.id)} aria-label={`Open lineage for ${item.name || item.title || 'artifact'}`} title="Open lineage"><Icon name="lineage" /> Lineage</button> : null}
86
+ {selectionActive && selectionCandidate ? <button type="button" className="tx-tree-record-select" onClick={() => onSelectCandidate?.(selectionCandidate)}>Select</button> : null}
87
+ </span>
88
+ </div>
89
+ );
90
+ }
91
+
92
+ function TreeCountBadges({ counts = {} }) {
93
+ const records = Number(counts.records || 0);
94
+ const leaves = Number(counts.leaves || 0);
95
+ const supporting = Number(counts.supporting || 0) + Number(counts.schemaDefinitions || 0);
96
+ const assets = Number(counts.assets || 0);
97
+ const candidates = Number(counts.workspaceArtifacts || 0);
98
+ return (
99
+ <span className="tx-tree-counts" aria-label={`${records} visible artifacts, ${leaves} visible leaves, ${supporting} visible supporting, ${assets} visible assets, ${candidates} visible workspace artifacts`}>
100
+ {records ? <span className="tx-tree-count-chip" title="Visible after Display options/search"><Icon name="manualFiles" />{records}<small>visible artifacts</small></span> : null}
101
+ {leaves ? <span className="tx-tree-count-chip tx-tree-leaf-chip" title="Visible leaf-role artifacts"><Icon name="lineage" />{leaves}<small>visible leaves</small></span> : null}
102
+ {supporting ? <span className="tx-tree-count-chip tx-tree-supporting-chip" title="Supporting/schema docs"><Icon name="open" />{supporting}</span> : null}
103
+ {assets ? <span className="tx-tree-count-chip"><Icon name="asset" />{assets}</span> : null}
104
+ {candidates ? <span className="tx-tree-count-chip"><Icon name="workspace" />{candidates}</span> : null}
105
+ </span>
106
+ );
107
+ }