@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,172 @@
1
+ import { RecordActionKind } from '@tiinex/core/actions/record.actions.js';
2
+ import { recordLogicalPath } from '@tiinex/core/workspaces/workspace.recordPaths.js';
3
+ import { sourceBoundaryClass } from '@tiinex/core/workspaces/workspace.materialRole.js';
4
+
5
+
6
+ export function assetSourceBadge(asset = {}) {
7
+ const boundary = sourceBoundaryClass(asset);
8
+ if (boundary === 'source-backed') return 'source-backed';
9
+ if (boundary === 'local') return 'local/session';
10
+ return 'source unknown';
11
+ }
12
+
13
+ export function assetSourceBoundary(asset = {}) {
14
+ const declared = String(asset?.source?.boundary || asset?.boundary || '').trim();
15
+ if (declared) return declared;
16
+ const boundary = sourceBoundaryClass(asset);
17
+ if (boundary === 'source-backed') return 'Source-backed asset material/reference; preview availability is separate from source provenance.';
18
+ if (boundary === 'local') return 'Browser-local asset; no GitHub provenance inferred.';
19
+ return 'Asset source boundary is unresolved; no provenance inferred.';
20
+ }
21
+
22
+ export function assetPreviewSummary(asset = {}) {
23
+ const boundary = sourceBoundaryClass(asset);
24
+ const size = Number(asset?.size || 0);
25
+ if (boundary === 'source-backed') return size > 0
26
+ ? `${size} bytes described for a source-backed asset; preview availability is separate.`
27
+ : 'Source-backed asset/reference preserved without inventing preview availability.';
28
+ if (boundary === 'local') return size > 0
29
+ ? `${size} bytes preserved as local asset.`
30
+ : 'Preserved as a local asset, not a fake leaf.';
31
+ return size > 0
32
+ ? `${size} bytes described; source ownership is unresolved.`
33
+ : 'Asset metadata preserved; source ownership is unresolved.';
34
+ }
35
+
36
+ export function compactPath(path = '') {
37
+ const value = String(path || '').trim();
38
+ if (value.length <= 44) return value;
39
+ const parts = value.split('/').filter(Boolean);
40
+ if (parts.length <= 2) return `…${value.slice(-41)}`;
41
+ return `${parts[0]}/…/${parts.slice(-2).join('/')}`;
42
+ }
43
+
44
+
45
+ export function recordDisplayPath(record = {}) {
46
+ return recordLogicalPath(record);
47
+ }
48
+
49
+ export function compactRecordDate(record = {}) {
50
+ const raw = record.currentCreatedAt || record.createdAt || record.date || '';
51
+ const text = String(raw || '').trim();
52
+ if (!text) return '';
53
+ const match = text.match(/\d{4}-\d{2}-\d{2}/);
54
+ return match ? match[0] : text.slice(0, 10);
55
+ }
56
+
57
+ export function recordSchemaOpenValue(record = {}) {
58
+ return String(record.schemaId || record.currentSchemaId || record.envelopeSchemaId || '').trim();
59
+ }
60
+
61
+
62
+ export function recordSchemaCanOpen(record = {}) {
63
+ const text = recordSchemaOpenValue(record).toLowerCase();
64
+ return Boolean(text && !['artifact', 'plain', 'markdown', 'unknown'].includes(text));
65
+ }
66
+
67
+ export function recordSchemaBadge(record = {}) {
68
+ const text = recordSchemaOpenValue(record);
69
+ if (!text) return 'artifact';
70
+ return text.replace(/^tiinex\./, '').replace(/\.v\d+$/, '');
71
+ }
72
+
73
+ export function recordMaterialBadge(record = {}) {
74
+ const status = String(record?.materialReconciliation?.status || '').trim();
75
+ if (status === 'checksum-match') return record.materialReconciliation.displayLabel || 'source + local';
76
+ if (status === 'source-canonical-pruned-local-duplicate' || status === 'local-duplicate-pruned-source-canonical') return 'source-backed';
77
+ if (status === 'local-shadowed-by-source') return record.materialReconciliation.displayLabel || 'local snapshot';
78
+ if (status === 'checksum-mismatch') return record.materialReconciliation.displayLabel || 'material mismatch';
79
+ if (status === 'same-origin-unverified') return record.materialReconciliation.displayLabel || 'same origin · unverified';
80
+ if (status === 'source-only-after-local-clear') return 'source only';
81
+ if (status === 'source-removed-local-restored') return 'local restored';
82
+ return '';
83
+ }
84
+
85
+ export function recordSourceBadge(record = {}) {
86
+ const source = record.source || {};
87
+ if (source.label) return source.label;
88
+ if (source.repo) return source.repo;
89
+ if (source.adapterId && source.adapterId !== 'local') return source.adapterId;
90
+ return 'Local';
91
+ }
92
+
93
+ export function recordLifecycleBadge(record = {}) {
94
+ const values = [record.lifecycleStatus, record.currentStatus, record.status, record.envelope?.current?.status];
95
+ const text = values.map((value) => String(value || '').trim()).find(Boolean) || '';
96
+ if (!text) return '';
97
+ const clean = text.toLowerCase();
98
+ if (clean === 'schema ok' || clean === 'local') return '';
99
+ return text;
100
+ }
101
+
102
+ export function actionClassName(action = {}) {
103
+ const id = action.id;
104
+ const isTransition = String(id || '').startsWith('record.transition:');
105
+ const labeled = id === RecordActionKind.continue || id === RecordActionKind.reference || id === RecordActionKind.editLocal || id === RecordActionKind.workspaceOpen || id === RecordActionKind.workspaceMerge;
106
+ const danger = id === RecordActionKind.deleteLocal;
107
+ const side = isTransition || id === RecordActionKind.continue || id === RecordActionKind.reference || id === RecordActionKind.workspaceOpen || id === RecordActionKind.workspaceMerge ? 'tx-action-right' : 'tx-action-left';
108
+ return ['tx-button', 'tx-button-ghost', 'tx-legacy-action', isTransition ? 'tx-transition-action' : '', danger ? 'tx-danger tx-delete-local-action' : '', labeled ? 'tx-labeled-action' : '', side].filter(Boolean).join(' ');
109
+ }
110
+
111
+ export function actionLabel(action = {}) {
112
+ if (action.id === RecordActionKind.open) return 'Details';
113
+ if (action.id === RecordActionKind.markdown) return 'Show markdown';
114
+ if (action.id === RecordActionKind.lineage) return 'Anchor';
115
+ if (action.id === RecordActionKind.workspaceOpen) return 'Open';
116
+ if (action.id === RecordActionKind.workspaceMerge) return 'Merge';
117
+ if (action.id === RecordActionKind.editLocal) return 'Edit local draft';
118
+ if (action.id === RecordActionKind.deleteLocal) return 'Delete local draft';
119
+ return action.label;
120
+ }
121
+
122
+ export function validationStateLabel(value = '') {
123
+ const state = String(value || '').trim();
124
+ if (state === 'exact-schema-validated') return 'schema validation ran';
125
+ if (state === 'root-validated') return 'root validation ran';
126
+ if (state === 'root-only-child-validator-unavailable') return 'root only · validator unavailable';
127
+ if (state === 'not-run-body-unavailable') return 'not run · body missing';
128
+ if (state === 'not-applicable-supporting') return 'not applicable';
129
+ if (state === 'validation-unknown') return 'validation unknown';
130
+ return state || 'validation unknown';
131
+ }
132
+
133
+ export function validatorLabel(childValidator = '', coverage = '') {
134
+ const child = String(childValidator || '').trim();
135
+ const cov = String(coverage || '').trim();
136
+ if (child === 'run') return 'exact child validator ran';
137
+ if (child === 'unavailable') return 'child validator unavailable';
138
+ if (child === 'skipped') return 'skipped until body loads';
139
+ if (child === 'not-applicable') return cov === 'root-exact' ? 'Root validator only' : 'not applicable';
140
+ return child || cov || 'validator unknown';
141
+ }
142
+
143
+ export function readStateLabel(value = '') {
144
+ const state = String(value || '').trim();
145
+ if (state === 'schema-owned') return 'schema-owned';
146
+ if (state === 'root-readable') return 'root-readable';
147
+ if (state === 'root-fallback') return 'root fallback';
148
+ if (state === 'unavailable-body') return 'body unavailable';
149
+ if (state === 'unknown-schema') return 'unknown schema';
150
+ return state || 'read state unknown';
151
+ }
152
+
153
+ export function schemaCoverageLabel(value = '') {
154
+ const state = String(value || '').trim();
155
+ if (state === 'exact-companion') return 'exact companion';
156
+ if (state === 'unknown-schema') return 'unknown schema';
157
+ if (state === 'missing-schema') return 'missing schema';
158
+ return state || 'schema unknown';
159
+ }
160
+
161
+ export function materialLedgerReceiptSummary(receipt = {}) {
162
+ const bits = [];
163
+ if (Number(receipt.rawAdapterRecords || 0)) bits.push(`${Number(receipt.rawAdapterRecords || 0)} adapter records`);
164
+ if (Number(receipt.sourceRecords || 0)) bits.push(`${Number(receipt.sourceRecords || 0)} inserted`);
165
+ if (Number(receipt.visibleSourceRecords || receipt.visibleRecords || 0)) bits.push(`${Number(receipt.visibleSourceRecords || receipt.visibleRecords || 0)} visible`);
166
+ if (Number(receipt.hiddenSourceRecords || receipt.hiddenRecords || 0)) bits.push(`${Number(receipt.hiddenSourceRecords || receipt.hiddenRecords || 0)} hidden`);
167
+ if (Number(receipt.groupedSourceRecords || receipt.groupedRecords || 0)) bits.push(`${Number(receipt.groupedSourceRecords || receipt.groupedRecords || 0)} grouped`);
168
+ if (Number(receipt.sourceWorkspaceArtifacts || 0)) bits.push(`${Number(receipt.sourceWorkspaceArtifacts || 0)} workspace artifact${Number(receipt.sourceWorkspaceArtifacts || 0) === 1 ? '' : 's'}`);
169
+ return bits.join(' · ') || 'material ledger unavailable';
170
+ }
171
+
172
+ export const recordSchemaFilterValue = recordSchemaOpenValue;
@@ -0,0 +1,210 @@
1
+ import React, { useEffect, useMemo, useRef } from 'react';
2
+ import { Button } from '../../ui/primitives/Button.jsx';
3
+ import { isWorkspaceRecord } from '@tiinex/core/actions/record.actions.js';
4
+ import { Icon } from '../../ui/primitives/Icon.jsx';
5
+ import { presentWorkspaceFeed, presentWorkspaceTree } from '@tiinex/core/schemas/workspace/tiinex.workspace.v1.presenter.js';
6
+ import { summarizeWorkspaceMaterial } from '../../workspaces/workspace.summary.js';
7
+ import { buildWorkspaceLineageView } from '../../workspaces/workspace.lineageView.js';
8
+ import { buildDiscoveryMaterialIndex, buildWorkspaceDiscoveryView } from '../../workspaces/workspace.discoveryView.js';
9
+ import { buildWorkspaceAuditView } from '../../workspaces/workspace.auditView.js';
10
+ import { normalizeWorkspaceDisplayOptions } from '../../workspaces/workspace.displayOptions.js';
11
+ import { WorkspaceBoundaryKicker, SourceStrip, WorkspaceDropHint, WorkspaceMaterialSummary, ModeToolbar, ProgressStrip, EmptyWorkspaceState } from './workspace.chrome.views.jsx';
12
+ import { DiscoveryRecordList } from './workspace.discovery.views.jsx';
13
+ import { WorkspaceTreeState } from './workspace.tree.views.jsx';
14
+ import { WorkspaceAuditState } from './workspace.audit.views.jsx';
15
+ import { WorkspaceLineageState } from './workspace.lineage.views.jsx';
16
+ import { transitionProductContextForWorkspace } from '../../transitions/transition.productPresentation.browser.js';
17
+ import { TimePortalBanner, TimePortalCompactMarker } from './workspace.timePortal.views.jsx';
18
+ import { WorkspaceSelectionSurface } from './workspace.selection.views.jsx';
19
+
20
+ const WorkspaceGraphState = React.lazy(() => import('./workspace.graph.views.jsx').then((module) => ({ default: module.WorkspaceGraphState })));
21
+
22
+ export { AssetDetailDialog } from './workspace.cards.views.jsx';
23
+ export { RecordDetailDialog, RecordMarkdownDialog, RecordActionDialog, CreateWorkspaceDialog, RenameWorkspaceDialog, CloseWorkspaceDialog } from './workspace.recordDialogs.views.jsx';
24
+ export { WorkspaceCanonicalCreateDialog } from './workspace.canonicalTaskDialog.views.jsx';
25
+ export { GovernanceBoundaryDialog } from './workspace.governance.views.jsx';
26
+
27
+ function auditIndexForWorkspace(workspace = {}, records = []) {
28
+ const audit = buildWorkspaceAuditView(workspace, { records, query: '' });
29
+ return new Map((audit.items || []).map((item) => [item.id, item]));
30
+ }
31
+
32
+ function selectedRecordFrom(workspace = {}, selectedRecordId = '') {
33
+ const records = Array.isArray(workspace.records) ? workspace.records : [];
34
+ return records.find((record) => record.id === selectedRecordId) || null;
35
+ }
36
+
37
+ function lineageControlsReadyForTraversal(traversal = null) {
38
+ if (!traversal) return false;
39
+ const state = String(traversal.terminalState || traversal.status?.terminalState || '').trim();
40
+ if (traversal.noParentDeclared === true) return true;
41
+ if (['root-reached', 'root-reached-scope-transition', 'no-parent-declared', 'target-unavailable', 'ambiguous-parent', 'integrity-mismatch'].includes(state)) return true;
42
+ return traversal.complete === true;
43
+ }
44
+
45
+ export const WorkspaceColumnSurface = React.memo(function WorkspaceColumnSurface({ workspace, state, referenceRecords = [], graphWorkspaces = [], selectionSession = null, onSelectionChoose, onSelectionCancel, layoutMode = 'expanded', onLayoutMode, onClose, onRenameWorkspace, onVerse, onQuery, onOpenDisplayOptions, onOpenAddDialog, onOpenCreateArtifact, onShareWorkspace, onExportWorkspace, onCloseSource, onDropFiles, onOpenRecord, onOpenGraphRecord, onFocusRecordLineage, onOpenAsset, onShareRecord, onRecordAction, onOpenSchema, onToggleTreeFolder, onSourceTransportRefresh, onOpenGovernance, onViewScroll, stageScrollTop, expandedLineageRecordIds = [], lineageAuditReport = null, lineageLoadReport = null, onToggleLineageCard, onRunLineageAudit, onLoadFullLineage, timePortal = null, historicalReadModel = null, readOnlyHistorical = false, onLoadHistoricalSnapshot, onReturnToLatest }) {
46
+ const stageRef = useRef(null);
47
+ const restoreKey = `${workspace?.id || 'workspace'}:${state.view?.workspaceVerse || 'feed'}:${state.view?.query || ''}:${state.view?.selectedRecordId || ''}`;
48
+ useEffect(() => {
49
+ const stage = stageRef.current;
50
+ if (!stage) return;
51
+ const top = Number(stageScrollTop || 0);
52
+ stage.scrollTop = Number.isFinite(top) && top > 0 ? top : 0;
53
+ }, [restoreKey, stageScrollTop]);
54
+ const sources = Array.isArray(workspace.sources) ? workspace.sources : [];
55
+ const requestedVerse = state.view?.workspaceVerse || 'feed';
56
+ const selectionActive = Boolean(selectionSession?.ok);
57
+ const selectionVerse = String(selectionSession?.presentation?.verse || '');
58
+ const verse = selectionActive && ['feed', 'tree'].includes(selectionVerse) ? selectionVerse : readOnlyHistorical && !['feed', 'tree', 'graph'].includes(requestedVerse) ? 'feed' : requestedVerse;
59
+ const lineageVerse = verse === 'lineage';
60
+ const allRecords = Array.isArray(workspace.records) ? workspace.records : [];
61
+ const transitionProductActionsVisible = !selectionActive && !readOnlyHistorical && (verse === 'feed' || verse === 'lineage');
62
+ const transitionProductContext = useMemo(() => (transitionProductActionsVisible
63
+ ? transitionProductContextForWorkspace({ workspaceRecords: allRecords, referenceRecords })
64
+ : null), [transitionProductActionsVisible, allRecords, referenceRecords]);
65
+ const selectedRecordId = String(state.view?.selectedRecordId || '');
66
+ const lineageTraversalPreview = useMemo(() => (lineageVerse && selectedRecordId
67
+ ? buildWorkspaceLineageView(workspace, { records: allRecords, query: '', selectedRecordId }).selectedTraversal
68
+ : null), [lineageVerse, selectedRecordId, workspace, allRecords]);
69
+ const lineageAlreadyReady = lineageControlsReadyForTraversal(lineageTraversalPreview);
70
+ const lineageLoadReady = Boolean(lineageVerse && selectedRecordId && (lineageAlreadyReady || (lineageLoadReport && String(lineageLoadReport.selectedRecordId || '') === String(state.view?.selectedRecordId || ''))));
71
+ const discoveryQuery = state.view?.query || '';
72
+ const lineageQuery = lineageLoadReady ? (state.view?.lineageQuery || '') : '';
73
+ const query = lineageVerse ? lineageQuery : discoveryQuery;
74
+ const displayOptions = useMemo(() => normalizeWorkspaceDisplayOptions(state.view?.displayOptions), [state.view?.displayOptions]);
75
+ const selectedRecord = selectedRecordFrom(workspace, selectedRecordId);
76
+ const materialIndex = useMemo(() => buildDiscoveryMaterialIndex(allRecords), [allRecords]);
77
+ const auditById = useMemo(() => auditIndexForWorkspace(workspace, allRecords), [workspace, allRecords]);
78
+ const allAssets = useMemo(() => (Array.isArray(workspace.assets) ? workspace.assets : []), [workspace.assets]);
79
+ const workspaceArtifactCount = useMemo(() => allRecords.filter(isWorkspaceRecord).length, [allRecords]);
80
+ const discoveryView = useMemo(() => buildWorkspaceDiscoveryView(workspace, {
81
+ records: allRecords,
82
+ assets: allAssets,
83
+ displayOptions,
84
+ query: discoveryQuery,
85
+ auditById,
86
+ materialIndex
87
+ }), [workspace, allRecords, allAssets, displayOptions, discoveryQuery, auditById, materialIndex]);
88
+ const selectionCandidates = useMemo(() => (Array.isArray(selectionSession?.candidates) ? selectionSession.candidates : []).filter((item) => item?.enabled !== false && String(item.workspaceId || '') === String(workspace?.id || '')), [selectionSession, workspace?.id]);
89
+ const selectionRecordIds = useMemo(() => new Set(selectionCandidates.filter((item) => item?.id).map((item) => String(item.id))), [selectionCandidates]);
90
+ const records = selectionActive && verse !== 'tree' ? allRecords.filter((record) => selectionRecordIds.has(String(record.id))) : discoveryView.records;
91
+ const assets = selectionActive ? [] : discoveryView.assets;
92
+ const hasMaterial = Boolean(allRecords.length || allAssets.length);
93
+ const isFilteredEmpty = Boolean(hasMaterial && !records.length && !assets.length);
94
+ const presentation = useMemo(() => (verse === 'tree'
95
+ ? presentWorkspaceTree(workspace, { verse, query: discoveryQuery })
96
+ : presentWorkspaceFeed(workspace, { verse, query: discoveryQuery })), [workspace, verse, discoveryQuery]);
97
+ const materialSummary = useMemo(() => summarizeWorkspaceMaterial(workspace), [workspace]);
98
+ const interactionRevision = [
99
+ state.activeWorkspaceId || '',
100
+ workspace?.id || '',
101
+ state.view?.workspaceVerse || '',
102
+ state.view?.selectedRecordId || '',
103
+ allRecords.length,
104
+ allAssets.length,
105
+ sources.map((source) => `${source.id || source.label || ''}:${source.discoveryState || ''}:${Number(source.count || 0)}`).join('|')
106
+ ].join('::');
107
+ if (layoutMode === 'compact') {
108
+ return (
109
+ <section className="tx-workspace-window tx-workspace-window-compact tx-schema-workspace-surface" aria-label={`Compact workspace ${presentation.title || ''}`.trim()} data-schema-id="tiinex.workspace.v1" data-workspace-layout="compact">
110
+ <div className="tx-workspace-compact-inner">
111
+ <Button icon="expand" variant="ghost" shape="round" aria-label={`Expand workspace ${presentation.title || ''}`.trim()} title="Expand workspace" onClick={() => onLayoutMode?.('expanded')} />
112
+ {readOnlyHistorical ? (
113
+ <div className="tx-workspace-compact-historical">
114
+ <TimePortalCompactMarker timePortal={timePortal} />
115
+ <div className="tx-workspace-compact-title tx-workspace-compact-title-readonly" title={`Historical workspace review · ${presentation.title || ''}`.trim()}>{presentation.title}</div>
116
+ </div>
117
+ ) : <button type="button" className="tx-workspace-compact-title" title="Rename workspace" onClick={onRenameWorkspace}>{presentation.title}</button>}
118
+ <div className="tx-workspace-compact-stats" aria-label={`${allRecords.length} records, ${allAssets.length} assets, ${sources.length} sources`}>
119
+ <span><Icon name="manualFiles" />{allRecords.length}</span>
120
+ <span><Icon name="asset" />{allAssets.length}</span>
121
+ <span><Icon name="source" />{sources.length}</span>
122
+ </div>
123
+ <Button icon="close" variant="ghost" shape="round" aria-label={`Close workspace ${presentation.title || ''}`.trim()} title="Close workspace" onClick={onClose} />
124
+ </div>
125
+ </section>
126
+ );
127
+ }
128
+
129
+ return (
130
+ <section className="tx-workspace-window tx-column-window tx-uc001-created-workspace tx-schema-workspace-surface tx-compact-column-window" aria-label="Tiinex workspace window" data-schema-id="tiinex.workspace.v1" data-workspace-layout="expanded" onDragOver={(event) => event.preventDefault()} onDrop={(event) => { event.preventDefault(); event.stopPropagation(); if (event.dataTransfer) onDropFiles?.(event.dataTransfer, { sourceMode: 'workspace-drop', fromDataTransfer: true }); }}>
131
+ <header className="tx-window-header tx-workspace-schema-header tx-compact-window-header">
132
+ <div className="tx-window-title-block">
133
+ <h1>
134
+ <button type="button" className="tx-workspace-title-rename-button" title={readOnlyHistorical ? 'Historical workspace review' : 'Rename workspace'} aria-label={`${readOnlyHistorical ? 'Historical workspace review' : 'Rename workspace'} ${presentation.title || ''}`.trim()} onClick={readOnlyHistorical ? undefined : onRenameWorkspace}>
135
+ <span>{presentation.title}</span>
136
+ <Icon name="edit" />
137
+ </button>
138
+ </h1>
139
+ <WorkspaceBoundaryKicker workspace={workspace} />
140
+ </div>
141
+ <div className="tx-window-actions tx-compact-window-actions" aria-label="Workspace actions">
142
+ <span className="tx-stat-pill" title="Visible records after Display options"><Icon name="manualFiles" />{records.length}</span>
143
+ <span className="tx-stat-pill" title="Local assets"><Icon name="asset" />{allAssets.length}</span>
144
+ <span className="tx-stat-pill" title="Workspace artifacts"><Icon name="workspace" />{workspaceArtifactCount}</span>
145
+ <span className="tx-stat-pill" title="Sources"><Icon name="source" />{sources.length}</span>
146
+ {!readOnlyHistorical ? <Button icon="create" variant="primary" aria-label="Create artifact" title="Create artifact" onClick={onOpenCreateArtifact}>Create</Button> : null}
147
+ {!readOnlyHistorical ? <Button icon="add" variant="primary" shape="round" aria-label="Add to workspace" title="Add to workspace" onClick={onOpenAddDialog} /> : null}
148
+ <Button icon="shareNodes" variant="ghost" shape="round" aria-label="Share workspace" title="Share workspace" onClick={onShareWorkspace} />
149
+ {!readOnlyHistorical ? <Button icon="edit" variant="ghost" shape="round" aria-label="Rename workspace" title="Rename workspace" onClick={onRenameWorkspace} /> : null}
150
+ {!readOnlyHistorical ? <Button icon="download" variant="ghost" shape="round" aria-label="Prepare workspace export" title="Prepare workspace export" onClick={onExportWorkspace} /> : null}
151
+ <Button icon="collapse" variant="ghost" shape="round" aria-label="Collapse workspace" title="Collapse workspace" onClick={() => onLayoutMode?.('compact')} />
152
+ <Button icon="close" variant="ghost" shape="round" aria-label="Close workspace" title="Close workspace" onClick={onClose} />
153
+ </div>
154
+ </header>
155
+ <TimePortalBanner timePortal={timePortal} readModel={historicalReadModel} onLoadSnapshot={onLoadHistoricalSnapshot} onReturnLatest={onReturnToLatest} />
156
+ <SourceStrip readOnly={readOnlyHistorical} workspace={workspace} boundary={presentation.sourceBoundary} onCloseSource={onCloseSource} onOpenAddDialog={onOpenAddDialog} onSourceTransportRefresh={onSourceTransportRefresh} onOpenGovernance={onOpenGovernance} />
157
+ {selectionActive ? <WorkspaceSelectionSurface session={selectionSession} onCancel={onSelectionCancel} /> : null}
158
+ {!readOnlyHistorical && !selectionActive ? <WorkspaceDropHint workspace={workspace} hasMaterial={hasMaterial} /> : null}
159
+ <WorkspaceMaterialSummary summary={materialSummary} />
160
+ <ModeToolbar readOnly={readOnlyHistorical} state={state} query={query} displayOptions={displayOptions} selectedRecord={selectedRecord} lineageLoadReport={lineageLoadReport} lineageReady={lineageLoadReady} onVerse={onVerse} onQuery={onQuery} onOpenDisplayOptions={onOpenDisplayOptions} onRunLineageAudit={onRunLineageAudit} onLoadFullLineage={onLoadFullLineage} />
161
+ <ProgressStrip workspace={workspace} />
162
+ <section ref={stageRef} className="tx-primary-stage tx-column-primary-stage" aria-label="Column feed" onScroll={(event) => onViewScroll?.(verse, event.currentTarget.scrollTop)} data-workspace-verse={verse}>
163
+ {verse === 'tree'
164
+ ? <WorkspaceTreeState workspace={workspace} query={selectionActive ? '' : query} records={selectionActive ? allRecords : records} assets={assets} auditById={auditById} expandedFolders={state.view?.expandedTreeFolders} onToggleTreeFolder={onToggleTreeFolder} onOpenRecord={onOpenRecord} onFocusRecordLineage={onFocusRecordLineage} onOpenAsset={onOpenAsset} readOnly={readOnlyHistorical || selectionActive} selectionActive={selectionActive} selectionCandidates={selectionCandidates} onSelectCandidate={onSelectionChoose} />
165
+ : verse === 'graph'
166
+ ? <React.Suspense fallback={<div className="tx-graph-loading" role="status">Loading Node Graph Verse…</div>}><WorkspaceGraphState workspace={workspace} graphWorkspaces={graphWorkspaces} query={query} selectedRecordId={selectedRecordId} onOpenRecord={onOpenGraphRecord} readOnly={readOnlyHistorical} /></React.Suspense>
167
+ : verse === 'lineage'
168
+ ? <WorkspaceLineageState workspace={workspace} query={query} records={allRecords} selectedRecordId={selectedRecordId} auditById={auditById} onOpenRecord={onOpenRecord} onRecordAction={onRecordAction} onFocusRecordLineage={onFocusRecordLineage} onShareRecord={onShareRecord} onOpenSchema={onOpenSchema} lineageAuditReport={lineageAuditReport} lineageLoadReport={lineageLoadReport} lineageReady={lineageLoadReady} expandedRecordIds={expandedLineageRecordIds} displayOptions={displayOptions} onToggleLineageCard={onToggleLineageCard} actionStateKey={interactionRevision} workspaceRecords={allRecords} workspaceId={workspace.id} transitionProductContext={transitionProductContext} />
169
+ : verse === 'audit'
170
+ ? <WorkspaceAuditState workspace={workspace} query={query} records={allRecords} assets={allAssets} onOpenRecord={onOpenRecord} />
171
+ : (records.length || assets.length)
172
+ ? <DiscoveryRecordList
173
+ records={records}
174
+ assets={assets}
175
+ stageScrollTop={stageScrollTop}
176
+ auditById={auditById}
177
+ actionStateKey={interactionRevision}
178
+ workspaceRecords={allRecords}
179
+ workspaceId={workspace.id}
180
+ transitionProductContext={transitionProductContext}
181
+ onOpenRecord={onOpenRecord}
182
+ onFocusRecordLineage={onFocusRecordLineage}
183
+ onShareRecord={onShareRecord}
184
+ onRecordAction={onRecordAction}
185
+ onOpenSchema={onOpenSchema}
186
+ onOpenAsset={onOpenAsset}
187
+ readOnly={readOnlyHistorical || selectionActive}
188
+ selectionActive={selectionActive}
189
+ selectionCandidates={selectionCandidates}
190
+ onSelectCandidate={onSelectionChoose}
191
+ />
192
+ : <EmptyWorkspaceState filtered={isFilteredEmpty} hasMaterial={hasMaterial} query={query} summary={materialSummary} progress={workspace.discoveryProgress} />}
193
+ </section>
194
+ </section>
195
+ );
196
+ }, workspaceColumnSurfacePropsEqual);
197
+
198
+ function workspaceColumnSurfacePropsEqual(previous = {}, next = {}) {
199
+ return previous.workspace === next.workspace
200
+ && previous.state === next.state
201
+ && previous.referenceRecords === next.referenceRecords
202
+ && previous.graphWorkspaces === next.graphWorkspaces
203
+ && previous.selectionSession === next.selectionSession
204
+ && previous.expandedLineageRecordIds === next.expandedLineageRecordIds
205
+ && previous.lineageAuditReport === next.lineageAuditReport
206
+ && previous.lineageLoadReport === next.lineageLoadReport
207
+ && previous.timePortal === next.timePortal
208
+ && previous.historicalReadModel === next.historicalReadModel
209
+ && previous.readOnlyHistorical === next.readOnlyHistorical;
210
+ }
@@ -0,0 +1,7 @@
1
+ export const sourceSettingsModel = {
2
+ type: 'tiinex.web.source-settings.model.v1',
3
+ owner: 'src/source-settings',
4
+ modes: ['static-fixture', 'local-file', 'draft', 'github-source-backed'],
5
+ invariant: 'local, draft, and static material remain non-GitHub unless an explicit source descriptor exists',
6
+ ergonomics: 'source state should remain visible as compact chips; detailed explanation belongs in expandable controls'
7
+ };
@@ -0,0 +1 @@
1
+ export function draftSource(id) { return { kind: 'draft', id }; }
@@ -0,0 +1,204 @@
1
+ import { createRecordFromMarkdown } from '@tiinex/core/artifacts/artifact.record.js';
2
+
3
+ function isHttps(url) {
4
+ return /^https:\/\//i.test(url);
5
+ }
6
+
7
+ function normalizeLoadTarget(item, index = 0) {
8
+ if (item && typeof item === 'object') {
9
+ const ref = String(item.ref || item.path || item.url || item.target || '').trim();
10
+ return {
11
+ ref,
12
+ surface: String(item.surface || item.sourceSurface || 'explicitFiles').trim() || 'explicitFiles',
13
+ targetKind: String(item.targetKind || item.kind || 'github-markdown').trim() || 'github-markdown',
14
+ inputTarget: String(item.inputTarget || item.original || item.ref || ref).trim() || ref,
15
+ targetIndex: Number.isFinite(Number(item.targetIndex)) ? Number(item.targetIndex) : index
16
+ };
17
+ }
18
+ const ref = String(item || '').trim();
19
+ return { ref, surface: 'explicitFiles', targetKind: 'github-markdown', inputTarget: ref, targetIndex: index };
20
+ }
21
+
22
+ function targetAttribution(target = {}) {
23
+ return {
24
+ surface: target.surface || 'explicitFiles',
25
+ targetKind: target.targetKind || 'github-markdown',
26
+ inputTarget: target.inputTarget || target.ref || '',
27
+ targetIndex: Number.isFinite(Number(target.targetIndex)) ? Number(target.targetIndex) : 0
28
+ };
29
+ }
30
+
31
+ function toRawFromBlobUrl(url) {
32
+ // https://github.com/:owner/:repo/blob/:ref/:path -> https://raw.githubusercontent.com/:owner/:repo/:ref/:path
33
+ const u = new URL(url);
34
+ const parts = u.pathname.split('/').filter(Boolean);
35
+ // parts: [owner, repo, 'blob', ref, ...path]
36
+ if (parts.length < 5) throw new Error('invalid blob URL');
37
+ const owner = parts[0];
38
+ const repo = parts[1];
39
+ const ref = parts[3];
40
+ const path = parts.slice(4).join('/');
41
+ return `https://raw.githubusercontent.com/${owner}/${repo}/${ref}/${path}`;
42
+ }
43
+
44
+ function rootPaths(source) {
45
+ return String(source?.rootPath || '')
46
+ .split(/\r?\n|,/)
47
+ .map((item) => item.trim().replace(/^\.\//, '').replace(/^\/+/, '').replace(/\/+$/, ''))
48
+ .filter((item) => item && item !== '.');
49
+ }
50
+
51
+ function sourceRepo(source) {
52
+ const srcRepo = String(source?.repo || source?.repository || '').trim().toLowerCase();
53
+ if (!srcRepo) throw new Error('source.repo missing');
54
+ return srcRepo;
55
+ }
56
+
57
+ function normalizeRelativePath(source, ref) {
58
+ const relative = String(ref || '').trim().replace(/^\/+/, '').replace(/\\/g, '/').replace(/\/{2,}/g, '/');
59
+ const roots = rootPaths(source);
60
+ if (!roots.length) return relative;
61
+ const matchingRoot = roots.find((root) => relative === root || relative.startsWith(root + '/')) || roots[0];
62
+ return relative === matchingRoot || relative.startsWith(matchingRoot + '/') ? relative : `${matchingRoot}/${relative}`;
63
+ }
64
+
65
+ export function normalizeGithubRefToRaw(source, ref) {
66
+ const srcRepo = sourceRepo(source);
67
+ const trimmed = String(ref || '').trim();
68
+ if (!trimmed) throw new Error('empty ref');
69
+
70
+ // Absolute URL handling: explicitly reject unsupported hosts or non-https.
71
+ const looksAbsolute = /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(trimmed);
72
+ if (looksAbsolute) {
73
+ const u = new URL(trimmed);
74
+ if (u.protocol !== 'https:') throw new Error('non-https URL');
75
+ if (u.hostname === 'raw.githubusercontent.com') {
76
+ const parts = u.pathname.split('/').filter(Boolean);
77
+ if (parts.length < 4) throw new Error('invalid raw GitHub URL');
78
+ const ownerRepo = `${parts[0]}/${parts[1]}`.toLowerCase();
79
+ if (ownerRepo !== srcRepo) throw new Error('cross-repo URL not allowed');
80
+ return u.href;
81
+ }
82
+ if (u.hostname === 'github.com' && /\/blob\//.test(u.pathname)) {
83
+ const raw = toRawFromBlobUrl(u.href);
84
+ const parts = new URL(raw).pathname.split('/').filter(Boolean);
85
+ const ownerRepo = `${parts[0]}/${parts[1]}`.toLowerCase();
86
+ if (ownerRepo !== srcRepo) throw new Error('cross-repo blob URL not allowed');
87
+ return raw;
88
+ }
89
+ // Explicit absolute URL but unsupported host: reject.
90
+ throw new Error('unsupported host');
91
+ }
92
+
93
+ const sourceRef = String(source.ref || '').trim();
94
+ if (!sourceRef) throw new Error('source.ref missing for repo-relative path');
95
+ const path = normalizeRelativePath(source, trimmed);
96
+ const [owner, repo] = srcRepo.split('/');
97
+ return `https://raw.githubusercontent.com/${owner}/${repo}/${sourceRef}/${path}`;
98
+ }
99
+
100
+
101
+ function exactCommitFromRawUrl(url = '') {
102
+ try {
103
+ const parts = new URL(url).pathname.split('/').filter(Boolean);
104
+ const ref = parts[2] || '';
105
+ return /^[0-9a-f]{40}$/i.test(ref) ? ref : '';
106
+ } catch (_) { return ''; }
107
+ }
108
+
109
+ export async function loadGithubFilesForSource(source, fileRefs = [], options = {}) {
110
+ const fetchImpl = options.fetchImpl || (typeof fetch !== 'undefined' ? fetch : null);
111
+ if (!fetchImpl) throw new Error('fetchImpl not available');
112
+ const refs = (Array.isArray(fileRefs) ? fileRefs : []).map((item, index) => normalizeLoadTarget(item, index));
113
+ const total = refs.length;
114
+ const concurrency = Math.max(1, Math.min(Number(options.concurrency || options.maxConcurrency || 8) || 8, 12, Math.max(total, 1)));
115
+ const recordsByIndex = new Array(total);
116
+ const errorsByIndex = new Array(total);
117
+ const transportEvents = [];
118
+ let requests = 0;
119
+ let nextIndex = 0;
120
+ let completed = 0;
121
+ let lastReported = -1;
122
+
123
+ const report = (loaded, labelPrefix = 'Loaded') => {
124
+ if (typeof options.onProgress !== 'function') return;
125
+ if (loaded === lastReported && loaded !== 0 && loaded !== total) return;
126
+ if (loaded !== 0 && loaded !== total && loaded % 10 !== 0) return;
127
+ lastReported = loaded;
128
+ options.onProgress({
129
+ phase: 'raw-file-load',
130
+ loaded,
131
+ total,
132
+ percent: total ? Math.min(92, 40 + Math.round((loaded / total) * 50)) : 90,
133
+ label: `${labelPrefix} GitHub Markdown ${loaded}/${total}`
134
+ });
135
+ };
136
+
137
+ const loadOne = async (index) => {
138
+ const target = refs[index];
139
+ const ref = target.ref;
140
+ let rawUrl;
141
+ try {
142
+ rawUrl = normalizeGithubRefToRaw(source, ref);
143
+ } catch (e) {
144
+ const message = String(e && e.message ? e.message : e);
145
+ errorsByIndex[index] = Object.assign({ ref, error: message }, targetAttribution(target));
146
+ transportEvents.push(Object.assign({ ref, code: 'github.raw.ref.invalid', severity: 'error', message }, targetAttribution(target)));
147
+ return;
148
+ }
149
+ if (!isHttps(rawUrl)) {
150
+ errorsByIndex[index] = Object.assign({ ref, error: 'non-https URL' }, targetAttribution(target));
151
+ transportEvents.push(Object.assign({ ref, code: 'github.raw.non-https', severity: 'error', message: 'non-https URL' }, targetAttribution(target)));
152
+ return;
153
+ }
154
+ try {
155
+ requests += 1;
156
+ const res = await fetchImpl(rawUrl, {});
157
+ if (!res || !res.ok) {
158
+ const message = `${res?.status || 'ERR'} ${res?.statusText || ''}`.trim();
159
+ errorsByIndex[index] = Object.assign({ ref, error: message }, targetAttribution(target));
160
+ transportEvents.push(Object.assign({ ref, url: rawUrl, status: res?.status || 0, code: 'github.raw.fetch.failed', severity: 'error', message }, targetAttribution(target)));
161
+ return;
162
+ }
163
+ const markdown = await res.text();
164
+ const name = rawUrl.split('/').pop() || ref;
165
+ const sourceTarget = Object.assign({
166
+ schema: 'tiinex.source.material.target.v1',
167
+ rawUrl,
168
+ materializedCommit: exactCommitFromRawUrl(rawUrl),
169
+ transportTier: res.transportTier || '',
170
+ loaded: true
171
+ }, targetAttribution(target));
172
+ recordsByIndex[index] = Object.assign(createRecordFromMarkdown(markdown, { path: rawUrl, name, sourceMode: 'github-source' }), { sourceTarget });
173
+ transportEvents.push(Object.assign({ ref, url: rawUrl, tier: res.transportTier || '', code: 'github.raw.record.loaded', severity: 'info' }, targetAttribution(target)));
174
+ } catch (e) {
175
+ const message = String(e && e.message ? e.message : e);
176
+ errorsByIndex[index] = Object.assign({ ref, error: message }, targetAttribution(target));
177
+ transportEvents.push(Object.assign({ ref, url: rawUrl || '', code: 'github.raw.fetch.exception', severity: 'error', message }, targetAttribution(target)));
178
+ }
179
+ };
180
+
181
+ const worker = async () => {
182
+ for (;;) {
183
+ const index = nextIndex;
184
+ nextIndex += 1;
185
+ if (index >= total) return;
186
+ await loadOne(index);
187
+ completed += 1;
188
+ report(completed);
189
+ }
190
+ };
191
+
192
+ if (total) report(0, 'Starting');
193
+ await Promise.all(Array.from({ length: concurrency }, () => worker()));
194
+
195
+ const records = recordsByIndex.filter(Boolean);
196
+ const errors = errorsByIndex.filter(Boolean);
197
+ return {
198
+ records,
199
+ errors,
200
+ okCount: records.length,
201
+ failCount: errors.length,
202
+ diagnostics: { requests, concurrency, transportEvents }
203
+ };
204
+ }
@@ -0,0 +1 @@
1
+ export function githubPermalink(repo, commit, path) { return `https://github.com/${repo}/blob/${commit}/${path}`; }
@@ -0,0 +1 @@
1
+ export function githubSource(repo, path) { return { kind: 'github', repo, path }; }