@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,63 @@
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import { Badge } from '../../ui/primitives/Badge.jsx';
3
+ import { Button } from '../../ui/primitives/Button.jsx';
4
+ import { Modal } from '../../ui/primitives/Modal.jsx';
5
+
6
+ export const CANONICAL_REFERENCE_SELECTION_ROLE = 'reference-target';
7
+
8
+ export function CanonicalReferenceDialog({ record, action, workspaceId = '', targets = [], selectionSession = null, selectionResult = null, onBeginSelection, onSelectionConsumed, onDismiss, onCreate }) {
9
+ const [selected, setSelected] = useState(null);
10
+ const [error, setError] = useState('');
11
+ const ownerKey = useMemo(() => `reference:${String(action?.definitionKey || action?.id || '')}:${String(workspaceId)}:${String(record?.id || '')}`, [action?.definitionKey, action?.id, workspaceId, record?.id]);
12
+ const enabled = useMemo(() => (Array.isArray(targets) ? targets : []).filter((item) => item?.enabled), [targets]);
13
+ useEffect(() => {
14
+ if (selectionResult?.ok && selectionResult.ownerKey === ownerKey && selectionResult.role === CANONICAL_REFERENCE_SELECTION_ROLE) {
15
+ setSelected(selectionResult.candidate); setError(''); onSelectionConsumed?.(selectionResult.sessionId);
16
+ }
17
+ }, [selectionResult, ownerKey, onSelectionConsumed]);
18
+ if (selectionSession?.ok && selectionSession.ownerKey === ownerKey) return null;
19
+ function beginSelection() {
20
+ if (!enabled.length) return setError('No qualified Reference target is currently available.');
21
+ const started = onBeginSelection?.({
22
+ role: CANONICAL_REFERENCE_SELECTION_ROLE,
23
+ ownerKey,
24
+ originWorkspaceId: workspaceId,
25
+ title: 'Choose Reference target',
26
+ guidance: 'Choose one qualified Task in the visible workspace surface. Reference remains a typed non-parent relation; Parent and provenance do not change.',
27
+ presentation: { verse: 'feed' },
28
+ candidates: enabled
29
+ });
30
+ if (started?.ok === false) setError(started.notice || 'Reference target selection could not start.');
31
+ }
32
+ async function submit(event) {
33
+ event.preventDefault();
34
+ if (!selected) return setError('Choose one qualified Reference target.');
35
+ setError('');
36
+ const result = await onCreate?.(record, action, selected);
37
+ if (result?.ok === false) setError(result.notice || 'Reference Relation could not be created.');
38
+ }
39
+ return (
40
+ <Modal title={action?.label || 'Reference'} onDismiss={onDismiss} className="tx-dialog-reference-review">
41
+ <form className="tx-form" onSubmit={submit} data-form="canonical-reference-form">
42
+ <p className="tx-muted">Create one browser-local Relation artifact from <strong>{record?.title || 'the selected Topic'}</strong> to a distinct qualified Task. Target selection happens in the workspace surface so spatial/source context remains visible.</p>
43
+ <div className="tx-dialog-actions tx-reference-picker-actions">
44
+ <Button type="button" variant="primary" icon="reference" onClick={beginSelection}>{selected ? 'Change target in workspace' : 'Choose target in workspace'}</Button>
45
+ </div>
46
+ {selected ? (
47
+ <div className="tx-record-action-result" data-reference-review="true">
48
+ <div className="tx-card-badges"><Badge>Relation</Badge><Badge>non-parent</Badge><Badge>local draft</Badge></div>
49
+ <p><strong>Subject:</strong> {record?.title || record?.path || 'Topic'}</p>
50
+ <p><strong>Target:</strong> {selected.title || selected.path || 'Task'}</p>
51
+ {selected.path ? <p><strong>Target path:</strong> <code>{selected.path}</code></p> : null}
52
+ <p className="tx-muted">The Relation preserves subject/object identity and explicit non-Parent meaning. Neither participant is mutated and no truth, evidence, authority, dependency, or Parent ancestry is implied.</p>
53
+ </div>
54
+ ) : <p className="tx-muted">No target selected yet.</p>}
55
+ {error ? <p className="tx-form-error" role="alert">{error}</p> : null}
56
+ <div className="tx-dialog-actions">
57
+ <Button type="button" variant="ghost" onClick={onDismiss}>Cancel</Button>
58
+ <Button type="submit" variant="primary" icon="reference" disabled={!selected}>Create local Relation</Button>
59
+ </div>
60
+ </form>
61
+ </Modal>
62
+ );
63
+ }
@@ -0,0 +1,169 @@
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import { Button } from '../../ui/primitives/Button.jsx';
3
+ import { Modal } from '../../ui/primitives/Modal.jsx';
4
+ import { TextareaField, TextField } from '../../ui/primitives/Field.jsx';
5
+ import { firstMissingSchemaFactoryAuthoringInput, initialSchemaFactoryAuthoringValues, isSchemaFactoryViewerCreateAction, normalizeSchemaFactoryAuthoringValues } from '../schema.factory.viewerProjection.js';
6
+
7
+ export const CANONICAL_STORAGE_PLACEMENT_SELECTION_ROLE = 'storage-placement';
8
+ export const CANONICAL_CONTINUITY_PARENT_SELECTION_ROLE = 'continuity-parent';
9
+
10
+ const SHORT_FIELD_NAMES = new Set(['Summary', 'Source Role', 'Target Role', 'Interpretation Action']);
11
+
12
+ export function CanonicalAuthoringDialog({ record, action, workspaceId = '', placementTargets = [], selectionSession = null, selectionResult = null, onBeginSelection, onSelectionConsumed, onDismiss, onCreate, onBack = null }) {
13
+ const requiredInputs = Array.isArray(action?.authoring?.requiredInputs) ? action.authoring.requiredInputs : [];
14
+ const fixedInputs = action?.authoring?.fixedInputs || {};
15
+ const factoryAuthoring = isSchemaFactoryViewerCreateAction(action);
16
+ const inputDescriptors = Object.fromEntries((Array.isArray(action?.authoring?.inputDescriptors) ? action.authoring.inputDescriptors : []).map((descriptor) => [descriptor.name, descriptor]));
17
+ const editableInputs = requiredInputs.filter((name) => !Object.prototype.hasOwnProperty.call(fixedInputs, name));
18
+ const initialValues = factoryAuthoring
19
+ ? { ...initialSchemaFactoryAuthoringValues(action), ...fixedInputs }
20
+ : Object.fromEntries(requiredInputs.map((name) => [name, Object.prototype.hasOwnProperty.call(fixedInputs, name) ? fixedInputs[name] : '']));
21
+ const [values, setValues] = useState(() => initialValues);
22
+ const [error, setError] = useState('');
23
+ const [placementFolder, setPlacementFolder] = useState('');
24
+ const [parentReviewed, setParentReviewed] = useState(false);
25
+ const ownerBase = useMemo(() => `authoring:${String(action?.definitionKey || action?.id || '')}:${String(workspaceId)}:${String(record?.id || 'root')}`, [action?.definitionKey, action?.id, workspaceId, record?.id]);
26
+ useEffect(() => {
27
+ if (!selectionResult?.ok || !String(selectionResult.ownerKey || '').startsWith(`${ownerBase}:`)) return;
28
+ if (selectionResult.role === CANONICAL_STORAGE_PLACEMENT_SELECTION_ROLE) setPlacementFolder(String(selectionResult.candidate?.path || ''));
29
+ if (selectionResult.role === CANONICAL_CONTINUITY_PARENT_SELECTION_ROLE) setParentReviewed(true);
30
+ setError(''); onSelectionConsumed?.(selectionResult.sessionId);
31
+ }, [selectionResult, ownerBase, onSelectionConsumed]);
32
+ const required = new Set(requiredInputs);
33
+ const schemaLabel = action?.authoring?.schemaLabel || action?.authoring?.schemaId || 'Artifact';
34
+ function set(name, value) { setValues((current) => ({ ...current, [name]: value })); }
35
+ async function submit(event) {
36
+ event.preventDefault();
37
+ const finalValues = factoryAuthoring
38
+ ? { ...normalizeSchemaFactoryAuthoringValues(action, values), ...fixedInputs }
39
+ : { ...values, ...fixedInputs };
40
+ const missing = factoryAuthoring
41
+ ? firstMissingSchemaFactoryAuthoringInput(action, finalValues)
42
+ : [...required].find((name) => finalValues[name] === undefined || String(finalValues[name]).trim() === '');
43
+ if (missing) return setError(`${missing} is required.`);
44
+ setError('');
45
+ const result = await onCreate?.(record, action, finalValues, { placementFolder, workspaceId });
46
+ if (result?.ok === false) setError(result.notice || `${schemaLabel} could not be created.`);
47
+ }
48
+ function beginPlacementSelection() {
49
+ const candidates = (Array.isArray(placementTargets) ? placementTargets : []).filter((item) => item?.enabled !== false);
50
+ if (!candidates.length) return setError('No qualified same-workspace storage folder is available.');
51
+ onBeginSelection?.({ role: CANONICAL_STORAGE_PLACEMENT_SELECTION_ROLE, ownerKey: `${ownerBase}:placement`, originWorkspaceId: workspaceId, title: 'Choose storage folder', guidance: 'Choose a same-workspace folder. This changes only browser-local storage placement; Parent, Reference and source provenance stay unchanged.', presentation: { verse: 'tree' }, candidates });
52
+ }
53
+ function beginParentReview() {
54
+ if (!record?.id || !workspaceId) return setError('Continuity Parent is not available for workspace selection.');
55
+ onBeginSelection?.({ role: CANONICAL_CONTINUITY_PARENT_SELECTION_ROLE, ownerKey: `${ownerBase}:parent`, originWorkspaceId: workspaceId, title: 'Review Continuity Parent', guidance: 'This Transition fixes the Parent. The workspace surface identifies that exact parent; selecting another artifact is not authorized.', presentation: { verse: 'feed' }, candidates: [{ kind:'record', key:`continuity-parent:${workspaceId}:${record.id}`, workspaceId, id:record.id, title:record.title || record.path || 'Parent', path:record.path || '', schemaId:record.schemaId || '', enabled:true, boundary:'Fixed by the qualified Transition; review only, not an arbitrary Parent override.' }] });
56
+ }
57
+ const focusInput = editableInputs[0] || requiredInputs[0] || '';
58
+ if (selectionSession?.ok && String(selectionSession.ownerKey || '').startsWith(`${ownerBase}:`)) return null;
59
+ return (
60
+ <Modal title={action?.label || `Create ${schemaLabel}`} onDismiss={onDismiss} initialFocus={focusInput ? authoringInputId(focusInput) : undefined}>
61
+ <form className="tx-form" onSubmit={submit} data-form="canonical-authoring-form">
62
+ {requiredInputs.map((name) => {
63
+ const id = authoringInputId(name);
64
+ const fixed = Object.prototype.hasOwnProperty.call(fixedInputs, name);
65
+ const descriptor = inputDescriptors[name] || null;
66
+ const common = { key: name, id, label: authoringFieldLabel(name, schemaLabel), value: fixed ? fixedInputs[name] : values[name], required: required.has(name) };
67
+ if (fixed) return <TextField {...common} onChange={() => {}} readOnly aria-readonly="true" />;
68
+ if (descriptor?.kind === 'ordinary-group') return <StructuredGroupAuthoringInput key={name} descriptor={descriptor} value={values[name]} onChange={(value) => set(name, value)} />;
69
+ if (descriptor?.kind === 'named-declaration-section') return <NamedDeclarationAuthoringInput key={name} descriptor={descriptor} value={values[name]} onChange={(value) => set(name, value)} />;
70
+ if (factoryAuthoring && ['ordinary-field', 'root-current-summary-body-title'].includes(descriptor?.kind)) return <TextField {...common} onChange={(value) => set(name, value)} autoFocus={name === focusInput} />;
71
+ if (SHORT_FIELD_NAMES.has(name)) return <TextField {...common} onChange={(value) => set(name, value)} autoFocus={name === focusInput} />;
72
+ return <TextareaField {...common} onChange={(value) => set(name, value)} rows={3} autoFocus={name === focusInput} />;
73
+ })}
74
+ <section className="tx-authoring-placement-controls" aria-label="Continuity and storage placement">
75
+ {action?.continuityMode === 'parent' && record ? <div><strong>Continuity Parent</strong><p className="tx-muted">{record.title || record.path || 'Selected artifact'} · fixed by the qualified Transition.</p><Button type="button" variant="ghost" icon="lineage" onClick={beginParentReview}>{parentReviewed ? 'Review Parent again' : 'Review Parent in workspace'}</Button></div> : null}
76
+ <div><strong>Storage placement</strong><p className="tx-muted">{placementFolder ? `Explicit same-workspace folder: ${placementFolder}` : 'Automatic canonical placement'}</p><Button type="button" variant="ghost" icon="folderOpen" onClick={beginPlacementSelection}>{placementFolder ? 'Change storage folder' : 'Choose storage folder'}</Button>{placementFolder ? <Button type="button" variant="ghost" onClick={() => setPlacementFolder('')}>Use automatic</Button> : null}</div>
77
+ </section>
78
+ <p className="tx-muted">{factoryAuthoring
79
+ ? `Creates one standalone browser-local ${schemaLabel} through its qualified Artifact Creation Contract and shared factory renderer/validator. No canonical Transition, Parent, or source provenance is invented.`
80
+ : action?.continuityMode === 'root' ? `Creates one standalone browser-local ${schemaLabel} through the selected qualified canonical Transition. No Parent or source provenance is invented.` : `Creates one browser-local ${schemaLabel} through the qualified canonical Transition from ${record?.title || 'the selected artifact'}. The selected source artifact remains unchanged; no remote write is performed.`}</p>
81
+ {error ? <p className="tx-form-error" role="alert">{error}</p> : null}
82
+ <div className="tx-dialog-actions">
83
+ {onBack ? <Button type="button" variant="ghost" onClick={onBack}>Back</Button> : <Button type="button" variant="ghost" onClick={onDismiss}>Cancel</Button>}
84
+ <Button type="submit" variant="primary" icon={action?.icon || 'create'}>Create local {schemaLabel.toLowerCase()}</Button>
85
+ </div>
86
+ </form>
87
+ </Modal>
88
+ );
89
+ }
90
+
91
+ function StructuredGroupAuthoringInput({ descriptor = {}, value = {}, onChange }) {
92
+ const current = value && typeof value === 'object' && !Array.isArray(value) ? value : {};
93
+ const fields = [...descriptor.requiredFields, ...descriptor.optionalFields];
94
+ function setField(field, next) { onChange?.({ ...current, [field]: next }); }
95
+ return (
96
+ <fieldset className="tx-authoring-structured-group" data-authoring-binding="ordinary-group">
97
+ <legend>{descriptor.name}</legend>
98
+ <p className="tx-muted">Structured fields from the qualified factory descriptor.</p>
99
+ {fields.map((field) => <TextField key={field} id={structuredInputId(descriptor.name, field)} label={field} value={current[field] || ''} onChange={(next) => setField(field, next)} required={descriptor.requiredFields.includes(field)} />)}
100
+ </fieldset>
101
+ );
102
+ }
103
+
104
+ function NamedDeclarationAuthoringInput({ descriptor = {}, value, onChange }) {
105
+ const literalNone = value === 'none';
106
+ const entries = Array.isArray(value) ? value : [];
107
+ function blankEntry() { return { name: '', fields: Object.fromEntries(descriptor.requiredFields.map((field) => [field, ''])) }; }
108
+ function updateEntry(index, updater) { onChange?.(entries.map((entry, entryIndex) => entryIndex === index ? updater(entry || blankEntry()) : entry)); }
109
+ function removeEntry(index) {
110
+ const next = entries.filter((_, entryIndex) => entryIndex !== index);
111
+ if (!next.length && descriptor.allowLiteralNone) onChange?.('none');
112
+ else onChange?.(next.length ? next : [blankEntry()]);
113
+ }
114
+ return (
115
+ <fieldset className="tx-authoring-named-declarations" data-authoring-binding="named-declaration-section">
116
+ <legend>{descriptor.name}</legend>
117
+ <p className="tx-muted">Repeatable named declarations remain structured; they are not flattened into free text.</p>
118
+ {literalNone ? <p className="tx-muted">Declared as <strong>none</strong>.</p> : entries.map((entry, index) => (
119
+ <section className="tx-authoring-declaration-entry" key={`${descriptor.name}-${index}`}>
120
+ <TextField id={structuredInputId(descriptor.name, `name-${index}`)} label="Declaration name" value={entry?.name || ''} onChange={(next) => updateEntry(index, (current) => ({ ...current, name: next }))} required />
121
+ {[...descriptor.requiredFields, ...descriptor.optionalFields].map((field) => <TextField key={field} id={structuredInputId(descriptor.name, `${field}-${index}`)} label={field} value={entry?.fields?.[field] || ''} onChange={(next) => updateEntry(index, (current) => ({ ...current, fields: { ...(current?.fields || {}), [field]: next } }))} required={descriptor.requiredFields.includes(field)} />)}
122
+ {entries.length > 1 || descriptor.allowLiteralNone ? <Button type="button" variant="ghost" onClick={() => removeEntry(index)}>Remove declaration</Button> : null}
123
+ </section>
124
+ ))}
125
+ <div className="tx-authoring-structured-actions">
126
+ {literalNone ? <Button type="button" variant="ghost" icon="add" onClick={() => onChange?.([blankEntry()])}>Add declaration</Button> : <Button type="button" variant="ghost" icon="add" onClick={() => onChange?.([...entries, blankEntry()])}>Add another</Button>}
127
+ {!literalNone && descriptor.allowLiteralNone ? <Button type="button" variant="ghost" onClick={() => onChange?.('none')}>Declare none</Button> : null}
128
+ </div>
129
+ </fieldset>
130
+ );
131
+ }
132
+
133
+ // Compatibility export for callers/tests that imported the first canonical slice by its old component name.
134
+ export const CanonicalTaskCreateDialog = CanonicalAuthoringDialog;
135
+
136
+ function authoringInputId(name = '') { return `canonicalAuthoring-${String(name).toLowerCase().replace(/[^a-z0-9]+/g, '-')}`; }
137
+ function structuredInputId(group = '', field = '') { return `${authoringInputId(group)}-${String(field).toLowerCase().replace(/[^a-z0-9]+/g, '-')}`; }
138
+ function authoringFieldLabel(name = '', schemaLabel = 'Artifact') { return name === 'Summary' ? `${schemaLabel} title` : name; }
139
+
140
+
141
+ export function WorkspaceCanonicalCreateDialog({ workspace, actions = [], placementTargets = [], selectionSession = null, selectionResult = null, onBeginSelection, onSelectionConsumed, onDismiss, onCreate }) {
142
+ const qualifiedActions = (Array.isArray(actions) ? actions : []).filter((action) => action?.productCapable === true && action?.enabled !== false && action?.productScope === 'workspace');
143
+ const [selectedDefinitionKey, setSelectedDefinitionKey] = useState('');
144
+ const selected = qualifiedActions.find((action) => action.definitionKey === selectedDefinitionKey) || null;
145
+ if (selected) {
146
+ return <CanonicalAuthoringDialog record={null} action={selected} workspaceId={workspace?.id || ''} placementTargets={placementTargets} selectionSession={selectionSession} selectionResult={selectionResult} onBeginSelection={onBeginSelection} onSelectionConsumed={onSelectionConsumed} onDismiss={onDismiss} onBack={() => setSelectedDefinitionKey('')} onCreate={onCreate} />;
147
+ }
148
+ return (
149
+ <Modal title="Create artifact" onDismiss={onDismiss} className="tx-workspace-entrypoint-choice-modal">
150
+ <div className="tx-workspace-entrypoint-choice-copy">
151
+ <p className="tx-kicker">{workspace?.name || workspace?.title || 'Workspace'}</p>
152
+ <p>Choose a qualified artifact type. Tiinex will ask only for the fields owned by that type's exact creation contract.</p>
153
+ </div>
154
+ {qualifiedActions.length ? (
155
+ <div className="tx-workspace-entrypoint-choice-actions" role="group" aria-label="Qualified artifact types">
156
+ {qualifiedActions.map((action) => (
157
+ <div className="tx-workspace-entrypoint-choice-option" key={action.definitionKey}>
158
+ <Button variant="primary" icon={action.icon || 'create'} onClick={() => setSelectedDefinitionKey(action.definitionKey)}>{action.label || action.authoring?.schemaLabel || 'Artifact'}</Button>
159
+ <small><strong>{action.authoring?.schemaLabel || action.authoring?.schemaId || 'Artifact'}.</strong> {action.description || 'Create one browser-local artifact through this qualified canonical Transition.'}</small>
160
+ </div>
161
+ ))}
162
+ </div>
163
+ ) : <p className="tx-muted">No standalone artifact type is currently qualified for creation in this workspace.</p>}
164
+ <div className="tx-dialog-actions">
165
+ <Button variant="subtle" onClick={onDismiss}>Cancel</Button>
166
+ </div>
167
+ </Modal>
168
+ );
169
+ }
@@ -0,0 +1,9 @@
1
+ export function appendTransitionActionsToStaticRow(actions = [], transitionActions = []) {
2
+ const stable = Array.isArray(actions) ? actions : [];
3
+ const transitions = Array.isArray(transitionActions) ? transitionActions : [];
4
+ if (!transitions.length) return stable;
5
+ // Keep learned/static controls in their stable order. Schema-owned transition
6
+ // affordances are dynamic, so they are appended as the right-edge group
7
+ // instead of inserted between static record actions.
8
+ return stable.concat(transitions);
9
+ }
@@ -0,0 +1,146 @@
1
+ import React from 'react';
2
+ import { Badge } from '../../ui/primitives/Badge.jsx';
3
+ import { Button } from '../../ui/primitives/Button.jsx';
4
+ import { Icon } from '../../ui/primitives/Icon.jsx';
5
+ import { Modal } from '../../ui/primitives/Modal.jsx';
6
+ import { isWorkspaceRecord, presentRecordActions, RecordActionKind } from '@tiinex/core/actions/record.actions.js';
7
+ import { transitionProductActionsForRecord } from '../../transitions/transition.productPresentation.browser.js';
8
+ import { AuditStatusBadge } from './workspace.auditBadge.views.jsx';
9
+ import { SchemaReadView } from './workspace.read.views.jsx';
10
+ import { appendTransitionActionsToStaticRow } from './workspace.cardActions.js';
11
+ import { assetPreviewSummary, assetSourceBadge, assetSourceBoundary, compactPath, compactRecordDate, recordDisplayPath, recordLifecycleBadge, recordMaterialBadge, recordSchemaBadge, recordSchemaCanOpen, recordSourceBadge } from './workspace.viewFormatting.js';
12
+ import { workspaceArtifactActionModel, workspaceArtifactBoundaryBadge } from '../../workspaces/workspace.artifactActions.js';
13
+ import { RecordActionButton } from './workspace.recordActionButton.views.jsx';
14
+ import { WORKSPACE_RECORD_PRIMARY_INTENT, workspaceRecordPrimaryIntent, workspaceRecordPrimaryLabel } from '../../workspaces/workspace.navigation.js';
15
+
16
+
17
+ export const AssetCard = React.memo(function AssetCard({ asset, actionStateKey = '', onOpenAsset }) {
18
+ return (
19
+ <article className="tx-artifact-card tx-asset-card">
20
+ <div className="tx-card-badges">
21
+ <Badge>{assetSourceBadge(asset)}</Badge>
22
+ <Badge>{asset.type || 'asset'}</Badge>
23
+ <Badge>{asset.previewState || 'metadata-only'}</Badge>
24
+ </div>
25
+ <h3>{asset.name || asset.path || 'Local asset'}</h3>
26
+ {asset.path ? <div className="tx-card-pathline" title={asset.path}><Icon name="folderOpen" />{compactPath(asset.path)}</div> : null}
27
+ <p>{assetPreviewSummary(asset)}</p>
28
+ <footer className="tx-artifact-actions">
29
+ <Button icon="open" variant="ghost" onClick={() => onOpenAsset?.(asset.id || asset.path)}>Open</Button>
30
+ </footer>
31
+ </article>
32
+ );
33
+ }, assetCardPropsEqual);
34
+
35
+ export function RecordCard({ record, auditItem, actionStateKey = '', workspaceRecords = [], workspaceId = '', transitionProductContext = null, onOpenRecord, onFocusRecordLineage, onShareRecord, onRecordAction, onOpenSchema, context = 'discovery', expanded = false, onToggleExpanded, readOnly = false, selectionActive = false, selectionCandidate = null, onSelectCandidate }) {
36
+ const lineageContext = context === 'lineage';
37
+ const displayPath = recordDisplayPath(record);
38
+ const transitionActions = readOnly || selectionActive ? [] : transitionProductActionsForRecord(record, { surface: context, maxPrimary: 1, workspaceRecords, workspaceId, productContext: transitionProductContext });
39
+ const isWorkspaceArtifact = isWorkspaceRecord(record);
40
+ const workspaceActionModel = isWorkspaceArtifact ? workspaceArtifactActionModel(record) : null;
41
+ const baseActions = selectionActive ? [] : readOnly ? [{ id: RecordActionKind.open, label: 'Open', icon: 'open', enabled: true }] : presentRecordActions(record).filter((action) => action.enabled !== false && action.id !== RecordActionKind.reference && action.id !== RecordActionKind.continue);
42
+ const lineageAction = { id: RecordActionKind.lineage, label: lineageContext ? 'Anchor' : 'Lineage', icon: 'lineage', enabled: true };
43
+ const contextualActions = readOnly ? baseActions : lineageContext
44
+ ? [lineageAction, ...baseActions]
45
+ : [baseActions[0], lineageAction, ...baseActions.slice(1)].filter(Boolean);
46
+ const actions = appendTransitionActionsToStaticRow(contextualActions, transitionActions);
47
+ const dateBadge = compactRecordDate(record);
48
+ const schemaBadge = recordSchemaBadge(record);
49
+ const schemaOpenable = recordSchemaCanOpen(record);
50
+ const sourceBadge = recordSourceBadge(record);
51
+ const primaryIntent = workspaceRecordPrimaryIntent({ surface: context, selectionActive, selectionCandidate });
52
+ const primaryClick = () => {
53
+ if (primaryIntent === WORKSPACE_RECORD_PRIMARY_INTENT.select) return onSelectCandidate?.(selectionCandidate);
54
+ if (primaryIntent === WORKSPACE_RECORD_PRIMARY_INTENT.unavailable) return undefined;
55
+ if (primaryIntent === WORKSPACE_RECORD_PRIMARY_INTENT.toggleLineagePreview) return onToggleExpanded?.(record.id);
56
+ return onOpenRecord?.(record.id);
57
+ };
58
+ const onKey = (event) => {
59
+ if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); primaryClick(); }
60
+ };
61
+ return (
62
+ <article className={`tx-artifact-card tx-record-card tx-old-like-record-card tx-clickable-record-card ${isWorkspaceArtifact ? 'tx-workspace-artifact-record-card' : ''} ${lineageContext ? 'tx-lineage-as-record-card' : ''} ${expanded ? 'tx-record-card-expanded' : ''}`} role="button" tabIndex="0" aria-expanded={lineageContext ? expanded : undefined} aria-label={workspaceRecordPrimaryLabel({ intent: primaryIntent, title: record.title || 'artifact' })} onClick={primaryClick} onKeyDown={onKey} data-workspace-artifact-action-model={workspaceActionModel?.schema || undefined}>
63
+ <div className="tx-card-badges tx-legacy-card-badges">
64
+ {isWorkspaceArtifact ? <Badge>workspace</Badge> : null}
65
+ {isWorkspaceArtifact ? <Badge>{workspaceActionModel.roleLabel}</Badge> : null}
66
+ {isWorkspaceArtifact ? <Badge>{workspaceArtifactBoundaryBadge(record)}</Badge> : null}
67
+ <AuditStatusBadge record={record} item={auditItem} />
68
+ {recordLifecycleBadge(record) ? <Badge title="Lifecycle/publication state">{recordLifecycleBadge(record)}</Badge> : null}
69
+ {!readOnly && schemaOpenable ? <button type="button" className="tx-badge tx-badge-default tx-schema-nav-badge" title={`Open reading contract schema lineage for ${schemaBadge}`} aria-label={`Open reading contract schema lineage for ${schemaBadge}`} onClick={(event) => { event.stopPropagation(); onOpenSchema?.(record); }}>{schemaBadge}</button> : <Badge>{schemaBadge}</Badge>}
70
+ {dateBadge ? <Badge>{dateBadge}</Badge> : null}
71
+ <Badge>{sourceBadge}</Badge>
72
+ {recordMaterialBadge(record) ? <Badge title={record.materialReconciliation?.message || 'Material reconciliation'}>{recordMaterialBadge(record)}</Badge> : null}
73
+ </div>
74
+ <h3>{record.title || 'Untitled'}</h3>
75
+ <p>{record.summary || 'No summary available yet.'}</p>
76
+ {displayPath ? <div className="tx-card-pathline" title={displayPath}><Icon name="folderOpen" />{compactPath(displayPath)}</div> : null}
77
+ {lineageContext && expanded ? (
78
+ <div className="tx-record-card-read-preview" onClick={(event) => event.stopPropagation()}>
79
+ <SchemaReadView record={record} compact maxSections={2} showHeader={false} lineClamp />
80
+ </div>
81
+ ) : null}
82
+ <footer className="tx-legacy-action-row tx-artifact-actions" aria-label={selectionActive ? 'Selection action' : 'Artifact actions'} onClick={(event) => event.stopPropagation()}>
83
+ {selectionActive && selectionCandidate ? <Button variant="primary" icon="check" onClick={() => onSelectCandidate?.(selectionCandidate)}>Select</Button> : null}
84
+ {!selectionActive ? actions.map((action) => <RecordActionButton key={action.id} action={action} record={record} workspaceActionModel={workspaceActionModel} onOpenRecord={onOpenRecord} onFocusRecordLineage={onFocusRecordLineage} onShareRecord={onShareRecord} onRecordAction={onRecordAction} />) : null}
85
+ </footer>
86
+ </article>
87
+ );
88
+ }
89
+
90
+
91
+
92
+ export const MemoRecordCard = React.memo(RecordCard, recordCardPropsEqual);
93
+
94
+
95
+
96
+
97
+ export function assetCardPropsEqual(previous = {}, next = {}) {
98
+ return previous.asset === next.asset
99
+ && previous.actionStateKey === next.actionStateKey
100
+ && Boolean(previous.onOpenAsset) === Boolean(next.onOpenAsset);
101
+ }
102
+
103
+ export function recordCardPropsEqual(previous = {}, next = {}) {
104
+ return previous.record === next.record
105
+ && previous.auditItem === next.auditItem
106
+ && previous.context === next.context
107
+ && previous.expanded === next.expanded
108
+ && previous.actionStateKey === next.actionStateKey
109
+ && previous.workspaceRecords === next.workspaceRecords
110
+ && previous.workspaceId === next.workspaceId
111
+ && previous.transitionProductContext === next.transitionProductContext
112
+ && previous.readOnly === next.readOnly
113
+ && previous.selectionActive === next.selectionActive
114
+ && previous.selectionCandidate === next.selectionCandidate
115
+ && Boolean(previous.onOpenRecord) === Boolean(next.onOpenRecord)
116
+ && Boolean(previous.onFocusRecordLineage) === Boolean(next.onFocusRecordLineage)
117
+ && Boolean(previous.onShareRecord) === Boolean(next.onShareRecord)
118
+ && Boolean(previous.onRecordAction) === Boolean(next.onRecordAction)
119
+ && Boolean(previous.onOpenSchema) === Boolean(next.onOpenSchema)
120
+ && Boolean(previous.onSelectCandidate) === Boolean(next.onSelectCandidate);
121
+ }
122
+
123
+ export function AssetDetailDialog({ asset, onDismiss }) {
124
+ return (
125
+ <Modal title={asset?.name || asset?.path || 'Local asset'} onDismiss={onDismiss}>
126
+ <div className="tx-record-detail tx-asset-detail">
127
+ <div className="tx-card-badges">
128
+ <Badge>{assetSourceBadge(asset)}</Badge>
129
+ <Badge>{asset?.type || 'asset'}</Badge>
130
+ <Badge>{asset?.previewState || 'metadata-only'}</Badge>
131
+ </div>
132
+ <dl className="tx-record-meta">
133
+ {asset?.path ? <div><dt>Path</dt><dd>{asset.path}</dd></div> : null}
134
+ {asset?.size != null ? <div><dt>Size</dt><dd>{asset.size} bytes</dd></div> : null}
135
+ <div><dt>Boundary</dt><dd>{assetSourceBoundary(asset)}</dd></div>
136
+ </dl>
137
+ {asset?.content ? <pre className="tx-record-markdown-preview">{String(asset.content).slice(0, 2400)}</pre> : null}
138
+ {asset?.dataUrl ? <img className="tx-local-asset-preview" src={asset.dataUrl} alt="" /> : null}
139
+ {!asset?.content && !asset?.dataUrl ? <p className="tx-muted">Preview is {asset?.previewState || 'metadata-only'}; metadata and source boundary are preserved.</p> : null}
140
+ <div className="tx-dialog-actions">
141
+ <Button variant="ghost" onClick={onDismiss}>Close</Button>
142
+ </div>
143
+ </div>
144
+ </Modal>
145
+ );
146
+ }