@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,34 @@
|
|
|
1
|
+
import { listPortableOperations, runPortableOperation } from '../../operation.catalog.js';
|
|
2
|
+
import { openPortableSession, restorePortableSession } from '../../session/portable.session.js';
|
|
3
|
+
|
|
4
|
+
export const TIINEX_LLM_ENTRYPOINT_SCHEMA_ID = 'tiinex.llm.entrypoint.v1';
|
|
5
|
+
|
|
6
|
+
export function openTiinexLlmSession(input = {}) {
|
|
7
|
+
return openPortableSession(input);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function restoreTiinexLlmSession(snapshot = {}) {
|
|
11
|
+
return restorePortableSession(snapshot);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function runTiinexLlmOperation(operation, input = {}, options = {}) {
|
|
15
|
+
return runPortableOperation(operation, input, options);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function describeTiinexLlmEntrypoint() {
|
|
19
|
+
return Object.freeze({
|
|
20
|
+
schema: TIINEX_LLM_ENTRYPOINT_SCHEMA_ID,
|
|
21
|
+
boundary: Object.freeze({
|
|
22
|
+
material: 'supplied attachments, project sources, or explicit records',
|
|
23
|
+
sourceProvenance: 'explicit-only; local material is never guessed as GitHub-backed',
|
|
24
|
+
remoteFetch: 'host-mediated only through explicit provider adapters or provider-response handoff',
|
|
25
|
+
remoteWrite: false,
|
|
26
|
+
sourceMutation: false,
|
|
27
|
+
receivedCodeExecution: false,
|
|
28
|
+
toolingDiscovery: 'capability-level with ranked concrete host-tool bindings and explicit normalized receipts; product-specific names are optional inputs, not semantic authority',
|
|
29
|
+
unknownSchemaResolution: 'loaded/cache/provider response first; otherwise self-describing host request'
|
|
30
|
+
}),
|
|
31
|
+
operations: listPortableOperations().operations,
|
|
32
|
+
bootstrap: 'src/tooling/portable/bootstrap/tiinex.llm.bootstrap.md'
|
|
33
|
+
});
|
|
34
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { access, readFile, readdir, stat, writeFile } from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import process from 'node:process';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { listPortableOperations } from '../../operation.catalog.js';
|
|
8
|
+
import {
|
|
9
|
+
PORTABLE_VALIDATION_RECEIPT_SCHEMA_ID,
|
|
10
|
+
describePortableCheckpointGate,
|
|
11
|
+
qualifyPortableCheckpoint
|
|
12
|
+
} from '../../conformance/checkpoint.qualification.js';
|
|
13
|
+
|
|
14
|
+
const MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const DEFAULT_REPO_ROOT = path.resolve(MODULE_DIR, '../../../../..');
|
|
16
|
+
|
|
17
|
+
export async function runNodePortableCheckpointVerification(options = {}) {
|
|
18
|
+
const repoRoot = path.resolve(options.repoRoot || DEFAULT_REPO_ROOT);
|
|
19
|
+
const profile = options.profile || 'source-clean';
|
|
20
|
+
const gate = describePortableCheckpointGate({ profile });
|
|
21
|
+
const packageJson = JSON.parse(await readFile(path.join(repoRoot, 'package.json'), 'utf8'));
|
|
22
|
+
const workflowText = await readOptional(path.join(repoRoot, '.github/workflows/publish-public.yml'));
|
|
23
|
+
const parityText = await readOptional(path.join(repoRoot, 'src/parity/poc.parityLedger.js'));
|
|
24
|
+
const portableFiles = await collectPortableSourceFiles(repoRoot);
|
|
25
|
+
const portableIdentity = await buildPortableIdentity(repoRoot, portableFiles);
|
|
26
|
+
const lockfiles = await existingPaths(repoRoot, ['package-lock.json', 'npm-shrinkwrap.json', 'yarn.lock', 'pnpm-lock.yaml']);
|
|
27
|
+
const installer = extractInstaller(workflowText);
|
|
28
|
+
const parityCheckpoint = extractParityCheckpoint(parityText);
|
|
29
|
+
const receipts = [];
|
|
30
|
+
|
|
31
|
+
for (const descriptor of gate.gates) {
|
|
32
|
+
const receipt = descriptor.id === 'portable-syntax'
|
|
33
|
+
? await runSyntaxGate(repoRoot, portableFiles, descriptor, options)
|
|
34
|
+
: await runCommandGate(repoRoot, descriptor, options);
|
|
35
|
+
receipts.push(receipt);
|
|
36
|
+
if (options.failFast && receipt.status === 'failed') break;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const qualification = qualifyPortableCheckpoint({
|
|
40
|
+
profile,
|
|
41
|
+
siteIdentity: {
|
|
42
|
+
name: packageJson.name,
|
|
43
|
+
version: packageJson.version,
|
|
44
|
+
description: packageJson.description,
|
|
45
|
+
commit: options.commit || '',
|
|
46
|
+
sourceCheckpoint: options.sourceCheckpoint || ''
|
|
47
|
+
},
|
|
48
|
+
portableIdentity,
|
|
49
|
+
receipts,
|
|
50
|
+
reproducibility: {
|
|
51
|
+
dependencies: packageJson.dependencies || {},
|
|
52
|
+
lockfiles,
|
|
53
|
+
installer
|
|
54
|
+
},
|
|
55
|
+
continuity: {
|
|
56
|
+
parityCheckpoint,
|
|
57
|
+
expectedVersion: options.expectedVersion || ''
|
|
58
|
+
},
|
|
59
|
+
evidence: options.evidence || []
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const result = Object.freeze({
|
|
63
|
+
schema: 'tiinex.portable.node-checkpoint-verification.v1',
|
|
64
|
+
generatedAt: new Date().toISOString(),
|
|
65
|
+
repoRoot: options.includePaths === true ? repoRoot : '.',
|
|
66
|
+
profile,
|
|
67
|
+
receipts: Object.freeze(receipts),
|
|
68
|
+
qualification
|
|
69
|
+
});
|
|
70
|
+
if (options.output) await writeFile(path.resolve(repoRoot, options.output), `${JSON.stringify(result, null, 2)}\n`, 'utf8');
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function runSyntaxGate(repoRoot, files, descriptor, options) {
|
|
75
|
+
const startedAt = new Date();
|
|
76
|
+
const details = [];
|
|
77
|
+
let failed = false;
|
|
78
|
+
for (const relativePath of files.filter((file) => /\.(?:js|mjs)$/i.test(file))) {
|
|
79
|
+
const result = await runProcess(repoRoot, process.execPath, ['--check', relativePath], options);
|
|
80
|
+
details.push({ path: relativePath, exitCode: result.exitCode, status: result.exitCode === 0 ? 'passed' : 'failed', stderrDigest: digest(result.stderr) });
|
|
81
|
+
if (result.exitCode !== 0) failed = true;
|
|
82
|
+
}
|
|
83
|
+
const finishedAt = new Date();
|
|
84
|
+
return receipt(descriptor, {
|
|
85
|
+
status: failed ? 'failed' : 'passed',
|
|
86
|
+
exitCode: failed ? 1 : 0,
|
|
87
|
+
startedAt,
|
|
88
|
+
finishedAt,
|
|
89
|
+
stdout: `${details.filter((entry) => entry.status === 'passed').length}/${details.length} portable JavaScript sources passed node --check`,
|
|
90
|
+
stderr: '',
|
|
91
|
+
details
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function runCommandGate(repoRoot, descriptor, options) {
|
|
96
|
+
const startedAt = new Date();
|
|
97
|
+
if (descriptor.requiresInstalledDependencies && !(await exists(path.join(repoRoot, 'node_modules')))) {
|
|
98
|
+
const canUseNoInstallTsc = descriptor.id === 'typecheck' && await commandAvailable(repoRoot, 'npx', ['--no-install', 'tsc', '--version']);
|
|
99
|
+
if (!canUseNoInstallTsc) {
|
|
100
|
+
const finishedAt = new Date();
|
|
101
|
+
return receipt(descriptor, {
|
|
102
|
+
status: 'blocked',
|
|
103
|
+
exitCode: null,
|
|
104
|
+
reason: 'installed-dependencies-unavailable',
|
|
105
|
+
startedAt,
|
|
106
|
+
finishedAt,
|
|
107
|
+
stdout: '',
|
|
108
|
+
stderr: 'node_modules is unavailable for a dependency-backed checkpoint gate.'
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const parsed = splitCommand(descriptor.command);
|
|
113
|
+
const result = await runProcess(repoRoot, parsed.command, parsed.args, options);
|
|
114
|
+
const finishedAt = new Date();
|
|
115
|
+
return receipt(descriptor, {
|
|
116
|
+
status: result.spawnError ? 'blocked' : result.exitCode === 0 ? 'passed' : 'failed',
|
|
117
|
+
exitCode: result.spawnError ? null : result.exitCode,
|
|
118
|
+
reason: result.spawnError ? 'command-unavailable' : '',
|
|
119
|
+
startedAt,
|
|
120
|
+
finishedAt,
|
|
121
|
+
stdout: result.stdout,
|
|
122
|
+
stderr: result.stderr,
|
|
123
|
+
details: result.spawnError ? { message: result.spawnError.message } : null
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function receipt(descriptor, input) {
|
|
128
|
+
return Object.freeze({
|
|
129
|
+
schema: PORTABLE_VALIDATION_RECEIPT_SCHEMA_ID,
|
|
130
|
+
gateId: descriptor.id,
|
|
131
|
+
command: descriptor.command,
|
|
132
|
+
status: input.status,
|
|
133
|
+
exitCode: input.exitCode,
|
|
134
|
+
reason: input.reason || '',
|
|
135
|
+
startedAt: input.startedAt.toISOString(),
|
|
136
|
+
finishedAt: input.finishedAt.toISOString(),
|
|
137
|
+
durationMs: input.finishedAt.getTime() - input.startedAt.getTime(),
|
|
138
|
+
stdoutDigest: digest(input.stdout),
|
|
139
|
+
stderrDigest: digest(input.stderr),
|
|
140
|
+
outputSummary: summarizeOutput(input.stdout, input.stderr),
|
|
141
|
+
details: input.details || null,
|
|
142
|
+
environment: Object.freeze({ node: process.version, platform: process.platform, arch: process.arch })
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function runProcess(cwd, command, args, options = {}) {
|
|
147
|
+
return await new Promise((resolve) => {
|
|
148
|
+
let stdout = '';
|
|
149
|
+
let stderr = '';
|
|
150
|
+
let settled = false;
|
|
151
|
+
const child = spawn(command, args, {
|
|
152
|
+
cwd,
|
|
153
|
+
env: { ...process.env, CI: process.env.CI || '1', NO_COLOR: '1' },
|
|
154
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
155
|
+
shell: false
|
|
156
|
+
});
|
|
157
|
+
child.stdout.on('data', (chunk) => {
|
|
158
|
+
stdout += String(chunk);
|
|
159
|
+
if (options.echo === true) process.stdout.write(chunk);
|
|
160
|
+
});
|
|
161
|
+
child.stderr.on('data', (chunk) => {
|
|
162
|
+
stderr += String(chunk);
|
|
163
|
+
if (options.echo === true) process.stderr.write(chunk);
|
|
164
|
+
});
|
|
165
|
+
child.on('error', (spawnError) => {
|
|
166
|
+
if (settled) return;
|
|
167
|
+
settled = true;
|
|
168
|
+
resolve({ exitCode: null, stdout, stderr, spawnError });
|
|
169
|
+
});
|
|
170
|
+
child.on('close', (exitCode) => {
|
|
171
|
+
if (settled) return;
|
|
172
|
+
settled = true;
|
|
173
|
+
resolve({ exitCode: typeof exitCode === 'number' ? exitCode : 1, stdout, stderr, spawnError: null });
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async function buildPortableIdentity(repoRoot, files) {
|
|
179
|
+
const sourceHash = createHash('sha256');
|
|
180
|
+
for (const relativePath of files) {
|
|
181
|
+
sourceHash.update(relativePath);
|
|
182
|
+
sourceHash.update('\0');
|
|
183
|
+
sourceHash.update(await readFile(path.join(repoRoot, relativePath)));
|
|
184
|
+
sourceHash.update('\0');
|
|
185
|
+
}
|
|
186
|
+
const operations = listPortableOperations().operations;
|
|
187
|
+
const operationFingerprint = digest(JSON.stringify(operations));
|
|
188
|
+
const bootstrapPath = 'src/tooling/portable/bootstrap/tiinex.llm.bootstrap.md';
|
|
189
|
+
const bootstrap = await readOptional(path.join(repoRoot, bootstrapPath));
|
|
190
|
+
return Object.freeze({
|
|
191
|
+
sourceFingerprint: `sha256:${sourceHash.digest('hex')}`,
|
|
192
|
+
operationFingerprint,
|
|
193
|
+
operationCount: operations.length,
|
|
194
|
+
sourceFiles: files.length,
|
|
195
|
+
bootstrapFingerprint: bootstrap ? digest(bootstrap) : ''
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async function collectPortableSourceFiles(repoRoot) {
|
|
200
|
+
const roots = [
|
|
201
|
+
'src/tooling/portable',
|
|
202
|
+
'tools/tiinex-portable.mjs',
|
|
203
|
+
'tools/tiinex-portable-verify.mjs',
|
|
204
|
+
'docs/architecture/portable-tooling-entrypoints.md'
|
|
205
|
+
];
|
|
206
|
+
const files = [];
|
|
207
|
+
for (const root of roots) {
|
|
208
|
+
const absolute = path.join(repoRoot, root);
|
|
209
|
+
if (!(await exists(absolute))) continue;
|
|
210
|
+
const info = await stat(absolute);
|
|
211
|
+
if (info.isFile()) files.push(root);
|
|
212
|
+
else files.push(...await walkFiles(repoRoot, absolute));
|
|
213
|
+
}
|
|
214
|
+
return [...new Set(files)].sort();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function walkFiles(repoRoot, directory) {
|
|
218
|
+
const out = [];
|
|
219
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
220
|
+
const absolute = path.join(directory, entry.name);
|
|
221
|
+
if (entry.isDirectory()) out.push(...await walkFiles(repoRoot, absolute));
|
|
222
|
+
else if (entry.isFile()) out.push(path.relative(repoRoot, absolute).replace(/\\/g, '/'));
|
|
223
|
+
}
|
|
224
|
+
return out;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async function existingPaths(repoRoot, names) {
|
|
228
|
+
const out = [];
|
|
229
|
+
for (const name of names) if (await exists(path.join(repoRoot, name))) out.push(name);
|
|
230
|
+
return out;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async function exists(target) {
|
|
234
|
+
try { await access(target); return true; }
|
|
235
|
+
catch { return false; }
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async function readOptional(target) {
|
|
239
|
+
try { return await readFile(target, 'utf8'); }
|
|
240
|
+
catch { return ''; }
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async function commandAvailable(cwd, command, args) {
|
|
244
|
+
const result = await runProcess(cwd, command, args, {});
|
|
245
|
+
return !result.spawnError && result.exitCode === 0;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function extractInstaller(workflow = '') {
|
|
249
|
+
const match = String(workflow || '').match(/run:\s*(npm\s+(?:install|ci)[^\n]*)/i);
|
|
250
|
+
return match?.[1]?.trim() || '';
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function extractParityCheckpoint(source = '') {
|
|
254
|
+
const match = String(source || '').match(/checkpoint:\s*['"]([^'"]+)['"]/);
|
|
255
|
+
return match?.[1]?.trim() || '';
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function splitCommand(commandLine = '') {
|
|
259
|
+
const tokens = String(commandLine || '').match(/(?:[^\s"]+|"[^"]*")+/g) || [];
|
|
260
|
+
return { command: tokens.shift() || '', args: tokens.map((token) => token.replace(/^"|"$/g, '')) };
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function digest(value = '') { return `sha256:${createHash('sha256').update(String(value || '')).digest('hex')}`; }
|
|
264
|
+
function summarizeOutput(stdout = '', stderr = '') {
|
|
265
|
+
const text = `${stdout}\n${stderr}`.trim().replace(/\s+/g, ' ');
|
|
266
|
+
return text.length <= 320 ? text : `${text.slice(0, 317)}...`;
|
|
267
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { lstat, readdir, readFile } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { sha256Hex } from '../../../../export/package.bytes.js';
|
|
6
|
+
|
|
7
|
+
export const PORTABLE_TOOLING_BOOTSTRAP_MANIFEST_SCHEMA_ID = 'tiinex.portable.tooling-bootstrap.manifest.v1';
|
|
8
|
+
|
|
9
|
+
const MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const DEFAULT_RUNTIME_ROOT = path.resolve(MODULE_DIR, '../../../../..');
|
|
11
|
+
const IMPORT_RE = /(?:\bimport\s+(?:[^'";]+?\s+from\s+)?|\bexport\s+(?:\*|\{[^}]*\})\s+from\s+|\bimport\s*\()\s*['"]([^'"]+)['"]/g;
|
|
12
|
+
|
|
13
|
+
export async function buildToolingBootstrapTransportFiles(input = {}) {
|
|
14
|
+
const delivery = normalizeDelivery(input.delivery);
|
|
15
|
+
const runtimeRoot = path.resolve(String(input.runtimeRoot || DEFAULT_RUNTIME_ROOT));
|
|
16
|
+
const runtime = await enumerateRuntimeDependencyGraph(runtimeRoot, { maxFiles: input.maxFiles });
|
|
17
|
+
const manifest = Object.freeze({
|
|
18
|
+
schema: PORTABLE_TOOLING_BOOTSTRAP_MANIFEST_SCHEMA_ID,
|
|
19
|
+
version: 1,
|
|
20
|
+
delivery,
|
|
21
|
+
entrypoint: 'runtime/tools/tiinex-portable.mjs',
|
|
22
|
+
qualification: Object.freeze({ authority: 'manifest-declared-exact-runtime-bytes-only', ordinaryWorkspaceBytesAreBootstrapAuthority: false, filenameOrColocationAuthority: false }),
|
|
23
|
+
runtime: Object.freeze({ files: runtime.entries.length, bytes: runtime.totalBytes, representationSha256: runtime.representationSha256, entries: Object.freeze(runtime.entries.map(({ path: entryPath, bytes, sha256 }) => Object.freeze({ path: `runtime/${entryPath}`, bytes, sha256 }))) }),
|
|
24
|
+
canonicalSchemaMaterial: Object.freeze({ boundary: 'Carried as runtime data required by the portable schema provider; canonical schema authority remains the declared external Tiinex/docs binding inside that material, not this bootstrap manifest.' }),
|
|
25
|
+
boundary: 'Portable Tooling bootstrap transport authority only. Transport orientation bootstrap and canonical schema-material authority remain separate concerns.'
|
|
26
|
+
});
|
|
27
|
+
const manifestBytes = new TextEncoder().encode(`${JSON.stringify(sortJson(manifest), null, 2)}\n`);
|
|
28
|
+
const manifestSha256 = sha256Hex(manifestBytes);
|
|
29
|
+
const persistentVerification = delivery === 'persistent' ? verifyExpectedPersistentBootstrap(input.expected, manifest, manifestSha256) : Object.freeze({ state: 'not-required' });
|
|
30
|
+
const summary = Object.freeze({ schema: 'tiinex.portable.tooling-bootstrap.summary.v1', delivery, manifestSha256, representationSha256: runtime.representationSha256, runtimeFiles: runtime.entries.length, runtimeBytes: runtime.totalBytes, status: delivery === 'embedded' ? 'embedded-qualified' : 'persistent-identity-verified', persistentVerification });
|
|
31
|
+
const files = [transportFile('tiinex.bootstrap/manifest.json', manifestBytes, 'tooling-bootstrap-manifest', 'portable-tooling-bootstrap-control')];
|
|
32
|
+
if (delivery === 'embedded') for (const entry of runtime.entries) files.push(transportFile(`tiinex.bootstrap/runtime/${entry.path}`, entry.data, 'tooling-bootstrap-runtime', 'portable-tooling-bootstrap-runtime'));
|
|
33
|
+
return Object.freeze({ manifest, summary, files: Object.freeze(files) });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function verifyExpectedPersistentBootstrap(expected, manifest, manifestSha256) {
|
|
37
|
+
if (!expected || typeof expected !== 'object' || !Object.keys(expected).length) throw new Error('portable.tooling-bootstrap.persistent-verification.required');
|
|
38
|
+
const candidate = expected.manifest && typeof expected.manifest === 'object' ? expected.manifest : expected;
|
|
39
|
+
const expectedRepresentationSha256 = String(candidate.runtime?.representationSha256 || candidate.representationSha256 || expected.representationSha256 || '');
|
|
40
|
+
if (!expectedRepresentationSha256) throw new Error('portable.tooling-bootstrap.persistent-verification.representation-required');
|
|
41
|
+
if (expectedRepresentationSha256 !== manifest.runtime.representationSha256) throw new Error('portable.tooling-bootstrap.persistent-verification.representation-mismatch');
|
|
42
|
+
const expectedFiles = Number(candidate.runtime?.files ?? candidate.runtimeFiles ?? expected.runtimeFiles ?? 0);
|
|
43
|
+
if (expectedFiles && expectedFiles !== manifest.runtime.files) throw new Error('portable.tooling-bootstrap.persistent-verification.file-count-mismatch');
|
|
44
|
+
const expectedBytes = Number(candidate.runtime?.bytes ?? candidate.runtimeBytes ?? expected.runtimeBytes ?? 0);
|
|
45
|
+
if (expectedBytes && expectedBytes !== manifest.runtime.bytes) throw new Error('portable.tooling-bootstrap.persistent-verification.byte-count-mismatch');
|
|
46
|
+
const expectedManifestSha256 = String(expected.manifestSha256 || '');
|
|
47
|
+
if (expectedManifestSha256 && expected.delivery === 'persistent' && expectedManifestSha256 !== manifestSha256) throw new Error('portable.tooling-bootstrap.persistent-verification.manifest-mismatch');
|
|
48
|
+
return Object.freeze({ state: 'verified', basis: 'caller-supplied-exact-runtime-identity', representationSha256: manifest.runtime.representationSha256, runtimeFiles: manifest.runtime.files, runtimeBytes: manifest.runtime.bytes, manifestSha256 });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function enumerateRuntimeDependencyGraph(runtimeRoot, options = {}) {
|
|
52
|
+
const maxFiles = positiveInteger(options.maxFiles, 4000);
|
|
53
|
+
const queue = ['tools/tiinex-portable.mjs'];
|
|
54
|
+
const seen = new Set();
|
|
55
|
+
const files = new Map();
|
|
56
|
+
while (queue.length) {
|
|
57
|
+
const relative = normalizeRelativePath(queue.shift());
|
|
58
|
+
if (seen.has(relative)) continue;
|
|
59
|
+
seen.add(relative);
|
|
60
|
+
if (seen.size > maxFiles) throw new Error(`portable.tooling-bootstrap.file-limit:${maxFiles}`);
|
|
61
|
+
const absolute = path.resolve(runtimeRoot, relative);
|
|
62
|
+
assertInside(runtimeRoot, absolute, 'portable.tooling-bootstrap.path.outside-runtime');
|
|
63
|
+
const info = await lstat(absolute);
|
|
64
|
+
if (!info.isFile()) throw new Error(`portable.tooling-bootstrap.dependency.not-file:${relative}`);
|
|
65
|
+
const data = new Uint8Array(await readFile(absolute));
|
|
66
|
+
files.set(relative, data);
|
|
67
|
+
if (!/\.(?:m?js|cjs)$/i.test(relative)) continue;
|
|
68
|
+
const text = new TextDecoder().decode(data);
|
|
69
|
+
for (const specifier of staticRelativeSpecifiers(text)) {
|
|
70
|
+
const resolved = resolveImportRelative(relative, specifier);
|
|
71
|
+
if (resolved) queue.push(resolved);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (const explicit of ['package.json', 'src/tooling/portable/bootstrap/tiinex.llm.bootstrap.md', 'src/tooling/portable/bootstrap/tiinex.llm.bootstrap.pointer.json']) if (!files.has(explicit)) files.set(explicit, new Uint8Array(await readFile(path.resolve(runtimeRoot, explicit))));
|
|
75
|
+
const canonicalRoot = path.resolve(runtimeRoot, 'src/tooling/portable/schema/bootstrap');
|
|
76
|
+
for (const relative of await enumerateFilesUnder(canonicalRoot, runtimeRoot)) if (!files.has(relative)) files.set(relative, new Uint8Array(await readFile(path.resolve(runtimeRoot, relative))));
|
|
77
|
+
const entries = [...files.entries()].map(([entryPath, data]) => Object.freeze({ path: entryPath, data, bytes: data.byteLength, sha256: sha256Hex(data) })).sort((a, b) => a.path.localeCompare(b.path));
|
|
78
|
+
const totalBytes = entries.reduce((sum, entry) => sum + entry.bytes, 0);
|
|
79
|
+
const representationSha256 = sha256Text(stableJson(entries.map(({ path: entryPath, bytes, sha256 }) => ({ path: `runtime/${entryPath}`, bytes, sha256 }))));
|
|
80
|
+
return Object.freeze({ entries: Object.freeze(entries), totalBytes, representationSha256 });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function enumerateFilesUnder(root, runtimeRoot) {
|
|
84
|
+
const out = [];
|
|
85
|
+
const queue = [root];
|
|
86
|
+
while (queue.length) {
|
|
87
|
+
const current = queue.shift();
|
|
88
|
+
const entries = await readdir(current, { withFileTypes: true });
|
|
89
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
90
|
+
for (const entry of entries) {
|
|
91
|
+
const absolute = path.join(current, entry.name);
|
|
92
|
+
if (entry.isDirectory()) queue.push(absolute);
|
|
93
|
+
else if (entry.isFile()) out.push(normalizeRelativePath(path.relative(runtimeRoot, absolute)));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return out.sort();
|
|
97
|
+
}
|
|
98
|
+
function staticRelativeSpecifiers(text = '') { const out = []; IMPORT_RE.lastIndex = 0; let match; while ((match = IMPORT_RE.exec(text))) if (String(match[1] || '').startsWith('.')) out.push(match[1]); return out; }
|
|
99
|
+
function resolveImportRelative(fromFile, specifier) { const clean = String(specifier || '').split('?')[0].split('#')[0]; if (!clean.startsWith('.')) return ''; let resolved = normalizeRelativePath(path.posix.normalize(path.posix.join(path.posix.dirname(fromFile), clean))); if (!path.posix.extname(resolved)) resolved = `${resolved}.js`; return resolved; }
|
|
100
|
+
function transportFile(filePath, data, kind, logicalKind) { return Object.freeze({ path: filePath, data, kind, logicalKind, mediaType: mediaTypeForPath(filePath), boundary: 'Manifest-declared portable Tooling bootstrap transport byte. Co-location does not grant bootstrap authority; exact manifest membership and digest are required.' }); }
|
|
101
|
+
function normalizeDelivery(value) { const delivery = String(value || 'embedded').trim().toLowerCase(); if (!['embedded', 'persistent'].includes(delivery)) throw new Error(`portable.tooling-bootstrap.delivery.unsupported:${delivery}`); return delivery; }
|
|
102
|
+
function mediaTypeForPath(value = '') { const lower = String(value).toLowerCase(); if (lower.endsWith('.md')) return 'text/markdown'; if (lower.endsWith('.json')) return 'application/json'; if (/\.(?:m?js|cjs)$/.test(lower)) return 'text/javascript'; if (lower.endsWith('.ts')) return 'text/typescript'; if (lower.endsWith('.css')) return 'text/css'; if (lower.endsWith('.html')) return 'text/html'; if (/\.(?:yml|yaml)$/.test(lower)) return 'text/yaml'; if (lower.endsWith('.txt')) return 'text/plain'; return 'application/octet-stream'; }
|
|
103
|
+
function normalizeRelativePath(value = '') { return String(value || '').replace(/\\/g, '/').replace(/^\/+/, '').split('/').filter((part) => part && part !== '.').join('/'); }
|
|
104
|
+
function inside(root, absolute) { const relative = path.relative(root, absolute); return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative)); }
|
|
105
|
+
function assertInside(root, absolute, code) { if (!inside(root, absolute)) throw new Error(code); }
|
|
106
|
+
function positiveInteger(value, fallback) { const parsed = Number.parseInt(value, 10); return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback; }
|
|
107
|
+
function sha256Text(value = '') { return createHash('sha256').update(String(value), 'utf8').digest('hex'); }
|
|
108
|
+
function stableJson(value) { return JSON.stringify(sortJson(value)); }
|
|
109
|
+
function sortJson(value) { if (Array.isArray(value)) return value.map(sortJson); if (!value || typeof value !== 'object') return value; return Object.fromEntries(Object.keys(value).sort().map((key) => [key, sortJson(value[key])]).filter(([, item]) => typeof item !== 'undefined')); }
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { sha256Hex } from '../../../../export/package.bytes.js';
|
|
4
|
+
import { safeWorkspaceToken, serializableMetadata } from './handoff.manufacture.multiRoot.js';
|
|
5
|
+
|
|
6
|
+
export const PORTABLE_NODE_WORKSPACE_ENUMERATION_SCHEMA_ID = 'tiinex.portable.node-workspace-enumeration.v1';
|
|
7
|
+
export const DEFAULT_HANDOFF_MANUFACTURE_EXCLUDED_DIRECTORIES = Object.freeze(['.git', '.tiinex', 'node_modules', '.site-publish']);
|
|
8
|
+
const DEFAULT_MAX_FILES = 10000;
|
|
9
|
+
|
|
10
|
+
export async function enumerateNodeWorkspace(rootInput = '.', options = {}) {
|
|
11
|
+
const root = path.resolve(String(rootInput || '.'));
|
|
12
|
+
const maxFiles = positiveInteger(options.maxFiles, DEFAULT_MAX_FILES);
|
|
13
|
+
const excluded = new Set([...(options.excludeDirectories || DEFAULT_HANDOFF_MANUFACTURE_EXCLUDED_DIRECTORIES)].map(String));
|
|
14
|
+
const queue = [root];
|
|
15
|
+
const absoluteFiles = [];
|
|
16
|
+
const skippedSymlinks = [];
|
|
17
|
+
while (queue.length) {
|
|
18
|
+
const current = queue.shift();
|
|
19
|
+
const entries = await readdir(current, { withFileTypes: true });
|
|
20
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
if (entry.isDirectory() && excluded.has(entry.name)) continue;
|
|
23
|
+
const absolute = path.join(current, entry.name);
|
|
24
|
+
if (entry.isSymbolicLink()) { skippedSymlinks.push(normalizeRelativePath(path.relative(root, absolute))); continue; }
|
|
25
|
+
if (entry.isDirectory()) queue.push(absolute);
|
|
26
|
+
else if (entry.isFile()) absoluteFiles.push(absolute);
|
|
27
|
+
if (absoluteFiles.length > maxFiles) {
|
|
28
|
+
return Object.freeze({
|
|
29
|
+
schema: PORTABLE_NODE_WORKSPACE_ENUMERATION_SCHEMA_ID,
|
|
30
|
+
status: 'file-limit-exceeded',
|
|
31
|
+
maxFiles,
|
|
32
|
+
observedFiles: absoluteFiles.length,
|
|
33
|
+
materialization: null,
|
|
34
|
+
evidence: Object.freeze({ state: 'blocked', proof: 'deterministic-node-enumeration-v1', maxFiles, observedFiles: absoluteFiles.length })
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
absoluteFiles.sort((a, b) => normalizeRelativePath(path.relative(root, a)).localeCompare(normalizeRelativePath(path.relative(root, b))));
|
|
40
|
+
const entries = [];
|
|
41
|
+
const includedEntries = [];
|
|
42
|
+
let totalBytes = 0;
|
|
43
|
+
for (const absolute of absoluteFiles) {
|
|
44
|
+
const relative = normalizeRelativePath(path.relative(root, absolute));
|
|
45
|
+
const data = new Uint8Array(await readFile(absolute));
|
|
46
|
+
const bytes = data.byteLength;
|
|
47
|
+
const sha256 = sha256Hex(data);
|
|
48
|
+
totalBytes += bytes;
|
|
49
|
+
entries.push(Object.freeze({ path: relative, data, bytes, sha256, mediaType: mediaTypeForPath(relative) }));
|
|
50
|
+
includedEntries.push(Object.freeze({ path: relative, bytes, sha256, referenceTarget: '' }));
|
|
51
|
+
}
|
|
52
|
+
const workspaceId = safeWorkspaceToken(options.workspaceId || path.basename(root) || 'workspace');
|
|
53
|
+
const workspaceTitle = String(options.workspaceTitle || '').trim();
|
|
54
|
+
const evidencePayload = Object.freeze({
|
|
55
|
+
schema: 'tiinex.portable.workspace-completeness-evidence.v1',
|
|
56
|
+
state: 'qualified',
|
|
57
|
+
proof: 'deterministic-node-enumeration-v1',
|
|
58
|
+
boundary: 'regular-files-under-workspace-root',
|
|
59
|
+
workspaceId,
|
|
60
|
+
entryCount: includedEntries.length,
|
|
61
|
+
totalBytes,
|
|
62
|
+
exclusions: Object.freeze({ directories: Object.freeze([...excluded].sort()), symbolicLinks: 'excluded-and-reported' }),
|
|
63
|
+
skippedSymlinks: Object.freeze(skippedSymlinks.sort()),
|
|
64
|
+
entriesFingerprint: sha256Text(stableJson(includedEntries))
|
|
65
|
+
});
|
|
66
|
+
return Object.freeze({
|
|
67
|
+
schema: PORTABLE_NODE_WORKSPACE_ENUMERATION_SCHEMA_ID,
|
|
68
|
+
status: 'qualified-complete',
|
|
69
|
+
rootBoundary: '.',
|
|
70
|
+
evidence: evidencePayload,
|
|
71
|
+
materialization: Object.freeze({
|
|
72
|
+
id: workspaceId,
|
|
73
|
+
title: workspaceTitle || workspaceId,
|
|
74
|
+
state: 'complete',
|
|
75
|
+
source: Object.freeze({
|
|
76
|
+
kind: 'node-directory-enumeration',
|
|
77
|
+
workspaceId,
|
|
78
|
+
boundary: '.',
|
|
79
|
+
operatorMetadata: Object.freeze(serializableMetadata(options.sourceMetadata || {})),
|
|
80
|
+
authority: 'none'
|
|
81
|
+
}),
|
|
82
|
+
completenessEvidence: evidencePayload,
|
|
83
|
+
entries: Object.freeze(entries),
|
|
84
|
+
includedEntries: Object.freeze(includedEntries)
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function normalizeRelativePath(value = '') { return String(value || '').replace(/\\/g, '/').replace(/^\.\//, '').replace(/^\/+/, ''); }
|
|
90
|
+
function mediaTypeForPath(value = '') { const lower = String(value).toLowerCase(); if (lower.endsWith('.md')) return 'text/markdown'; if (lower.endsWith('.json')) return 'application/json'; if (/\.(?:m?js|cjs)$/.test(lower)) return 'text/javascript'; if (lower.endsWith('.ts')) return 'text/typescript'; if (lower.endsWith('.css')) return 'text/css'; if (lower.endsWith('.html')) return 'text/html'; if (/\.(?:yml|yaml)$/.test(lower)) return 'text/yaml'; if (lower.endsWith('.txt')) return 'text/plain'; return 'application/octet-stream'; }
|
|
91
|
+
function positiveInteger(value, fallback) { const parsed = Number.parseInt(value, 10); return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback; }
|
|
92
|
+
function sha256Text(value) { return sha256Hex(new TextEncoder().encode(String(value))); }
|
|
93
|
+
function stableJson(value) { return JSON.stringify(sortJson(value)); }
|
|
94
|
+
function sortJson(value) { if (Array.isArray(value)) return value.map(sortJson); if (!value || typeof value !== 'object') return value; return Object.fromEntries(Object.keys(value).sort().map((key) => [key, sortJson(value[key])])); }
|