@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,124 @@
1
+ import { collectLocalFilesFromDataTransfer, materializeLocalMarkdownFiles } from '../adapters/local/local.adapter.js';
2
+ import { applyLocalAdapterResultToWorkspace } from '../workspaces/workspace.import.js';
3
+ import { assertCanonicalWorkspaceRuntimeState } from '../workspaces/workspace.runtimeCanonical.js';
4
+ import { durableLocalMutationDecision, DurableLocalMutationOperation } from './durableLocalMutationPolicy.js';
5
+ import { applyOperationalHandoffPackageToWorkspace, tryReadOperationalHandoffPackage } from './handoffPackageImportCommand.js';
6
+ import { fileToArchiveDecodedEntries } from '@tiinex/core/adapters/archive/archive.adapter.js';
7
+
8
+ export async function runLocalMaterialImportCommand(input = {}) {
9
+ const lifecycle = input.lifecycle;
10
+ const state = input.state;
11
+ const options = input.options || {};
12
+ const authority = durableLocalMutationDecision(input.persistenceOwnership, DurableLocalMutationOperation.localMaterialIntake);
13
+ if (!authority.ok) return { ok: false, error: authority.error, state, notice: authority.notice, authority };
14
+ if (!lifecycle) return { ok: false, error: 'lifecycle.missing', state, notice: 'Could not add selected material.' };
15
+ const fileList = input.fileList || [];
16
+ const collectFiles = input.collectFiles || collectLocalFilesFromDataTransfer;
17
+ const materialize = input.materialize || materializeLocalMarkdownFiles;
18
+ const apply = input.apply || applyLocalAdapterResultToWorkspace;
19
+ const files = options.fromDataTransfer ? await collectFiles(fileList) : Array.from(fileList || []).filter(Boolean);
20
+ if (!files.length && !input.adapterResult) return { ok: false, error: 'local.files.empty', state, notice: 'No files selected.', files: [] };
21
+
22
+ let adapterResult = input.adapterResult || null;
23
+ let predecodedArchive = null;
24
+ const singleZip = files.length === 1 && /\.zip$/i.test(String(files[0]?.name || files[0]?.relativePath || files[0]?.tiinexRelativePath || ''));
25
+ if (!adapterResult && options.handoffPackage !== false && singleZip) {
26
+ try {
27
+ predecodedArchive = await fileToArchiveDecodedEntries(files[0], options);
28
+ } catch (error) {
29
+ return { ok: false, error: 'local.materialize.failed', state, notice: 'Could not read local files or archives.', exception: error, files };
30
+ }
31
+ }
32
+ if (!adapterResult && options.handoffPackage !== false) {
33
+ const handoff = await tryReadOperationalHandoffPackage(files, predecodedArchive ? { ...options, predecodedArchive } : options);
34
+ if (handoff.detected) {
35
+ if (!handoff.ok) return { ok: false, error: handoff.error || 'handoff-package.invalid', state, notice: handoff.notice || 'Claimed Handoff package failed validation.', files, handoffPackage: handoff };
36
+ const appliedHandoff = applyOperationalHandoffPackageToWorkspace({ lifecycle, state, handoff, options });
37
+ if (!appliedHandoff?.ok) return { ok: false, error: appliedHandoff?.error || 'handoff-package.apply-failed', state, notice: appliedHandoff?.notice || 'Could not import Handoff package.', files, handoffPackage: handoff, applied: appliedHandoff };
38
+ const canonicality = assertCanonicalWorkspaceRuntimeState(appliedHandoff.state, 'handoff-package-import');
39
+ if (!canonicality.ok) return { ok: false, error: 'workspace.runtime-candidate-model-leak', state, notice: 'Imported Handoff package could not be normalized safely.', files, handoffPackage: handoff, applied: appliedHandoff, canonicality };
40
+ return { ok: true, state: appliedHandoff.state, notice: appliedHandoff.notice, files, handoffPackage: handoff, applied: appliedHandoff, materialCount: (appliedHandoff.adapterResult?.records?.length || 0) + (appliedHandoff.adapterResult?.assets?.length || 0) + (appliedHandoff.adapterResult?.workspaceEntries?.length || 0), workspaceId: appliedHandoff.workspaceId || '' };
41
+ }
42
+ }
43
+ if (!adapterResult) {
44
+ try {
45
+ adapterResult = await materialize(files, { ...options, ...(predecodedArchive ? { predecodedArchive } : {}), sourceMode: options.sourceMode || 'manual-files' });
46
+ } catch (error) {
47
+ return { ok: false, error: 'local.materialize.failed', state, notice: 'Could not read local files or archives.', exception: error, files };
48
+ }
49
+ }
50
+
51
+ const materialCount = localMaterialCount(adapterResult);
52
+ if (!materialCount) {
53
+ const skipped = (adapterResult?.warnings?.length || 0) + (adapterResult?.errors?.length || 0);
54
+ return {
55
+ ok: false,
56
+ error: skipped ? 'local.material.empty-with-findings' : 'local.material.empty',
57
+ state,
58
+ notice: skipped ? 'No readable Markdown, workspace, asset, or zip material was imported.' : 'No files selected.',
59
+ files,
60
+ adapterResult,
61
+ materialCount
62
+ };
63
+ }
64
+
65
+ let applied;
66
+ try {
67
+ applied = apply(lifecycle, state, input.workspaceId || '', adapterResult, options);
68
+ } catch (error) {
69
+ return { ok: false, error: 'local.apply.failed', state, notice: 'Could not materialize selected zip/files into the workspace.', exception: error, files, adapterResult, materialCount };
70
+ }
71
+
72
+ const changed = Boolean(applied?.addedRecords || applied?.addedAssets || applied?.workspaceOpened || applied?.workspaceEntries);
73
+ if (applied?.error === 'import.conflict.requires-resolution') {
74
+ return { ok: false, error: applied.error, state, notice: 'Incoming material overlaps this workspace.', conflicts: applied.conflicts || [], files, adapterResult, applied, materialCount };
75
+ }
76
+ if (applied?.error === 'import.cancelled') {
77
+ return { ok: false, error: applied.error, cancelled: true, state, notice: 'Import cancelled.', conflicts: applied.conflicts || [], files, adapterResult, applied, materialCount };
78
+ }
79
+ if (!applied?.ok && applied?.state === state && !changed) {
80
+ return { ok: false, error: applied?.error || 'local.apply.noop', state, notice: 'Could not add selected material.', files, adapterResult, applied, materialCount };
81
+ }
82
+ const nextState = applied?.state || state;
83
+ const canonicality = assertCanonicalWorkspaceRuntimeState(nextState, 'local-import');
84
+ if (!canonicality.ok) return { ok: false, error: 'workspace.runtime-candidate-model-leak', state, notice: 'Imported workspace material could not be normalized safely.', files, adapterResult, applied, materialCount, canonicality };
85
+ return {
86
+ ok: applied?.ok !== false || changed,
87
+ state: nextState,
88
+ notice: applied?.summary?.message || 'Import completed.',
89
+ files,
90
+ adapterResult,
91
+ applied,
92
+ materialCount,
93
+ summary: applied?.summary || null,
94
+ workspaceId: applied?.workspaceId || input.workspaceId || ''
95
+ };
96
+ }
97
+
98
+ export function localMaterialCount(adapterResult = {}) {
99
+ return (adapterResult.records?.length || 0) + (adapterResult.assets?.length || 0) + (adapterResult.workspaceEntries?.length || 0);
100
+ }
101
+
102
+
103
+ export function looksLikePastedTraceMarkdown(text = '') {
104
+ const body = String(text || '');
105
+ if (!body.trim()) return false;
106
+ if (/^#\s+Continuity Context\s*$/m.test(body)) return true;
107
+ return /^\s*Current Schema\s*:/mi.test(body) && /^#\s+Continuity Integrity\s*$/m.test(body);
108
+ }
109
+
110
+ export function makePastedTraceFile(text = '', options = {}) {
111
+ const body = String(text || '');
112
+ if (!looksLikePastedTraceMarkdown(body)) return null;
113
+ const stamp = (typeof options.clock === 'function' ? options.clock() : new Date().toISOString()).replace(/[:.]/g, '-');
114
+ const name = `pasted-trace-${stamp}.trace.md`;
115
+ const bytes = new TextEncoder().encode(body);
116
+ if (typeof File !== 'undefined') return new File([body], name, { type: 'text/markdown' });
117
+ return {
118
+ name,
119
+ size: bytes.byteLength,
120
+ type: 'text/markdown',
121
+ async text() { return body; },
122
+ async arrayBuffer() { return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength); }
123
+ };
124
+ }
@@ -0,0 +1,111 @@
1
+ import assert from 'node:assert/strict';
2
+ import fs from 'node:fs';
3
+ import { createRecordFromMarkdown } from '@tiinex/core/artifacts/artifact.record.js';
4
+ import { applyArtifactGraphLod, ArtifactGraphScope, buildArtifactGraph, graphNodeId, projectArtifactGraphScope } from '../graph/artifactGraph.model.js';
5
+ import { deterministicArtifactGraphLayout, prepareArtifactGraphProjection, scheduleArtifactGraphProjection } from '../graph/artifactGraph.project.js';
6
+ import { activeWorkspaceViewFor } from './workspaceMulticolumn.js';
7
+ import { stateWithWorkspaceViewPatchAndFocus, workspaceVerseNavigationPatch } from './workspaceScopedInteraction.js';
8
+
9
+ const root = record('root', 'Root', '.topics/root.trace.md');
10
+ const child = record('child', 'Child', '.topics/branch/child.trace.md', '.topics/root.trace.md');
11
+ const sibling = record('sibling', 'Sibling', '.topics/branch/sibling.trace.md');
12
+ const alpha = { id: 'alpha', title: 'Alpha', records: [root], assets: [] };
13
+ const beta = { id: 'beta', title: 'Beta', records: [child, sibling], assets: [] };
14
+
15
+ // The model reuses declared lineage truth and namespaces workspace identity without merging workspace authority.
16
+ const model = buildArtifactGraph([alpha, beta]);
17
+ assert.equal(model.schema, 'tiinex.artifact-graph.model.v1');
18
+ assert.equal(model.nodes.length, 3);
19
+ assert(model.nodes.some((node) => node.id === graphNodeId('alpha', root.id)));
20
+ const crossParent = model.edges.find((edge) => edge.kind === 'parent' && edge.to === graphNodeId('beta', child.id));
21
+ assert(crossParent, 'declared Parent edge should remain present');
22
+ assert.equal(crossParent.from, graphNodeId('alpha', root.id), 'unique exact Parent path may project across workspace boundaries');
23
+ assert.equal(crossParent.crossWorkspace, true);
24
+ assert.match(crossParent.method, /^exact-cross-workspace-/);
25
+
26
+ const workspaceProjection = projectArtifactGraphScope(model, { workspaceId: 'beta', scope: ArtifactGraphScope.workspace });
27
+ assert.deepEqual(workspaceProjection.nodes.map((node) => node.workspaceId), ['beta', 'beta']);
28
+ assert.equal(workspaceProjection.edges.some((edge) => edge.crossWorkspace), false, 'single-workspace scope does not silently import another boundary');
29
+ const focusProjection = projectArtifactGraphScope(model, { workspaceId: 'beta', scope: ArtifactGraphScope.focus, selectedRecordId: child.id });
30
+ assert(focusProjection.nodes.some((node) => node.id === graphNodeId('alpha', root.id)), 'focus neighborhood can intentionally traverse an exact cross-workspace relation');
31
+ const multiverse = projectArtifactGraphScope(model, { workspaceId: 'beta', scope: ArtifactGraphScope.multi });
32
+ assert.equal(multiverse.workspaces.length, 2);
33
+ assert.equal(multiverse.edges.filter((edge) => edge.crossWorkspace).length, 1);
34
+
35
+ // Ambiguous exact cross-workspace targets remain unresolved rather than fabricating a relation.
36
+ const alphaDuplicate = { id: 'alpha-duplicate', title: 'Alpha duplicate', records: [record('root-duplicate', 'Root duplicate', '.topics/root.trace.md')], assets: [] };
37
+ const ambiguous = buildArtifactGraph([alpha, alphaDuplicate, beta]);
38
+ const ambiguousParent = ambiguous.edges.find((edge) => edge.kind === 'parent' && edge.to === graphNodeId('beta', child.id));
39
+ assert.equal(ambiguousParent.from, '');
40
+ assert(ambiguous.findings.some((finding) => finding.code === 'artifactGraph.crossWorkspaceParent.ambiguous'));
41
+
42
+ // LOD is explicit, deterministic, boundary-aware and reports omitted material.
43
+ const many = {
44
+ id: 'many', title: 'Many', records: Array.from({ length: 80 }, (_, index) => {
45
+ const suffix = String(index).padStart(3, '0');
46
+ const parentSuffix = String(index - 1).padStart(3, '0');
47
+ return record(`n-${suffix}`, `Node ${index}`, `.topics/n-${suffix}.trace.md`, index ? `.topics/n-${parentSuffix}.trace.md` : '');
48
+ })
49
+ };
50
+ const manyGraph = projectArtifactGraphScope(buildArtifactGraph([many]), { workspaceId: 'many', scope: ArtifactGraphScope.workspace });
51
+ const lod = applyArtifactGraphLod(manyGraph, { maxNodes: 20 });
52
+ assert.equal(lod.nodes.length, 20);
53
+ assert.equal(lod.lod.truncated, true);
54
+ assert.equal(lod.lod.omittedNodes, 60);
55
+ assert.equal(lod.edges.length, 19, 'LOD should preserve a connected local topology for a linear lineage instead of returning disconnected ranked ties');
56
+
57
+ // Layout is stable for the same semantic graph regardless of input order and never claims authority.
58
+ const layoutA = deterministicArtifactGraphLayout(multiverse);
59
+ const layoutB = deterministicArtifactGraphLayout({ ...multiverse, nodes: multiverse.nodes.slice().reverse(), edges: multiverse.edges.slice().reverse() });
60
+ assert.deepEqual(layoutA.positions, layoutB.positions);
61
+ assert.equal(layoutA.authority, 'derived-projection-only');
62
+ assert.equal(layoutA.deterministic, true);
63
+ assert.equal(layoutA.bands.length, 2);
64
+
65
+ const prepared = prepareArtifactGraphProjection({ workspaces: [alpha, beta], workspaceId: 'beta', scope: ArtifactGraphScope.multi, maxNodes: 200 });
66
+ assert.equal(prepared.layout.schema, 'tiinex.artifact-graph.layout.v1');
67
+ assert.equal(prepared.graph.lod.truncated, false);
68
+
69
+
70
+ let workerPosted = false;
71
+ let workerTerminated = false;
72
+ await new Promise((resolve, reject) => {
73
+ const listeners = {};
74
+ const fakeWorker = {
75
+ addEventListener(type, handler) { listeners[type] = handler; },
76
+ postMessage(message) { workerPosted = true; queueMicrotask(() => listeners.message?.({ data: { id: message.id, ok: true, projection: { workerPrepared: true } } })); },
77
+ terminate() { workerTerminated = true; }
78
+ };
79
+ scheduleArtifactGraphProjection({ workspaces: [alpha], workspaceId: 'alpha' }, { workerFactory: () => fakeWorker, onReady: (value) => { try { assert.equal(value.workerPrepared, true); resolve(); } catch (error) { reject(error); } }, onError: reject });
80
+ });
81
+ assert.equal(workerPosted, true, 'browser scheduler should prefer off-thread preparation when a Worker is available');
82
+ assert.equal(workerTerminated, true, 'one-shot graph worker should terminate after returning its projection');
83
+
84
+ // Graph navigation preserves selected artifact focus while Feed/Tree return still clears lineage-only state.
85
+ const view = { universe: 'column', workspaceVerse: 'lineage', selectedRecordId: child.id, lineageReturnVerse: 'tree', query: 'child' };
86
+ const state = { activeWorkspaceId: beta.id, workspaces: [beta], view, workspaceViews: { [beta.id]: view } };
87
+ const graphState = stateWithWorkspaceViewPatchAndFocus(state, beta.id, workspaceVerseNavigationPatch('graph'), 1280);
88
+ assert.equal(graphState.view.workspaceVerse, 'graph');
89
+ assert.equal(graphState.view.selectedRecordId, child.id);
90
+ assert.equal(activeWorkspaceViewFor(graphState, beta.id).workspaceVerse, 'graph');
91
+ const feedState = stateWithWorkspaceViewPatchAndFocus(graphState, beta.id, workspaceVerseNavigationPatch('feed'), 1280);
92
+ assert.equal(feedState.view.selectedRecordId, '');
93
+
94
+ // Product wiring keeps graph code out of first paint and opens the canonical workspace artifact on selection.
95
+ const workspaceViewSource = fs.readFileSync(new URL('../schemas/workspace/workspace.views.jsx', import.meta.url), 'utf8');
96
+ const graphViewSource = fs.readFileSync(new URL('../schemas/workspace/workspace.graph.views.jsx', import.meta.url), 'utf8');
97
+ const toolbarSource = fs.readFileSync(new URL('../schemas/workspace/workspace.chrome.views.jsx', import.meta.url), 'utf8');
98
+ assert.ok(workspaceViewSource.includes("React.lazy(() => import('./workspace.graph.views.jsx')"));
99
+ assert.ok(graphViewSource.includes('scheduleArtifactGraphProjection'));
100
+ assert.ok(graphViewSource.includes('onOpenRecord?.(node.workspaceId, node.recordId)'));
101
+ assert.ok(graphViewSource.includes('Multi-Verse'));
102
+ assert.ok(toolbarSource.includes('GRAPH ORIENTATION'));
103
+ assert.ok(toolbarSource.includes('aria-label="Discovery view"'), 'existing Feed/Tree discovery UI shape remains intact');
104
+
105
+ console.log('✓ Node Graph Verse projection invariants passed');
106
+
107
+ function record(id, title, path, trace = '') {
108
+ const parent = trace ? `- Parent\n - Parent Schema: [tiinex.topic.v1](tiinex.topic.v1.schema.md)\n - Trace: [Parent](${trace})\n` : '';
109
+ const markdown = `# Continuity Context\n\n- Envelope Schema: [tiinex.root.v1](tiinex.root.v1.schema.md)\n${parent}- Current\n - Current Schema: [tiinex.topic.v1](tiinex.topic.v1.schema.md)\n - Created At: 2026-09-03 12:00:00\n - Summary: ${title}\n\n---\n\n# ${title}\n\n${title} body.\n\n---\n\n# Continuity Integrity\n\n- local-test\n - Towards: self\n - Value: ${id}-self\n`;
110
+ return Object.assign(createRecordFromMarkdown(markdown, { path, sourceMode: 'local-test' }), { id });
111
+ }
@@ -0,0 +1,92 @@
1
+ export const PersistenceRouteOwner = Object.freeze({
2
+ semanticState: 'semantic-state',
3
+ publicTarget: 'public-target',
4
+ clean: 'clean'
5
+ });
6
+
7
+ export const TIINEX_HISTORY_AUTHORITY_KEY = '__tiinexPersistenceAuthority';
8
+ export const TIINEX_HISTORY_AUTHORITY_SCHEMA = 'tiinex.history.persistenceAuthority.v1';
9
+
10
+ export const DurableLocalAuthority = Object.freeze({
11
+ normal: 'normal',
12
+ isolatedPreexistingRecovery: 'isolated-preexisting-recovery'
13
+ });
14
+
15
+ export function createPersistenceOwnershipPolicy(initialRouteKind = PersistenceRouteOwner.clean, options = {}) {
16
+ let routeKind = normalizeRouteKind(initialRouteKind);
17
+ let durableLocalAuthority = normalizeDurableLocalAuthority(
18
+ options.durableLocalAuthority,
19
+ routeKind === PersistenceRouteOwner.publicTarget ? DurableLocalAuthority.isolatedPreexistingRecovery : DurableLocalAuthority.normal
20
+ );
21
+
22
+ function setRouteKind(nextKind = PersistenceRouteOwner.clean) {
23
+ routeKind = normalizeRouteKind(nextKind);
24
+ return routeKind;
25
+ }
26
+
27
+ function setDurableLocalAuthority(nextAuthority = DurableLocalAuthority.normal) {
28
+ durableLocalAuthority = normalizeDurableLocalAuthority(nextAuthority);
29
+ return durableLocalAuthority;
30
+ }
31
+
32
+ function restoreHistoryEntry({ routeKind: nextRouteKind = PersistenceRouteOwner.clean, durableLocalAuthority: nextDurableAuthority = DurableLocalAuthority.normal } = {}) {
33
+ routeKind = normalizeRouteKind(nextRouteKind);
34
+ durableLocalAuthority = normalizeDurableLocalAuthority(nextDurableAuthority, routeKind === PersistenceRouteOwner.publicTarget ? DurableLocalAuthority.isolatedPreexistingRecovery : DurableLocalAuthority.normal);
35
+ return report();
36
+ }
37
+
38
+ function beginSemanticNavigation(requestedMode = 'push') {
39
+ const firstExitFromPublicTarget = routeKind === PersistenceRouteOwner.publicTarget;
40
+ routeKind = PersistenceRouteOwner.semanticState;
41
+ return Object.freeze({
42
+ firstExitFromPublicTarget,
43
+ mode: firstExitFromPublicTarget ? 'push' : normalizeWriteMode(requestedMode),
44
+ routeKind,
45
+ durableLocalAuthority
46
+ });
47
+ }
48
+
49
+ function writePolicy() {
50
+ const out = { routeKind, durableLocalAuthority };
51
+ if (routeKind === PersistenceRouteOwner.publicTarget) out.preserveUrl = true;
52
+ if (durableLocalAuthority === DurableLocalAuthority.isolatedPreexistingRecovery) out.durableLocalPolicy = 'preserve-existing';
53
+ out.historyStatePatch = historyStatePatch(durableLocalAuthority);
54
+ return Object.freeze(out);
55
+ }
56
+
57
+ function report() { return Object.freeze({ routeKind, durableLocalAuthority }); }
58
+
59
+ return Object.freeze({ setRouteKind, setDurableLocalAuthority, restoreHistoryEntry, beginSemanticNavigation, writePolicy, report });
60
+ }
61
+
62
+ export function persistenceWriteEnvForOwnership(ownership = null, base = {}) {
63
+ const policy = ownership?.writePolicy?.() || {};
64
+ return Object.assign({}, base || {}, policy);
65
+ }
66
+
67
+ export function isolatedDurableLocalAuthority(ownership = null) {
68
+ return ownership?.report?.().durableLocalAuthority === DurableLocalAuthority.isolatedPreexistingRecovery;
69
+ }
70
+
71
+ function historyStatePatch(durableLocalAuthority) {
72
+ return {
73
+ [TIINEX_HISTORY_AUTHORITY_KEY]: durableLocalAuthority === DurableLocalAuthority.isolatedPreexistingRecovery
74
+ ? Object.freeze({ schema: TIINEX_HISTORY_AUTHORITY_SCHEMA, durableLocalAuthority: DurableLocalAuthority.isolatedPreexistingRecovery })
75
+ : null
76
+ };
77
+ }
78
+
79
+ function normalizeRouteKind(value = '') {
80
+ const kind = String(value || '').trim();
81
+ if (kind === PersistenceRouteOwner.semanticState || kind === PersistenceRouteOwner.publicTarget) return kind;
82
+ return PersistenceRouteOwner.clean;
83
+ }
84
+
85
+ function normalizeDurableLocalAuthority(value = '', fallback = DurableLocalAuthority.normal) {
86
+ const authority = String(value || '').trim();
87
+ if (authority === DurableLocalAuthority.isolatedPreexistingRecovery) return authority;
88
+ if (authority === DurableLocalAuthority.normal) return authority;
89
+ return fallback;
90
+ }
91
+
92
+ function normalizeWriteMode(value = '') { return value === 'push' ? 'push' : 'replace'; }
@@ -0,0 +1,7 @@
1
+ import { stateWithWorkspacePresentationPruned } from './workspaceMulticolumn.js';
2
+
3
+ export function canonicalProductState(state = {}, _persistence = null, boundary = 'product-runtime') {
4
+ const violation = (state?.workspaces || []).find((workspace) => workspace && Object.prototype.hasOwnProperty.call(workspace, 'workspaceMergeCandidates'));
5
+ if (violation) throw new Error(`workspace.runtime-candidate-leak:${boundary}:${violation.id || 'workspace'}`);
6
+ return stateWithWorkspacePresentationPruned(state);
7
+ }
@@ -0,0 +1 @@
1
+ export function AppProviders(model) { return model; }
@@ -0,0 +1 @@
1
+ export function LocaleProvider(locale) { return { locale }; }
@@ -0,0 +1 @@
1
+ export function SchemaRegistryProvider(registry) { return registry; }
@@ -0,0 +1 @@
1
+ export function WorkspaceProvider(workspace) { return workspace; }
@@ -0,0 +1,251 @@
1
+ import { parseGithubIssueSnapshotTarget } from '../adapters/github/github.issueSnapshot.js';
2
+ import { normalizeWorkspaceMemberIdentity, singleWorkspaceMemberBinding } from '../workspaces/workspace.memberIdentity.js';
3
+
4
+ export const PUBLIC_TARGET_SCHEMA = 'tiinex.publicTarget.v1';
5
+
6
+ export const PublicTargetRestoreCapability = Object.freeze({
7
+ restorable: 'restorable',
8
+ unsupported: 'unsupported',
9
+ invalid: 'invalid'
10
+ });
11
+
12
+ export function classifyRouteLocation(locationLike = {}) {
13
+ const hash = String(locationLike?.hash || '').trim();
14
+ if (!hash) return Object.freeze({ kind: 'clean', hash: '' });
15
+ if (/^#state=/i.test(hash)) return Object.freeze({ kind: 'semantic-state', hash });
16
+ const target = parsePublicTargetHash(hash);
17
+ if (target) return Object.freeze({ kind: 'public-target', hash, target });
18
+ return Object.freeze({ kind: 'unsupported-hash', hash });
19
+ }
20
+
21
+ export function parsePublicTargetHash(hashValue = '') {
22
+ const raw = String(hashValue || '').replace(/^#/, '').trim();
23
+ if (!raw) return null;
24
+ const decoded = safeDecode(raw);
25
+ if (/^(?:state|view)=/i.test(decoded)) return null;
26
+ const splitter = decoded.indexOf('|');
27
+ const adapterHint = splitter > 0 ? normalizePublicAdapter(decoded.slice(0, splitter)) : '';
28
+ const payload = splitter > 0 ? decoded.slice(splitter + 1) : decoded;
29
+ if (adapterHint === 'workspace.member') return parseWorkspaceMemberRoutePayload(payload);
30
+ const externalTarget = safeDecode(payload);
31
+ return publicTargetFromExternalUrl(externalTarget, adapterHint);
32
+ }
33
+
34
+ export function publicTargetFromExternalUrl(value = '', adapterHint = '') {
35
+ const externalTarget = String(value || '').trim();
36
+ if (!/^https?:\/\//i.test(externalTarget)) return null;
37
+ const hinted = normalizePublicAdapter(adapterHint);
38
+ const githubIssue = parseGithubIssueSnapshotTarget(externalTarget);
39
+ if (githubIssue.ok && (!hinted || hinted === 'github.issue' || hinted === 'github.discussion')) {
40
+ return freezeTarget({
41
+ adapterId: 'github',
42
+ targetKind: githubIssue.commentId ? 'github.issue.comment' : (githubIssue.kind === 'discussion' ? 'github.discussion' : 'github.issue'),
43
+ externalTarget: githubIssue.canonicalUrl,
44
+ repository: githubIssue.repository,
45
+ issueNumber: githubIssue.number,
46
+ commentId: githubIssue.commentId || ''
47
+ });
48
+ }
49
+ const githubFile = parseGithubFileTarget(externalTarget);
50
+ if (githubFile && (!hinted || hinted === 'github.file' || hinted === 'workspace')) {
51
+ return freezeTarget(Object.assign({}, githubFile, {
52
+ targetKind: hinted === 'workspace'
53
+ ? 'workspace'
54
+ : (hinted === 'github.file' ? 'github.file' : (/\.workspace\.md$/i.test(githubFile.path) ? 'workspace' : 'github.file'))
55
+ }));
56
+ }
57
+ let url;
58
+ try { url = new URL(externalTarget); } catch (_) { return null; }
59
+ const path = url.pathname || '';
60
+ const targetKind = hinted === 'workspace'
61
+ ? 'workspace'
62
+ : (hinted === 'web.markdown'
63
+ ? 'web.markdown'
64
+ : (/\.workspace\.md$/i.test(path) ? 'workspace' : (/\.(?:md|markdown|txt)$/i.test(path) ? 'web.markdown' : 'web.url')));
65
+ return freezeTarget({ adapterId: 'web', targetKind, externalTarget: url.href });
66
+ }
67
+
68
+ export function artifactPublicTargetFromRecord(record = {}) {
69
+ for (const value of recordPublicTargetValues(record)) {
70
+ const parsed = artifactPublicTargetFromExternalUrl(value);
71
+ if (parsed) return parsed;
72
+ }
73
+ return null;
74
+ }
75
+
76
+ export function publicTargetFromRecord(record = {}) {
77
+ for (const value of recordPublicTargetValues(record)) {
78
+ const parsed = publicTargetFromExternalUrl(value, isWorkspaceArtifact(record) ? 'workspace' : '');
79
+ if (parsed) return parsed;
80
+ }
81
+ return null;
82
+ }
83
+
84
+ export function buildPublicTargetHash(target = {}) {
85
+ const normalized = normalizePublicTarget(target);
86
+ if (!normalized) return '';
87
+ const adapter = routeAdapterForTarget(normalized);
88
+ if (normalized.targetKind === 'workspace.member') {
89
+ const payload = JSON.stringify({ target: normalized.externalTarget, memberKey: normalized.memberIdentity?.key || '' });
90
+ return `#${encodeURIComponent(`${adapter}|${payload}`)}`;
91
+ }
92
+ return `#${encodeURIComponent(`${adapter}|${normalized.externalTarget}`)}`;
93
+ }
94
+
95
+ export function buildPublicViewerTargetUrl(target = {}, publicViewerUrl = '') {
96
+ const hash = buildPublicTargetHash(target);
97
+ const base = safePublicViewerUrl(publicViewerUrl);
98
+ if (!hash || !base) return '';
99
+ const url = new URL(base);
100
+ url.hash = '';
101
+ return `${url.href}${hash}`;
102
+ }
103
+
104
+ export function normalizePublicTarget(target = {}) {
105
+ if (target?.schema === PUBLIC_TARGET_SCHEMA && /^https?:\/\//i.test(String(target.externalTarget || ''))) {
106
+ if (target.targetKind === 'workspace.member' && !normalizeWorkspaceMemberIdentity(target.memberIdentity)) return null;
107
+ return freezeTarget(target);
108
+ }
109
+ return publicTargetFromExternalUrl(target?.externalTarget || target?.url || '', target?.targetKind || target?.adapter || target?.adapterId || '');
110
+ }
111
+
112
+ export function publicTargetFromWorkspaceMemberBinding(binding = null) {
113
+ const descriptor = binding?.descriptorTarget;
114
+ const memberIdentity = normalizeWorkspaceMemberIdentity(binding?.memberIdentity);
115
+ if (!descriptor || !memberIdentity) return null;
116
+ const target = publicTargetFromExternalUrl(descriptor.externalTarget || '', 'workspace');
117
+ return target ? freezeTarget(Object.assign({}, target, { targetKind: 'workspace.member', memberIdentity })) : null;
118
+ }
119
+
120
+ export function publicTargetFromWorkspace(workspace = {}) {
121
+ const binding = singleWorkspaceMemberBinding(workspace);
122
+ return binding ? publicTargetFromWorkspaceMemberBinding(binding) : null;
123
+ }
124
+
125
+
126
+ export function publicTargetRestoreCapability(target = {}) {
127
+ const normalized = normalizePublicTarget(target);
128
+ if (!normalized) return PublicTargetRestoreCapability.invalid;
129
+ const kind = normalized.targetKind;
130
+ if (kind === 'web.url') return PublicTargetRestoreCapability.unsupported;
131
+ if (['github.issue', 'github.issue.comment', 'github.discussion'].includes(kind)) {
132
+ return normalized.adapterId === 'github' && normalized.repository && normalized.issueNumber
133
+ ? PublicTargetRestoreCapability.restorable
134
+ : PublicTargetRestoreCapability.invalid;
135
+ }
136
+ if (kind === 'github.file') {
137
+ return normalized.adapterId === 'github' && normalized.repository && normalized.path
138
+ ? PublicTargetRestoreCapability.restorable
139
+ : PublicTargetRestoreCapability.invalid;
140
+ }
141
+ if (kind === 'web.markdown') {
142
+ return normalized.adapterId === 'web'
143
+ ? PublicTargetRestoreCapability.restorable
144
+ : PublicTargetRestoreCapability.invalid;
145
+ }
146
+ if (kind === 'workspace' || kind === 'workspace.member') {
147
+ if (normalized.adapterId === 'github') {
148
+ return normalized.repository && normalized.path
149
+ ? PublicTargetRestoreCapability.restorable
150
+ : PublicTargetRestoreCapability.invalid;
151
+ }
152
+ return normalized.adapterId === 'web'
153
+ ? PublicTargetRestoreCapability.restorable
154
+ : PublicTargetRestoreCapability.invalid;
155
+ }
156
+ return PublicTargetRestoreCapability.unsupported;
157
+ }
158
+
159
+ function artifactPublicTargetFromExternalUrl(value = '') {
160
+ const externalTarget = String(value || '').trim();
161
+ if (!/^https?:\/\//i.test(externalTarget)) return null;
162
+ const githubIssue = parseGithubIssueSnapshotTarget(externalTarget);
163
+ if (githubIssue.ok) return publicTargetFromExternalUrl(externalTarget);
164
+ if (parseGithubFileTarget(externalTarget)) return publicTargetFromExternalUrl(externalTarget, 'github.file');
165
+ let url;
166
+ try { url = new URL(externalTarget); } catch (_) { return null; }
167
+ if (/\.(?:md|markdown|txt)$/i.test(url.pathname || '')) return publicTargetFromExternalUrl(externalTarget, 'web.markdown');
168
+ return publicTargetFromExternalUrl(externalTarget);
169
+ }
170
+
171
+ function recordPublicTargetValues(record = {}) {
172
+ return [
173
+ record?.sourceTarget?.inputTarget,
174
+ record?.sourceTarget?.sourceUrl,
175
+ record?.sourceTarget?.rawUrl,
176
+ record?.snapshot?.target?.canonicalUrl,
177
+ record?.snapshot?.sourceUrl,
178
+ record?.source?.url
179
+ ].map((value) => String(value || '').trim()).filter(Boolean);
180
+ }
181
+
182
+ function freezeTarget(input = {}) {
183
+ const memberIdentity = input.targetKind === 'workspace.member' ? normalizeWorkspaceMemberIdentity(input.memberIdentity) : null;
184
+ return Object.freeze({
185
+ schema: PUBLIC_TARGET_SCHEMA,
186
+ adapterId: String(input.adapterId || '').trim(),
187
+ targetKind: String(input.targetKind || '').trim(),
188
+ externalTarget: String(input.externalTarget || '').trim(),
189
+ repository: String(input.repository || '').trim(),
190
+ ref: String(input.ref || '').trim(),
191
+ path: String(input.path || '').trim(),
192
+ issueNumber: Number(input.issueNumber || 0),
193
+ commentId: String(input.commentId || '').trim(),
194
+ ...(memberIdentity ? { memberIdentity } : {})
195
+ });
196
+ }
197
+
198
+ function parseWorkspaceMemberRoutePayload(payload = '') {
199
+ let parsed = null;
200
+ try { parsed = JSON.parse(String(payload || '')); } catch (_) { return null; }
201
+ const descriptor = publicTargetFromExternalUrl(parsed?.target || '', 'workspace');
202
+ const memberIdentity = normalizeWorkspaceMemberIdentity({ key: parsed?.memberKey || '' });
203
+ if (!descriptor || !memberIdentity) return null;
204
+ return freezeTarget(Object.assign({}, descriptor, { targetKind: 'workspace.member', memberIdentity }));
205
+ }
206
+
207
+ function parseGithubFileTarget(value = '') {
208
+ let url;
209
+ try { url = new URL(value); } catch (_) { return null; }
210
+ const parts = url.pathname.split('/').filter(Boolean);
211
+ if (url.hostname === 'github.com' && parts.length >= 5 && parts[2] === 'blob') {
212
+ const [owner, repo, , ref, ...pathParts] = parts;
213
+ if (!owner || !repo || !ref || !pathParts.length) return null;
214
+ return { adapterId: 'github', externalTarget: url.href, repository: `${owner}/${repo}`, ref, path: pathParts.join('/') };
215
+ }
216
+ if (url.hostname === 'raw.githubusercontent.com' && parts.length >= 4) {
217
+ const [owner, repo, ref, ...pathParts] = parts;
218
+ if (!owner || !repo || !ref || !pathParts.length) return null;
219
+ return { adapterId: 'github', externalTarget: url.href, repository: `${owner}/${repo}`, ref, path: pathParts.join('/') };
220
+ }
221
+ return null;
222
+ }
223
+
224
+ function normalizePublicAdapter(value = '') {
225
+ const key = String(value || '').trim().toLowerCase().replace(/:/g, '.');
226
+ if (['issue', 'github-issue', 'github.issue'].includes(key)) return 'github.issue';
227
+ if (['discussion', 'github-discussion', 'github.discussion'].includes(key)) return 'github.discussion';
228
+ if (['github.file', 'github.raw', 'github.blob', 'github.raw-file'].includes(key)) return 'github.file';
229
+ if (['workspace.member', 'tiinex.workspace.member', 'workspace-member'].includes(key)) return 'workspace.member';
230
+ if (['workspace', 'tiinex.workspace', 'web.workspace', 'workspace.md'].includes(key)) return 'workspace';
231
+ if (['web.markdown', 'web.md', 'markdown', 'web.file'].includes(key)) return 'web.markdown';
232
+ if (['web.url', 'web', 'url'].includes(key)) return 'web.url';
233
+ return key;
234
+ }
235
+
236
+ function routeAdapterForTarget(target = {}) {
237
+ if (target.targetKind === 'workspace.member') return 'workspace.member';
238
+ if (target.targetKind === 'workspace') return 'workspace';
239
+ if (target.targetKind === 'github.issue' || target.targetKind === 'github.issue.comment') return 'github.issue';
240
+ if (target.targetKind === 'github.discussion') return 'github.discussion';
241
+ if (target.targetKind === 'github.file') return 'github.file';
242
+ if (target.targetKind === 'web.markdown') return 'web.markdown';
243
+ return 'web.url';
244
+ }
245
+
246
+ function isWorkspaceArtifact(record = {}) {
247
+ return Boolean(record?.workspaceArtifactRole?.openEligible) || /\.workspace\.md$/i.test(String(record?.path || record?.sourceTarget?.sourceArtifactPath || ''));
248
+ }
249
+
250
+ function safeDecode(value = '') { try { return decodeURIComponent(String(value || '')); } catch (_) { return String(value || ''); } }
251
+ function safePublicViewerUrl(value = '') { try { const url = new URL(String(value || '').trim()); return /^https?:$/.test(url.protocol) ? url.href : ''; } catch (_) { return ''; } }