@b00dea/cockpit 0.0.0-stage → 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/CHANGELOG.md +474 -0
- package/LICENSE +21 -0
- package/README.md +25 -2
- package/bin/cockpit.mjs +33 -0
- package/cockpit.schema.json +2644 -0
- package/dist/autonomy.d.ts +45 -0
- package/dist/autonomy.js +173 -0
- package/dist/bounded-read.d.ts +14 -0
- package/dist/bounded-read.js +42 -0
- package/dist/browser/commands.d.ts +117 -0
- package/dist/browser/commands.js +453 -0
- package/dist/browser/package-paths.d.ts +1 -0
- package/dist/browser/package-paths.js +6 -0
- package/dist/browser/proxy.d.ts +22 -0
- package/dist/browser/proxy.js +37 -0
- package/dist/browser/runtime.d.ts +118 -0
- package/dist/browser/runtime.js +186 -0
- package/dist/browser/surfaces.d.ts +141 -0
- package/dist/browser/surfaces.js +561 -0
- package/dist/browser/ui-gate.d.ts +15 -0
- package/dist/browser/ui-gate.js +18 -0
- package/dist/canonical-json.d.ts +2 -0
- package/dist/canonical-json.js +5 -0
- package/dist/cli-guard.d.ts +5 -0
- package/dist/cli-guard.js +71 -0
- package/dist/cli-main.d.ts +176 -0
- package/dist/cli-main.js +1584 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +16 -0
- package/dist/command-table.d.ts +121 -0
- package/dist/command-table.js +664 -0
- package/dist/config/load.d.ts +183 -0
- package/dist/config/load.js +367 -0
- package/dist/config/sibling-toml.d.ts +48 -0
- package/dist/config/sibling-toml.js +160 -0
- package/dist/config/surface-tools-toml.d.ts +9 -0
- package/dist/config/surface-tools-toml.js +37 -0
- package/dist/config/unconfirmed-toml.d.ts +9 -0
- package/dist/config/unconfirmed-toml.js +29 -0
- package/dist/config/verified-write.d.ts +43 -0
- package/dist/config/verified-write.js +89 -0
- package/dist/diagnostics.d.ts +26 -0
- package/dist/diagnostics.js +344 -0
- package/dist/docs/check.d.ts +16 -0
- package/dist/docs/check.js +197 -0
- package/dist/docs/decision-record.d.ts +34 -0
- package/dist/docs/decision-record.js +135 -0
- package/dist/docs/decisions.d.ts +16 -0
- package/dist/docs/decisions.js +103 -0
- package/dist/docs/markdown.d.ts +36 -0
- package/dist/docs/markdown.js +88 -0
- package/dist/docs/references.d.ts +32 -0
- package/dist/docs/references.js +148 -0
- package/dist/emit.d.ts +22 -0
- package/dist/emit.js +43 -0
- package/dist/entrypoint-kinds.d.ts +3 -0
- package/dist/entrypoint-kinds.js +11 -0
- package/dist/environment/application/confirm.d.ts +35 -0
- package/dist/environment/application/confirm.js +122 -0
- package/dist/environment/application/destructive.d.ts +6 -0
- package/dist/environment/application/destructive.js +429 -0
- package/dist/environment/application/doctor.d.ts +94 -0
- package/dist/environment/application/doctor.js +247 -0
- package/dist/environment/application/guard.d.ts +49 -0
- package/dist/environment/application/guard.js +677 -0
- package/dist/environment/application/health.d.ts +143 -0
- package/dist/environment/application/health.js +385 -0
- package/dist/environment/application/lifecycle-context.d.ts +235 -0
- package/dist/environment/application/lifecycle-context.js +154 -0
- package/dist/environment/application/lifecycle-state.d.ts +25 -0
- package/dist/environment/application/lifecycle-state.js +202 -0
- package/dist/environment/application/lifecycle.d.ts +18 -0
- package/dist/environment/application/lifecycle.js +737 -0
- package/dist/environment/application/logs.d.ts +45 -0
- package/dist/environment/application/logs.js +127 -0
- package/dist/environment/application/services.d.ts +60 -0
- package/dist/environment/application/services.js +89 -0
- package/dist/environment/application/setup.d.ts +129 -0
- package/dist/environment/application/setup.js +741 -0
- package/dist/environment/application/shared.d.ts +11 -0
- package/dist/environment/application/shared.js +61 -0
- package/dist/environment/application/siblings.d.ts +43 -0
- package/dist/environment/application/siblings.js +269 -0
- package/dist/environment/claims.d.ts +389 -0
- package/dist/environment/claims.js +1701 -0
- package/dist/environment/codex-hook-trust.d.ts +11 -0
- package/dist/environment/codex-hook-trust.js +185 -0
- package/dist/environment/compose-environment.d.ts +1 -0
- package/dist/environment/compose-environment.js +6 -0
- package/dist/environment/compose-ownership.d.ts +21 -0
- package/dist/environment/compose-ownership.js +117 -0
- package/dist/environment/compose-topology.d.ts +125 -0
- package/dist/environment/compose-topology.js +490 -0
- package/dist/environment/contract.d.ts +522 -0
- package/dist/environment/contract.js +794 -0
- package/dist/environment/declaration.d.ts +14 -0
- package/dist/environment/declaration.js +39 -0
- package/dist/environment/destructive-composition.d.ts +29 -0
- package/dist/environment/destructive-composition.js +333 -0
- package/dist/environment/docker-daemon.d.ts +30 -0
- package/dist/environment/docker-daemon.js +78 -0
- package/dist/environment/docker-endpoint.d.ts +10 -0
- package/dist/environment/docker-endpoint.js +19 -0
- package/dist/environment/env-schema-observation.d.ts +46 -0
- package/dist/environment/env-schema-observation.js +241 -0
- package/dist/environment/evidence.d.ts +136 -0
- package/dist/environment/evidence.js +437 -0
- package/dist/environment/executable.d.ts +38 -0
- package/dist/environment/executable.js +190 -0
- package/dist/environment/generated-application/authorities.d.ts +5 -0
- package/dist/environment/generated-application/authorities.js +61 -0
- package/dist/environment/generated-application/bootstrap-skill.d.ts +16 -0
- package/dist/environment/generated-application/bootstrap-skill.js +328 -0
- package/dist/environment/generated-application/check.d.ts +13 -0
- package/dist/environment/generated-application/check.js +191 -0
- package/dist/environment/generated-application/custom-surface.d.ts +26 -0
- package/dist/environment/generated-application/custom-surface.js +289 -0
- package/dist/environment/generated-application/prepare.d.ts +29 -0
- package/dist/environment/generated-application/prepare.js +278 -0
- package/dist/environment/generated-application/publication.d.ts +33 -0
- package/dist/environment/generated-application/publication.js +547 -0
- package/dist/environment/generated-application/shared.d.ts +492 -0
- package/dist/environment/generated-application/shared.js +354 -0
- package/dist/environment/generated-application/surface-observation.d.ts +4 -0
- package/dist/environment/generated-application/surface-observation.js +69 -0
- package/dist/environment/generated-application/surface-outputs.d.ts +71 -0
- package/dist/environment/generated-application/surface-outputs.js +400 -0
- package/dist/environment/generated-application/surfaces.d.ts +3 -0
- package/dist/environment/generated-application/surfaces.js +704 -0
- package/dist/environment/generated-application/sync.d.ts +6 -0
- package/dist/environment/generated-application/sync.js +124 -0
- package/dist/environment/git-observation.d.ts +202 -0
- package/dist/environment/git-observation.js +553 -0
- package/dist/environment/health-composition.d.ts +12 -0
- package/dist/environment/health-composition.js +645 -0
- package/dist/environment/host-observation.d.ts +56 -0
- package/dist/environment/host-observation.js +52 -0
- package/dist/environment/identity.d.ts +48 -0
- package/dist/environment/identity.js +85 -0
- package/dist/environment/init-application.d.ts +333 -0
- package/dist/environment/init-application.js +726 -0
- package/dist/environment/install-policy-observation.d.ts +71 -0
- package/dist/environment/install-policy-observation.js +284 -0
- package/dist/environment/install-policy.d.ts +48 -0
- package/dist/environment/install-policy.js +96 -0
- package/dist/environment/instance.d.ts +33 -0
- package/dist/environment/instance.js +122 -0
- package/dist/environment/instruction-pointer.d.ts +19 -0
- package/dist/environment/instruction-pointer.js +144 -0
- package/dist/environment/lifecycle-composition.d.ts +31 -0
- package/dist/environment/lifecycle-composition.js +742 -0
- package/dist/environment/lifecycle-stage.d.ts +120 -0
- package/dist/environment/lifecycle-stage.js +408 -0
- package/dist/environment/lifecycle.d.ts +75 -0
- package/dist/environment/lifecycle.js +354 -0
- package/dist/environment/logs.d.ts +132 -0
- package/dist/environment/logs.js +519 -0
- package/dist/environment/map-limit.d.ts +2 -0
- package/dist/environment/map-limit.js +13 -0
- package/dist/environment/mcp-observation.d.ts +9 -0
- package/dist/environment/mcp-observation.js +46 -0
- package/dist/environment/observations.d.ts +46 -0
- package/dist/environment/observations.js +346 -0
- package/dist/environment/operator-application.d.ts +79 -0
- package/dist/environment/operator-application.js +197 -0
- package/dist/environment/ports.d.ts +182 -0
- package/dist/environment/ports.js +1205 -0
- package/dist/environment/posture-observation.d.ts +68 -0
- package/dist/environment/posture-observation.js +253 -0
- package/dist/environment/presence.d.ts +4 -0
- package/dist/environment/presence.js +26 -0
- package/dist/environment/read-composition.d.ts +32 -0
- package/dist/environment/read-composition.js +397 -0
- package/dist/environment/readiness-composition.d.ts +57 -0
- package/dist/environment/readiness-composition.js +151 -0
- package/dist/environment/reclaim.d.ts +370 -0
- package/dist/environment/reclaim.js +1940 -0
- package/dist/environment/repository-identity.d.ts +13 -0
- package/dist/environment/repository-identity.js +108 -0
- package/dist/environment/runtime-measurement-record.d.ts +38 -0
- package/dist/environment/runtime-measurement-record.js +111 -0
- package/dist/environment/runtime-measurement.d.ts +27 -0
- package/dist/environment/runtime-measurement.js +224 -0
- package/dist/environment/runtime-probe-residue.d.ts +43 -0
- package/dist/environment/runtime-probe-residue.js +148 -0
- package/dist/environment/runtime-probe.d.ts +72 -0
- package/dist/environment/runtime-probe.js +725 -0
- package/dist/environment/runtime.d.ts +551 -0
- package/dist/environment/runtime.js +2405 -0
- package/dist/environment/seed.d.ts +16 -0
- package/dist/environment/seed.js +43 -0
- package/dist/environment/selftest-application.d.ts +86 -0
- package/dist/environment/selftest-application.js +713 -0
- package/dist/environment/sensitive.d.ts +3 -0
- package/dist/environment/sensitive.js +48 -0
- package/dist/environment/served-checkout-grants.d.ts +53 -0
- package/dist/environment/served-checkout-grants.js +182 -0
- package/dist/environment/setup-observation.d.ts +62 -0
- package/dist/environment/setup-observation.js +1473 -0
- package/dist/environment/setup.d.ts +43 -0
- package/dist/environment/setup.js +176 -0
- package/dist/environment/sibling-checkouts.d.ts +119 -0
- package/dist/environment/sibling-checkouts.js +254 -0
- package/dist/environment/sibling-instructions.d.ts +33 -0
- package/dist/environment/sibling-instructions.js +224 -0
- package/dist/environment/sibling-observation.d.ts +27 -0
- package/dist/environment/sibling-observation.js +45 -0
- package/dist/environment/sibling-pull.d.ts +23 -0
- package/dist/environment/sibling-pull.js +95 -0
- package/dist/environment/sibling-registration.d.ts +45 -0
- package/dist/environment/sibling-registration.js +538 -0
- package/dist/environment/stack-inputs.d.ts +18 -0
- package/dist/environment/stack-inputs.js +210 -0
- package/dist/environment/stack-inventory-prune.d.ts +31 -0
- package/dist/environment/stack-inventory-prune.js +129 -0
- package/dist/environment/stack-inventory-report.d.ts +44 -0
- package/dist/environment/stack-inventory-report.js +78 -0
- package/dist/environment/stack-inventory.d.ts +94 -0
- package/dist/environment/stack-inventory.js +418 -0
- package/dist/environment/state.d.ts +410 -0
- package/dist/environment/state.js +2153 -0
- package/dist/environment/templates.d.ts +140 -0
- package/dist/environment/templates.js +685 -0
- package/dist/environment/tool-registration.d.ts +9 -0
- package/dist/environment/tool-registration.js +92 -0
- package/dist/environment/upgrade-application.d.ts +19 -0
- package/dist/environment/upgrade-application.js +175 -0
- package/dist/environment-exec/execute.d.ts +105 -0
- package/dist/environment-exec/execute.js +1179 -0
- package/dist/environment-exec/libexec-program.d.ts +6 -0
- package/dist/environment-exec/libexec-program.js +22 -0
- package/dist/environment-exec/verified-digest.d.ts +4 -0
- package/dist/environment-exec/verified-digest.js +16 -0
- package/dist/exact-keys.d.ts +7 -0
- package/dist/exact-keys.js +15 -0
- package/dist/fix-catalogue.d.ts +32 -0
- package/dist/fix-catalogue.js +60 -0
- package/dist/freshness.d.ts +29 -0
- package/dist/freshness.js +75 -0
- package/dist/generated-environment/adopt.d.ts +16 -0
- package/dist/generated-environment/adopt.js +271 -0
- package/dist/generated-environment/command.d.ts +47 -0
- package/dist/generated-environment/command.js +75 -0
- package/dist/generated-environment/transaction.d.ts +186 -0
- package/dist/generated-environment/transaction.js +1770 -0
- package/dist/grading/evaluate.d.ts +71 -0
- package/dist/grading/evaluate.js +403 -0
- package/dist/grading/grade.d.ts +33 -0
- package/dist/grading/grade.js +57 -0
- package/dist/guards/answer-confirmation.d.ts +41 -0
- package/dist/guards/answer-confirmation.js +109 -0
- package/dist/guards/evaluator.d.ts +130 -0
- package/dist/guards/evaluator.js +1258 -0
- package/dist/guards/harness-adapter.d.ts +17 -0
- package/dist/guards/harness-adapter.js +57 -0
- package/dist/guards/host.d.ts +8 -0
- package/dist/guards/host.js +10 -0
- package/dist/guards/invocation-parser.d.ts +66 -0
- package/dist/guards/invocation-parser.js +595 -0
- package/dist/guards/local-identity.d.ts +44 -0
- package/dist/guards/local-identity.js +129 -0
- package/dist/guards/policy-change.d.ts +43 -0
- package/dist/guards/policy-change.js +159 -0
- package/dist/guards/policy-pin.d.ts +13 -0
- package/dist/guards/policy-pin.js +177 -0
- package/dist/guards/protected-locations.d.ts +62 -0
- package/dist/guards/protected-locations.js +461 -0
- package/dist/guards/read-only.d.ts +37 -0
- package/dist/guards/read-only.js +315 -0
- package/dist/init/command.d.ts +41 -0
- package/dist/init/command.js +330 -0
- package/dist/init/derive.d.ts +53 -0
- package/dist/init/derive.js +819 -0
- package/dist/init/draft.d.ts +140 -0
- package/dist/init/draft.js +1228 -0
- package/dist/init/render.d.ts +47 -0
- package/dist/init/render.js +104 -0
- package/dist/init/scaffold.d.ts +53 -0
- package/dist/init/scaffold.js +121 -0
- package/dist/invocation.d.ts +13 -0
- package/dist/invocation.js +20 -0
- package/dist/package-metadata.d.ts +9 -0
- package/dist/package-metadata.js +19 -0
- package/dist/readiness.d.ts +53 -0
- package/dist/readiness.js +88 -0
- package/dist/references/named.d.ts +24 -0
- package/dist/references/named.js +27 -0
- package/dist/refusal.d.ts +15 -0
- package/dist/refusal.js +7 -0
- package/dist/registry-derivation.d.ts +31 -0
- package/dist/registry-derivation.js +32 -0
- package/dist/registry-resolve/command.d.ts +47 -0
- package/dist/registry-resolve/command.js +226 -0
- package/dist/registry-resolve/registry.d.ts +68 -0
- package/dist/registry-resolve/registry.js +292 -0
- package/dist/registry-resolve/render-shell.d.ts +18 -0
- package/dist/registry-resolve/render-shell.js +36 -0
- package/dist/repair.d.ts +29 -0
- package/dist/repair.js +8 -0
- package/dist/repository-path.d.ts +9 -0
- package/dist/repository-path.js +16 -0
- package/dist/schema-json.d.ts +1 -0
- package/dist/schema-json.js +177 -0
- package/dist/schema.d.ts +1289 -0
- package/dist/schema.js +985 -0
- package/dist/setup/command.d.ts +4 -0
- package/dist/setup/command.js +4 -0
- package/dist/sha256.d.ts +1 -0
- package/dist/sha256.js +4 -0
- package/dist/surfaces/adoption.d.ts +41 -0
- package/dist/surfaces/adoption.js +217 -0
- package/dist/surfaces/consumer-instructions.d.ts +20 -0
- package/dist/surfaces/consumer-instructions.js +43 -0
- package/dist/surfaces/contract.d.ts +42 -0
- package/dist/surfaces/contract.js +169 -0
- package/dist/surfaces/core-declarations.d.ts +24 -0
- package/dist/surfaces/core-declarations.js +79 -0
- package/dist/surfaces/development-markers.d.ts +1 -0
- package/dist/surfaces/development-markers.js +18 -0
- package/dist/surfaces/generator-adapter.d.ts +71 -0
- package/dist/surfaces/generator-adapter.js +809 -0
- package/dist/surfaces/harness-registry.d.ts +260 -0
- package/dist/surfaces/harness-registry.js +146 -0
- package/dist/surfaces/mcp.d.ts +145 -0
- package/dist/surfaces/mcp.js +349 -0
- package/dist/surfaces/merge.d.ts +30 -0
- package/dist/surfaces/merge.js +105 -0
- package/dist/surfaces/ownership.d.ts +190 -0
- package/dist/surfaces/ownership.js +795 -0
- package/dist/surfaces/projection.d.ts +136 -0
- package/dist/surfaces/projection.js +716 -0
- package/dist/surfaces/render.d.ts +79 -0
- package/dist/surfaces/render.js +636 -0
- package/dist/surfaces/restrictions.d.ts +130 -0
- package/dist/surfaces/restrictions.js +447 -0
- package/dist/surfaces/selftest.d.ts +162 -0
- package/dist/surfaces/selftest.js +393 -0
- package/dist/surfaces/skill-contract.d.ts +85 -0
- package/dist/surfaces/skill-contract.js +449 -0
- package/dist/surfaces/sync.d.ts +57 -0
- package/dist/surfaces/sync.js +164 -0
- package/dist/team-metadata.d.ts +41 -0
- package/dist/team-metadata.js +513 -0
- package/dist/testing/gates.d.ts +91 -0
- package/dist/testing/gates.js +182 -0
- package/dist/testing/hooks.d.ts +59 -0
- package/dist/testing/hooks.js +139 -0
- package/dist/testing/test-protection.d.ts +34 -0
- package/dist/testing/test-protection.js +137 -0
- package/dist/testing/verdict.d.ts +29 -0
- package/dist/testing/verdict.js +62 -0
- package/dist/testing/weakening.d.ts +15 -0
- package/dist/testing/weakening.js +30 -0
- package/dist/work-orders/application-closure.d.ts +7 -0
- package/dist/work-orders/application-closure.js +76 -0
- package/dist/work-orders/application-context.d.ts +162 -0
- package/dist/work-orders/application-context.js +137 -0
- package/dist/work-orders/application-decisions.d.ts +27 -0
- package/dist/work-orders/application-decisions.js +121 -0
- package/dist/work-orders/application-grading.d.ts +11 -0
- package/dist/work-orders/application-grading.js +212 -0
- package/dist/work-orders/application.d.ts +6 -0
- package/dist/work-orders/application.js +223 -0
- package/dist/work-orders/composition.d.ts +101 -0
- package/dist/work-orders/composition.js +1202 -0
- package/dist/work-orders/contract.d.ts +77 -0
- package/dist/work-orders/contract.js +140 -0
- package/dist/work-orders/decisions.d.ts +23 -0
- package/dist/work-orders/decisions.js +55 -0
- package/dist/work-orders/store.d.ts +207 -0
- package/dist/work-orders/store.js +291 -0
- package/docs/README.md +68 -0
- package/docs/architecture.md +136 -0
- package/docs/capability-matrix.md +58 -0
- package/docs/cli-reference.md +807 -0
- package/docs/command-list.md +62 -0
- package/docs/compose-patterns.md +99 -0
- package/docs/concepts.md +173 -0
- package/docs/configuration-essentials.md +177 -0
- package/docs/configuration-reference.md +636 -0
- package/docs/docs-check.md +76 -0
- package/docs/environment.md +948 -0
- package/docs/extending.md +43 -0
- package/docs/faq.md +113 -0
- package/docs/getting-started.md +692 -0
- package/docs/harness-surfaces.md +500 -0
- package/docs/joining-a-team.md +76 -0
- package/docs/release-policy.md +49 -0
- package/docs/safety-and-autonomy.md +463 -0
- package/docs/troubleshooting.md +382 -0
- package/docs/tutorial.md +171 -0
- package/docs/work-and-browser.md +420 -0
- package/libexec/browser-operation.cjs +270 -0
- package/libexec/fence-marker.cjs +101 -0
- package/libexec/fence-marker.d.cts +24 -0
- package/libexec/fenced-group-runner.cjs +77 -0
- package/libexec/fenced-supervisor.cjs +137 -0
- package/libexec/generated-filesystem.cjs +731 -0
- package/libexec/install-filesystem.cjs +225 -0
- package/libexec/rulesync-generator.NOTICE.md +1112 -0
- package/libexec/rulesync-generator.cjs +743 -0
- package/libexec/surface-generator-worker.cjs +266 -0
- package/libexec/surface-output-reader.cjs +99 -0
- package/libexec/surface-scratch-cleanup.cjs +14 -0
- package/libexec/validate-harness-evidence.d.mts +183 -0
- package/libexec/validate-harness-evidence.mjs +1312 -0
- package/package.json +74 -4
- package/surfaces/README.md +33 -0
- package/surfaces/agents/evaluator.agent.md +76 -0
- package/surfaces/guards/bash-guard.sh +48 -0
- package/surfaces/guards/claude.adapter.json +25 -0
- package/surfaces/guards/codex.adapter.json +24 -0
- package/surfaces/guards/opencode.adapter.json +25 -0
- package/surfaces/references/browser.md +63 -0
- package/surfaces/references/test-data-and-personas.md +84 -0
- package/surfaces/references/testing-tiers.md +11 -0
- package/surfaces/skills/cockpit-browser.skill.md +59 -0
- package/surfaces/skills/cockpit-explain.skill.md +32 -0
- package/surfaces/skills/cockpit-fix.skill.md +37 -0
- package/surfaces/skills/cockpit-setup.skill.md +39 -0
- package/surfaces/skills/cockpit-work.skill.md +34 -0
- package/surfaces/skills/collection.json +5 -0
- package/surfaces/skills/procedures/explain.md +66 -0
- package/surfaces/skills/procedures/fix.md +95 -0
- package/surfaces/skills/procedures/setup.md +452 -0
- package/surfaces/skills/procedures/work.md +134 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { lstat } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
3
|
+
import { isProxy } from 'node:util/types';
|
|
4
|
+
import { parseDocument } from 'yaml';
|
|
5
|
+
import { consumeWorkEnvironmentConfigProjection, loadCockpitConfig, projectWorkEnvironmentConfig } from '../../config/load.js';
|
|
6
|
+
import { deriveRegistry } from '../../registry-derivation.js';
|
|
7
|
+
import { SURFACE_TARGETS } from '../../surfaces/contract.js';
|
|
8
|
+
import { parseOwnershipManifest } from '../../surfaces/ownership.js';
|
|
9
|
+
import { nodeAuthority, readAnchoredFile, readAnchoredConfigSource } from '../../generated-environment/transaction.js';
|
|
10
|
+
import { ENVIRONMENT_CODES, hasErrorCode } from '../contract.js';
|
|
11
|
+
import { checkoutId, cockpitId, publicationCockpitId, stackId } from '../identity.js';
|
|
12
|
+
import { composePublishedPorts, variableName } from '../compose-topology.js';
|
|
13
|
+
import { COMPOSE_OWNERSHIP_FILE, renderComposeOwnership } from '../compose-ownership.js';
|
|
14
|
+
import { earlierNameRefusalMessage, findStackUnderEarlierName } from '../lifecycle-stage.js';
|
|
15
|
+
import { selectStateRoot } from '../state.js';
|
|
16
|
+
import { observeGeneratedCheckoutIdentity } from '../setup-observation.js';
|
|
17
|
+
import { exactKeys } from '../../exact-keys.js';
|
|
18
|
+
import { refusalOutcome as refuse } from '../../refusal.js';
|
|
19
|
+
import { COMPOSE_SOURCE_BYTES, MAX_OWNERSHIP_BYTES, OWNERSHIP_PATH, authenticateSiblingRoots, compareCodeUnits, confined, ownRecord, sha256, } from './shared.js';
|
|
20
|
+
export function commandInput(input) {
|
|
21
|
+
try {
|
|
22
|
+
if (input === null || typeof input !== 'object' || Array.isArray(input) || isProxy(input))
|
|
23
|
+
return undefined;
|
|
24
|
+
const descriptors = Object.getOwnPropertyDescriptors(input);
|
|
25
|
+
const keys = Reflect.ownKeys(descriptors);
|
|
26
|
+
if (keys.some((key) => typeof key !== 'string' || key !== 'configPath')
|
|
27
|
+
|| !Object.hasOwn(descriptors, 'configPath') || !('value' in descriptors.configPath))
|
|
28
|
+
return undefined;
|
|
29
|
+
const configPath = descriptors.configPath.value;
|
|
30
|
+
if (typeof configPath !== 'string' || configPath.length === 0 || configPath.includes('\0'))
|
|
31
|
+
return undefined;
|
|
32
|
+
return { configPath };
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// a guard over caller-supplied values; a throwing accessor or proxy trap is malformed input the caller refuses.
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function syncCommandInput(input) {
|
|
40
|
+
try {
|
|
41
|
+
if (input === null || typeof input !== 'object' || Array.isArray(input) || isProxy(input))
|
|
42
|
+
return undefined;
|
|
43
|
+
const descriptors = Object.getOwnPropertyDescriptors(input);
|
|
44
|
+
const keys = Reflect.ownKeys(descriptors);
|
|
45
|
+
if (keys.some((key) => typeof key !== 'string' || key !== 'configPath' && key !== 'dryRun' && key !== 'bootstrapState')
|
|
46
|
+
|| !Object.hasOwn(descriptors, 'configPath') || !('value' in descriptors.configPath))
|
|
47
|
+
return undefined;
|
|
48
|
+
const configPath = descriptors.configPath.value;
|
|
49
|
+
const dryRun = Object.hasOwn(descriptors, 'dryRun') && 'value' in descriptors.dryRun ? descriptors.dryRun.value : false;
|
|
50
|
+
if (typeof configPath !== 'string' || configPath.length === 0 || configPath.includes('\0') || typeof dryRun !== 'boolean')
|
|
51
|
+
return undefined;
|
|
52
|
+
const bootstrapState = Object.hasOwn(descriptors, 'bootstrapState') && 'value' in descriptors.bootstrapState
|
|
53
|
+
? descriptors.bootstrapState.value : undefined;
|
|
54
|
+
if (bootstrapState !== undefined) {
|
|
55
|
+
const state = ownRecord(bootstrapState);
|
|
56
|
+
if (!state || !exactKeys(state, ['publication', 'address']))
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
return { configPath, dryRun, ...(bootstrapState === undefined ? {} : { bootstrapState }) };
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// a guard over caller-supplied values; a throwing accessor or proxy trap is malformed input the caller refuses.
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export async function safePath(root, path, allowMissing) {
|
|
67
|
+
const target = confined(root, path);
|
|
68
|
+
if (!target)
|
|
69
|
+
return undefined;
|
|
70
|
+
const parts = relative(root, target).split(sep);
|
|
71
|
+
let current = root;
|
|
72
|
+
for (const [index, part] of parts.entries()) {
|
|
73
|
+
current = resolve(current, part);
|
|
74
|
+
try {
|
|
75
|
+
const entry = await lstat(current);
|
|
76
|
+
if (entry.isSymbolicLink() || index < parts.length - 1 && !entry.isDirectory()
|
|
77
|
+
|| index === parts.length - 1 && !entry.isFile())
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
if (!hasErrorCode(error, 'ENOENT'))
|
|
82
|
+
return undefined;
|
|
83
|
+
if (!allowMissing && index === parts.length - 1)
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return target;
|
|
88
|
+
}
|
|
89
|
+
export async function readOwnership(prepared, adapters) {
|
|
90
|
+
const read = await readAnchoredFile(prepared.root, OWNERSHIP_PATH, MAX_OWNERSHIP_BYTES, prepared.node, adapters);
|
|
91
|
+
if (read.kind === 'missing')
|
|
92
|
+
return { kind: 'missing' };
|
|
93
|
+
if (read.kind !== 'complete')
|
|
94
|
+
return { kind: 'invalid' };
|
|
95
|
+
try {
|
|
96
|
+
const bytes = new TextDecoder('utf-8', { fatal: true }).decode(read.bytes);
|
|
97
|
+
const parsed = parseOwnershipManifest(bytes, { root: prepared.root, cockpitId: prepared.cockpitId, configPath: prepared.configPath });
|
|
98
|
+
return parsed.kind === 'complete' ? { kind: 'complete', manifest: parsed.manifest, bytes, sha256: read.sha256, identity: read.identity } : parsed;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// invalid ownership bytes are reported as invalid.
|
|
102
|
+
return { kind: 'invalid' };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export async function expectedOutputExists(prepared) {
|
|
106
|
+
for (const file of prepared.owned) {
|
|
107
|
+
if (await safePath(prepared.root, file.path, false))
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
// A ledger recorded under another name means `cockpit.name` was renamed. Publishing under the new
|
|
113
|
+
// name is safe for the files, but a stack still recorded under the old one would be left where
|
|
114
|
+
// down cannot reach it, so the rename waits until that stack is down.
|
|
115
|
+
export async function renamedStackRefusal(prepared) {
|
|
116
|
+
const checkout = prepared.runtimeCheckout;
|
|
117
|
+
if (!checkout || process.platform !== 'darwin' && process.platform !== 'linux')
|
|
118
|
+
return undefined;
|
|
119
|
+
const namespace = await selectStateRoot({ platform: process.platform, home: process.env.HOME,
|
|
120
|
+
xdgStateHome: process.env.XDG_STATE_HOME,
|
|
121
|
+
checkoutRoots: [checkout.currentCheckoutPath, checkout.mainCheckoutPath], cockpitId: checkout.cockpitId });
|
|
122
|
+
if (namespace.kind !== 'complete')
|
|
123
|
+
return refuse(ENVIRONMENT_CODES.STATE_ROOT_UNAVAILABLE, `cannot tell whether a stack started before cockpit.name was renamed is still recorded: ${'message' in namespace ? namespace.message : 'the state root is missing'}; nothing was written`, prepared.configPath);
|
|
124
|
+
const earlier = await findStackUnderEarlierName({ namespace: namespace.value, cockpitId: checkout.cockpitId, checkoutId: checkout.checkoutId });
|
|
125
|
+
if (earlier.kind === 'refusal')
|
|
126
|
+
return refuse(earlier.code, `${earlier.message}; nothing was written`, earlier.target);
|
|
127
|
+
return earlier.name === undefined ? undefined
|
|
128
|
+
: refuse(ENVIRONMENT_CODES.STACK_RECORDED_UNDER_EARLIER_NAME, earlierNameRefusalMessage(prepared.configPath, earlier.name), prepared.configPath);
|
|
129
|
+
}
|
|
130
|
+
const LOOPBACK_HOST_IPS = new Set(['127.0.0.1', 'localhost', '::1', '[::1]']);
|
|
131
|
+
/** Why no single Compose service publishes the endpoint's port on loopback, or undefined when exactly one does. */
|
|
132
|
+
export function browserEndpointUnpublished(endpoint, sources, bases) {
|
|
133
|
+
const port = Number(new URL(endpoint).port || 80);
|
|
134
|
+
const publishers = [];
|
|
135
|
+
for (const { reference, source } of sources) {
|
|
136
|
+
const document = parseDocument(source);
|
|
137
|
+
const services = document.errors.length === 0 ? document.toJS()?.services : undefined;
|
|
138
|
+
for (const [id, service] of Object.entries(services ?? {})) {
|
|
139
|
+
const ports = composePublishedPorts(service?.ports);
|
|
140
|
+
if (!ports)
|
|
141
|
+
return `${reference} service ${id} has a ports entry cockpit cannot read, so it cannot tell whether it publishes browser.endpoint`;
|
|
142
|
+
if (ports.some(published => {
|
|
143
|
+
if (published.hostIp === null || !LOOPBACK_HOST_IPS.has(published.hostIp) || published.published === null)
|
|
144
|
+
return false;
|
|
145
|
+
const name = variableName(published.published);
|
|
146
|
+
return (name === undefined ? Number(published.published) : bases[name]) === port;
|
|
147
|
+
}))
|
|
148
|
+
publishers.push(`${reference}:${id}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return publishers.length === 1 ? undefined
|
|
152
|
+
: publishers.length === 0 ? `browser.endpoint port ${port} is not published on loopback by any service in environment.compose_files`
|
|
153
|
+
: `browser.endpoint port ${port} is published on loopback by more than one service (${publishers.join(', ')})`;
|
|
154
|
+
}
|
|
155
|
+
export async function prepare(input, adapters) {
|
|
156
|
+
const request = commandInput(input);
|
|
157
|
+
if (!request)
|
|
158
|
+
return refuse('GENERATED_INPUT_INVALID', 'generated environment command input is invalid', 'generated-environment');
|
|
159
|
+
const loaded = await loadCockpitConfig(request.configPath);
|
|
160
|
+
if (loaded.kind !== 'complete')
|
|
161
|
+
return {
|
|
162
|
+
kind: 'refusal', artifact: null, destination: null, result: null, status: 2,
|
|
163
|
+
diagnostics: [...loaded.diagnostics],
|
|
164
|
+
};
|
|
165
|
+
const workProjection = projectWorkEnvironmentConfig(loaded.result);
|
|
166
|
+
const workEnvironment = workProjection && consumeWorkEnvironmentConfigProjection(workProjection);
|
|
167
|
+
if (!workEnvironment || workEnvironment.source.path !== loaded.result.source.path
|
|
168
|
+
|| workEnvironment.source.sha256 !== loaded.result.source.sha256) {
|
|
169
|
+
return refuse('GENERATED_RENDER_UNAUTHENTICATED', 'the work environment configuration could not be consumed', loaded.result.source.path);
|
|
170
|
+
}
|
|
171
|
+
const derived = deriveRegistry(loaded.result.config);
|
|
172
|
+
if (derived.kind !== 'complete')
|
|
173
|
+
return refuse(derived.code, derived.message, loaded.result.source.path);
|
|
174
|
+
const config = derived.result.config;
|
|
175
|
+
const root = dirname(loaded.result.source.path);
|
|
176
|
+
const authenticatedSiblings = await authenticateSiblingRoots(root, derived.result.config, loaded.result.source.path);
|
|
177
|
+
if (authenticatedSiblings.kind === 'refusal')
|
|
178
|
+
return refuse(authenticatedSiblings.code ?? 'GENERATED_SIBLING_ROOT_INVALID', authenticatedSiblings.reason, authenticatedSiblings.target ?? 'sibling', authenticatedSiblings.fix);
|
|
179
|
+
const siblingRoots = authenticatedSiblings.roots;
|
|
180
|
+
const runtimeCheckout = workEnvironment.browser || config.environment.compose_files.length > 0
|
|
181
|
+
? await observeGeneratedCheckoutIdentity({ source: loaded.result.source, cockpitName: config.cockpit.name,
|
|
182
|
+
env: process.env }) : undefined;
|
|
183
|
+
if (runtimeCheckout?.state === 'failed')
|
|
184
|
+
return refuse('GENERATED_INPUT_INVALID', `generated checkout identity is unavailable: ${runtimeCheckout.reason}`, loaded.result.source.path, 'restore the configuration checkout and Git installation, then run npx --no cockpit sync --config <your cockpit.toml>');
|
|
185
|
+
const currentCockpit = runtimeCheckout?.cockpitId ?? cockpitId({ name: config.cockpit.name, mainCheckoutPath: root });
|
|
186
|
+
const publishedCockpit = publicationCockpitId({ name: config.cockpit.name });
|
|
187
|
+
const currentCheckout = runtimeCheckout?.checkoutId ?? checkoutId({ checkoutPath: root });
|
|
188
|
+
const currentStack = stackId({ cockpitId: currentCockpit, checkoutId: currentCheckout, variant: { kind: 'shared' } });
|
|
189
|
+
// Derived from the runtime declarations, not the file bytes, so rewording a purpose or a guard
|
|
190
|
+
// keeps the running stack's identity.
|
|
191
|
+
const generation = sha256(`generated-environment\0${loaded.result.runtimeSha256}`);
|
|
192
|
+
const node = await nodeAuthority();
|
|
193
|
+
if (!node)
|
|
194
|
+
return refuse('GENERATED_EXECUTABLE_UNAVAILABLE', 'the current Node executable could not be authenticated', process.execPath);
|
|
195
|
+
let composeOwnership;
|
|
196
|
+
const composeSources = [];
|
|
197
|
+
const sources = [];
|
|
198
|
+
if (config.environment.compose_files.length > 0) {
|
|
199
|
+
for (const reference of config.environment.compose_files) {
|
|
200
|
+
const read = await readAnchoredFile(root, reference, COMPOSE_SOURCE_BYTES, node, adapters);
|
|
201
|
+
if (read.kind !== 'complete')
|
|
202
|
+
return refuse('GENERATED_PATH_UNSAFE', 'a declared Compose file is missing, unreadable, or crosses a symbolic-link boundary', reference);
|
|
203
|
+
sources.push({ reference, source: read.bytes.toString('utf8') });
|
|
204
|
+
composeSources.push({ path: reference, sha256: read.sha256, identity: read.identity });
|
|
205
|
+
}
|
|
206
|
+
const ownership = renderComposeOwnership({ sources, stackId: currentStack, cockpitId: currentCockpit,
|
|
207
|
+
configSha256: loaded.result.runtimeSha256, resettableVolumes: config.environment.resettable_volumes });
|
|
208
|
+
if (ownership.kind !== 'complete')
|
|
209
|
+
return refuse('GENERATED_DECLARATION_INVALID', `the ownership override cannot be rendered from environment.compose_files: ${ownership.reason}`, ownership.target);
|
|
210
|
+
composeOwnership = { path: COMPOSE_OWNERSHIP_FILE, bytes: ownership.bytes, sha256: sha256(ownership.bytes) };
|
|
211
|
+
}
|
|
212
|
+
// A browser endpoint is a server the project's own Compose files run, so it must be reachable
|
|
213
|
+
// only from this machine, by exactly the service that publishes its port.
|
|
214
|
+
const endpoint = workEnvironment.browser?.endpoint;
|
|
215
|
+
const unpublished = endpoint === undefined ? undefined : browserEndpointUnpublished(endpoint, sources, config.ports.bases);
|
|
216
|
+
if (unpublished)
|
|
217
|
+
return refuse('GENERATED_BROWSER_ENDPOINT_UNPUBLISHED', unpublished, 'browser', 'publish the endpoint port from exactly one service in environment.compose_files as "127.0.0.1:${VAR}:<container port>" with VAR under [ports.bases] set to the endpoint port, or remove browser.endpoint to drive a local browser, then run npx --no cockpit sync --config <your cockpit.toml>');
|
|
218
|
+
const generated = composeOwnership ? [composeOwnership] : [];
|
|
219
|
+
// The anchored read of the configuration file pins the publication root's identity for the whole sync.
|
|
220
|
+
const sourcePath = relative(root, loaded.result.source.path);
|
|
221
|
+
const sourceTarget = await safePath(root, sourcePath, false);
|
|
222
|
+
if (!sourceTarget)
|
|
223
|
+
return refuse('GENERATED_CONFIG_SOURCE_UNAVAILABLE', 'the cockpit configuration file is missing or crosses a symbolic-link boundary', sourcePath);
|
|
224
|
+
const source = await readAnchoredConfigSource(root, sourcePath, node, adapters);
|
|
225
|
+
if (!source) {
|
|
226
|
+
return refuse('GENERATED_CONFIG_SOURCE_UNAVAILABLE', 'the cockpit configuration file is unreadable', sourcePath);
|
|
227
|
+
}
|
|
228
|
+
const owned = [...generated].sort((left, right) => compareCodeUnits(left.path, right.path));
|
|
229
|
+
if (new Set(owned.map(({ path }) => path)).size !== owned.length
|
|
230
|
+
|| owned.some(({ path }) => path === OWNERSHIP_PATH)
|
|
231
|
+
|| owned.some(({ path }) => [loaded.result.source.path, sourceTarget].includes(resolve(root, path)))) {
|
|
232
|
+
return refuse('GENERATED_PATH_DUPLICATE', 'generated ownership contains a duplicate or input path', 'generated-environment');
|
|
233
|
+
}
|
|
234
|
+
for (const file of owned) {
|
|
235
|
+
if (!await safePath(root, file.path, true)) {
|
|
236
|
+
return refuse('GENERATED_PATH_UNSAFE', 'generated destination crosses an existing symbolic-link or non-directory boundary', file.path);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
const producedAt = (adapters.now ?? (() => new Date().toISOString()))();
|
|
240
|
+
const now = producedAt.slice(0, 10);
|
|
241
|
+
return {
|
|
242
|
+
root,
|
|
243
|
+
cockpitId: publishedCockpit,
|
|
244
|
+
stackId: currentStack,
|
|
245
|
+
...(runtimeCheckout ? { runtimeCheckout } : {}),
|
|
246
|
+
configPath: loaded.result.source.path,
|
|
247
|
+
sourceSha256: loaded.result.source.sha256,
|
|
248
|
+
runtimeSha256: loaded.result.runtimeSha256,
|
|
249
|
+
configSource: { path: sourcePath, sha256: source.sha256 },
|
|
250
|
+
configSourceIdentity: source.identity,
|
|
251
|
+
generation,
|
|
252
|
+
generated,
|
|
253
|
+
owned,
|
|
254
|
+
surfaces: [],
|
|
255
|
+
compactSurfacePaths: new Set(),
|
|
256
|
+
configuredHarnesses: [...SURFACE_TARGETS],
|
|
257
|
+
activeSurfaceOverrides: [],
|
|
258
|
+
changedOverrideOriginals: [],
|
|
259
|
+
composeSources,
|
|
260
|
+
guideSources: { requests: [], observations: [], missing: [] },
|
|
261
|
+
openCodeGrantRoots: [],
|
|
262
|
+
sourceEvidence: [],
|
|
263
|
+
sourceRoots: [],
|
|
264
|
+
customSources: [],
|
|
265
|
+
adoptedSources: [],
|
|
266
|
+
surfaceAssets: [],
|
|
267
|
+
warnings: [],
|
|
268
|
+
unapprovedMcpServers: [],
|
|
269
|
+
mcpTransportGaps: [],
|
|
270
|
+
mcpServers: [],
|
|
271
|
+
registry: derived.result,
|
|
272
|
+
siblingRoots,
|
|
273
|
+
workEnvironment,
|
|
274
|
+
node,
|
|
275
|
+
now,
|
|
276
|
+
producedAt,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type GeneratedPathClassificationResult, type OwnershipManifest, type SurfaceDiagnostic, type SurfacePriorOwnedEntry } from '../../surfaces/ownership.js';
|
|
2
|
+
import { type SurfaceObservedEntry, type SurfaceChangePlanResult } from '../../surfaces/sync.js';
|
|
3
|
+
import { type AnchoredEntry, type AnchoredBatchReadResult, type PublicationPlan } from '../../generated-environment/transaction.js';
|
|
4
|
+
import { type GeneratedEnvironmentCommandAdapters, type GeneratedEnvironmentSyncInput, type PreparedEnvironment, type RefusalOutcome } from './shared.js';
|
|
5
|
+
import { type OwnershipState } from './prepare.js';
|
|
6
|
+
import { type UnfinishedInit } from './bootstrap-skill.js';
|
|
7
|
+
export declare function inputSourcesCurrent(prepared: PreparedEnvironment, adapters: GeneratedEnvironmentCommandAdapters, deadline?: number): Promise<boolean>;
|
|
8
|
+
export declare function ownedInputOverlap(prepared: PreparedEnvironment, prior: readonly Readonly<{
|
|
9
|
+
path: string;
|
|
10
|
+
}>[]): Promise<Readonly<{
|
|
11
|
+
kind: 'complete';
|
|
12
|
+
path?: string;
|
|
13
|
+
}> | Readonly<{
|
|
14
|
+
kind: 'invalid';
|
|
15
|
+
}>>;
|
|
16
|
+
export declare function observeSurfaceState(prepared: PreparedEnvironment, prior: readonly SurfacePriorOwnedEntry[], adapters: GeneratedEnvironmentCommandAdapters): Promise<{
|
|
17
|
+
observed: readonly SurfaceObservedEntry[];
|
|
18
|
+
raw: ReadonlyMap<string, AnchoredEntry>;
|
|
19
|
+
opaque: ReadonlySet<string>;
|
|
20
|
+
} | undefined>;
|
|
21
|
+
export declare function classifyOwnedState(prepared: PreparedEnvironment, manifest: OwnershipManifest | undefined, raw: ReadonlyMap<string, AnchoredBatchReadResult>): Promise<GeneratedPathClassificationResult>;
|
|
22
|
+
export declare function planObservedSurfaces(prepared: PreparedEnvironment, priorOwned: readonly SurfacePriorOwnedEntry[], state: NonNullable<Awaited<ReturnType<typeof observeSurfaceState>>>): SurfaceChangePlanResult;
|
|
23
|
+
/** A hand edit to a merged adopted file belongs in its adopted copy; say so where the conflict is reported. */
|
|
24
|
+
export declare function surfacePlanRefusal(prepared: PreparedEnvironment, diagnostic: SurfaceDiagnostic, unfinishedInit?: UnfinishedInit): RefusalOutcome;
|
|
25
|
+
export declare function preparePublication(input: GeneratedEnvironmentSyncInput, adapterOverrides?: Partial<GeneratedEnvironmentCommandAdapters>, seed?: PreparedEnvironment, knownOwnership?: OwnershipState): Promise<RefusalOutcome | Readonly<{
|
|
26
|
+
prepared: PreparedEnvironment;
|
|
27
|
+
ownership: OwnershipState;
|
|
28
|
+
plan: PublicationPlan;
|
|
29
|
+
}> | Readonly<{
|
|
30
|
+
prepared: PreparedEnvironment;
|
|
31
|
+
ownership: OwnershipState;
|
|
32
|
+
refusal: RefusalOutcome;
|
|
33
|
+
}>>;
|