@tiinex/core 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.
- package/LICENSE +201 -0
- package/NOTICE +31 -0
- package/README.md +45 -0
- package/package.json +176 -0
- package/src/actions/record.actions.js +312 -0
- package/src/adapters/adapter.contracts.js +143 -0
- package/src/adapters/archive/archive.adapter.js +502 -0
- package/src/adapters/archive/archive.portableChangeset.js +141 -0
- package/src/adapters/archive/archive.transport.js +124 -0
- package/src/artifacts/artifact.localDraft.js +27 -0
- package/src/artifacts/artifact.normalize.js +28 -0
- package/src/artifacts/artifact.parse.js +207 -0
- package/src/artifacts/artifact.record.js +83 -0
- package/src/audit/audit.run.js +103 -0
- package/src/audit/audit.summary.js +7 -0
- package/src/diagnostics/sourceBoundary.report.js +112 -0
- package/src/export/package.apply.js +349 -0
- package/src/export/package.builder.js +366 -0
- package/src/export/package.bytes.js +164 -0
- package/src/export/package.controlIntegrity.js +42 -0
- package/src/export/package.controlTopology.js +97 -0
- package/src/export/package.fileMap.js +174 -0
- package/src/export/package.manifest.js +401 -0
- package/src/export/package.preflight.js +204 -0
- package/src/export/package.sourceReference.js +81 -0
- package/src/export/package.workspaceContext.js +144 -0
- package/src/export/package.zip.js +128 -0
- package/src/export/tree.bundle.js +278 -0
- package/src/governance/governance.boundary.js +196 -0
- package/src/integrity/integrity.c14nV2.js +190 -0
- package/src/integrity/integrity.methodReference.js +73 -0
- package/src/integrity/integrity.validate.js +56 -0
- package/src/lineage/lineage.candidateResolution.js +46 -0
- package/src/lineage/lineage.githubIssueComment.js +106 -0
- package/src/lineage/lineage.githubIssueLocal.js +196 -0
- package/src/lineage/lineage.githubIssueTarget.js +89 -0
- package/src/lineage/lineage.integrity.js +133 -0
- package/src/lineage/lineage.materialPreference.js +26 -0
- package/src/lineage/lineage.model.js +63 -0
- package/src/lineage/lineage.parentAuthority.js +5 -0
- package/src/lineage/lineage.parentBinding.js +104 -0
- package/src/lineage/lineage.pathBasis.js +47 -0
- package/src/lineage/lineage.resolve.js +388 -0
- package/src/lineage/lineage.sourceScope.js +74 -0
- package/src/lineage/lineage.targetKeys.js +80 -0
- package/src/lineage/lineage.traverse.js +132 -0
- package/src/public/applicationProjection.js +236 -0
- package/src/public/companionResources.js +246 -0
- package/src/public/index.js +16 -0
- package/src/public/node.js +2 -0
- package/src/public/schemaAncestry.js +26 -0
- package/src/publication/publication.contract.js +196 -0
- package/src/publication/publication.preflight.js +159 -0
- package/src/publication/publication.targetContract.js +241 -0
- package/src/reingest/reingest.plan.js +162 -0
- package/src/release/plan.mjs +28 -0
- package/src/release/policy.mjs +100 -0
- package/src/release/run.mjs +74 -0
- package/src/schemas/capability.registry.js +226 -0
- package/src/schemas/companion.js +245 -0
- package/src/schemas/contracts.js +6 -0
- package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.js +14 -0
- package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.json +23 -0
- package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.runtime.json +4283 -0
- package/src/schemas/coordination/handoff/tiinex.handoff.v1.schema.source.js +9 -0
- package/src/schemas/coordination/project/tiinex.project.v1.schema.js +26 -0
- package/src/schemas/coordination/project/tiinex.project.v1.schema.json +23 -0
- package/src/schemas/coordination/project/tiinex.project.v1.schema.runtime.json +1985 -0
- package/src/schemas/coordination/project/tiinex.project.v1.schema.source.js +9 -0
- package/src/schemas/core/decision/tiinex.decision.v1.schema.js +14 -0
- package/src/schemas/core/decision/tiinex.decision.v1.schema.json +24 -0
- package/src/schemas/core/decision/tiinex.decision.v1.schema.runtime.json +1700 -0
- package/src/schemas/core/decision/tiinex.decision.v1.schema.source.js +9 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.capabilities.js +14 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.en.i18n.json +6 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.findings.js +9 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.presenter.js +1 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.schema.js +32 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.schema.json +24 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.schema.runtime.json +2184 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.schema.source.js +9 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.sv.i18n.json +6 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.transitions.js +1 -0
- package/src/schemas/core/evidence/tiinex.evidence.v1.validate.js +10 -0
- package/src/schemas/core/feedback/tiinex.feedback.v1.schema.js +14 -0
- package/src/schemas/core/feedback/tiinex.feedback.v1.schema.json +23 -0
- package/src/schemas/core/feedback/tiinex.feedback.v1.schema.runtime.json +1773 -0
- package/src/schemas/core/feedback/tiinex.feedback.v1.schema.source.js +9 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.capabilities.js +11 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.contract.js +40 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.en.i18n.json +9 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.findings.js +12 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.localMaterialization.js +89 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.presenter.js +8 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.js +34 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.json +23 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.runtime.json +2029 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.schema.source.js +9 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.sv.i18n.json +9 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.transitions.js +1 -0
- package/src/schemas/core/interpretation/tiinex.interpretation.v1.validate.js +25 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.capabilities.js +14 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.en.i18n.json +6 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.findings.js +9 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.presenter.js +1 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.schema.js +31 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.schema.json +23 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.schema.runtime.json +2033 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.schema.source.js +9 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.sv.i18n.json +6 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.transitions.js +1 -0
- package/src/schemas/core/preservation/tiinex.preservation.v1.validate.js +10 -0
- package/src/schemas/core/relation/tiinex.relation.v1.capabilities.js +7 -0
- package/src/schemas/core/relation/tiinex.relation.v1.contract.js +3 -0
- package/src/schemas/core/relation/tiinex.relation.v1.en.i18n.json +4 -0
- package/src/schemas/core/relation/tiinex.relation.v1.findings.js +9 -0
- package/src/schemas/core/relation/tiinex.relation.v1.localMaterialization.js +153 -0
- package/src/schemas/core/relation/tiinex.relation.v1.presenter.js +3 -0
- package/src/schemas/core/relation/tiinex.relation.v1.schema.js +20 -0
- package/src/schemas/core/relation/tiinex.relation.v1.schema.json +23 -0
- package/src/schemas/core/relation/tiinex.relation.v1.schema.runtime.json +1668 -0
- package/src/schemas/core/relation/tiinex.relation.v1.schema.source.js +9 -0
- package/src/schemas/core/relation/tiinex.relation.v1.sv.i18n.json +4 -0
- package/src/schemas/core/relation/tiinex.relation.v1.transitions.js +1 -0
- package/src/schemas/core/relation/tiinex.relation.v1.validate.js +36 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.capabilities.js +14 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.contract.js +57 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.en.i18n.json +4 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.findings.js +13 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.presenter.js +3 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.js +20 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.json +24 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.runtime.json +3315 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.schema.source.js +9 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.sv.i18n.json +4 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.transitions.js +1 -0
- package/src/schemas/core/relation/workspace/representation/tiinex.workspace.representation.v1.validate.js +78 -0
- package/src/schemas/core/signal/tiinex.signal.v1.schema.js +14 -0
- package/src/schemas/core/signal/tiinex.signal.v1.schema.json +23 -0
- package/src/schemas/core/signal/tiinex.signal.v1.schema.runtime.json +1733 -0
- package/src/schemas/core/signal/tiinex.signal.v1.schema.source.js +9 -0
- package/src/schemas/core/task/tiinex.task.v1.capabilities.js +11 -0
- package/src/schemas/core/task/tiinex.task.v1.contract.js +3 -0
- package/src/schemas/core/task/tiinex.task.v1.en.i18n.json +15 -0
- package/src/schemas/core/task/tiinex.task.v1.findings.js +18 -0
- package/src/schemas/core/task/tiinex.task.v1.localMaterialization.js +148 -0
- package/src/schemas/core/task/tiinex.task.v1.presenter.js +8 -0
- package/src/schemas/core/task/tiinex.task.v1.schema.js +35 -0
- package/src/schemas/core/task/tiinex.task.v1.schema.json +23 -0
- package/src/schemas/core/task/tiinex.task.v1.schema.runtime.json +1708 -0
- package/src/schemas/core/task/tiinex.task.v1.schema.source.js +9 -0
- package/src/schemas/core/task/tiinex.task.v1.sv.i18n.json +15 -0
- package/src/schemas/core/task/tiinex.task.v1.transitions.js +3 -0
- package/src/schemas/core/task/tiinex.task.v1.validate.js +41 -0
- package/src/schemas/core/topic/tiinex.topic.v1.capabilities.js +14 -0
- package/src/schemas/core/topic/tiinex.topic.v1.creation.js +46 -0
- package/src/schemas/core/topic/tiinex.topic.v1.en.i18n.json +8 -0
- package/src/schemas/core/topic/tiinex.topic.v1.findings.js +11 -0
- package/src/schemas/core/topic/tiinex.topic.v1.localMaterialization.js +135 -0
- package/src/schemas/core/topic/tiinex.topic.v1.presenter.js +1 -0
- package/src/schemas/core/topic/tiinex.topic.v1.schema.js +34 -0
- package/src/schemas/core/topic/tiinex.topic.v1.schema.json +23 -0
- package/src/schemas/core/topic/tiinex.topic.v1.schema.runtime.json +1699 -0
- package/src/schemas/core/topic/tiinex.topic.v1.schema.source.js +9 -0
- package/src/schemas/core/topic/tiinex.topic.v1.sv.i18n.json +8 -0
- package/src/schemas/core/topic/tiinex.topic.v1.transitions.js +31 -0
- package/src/schemas/core/topic/tiinex.topic.v1.validate.js +11 -0
- package/src/schemas/creation.capability.js +289 -0
- package/src/schemas/creation.contracts.js +334 -0
- package/src/schemas/creation.executionSnapshot.js +79 -0
- package/src/schemas/creation.factoryQualification.js +73 -0
- package/src/schemas/creation.renderer.js +244 -0
- package/src/schemas/creation.representation.js +279 -0
- package/src/schemas/creation.rootMetadata.js +6 -0
- package/src/schemas/creation.schemaReferences.js +65 -0
- package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.js +14 -0
- package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.json +23 -0
- package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.runtime.json +1873 -0
- package/src/schemas/discovery/finding/tiinex.discovery.finding.v1.schema.source.js +9 -0
- package/src/schemas/discovery/tiinex.discovery.v1.schema.js +14 -0
- package/src/schemas/discovery/tiinex.discovery.v1.schema.json +23 -0
- package/src/schemas/discovery/tiinex.discovery.v1.schema.runtime.json +1839 -0
- package/src/schemas/discovery/tiinex.discovery.v1.schema.source.js +9 -0
- package/src/schemas/generic.artifact.module.js +25 -0
- package/src/schemas/party/organization/tiinex.party.organization.v1.schema.js +26 -0
- package/src/schemas/party/organization/tiinex.party.organization.v1.schema.json +23 -0
- package/src/schemas/party/organization/tiinex.party.organization.v1.schema.runtime.json +2249 -0
- package/src/schemas/party/organization/tiinex.party.organization.v1.schema.source.js +9 -0
- package/src/schemas/party/role/tiinex.party.role.v1.schema.js +26 -0
- package/src/schemas/party/role/tiinex.party.role.v1.schema.json +24 -0
- package/src/schemas/party/role/tiinex.party.role.v1.schema.runtime.json +2091 -0
- package/src/schemas/party/role/tiinex.party.role.v1.schema.source.js +9 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.capabilities.js +14 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.en.i18n.json +4 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.findings.js +1 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.presenter.js +1 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.js +29 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.json +21 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.runtime.json +2180 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.schema.source.js +9 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.sv.i18n.json +4 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.transitions.js +1 -0
- package/src/schemas/presentation/surface/tiinex.presentation.surface.v1.validate.js +1 -0
- package/src/schemas/reduction/tiinex.reduction.v1.schema.js +26 -0
- package/src/schemas/reduction/tiinex.reduction.v1.schema.json +23 -0
- package/src/schemas/reduction/tiinex.reduction.v1.schema.runtime.json +1733 -0
- package/src/schemas/reduction/tiinex.reduction.v1.schema.source.js +9 -0
- package/src/schemas/reference.shapes.js +33 -0
- package/src/schemas/registry.js +36 -0
- package/src/schemas/resolver.js +13 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.capabilities.js +14 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.en.i18n.json +4 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.findings.js +1 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.presenter.js +1 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.schema.js +29 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.schema.json +21 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.schema.runtime.json +2093 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.schema.source.js +9 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.sv.i18n.json +4 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.transitions.js +1 -0
- package/src/schemas/schema/module/tiinex.schema.module.v1.validate.js +1 -0
- package/src/schemas/schema.factory.descriptor.js +104 -0
- package/src/schemas/schema.githubSourceTarget.js +131 -0
- package/src/schemas/schema.identity.js +10 -0
- package/src/schemas/schema.reference.js +133 -0
- package/src/schemas/schema.source.js +239 -0
- package/src/schemas/tiinex.root.v1.capabilities.js +14 -0
- package/src/schemas/tiinex.root.v1.classify.js +55 -0
- package/src/schemas/tiinex.root.v1.en.i18n.json +24 -0
- package/src/schemas/tiinex.root.v1.fallback.js +84 -0
- package/src/schemas/tiinex.root.v1.findings.js +19 -0
- package/src/schemas/tiinex.root.v1.presenter.js +5 -0
- package/src/schemas/tiinex.root.v1.schema.js +29 -0
- package/src/schemas/tiinex.root.v1.schema.json +24 -0
- package/src/schemas/tiinex.root.v1.schema.runtime.json +1574 -0
- package/src/schemas/tiinex.root.v1.schema.source.js +9 -0
- package/src/schemas/tiinex.root.v1.sv.i18n.json +24 -0
- package/src/schemas/tiinex.root.v1.transitions.js +1 -0
- package/src/schemas/tiinex.root.v1.validate.js +36 -0
- package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.js +14 -0
- package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.json +23 -0
- package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.runtime.json +2027 -0
- package/src/schemas/validation/finding/tiinex.validation.finding.v1.schema.source.js +9 -0
- package/src/schemas/validation/method/tiinex.validation.method.v1.schema.js +14 -0
- package/src/schemas/validation/method/tiinex.validation.method.v1.schema.json +23 -0
- package/src/schemas/validation/method/tiinex.validation.method.v1.schema.runtime.json +1848 -0
- package/src/schemas/validation/method/tiinex.validation.method.v1.schema.source.js +9 -0
- package/src/schemas/validation/report/tiinex.validation.report.v1.schema.js +14 -0
- package/src/schemas/validation/report/tiinex.validation.report.v1.schema.json +23 -0
- package/src/schemas/validation/report/tiinex.validation.report.v1.schema.runtime.json +2015 -0
- package/src/schemas/validation/report/tiinex.validation.report.v1.schema.source.js +9 -0
- package/src/schemas/workspace/tiinex.workspace.v1.capabilities.js +12 -0
- package/src/schemas/workspace/tiinex.workspace.v1.en.i18n.json +7 -0
- package/src/schemas/workspace/tiinex.workspace.v1.findings.js +5 -0
- package/src/schemas/workspace/tiinex.workspace.v1.presenter.js +27 -0
- package/src/schemas/workspace/tiinex.workspace.v1.schema.js +30 -0
- package/src/schemas/workspace/tiinex.workspace.v1.schema.json +23 -0
- package/src/schemas/workspace/tiinex.workspace.v1.schema.runtime.json +1596 -0
- package/src/schemas/workspace/tiinex.workspace.v1.schema.source.js +9 -0
- package/src/schemas/workspace/tiinex.workspace.v1.sv.i18n.json +7 -0
- package/src/schemas/workspace/tiinex.workspace.v1.transitions.js +10 -0
- package/src/schemas/workspace/tiinex.workspace.v1.validate.js +10 -0
- package/src/sources/github/github.issueTarget.js +127 -0
- package/src/sources/origin.references.js +249 -0
- package/src/sources/source.explicitTargets.js +49 -0
- package/src/sources/transport.levels.js +107 -0
- package/src/tooling/portable/adapters/cli/cli.cold-start-input.js +34 -0
- package/src/tooling/portable/adapters/cli/cli.command-input.js +455 -0
- package/src/tooling/portable/adapters/cli/cli.common-author.js +249 -0
- package/src/tooling/portable/adapters/cli/cli.common-output.js +330 -0
- package/src/tooling/portable/adapters/cli/cli.editor-assistance.js +13 -0
- package/src/tooling/portable/adapters/cli/cli.ground-materialize.js +96 -0
- package/src/tooling/portable/adapters/cli/cli.ground-recovery.js +99 -0
- package/src/tooling/portable/adapters/cli/cli.handoff-manufacture.js +345 -0
- package/src/tooling/portable/adapters/cli/cli.handoff-sibling-allocation.js +31 -0
- package/src/tooling/portable/adapters/cli/cli.help.js +80 -0
- package/src/tooling/portable/adapters/cli/cli.land.js +13 -0
- package/src/tooling/portable/adapters/cli/cli.local-output.js +72 -0
- package/src/tooling/portable/adapters/cli/cli.material-policy.js +6 -0
- package/src/tooling/portable/adapters/cli/cli.operator-bridge.js +18 -0
- package/src/tooling/portable/adapters/cli/cli.reduction-input.js +14 -0
- package/src/tooling/portable/adapters/cli/cli.run.js +434 -0
- package/src/tooling/portable/adapters/llm/llm.entrypoint.js +34 -0
- package/src/tooling/portable/adapters/node/checkpoint.verify.js +267 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.bootstrap.js +109 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.enumeration.js +94 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.js +193 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.multiRoot.js +49 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.packageParent.js +130 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.requirements.js +353 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.scope.js +147 -0
- package/src/tooling/portable/adapters/node/workspaceCarrier.manufacture.js +62 -0
- package/src/tooling/portable/assets/asset.operations.js +170 -0
- package/src/tooling/portable/audit/audit.capability.js +119 -0
- package/src/tooling/portable/bootstrap/artifact.result.selfverify.mjs +109 -0
- package/src/tooling/portable/bootstrap/bootstrap.case.mjs +43 -0
- package/src/tooling/portable/bootstrap/tiinex.llm.bootstrap.md +814 -0
- package/src/tooling/portable/bootstrap/tiinex.llm.bootstrap.pointer.json +25 -0
- package/src/tooling/portable/checkpoint/portable.checkpoint.js +89 -0
- package/src/tooling/portable/conformance/checkpoint.qualification.js +271 -0
- package/src/tooling/portable/draft/draft.create.js +389 -0
- package/src/tooling/portable/draft/draft.crud.js +175 -0
- package/src/tooling/portable/draft/draft.exact.js +173 -0
- package/src/tooling/portable/draft/draft.operations.js +265 -0
- package/src/tooling/portable/draft/draft.qualification.js +45 -0
- package/src/tooling/portable/draft/draft.set.js +193 -0
- package/src/tooling/portable/draft/draft.validation-context.js +7 -0
- package/src/tooling/portable/editor/authoring.parent.js +37 -0
- package/src/tooling/portable/editor/editor.assistance.js +221 -0
- package/src/tooling/portable/editor/staged.validation.js +96 -0
- package/src/tooling/portable/engine.facade.js +468 -0
- package/src/tooling/portable/findings.js +92 -0
- package/src/tooling/portable/grounding/grounding.capsule.js +128 -0
- package/src/tooling/portable/grounding/grounding.continuity.js +283 -0
- package/src/tooling/portable/grounding/grounding.participantAuthority.js +20 -0
- package/src/tooling/portable/grounding/grounding.planningContext.js +34 -0
- package/src/tooling/portable/grounding/grounding.readiness.authority.js +17 -0
- package/src/tooling/portable/grounding/grounding.readiness.js +316 -0
- package/src/tooling/portable/grounding/grounding.readiness.support.js +245 -0
- package/src/tooling/portable/grounding/grounding.sourceEvidence.js +71 -0
- package/src/tooling/portable/grounding/grounding.workContext.js +72 -0
- package/src/tooling/portable/grounding/grounding.workProvenance.js +153 -0
- package/src/tooling/portable/handoff/carrierLineage.js +214 -0
- package/src/tooling/portable/handoff/carrierProfile.js +54 -0
- package/src/tooling/portable/handoff/carrierProjection.js +193 -0
- package/src/tooling/portable/handoff/carrierProjection.routeQualification.js +228 -0
- package/src/tooling/portable/handoff/carrierProjection.shared.js +7 -0
- package/src/tooling/portable/handoff/carrierProjection.workspaces.js +54 -0
- package/src/tooling/portable/handoff/coldConsumerEntrypoint.js +185 -0
- package/src/tooling/portable/handoff/coldStartQualification.contract.js +184 -0
- package/src/tooling/portable/handoff/coldStartQualification.grounding.js +392 -0
- package/src/tooling/portable/handoff/coldStartQualification.js +22 -0
- package/src/tooling/portable/handoff/coldStartQualification.materials.js +364 -0
- package/src/tooling/portable/handoff/coldStartQualification.observation.js +220 -0
- package/src/tooling/portable/handoff/coldStartQualification.run.js +81 -0
- package/src/tooling/portable/handoff/coldStartQualification.shared.js +57 -0
- package/src/tooling/portable/handoff/coldStartRolePointers.js +39 -0
- package/src/tooling/portable/handoff/contextAudit.js +247 -0
- package/src/tooling/portable/handoff/contracts/tiinex.handoff.package.v1.schema.md +409 -0
- package/src/tooling/portable/handoff/handoffAuthoringPlan.js +35 -0
- package/src/tooling/portable/handoff/handoffEndpointProjection.js +61 -0
- package/src/tooling/portable/handoff/handoffLeafProjection.js +91 -0
- package/src/tooling/portable/handoff/humanOutputPresentation.js +21 -0
- package/src/tooling/portable/handoff/manufacture.js +84 -0
- package/src/tooling/portable/handoff/materialClosure.archiveV2.binding.js +72 -0
- package/src/tooling/portable/handoff/materialClosure.archiveV2.direct.js +160 -0
- package/src/tooling/portable/handoff/materialClosure.archiveV2.indexes.js +36 -0
- package/src/tooling/portable/handoff/materialClosure.archiveV2.js +247 -0
- package/src/tooling/portable/handoff/materialClosure.archiveV2.projectionProvider.js +44 -0
- package/src/tooling/portable/handoff/materialClosure.archiveV2.workspace.js +226 -0
- package/src/tooling/portable/handoff/materialClosure.descriptor.js +169 -0
- package/src/tooling/portable/handoff/materialClosure.inputBinding.js +372 -0
- package/src/tooling/portable/handoff/materialClosure.inputBinding.support.js +62 -0
- package/src/tooling/portable/handoff/materialClosure.materialized.js +143 -0
- package/src/tooling/portable/handoff/materialClosure.materials.js +116 -0
- package/src/tooling/portable/handoff/materialClosure.package.js +181 -0
- package/src/tooling/portable/handoff/materialClosure.plan.js +204 -0
- package/src/tooling/portable/handoff/materialClosure.readiness.js +36 -0
- package/src/tooling/portable/handoff/materialClosure.requirements.js +137 -0
- package/src/tooling/portable/handoff/operatorContextProjection.js +105 -0
- package/src/tooling/portable/handoff/pointerEntrypoint.js +138 -0
- package/src/tooling/portable/handoff/qualifiedHandoffFixture.js +34 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.build.js +321 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.closure.js +126 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.inspect.js +194 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.materials.js +207 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.projection.js +69 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.roles.js +166 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.routes.js +113 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.shared.js +87 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirst.workspaces.js +160 -0
- package/src/tooling/portable/handoff/recipientV2.artifactFirstPhase1.js +44 -0
- package/src/tooling/portable/handoff/recipientV2.artifactInspection.js +55 -0
- package/src/tooling/portable/handoff/recipientV2.artifacts.js +174 -0
- package/src/tooling/portable/handoff/recipientV2.coldProjection.js +24 -0
- package/src/tooling/portable/handoff/recipientV2.delivery.js +48 -0
- package/src/tooling/portable/handoff/recipientV2.endpointRolePointers.js +179 -0
- package/src/tooling/portable/handoff/recipientV2.entryContract.js +28 -0
- package/src/tooling/portable/handoff/recipientV2.humanOutput.js +78 -0
- package/src/tooling/portable/handoff/recipientV2.inspect.helpers.js +218 -0
- package/src/tooling/portable/handoff/recipientV2.inspect.js +194 -0
- package/src/tooling/portable/handoff/recipientV2.inspect.pathToken.js +9 -0
- package/src/tooling/portable/handoff/recipientV2.inspect.projection.js +58 -0
- package/src/tooling/portable/handoff/recipientV2.inspect.workspaces.js +177 -0
- package/src/tooling/portable/handoff/recipientV2.lineage.js +142 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.build.js +147 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.constants.js +4 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.contract.js +101 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.inspect.helpers.js +126 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.inspect.js +185 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.js +12 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.shared.js +24 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.workspaceProjection.js +22 -0
- package/src/tooling/portable/handoff/recipientV2.pointer.js +40 -0
- package/src/tooling/portable/handoff/recipientV2.routeSelection.js +16 -0
- package/src/tooling/portable/handoff/recipientV2.topology.helpers.js +20 -0
- package/src/tooling/portable/handoff/recipientV2.topology.js +320 -0
- package/src/tooling/portable/handoff/recipientV2.topology.materials.js +70 -0
- package/src/tooling/portable/handoff/recipientV2.topology.workspaces.js +193 -0
- package/src/tooling/portable/handoff/recipientV2.transportManifest.js +123 -0
- package/src/tooling/portable/handoff/recipientV2.workspaceRepresentation.js +163 -0
- package/src/tooling/portable/handoff/routeArtifactConformance.js +130 -0
- package/src/tooling/portable/handoff/toolingBootstrap.js +67 -0
- package/src/tooling/portable/handoff/transportCompanion.js +175 -0
- package/src/tooling/portable/handoff/workspaceByteProvider.archive.js +95 -0
- package/src/tooling/portable/handoff/workspaceByteProvider.js +271 -0
- package/src/tooling/portable/handoff/workspaceCarrier.manufacture.js +93 -0
- package/src/tooling/portable/handoff/workspaceLandingPlan.js +142 -0
- package/src/tooling/portable/handoff/workspacePackageSources.js +105 -0
- package/src/tooling/portable/handoff/workspaceQualifiedReference.js +10 -0
- package/src/tooling/portable/handoff/workspaceSourceIdentity.js +52 -0
- package/src/tooling/portable/handoff/workspaceTargetConformance.js +134 -0
- package/src/tooling/portable/host/host.capabilities.js +181 -0
- package/src/tooling/portable/host/tool.bindings.js +357 -0
- package/src/tooling/portable/host/tool.receiptNormalization.js +141 -0
- package/src/tooling/portable/index.js +52 -0
- package/src/tooling/portable/input/node.input.js +184 -0
- package/src/tooling/portable/input/portable.input.js +249 -0
- package/src/tooling/portable/lifecycle/lifecycle.action.js +11 -0
- package/src/tooling/portable/lifecycle/lifecycle.material.js +173 -0
- package/src/tooling/portable/lifecycle/lifecycle.operations.js +34 -0
- package/src/tooling/portable/lifecycle/lifecycle.readiness.js +247 -0
- package/src/tooling/portable/lineage/lineage.integrity.apply.audit.js +22 -0
- package/src/tooling/portable/lineage/lineage.integrity.apply.evidence.js +36 -0
- package/src/tooling/portable/lineage/lineage.integrity.apply.js +306 -0
- package/src/tooling/portable/lineage/lineage.integrity.apply.structure.js +178 -0
- package/src/tooling/portable/lineage/lineage.integrity.plan.js +377 -0
- package/src/tooling/portable/lineage/lineage.integrity.projection.human.js +82 -0
- package/src/tooling/portable/lineage/lineage.integrity.projection.js +349 -0
- package/src/tooling/portable/lineage/lineage.operations.js +32 -0
- package/src/tooling/portable/lineage/lineage.print.js +398 -0
- package/src/tooling/portable/lineage/lineage.print.render.js +88 -0
- package/src/tooling/portable/lineage/lineage.print.utils.js +58 -0
- package/src/tooling/portable/lineage/lineage.publicationProviderReceipts.js +141 -0
- package/src/tooling/portable/lineage/lineage.publicationQualification.js +183 -0
- package/src/tooling/portable/lineage/lineage.search.js +301 -0
- package/src/tooling/portable/live/live.artifact.js +192 -0
- package/src/tooling/portable/live/live.export.js +107 -0
- package/src/tooling/portable/live/live.lineage.closure.js +71 -0
- package/src/tooling/portable/live/live.lineage.js +338 -0
- package/src/tooling/portable/live/live.protocol.js +181 -0
- package/src/tooling/portable/materialization/durable.materialize.js +162 -0
- package/src/tooling/portable/materialization/epistemic.plan.js +239 -0
- package/src/tooling/portable/materialization/loaded.parent.js +54 -0
- package/src/tooling/portable/materialization/materialization.facade.js +30 -0
- package/src/tooling/portable/operation.catalog.js +393 -0
- package/src/tooling/portable/operation.catalog.package.js +183 -0
- package/src/tooling/portable/operation.result.js +25 -0
- package/src/tooling/portable/orchestration/task.prepare.js +191 -0
- package/src/tooling/portable/output/artifact.result.package.js +308 -0
- package/src/tooling/portable/output/deterministic.zip.js +88 -0
- package/src/tooling/portable/output/node.artifact-set.js +223 -0
- package/src/tooling/portable/output/node.draft.js +41 -0
- package/src/tooling/portable/output/node.zip.js +39 -0
- package/src/tooling/portable/output/recipientV2.zip.js +59 -0
- package/src/tooling/portable/overview/blockingCue.js +16 -0
- package/src/tooling/portable/overview/operatingOverview.js +413 -0
- package/src/tooling/portable/package/generation.binding.js +314 -0
- package/src/tooling/portable/package/generation.binding.projection.js +128 -0
- package/src/tooling/portable/package/material.graph.js +236 -0
- package/src/tooling/portable/package/runtime.package.js +321 -0
- package/src/tooling/portable/package/schema.transition.companion.js +196 -0
- package/src/tooling/portable/package/semantic.package.graph.js +272 -0
- package/src/tooling/portable/package/semantic.package.js +203 -0
- package/src/tooling/portable/package/semantic.package.schema-resolution.js +158 -0
- package/src/tooling/portable/package/semantic.package.transition-registry.js +189 -0
- package/src/tooling/portable/package/semantic.package.types.js +18 -0
- package/src/tooling/portable/providers/schema.bootstrap.provenance.js +10 -0
- package/src/tooling/portable/providers/schema.provider.qualification.js +52 -0
- package/src/tooling/portable/providers/schema.providers.js +458 -0
- package/src/tooling/portable/publication/runtime.publication.js +53 -0
- package/src/tooling/portable/qualification.js +150 -0
- package/src/tooling/portable/reduction/reduction.composition.js +229 -0
- package/src/tooling/portable/reduction/reduction.eligibility.helpers.js +258 -0
- package/src/tooling/portable/reduction/reduction.eligibility.js +191 -0
- package/src/tooling/portable/reduction/reduction.operations.js +30 -0
- package/src/tooling/portable/reduction/reduction.preflight.js +85 -0
- package/src/tooling/portable/reduction/reduction.shared.js +173 -0
- package/src/tooling/portable/schema/bootstrap/canonical.pack.js +24 -0
- package/src/tooling/portable/schema/bootstrap/docs-3988951208eb9a8926e84ab42625d4b42fa00c2d/party/role/tiinex.party.role.v1.schema.md +289 -0
- package/src/tooling/portable/schema/bootstrap/docs-3988951208eb9a8926e84ab42625d4b42fa00c2d/validation/report/tiinex.validation.report.v1.schema.md +300 -0
- package/src/tooling/portable/schema/bootstrap/qualified-local-root/tiinex.root.v1.runtime-projection.json +48 -0
- package/src/tooling/portable/schema/bootstrap/qualified-local-root/tiinex.root.v1.schema.md +865 -0
- package/src/tooling/portable/schema/contract.compile.js +406 -0
- package/src/tooling/portable/schema/contract.compile.utils.js +9 -0
- package/src/tooling/portable/schema/contract.constraints.js +117 -0
- package/src/tooling/portable/schema/contract.envelope.validate.js +177 -0
- package/src/tooling/portable/schema/contract.field-domain.compile.js +399 -0
- package/src/tooling/portable/schema/contract.field-domain.js +247 -0
- package/src/tooling/portable/schema/contract.field-shape.compile.js +34 -0
- package/src/tooling/portable/schema/contract.inheritance.inline.js +103 -0
- package/src/tooling/portable/schema/contract.inheritance.js +210 -0
- package/src/tooling/portable/schema/contract.inheritance.record.js +76 -0
- package/src/tooling/portable/schema/contract.machine-shape.js +309 -0
- package/src/tooling/portable/schema/contract.project.js +81 -0
- package/src/tooling/portable/schema/contract.semantic-resolution.js +82 -0
- package/src/tooling/portable/schema/contract.validate.js +0 -0
- package/src/tooling/portable/schema/lexical.shape.v1.js +338 -0
- package/src/tooling/portable/schema/llm.companion.js +108 -0
- package/src/tooling/portable/schema/named.declarations.js +162 -0
- package/src/tooling/portable/schema/ordinary.contract.js +193 -0
- package/src/tooling/portable/schema/ordinary.fields.js +205 -0
- package/src/tooling/portable/schema/qualifiedLocalRoot.projection.js +70 -0
- package/src/tooling/portable/schema/qualifiedLocalRoot.runtime.js +170 -0
- package/src/tooling/portable/schema/schema.contract.js +465 -0
- package/src/tooling/portable/schema/schema.guide.js +326 -0
- package/src/tooling/portable/schema/schema.snapshot.js +119 -0
- package/src/tooling/portable/session/portable.session.js +145 -0
- package/src/tooling/portable/transfer/transfer.plan.js +102 -0
- package/src/transitions/record.transitions.js +484 -0
- package/src/transitions/transition.validate.js +129 -0
- package/src/validation/findings.js +76 -0
- package/src/validation/validateArtifact.js +216 -0
- package/src/workspaces/workspace.entrypointCapability.js +44 -0
- package/src/workspaces/workspace.materialRole.js +242 -0
- package/src/workspaces/workspace.recordPaths.js +426 -0
- package/tools/tiinex-portable.mjs +6 -0
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
import { resolveLineage } from '../../../lineage/lineage.resolve.js';
|
|
2
|
+
import { normalizePortableInput } from '../input/portable.input.js';
|
|
3
|
+
import { portableFinding, summarizePortableFindings } from '../findings.js';
|
|
4
|
+
import { renderDot, renderMermaid, renderTextMap } from './lineage.print.render.js';
|
|
5
|
+
import { compactNode, compareEdges, compareIds, compareLatest, compareNodeOrder, hasExplicitMetadata, normalizeList, positiveInteger, slugFromPath, truncate } from './lineage.print.utils.js';
|
|
6
|
+
|
|
7
|
+
export const PORTABLE_LINEAGE_PRINT_SCHEMA_ID = 'tiinex.portable.lineage-print.v1';
|
|
8
|
+
export const PORTABLE_LINEAGE_PRINT_REQUEST_SCHEMA_ID = 'tiinex.portable.lineage-print.request.v1';
|
|
9
|
+
|
|
10
|
+
const SUPPORTED_SCOPES = Object.freeze(['all', 'leaves', 'latest-leaves', 'node-ancestors', 'node-neighborhood', 'segment', 'export-scope']);
|
|
11
|
+
const BOUNDARY = Object.freeze({
|
|
12
|
+
projectionOnly: true,
|
|
13
|
+
sourceMutation: false,
|
|
14
|
+
stateMutation: false,
|
|
15
|
+
remoteFetch: false,
|
|
16
|
+
packageMutation: false,
|
|
17
|
+
loadedOnly: true,
|
|
18
|
+
rawMarkdownIncluded: false,
|
|
19
|
+
notSourceTruth: true
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export function printPortableLineage(input = {}, options = {}) {
|
|
23
|
+
const scope = normalizeScope(input.scope || options.scope || 'all');
|
|
24
|
+
if (!SUPPORTED_SCOPES.includes(scope)) {
|
|
25
|
+
const findings = [portableFinding('error', 'lineage-print.scope.unsupported', 'Lineage print scope is not supported.', { scope, supportedScopes: SUPPORTED_SCOPES })];
|
|
26
|
+
return projectionResult({ scope, findings, status: 'blocked' });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const material = normalizePortableInput(input.materials || input);
|
|
30
|
+
const manifest = parseManifest(input);
|
|
31
|
+
const resolved = resolveLineage(material.records || [], { depth: 'portable-lineage-print' });
|
|
32
|
+
const model = buildProjectionModel(material.records || [], resolved, manifest);
|
|
33
|
+
const selection = selectScope(model, {
|
|
34
|
+
scope,
|
|
35
|
+
focusId: input.focusArtifactId || input.focusId || input.focus || options.focusId || options.startId || '',
|
|
36
|
+
fromId: input.fromArtifactId || input.fromId || input.from || '',
|
|
37
|
+
toId: input.toArtifactId || input.toId || input.to || '',
|
|
38
|
+
artifactIds: normalizeList(input.artifactIds || input.artifacts || options.artifactIds),
|
|
39
|
+
latestLimit: positiveInteger(input.latestLimit || input.limit || options.latestLimit, 5)
|
|
40
|
+
});
|
|
41
|
+
const graph = buildScopedGraph(model, selection, scope);
|
|
42
|
+
const findings = [
|
|
43
|
+
...(material.findings || []),
|
|
44
|
+
...normalizeLineageFindings(resolved.findings || []),
|
|
45
|
+
...(selection.findings || []),
|
|
46
|
+
...graph.findings,
|
|
47
|
+
...diagnosticFindings(model, graph, manifest)
|
|
48
|
+
];
|
|
49
|
+
const allFindings = dedupeByCodeRef(findings);
|
|
50
|
+
const outputFormats = new Set(normalizeList(input.outputFormats || input.formats || options.outputFormats));
|
|
51
|
+
const includeMermaid = outputFormats.has('mermaid') || outputFormats.has('mmd');
|
|
52
|
+
const includeDot = outputFormats.has('dot');
|
|
53
|
+
const textMap = renderTextMap(model, graph, scope, allFindings, manifest);
|
|
54
|
+
return projectionResult({
|
|
55
|
+
scope,
|
|
56
|
+
status: allFindings.some((finding) => finding.severity === 'error') ? 'partial' : 'ready',
|
|
57
|
+
material,
|
|
58
|
+
model,
|
|
59
|
+
graph,
|
|
60
|
+
textMap,
|
|
61
|
+
findings: allFindings,
|
|
62
|
+
exportPreview: buildExportPreview(model, graph, scope, normalizeList(input.artifactIds || input.artifacts || options.artifactIds)),
|
|
63
|
+
manifestSummary: manifestSummary(manifest),
|
|
64
|
+
mermaid: includeMermaid ? renderMermaid(graph) : undefined,
|
|
65
|
+
dot: includeDot ? renderDot(graph) : undefined
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function projectionResult({ scope = 'all', status = 'ready', material = {}, model = emptyModel(), graph = emptyGraph(), textMap = '', findings = [], exportPreview = null, manifestSummary: manifest = null, mermaid, dot }) {
|
|
70
|
+
const findingSummary = summarizePortableFindings(findings);
|
|
71
|
+
return Object.freeze({
|
|
72
|
+
schema: PORTABLE_LINEAGE_PRINT_SCHEMA_ID,
|
|
73
|
+
status,
|
|
74
|
+
scope,
|
|
75
|
+
stats: Object.freeze({
|
|
76
|
+
artifacts: model.records.length,
|
|
77
|
+
selectedArtifacts: graph.nodes.filter((node) => node.kind === 'artifact' && node.status === 'included').length,
|
|
78
|
+
roots: model.roots.length,
|
|
79
|
+
leaves: model.leaves.length,
|
|
80
|
+
parentEdges: model.parentEdges.length,
|
|
81
|
+
missingParentEdges: model.missingParentEdges.length,
|
|
82
|
+
hiddenEdges: graph.edges.filter((edge) => edge.status === 'hidden-intermediate' || edge.status === 'known-but-excluded').length,
|
|
83
|
+
liveProcessedTurns: model.live.processedTurnCount,
|
|
84
|
+
liveArtifactChangeTurns: model.live.artifactChangeTurnCount
|
|
85
|
+
}),
|
|
86
|
+
graph: Object.freeze({ nodes: Object.freeze(graph.nodes), edges: Object.freeze(graph.edges) }),
|
|
87
|
+
textMap,
|
|
88
|
+
latestLeaves: Object.freeze(model.latestLeaves.map((id) => compactNode(model.nodeById.get(id))).filter(Boolean)),
|
|
89
|
+
roots: Object.freeze(model.roots.map((id) => compactNode(model.nodeById.get(id))).filter(Boolean)),
|
|
90
|
+
leaves: Object.freeze(model.leaves.map((id) => compactNode(model.nodeById.get(id))).filter(Boolean)),
|
|
91
|
+
exportPreview: exportPreview ? Object.freeze(exportPreview) : undefined,
|
|
92
|
+
manifestSummary: manifest ? Object.freeze(manifest) : undefined,
|
|
93
|
+
...(mermaid ? { mermaid } : {}),
|
|
94
|
+
...(dot ? { dot } : {}),
|
|
95
|
+
findings: Object.freeze(findings),
|
|
96
|
+
findingSummary,
|
|
97
|
+
boundary: BOUNDARY
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function buildProjectionModel(records = [], resolved = {}, manifest = {}) {
|
|
102
|
+
const nodes = (resolved.nodes || []).map((node, index) => normalizeNode(node, records[index] || node.record || {}, index));
|
|
103
|
+
const nodeById = new Map(nodes.map((node) => [node.id, node]));
|
|
104
|
+
const edges = (resolved.edges || []).map(normalizeEdge).sort(compareEdges);
|
|
105
|
+
const parentEdges = edges.filter((edge) => edge.relation === 'parent' && edge.from && edge.to && edge.status !== 'missing');
|
|
106
|
+
const missingParentEdges = edges.filter((edge) => edge.relation === 'parent' && (!edge.from || edge.status === 'missing'));
|
|
107
|
+
const parentByChild = new Map();
|
|
108
|
+
const childrenByParent = new Map();
|
|
109
|
+
for (const edge of parentEdges) {
|
|
110
|
+
parentByChild.set(edge.to, edge.from);
|
|
111
|
+
if (!childrenByParent.has(edge.from)) childrenByParent.set(edge.from, []);
|
|
112
|
+
childrenByParent.get(edge.from).push(edge.to);
|
|
113
|
+
}
|
|
114
|
+
for (const children of childrenByParent.values()) children.sort(compareIds);
|
|
115
|
+
const roots = nodes.filter((node) => !parentByChild.has(node.id)).map((node) => node.id).sort(compareNodeOrder(nodeById));
|
|
116
|
+
const leaves = nodes.filter((node) => !(childrenByParent.get(node.id) || []).length).map((node) => node.id).sort(compareNodeOrder(nodeById));
|
|
117
|
+
const live = liveStats(manifest, nodes);
|
|
118
|
+
const latestLeaves = [...leaves].sort(compareLatest(nodeById, live));
|
|
119
|
+
return Object.freeze({ records, nodes, nodeById, edges, parentEdges, missingParentEdges, parentByChild, childrenByParent, roots, leaves, latestLeaves, live });
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function normalizeNode(node = {}, record = {}, index = 0) {
|
|
123
|
+
const id = String(node.id || record.id || record.path || `lineage-node-${index + 1}`);
|
|
124
|
+
const slug = slugFromPath(record.path || node.path || id);
|
|
125
|
+
const liveTouch = { latestTurnSequence: 0, latestObservedAt: '' };
|
|
126
|
+
return {
|
|
127
|
+
id,
|
|
128
|
+
slug,
|
|
129
|
+
kind: 'artifact',
|
|
130
|
+
status: 'included',
|
|
131
|
+
title: String(node.title || record.title || record.path || id),
|
|
132
|
+
path: String(node.path || record.path || ''),
|
|
133
|
+
schemaId: String(node.schemaId || record.schemaId || record.kind || ''),
|
|
134
|
+
sourceMode: String(node.sourceMode || record.sourceMode || ''),
|
|
135
|
+
boundary: String(node.boundary || record.boundary || record.source?.boundary || 'Portable local material; no GitHub provenance inferred.'),
|
|
136
|
+
summary: truncate(String(record.summary || node.record?.summary || ''), 220),
|
|
137
|
+
currentCreatedAt: String(record.currentCreatedAt || ''),
|
|
138
|
+
lifecycleStatus: String(record.lifecycleStatus || ''),
|
|
139
|
+
hasContinuityContext: Boolean(record.hasContinuityContext || node.hasContinuityContext),
|
|
140
|
+
hasIntegrity: Boolean(record.hasIntegrity || node.hasIntegrity),
|
|
141
|
+
hasAuthorshipMetadata: hasExplicitMetadata(record.markdown, ['author', 'authors', 'contributor', 'contributors', 'authorship']),
|
|
142
|
+
hasReductionMetadata: hasExplicitMetadata(record.markdown, ['reduction', 'reducer', 'reduced from', 'selection rule', 'known losses']),
|
|
143
|
+
hasSourceSpanMetadata: hasExplicitMetadata(record.markdown, ['source span', 'source-span', 'source range', 'covers turns', 'source turns']),
|
|
144
|
+
liveTouch
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function normalizeEdge(edge = {}) {
|
|
149
|
+
return Object.freeze({
|
|
150
|
+
id: String(edge.id || `${edge.kind || 'edge'}:${edge.from || 'missing'}->${edge.to || 'missing'}`),
|
|
151
|
+
from: String(edge.from || ''),
|
|
152
|
+
to: String(edge.to || ''),
|
|
153
|
+
relation: String(edge.kind || edge.relation || 'parent'),
|
|
154
|
+
status: edge.status === 'missing' ? 'missing' : String(edge.status || 'included'),
|
|
155
|
+
target: String(edge.target || ''),
|
|
156
|
+
source: 'declared-lineage',
|
|
157
|
+
label: String(edge.label || edge.kind || 'edge')
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function selectScope(model, request = {}) {
|
|
162
|
+
const findings = [];
|
|
163
|
+
let selected = new Set();
|
|
164
|
+
const artifactIds = resolveArtifactIds(model, request.artifactIds || []);
|
|
165
|
+
if (request.scope === 'all') selected = new Set(model.nodes.map((node) => node.id));
|
|
166
|
+
else if (request.scope === 'export-scope') selected = new Set(artifactIds.length ? artifactIds : model.nodes.map((node) => node.id));
|
|
167
|
+
else if (request.scope === 'leaves') selected = idsWithAncestors(model, model.leaves);
|
|
168
|
+
else if (request.scope === 'latest-leaves') selected = idsWithAncestors(model, model.latestLeaves.slice(0, request.latestLimit || 5));
|
|
169
|
+
else if (request.scope === 'node-ancestors') {
|
|
170
|
+
const focus = resolveArtifactId(model, request.focusId);
|
|
171
|
+
if (!focus) findings.push(portableFinding('error', 'lineage-print.focus-missing', 'node-ancestors scope requires a loaded focus artifact id/path/slug.', { ref: request.focusId || '' }));
|
|
172
|
+
selected = focus ? idsWithAncestors(model, [focus]) : new Set();
|
|
173
|
+
} else if (request.scope === 'node-neighborhood') {
|
|
174
|
+
const focus = resolveArtifactId(model, request.focusId);
|
|
175
|
+
if (!focus) findings.push(portableFinding('error', 'lineage-print.focus-missing', 'node-neighborhood scope requires a loaded focus artifact id/path/slug.', { ref: request.focusId || '' }));
|
|
176
|
+
selected = focus ? neighborhoodIds(model, focus) : new Set();
|
|
177
|
+
} else if (request.scope === 'segment') {
|
|
178
|
+
const from = resolveArtifactId(model, request.fromId);
|
|
179
|
+
const to = resolveArtifactId(model, request.toId);
|
|
180
|
+
if (!from || !to) findings.push(portableFinding('error', 'lineage-print.segment-endpoint-missing', 'segment scope requires loaded from/to artifact ids, paths, or slugs.', { from: request.fromId || '', to: request.toId || '' }));
|
|
181
|
+
selected = from && to ? segmentIds(model, from, to, findings) : new Set();
|
|
182
|
+
}
|
|
183
|
+
return Object.freeze({ ids: selected, findings });
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function buildScopedGraph(model, selection, scope = 'all') {
|
|
187
|
+
const selected = selection.ids || new Set();
|
|
188
|
+
const findings = [];
|
|
189
|
+
const nodes = [...selected].map((id) => model.nodeById.get(id)).filter(Boolean).sort(compareNodeOrder(model.nodeById)).map(compactNode);
|
|
190
|
+
const edgeKeys = new Set();
|
|
191
|
+
const edges = [];
|
|
192
|
+
function addEdge(edge) {
|
|
193
|
+
const key = [edge.relation, edge.from || '', edge.to || '', edge.status || '', edge.hiddenCount || 0].join(':');
|
|
194
|
+
if (edgeKeys.has(key)) return;
|
|
195
|
+
edgeKeys.add(key);
|
|
196
|
+
edges.push(Object.freeze(edge));
|
|
197
|
+
}
|
|
198
|
+
for (const edge of model.parentEdges) {
|
|
199
|
+
if (selected.has(edge.from) && selected.has(edge.to)) addEdge({ ...edge, status: 'included' });
|
|
200
|
+
}
|
|
201
|
+
for (const id of selected) {
|
|
202
|
+
const hidden = hiddenParentPathToSelectedAncestor(model, id, selected);
|
|
203
|
+
if (hidden.hiddenCount > 0 && hidden.ancestorId) {
|
|
204
|
+
addEdge({
|
|
205
|
+
id: `parent-path:${hidden.ancestorId}->${id}`,
|
|
206
|
+
from: hidden.ancestorId,
|
|
207
|
+
to: id,
|
|
208
|
+
relation: 'parent-path',
|
|
209
|
+
status: 'hidden-intermediate',
|
|
210
|
+
hiddenCount: hidden.hiddenCount,
|
|
211
|
+
hiddenIds: Object.freeze(hidden.hiddenIds),
|
|
212
|
+
reason: 'selection-scope',
|
|
213
|
+
source: 'declared-lineage-selection'
|
|
214
|
+
});
|
|
215
|
+
findings.push(portableFinding('info', 'lineage-print.hidden-intermediate', 'Projection hides one or more loaded intermediate lineage nodes; no direct parent edge is implied.', { nodeId: id, ancestorId: hidden.ancestorId, hiddenCount: hidden.hiddenCount, scope }));
|
|
216
|
+
} else if (hidden.hiddenCount > 0) {
|
|
217
|
+
findings.push(portableFinding('info', 'lineage-print.hidden-by-scope', 'Projection omits a loaded parent because it is outside the selected scope.', { nodeId: id, hiddenCount: hidden.hiddenCount, scope }));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
for (const edge of model.missingParentEdges) {
|
|
221
|
+
if (!selected.has(edge.to)) continue;
|
|
222
|
+
addEdge({ ...edge, from: null, status: 'missing-parent', reason: 'declared-parent-not-loaded' });
|
|
223
|
+
findings.push(portableFinding('warning', 'lineage-print.parent.missing', 'A selected artifact declares a parent that is not loaded.', { nodeId: edge.to, target: edge.target }));
|
|
224
|
+
}
|
|
225
|
+
return Object.freeze({ nodes: Object.freeze(nodes), edges: Object.freeze(edges.sort(compareEdges)), findings: Object.freeze(findings) });
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function diagnosticFindings(model, graph, manifest = {}) {
|
|
229
|
+
const findings = [];
|
|
230
|
+
const live = model.live;
|
|
231
|
+
if (live.processedTurnCount >= 3 && live.artifactChangeTurnCount >= 2 && model.nodes.length <= 1 && model.parentEdges.length === 0) {
|
|
232
|
+
findings.push(portableFinding('warning', 'lineage-print.overcompression.possible', 'Many live turns changed artifacts, but the loaded export contains one or fewer artifacts and no child lineage.', {
|
|
233
|
+
processedTurnCount: live.processedTurnCount,
|
|
234
|
+
artifactChangeTurnCount: live.artifactChangeTurnCount,
|
|
235
|
+
artifactCount: model.nodes.length,
|
|
236
|
+
parentEdges: model.parentEdges.length
|
|
237
|
+
}));
|
|
238
|
+
if (!model.nodes.some((node) => node.hasReductionMetadata)) findings.push(portableFinding('info', 'lineage-print.reduction.capability-missing', 'Compression risk is present, but no explicit reduction metadata/capability is visible in the loaded artifacts.'));
|
|
239
|
+
if (!model.nodes.some((node) => node.hasSourceSpanMetadata)) findings.push(portableFinding('warning', 'lineage-print.source-span.metadata-missing', 'Compression risk is present, but no explicit source-span metadata is visible in the loaded artifacts.'));
|
|
240
|
+
}
|
|
241
|
+
if (model.nodes.length && !model.nodes.some((node) => node.hasAuthorshipMetadata)) findings.push(portableFinding('info', 'lineage-print.authorship.metadata-missing', 'No explicit authorship/contributor metadata was found in loaded artifact envelopes or body fields.'));
|
|
242
|
+
if (manifest?.liveOperations?.boundary?.rawMarkdownIncluded === true) findings.push(portableFinding('warning', 'lineage-print.boundary.raw-markdown-reported', 'Manifest reports raw Markdown was included in live-operation boundary; projection output still omits raw Markdown.'));
|
|
243
|
+
return findings;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function buildExportPreview(model, graph, scope, requestedIds = []) {
|
|
247
|
+
const selected = graph.nodes.filter((node) => node.kind === 'artifact' && node.status === 'included');
|
|
248
|
+
const requested = resolveArtifactIds(model, requestedIds);
|
|
249
|
+
return Object.freeze({
|
|
250
|
+
schema: 'tiinex.portable.lineage-print.export-preview.v1',
|
|
251
|
+
mode: scope === 'export-scope' ? 'selected-export-scope' : 'loaded-material-summary',
|
|
252
|
+
requestedArtifactIds: Object.freeze(requested),
|
|
253
|
+
selectedArtifactIds: Object.freeze(selected.map((node) => node.id)),
|
|
254
|
+
selectedArtifactCount: selected.length,
|
|
255
|
+
loadedArtifactCount: model.nodes.length,
|
|
256
|
+
packageMutation: false,
|
|
257
|
+
exportReceiptCreated: false,
|
|
258
|
+
rawMarkdownIncluded: false,
|
|
259
|
+
obviousBlockers: Object.freeze(selected.length ? [] : ['no-selected-artifacts'])
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function manifestSummary(manifest = {}) {
|
|
264
|
+
if (!manifest || !Object.keys(manifest).length) return null;
|
|
265
|
+
const live = liveStats(manifest, []);
|
|
266
|
+
return Object.freeze({
|
|
267
|
+
schema: 'tiinex.portable.lineage-print.manifest-summary.v1',
|
|
268
|
+
hasManifest: true,
|
|
269
|
+
liveOperations: Object.freeze({
|
|
270
|
+
processedTurnCount: live.processedTurnCount,
|
|
271
|
+
preparedTurnCount: live.preparedTurnCount,
|
|
272
|
+
artifactChangeTurnCount: live.artifactChangeTurnCount,
|
|
273
|
+
noArtifactChangeTurnCount: live.noArtifactChangeTurnCount,
|
|
274
|
+
latestTurnSequence: live.latestTurnSequence,
|
|
275
|
+
latestEventSequence: live.latestEventSequence,
|
|
276
|
+
providerInterleaving: manifest.liveOperations?.qualification?.providerInterleaving || manifest.liveOperations?.boundary?.providerInterleavingQualification || ''
|
|
277
|
+
}),
|
|
278
|
+
boundary: manifest.boundary || null,
|
|
279
|
+
lineage: manifest.lineage || null
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function liveStats(manifest = {}, nodes = []) {
|
|
284
|
+
const liveOperations = manifest.liveOperations || {};
|
|
285
|
+
const receipts = Array.isArray(liveOperations.receipts) ? liveOperations.receipts : [];
|
|
286
|
+
const updateReceipts = receipts.filter((receipt) => receipt.operation === 'update-live-lineage');
|
|
287
|
+
const prepareReceipts = receipts.filter((receipt) => receipt.operation === 'prepare-live-response');
|
|
288
|
+
const artifactChange = updateReceipts.filter((receipt) => receipt.decision === 'artifact-change');
|
|
289
|
+
const noArtifactChange = updateReceipts.filter((receipt) => receipt.decision === 'no-artifact-change');
|
|
290
|
+
const touchesBySlug = new Map();
|
|
291
|
+
for (const receipt of updateReceipts) {
|
|
292
|
+
for (const artifactId of Array.isArray(receipt.artifactIds) ? receipt.artifactIds : []) {
|
|
293
|
+
const key = String(artifactId || '').trim();
|
|
294
|
+
if (!key) continue;
|
|
295
|
+
const current = touchesBySlug.get(key) || { latestTurnSequence: 0, latestObservedAt: '' };
|
|
296
|
+
const turnSequence = Number(receipt.turnSequence || 0);
|
|
297
|
+
if (turnSequence >= current.latestTurnSequence) touchesBySlug.set(key, { latestTurnSequence: turnSequence, latestObservedAt: receipt.observedAt || current.latestObservedAt });
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
for (const node of nodes) {
|
|
301
|
+
const touch = touchesBySlug.get(node.slug) || touchesBySlug.get(node.id) || touchesBySlug.get(slugFromPath(node.path));
|
|
302
|
+
if (touch) node.liveTouch = touch;
|
|
303
|
+
}
|
|
304
|
+
return Object.freeze({
|
|
305
|
+
processedTurnCount: Number(liveOperations.latestTurnSequence || updateReceipts.length || liveOperations.counts?.['update-live-lineage'] || 0),
|
|
306
|
+
preparedTurnCount: Number(liveOperations.preparedTurnSequence || prepareReceipts.length || liveOperations.counts?.['prepare-live-response'] || 0),
|
|
307
|
+
artifactChangeTurnCount: artifactChange.length,
|
|
308
|
+
noArtifactChangeTurnCount: noArtifactChange.length,
|
|
309
|
+
latestTurnSequence: Number(liveOperations.latestTurnSequence || 0),
|
|
310
|
+
latestEventSequence: Number(liveOperations.latestEventSequence || 0)
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function parseManifest(input = {}) {
|
|
315
|
+
const files = Array.isArray(input.files) ? input.files : [];
|
|
316
|
+
const manifests = files.filter((file) => /(^|\/)manifest\.json$/i.test(String(file.path || file.name || '')) && typeof (file.content || file.markdown) === 'string');
|
|
317
|
+
for (const file of manifests) {
|
|
318
|
+
try { return JSON.parse(file.content || file.markdown || '{}'); }
|
|
319
|
+
catch { /* ignore invalid manifest */ }
|
|
320
|
+
}
|
|
321
|
+
if (input.manifest && typeof input.manifest === 'object') return input.manifest;
|
|
322
|
+
return {};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function normalizeLineageFindings(findings = []) {
|
|
326
|
+
return findings.map((finding) => portableFinding(finding.severity || 'info', finding.code || 'lineage.finding', finding.message || 'Lineage finding.', { nodeId: finding.nodeId || '', target: finding.target || '', source: finding.source || 'tiinex.lineage.v1' }));
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function idsWithAncestors(model, ids = []) {
|
|
330
|
+
const out = new Set();
|
|
331
|
+
for (const id of ids) {
|
|
332
|
+
let current = id;
|
|
333
|
+
while (current && !out.has(current)) {
|
|
334
|
+
out.add(current);
|
|
335
|
+
current = model.parentByChild.get(current) || '';
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return out;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function neighborhoodIds(model, id) {
|
|
342
|
+
const out = idsWithAncestors(model, [id]);
|
|
343
|
+
for (const child of model.childrenByParent.get(id) || []) out.add(child);
|
|
344
|
+
const parent = model.parentByChild.get(id);
|
|
345
|
+
if (parent) for (const sibling of model.childrenByParent.get(parent) || []) out.add(sibling);
|
|
346
|
+
return out;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function segmentIds(model, from, to, findings) {
|
|
350
|
+
const path = [];
|
|
351
|
+
let current = to;
|
|
352
|
+
while (current) {
|
|
353
|
+
path.push(current);
|
|
354
|
+
if (current === from) return new Set(path.reverse());
|
|
355
|
+
current = model.parentByChild.get(current) || '';
|
|
356
|
+
}
|
|
357
|
+
findings.push(portableFinding('warning', 'lineage-print.segment.not-connected', 'No loaded parent path connects the requested segment endpoints.', { from, to }));
|
|
358
|
+
return new Set([from, to]);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function hiddenParentPathToSelectedAncestor(model, id, selected) {
|
|
362
|
+
let current = model.parentByChild.get(id) || '';
|
|
363
|
+
const hiddenIds = [];
|
|
364
|
+
while (current) {
|
|
365
|
+
if (selected.has(current)) return { ancestorId: current, hiddenCount: hiddenIds.length, hiddenIds };
|
|
366
|
+
hiddenIds.push(current);
|
|
367
|
+
current = model.parentByChild.get(current) || '';
|
|
368
|
+
}
|
|
369
|
+
return { ancestorId: '', hiddenCount: hiddenIds.length, hiddenIds };
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function resolveArtifactIds(model, values = []) {
|
|
373
|
+
return values.map((value) => resolveArtifactId(model, value)).filter(Boolean);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function resolveArtifactId(model, value = '') {
|
|
377
|
+
const raw = String(value || '').trim();
|
|
378
|
+
if (!raw) return '';
|
|
379
|
+
if (model.nodeById.has(raw)) return raw;
|
|
380
|
+
const lower = raw.toLowerCase();
|
|
381
|
+
const match = model.nodes.find((node) => node.path.toLowerCase() === lower || node.path.toLowerCase().endsWith(lower) || node.slug === lower || node.title.toLowerCase() === lower);
|
|
382
|
+
return match?.id || '';
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function normalizeScope(value = '') { return String(value || 'all').trim() || 'all'; }
|
|
386
|
+
function emptyModel() { return { records: [], nodes: [], nodeById: new Map(), edges: [], parentEdges: [], missingParentEdges: [], roots: [], leaves: [], latestLeaves: [], live: liveStats({}, []) }; }
|
|
387
|
+
function emptyGraph() { return { nodes: [], edges: [], findings: [] }; }
|
|
388
|
+
function dedupeByCodeRef(findings = []) {
|
|
389
|
+
const seen = new Set();
|
|
390
|
+
const out = [];
|
|
391
|
+
for (const finding of findings) {
|
|
392
|
+
const key = [finding.code, finding.evidencePath || finding.ref || finding.nodeId || '', finding.target || '', finding.scope || '', finding.ancestorId || ''].join(':');
|
|
393
|
+
if (seen.has(key)) continue;
|
|
394
|
+
seen.add(key);
|
|
395
|
+
out.push(finding);
|
|
396
|
+
}
|
|
397
|
+
return out;
|
|
398
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
function nodeLabel(node = {}) {
|
|
2
|
+
const schema = node.schemaId ? ` [${node.schemaId}]` : '';
|
|
3
|
+
const path = node.path ? ` (${node.path})` : '';
|
|
4
|
+
return `${node.title || node.id}${schema}${path}`;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function compareNodeOrder(nodeById) {
|
|
8
|
+
return (a, b) => {
|
|
9
|
+
const an = typeof a === 'string' ? nodeById.get(a) || { id: a } : a;
|
|
10
|
+
const bn = typeof b === 'string' ? nodeById.get(b) || { id: b } : b;
|
|
11
|
+
return String(an.path || an.title || an.id).localeCompare(String(bn.path || bn.title || bn.id));
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function escapeMermaid(value = '') { return String(value).replace(/["<>]/g, ''); }
|
|
16
|
+
function escapeDot(value = '') { return String(value).replace(/\\/g, '\\\\').replace(/"/g, '\"'); }
|
|
17
|
+
function mermaidId(value = '') { return `n_${String(value || '').replace(/[^A-Za-z0-9_]/g, '_')}`; }
|
|
18
|
+
|
|
19
|
+
export function renderTextMap(model, graph, scope, findings, manifest = {}) {
|
|
20
|
+
const lines = [];
|
|
21
|
+
lines.push('Tiinex lineage print');
|
|
22
|
+
lines.push(`Scope: ${scope}`);
|
|
23
|
+
lines.push(`Artifacts: ${model.nodes.length} | Selected: ${graph.nodes.length} | Roots: ${model.roots.length} | Leaves: ${model.leaves.length} | Parent edges: ${model.parentEdges.length}`);
|
|
24
|
+
if (model.live.processedTurnCount) lines.push(`Live receipts: processed turns ${model.live.processedTurnCount}, artifact-change turns ${model.live.artifactChangeTurnCount}, prepare turns ${model.live.preparedTurnCount}`);
|
|
25
|
+
const warningCount = findings.filter((finding) => finding.severity === 'warning' || finding.severity === 'error').length;
|
|
26
|
+
lines.push(`Findings: ${findings.length}${warningCount ? ` (${warningCount} warning/error)` : ''}`);
|
|
27
|
+
lines.push('');
|
|
28
|
+
lines.push('Tree');
|
|
29
|
+
const printed = new Set();
|
|
30
|
+
const selected = new Set(graph.nodes.map((node) => node.id));
|
|
31
|
+
const roots = graph.nodes.filter((node) => !model.parentByChild.has(node.id) || !selected.has(model.parentByChild.get(node.id))).map((node) => node.id).sort(compareNodeOrder(model.nodeById));
|
|
32
|
+
for (const root of roots) printSubtree(lines, model, selected, root, '', printed);
|
|
33
|
+
for (const node of graph.nodes) {
|
|
34
|
+
if (printed.has(node.id)) continue;
|
|
35
|
+
lines.push(`└─ ${nodeLabel(node)}`);
|
|
36
|
+
printed.add(node.id);
|
|
37
|
+
}
|
|
38
|
+
if (!graph.nodes.length) lines.push('└─ (no selected loaded artifacts)');
|
|
39
|
+
const hidden = graph.edges.filter((edge) => edge.status === 'hidden-intermediate' || edge.status === 'missing-parent' || edge.status === 'known-but-excluded');
|
|
40
|
+
if (hidden.length) {
|
|
41
|
+
lines.push('');
|
|
42
|
+
lines.push('Lineage gaps / scoped edges');
|
|
43
|
+
for (const edge of hidden) lines.push(`- ${edge.status}: ${edge.from || '(missing)'} → ${edge.to || '(missing)'}${edge.hiddenCount ? ` (${edge.hiddenCount} hidden)` : ''}`);
|
|
44
|
+
}
|
|
45
|
+
if (findings.length) {
|
|
46
|
+
lines.push('');
|
|
47
|
+
lines.push('Findings');
|
|
48
|
+
for (const finding of findings) lines.push(`- ${finding.severity}: ${finding.code}`);
|
|
49
|
+
}
|
|
50
|
+
return lines.join('\n');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function printSubtree(lines, model, selected, id, prefix, printed) {
|
|
54
|
+
const node = model.nodeById.get(id);
|
|
55
|
+
if (!node || printed.has(id) || !selected.has(id)) return;
|
|
56
|
+
const selectedChildren = (model.childrenByParent.get(id) || []).filter((child) => selected.has(child)).sort(compareNodeOrder(model.nodeById));
|
|
57
|
+
const connector = prefix ? '└─ ' : '└─ ';
|
|
58
|
+
lines.push(`${prefix}${connector}${nodeLabel(node)}`);
|
|
59
|
+
printed.add(id);
|
|
60
|
+
selectedChildren.forEach((child, index) => {
|
|
61
|
+
const nextPrefix = `${prefix}${index === selectedChildren.length - 1 ? ' ' : '│ '}`;
|
|
62
|
+
printSubtree(lines, model, selected, child, nextPrefix, printed);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function renderMermaid(graph = {}) {
|
|
67
|
+
const lines = ['graph TD'];
|
|
68
|
+
for (const node of graph.nodes || []) lines.push(` ${mermaidId(node.id)}["${escapeMermaid(node.title || node.id)}"]`);
|
|
69
|
+
for (const edge of graph.edges || []) {
|
|
70
|
+
if (!edge.from || !edge.to) continue;
|
|
71
|
+
const arrow = edge.status === 'hidden-intermediate' ? '-. hidden .->' : '-->';
|
|
72
|
+
lines.push(` ${mermaidId(edge.from)} ${arrow} ${mermaidId(edge.to)}`);
|
|
73
|
+
}
|
|
74
|
+
return lines.join('\n');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function renderDot(graph = {}) {
|
|
78
|
+
const lines = ['digraph tiinex_lineage {', ' rankdir=TB;'];
|
|
79
|
+
for (const node of graph.nodes || []) lines.push(` "${escapeDot(node.id)}" [label="${escapeDot(node.title || node.id)}"];`);
|
|
80
|
+
for (const edge of graph.edges || []) {
|
|
81
|
+
if (!edge.from || !edge.to) continue;
|
|
82
|
+
const style = edge.status === 'hidden-intermediate' ? ' [style=dashed,label="hidden"]' : '';
|
|
83
|
+
lines.push(` "${escapeDot(edge.from)}" -> "${escapeDot(edge.to)}"${style};`);
|
|
84
|
+
}
|
|
85
|
+
lines.push('}');
|
|
86
|
+
return lines.join('\n');
|
|
87
|
+
}
|
|
88
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export function compactNode(node = {}) {
|
|
2
|
+
if (!node) return null;
|
|
3
|
+
return Object.freeze({
|
|
4
|
+
id: node.id,
|
|
5
|
+
slug: node.slug,
|
|
6
|
+
kind: node.kind || 'artifact',
|
|
7
|
+
status: node.status || 'included',
|
|
8
|
+
title: node.title || node.id,
|
|
9
|
+
path: node.path || '',
|
|
10
|
+
schemaId: node.schemaId || '',
|
|
11
|
+
sourceMode: node.sourceMode || '',
|
|
12
|
+
boundary: node.boundary || '',
|
|
13
|
+
summary: node.summary || '',
|
|
14
|
+
currentCreatedAt: node.currentCreatedAt || '',
|
|
15
|
+
lifecycleStatus: node.lifecycleStatus || '',
|
|
16
|
+
hasContinuityContext: Boolean(node.hasContinuityContext),
|
|
17
|
+
hasIntegrity: Boolean(node.hasIntegrity)
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function hasExplicitMetadata(markdown = '', labels = []) {
|
|
22
|
+
const text = String(markdown || '').toLowerCase();
|
|
23
|
+
return labels.some((label) => new RegExp(`(^|[\\n#*_ -])${escapeRegExp(label.toLowerCase())}([\\s:#*_ -]|$)`).test(text));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function compareLatest(nodeById) {
|
|
27
|
+
return (a, b) => {
|
|
28
|
+
const an = nodeById.get(a) || {};
|
|
29
|
+
const bn = nodeById.get(b) || {};
|
|
30
|
+
const at = Number(an.liveTouch?.latestTurnSequence || 0);
|
|
31
|
+
const bt = Number(bn.liveTouch?.latestTurnSequence || 0);
|
|
32
|
+
if (bt !== at) return bt - at;
|
|
33
|
+
const ad = Date.parse(an.currentCreatedAt || '') || 0;
|
|
34
|
+
const bd = Date.parse(bn.currentCreatedAt || '') || 0;
|
|
35
|
+
if (bd !== ad) return bd - ad;
|
|
36
|
+
return compareNodeOrder(nodeById)(a, b);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function compareNodeOrder(nodeById) {
|
|
41
|
+
return (a, b) => {
|
|
42
|
+
const an = typeof a === 'string' ? nodeById.get(a) || { id: a } : a;
|
|
43
|
+
const bn = typeof b === 'string' ? nodeById.get(b) || { id: b } : b;
|
|
44
|
+
return String(an.path || an.title || an.id).localeCompare(String(bn.path || bn.title || bn.id));
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function compareEdges(a = {}, b = {}) {
|
|
49
|
+
return [a.relation, a.from || '', a.to || '', a.status || ''].join('|').localeCompare([b.relation, b.from || '', b.to || '', b.status || ''].join('|'));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function normalizeList(value = []) { return (Array.isArray(value) ? value : String(value || '').split(',')).map((entry) => String(entry || '').trim()).filter(Boolean); }
|
|
53
|
+
export function positiveInteger(value, fallback) { const number = Number.parseInt(value, 10); return Number.isFinite(number) && number > 0 ? number : fallback; }
|
|
54
|
+
export function truncate(value = '', max = 220) { const text = String(value || '').replace(/\s+/g, ' ').trim(); return text.length <= max ? text : `${text.slice(0, max - 1)}…`; }
|
|
55
|
+
export function slugFromPath(value = '') { const last = String(value || '').split('/').filter(Boolean).pop() || String(value || ''); return last.toLowerCase().replace(/\.trace\.md$/i, '').replace(/\.(md|markdown)$/i, ''); }
|
|
56
|
+
export function compareIds(a, b) { return String(a).localeCompare(String(b)); }
|
|
57
|
+
|
|
58
|
+
function escapeRegExp(value = '') { return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
|