@platforma-sdk/block-tools 2.10.14 → 2.10.16
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/dist/cli.js +23 -2
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +1944 -100
- package/dist/cli.mjs.map +1 -1
- package/dist/cmd/index.d.ts +10 -4
- package/dist/cmd/structure/check.d.ts +10 -0
- package/dist/cmd/structure/init.d.ts +18 -0
- package/dist/cmd/structure/refresh.d.ts +11 -0
- package/dist/cmd/update-deps.d.ts +7 -0
- package/dist/structure/cli/run-structure.d.ts +19 -0
- package/dist/structure/engine/api.d.ts +55 -0
- package/dist/structure/engine/builders.d.ts +95 -0
- package/dist/structure/engine/content-rules.d.ts +148 -0
- package/dist/structure/engine/ctx.d.ts +34 -0
- package/dist/structure/engine/discovery-fs.d.ts +22 -0
- package/dist/structure/engine/discovery.d.ts +39 -0
- package/dist/structure/engine/flatten.d.ts +3 -0
- package/dist/structure/engine/fs/api.d.ts +27 -0
- package/dist/structure/engine/fs/memory.d.ts +16 -0
- package/dist/structure/engine/fs/node.d.ts +14 -0
- package/dist/structure/engine/glob.d.ts +4 -0
- package/dist/structure/engine/ir.d.ts +124 -0
- package/dist/structure/engine/parsers/json.d.ts +37 -0
- package/dist/structure/engine/parsers/lines.d.ts +9 -0
- package/dist/structure/engine/parsers/yaml.d.ts +18 -0
- package/dist/structure/engine/registry-client.d.ts +34 -0
- package/dist/structure/engine/runner.d.ts +45 -0
- package/dist/structure/engine/templates.d.ts +30 -0
- package/dist/structure/engine/testing.d.ts +34 -0
- package/dist/structure/engine/version.d.ts +18 -0
- package/dist/structure/init-block-constructor.d.ts +32 -0
- package/dist/structure/rules/block-package-json.d.ts +9 -0
- package/dist/structure/rules/block.d.ts +1 -0
- package/dist/structure/rules/migrations.d.ts +2 -0
- package/dist/structure/rules/model-package-json.d.ts +3 -0
- package/dist/structure/rules/model.d.ts +1 -0
- package/dist/structure/rules/root-catalog-bump.d.ts +1 -0
- package/dist/structure/rules/root-gitignore.d.ts +2 -0
- package/dist/structure/rules/root-package-json.d.ts +3 -0
- package/dist/structure/rules/root-pnpm-workspace.d.ts +15 -0
- package/dist/structure/rules/root.d.ts +1 -0
- package/dist/structure/rules/shared/colocated-tests.d.ts +2 -0
- package/dist/structure/rules/shared/key-order.d.ts +1 -0
- package/dist/structure/rules/software-package-json.d.ts +3 -0
- package/dist/structure/rules/software.d.ts +1 -0
- package/dist/structure/rules/test-package-json.d.ts +3 -0
- package/dist/structure/rules/test.d.ts +1 -0
- package/dist/structure/rules/ui-package-json.d.ts +3 -0
- package/dist/structure/rules/ui.d.ts +1 -0
- package/dist/structure/rules/workflow-package-json.d.ts +3 -0
- package/dist/structure/rules/workflow.d.ts +1 -0
- package/dist/structure/structure-definition.d.ts +1 -0
- package/package.json +9 -7
- package/src/cmd/index.ts +10 -4
- package/src/cmd/structure/check.ts +51 -0
- package/src/cmd/structure/init.ts +65 -0
- package/src/cmd/structure/refresh.ts +44 -0
- package/src/cmd/update-deps.ts +15 -3
- package/src/structure/__tests__/colocated-test-wiring.test.ts +107 -0
- package/src/structure/__tests__/floor-version.test.ts +52 -0
- package/src/structure/__tests__/init-catalog-resolution.test.ts +82 -0
- package/src/structure/__tests__/init-check-parity.test.ts +59 -0
- package/src/structure/__tests__/model-package-json.snapshot.test.ts +60 -0
- package/src/structure/__tests__/oxfmt-clean-init.test.ts +64 -0
- package/src/structure/__tests__/root-catalog-bump.test.ts +110 -0
- package/src/structure/__tests__/seed-disjointness.test.ts +79 -0
- package/src/structure/cli/run-structure.ts +89 -0
- package/src/structure/engine/__tests__/content-rules/active-state-guards.test.ts +61 -0
- package/src/structure/engine/__tests__/content-rules/catalog-pin.test.ts +46 -0
- package/src/structure/engine/__tests__/content-rules/enforce-alphabetical-order.test.ts +55 -0
- package/src/structure/engine/__tests__/content-rules/enforce-field-order.test.ts +73 -0
- package/src/structure/engine/__tests__/content-rules/ensure-catalog-absent.test.ts +29 -0
- package/src/structure/engine/__tests__/content-rules/ensure-catalog-latest.test.ts +70 -0
- package/src/structure/engine/__tests__/content-rules/ensure-dep.test.ts +63 -0
- package/src/structure/engine/__tests__/content-rules/ensure-deps-bulk.test.ts +46 -0
- package/src/structure/engine/__tests__/content-rules/ensure-field-entries.test.ts +35 -0
- package/src/structure/engine/__tests__/content-rules/ensure-field.test.ts +56 -0
- package/src/structure/engine/__tests__/content-rules/ensure-script.test.ts +39 -0
- package/src/structure/engine/__tests__/content-rules/ensure-workspace-scope-deps.test.ts +92 -0
- package/src/structure/engine/__tests__/content-rules/gitignore.test.ts +50 -0
- package/src/structure/engine/__tests__/content-rules/pin-catalog-to.test.ts +64 -0
- package/src/structure/engine/__tests__/content-rules/prune-keys.test.ts +59 -0
- package/src/structure/engine/__tests__/content-rules/registry-client.test.ts +116 -0
- package/src/structure/engine/__tests__/content-rules/remove-field.test.ts +49 -0
- package/src/structure/engine/__tests__/content-rules/require-field.test.ts +40 -0
- package/src/structure/engine/__tests__/content-rules/transform-at.test.ts +33 -0
- package/src/structure/engine/__tests__/content-rules/when-inner.test.ts +244 -0
- package/src/structure/engine/__tests__/content-rules/workspace-module-paths.test.ts +53 -0
- package/src/structure/engine/__tests__/discovery.test.ts +160 -0
- package/src/structure/engine/__tests__/fs-memory.test.ts +59 -0
- package/src/structure/engine/__tests__/glob.test.ts +43 -0
- package/src/structure/engine/__tests__/parsers-json.test.ts +189 -0
- package/src/structure/engine/__tests__/parsers-lines.test.ts +44 -0
- package/src/structure/engine/__tests__/parsers-yaml.test.ts +90 -0
- package/src/structure/engine/__tests__/recheck.test.ts +99 -0
- package/src/structure/engine/__tests__/registry-lookup.test.ts +49 -0
- package/src/structure/engine/__tests__/runner-when-inside-managed.test.ts +136 -0
- package/src/structure/engine/__tests__/runner.test.ts +136 -0
- package/src/structure/engine/__tests__/synthetic.test.ts +153 -0
- package/src/structure/engine/__tests__/version.test.ts +44 -0
- package/src/structure/engine/__tests__/when-files-exist.test.ts +89 -0
- package/src/structure/engine/api.ts +131 -0
- package/src/structure/engine/builders.ts +341 -0
- package/src/structure/engine/content-rules.ts +616 -0
- package/src/structure/engine/ctx.ts +94 -0
- package/src/structure/engine/discovery-fs.ts +209 -0
- package/src/structure/engine/discovery.ts +168 -0
- package/src/structure/engine/flatten.ts +117 -0
- package/src/structure/engine/fs/api.ts +40 -0
- package/src/structure/engine/fs/memory.ts +132 -0
- package/src/structure/engine/fs/node.ts +89 -0
- package/src/structure/engine/glob.ts +42 -0
- package/src/structure/engine/ir.ts +149 -0
- package/src/structure/engine/parsers/json.ts +212 -0
- package/src/structure/engine/parsers/lines.ts +42 -0
- package/src/structure/engine/parsers/yaml.ts +72 -0
- package/src/structure/engine/registry-client.ts +140 -0
- package/src/structure/engine/runner.ts +519 -0
- package/src/structure/engine/templates.ts +74 -0
- package/src/structure/engine/testing.ts +93 -0
- package/src/structure/engine/version.ts +60 -0
- package/src/structure/init-block-constructor.ts +164 -0
- package/src/structure/rules/block-package-json.ts +156 -0
- package/src/structure/rules/block.ts +29 -0
- package/src/structure/rules/migrations.ts +63 -0
- package/src/structure/rules/model-package-json.ts +123 -0
- package/src/structure/rules/model.ts +65 -0
- package/src/structure/rules/root-catalog-bump.ts +77 -0
- package/src/structure/rules/root-gitignore.ts +27 -0
- package/src/structure/rules/root-package-json.ts +119 -0
- package/src/structure/rules/root-pnpm-workspace.ts +103 -0
- package/src/structure/rules/root.ts +43 -0
- package/src/structure/rules/shared/colocated-tests.ts +11 -0
- package/src/structure/rules/shared/key-order.ts +34 -0
- package/src/structure/rules/software-package-json.ts +86 -0
- package/src/structure/rules/software.ts +33 -0
- package/src/structure/rules/test-package-json.ts +70 -0
- package/src/structure/rules/test.ts +40 -0
- package/src/structure/rules/ui-package-json.ts +108 -0
- package/src/structure/rules/ui.ts +75 -0
- package/src/structure/rules/workflow-package-json.ts +92 -0
- package/src/structure/rules/workflow.ts +51 -0
- package/src/structure/structure-definition.ts +28 -0
- package/src/structure/templates/static/block/index.d.ts +6 -0
- package/src/structure/templates/static/block/index.js +8 -0
- package/src/structure/templates/static/block/logos/block-logo.png +0 -0
- package/src/structure/templates/static/block/logos/organization-logo.png +0 -0
- package/src/structure/templates/static/model/.oxfmtrc.json +4 -0
- package/src/structure/templates/static/model/.oxlintrc.json +3 -0
- package/src/structure/templates/static/model/src/index.ts +13 -0
- package/src/structure/templates/static/model/tsconfig.json +4 -0
- package/src/structure/templates/static/root/.gitignore +13 -0
- package/src/structure/templates/static/root/.vscode/settings.json +3 -0
- package/src/structure/templates/static/root/turbo.json +35 -0
- package/src/structure/templates/static/test/tsconfig.json +5 -0
- package/src/structure/templates/static/test/vitest.config.mts +8 -0
- package/src/structure/templates/static/ui/.oxfmtrc.json +3 -0
- package/src/structure/templates/static/ui/.oxlintrc.json +3 -0
- package/src/structure/templates/static/ui/index.html +12 -0
- package/src/structure/templates/static/ui/src/main.ts +5 -0
- package/src/structure/templates/static/ui/tsconfig.json +4 -0
- package/src/structure/templates/static/workflow/format.el +42 -0
- package/src/structure/templates/static/workflow/tsconfig.json +16 -0
- package/src/structure/templates/static/workflow/vitest.config.mts +9 -0
- package/src/structure/templates/text/README.md +5 -0
- package/src/structure/templates/text/docs/description.md +3 -0
- package/src/structure/templates/text/ui/src/MainPage.tpl.vue +9 -0
- package/src/structure/templates/text/ui/src/app.tpl.ts +11 -0
- package/src/structure/templates/text/workflow/src/main.tpl.tengo +10 -0
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cmd/build-meta.ts","../src/cmd/build-model.ts","../src/cmd/list-overview-snapshots.ts","../src/cmd/mark-stable.ts","../src/cmd/pack.ts","../src/cmd/publish.ts","../src/cmd/refresh-registry.ts","../src/cmd/restore-overview-from-snapshot.ts","../src/registry_v1/flags.ts","../src/cmd/upload-package-v1.ts","../src/cmd/update-deps.ts","../src/cmd/index.ts"],"sourcesContent":["import { Command, Flags } from \"@oclif/core\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { loadPackDescriptionRaw } from \"../v2\";\nimport { embedBlockPackMetaAbsoluteBase64, resolveBlockPackMeta } from \"../v2/model/block_meta\";\n\nexport default class BuildMeta extends Command {\n static override description =\n \"Extracts meta information from blocks package.json and outputs meta.json with embedded binary \" +\n \"and textual information linked from the meta section.\";\n\n static flags = {\n modulePath: Flags.string({\n char: \"i\",\n summary: \"input module path\",\n helpValue: \"<path>\",\n default: \".\",\n }),\n\n destination: Flags.string({\n char: \"o\",\n summary: \"output meta.json file\",\n helpValue: \"<path>\",\n required: true,\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(BuildMeta);\n const modulePath = path.resolve(flags.modulePath);\n const descriptionRaw = await loadPackDescriptionRaw(modulePath);\n const metaEmbedded = await embedBlockPackMetaAbsoluteBase64(\n await resolveBlockPackMeta(descriptionRaw.meta, modulePath),\n );\n\n await fs.promises.writeFile(path.resolve(flags.destination), JSON.stringify(metaEmbedded));\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nasync function getFileContent(path: string) {\n try {\n return await fs.promises.readFile(path, \"utf8\");\n } catch (error: unknown) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nexport default class BuildModel extends Command {\n static override description =\n \"Extracts and outputs block model JSON from pre-built block model module\";\n\n static flags = {\n modulePath: Flags.string({\n char: \"i\",\n summary: \"input module path\",\n helpValue: \"<path>\",\n default: \".\",\n }),\n\n sourceBundle: Flags.string({\n char: \"b\",\n summary: \"bundled model code to embed into the model for callback-based rendering to work\",\n helpValue: \"<path>\",\n default: \"./dist/bundle.js\",\n }),\n\n destination: Flags.string({\n char: \"o\",\n summary: \"output model file\",\n helpValue: \"<path>\",\n default: \"./dist/model.json\",\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(BuildModel);\n const modulePath = path.resolve(flags.modulePath); // i.e. folder with package.json file\n // eslint-disable-next-line prefer-const, @typescript-eslint/no-unsafe-assignment\n let { model, platforma } = require(modulePath);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n if (!model) model = platforma;\n if (!model) throw new Error('\"model\" export not found');\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const { config } = model;\n\n if (!config)\n throw new Error(\n 'Malformed \"model\" object, check it is created with \"BlockModel\" ' +\n 'and \".done()\" is executed as the call in the chain.',\n );\n\n if (!(\"outputs\" in config) || !(\"sections\" in config))\n throw new Error('\"config\" has unexpected structure');\n\n const code = await getFileContent(flags.sourceBundle);\n if (code !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n config.code = {\n type: \"plain\",\n content: code,\n };\n }\n\n await fs.promises.writeFile(path.resolve(flags.destination), JSON.stringify(config));\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport { BlockRegistryV2 } from \"../v2/registry/registry\";\nimport { storageByUrl } from \"../io/storage\";\nimport { OclifLoggerAdapter } from \"@milaboratories/ts-helpers-oclif\";\n\nexport default class ListOverviewSnapshots extends Command {\n static description = \"List all available global overview snapshots in the registry\";\n\n static flags = {\n registry: Flags.string({\n char: \"r\",\n summary: \"full address of the registry\",\n helpValue: \"<address>\",\n env: \"PL_REGISTRY\",\n required: true,\n }),\n\n json: Flags.boolean({\n summary: \"output in JSON format\",\n default: false,\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(ListOverviewSnapshots);\n const storage = storageByUrl(flags.registry);\n const registry = new BlockRegistryV2(storage, new OclifLoggerAdapter(this));\n\n const snapshots = await registry.listGlobalOverviewSnapshots();\n\n if (flags.json) {\n this.log(JSON.stringify(snapshots, null, 2));\n } else {\n if (snapshots.length === 0) {\n this.log(\"No snapshots found.\");\n } else {\n this.log(`Found ${snapshots.length} snapshot(s):\\n`);\n for (const snapshot of snapshots) {\n this.log(` ${snapshot.timestamp}`);\n this.log(` Path: ${snapshot.path}`);\n this.log(\"\");\n }\n }\n }\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport { BlockRegistryV2, loadPackDescriptionRaw } from \"../v2\";\nimport path from \"node:path\";\nimport { overrideDescriptionVersion, StableChannel } from \"@milaboratories/pl-model-middle-layer\";\nimport { storageByUrl } from \"../io\";\nimport { OclifLoggerAdapter } from \"@milaboratories/ts-helpers-oclif\";\n\nexport default class MarkStable extends Command {\n static description = \"Mark target block stable\";\n\n static flags = {\n modulePath: Flags.string({\n char: \"i\",\n summary: \"input module path\",\n helpValue: \"<path>\",\n default: \".\",\n }),\n\n channel: Flags.string({\n char: \"c\",\n hidden: true,\n summary: \"custom channel\",\n helpValue: \"<channel name>\",\n default: StableChannel,\n }),\n\n \"version-override\": Flags.file({\n char: \"v\",\n summary: \"override package version\",\n }),\n\n registry: Flags.string({\n char: \"r\",\n summary: \"full address of the registry\",\n helpValue: \"<address>\",\n env: \"PL_REGISTRY\",\n required: true,\n }),\n\n refresh: Flags.boolean({\n summary: \"refresh repository after adding the package\",\n default: true,\n allowNo: true,\n env: \"PL_REGISTRY_REFRESH\",\n }),\n\n unmark: Flags.boolean({\n summary:\n 'reverses meaning of this command, flag can be used to remove \"stable\" flag from the package',\n default: false,\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(MarkStable);\n let description = await loadPackDescriptionRaw(path.resolve(flags.modulePath));\n if (flags[\"version-override\"])\n description = overrideDescriptionVersion(description, flags[\"version-override\"]);\n const storage = storageByUrl(flags.registry);\n const registry = new BlockRegistryV2(storage, new OclifLoggerAdapter(this));\n\n if (flags.unmark) await registry.removePackageFromChannel(description.id, flags.channel);\n else await registry.addPackageToChannel(description.id, flags.channel);\n\n if (flags.refresh) await registry.updateIfNeeded();\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport { loadPackDescription } from \"../v2/source_package\";\nimport path from \"node:path\";\nimport { buildBlockPackDist } from \"../v2/build_dist\";\n\nexport default class PackBlock extends Command {\n static description =\n \"Builds block pack and outputs a block pack manifest consolidating all \" +\n \"references assets into a single folder\";\n\n static flags = {\n modulePath: Flags.string({\n char: \"i\",\n summary: \"input module path\",\n helpValue: \"<path>\",\n default: \".\",\n }),\n\n destinationPath: Flags.string({\n char: \"o\",\n summary: \"output folder\",\n helpValue: \"<path>\",\n default: \"./block-pack\",\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(PackBlock);\n const description = await loadPackDescription(path.resolve(flags.modulePath));\n await buildBlockPackDist(description, path.resolve(flags.destinationPath));\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport fs from \"node:fs\";\nimport { OclifLoggerAdapter } from \"@milaboratories/ts-helpers-oclif\";\nimport { ManifestFileName } from \"../v2/registry/schema_public\";\nimport {\n BlockPackManifest,\n overrideManifestVersion,\n StableChannel,\n} from \"@milaboratories/pl-model-middle-layer\";\nimport { storageByUrl } from \"../io/storage\";\nimport { BlockRegistryV2 } from \"../v2/registry/registry\";\nimport path from \"node:path\";\n\nfunction simpleDeepMerge<T extends Record<string, unknown>>(\n target: Record<string, unknown>,\n source: T,\n): T {\n const result = { ...target };\n\n for (const key in source) {\n if (source[key] && typeof source[key] === \"object\" && !Array.isArray(source[key])) {\n if (result[key] && typeof result[key] === \"object\" && !Array.isArray(result[key])) {\n result[key] = simpleDeepMerge(\n result[key] as Record<string, unknown>,\n source[key] as Record<string, unknown>,\n );\n } else {\n result[key] = source[key];\n }\n } else {\n result[key] = source[key];\n }\n }\n\n return result as T;\n}\n\nexport default class Publish extends Command {\n static description =\n \"Publishes the block package and refreshes the registry (for v2 block-pack schema)\";\n\n static flags = {\n registry: Flags.string({\n char: \"r\",\n summary: \"full address of the registry\",\n helpValue: \"<address>\",\n env: \"PL_REGISTRY\",\n required: true,\n }),\n\n manifest: Flags.file({\n char: \"m\",\n summary: \"manifest file path\",\n exists: true,\n default: `./block-pack/${ManifestFileName}`,\n }),\n\n \"version-override\": Flags.file({\n char: \"v\",\n summary: \"override package version\",\n }),\n\n refresh: Flags.boolean({\n summary: \"refresh repository after adding the package\",\n default: true,\n allowNo: true,\n env: \"PL_REGISTRY_REFRESH\",\n }),\n\n unstable: Flags.boolean({\n summary: \"do not add the published package to stable channel\",\n default: false,\n env: \"PL_PUBLISH_UNSTABLE\",\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(Publish);\n\n const manifestPath = path.resolve(flags.manifest);\n const rawManifest = JSON.parse(\n await fs.promises.readFile(manifestPath, { encoding: \"utf-8\" }),\n ) as Record<string, unknown>;\n let manifest = BlockPackManifest.parse(rawManifest);\n // To keep extra fields from the manifest and keep coerced fields\n manifest = simpleDeepMerge(\n rawManifest,\n manifest as BlockPackManifest & Record<string, unknown>,\n );\n const manifestRoot = path.dirname(manifestPath);\n\n this.log(`Manifest root = ${manifestRoot}`);\n\n if (flags[\"version-override\"])\n manifest = overrideManifestVersion(manifest, flags[\"version-override\"]);\n\n const storage = storageByUrl(flags.registry);\n const registry = new BlockRegistryV2(storage, new OclifLoggerAdapter(this));\n\n await registry.publishPackage(manifest, async (file) =>\n Buffer.from(await fs.promises.readFile(path.resolve(manifestRoot, file))),\n );\n\n if (!flags.unstable) {\n this.log(`Adding package to ${StableChannel} channel...`);\n await registry.addPackageToChannel(manifest.description.id, StableChannel);\n }\n\n if (flags.refresh) await registry.updateIfNeeded();\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport { BlockRegistryV2 } from \"../v2\";\nimport { storageByUrl } from \"../io\";\nimport { OclifLoggerAdapter } from \"@milaboratories/ts-helpers-oclif\";\n\nexport default class RefreshRegistry extends Command {\n static description = \"Refresh overview files based on published but not proecessed artefacts\";\n\n static flags = {\n registry: Flags.string({\n char: \"r\",\n summary: \"full address of the registry\",\n helpValue: \"<address>\",\n env: \"PL_REGISTRY\",\n required: true,\n }),\n\n mode: Flags.string({\n char: \"m\",\n summary: 'refresh mode (allowed valiues: \"force\", \"normal\", \"dry-run\")',\n helpValue: \"<mode>\",\n options: [\"force\", \"normal\", \"dry-run\"],\n env: \"PL_REGISTRY_REFRESH_DRY_RUN\",\n default: \"normal\",\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(RefreshRegistry);\n const storage = storageByUrl(flags.registry);\n const registry = new BlockRegistryV2(storage, new OclifLoggerAdapter(this));\n await registry.updateIfNeeded(flags.mode as \"force\" | \"normal\" | \"dry-run\");\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport { BlockRegistryV2 } from \"../v2/registry/registry\";\nimport { storageByUrl } from \"../io/storage\";\nimport { OclifLoggerAdapter } from \"@milaboratories/ts-helpers-oclif\";\n\nexport default class RestoreOverviewFromSnapshot extends Command {\n static description = \"Restore global overview from a snapshot\";\n\n static flags = {\n registry: Flags.string({\n char: \"r\",\n summary: \"full address of the registry\",\n helpValue: \"<address>\",\n env: \"PL_REGISTRY\",\n required: true,\n }),\n\n snapshot: Flags.string({\n char: \"s\",\n summary: \"snapshot timestamp ID to restore from\",\n helpValue: \"<timestamp>\",\n required: true,\n }),\n\n \"skip-confirmation\": Flags.boolean({\n summary: \"skip confirmation prompt (use with caution)\",\n default: false,\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(RestoreOverviewFromSnapshot);\n const storage = storageByUrl(flags.registry);\n const registry = new BlockRegistryV2(storage, new OclifLoggerAdapter(this));\n\n // Check if snapshot exists\n const snapshots = await registry.listGlobalOverviewSnapshots();\n const targetSnapshot = snapshots.find((s) => s.timestamp === flags.snapshot);\n\n if (!targetSnapshot) {\n this.error(\n `Snapshot '${flags.snapshot}' not found. Available snapshots:\\n${\n snapshots.map((s) => ` - ${s.timestamp}`).join(\"\\n\") || \" (none)\"\n }`,\n );\n }\n\n // Confirmation prompt (unless skipped)\n if (!flags[\"skip-confirmation\"]) {\n const readline = await import(\"node:readline\");\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const answer = await new Promise<string>((resolve) => {\n rl.question(\n `⚠️ This will overwrite the current global overview with snapshot '${flags.snapshot}'.\\n` +\n `Are you sure you want to continue? (y/N): `,\n resolve,\n );\n });\n\n rl.close();\n\n if (answer.toLowerCase() !== \"y\" && answer.toLowerCase() !== \"yes\") {\n this.log(\"Restore cancelled.\");\n return;\n }\n }\n\n // Perform restore\n try {\n await registry.restoreGlobalOverviewFromSnapshot(flags.snapshot);\n this.log(`✅ Successfully restored global overview from snapshot '${flags.snapshot}'`);\n } catch (error) {\n this.error(`Failed to restore from snapshot: ${String(error)}`);\n }\n }\n}\n","import { Flags } from \"@oclif/core\";\nimport path from \"node:path\";\n\nexport interface TargetFile {\n src: string;\n destName: string;\n}\n\nfunction parseTargetFile(arg: string): TargetFile {\n const match = arg.match(/(?<destName>[^/\\\\]+)=(?<src>.*)/);\n if (match) {\n const { src, destName } = match.groups!;\n return { src, destName };\n } else {\n return { src: arg, destName: path.basename(arg) };\n }\n}\n\nexport const targetFile = Flags.custom<TargetFile>({\n summary: \"target files to upload\",\n helpValue: \"file_path | package_name=file_path\",\n // eslint-disable-next-line @typescript-eslint/require-await -- oclif requires async but parsing is sync\n parse: async (arg) => parseTargetFile(arg),\n});\n","import { Command, Flags } from \"@oclif/core\";\nimport { getConfig } from \"../registry_v1/config\";\nimport { targetFile } from \"../registry_v1/flags\";\nimport fs from \"node:fs\";\nimport YAML from \"yaml\";\nimport { PlRegPackageConfigDataShard } from \"../registry_v1/config_schema\";\nimport { OclifLoggerAdapter } from \"@milaboratories/ts-helpers-oclif\";\n\ntype BasicConfigField = keyof PlRegPackageConfigDataShard &\n (\"registry\" | \"organization\" | \"package\" | \"version\");\nconst BasicConfigFields: BasicConfigField[] = [\"registry\", \"organization\", \"package\", \"version\"];\n\nexport default class UploadPackageV1 extends Command {\n static description = \"Uploads V1 package and refreshes the registry\";\n\n static flags = {\n registry: Flags.string({\n char: \"r\",\n summary: \"full address of the registry or alias from .pl.reg\",\n helpValue: \"<address|alias>\",\n env: \"PL_REGISTRY\",\n }),\n\n organization: Flags.string({\n char: \"o\",\n summary: \"target organisation\",\n env: \"PL_PACKAGE_ORGANIZATION\",\n }),\n\n package: Flags.string({\n char: \"p\",\n summary: \"target package\",\n env: \"PL_PACKAGE_NAME\",\n }),\n\n version: Flags.string({\n char: \"v\",\n summary: \"target version\",\n env: \"PL_PACKAGE_VERSION\",\n }),\n\n meta: Flags.file({\n char: \"m\",\n summary: \"json file containing meta information to associate with tha package\",\n exists: true,\n }),\n\n file: targetFile({\n char: \"f\",\n summary: \"package files\",\n multiple: true,\n default: [],\n }),\n\n refresh: Flags.boolean({\n summary: \"refresh repository after adding the package\",\n default: true,\n allowNo: true,\n env: \"PL_REGISTRY_REFRESH\",\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(UploadPackageV1);\n const configFromFlags: PlRegPackageConfigDataShard = PlRegPackageConfigDataShard.parse({});\n\n for (const field of BasicConfigFields) if (flags[field]) configFromFlags[field] = flags[field];\n\n if (flags.meta) {\n if (flags.meta.endsWith(\".json\"))\n configFromFlags.meta = JSON.parse(\n await fs.promises.readFile(flags.meta, { encoding: \"utf-8\" }),\n ) as Record<string, unknown>;\n else if (flags.meta.endsWith(\".yaml\"))\n configFromFlags.meta = YAML.parse(\n await fs.promises.readFile(flags.meta, { encoding: \"utf-8\" }),\n ) as Record<string, unknown>;\n }\n\n for (const targetFile of flags.file) {\n configFromFlags.files[targetFile.destName] = targetFile.src;\n }\n\n const conf = await getConfig(configFromFlags);\n\n this.log(YAML.stringify(conf.conf));\n\n const registry = conf.createRegistry(new OclifLoggerAdapter(this));\n const name = conf.fullPackageName;\n\n const builder = registry.constructNewPackage(name);\n\n for (const [dst, src] of Object.entries(conf.conf.files)) {\n this.log(`Uploading ${src} -> ${dst} ...`);\n const content = await fs.promises.readFile(src);\n await builder.addFile(dst, content);\n }\n\n this.log(`Uploading meta information...`);\n await builder.writeMeta(conf.conf.meta);\n await builder.finish();\n\n if (flags.refresh) await registry.updateIfNeeded();\n }\n}\n","import { Command } from \"@oclif/core\";\nimport { updatePackages } from \"@platforma-sdk/blocks-deps-updater\";\n\nexport default class UpdateDeps extends Command {\n static override description =\n \"Updates @platforma-sdk and @milaboratories packages in pnpm-workspace.yaml catalog to their latest versions from npm registry.\";\n\n static override examples = [\"<%= config.bin %> <%= command.id %>\"];\n\n public async run(): Promise<void> {\n await updatePackages();\n }\n}\n","// DO NOT EDIT. This file was generated by oclif-index utility.\n\nimport Cmd0 from \"./build-meta\";\nimport Cmd1 from \"./build-model\";\nimport Cmd3 from \"./list-overview-snapshots\";\nimport Cmd4 from \"./mark-stable\";\nimport Cmd5 from \"./pack\";\nimport Cmd6 from \"./publish\";\nimport Cmd7 from \"./refresh-registry\";\nimport Cmd8 from \"./restore-overview-from-snapshot\";\nimport Cmd9 from \"./upload-package-v1\";\nimport Cmd10 from \"./update-deps\";\n\nexport const COMMANDS = {\n \"build-meta\": Cmd0,\n \"build-model\": Cmd1,\n \"list-overview-snapshots\": Cmd3,\n \"mark-stable\": Cmd4,\n pack: Cmd5,\n publish: Cmd6,\n \"refresh-registry\": Cmd7,\n \"restore-overview-from-snapshot\": Cmd8,\n \"upload-package-v1\": Cmd9,\n \"update-deps\": Cmd10,\n};\n"],"mappings":";;;;;;;;;AAMA,IAAqB,IAArB,MAAqB,UAAkB,EAAQ;CAC7C,OAAgB,cACd;CAGF,OAAO,QAAQ;EACb,YAAY,EAAM,OAAO;GACvB,MAAM;GACN,SAAS;GACT,WAAW;GACX,SAAS;GACV,CAAC;EAEF,aAAa,EAAM,OAAO;GACxB,MAAM;GACN,SAAS;GACT,WAAW;GACX,UAAU;GACX,CAAC;EACH;CAED,MAAa,MAAqB;EAChC,IAAM,EAAE,aAAU,MAAM,KAAK,MAAM,EAAU,EACvC,IAAa,EAAK,QAAQ,EAAM,WAAW,EAE3C,IAAe,MAAM,EACzB,MAAM,GAFe,MAAM,EAAuB,EAAW,EAEnB,MAAM,EAAW,CAC5D;AAED,QAAM,EAAG,SAAS,UAAU,EAAK,QAAQ,EAAM,YAAY,EAAE,KAAK,UAAU,EAAa,CAAC;;;;;AC/B9F,eAAe,EAAe,GAAc;AAC1C,KAAI;AACF,SAAO,MAAM,EAAG,SAAS,SAAS,GAAM,OAAO;UACxC,GAAgB;AACvB,MAAI,aAAiB,SAAS,UAAU,KAAS,EAAM,SAAS,SAC9D;AAEF,QAAM;;;AAIV,IAAqB,IAArB,MAAqB,UAAmB,EAAQ;CAC9C,OAAgB,cACd;CAEF,OAAO,QAAQ;EACb,YAAY,EAAM,OAAO;GACvB,MAAM;GACN,SAAS;GACT,WAAW;GACX,SAAS;GACV,CAAC;EAEF,cAAc,EAAM,OAAO;GACzB,MAAM;GACN,SAAS;GACT,WAAW;GACX,SAAS;GACV,CAAC;EAEF,aAAa,EAAM,OAAO;GACxB,MAAM;GACN,SAAS;GACT,WAAW;GACX,SAAS;GACV,CAAC;EACH;CAED,MAAa,MAAqB;EAChC,IAAM,EAAE,aAAU,MAAM,KAAK,MAAM,EAAW,EAG1C,EAAE,UAAO,iBAAA,EAFM,EAAK,QAAQ,EAAM,WAAW,CAEH;AAI9C,MADA,AAAY,MAAQ,GAChB,CAAC,EAAO,OAAU,MAAM,6BAA2B;EAGvD,IAAM,EAAE,cAAW;AAEnB,MAAI,CAAC,EACH,OAAU,MACR,4HAED;AAEH,MAAI,EAAE,aAAa,MAAW,EAAE,cAAc,GAC5C,OAAU,MAAM,sCAAoC;EAEtD,IAAM,IAAO,MAAM,EAAe,EAAM,aAAa;AASrD,EARI,MAAS,KAAA,MAEX,EAAO,OAAO;GACZ,MAAM;GACN,SAAS;GACV,GAGH,MAAM,EAAG,SAAS,UAAU,EAAK,QAAQ,EAAM,YAAY,EAAE,KAAK,UAAU,EAAO,CAAC;;GCpEnE,IAArB,MAAqB,UAA8B,EAAQ;CACzD,OAAO,cAAc;CAErB,OAAO,QAAQ;EACb,UAAU,EAAM,OAAO;GACrB,MAAM;GACN,SAAS;GACT,WAAW;GACX,KAAK;GACL,UAAU;GACX,CAAC;EAEF,MAAM,EAAM,QAAQ;GAClB,SAAS;GACT,SAAS;GACV,CAAC;EACH;CAED,MAAa,MAAqB;EAChC,IAAM,EAAE,aAAU,MAAM,KAAK,MAAM,EAAsB,EAInD,IAAY,MAFD,IAAI,EADL,EAAa,EAAM,SAAS,EACE,IAAI,EAAmB,KAAK,CAAC,CAE1C,6BAA6B;AAE9D,MAAI,EAAM,KACR,MAAK,IAAI,KAAK,UAAU,GAAW,MAAM,EAAE,CAAC;WAExC,EAAU,WAAW,EACvB,MAAK,IAAI,sBAAsB;OAC1B;AACL,QAAK,IAAI,SAAS,EAAU,OAAO,iBAAiB;AACpD,QAAK,IAAM,KAAY,EAGrB,CAFA,KAAK,IAAI,KAAK,EAAS,YAAY,EACnC,KAAK,IAAI,aAAa,EAAS,OAAO,EACtC,KAAK,IAAI,GAAG;;;GCjCD,IAArB,MAAqB,UAAmB,EAAQ;CAC9C,OAAO,cAAc;CAErB,OAAO,QAAQ;EACb,YAAY,EAAM,OAAO;GACvB,MAAM;GACN,SAAS;GACT,WAAW;GACX,SAAS;GACV,CAAC;EAEF,SAAS,EAAM,OAAO;GACpB,MAAM;GACN,QAAQ;GACR,SAAS;GACT,WAAW;GACX,SAAS;GACV,CAAC;EAEF,oBAAoB,EAAM,KAAK;GAC7B,MAAM;GACN,SAAS;GACV,CAAC;EAEF,UAAU,EAAM,OAAO;GACrB,MAAM;GACN,SAAS;GACT,WAAW;GACX,KAAK;GACL,UAAU;GACX,CAAC;EAEF,SAAS,EAAM,QAAQ;GACrB,SAAS;GACT,SAAS;GACT,SAAS;GACT,KAAK;GACN,CAAC;EAEF,QAAQ,EAAM,QAAQ;GACpB,SACE;GACF,SAAS;GACV,CAAC;EACH;CAED,MAAa,MAAqB;EAChC,IAAM,EAAE,aAAU,MAAM,KAAK,MAAM,EAAW,EAC1C,IAAc,MAAM,EAAuB,EAAK,QAAQ,EAAM,WAAW,CAAC;AAC9E,EAAI,EAAM,wBACR,IAAc,EAA2B,GAAa,EAAM,oBAAoB;EAElF,IAAM,IAAW,IAAI,EADL,EAAa,EAAM,SAAS,EACE,IAAI,EAAmB,KAAK,CAAC;AAK3E,EAHI,EAAM,SAAQ,MAAM,EAAS,yBAAyB,EAAY,IAAI,EAAM,QAAQ,GACnF,MAAM,EAAS,oBAAoB,EAAY,IAAI,EAAM,QAAQ,EAElE,EAAM,WAAS,MAAM,EAAS,gBAAgB;;GC3DjC,IAArB,MAAqB,UAAkB,EAAQ;CAC7C,OAAO,cACL;CAGF,OAAO,QAAQ;EACb,YAAY,EAAM,OAAO;GACvB,MAAM;GACN,SAAS;GACT,WAAW;GACX,SAAS;GACV,CAAC;EAEF,iBAAiB,EAAM,OAAO;GAC5B,MAAM;GACN,SAAS;GACT,WAAW;GACX,SAAS;GACV,CAAC;EACH;CAED,MAAa,MAAqB;EAChC,IAAM,EAAE,aAAU,MAAM,KAAK,MAAM,EAAU;AAE7C,QAAM,EADc,MAAM,EAAoB,EAAK,QAAQ,EAAM,WAAW,CAAC,EACvC,EAAK,QAAQ,EAAM,gBAAgB,CAAC;;;;;AChB9E,SAAS,EACP,GACA,GACG;CACH,IAAM,IAAS,EAAE,GAAG,GAAQ;AAE5B,MAAK,IAAM,KAAO,EAChB,CAAI,EAAO,MAAQ,OAAO,EAAO,MAAS,YAAY,CAAC,MAAM,QAAQ,EAAO,GAAK,IAC3E,EAAO,MAAQ,OAAO,EAAO,MAAS,YAAY,CAAC,MAAM,QAAQ,EAAO,GAAK,GAC/E,EAAO,KAAO,EACZ,EAAO,IACP,EAAO,GACR,GAED,EAAO,KAAO,EAAO;AAO3B,QAAO;;AAGT,IAAqB,IAArB,MAAqB,UAAgB,EAAQ;CAC3C,OAAO,cACL;CAEF,OAAO,QAAQ;EACb,UAAU,EAAM,OAAO;GACrB,MAAM;GACN,SAAS;GACT,WAAW;GACX,KAAK;GACL,UAAU;GACX,CAAC;EAEF,UAAU,EAAM,KAAK;GACnB,MAAM;GACN,SAAS;GACT,QAAQ;GACR,SAAS,gBAAgB;GAC1B,CAAC;EAEF,oBAAoB,EAAM,KAAK;GAC7B,MAAM;GACN,SAAS;GACV,CAAC;EAEF,SAAS,EAAM,QAAQ;GACrB,SAAS;GACT,SAAS;GACT,SAAS;GACT,KAAK;GACN,CAAC;EAEF,UAAU,EAAM,QAAQ;GACtB,SAAS;GACT,SAAS;GACT,KAAK;GACN,CAAC;EACH;CAED,MAAa,MAAqB;EAChC,IAAM,EAAE,aAAU,MAAM,KAAK,MAAM,EAAQ,EAErC,IAAe,EAAK,QAAQ,EAAM,SAAS,EAC3C,IAAc,KAAK,MACvB,MAAM,EAAG,SAAS,SAAS,GAAc,EAAE,UAAU,SAAS,CAAC,CAChE,EACG,IAAW,EAAkB,MAAM,EAAY;AAEnD,MAAW,EACT,GACA,EACD;EACD,IAAM,IAAe,EAAK,QAAQ,EAAa;AAI/C,EAFA,KAAK,IAAI,mBAAmB,IAAe,EAEvC,EAAM,wBACR,IAAW,EAAwB,GAAU,EAAM,oBAAoB;EAGzE,IAAM,IAAW,IAAI,EADL,EAAa,EAAM,SAAS,EACE,IAAI,EAAmB,KAAK,CAAC;AAW3E,EATA,MAAM,EAAS,eAAe,GAAU,OAAO,MAC7C,OAAO,KAAK,MAAM,EAAG,SAAS,SAAS,EAAK,QAAQ,GAAc,EAAK,CAAC,CAAC,CAC1E,EAEI,EAAM,aACT,KAAK,IAAI,qBAAqB,EAAc,aAAa,EACzD,MAAM,EAAS,oBAAoB,EAAS,YAAY,IAAI,EAAc,GAGxE,EAAM,WAAS,MAAM,EAAS,gBAAgB;;GCvGjC,IAArB,MAAqB,UAAwB,EAAQ;CACnD,OAAO,cAAc;CAErB,OAAO,QAAQ;EACb,UAAU,EAAM,OAAO;GACrB,MAAM;GACN,SAAS;GACT,WAAW;GACX,KAAK;GACL,UAAU;GACX,CAAC;EAEF,MAAM,EAAM,OAAO;GACjB,MAAM;GACN,SAAS;GACT,WAAW;GACX,SAAS;IAAC;IAAS;IAAU;IAAU;GACvC,KAAK;GACL,SAAS;GACV,CAAC;EACH;CAED,MAAa,MAAqB;EAChC,IAAM,EAAE,aAAU,MAAM,KAAK,MAAM,EAAgB;AAGnD,QADiB,IAAI,EADL,EAAa,EAAM,SAAS,EACE,IAAI,EAAmB,KAAK,CAAC,CAC5D,eAAe,EAAM,KAAuC;;GC1B1D,IAArB,MAAqB,UAAoC,EAAQ;CAC/D,OAAO,cAAc;CAErB,OAAO,QAAQ;EACb,UAAU,EAAM,OAAO;GACrB,MAAM;GACN,SAAS;GACT,WAAW;GACX,KAAK;GACL,UAAU;GACX,CAAC;EAEF,UAAU,EAAM,OAAO;GACrB,MAAM;GACN,SAAS;GACT,WAAW;GACX,UAAU;GACX,CAAC;EAEF,qBAAqB,EAAM,QAAQ;GACjC,SAAS;GACT,SAAS;GACV,CAAC;EACH;CAED,MAAa,MAAqB;EAChC,IAAM,EAAE,aAAU,MAAM,KAAK,MAAM,EAA4B,EAEzD,IAAW,IAAI,EADL,EAAa,EAAM,SAAS,EACE,IAAI,EAAmB,KAAK,CAAC,EAGrE,IAAY,MAAM,EAAS,6BAA6B;AAY9D,MAXuB,EAAU,MAAM,MAAM,EAAE,cAAc,EAAM,SAAS,IAG1E,KAAK,MACH,aAAa,EAAM,SAAS,qCAC1B,EAAU,KAAK,MAAM,OAAO,EAAE,YAAY,CAAC,KAAK,KAAK,IAAI,aAE5D,EAIC,CAAC,EAAM,sBAAsB;GAE/B,IAAM,KADW,MAAM,OAAO,kBACV,gBAAgB;IAClC,OAAO,QAAQ;IACf,QAAQ,QAAQ;IACjB,CAAC,EAEI,IAAS,MAAM,IAAI,SAAiB,MAAY;AACpD,MAAG,SACD,sEAAsE,EAAM,SAAS,iDAErF,EACD;KACD;AAIF,OAFA,EAAG,OAAO,EAEN,EAAO,aAAa,KAAK,OAAO,EAAO,aAAa,KAAK,OAAO;AAClE,SAAK,IAAI,qBAAqB;AAC9B;;;AAKJ,MAAI;AAEF,GADA,MAAM,EAAS,kCAAkC,EAAM,SAAS,EAChE,KAAK,IAAI,0DAA0D,EAAM,SAAS,GAAG;WAC9E,GAAO;AACd,QAAK,MAAM,oCAAoC,OAAO,EAAM,GAAG;;;;;;ACpErE,SAAS,EAAgB,GAAyB;CAChD,IAAM,IAAQ,EAAI,MAAM,kCAAkC;AAC1D,KAAI,GAAO;EACT,IAAM,EAAE,QAAK,gBAAa,EAAM;AAChC,SAAO;GAAE;GAAK;GAAU;OAExB,QAAO;EAAE,KAAK;EAAK,UAAU,EAAK,SAAS,EAAI;EAAE;;AAIrD,IAAa,IAAa,EAAM,OAAmB;CACjD,SAAS;CACT,WAAW;CAEX,OAAO,OAAO,MAAQ,EAAgB,EAAI;CAC3C,CAAC,ECbI,IAAwC;CAAC;CAAY;CAAgB;CAAW;CAAU,EEGnF,IAAW;CACtB,cAAc;CACd,eAAe;CACf,2BAA2B;CAC3B,eAAe;CACf,MAAM;CACN,SAAS;CACT,oBAAoB;CACpB,kCAAkC;CAClC,qBFVF,MAAqB,UAAwB,EAAQ;EACnD,OAAO,cAAc;EAErB,OAAO,QAAQ;GACb,UAAU,EAAM,OAAO;IACrB,MAAM;IACN,SAAS;IACT,WAAW;IACX,KAAK;IACN,CAAC;GAEF,cAAc,EAAM,OAAO;IACzB,MAAM;IACN,SAAS;IACT,KAAK;IACN,CAAC;GAEF,SAAS,EAAM,OAAO;IACpB,MAAM;IACN,SAAS;IACT,KAAK;IACN,CAAC;GAEF,SAAS,EAAM,OAAO;IACpB,MAAM;IACN,SAAS;IACT,KAAK;IACN,CAAC;GAEF,MAAM,EAAM,KAAK;IACf,MAAM;IACN,SAAS;IACT,QAAQ;IACT,CAAC;GAEF,MAAM,EAAW;IACf,MAAM;IACN,SAAS;IACT,UAAU;IACV,SAAS,EAAE;IACZ,CAAC;GAEF,SAAS,EAAM,QAAQ;IACrB,SAAS;IACT,SAAS;IACT,SAAS;IACT,KAAK;IACN,CAAC;GACH;EAED,MAAa,MAAqB;GAChC,IAAM,EAAE,aAAU,MAAM,KAAK,MAAM,EAAgB,EAC7C,IAA+C,EAA4B,MAAM,EAAE,CAAC;AAE1F,QAAK,IAAM,KAAS,EAAmB,CAAI,EAAM,OAAQ,EAAgB,KAAS,EAAM;AAExF,GAAI,EAAM,SACJ,EAAM,KAAK,SAAS,QAAQ,GAC9B,EAAgB,OAAO,KAAK,MAC1B,MAAM,EAAG,SAAS,SAAS,EAAM,MAAM,EAAE,UAAU,SAAS,CAAC,CAC9D,GACM,EAAM,KAAK,SAAS,QAAQ,KACnC,EAAgB,OAAO,EAAK,MAC1B,MAAM,EAAG,SAAS,SAAS,EAAM,MAAM,EAAE,UAAU,SAAS,CAAC,CAC9D;AAGL,QAAK,IAAM,KAAc,EAAM,KAC7B,GAAgB,MAAM,EAAW,YAAY,EAAW;GAG1D,IAAM,IAAO,MAAM,EAAU,EAAgB;AAE7C,QAAK,IAAI,EAAK,UAAU,EAAK,KAAK,CAAC;GAEnC,IAAM,IAAW,EAAK,eAAe,IAAI,EAAmB,KAAK,CAAC,EAC5D,IAAO,EAAK,iBAEZ,IAAU,EAAS,oBAAoB,EAAK;AAElD,QAAK,IAAM,CAAC,GAAK,MAAQ,OAAO,QAAQ,EAAK,KAAK,MAAM,EAAE;AACxD,SAAK,IAAI,aAAa,EAAI,MAAM,EAAI,MAAM;IAC1C,IAAM,IAAU,MAAM,EAAG,SAAS,SAAS,EAAI;AAC/C,UAAM,EAAQ,QAAQ,GAAK,EAAQ;;AAOrC,GAJA,KAAK,IAAI,gCAAgC,EACzC,MAAM,EAAQ,UAAU,EAAK,KAAK,KAAK,EACvC,MAAM,EAAQ,QAAQ,EAElB,EAAM,WAAS,MAAM,EAAS,gBAAgB;;;CE/EpD,eDpBF,cAAwC,EAAQ;EAC9C,OAAgB,cACd;EAEF,OAAgB,WAAW,CAAC,sCAAsC;EAElE,MAAa,MAAqB;AAChC,SAAM,GAAgB;;;CCczB"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cmd/build-meta.ts","../src/cmd/build-model.ts","../src/cmd/list-overview-snapshots.ts","../src/cmd/mark-stable.ts","../src/cmd/pack.ts","../src/cmd/publish.ts","../src/cmd/refresh-registry.ts","../src/cmd/restore-overview-from-snapshot.ts","../src/cmd/update-deps.ts","../src/registry_v1/flags.ts","../src/cmd/upload-package-v1.ts","../src/structure/engine/fs/node.ts","../src/structure/engine/templates.ts","../src/structure/engine/flatten.ts","../src/structure/engine/glob.ts","../src/structure/engine/builders.ts","../src/structure/engine/parsers/json.ts","../src/structure/engine/parsers/lines.ts","../src/structure/engine/content-rules.ts","../src/structure/engine/parsers/yaml.ts","../src/structure/engine/version.ts","../src/structure/engine/runner.ts","../src/structure/engine/discovery.ts","../src/structure/engine/ctx.ts","../src/structure/engine/discovery-fs.ts","../src/structure/rules/shared/key-order.ts","../src/structure/rules/root-package-json.ts","../src/structure/engine/registry-client.ts","../src/structure/rules/root-pnpm-workspace.ts","../src/structure/rules/root-gitignore.ts","../src/structure/rules/root.ts","../src/structure/rules/block-package-json.ts","../src/structure/rules/block.ts","../src/structure/rules/shared/colocated-tests.ts","../src/structure/rules/model-package-json.ts","../src/structure/rules/model.ts","../src/structure/rules/ui-package-json.ts","../src/structure/rules/ui.ts","../src/structure/rules/workflow-package-json.ts","../src/structure/rules/workflow.ts","../src/structure/rules/test-package-json.ts","../src/structure/rules/test.ts","../src/structure/rules/software-package-json.ts","../src/structure/rules/software.ts","../src/structure/rules/migrations.ts","../src/structure/rules/root-catalog-bump.ts","../src/structure/structure-definition.ts","../src/structure/cli/run-structure.ts","../src/cmd/structure/check.ts","../src/structure/init-block-constructor.ts","../src/cmd/structure/init.ts","../src/cmd/structure/refresh.ts","../src/cmd/index.ts"],"sourcesContent":["import { Command, Flags } from \"@oclif/core\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { loadPackDescriptionRaw } from \"../v2\";\nimport { embedBlockPackMetaAbsoluteBase64, resolveBlockPackMeta } from \"../v2/model/block_meta\";\n\nexport default class BuildMeta extends Command {\n static override description =\n \"Extracts meta information from blocks package.json and outputs meta.json with embedded binary \" +\n \"and textual information linked from the meta section.\";\n\n static flags = {\n modulePath: Flags.string({\n char: \"i\",\n summary: \"input module path\",\n helpValue: \"<path>\",\n default: \".\",\n }),\n\n destination: Flags.string({\n char: \"o\",\n summary: \"output meta.json file\",\n helpValue: \"<path>\",\n required: true,\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(BuildMeta);\n const modulePath = path.resolve(flags.modulePath);\n const descriptionRaw = await loadPackDescriptionRaw(modulePath);\n const metaEmbedded = await embedBlockPackMetaAbsoluteBase64(\n await resolveBlockPackMeta(descriptionRaw.meta, modulePath),\n );\n\n await fs.promises.writeFile(path.resolve(flags.destination), JSON.stringify(metaEmbedded));\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nasync function getFileContent(path: string) {\n try {\n return await fs.promises.readFile(path, \"utf8\");\n } catch (error: unknown) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nexport default class BuildModel extends Command {\n static override description =\n \"Extracts and outputs block model JSON from pre-built block model module\";\n\n static flags = {\n modulePath: Flags.string({\n char: \"i\",\n summary: \"input module path\",\n helpValue: \"<path>\",\n default: \".\",\n }),\n\n sourceBundle: Flags.string({\n char: \"b\",\n summary: \"bundled model code to embed into the model for callback-based rendering to work\",\n helpValue: \"<path>\",\n default: \"./dist/bundle.js\",\n }),\n\n destination: Flags.string({\n char: \"o\",\n summary: \"output model file\",\n helpValue: \"<path>\",\n default: \"./dist/model.json\",\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(BuildModel);\n const modulePath = path.resolve(flags.modulePath); // i.e. folder with package.json file\n // eslint-disable-next-line prefer-const, @typescript-eslint/no-unsafe-assignment\n let { model, platforma } = require(modulePath);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n if (!model) model = platforma;\n if (!model) throw new Error('\"model\" export not found');\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const { config } = model;\n\n if (!config)\n throw new Error(\n 'Malformed \"model\" object, check it is created with \"BlockModel\" ' +\n 'and \".done()\" is executed as the call in the chain.',\n );\n\n if (!(\"outputs\" in config) || !(\"sections\" in config))\n throw new Error('\"config\" has unexpected structure');\n\n const code = await getFileContent(flags.sourceBundle);\n if (code !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n config.code = {\n type: \"plain\",\n content: code,\n };\n }\n\n await fs.promises.writeFile(path.resolve(flags.destination), JSON.stringify(config));\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport { BlockRegistryV2 } from \"../v2/registry/registry\";\nimport { storageByUrl } from \"../io/storage\";\nimport { OclifLoggerAdapter } from \"@milaboratories/ts-helpers-oclif\";\n\nexport default class ListOverviewSnapshots extends Command {\n static description = \"List all available global overview snapshots in the registry\";\n\n static flags = {\n registry: Flags.string({\n char: \"r\",\n summary: \"full address of the registry\",\n helpValue: \"<address>\",\n env: \"PL_REGISTRY\",\n required: true,\n }),\n\n json: Flags.boolean({\n summary: \"output in JSON format\",\n default: false,\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(ListOverviewSnapshots);\n const storage = storageByUrl(flags.registry);\n const registry = new BlockRegistryV2(storage, new OclifLoggerAdapter(this));\n\n const snapshots = await registry.listGlobalOverviewSnapshots();\n\n if (flags.json) {\n this.log(JSON.stringify(snapshots, null, 2));\n } else {\n if (snapshots.length === 0) {\n this.log(\"No snapshots found.\");\n } else {\n this.log(`Found ${snapshots.length} snapshot(s):\\n`);\n for (const snapshot of snapshots) {\n this.log(` ${snapshot.timestamp}`);\n this.log(` Path: ${snapshot.path}`);\n this.log(\"\");\n }\n }\n }\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport { BlockRegistryV2, loadPackDescriptionRaw } from \"../v2\";\nimport path from \"node:path\";\nimport { overrideDescriptionVersion, StableChannel } from \"@milaboratories/pl-model-middle-layer\";\nimport { storageByUrl } from \"../io\";\nimport { OclifLoggerAdapter } from \"@milaboratories/ts-helpers-oclif\";\n\nexport default class MarkStable extends Command {\n static description = \"Mark target block stable\";\n\n static flags = {\n modulePath: Flags.string({\n char: \"i\",\n summary: \"input module path\",\n helpValue: \"<path>\",\n default: \".\",\n }),\n\n channel: Flags.string({\n char: \"c\",\n hidden: true,\n summary: \"custom channel\",\n helpValue: \"<channel name>\",\n default: StableChannel,\n }),\n\n \"version-override\": Flags.file({\n char: \"v\",\n summary: \"override package version\",\n }),\n\n registry: Flags.string({\n char: \"r\",\n summary: \"full address of the registry\",\n helpValue: \"<address>\",\n env: \"PL_REGISTRY\",\n required: true,\n }),\n\n refresh: Flags.boolean({\n summary: \"refresh repository after adding the package\",\n default: true,\n allowNo: true,\n env: \"PL_REGISTRY_REFRESH\",\n }),\n\n unmark: Flags.boolean({\n summary:\n 'reverses meaning of this command, flag can be used to remove \"stable\" flag from the package',\n default: false,\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(MarkStable);\n let description = await loadPackDescriptionRaw(path.resolve(flags.modulePath));\n if (flags[\"version-override\"])\n description = overrideDescriptionVersion(description, flags[\"version-override\"]);\n const storage = storageByUrl(flags.registry);\n const registry = new BlockRegistryV2(storage, new OclifLoggerAdapter(this));\n\n if (flags.unmark) await registry.removePackageFromChannel(description.id, flags.channel);\n else await registry.addPackageToChannel(description.id, flags.channel);\n\n if (flags.refresh) await registry.updateIfNeeded();\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport { loadPackDescription } from \"../v2/source_package\";\nimport path from \"node:path\";\nimport { buildBlockPackDist } from \"../v2/build_dist\";\n\nexport default class PackBlock extends Command {\n static description =\n \"Builds block pack and outputs a block pack manifest consolidating all \" +\n \"references assets into a single folder\";\n\n static flags = {\n modulePath: Flags.string({\n char: \"i\",\n summary: \"input module path\",\n helpValue: \"<path>\",\n default: \".\",\n }),\n\n destinationPath: Flags.string({\n char: \"o\",\n summary: \"output folder\",\n helpValue: \"<path>\",\n default: \"./block-pack\",\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(PackBlock);\n const description = await loadPackDescription(path.resolve(flags.modulePath));\n await buildBlockPackDist(description, path.resolve(flags.destinationPath));\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport fs from \"node:fs\";\nimport { OclifLoggerAdapter } from \"@milaboratories/ts-helpers-oclif\";\nimport { ManifestFileName } from \"../v2/registry/schema_public\";\nimport {\n BlockPackManifest,\n overrideManifestVersion,\n StableChannel,\n} from \"@milaboratories/pl-model-middle-layer\";\nimport { storageByUrl } from \"../io/storage\";\nimport { BlockRegistryV2 } from \"../v2/registry/registry\";\nimport path from \"node:path\";\n\nfunction simpleDeepMerge<T extends Record<string, unknown>>(\n target: Record<string, unknown>,\n source: T,\n): T {\n const result = { ...target };\n\n for (const key in source) {\n if (source[key] && typeof source[key] === \"object\" && !Array.isArray(source[key])) {\n if (result[key] && typeof result[key] === \"object\" && !Array.isArray(result[key])) {\n result[key] = simpleDeepMerge(\n result[key] as Record<string, unknown>,\n source[key] as Record<string, unknown>,\n );\n } else {\n result[key] = source[key];\n }\n } else {\n result[key] = source[key];\n }\n }\n\n return result as T;\n}\n\nexport default class Publish extends Command {\n static description =\n \"Publishes the block package and refreshes the registry (for v2 block-pack schema)\";\n\n static flags = {\n registry: Flags.string({\n char: \"r\",\n summary: \"full address of the registry\",\n helpValue: \"<address>\",\n env: \"PL_REGISTRY\",\n required: true,\n }),\n\n manifest: Flags.file({\n char: \"m\",\n summary: \"manifest file path\",\n exists: true,\n default: `./block-pack/${ManifestFileName}`,\n }),\n\n \"version-override\": Flags.file({\n char: \"v\",\n summary: \"override package version\",\n }),\n\n refresh: Flags.boolean({\n summary: \"refresh repository after adding the package\",\n default: true,\n allowNo: true,\n env: \"PL_REGISTRY_REFRESH\",\n }),\n\n unstable: Flags.boolean({\n summary: \"do not add the published package to stable channel\",\n default: false,\n env: \"PL_PUBLISH_UNSTABLE\",\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(Publish);\n\n const manifestPath = path.resolve(flags.manifest);\n const rawManifest = JSON.parse(\n await fs.promises.readFile(manifestPath, { encoding: \"utf-8\" }),\n ) as Record<string, unknown>;\n let manifest = BlockPackManifest.parse(rawManifest);\n // To keep extra fields from the manifest and keep coerced fields\n manifest = simpleDeepMerge(\n rawManifest,\n manifest as BlockPackManifest & Record<string, unknown>,\n );\n const manifestRoot = path.dirname(manifestPath);\n\n this.log(`Manifest root = ${manifestRoot}`);\n\n if (flags[\"version-override\"])\n manifest = overrideManifestVersion(manifest, flags[\"version-override\"]);\n\n const storage = storageByUrl(flags.registry);\n const registry = new BlockRegistryV2(storage, new OclifLoggerAdapter(this));\n\n await registry.publishPackage(manifest, async (file) =>\n Buffer.from(await fs.promises.readFile(path.resolve(manifestRoot, file))),\n );\n\n if (!flags.unstable) {\n this.log(`Adding package to ${StableChannel} channel...`);\n await registry.addPackageToChannel(manifest.description.id, StableChannel);\n }\n\n if (flags.refresh) await registry.updateIfNeeded();\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport { BlockRegistryV2 } from \"../v2\";\nimport { storageByUrl } from \"../io\";\nimport { OclifLoggerAdapter } from \"@milaboratories/ts-helpers-oclif\";\n\nexport default class RefreshRegistry extends Command {\n static description = \"Refresh overview files based on published but not proecessed artefacts\";\n\n static flags = {\n registry: Flags.string({\n char: \"r\",\n summary: \"full address of the registry\",\n helpValue: \"<address>\",\n env: \"PL_REGISTRY\",\n required: true,\n }),\n\n mode: Flags.string({\n char: \"m\",\n summary: 'refresh mode (allowed valiues: \"force\", \"normal\", \"dry-run\")',\n helpValue: \"<mode>\",\n options: [\"force\", \"normal\", \"dry-run\"],\n env: \"PL_REGISTRY_REFRESH_DRY_RUN\",\n default: \"normal\",\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(RefreshRegistry);\n const storage = storageByUrl(flags.registry);\n const registry = new BlockRegistryV2(storage, new OclifLoggerAdapter(this));\n await registry.updateIfNeeded(flags.mode as \"force\" | \"normal\" | \"dry-run\");\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport { BlockRegistryV2 } from \"../v2/registry/registry\";\nimport { storageByUrl } from \"../io/storage\";\nimport { OclifLoggerAdapter } from \"@milaboratories/ts-helpers-oclif\";\n\nexport default class RestoreOverviewFromSnapshot extends Command {\n static description = \"Restore global overview from a snapshot\";\n\n static flags = {\n registry: Flags.string({\n char: \"r\",\n summary: \"full address of the registry\",\n helpValue: \"<address>\",\n env: \"PL_REGISTRY\",\n required: true,\n }),\n\n snapshot: Flags.string({\n char: \"s\",\n summary: \"snapshot timestamp ID to restore from\",\n helpValue: \"<timestamp>\",\n required: true,\n }),\n\n \"skip-confirmation\": Flags.boolean({\n summary: \"skip confirmation prompt (use with caution)\",\n default: false,\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(RestoreOverviewFromSnapshot);\n const storage = storageByUrl(flags.registry);\n const registry = new BlockRegistryV2(storage, new OclifLoggerAdapter(this));\n\n // Check if snapshot exists\n const snapshots = await registry.listGlobalOverviewSnapshots();\n const targetSnapshot = snapshots.find((s) => s.timestamp === flags.snapshot);\n\n if (!targetSnapshot) {\n this.error(\n `Snapshot '${flags.snapshot}' not found. Available snapshots:\\n${\n snapshots.map((s) => ` - ${s.timestamp}`).join(\"\\n\") || \" (none)\"\n }`,\n );\n }\n\n // Confirmation prompt (unless skipped)\n if (!flags[\"skip-confirmation\"]) {\n const readline = await import(\"node:readline\");\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const answer = await new Promise<string>((resolve) => {\n rl.question(\n `⚠️ This will overwrite the current global overview with snapshot '${flags.snapshot}'.\\n` +\n `Are you sure you want to continue? (y/N): `,\n resolve,\n );\n });\n\n rl.close();\n\n if (answer.toLowerCase() !== \"y\" && answer.toLowerCase() !== \"yes\") {\n this.log(\"Restore cancelled.\");\n return;\n }\n }\n\n // Perform restore\n try {\n await registry.restoreGlobalOverviewFromSnapshot(flags.snapshot);\n this.log(`✅ Successfully restored global overview from snapshot '${flags.snapshot}'`);\n } catch (error) {\n this.error(`Failed to restore from snapshot: ${String(error)}`);\n }\n }\n}\n","import { Command } from \"@oclif/core\";\n\n/**\n * Deprecated. Phase-2 forwarding alias (spec.md § \"Coexistence And\n * Retirement\"): delegates to `structure refresh --update-deps-only`,\n * which lands at parity with the old `blocks-deps-updater` catalog-bump\n * semantics. Prints a deprecation warning; will be removed once the\n * structurer path has been live without surprises.\n */\nexport default class UpdateDeps extends Command {\n static override description =\n \"[DEPRECATED] Use `block-tools structure refresh --update-deps-only`. This alias delegates to it.\";\n\n static override examples = [\"<%= config.bin %> <%= command.id %>\"];\n\n public async run(): Promise<void> {\n this.warn(\n \"`block-tools update-deps` is deprecated and will be removed in a future release. \" +\n \"Use `block-tools structure refresh --update-deps-only` instead. Delegating now.\",\n );\n // oclif resolves commands by their internal colon-form id, even\n // though the user-facing form uses the configured \" \" topic separator.\n await this.config.runCommand(\"structure:refresh\", [\"--update-deps-only\"]);\n }\n}\n","import { Flags } from \"@oclif/core\";\nimport path from \"node:path\";\n\nexport interface TargetFile {\n src: string;\n destName: string;\n}\n\nfunction parseTargetFile(arg: string): TargetFile {\n const match = arg.match(/(?<destName>[^/\\\\]+)=(?<src>.*)/);\n if (match) {\n const { src, destName } = match.groups!;\n return { src, destName };\n } else {\n return { src: arg, destName: path.basename(arg) };\n }\n}\n\nexport const targetFile = Flags.custom<TargetFile>({\n summary: \"target files to upload\",\n helpValue: \"file_path | package_name=file_path\",\n // eslint-disable-next-line @typescript-eslint/require-await -- oclif requires async but parsing is sync\n parse: async (arg) => parseTargetFile(arg),\n});\n","import { Command, Flags } from \"@oclif/core\";\nimport { getConfig } from \"../registry_v1/config\";\nimport { targetFile } from \"../registry_v1/flags\";\nimport fs from \"node:fs\";\nimport YAML from \"yaml\";\nimport { PlRegPackageConfigDataShard } from \"../registry_v1/config_schema\";\nimport { OclifLoggerAdapter } from \"@milaboratories/ts-helpers-oclif\";\n\ntype BasicConfigField = keyof PlRegPackageConfigDataShard &\n (\"registry\" | \"organization\" | \"package\" | \"version\");\nconst BasicConfigFields: BasicConfigField[] = [\"registry\", \"organization\", \"package\", \"version\"];\n\nexport default class UploadPackageV1 extends Command {\n static description = \"Uploads V1 package and refreshes the registry\";\n\n static flags = {\n registry: Flags.string({\n char: \"r\",\n summary: \"full address of the registry or alias from .pl.reg\",\n helpValue: \"<address|alias>\",\n env: \"PL_REGISTRY\",\n }),\n\n organization: Flags.string({\n char: \"o\",\n summary: \"target organisation\",\n env: \"PL_PACKAGE_ORGANIZATION\",\n }),\n\n package: Flags.string({\n char: \"p\",\n summary: \"target package\",\n env: \"PL_PACKAGE_NAME\",\n }),\n\n version: Flags.string({\n char: \"v\",\n summary: \"target version\",\n env: \"PL_PACKAGE_VERSION\",\n }),\n\n meta: Flags.file({\n char: \"m\",\n summary: \"json file containing meta information to associate with tha package\",\n exists: true,\n }),\n\n file: targetFile({\n char: \"f\",\n summary: \"package files\",\n multiple: true,\n default: [],\n }),\n\n refresh: Flags.boolean({\n summary: \"refresh repository after adding the package\",\n default: true,\n allowNo: true,\n env: \"PL_REGISTRY_REFRESH\",\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(UploadPackageV1);\n const configFromFlags: PlRegPackageConfigDataShard = PlRegPackageConfigDataShard.parse({});\n\n for (const field of BasicConfigFields) if (flags[field]) configFromFlags[field] = flags[field];\n\n if (flags.meta) {\n if (flags.meta.endsWith(\".json\"))\n configFromFlags.meta = JSON.parse(\n await fs.promises.readFile(flags.meta, { encoding: \"utf-8\" }),\n ) as Record<string, unknown>;\n else if (flags.meta.endsWith(\".yaml\"))\n configFromFlags.meta = YAML.parse(\n await fs.promises.readFile(flags.meta, { encoding: \"utf-8\" }),\n ) as Record<string, unknown>;\n }\n\n for (const targetFile of flags.file) {\n configFromFlags.files[targetFile.destName] = targetFile.src;\n }\n\n const conf = await getConfig(configFromFlags);\n\n this.log(YAML.stringify(conf.conf));\n\n const registry = conf.createRegistry(new OclifLoggerAdapter(this));\n const name = conf.fullPackageName;\n\n const builder = registry.constructNewPackage(name);\n\n for (const [dst, src] of Object.entries(conf.conf.files)) {\n this.log(`Uploading ${src} -> ${dst} ...`);\n const content = await fs.promises.readFile(src);\n await builder.addFile(dst, content);\n }\n\n this.log(`Uploading meta information...`);\n await builder.writeMeta(conf.conf.meta);\n await builder.finish();\n\n if (flags.refresh) await registry.updateIfNeeded();\n }\n}\n","// node:fs-backed implementation (synchronous). Anchored at a configured\n// `root`. All FileSystem methods take block-relative paths; this wrapper\n// joins them against root before touching disk.\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { DirEntry, FileSystem } from \"./api\";\n\nexport class NodeFileSystem implements FileSystem {\n constructor(private root: string) {}\n\n private abs(p: string): string {\n return path.resolve(this.root, p);\n }\n\n read(p: string): string {\n return fs.readFileSync(this.abs(p), \"utf-8\");\n }\n\n write(p: string, content: string): void {\n const a = this.abs(p);\n fs.mkdirSync(path.dirname(a), { recursive: true });\n fs.writeFileSync(a, content, \"utf-8\");\n }\n\n writeBinary(p: string, content: Uint8Array): void {\n const a = this.abs(p);\n fs.mkdirSync(path.dirname(a), { recursive: true });\n fs.writeFileSync(a, content);\n }\n\n exists(p: string): boolean {\n try {\n fs.statSync(this.abs(p));\n return true;\n } catch {\n return false;\n }\n }\n\n list(dir: string): string[] {\n const a = this.abs(dir);\n try {\n const stat = fs.statSync(a);\n if (!stat.isDirectory()) return [];\n } catch {\n return [];\n }\n const out: string[] = [];\n function walk(rel: string, absDir: string): void {\n const entries = fs.readdirSync(absDir, { withFileTypes: true });\n for (const e of entries) {\n const childRel = rel ? `${rel}/${e.name}` : e.name;\n const childAbs = path.join(absDir, e.name);\n if (e.isDirectory()) {\n walk(childRel, childAbs);\n } else if (e.isFile()) {\n out.push(childRel);\n }\n }\n }\n walk(dir === \"\" || dir === \".\" ? \"\" : dir, a);\n return out.sort();\n }\n\n listDir(dir: string): DirEntry[] {\n const a = this.abs(dir);\n let entries;\n try {\n entries = fs.readdirSync(a, { withFileTypes: true });\n } catch {\n return [];\n }\n return entries\n .map((e) => ({ name: e.name, isDirectory: e.isDirectory() }))\n .sort((x, y) => x.name.localeCompare(y.name));\n }\n\n move(from: string, to: string): void {\n const fromA = this.abs(from);\n const toA = this.abs(to);\n fs.mkdirSync(path.dirname(toA), { recursive: true });\n fs.renameSync(fromA, toA);\n }\n\n delete(p: string): void {\n fs.rmSync(this.abs(p), { recursive: true, force: true });\n }\n}\n","// Template-content provider for the runner.\n//\n// `file(path)` and `tpl(path, vars)` content forms resolve through this\n// provider. Static templates live at `<root>/static/`; templated text\n// lives at `<root>/text/`. The runner accepts a TemplateProvider via\n// `RunOptions.templates`; the production CLI wires a NodeTemplateProvider\n// rooted at the bundled `templates/` directory, and tests can use\n// `MemoryTemplateProvider` or point at the on-disk templates directory\n// during the Layer-2 zero-diff invariant.\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport interface TemplateProvider {\n /** Read a static template file (under `<root>/static/`). */\n staticRead(p: string): string;\n /** Read a static template file as raw bytes (under `<root>/static/`).\n * For binary assets (logos, images) that must not be utf-8 decoded. */\n staticReadBinary(p: string): Uint8Array;\n /** Read a text template file (under `<root>/text/`). */\n textRead(p: string): string;\n}\n\n/** Provider backed by an on-disk template tree. Reads are synchronous\n * so the runner can stay sync inside content-form resolution. */\nexport class NodeTemplateProvider implements TemplateProvider {\n constructor(private root: string) {}\n\n staticRead(p: string): string {\n return fs.readFileSync(path.resolve(this.root, \"static\", p), \"utf-8\");\n }\n\n staticReadBinary(p: string): Uint8Array {\n return fs.readFileSync(path.resolve(this.root, \"static\", p));\n }\n\n textRead(p: string): string {\n return fs.readFileSync(path.resolve(this.root, \"text\", p), \"utf-8\");\n }\n}\n\n/** In-memory provider for tests. Keyed by the same `static/...` /\n * `text/...` shape as on disk. */\nexport class MemoryTemplateProvider implements TemplateProvider {\n constructor(private files: Record<string, string>) {}\n\n staticRead(p: string): string {\n const k = `static/${p}`;\n const v = this.files[k];\n if (v === undefined) throw new Error(`MemoryTemplateProvider: missing '${k}'`);\n return v;\n }\n\n staticReadBinary(p: string): Uint8Array {\n // In-memory templates are stored as strings; expose their bytes. Real\n // binary assets are exercised through NodeTemplateProvider on disk.\n return new TextEncoder().encode(this.staticRead(p));\n }\n\n textRead(p: string): string {\n const k = `text/${p}`;\n const v = this.files[k];\n if (v === undefined) throw new Error(`MemoryTemplateProvider: missing '${k}'`);\n return v;\n }\n}\n\n/** Shell-style `${name}` substitution. Unknown names left as-is so\n * template authors notice. Backslash escape is not supported. */\nexport function substituteVars(text: string, vars: Record<string, string>): string {\n return text.replace(/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_m, name: string) => {\n return vars[name] ?? `\\${${name}}`;\n });\n}\n","// Flatten: DFS over the tree IR; fan out each scope frame once per\n// matching module in `ctx.modules`. Compose enclosing `when` triggers\n// (AND of all on the path from root). Track which run modes the leaf\n// fires in (its enclosing mode frame, or the `[\"default\", \"init\"]`\n// default) and emit that as `modes` on the FlatItem. No execution here —\n// execution lives in `runner.ts`.\n\nimport type { Module, RunContext, Scope } from \"./api\";\nimport type { FlatItem, LeafItem, RunMode, Structure, TreeNode, TriggerFn } from \"./ir\";\n\n/** Modes a leaf fires in when it sits outside any mode frame: default\n * refresh/check plus init. (`onUpdateDeps` / `onInitOrUpdate` frames\n * override this for their children.) */\nconst DEFAULT_MODES: RunMode[] = [\"default\", \"init\"];\n\nfunction resolveRelative(modulePath: string, fileRel: string): string {\n if (!modulePath) return fileRel;\n if (!fileRel) return modulePath;\n // Strip trailing slash on modulePath, leading slash on fileRel.\n const m = modulePath.endsWith(\"/\") ? modulePath.slice(0, -1) : modulePath;\n const f = fileRel.startsWith(\"/\") ? fileRel.slice(1) : fileRel;\n return f ? `${m}/${f}` : m;\n}\n\n/**\n * Lexicographic sort of modules by `path`.\n * Used for deterministic fan-out order.\n */\nfunction modulesByScope(modules: Module[], scope: Scope): Module[] {\n return modules\n .filter((m) => m.scope === scope)\n .slice()\n .sort((a, b) => a.path.localeCompare(b.path));\n}\n\nexport function flatten(structure: Structure, ctx: RunContext): FlatItem[] {\n const out: FlatItem[] = [];\n\n function visit(\n node: TreeNode,\n boundScope: Scope | undefined,\n boundModulePath: string | undefined,\n triggers: TriggerFn[],\n modes: RunMode[],\n ): void {\n if (node.kind === \"scope\") {\n const matches = modulesByScope(ctx.modules, node.scope);\n for (const m of matches) {\n for (const child of node.children) {\n visit(child, node.scope, m.path, triggers, modes);\n }\n }\n return;\n }\n if (node.kind === \"when\") {\n const nextTriggers = triggers.concat(node.trigger);\n for (const child of node.children) {\n visit(child, boundScope, boundModulePath, nextTriggers, modes);\n }\n return;\n }\n if (node.kind === \"mode\") {\n for (const child of node.children) {\n visit(child, boundScope, boundModulePath, triggers, node.modes);\n }\n return;\n }\n // Leaf.\n if (boundScope === undefined || boundModulePath === undefined) {\n throw new Error(`flatten: leaf '${describeLeaf(node)}' is not inside a scope() frame`);\n }\n if (node.kind === \"rename\") {\n out.push({\n leaf: node,\n scope: boundScope,\n modulePath: boundModulePath,\n resolvedPath: resolveRelative(boundModulePath, node.from),\n resolvedTo: resolveRelative(boundModulePath, node.to),\n triggers,\n modes,\n });\n return;\n }\n out.push({\n leaf: node,\n scope: boundScope,\n modulePath: boundModulePath,\n resolvedPath: resolveRelative(boundModulePath, leafPath(node)),\n triggers,\n modes,\n });\n }\n\n for (const node of structure.children) {\n visit(node, undefined, undefined, [], DEFAULT_MODES);\n }\n\n return out;\n}\n\nfunction leafPath(leaf: LeafItem): string {\n switch (leaf.kind) {\n case \"fixed\":\n case \"managed\":\n case \"scaffold\":\n case \"seed\":\n case \"remove\":\n return leaf.path;\n case \"rename\":\n return leaf.from;\n }\n}\n\nfunction describeLeaf(leaf: LeafItem): string {\n if (leaf.kind === \"rename\") return `rename ${leaf.from} -> ${leaf.to}`;\n return `${leaf.kind} ${leaf.path}`;\n}\n","// Minimal glob matcher for the structurer's file-existence triggers.\n//\n// Supports `**` (any number of path segments, including none), `*` (any\n// run of chars except `/`), and `?` (a single non-`/` char); every other\n// character is matched literally. No brace expansion / char classes — the\n// patterns we match are deliberately simple (e.g. `src/**/*.test.ts`).\n// Paths are matched whole (anchored at both ends).\n\nconst REGEXP_SPECIALS = /[.+^${}()|[\\]\\\\]/g;\n\n/** Compile a glob to an anchored RegExp. */\nexport function globToRegExp(glob: string): RegExp {\n let re = \"\";\n for (let i = 0; i < glob.length; i++) {\n const c = glob[i]!;\n if (c === \"*\") {\n if (glob[i + 1] === \"*\") {\n // `**`: any path segments. Absorb a following `/` so `**/x` also\n // matches `x` at depth 0 (zero segments).\n i++;\n if (glob[i + 1] === \"/\") {\n i++;\n re += \"(?:.*/)?\";\n } else {\n re += \".*\";\n }\n } else {\n re += \"[^/]*\";\n }\n } else if (c === \"?\") {\n re += \"[^/]\";\n } else {\n re += c.replace(REGEXP_SPECIALS, \"\\\\$&\");\n }\n }\n return new RegExp(`^${re}$`);\n}\n\n/** True if `path` matches `glob` (whole-path, anchored). */\nexport function matchesGlob(glob: string, path: string): boolean {\n return globToRegExp(glob).test(path);\n}\n","// `defineStructure` + the module-global builder set.\n//\n// Active context is a module-level mutable: `defineStructure` pushes a\n// fresh tree state, invokes the zero-arg lambda, pops, returns. Each\n// builder reads the active state and appends to the current children\n// list. Calling a builder outside `defineStructure` throws with a\n// clear message. Re-entering `defineStructure` from inside another\n// `defineStructure` lambda is rejected.\n\nimport type { Scope, RunContext, BlockVars, ContentForm } from \"./api\";\nimport type {\n ManagedBody,\n Structure,\n TriggerFn,\n TreeNode,\n ScopeFrame,\n WhenFrame,\n ModeFrame,\n RunMode,\n} from \"./ir\";\n\ntype TreeState = {\n root: TreeNode[];\n /** Stack of children-lists; top is where new nodes append. */\n stack: TreeNode[][];\n inScope: boolean;\n};\n\nlet activeTree: TreeState | undefined;\nlet activeRunContext: RunContext | undefined;\n\nfunction requireActiveTree(builder: string): TreeState {\n if (!activeTree) {\n throw new Error(\n `${builder}() called outside defineStructure(). ` +\n `Builders must run inside the lambda passed to defineStructure(...).`,\n );\n }\n return activeTree;\n}\n\nfunction appendNode(builder: string, node: TreeNode): void {\n const t = requireActiveTree(builder);\n t.stack[t.stack.length - 1]!.push(node);\n}\n\n/** Engine-internal: scope `blockVars()` lookups during a run. The body is\n * synchronous, so the module-global `activeRunContext` cannot be observed\n * by an interleaved run — a sync call stack runs to completion before any\n * other `run()` can start. The try/finally restores the previous context\n * (supporting the nested-run case the post-run recheck used to imply). */\nexport function withRunContext<T>(ctx: RunContext, fn: () => T): T {\n const prev = activeRunContext;\n activeRunContext = ctx;\n try {\n return fn();\n } finally {\n activeRunContext = prev;\n }\n}\n\n/** Engine-internal: content-rule builders that need `ctx.modules` look\n * up the active context through this accessor. Returns `undefined`\n * outside a run. */\nexport function tryGetActiveRunContext(): RunContext | undefined {\n return activeRunContext;\n}\n\n/** Get-or-die counterpart of `tryGetActiveRunContext`. Generators run\n * only inside `engine.run()`; an absent context is framework misuse, not\n * a valid state, so throw rather than emit degenerate (empty) output.\n * Mirrors `blockVars()`. */\nexport function getActiveRunContext(): RunContext {\n if (!activeRunContext) {\n throw new Error(\n \"getActiveRunContext() called outside engine.run(). \" +\n \"Generators only see the run context during a run.\",\n );\n }\n return activeRunContext;\n}\n\n/** The single entry point: build a {@link Structure} from `fn`, which calls\n * the scaffold-DSL builders (`scope`, `fixed`, `managed`, `seed`, …). Throws\n * if called nested, or if `fn` leaves an unclosed group frame. */\nexport function defineStructure(fn: () => void): Structure {\n if (activeTree) {\n throw new Error(\"defineStructure() cannot be called from inside another defineStructure().\");\n }\n const root: TreeNode[] = [];\n const state: TreeState = { root, stack: [root], inScope: false };\n activeTree = state;\n try {\n fn();\n if (state.stack.length !== 1) {\n throw new Error(\n `defineStructure: builder body left ${state.stack.length - 1} unclosed group frame(s)`,\n );\n }\n const structure: Structure = { children: root };\n // Validation: a path may not appear as both `seed` and any\n // engine-managed primitive (`fixed` / `managed` / `scaffold`) within\n // the same scope. The two contracts (write-once-and-ignore vs\n // rewrite-on-every-refresh) are mutually exclusive. Detect at\n // tree-build time.\n validateSeedDisjointness(structure);\n return structure;\n } finally {\n activeTree = undefined;\n }\n}\n\nfunction validateSeedDisjointness(structure: Structure): void {\n // (scope) → (path) → set of leaf kinds present at that path.\n const perScope = new Map<string, Map<string, Set<string>>>();\n\n function visit(node: TreeNode, scopeName: string): void {\n if (node.kind === \"scope\") {\n for (const c of node.children) visit(c, node.scope);\n return;\n }\n if (node.kind === \"when\" || node.kind === \"mode\") {\n for (const c of node.children) visit(c, scopeName);\n return;\n }\n if (node.kind === \"rename\") return; // rename works on paths; not a content leaf\n let scopeMap = perScope.get(scopeName);\n if (!scopeMap) {\n scopeMap = new Map();\n perScope.set(scopeName, scopeMap);\n }\n let kinds = scopeMap.get(node.path);\n if (!kinds) {\n kinds = new Set();\n scopeMap.set(node.path, kinds);\n }\n kinds.add(node.kind);\n }\n\n for (const n of structure.children) visit(n, \"(top-level)\");\n\n for (const [scopeName, paths] of perScope) {\n for (const [path, kinds] of paths) {\n if (\n kinds.has(\"seed\") &&\n (kinds.has(\"managed\") || kinds.has(\"fixed\") || kinds.has(\"scaffold\"))\n ) {\n const others = [...kinds]\n .filter((k) => k !== \"seed\")\n .sort()\n .join(\", \");\n throw new Error(\n `defineStructure validation: path '${path}' under scope '${scopeName}' ` +\n `is declared as both seed and ${others}. Seeds are block-author territory ` +\n `(written once at init, untouched thereafter); engine-managed primitives ` +\n `(fixed/managed/scaffold) rewrite on every refresh. The two contracts cannot ` +\n `coexist on the same path.`,\n );\n }\n }\n }\n}\n\n/** Open a scope (`root` / `block` / `model` / `ui` / `workflow` / `test` /\n * `software`); builders called inside `body` attach to it. Cannot nest. */\nexport function scope(name: Scope, body: () => void): void {\n const t = requireActiveTree(\"scope\");\n if (t.inScope) {\n throw new Error(\"scope() cannot nest. Already inside a scope.\");\n }\n const frame: ScopeFrame = { kind: \"scope\", scope: name, children: [] };\n t.stack[t.stack.length - 1]!.push(frame);\n t.stack.push(frame.children);\n t.inScope = true;\n try {\n body();\n } finally {\n t.stack.pop();\n t.inScope = false;\n }\n}\n\n/** Inner-mode `when` handler. Registered by `content-rules.ts` at\n * load time. Returns true if the call was dispatched (an inner active\n * state was present); false otherwise. Avoids a circular import. */\ntype InnerWhenHandler = (trigger: TriggerFn, body: () => void) => boolean;\nlet innerWhenHandler: InnerWhenHandler | undefined;\n\n/** Engine-internal: register the inner-mode `when` handler (set by\n * `content-rules.ts` at load time to avoid a circular import). */\nexport function registerInnerWhenHandler(h: InnerWhenHandler): void {\n innerWhenHandler = h;\n}\n\n/**\n * Conditionally run `body`. Two dispatch modes by active state:\n * - inside `defineStructure(...)` → push a `WhenFrame` into the tree;\n * trigger fires later at runner time per `FlatItem`.\n * - inside a `managed(...)` body → evaluate `trigger` immediately\n * against the runner-supplied `TriggerContext`; run/skip `body`\n * synchronously.\n *\n * One `when` symbol for both layers — same user contract, dispatch\n * picks the matching execution timing.\n */\nexport function when(trigger: TriggerFn, body: () => void): void {\n if (activeTree) {\n const t = activeTree;\n const frame: WhenFrame = { kind: \"when\", trigger, children: [] };\n t.stack[t.stack.length - 1]!.push(frame);\n t.stack.push(frame.children);\n try {\n body();\n } finally {\n t.stack.pop();\n }\n return;\n }\n if (innerWhenHandler && innerWhenHandler(trigger, body)) return;\n throw new Error(\n \"when() called outside defineStructure() and outside any managed(...) body. \" +\n \"Place this call inside one of the two.\",\n );\n}\n\n/** Trigger factory: true when at least one file in the leaf's module\n * matches `glob` (module-relative — see `TriggerContext.filesMatch`). Use\n * to gate a rule on the presence of co-located files, e.g. add a vitest\n * `test` script only when `src/**\\/*.test.ts` exists. Pairs with `when`:\n * `when(whenFilesExist(\"src/**\\/*.test.ts\"), () => { ... })`. */\nexport function whenFilesExist(glob: string): TriggerFn {\n return (tctx) => tctx.filesMatch(glob);\n}\n\nfunction pushModeFrame(builder: string, modes: RunMode[], body: () => void): void {\n const t = requireActiveTree(builder);\n const frame: ModeFrame = { kind: \"mode\", modes, children: [] };\n t.stack[t.stack.length - 1]!.push(frame);\n t.stack.push(frame.children);\n try {\n body();\n } finally {\n t.stack.pop();\n }\n}\n\n/** Leaves inside fire ONLY under `--update-deps-only` (mode\n * `\"updateDeps\"`); they are skipped on default refresh/check and init. */\nexport function onUpdateDeps(body: () => void): void {\n pushModeFrame(\"onUpdateDeps\", [\"updateDeps\"], body);\n}\n\n/** Leaves inside fire on `init` AND `--update-deps-only`, but NOT on\n * default refresh/check. The frame for rules that resolve/write current\n * versions: both init and update-deps mean \"fetch and write latest\",\n * while a plain refresh leaves them as the author/lockfile has them. */\nexport function onInitOrUpdate(body: () => void): void {\n pushModeFrame(\"onInitOrUpdate\", [\"init\", \"updateDeps\"], body);\n}\n\n/** Engine-OWNED file: (re)written verbatim from `content` on every refresh —\n * author edits are overwritten. */\nexport function fixed(path: string, content: ContentForm): void {\n appendNode(\"fixed\", { kind: \"fixed\", path, content });\n}\n\n/** Engine-RECONCILED file: parsed from disk (or `initial` when absent),\n * mutated by `body` (the JSON/YAML/lines builders), then re-serialised.\n * Content the body does not touch is preserved. */\nexport function managed(path: string, initial: ContentForm, body: ManagedBody): void {\n appendNode(\"managed\", { kind: \"managed\", path, initial, body });\n}\n\n/** Write-once file: created from `initial` if absent (on init AND refresh),\n * never overwritten once present. For files the author subsequently owns. */\nexport function scaffold(path: string, initial: ContentForm): void {\n appendNode(\"scaffold\", { kind: \"scaffold\", path, initial });\n}\n\n/** Author-owned starter file: written from `initial` only on `init`, and only\n * if absent; `refresh` / `check` never touch it. */\nexport function seed(path: string, initial: ContentForm): void {\n appendNode(\"seed\", { kind: \"seed\", path, initial });\n}\n\n/** Delete `path` if present, on every refresh. */\nexport function remove(path: string): void {\n appendNode(\"remove\", { kind: \"remove\", path });\n}\n\n/** Rename file `from` → `to` on refresh (migrating a renamed scaffold file). */\nexport function rename(from: string, to: string): void {\n appendNode(\"rename\", { kind: \"rename\", from, to });\n}\n\n/** Content form: a UTF-8 static template read from the structurer's static\n * templates. Use inside `fixed` / `managed` / `scaffold` / `seed`. */\nexport function file(path: string): ContentForm {\n return { kind: \"file\", path };\n}\n\n/** A binary static asset (e.g. a logo) read verbatim from `<root>/static/`.\n * Unlike `file()`, the bytes are never decoded to a string — use for\n * images / archives. Only valid inside `seed()` / `scaffold()`. */\nexport function binaryFile(path: string): ContentForm {\n return { kind: \"binary\", path };\n}\n\n/** Content form: an inline literal string. */\nexport function text(value: string): ContentForm {\n return { kind: \"text\", value };\n}\n\n/** Content form: a text template (the structurer's `text/` templates) with\n * `${var}` placeholders substituted from `vars`. */\nexport function tpl(\n path: string,\n vars: Record<string, string> | (() => Record<string, string>),\n): ContentForm {\n return { kind: \"tpl\", path, vars };\n}\n\n/** Content form: content computed at run time. The return value is serialised\n * as JSON / YAML by the target file's extension, or used verbatim if it is\n * already a string. */\nexport function generate(fn: () => unknown): ContentForm {\n return { kind: \"generate\", fn };\n}\n\n/** The active run's {@link BlockVars} (block name parts + software platform).\n * Valid only during a run (inside a generator or managed body); throws\n * otherwise. */\nexport function blockVars(): BlockVars {\n if (!activeRunContext) {\n throw new Error(\n \"blockVars() called outside engine.run(). \" +\n \"Generators and managed bodies only see BlockVars during a run.\",\n );\n }\n return activeRunContext.blockVars;\n}\n","// JSON parser + serialiser + jsonPath helpers + top-level key reorder.\n//\n// `parseJson`/`stringifyJson` are the canonical round-trip primitives the\n// managed pass uses. The dot-notation helpers (`getAtPath`, `setAtPath`,\n// `hasAtPath`, `deleteAtPath`) back the content-rule builders. `reorderTopLevel`\n// implements the \"known keys in declared order, unknown keys stay adjacent to\n// preceding known key\" projection.\n\nexport type JsonValue = string | number | boolean | null | JsonValue[] | { [k: string]: JsonValue };\n\nexport type JsonObject = { [k: string]: unknown };\n\n/** Parse JSON; throws on invalid input. */\nexport function parseJson(raw: string): unknown {\n return JSON.parse(raw);\n}\n\n// oxfmt formats JSON two ways, keyed on filename:\n// - package.json: every array/object fully expanded, one element per line,\n// regardless of width (what `JSON.stringify(…, 2)` already produces).\n// - any other .json (e.g. tsconfig.json): oxfmt's generic shape —\n// * objects: always expanded, one property per line (oxfmt preserves\n// the brace newline, so the expanded form is a fixpoint);\n// * arrays: collapsed onto one line when that line — its indent, the\n// `\"key\": ` prefix, the flat array, and a trailing comma if a sibling\n// follows — fits `PRINT_WIDTH` (oxfmt's default 100), else broken one\n// element per line.\n// This is exactly the form `oxfmt` itself produces, verified against\n// oxfmt 0.35 at the array boundary (≤100 collapses, 101 breaks; a\n// trailing comma counts) and across all in-mono blocks. The single-\n// element `include` array was the regression: `JSON.stringify` expanded\n// it while oxfmt collapses it.\n// `stringifyJson` defaults to the expanded form; callers serialising a\n// generic .json pass `{ collapse: true }` so the output is oxfmt-clean by\n// construction (no prior `pnpm fmt` needed for `check` — the same\n// emit-clean-by-design contract as the canonical key/dependency ordering).\nconst PRINT_WIDTH = 100;\nconst INDENT = 2;\n\n/** One-line rendering of an array, matching oxfmt's flat spacing: `[a, b]`\n * (no inner padding), nested objects inline as `{ \"k\": v }`, empty `[]`.\n * Only arrays collapse, so this is the array-fits primitive. */\nfunction flatArray(value: unknown[]): string {\n if (value.length === 0) return \"[]\";\n return \"[\" + value.map(flatValue).join(\", \") + \"]\";\n}\n\n/** One-line rendering of any value (used inside a collapsed array, where\n * contained objects render inline). */\nfunction flatValue(value: unknown): string {\n if (Array.isArray(value)) return flatArray(value);\n if (isObject(value)) {\n const entries = Object.entries(value);\n if (entries.length === 0) return \"{}\";\n return (\n \"{ \" + entries.map(([k, v]) => `${JSON.stringify(k)}: ${flatValue(v)}`).join(\", \") + \" }\"\n );\n }\n return JSON.stringify(value);\n}\n\n/** Print `value` starting at `column`. Objects always break (one property per\n * line); arrays collapse when their flat line — `column` + the flat array +\n * `reserved` (1 for a trailing comma when a sibling follows) — fits\n * `PRINT_WIDTH`, else break. `indent` is the leading-space width of the line\n * the container opens on. */\nfunction printValue(value: unknown, indent: number, column: number, reserved: number): string {\n const inner = indent + INDENT;\n const pad = \" \".repeat(inner);\n if (Array.isArray(value)) {\n const flat = flatArray(value);\n if (column + flat.length + reserved <= PRINT_WIDTH) return flat;\n const last = value.length - 1;\n const lines = value.map((item, i) => pad + printValue(item, inner, inner, i === last ? 0 : 1));\n return \"[\\n\" + lines.join(\",\\n\") + \"\\n\" + \" \".repeat(indent) + \"]\";\n }\n if (isObject(value)) {\n const entries = Object.entries(value);\n if (entries.length === 0) return \"{}\";\n const last = entries.length - 1;\n const lines = entries.map(([k, v], i) => {\n const prefix = `${pad}${JSON.stringify(k)}: `;\n return prefix + printValue(v, inner, prefix.length, i === last ? 0 : 1);\n });\n return \"{\\n\" + lines.join(\",\\n\") + \"\\n\" + \" \".repeat(indent) + \"}\";\n }\n return JSON.stringify(value);\n}\n\n/** Canonical serialiser: 2-space indent, trailing newline.\n * Default — every container expanded (the package.json shape, byte-identical\n * to `JSON.stringify(…, 2)`).\n * `{ collapse: true }` — oxfmt's generic-.json shape: containers that fit\n * `PRINT_WIDTH` collapse onto one line. Used for tsconfig.json and any other\n * non-package.json the engine emits, so `oxfmt --check` passes without a\n * prior format pass. */\nexport function stringifyJson(value: unknown, opts?: { collapse?: boolean }): string {\n if (!opts?.collapse) return JSON.stringify(value, null, 2) + \"\\n\";\n // Normalise through a round-trip so non-JSON inputs (undefined values,\n // functions) are dropped exactly as `JSON.stringify` would.\n const normalized = JSON.parse(JSON.stringify(value ?? null));\n return printValue(normalized, 0, 0, 0) + \"\\n\";\n}\n\nfunction splitPath(jsonPath: string): string[] {\n if (jsonPath === \"\" || jsonPath === undefined) return [];\n return jsonPath.split(\".\");\n}\n\nfunction isObject(v: unknown): v is JsonObject {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Get the value at `jsonPath`. Returns `undefined` if any segment is\n * missing or not an object. */\nexport function getAtPath(obj: JsonObject, jsonPath: string): unknown {\n const parts = splitPath(jsonPath);\n let cur: unknown = obj;\n for (const p of parts) {\n if (!isObject(cur)) return undefined;\n cur = cur[p];\n }\n return cur;\n}\n\n/** True if `jsonPath` resolves to a defined value (including `null`). */\nexport function hasAtPath(obj: JsonObject, jsonPath: string): boolean {\n const parts = splitPath(jsonPath);\n if (parts.length === 0) return true;\n let cur: unknown = obj;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!isObject(cur)) return false;\n cur = cur[parts[i]!];\n }\n if (!isObject(cur)) return false;\n return parts[parts.length - 1]! in cur;\n}\n\n/** Set `value` at `jsonPath`. Auto-creates intermediate objects. Throws\n * if a non-object value is on the path (would be silently overwritten\n * otherwise — caller bug). */\nexport function setAtPath(obj: JsonObject, jsonPath: string, value: unknown): void {\n const parts = splitPath(jsonPath);\n if (parts.length === 0) {\n throw new Error(\"setAtPath: jsonPath must be non-empty\");\n }\n let cur: JsonObject = obj;\n for (let i = 0; i < parts.length - 1; i++) {\n const k = parts[i]!;\n const next = cur[k];\n if (next === undefined) {\n const fresh: JsonObject = {};\n cur[k] = fresh;\n cur = fresh;\n } else if (isObject(next)) {\n cur = next;\n } else {\n throw new Error(\n `setAtPath: cannot descend into non-object at '${parts.slice(0, i + 1).join(\".\")}'`,\n );\n }\n }\n cur[parts[parts.length - 1]!] = value;\n}\n\n/** Delete the value at `jsonPath`. No-op if any segment is missing. */\nexport function deleteAtPath(obj: JsonObject, jsonPath: string): void {\n const parts = splitPath(jsonPath);\n if (parts.length === 0) {\n throw new Error(\"deleteAtPath: jsonPath must be non-empty\");\n }\n let cur: unknown = obj;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!isObject(cur)) return;\n cur = cur[parts[i]!];\n }\n if (!isObject(cur)) return;\n delete cur[parts[parts.length - 1]!];\n}\n\n/**\n * Reorder top-level keys of `obj`:\n * - Known keys (those listed in `order`) appear in declared order.\n * - Unknown keys (not in `order`) stay adjacent to the preceding known\n * key they followed in the source. Unknown keys appearing before any\n * known key go first, in source order.\n */\nexport function reorderTopLevel(obj: JsonObject, order: readonly string[]): JsonObject {\n const known = new Set(order);\n const sourceKeys = Object.keys(obj);\n\n const adjacents = new Map<string, string[]>();\n adjacents.set(\"\", []);\n let anchor = \"\";\n for (const k of sourceKeys) {\n if (known.has(k)) {\n anchor = k;\n adjacents.set(anchor, []);\n } else {\n adjacents.get(anchor)!.push(k);\n }\n }\n\n const out: JsonObject = {};\n for (const k of adjacents.get(\"\")!) out[k] = obj[k];\n for (const k of order) {\n if (!(k in obj)) continue;\n out[k] = obj[k];\n for (const u of adjacents.get(k) ?? []) out[u] = obj[u];\n }\n return out;\n}\n","// .gitignore-style line list parser/serialiser.\n//\n// `parseLines` keeps the file verbatim as an array of lines (one per\n// \"\\n\"). `serializeLines` joins them with \"\\n\" and guarantees a trailing\n// newline. `normaliseLine` strips comments and surrounding whitespace —\n// used by the `ensureGitignoreEntries` family to compare an existing\n// line to a required entry without being fooled by inline `#` comments\n// or extra indentation.\n\nexport function parseLines(raw: string): string[] {\n // Drop the synthetic empty entry caused by a trailing newline so a\n // serialise-then-parse round-trip is stable.\n const lines = raw.split(\"\\n\");\n if (lines.length > 0 && lines[lines.length - 1] === \"\") lines.pop();\n return lines;\n}\n\nexport function serializeLines(lines: readonly string[]): string {\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/** Strip leading/trailing whitespace and trailing inline `# ...` comments.\n * Returns empty string for blank / comment-only lines. */\nexport function normaliseLine(line: string): string {\n const noComment = line.replace(/(^|\\s)#.*$/, \"$1\");\n return noComment.trim();\n}\n\n/** True if `line` (after normalisation) equals `entry` (after trim). */\nexport function lineEqualsEntry(line: string, entry: string): boolean {\n const n = normaliseLine(line);\n if (n === \"\") return false;\n return n === entry.trim();\n}\n\n/** True if any line in `lines` normalises to `entry`. */\nexport function containsEntry(lines: readonly string[], entry: string): boolean {\n for (const line of lines) {\n if (lineEqualsEntry(line, entry)) return true;\n }\n return false;\n}\n","// Content-rules DSL — builders that mutate the parsed representation\n// of a `managed(path, initial, body)` file.\n//\n// Three active-state kinds correspond to three file flavours:\n// - JSON object (package.json) → withManagedBody(obj, body)\n// - YAML Document (pnpm-workspace.yaml) → withManagedYaml(doc, body)\n// - line list (.gitignore) → withManagedLines(lines, body)\n//\n// Each builder verifies it is invoked under the matching active state\n// and throws otherwise. The full inventory: JSON\n// ensure*/remove*/require*/prune/enforce*/transform; YAML catalog\n// management + workspace module paths; gitignore line management.\n\nimport { registerInnerWhenHandler, tryGetActiveRunContext } from \"./builders\";\nimport type { RunContext, Scope } from \"./api\";\nimport type { TriggerContext, TriggerFn } from \"./ir\";\nimport {\n deleteAtPath,\n getAtPath,\n hasAtPath,\n reorderTopLevel,\n setAtPath,\n type JsonObject,\n} from \"./parsers/json\";\nimport { containsEntry, normaliseLine } from \"./parsers/lines\";\nimport type { YamlDocument } from \"./parsers/yaml\";\n\nexport type { JsonObject };\n\n/** Allowed dep version strings. Specific versions live in the catalog.\n * `\"sdk:\"` is an authoring abstraction, not an on-disk value: the engine\n * resolves it at write time (`workspace:*` when `ctx.isSdkInternal`, else\n * `\"catalog:\"`) and the resolved literal is what serializes. Use it for\n * every dep that is a member of the platforma monorepo's pnpm workspace\n * (the `@platforma-sdk/*` packages + `@milaboratories/ts-builder` /\n * `ts-configs`). */\nexport type DepVersion = \"catalog:\" | \"sdk:\" | `workspace:${string}` | \"*\";\n\n/** Resolve the `\"sdk:\"` sentinel to its on-disk literal. All other\n * `DepVersion` forms pass through unchanged — `\"sdk:\"` never serializes. */\nexport function resolveDepVersion(\n version: DepVersion,\n isSdkInternal: boolean,\n): Exclude<DepVersion, \"sdk:\"> {\n if (version === \"sdk:\") return isSdkInternal ? \"workspace:*\" : \"catalog:\";\n return version;\n}\n\nconst DEP_SECTION_KEYS = [\n \"dependencies\",\n \"devDependencies\",\n \"peerDependencies\",\n \"optionalDependencies\",\n] as const;\n\n/** Resolve any `\"sdk:\"` sentinels in the dep sections of a generated\n * package.json object, in place. Mirrors `resolveDepVersion` for the\n * generator (`initial` content) path — the runner calls this on every\n * `generate()`-produced `.json` value so the sentinel never reaches disk\n * via a generator. */\nexport function resolveSdkSentinelsInJson(value: unknown, isSdkInternal: boolean): void {\n if (!isObject(value)) return;\n for (const section of DEP_SECTION_KEYS) {\n const sec = value[section];\n if (!isObject(sec)) continue;\n for (const k of Object.keys(sec)) {\n if (sec[k] === \"sdk:\") sec[k] = isSdkInternal ? \"workspace:*\" : \"catalog:\";\n }\n }\n}\n\ntype JsonState = {\n kind: \"json\";\n obj: JsonObject;\n ctx?: RunContext;\n triggerContext?: TriggerContext;\n};\n\ntype YamlState = {\n kind: \"yaml\";\n doc: YamlDocument;\n ctx?: RunContext;\n triggerContext?: TriggerContext;\n /** Synchronous accessor for prefetched npm latest versions. */\n getLatestVersion?: (packageName: string) => string | undefined;\n};\n\ntype LinesState = {\n kind: \"lines\";\n lines: string[];\n ctx?: RunContext;\n triggerContext?: TriggerContext;\n};\n\ntype ActiveState = JsonState | YamlState | LinesState;\n\nlet active: ActiveState | undefined;\n\nfunction requireActive(builder: string): ActiveState {\n if (!active) {\n throw new Error(\n `${builder}() only valid inside a managed(...) body. ` +\n `Move this call inside managed(path, initial, () => {...}).`,\n );\n }\n return active;\n}\n\nfunction requireJson(builder: string): JsonState {\n const a = requireActive(builder);\n if (a.kind !== \"json\") {\n throw new Error(`${builder}() requires a JSON-managed body; got '${a.kind}'.`);\n }\n return a;\n}\n\nfunction requireYaml(builder: string): YamlState {\n const a = requireActive(builder);\n if (a.kind !== \"yaml\") {\n throw new Error(`${builder}() requires a YAML-managed body; got '${a.kind}'.`);\n }\n return a;\n}\n\nfunction requireLines(builder: string): LinesState {\n const a = requireActive(builder);\n if (a.kind !== \"lines\") {\n throw new Error(`${builder}() requires a lines-managed body; got '${a.kind}'.`);\n }\n return a;\n}\n\nfunction ctxOrThrow(state: ActiveState, builder: string): RunContext {\n const c = state.ctx ?? tryGetActiveRunContext();\n if (!c) {\n throw new Error(\n `${builder}() needs a RunContext but none is active. ` +\n `Pass { ctx } via the with-managed-* helper or run inside engine.run(...).`,\n );\n }\n return c;\n}\n\nfunction isObject(v: unknown): v is JsonObject {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n// --- Active-context wrappers (used by the runner + Layer-1 helpers) ---\n\nexport type WithManagedOpts = {\n ctx?: RunContext;\n /** Trigger context for `when(...)` calls inside the body. The runner\n * builds this from the post-structural-pass FS snapshot + run ctx.\n * Without it, `when(...)` inside the body throws. */\n triggerContext?: TriggerContext;\n};\n\n/** Engine-internal: run `body` with `obj` as the active JSON state so the\n * JSON builders mutate it; returns the mutated object. Exported for tests —\n * the runner calls this for managed `.json` files. */\nexport function withManagedBody(\n obj: JsonObject,\n body: () => void,\n opts: WithManagedOpts = {},\n): JsonObject {\n if (active) throw new Error(\"Nested managed(...) body — engine bug.\");\n active = { kind: \"json\", obj, ctx: opts.ctx, triggerContext: opts.triggerContext };\n try {\n body();\n return obj;\n } finally {\n active = undefined;\n }\n}\n\nexport type WithManagedYamlOpts = WithManagedOpts & {\n /** Sync accessor for prefetched latest versions. Required for\n * `ensureCatalogLatest` to take effect. */\n getLatestVersion?: (packageName: string) => string | undefined;\n};\n\n/** Engine-internal: run `body` with `doc` as the active YAML state (for\n * `pnpm-workspace.yaml`); returns the mutated document. Exported for tests. */\nexport function withManagedYaml(\n doc: YamlDocument,\n body: () => void,\n opts: WithManagedYamlOpts = {},\n): YamlDocument {\n if (active) throw new Error(\"Nested managed(...) body — engine bug.\");\n active = {\n kind: \"yaml\",\n doc,\n ctx: opts.ctx,\n triggerContext: opts.triggerContext,\n getLatestVersion: opts.getLatestVersion,\n };\n try {\n body();\n return doc;\n } finally {\n active = undefined;\n }\n}\n\n/** Engine-internal: run `body` with `lines` as the active line-based state\n * (for `.gitignore`); returns the mutated lines. Exported for tests. */\nexport function withManagedLines(\n lines: string[],\n body: () => void,\n opts: WithManagedOpts = {},\n): string[] {\n if (active) throw new Error(\"Nested managed(...) body — engine bug.\");\n active = {\n kind: \"lines\",\n lines,\n ctx: opts.ctx,\n triggerContext: opts.triggerContext,\n };\n try {\n body();\n return lines;\n } finally {\n active = undefined;\n }\n}\n\n// --- Inner-when handler registration ---\n//\n// `when(...)` is exported from `builders.ts`. When the active tree is\n// absent (we are inside a managed body, not inside `defineStructure`),\n// it delegates here. The handler returns true iff there is an inner\n// active state to dispatch against; the caller in `builders.ts` then\n// treats the call as handled. Outer/inner dispatch lives in one\n// exported `when` symbol — no separate inner-when builder.\n\nregisterInnerWhenHandler((trigger: TriggerFn, body: () => void): boolean => {\n if (!active) return false;\n const tctx = active.triggerContext;\n if (!tctx) {\n throw new Error(\n \"when() inside a managed(...) body requires a triggerContext. \" +\n \"The runner supplies it via the `triggerContext` opt to with-managed-*; \" +\n \"ensure your test/test helper passes one.\",\n );\n }\n if (trigger(tctx)) body();\n return true;\n});\n\n// ============================================================\n// JSON builders — `package.json` (and other JSON managed files)\n// ============================================================\n\n/** Set the value at `jsonPath` in the active managed JSON object. */\nexport function ensureField(jsonPath: string, value: unknown): void {\n setAtPath(requireJson(\"ensureField\").obj, jsonPath, value);\n}\n\n/** Remove the field at `jsonPath`. With `predicate`, only removes when\n * the predicate returns true against the current value. */\nexport function removeField(\n jsonPath: string,\n predicate?: (currentValue: unknown) => boolean,\n): void {\n const obj = requireJson(\"removeField\").obj;\n if (!hasAtPath(obj, jsonPath)) return;\n if (predicate) {\n const current = getAtPath(obj, jsonPath);\n if (!predicate(current)) return;\n }\n deleteAtPath(obj, jsonPath);\n}\n\n/** Assert a field exists; throw if absent. No mutation. */\nexport function requireField(jsonPath: string, message?: string): void {\n const obj = requireJson(\"requireField\").obj;\n if (!hasAtPath(obj, jsonPath)) {\n throw new Error(message ?? `requireField: missing field '${jsonPath}'`);\n }\n}\n\n/** Merge `entries` into the object at `jsonPath`. Auto-creates the\n * object if missing. Existing other entries preserved. */\nexport function ensureFieldEntries(jsonPath: string, entries: Record<string, unknown>): void {\n const obj = requireJson(\"ensureFieldEntries\").obj;\n const current = hasAtPath(obj, jsonPath) ? getAtPath(obj, jsonPath) : undefined;\n const base: JsonObject = isObject(current) ? current : {};\n for (const [k, v] of Object.entries(entries)) base[k] = v;\n if (!isObject(current)) setAtPath(obj, jsonPath, base);\n}\n\n/** Set `scripts.<name>` to `command`. */\nexport function ensureScript(name: string, command: string): void {\n ensureField(`scripts.${name}`, command);\n}\n\n/** Remove `scripts.<name>` if present. */\nexport function removeScript(name: string): void {\n removeField(`scripts.${name}`);\n}\n\n// --- Dependency builders ---\n\nconst DEP_SECTIONS = [\n \"dependencies\",\n \"devDependencies\",\n \"peerDependencies\",\n \"optionalDependencies\",\n] as const;\ntype DepSection = (typeof DEP_SECTIONS)[number];\n\nfunction ensureInSection(\n builder: string,\n name: string,\n version: DepVersion,\n section: DepSection,\n): void {\n const state = requireJson(builder);\n const obj = state.obj;\n // Resolve the `sdk:` sentinel against the run mode before writing — it\n // must never reach disk.\n const resolved =\n version === \"sdk:\"\n ? resolveDepVersion(version, ctxOrThrow(state, builder).isSdkInternal)\n : version;\n // Single-section invariant: remove from any other section first.\n for (const s of DEP_SECTIONS) {\n if (s === section) continue;\n const sec = obj[s];\n if (isObject(sec) && name in sec) delete sec[name];\n }\n const existing = obj[section];\n const target: JsonObject = isObject(existing) ? existing : {};\n target[name] = resolved;\n if (!isObject(existing)) obj[section] = target;\n}\n\n/** Pin `name` to `version` in `dependencies`. Enforces the single-section\n * invariant — `name` may live in only one dependency section, so it is\n * removed from the others first. A `sdk:` sentinel version is resolved\n * against the run's `--sdk-internal` flag before it reaches disk. */\nexport function ensureDep(name: string, version: DepVersion): void {\n ensureInSection(\"ensureDep\", name, version, \"dependencies\");\n}\n\n/** Pin `name` to `version` in `devDependencies` (see {@link ensureDep} for the\n * single-section + `sdk:` semantics). */\nexport function ensureDevDep(name: string, version: DepVersion): void {\n ensureInSection(\"ensureDevDep\", name, version, \"devDependencies\");\n}\n\n/** Pin `name` to `version` in `peerDependencies` (see {@link ensureDep}). */\nexport function ensurePeerDep(name: string, version: DepVersion): void {\n ensureInSection(\"ensurePeerDep\", name, version, \"peerDependencies\");\n}\n\n/** Pin `name` to `version` in `optionalDependencies` (see {@link ensureDep}). */\nexport function ensureOptionalDep(name: string, version: DepVersion): void {\n ensureInSection(\"ensureOptionalDep\", name, version, \"optionalDependencies\");\n}\n\n/** Remove `name` from every dependency section. */\nexport function removeDep(name: string): void {\n const obj = requireJson(\"removeDep\").obj;\n for (const s of DEP_SECTIONS) {\n const sec = obj[s];\n if (isObject(sec) && name in sec) delete sec[name];\n }\n}\n\n/** Bulk {@link ensureDep} for each `name → version` entry. */\nexport function ensureDeps(entries: Record<string, DepVersion>): void {\n for (const [n, v] of Object.entries(entries)) ensureDep(n, v);\n}\n\n/** Bulk {@link ensureDevDep} for each `name → version` entry. */\nexport function ensureDevDeps(entries: Record<string, DepVersion>): void {\n for (const [n, v] of Object.entries(entries)) ensureDevDep(n, v);\n}\n\n/** Bulk {@link ensurePeerDep} for each `name → version` entry. */\nexport function ensurePeerDeps(entries: Record<string, DepVersion>): void {\n for (const [n, v] of Object.entries(entries)) ensurePeerDep(n, v);\n}\n\n/** Bulk {@link ensureOptionalDep} for each `name → version` entry. */\nexport function ensureOptionalDeps(entries: Record<string, DepVersion>): void {\n for (const [n, v] of Object.entries(entries)) ensureOptionalDep(n, v);\n}\n\nfunction ensureWorkspaceScopeIn(builder: string, scope: Scope, section: DepSection): void {\n const state = requireJson(builder);\n const ctx = ctxOrThrow(state, builder);\n for (const m of ctx.modules) {\n if (m.scope === scope) {\n ensureInSection(builder, m.name, \"workspace:*\", section);\n }\n }\n}\n\n/** Add every discovered module of `scope` as a `workspace:*` entry in\n * `dependencies` — wires a block's intra-workspace links (e.g. the test\n * scope depending on the other scopes). Single-section invariant per\n * {@link ensureDep}. */\nexport function ensureWorkspaceScopeDeps(scope: Scope): void {\n ensureWorkspaceScopeIn(\"ensureWorkspaceScopeDeps\", scope, \"dependencies\");\n}\n\n/** Like {@link ensureWorkspaceScopeDeps}, into `devDependencies`. */\nexport function ensureWorkspaceScopeDevDeps(scope: Scope): void {\n ensureWorkspaceScopeIn(\"ensureWorkspaceScopeDevDeps\", scope, \"devDependencies\");\n}\n\n/** Like {@link ensureWorkspaceScopeDeps}, into `peerDependencies`. */\nexport function ensureWorkspaceScopePeerDeps(scope: Scope): void {\n ensureWorkspaceScopeIn(\"ensureWorkspaceScopePeerDeps\", scope, \"peerDependencies\");\n}\n\n// --- Prune ---\n\n/** Delete every top-level key for which `predicate(key, value)` is true. */\nexport function pruneKeysMatching(predicate: (key: string, value: unknown) => boolean): void {\n const obj = requireJson(\"pruneKeysMatching\").obj;\n for (const k of Object.keys(obj)) {\n if (predicate(k, obj[k])) delete obj[k];\n }\n}\n\n/** Delete every key of the object at `jsonPath` for which\n * `predicate(key, value)` is true. No-op if the path is not an object. */\nexport function pruneKeysMatchingAt(\n jsonPath: string,\n predicate: (key: string, value: unknown) => boolean,\n): void {\n const obj = requireJson(\"pruneKeysMatchingAt\").obj;\n const sub = getAtPath(obj, jsonPath);\n if (!isObject(sub)) return;\n for (const k of Object.keys(sub)) {\n if (predicate(k, sub[k])) delete sub[k];\n }\n}\n\n// --- Field order ---\n\nfunction applyOrderInPlace(o: JsonObject, order: readonly string[]): void {\n const reordered = reorderTopLevel(o, order);\n for (const k of Object.keys(o)) delete o[k];\n for (const k of Object.keys(reordered)) o[k] = reordered[k];\n}\n\n/** Reorder top-level keys to `orderedKeys`; keys not listed keep their\n * position relative to the preceding listed key. Typically the LAST call in\n * a managed body, projecting the canonical field order. */\nexport function enforceFieldOrder(orderedKeys: string[]): void {\n applyOrderInPlace(requireJson(\"enforceFieldOrder\").obj, orderedKeys);\n}\n\n/** Like {@link enforceFieldOrder}, applied to the object at `jsonPath`. No-op\n * if the path is not an object. */\nexport function enforceFieldOrderAt(jsonPath: string, orderedKeys: string[]): void {\n const obj = requireJson(\"enforceFieldOrderAt\").obj;\n const sub = getAtPath(obj, jsonPath);\n if (!isObject(sub)) return;\n applyOrderInPlace(sub, orderedKeys);\n}\n\nfunction sortAlphabeticalInPlace(o: JsonObject, recursive: boolean): void {\n const sorted = Object.keys(o).sort();\n const buf: JsonObject = {};\n for (const k of sorted) buf[k] = o[k];\n for (const k of Object.keys(o)) delete o[k];\n for (const k of sorted) {\n o[k] = buf[k];\n if (recursive && isObject(o[k])) sortAlphabeticalInPlace(o[k] as JsonObject, true);\n }\n}\n\n/** Sort keys alphabetically. Called with no args it is a deliberate no-op\n * (guards against accidental whole-file sorts); pass a `jsonPath` to sort one\n * object, or `{ recursive: true }` to sort the whole tree. Matches oxfmt's\n * dependency-section ordering. */\nexport function enforceAlphabeticalOrder(\n jsonPath: string = \"\",\n opts: { recursive?: boolean } = {},\n): void {\n const recursive = opts.recursive ?? false;\n // Default jsonPath=\"\" with recursive:false is a no-op (prevents accidents).\n if (jsonPath === \"\" && !recursive) return;\n const obj = requireJson(\"enforceAlphabeticalOrder\").obj;\n if (jsonPath === \"\") {\n sortAlphabeticalInPlace(obj, true);\n return;\n }\n const sub = getAtPath(obj, jsonPath);\n if (!isObject(sub)) return;\n sortAlphabeticalInPlace(sub, recursive);\n}\n\n// --- Generic transform escape hatch ---\n\n/** Escape hatch: replace the value at `jsonPath` with `transform(current)`,\n * for shapes the typed builders above do not cover. */\nexport function transformAt<T = unknown>(jsonPath: string, transform: (current: T) => T): void {\n const obj = requireJson(\"transformAt\").obj;\n const current = getAtPath(obj, jsonPath) as T;\n const next = transform(current);\n setAtPath(obj, jsonPath, next);\n}\n\n// ============================================================\n// YAML builders — `pnpm-workspace.yaml`\n// ============================================================\n\n/** Set the workspace `packages:` list to all discovered NON-root module\n * paths (sorted lex). The block root (\"\") is discovered implicitly\n * and is NEVER written to `packages:` — listing \".\" there breaks turbo's\n * task graph. Equality-guarded — skips the rewrite when the existing\n * list already matches, so a YAML round-trip on an already-canonical\n * file produces zero churn. */\nexport function ensureWorkspaceModulePaths(): void {\n const state = requireYaml(\"ensureWorkspaceModulePaths\");\n const ctx = ctxOrThrow(state, \"ensureWorkspaceModulePaths\");\n const paths = ctx.modules\n .filter((m) => m.path !== \"\")\n .map((m) => m.path)\n .sort();\n const json = state.doc.toJSON() as { packages?: unknown } | null;\n const cur = json?.packages;\n if (Array.isArray(cur) && cur.length === paths.length && cur.every((v, i) => v === paths[i])) {\n return;\n }\n state.doc.setIn([\"packages\"], paths);\n}\n\nfunction readCatalogString(state: YamlState, name: string): string | undefined {\n const node = state.doc.getIn([\"catalog\", name]);\n return typeof node === \"string\" ? node : undefined;\n}\n\n/** Add `catalog.<name>` at `version` ONLY if the key is absent. An entry\n * the block already carries is left untouched — no overwrite, no\n * downgrade. This is the seeding primitive for curated fixed versions\n * (`INFRA_CATALOG_FLOOR`, the python runenv pin): on\n * `refresh --update-deps-only` a missing standard catalog key is added,\n * while a key the block already pins keeps its own version. To force a\n * specific version regardless of what is present, use `pinCatalogTo`. */\nexport function ensureCatalogVersion(name: string, version: string): void {\n const state = requireYaml(\"ensureCatalogVersion\");\n if (readCatalogString(state, name) !== undefined) return;\n state.doc.setIn([\"catalog\", name], version);\n}\n\n/** Set `catalog.<name>` to `version` EXACTLY — creates the entry if\n * missing, overwrites it (including a downgrade) if present. Use to force\n * a specific version; with top-to-bottom declaration order a later\n * `pinCatalogTo` overrides an earlier `ensureCatalogLatest`. Distinct\n * from `ensureCatalogVersion`, which never touches a present key. */\nexport function pinCatalogTo(name: string, version: string): void {\n const state = requireYaml(\"pinCatalogTo\");\n if (readCatalogString(state, name) === version) return;\n state.doc.setIn([\"catalog\", name], version);\n}\n\n/** Resolve `catalog.<name>` to npm \"latest\" from the active state's\n * prefetched `getLatestVersion` accessor (the caller pre-resolves; no\n * network here), creating the key if absent. No-op when no latest is\n * available — default refresh passes no lookup, and a name that was not\n * prefetched resolves to `undefined`; in both cases any existing entry is\n * left untouched. This is the SDK-family resolver: on\n * `refresh --update-deps-only` it both SEEDS a missing standard SDK key\n * and refreshes a present one, and on `init` it overwrites the\n * placeholder with the real latest. */\nexport function ensureCatalogLatest(name: string): void {\n const state = requireYaml(\"ensureCatalogLatest\");\n if (!state.getLatestVersion) return;\n const latest = state.getLatestVersion(name);\n if (latest === undefined) return;\n if (readCatalogString(state, name) === latest) return;\n state.doc.setIn([\"catalog\", name], latest);\n}\n\n/** Remove `catalog.<name>` if present; no-op when absent. */\nexport function ensureCatalogAbsent(name: string): void {\n const state = requireYaml(\"ensureCatalogAbsent\");\n if (!state.doc.hasIn([\"catalog\", name])) return;\n state.doc.deleteIn([\"catalog\", name]);\n}\n\n// ============================================================\n// Lines builders — `.gitignore`\n// ============================================================\n\n/** Append each `entry` if not already present (comment-aware equality). */\nexport function ensureGitignoreEntries(entries: string[]): void {\n const state = requireLines(\"ensureGitignoreEntries\");\n for (const e of entries) {\n if (containsEntry(state.lines, e)) continue;\n state.lines.push(e);\n }\n}\n\n/** Drop any line whose normalised form matches any of `patterns`. */\nexport function removeGitignoreEntries(patterns: RegExp[]): void {\n const state = requireLines(\"removeGitignoreEntries\");\n const kept: string[] = [];\n for (const line of state.lines) {\n const n = normaliseLine(line);\n if (n === \"\") {\n kept.push(line);\n continue;\n }\n if (patterns.some((p) => p.test(n))) continue;\n kept.push(line);\n }\n state.lines.splice(0, state.lines.length, ...kept);\n}\n","// YAML parser + serialiser, comment-preserving via the `yaml` lib's\n// Document API (CST-preserving). Wraps `parseDocument` + `Document.toString`.\n// Helpers (`yamlGet`, `yamlSet`, `yamlHas`, `yamlDelete`) operate on the\n// Document by jsonPath-style addresses, matching the JSON parser's API.\n// Comments attached to map entries survive set/delete operations as long\n// as the affected nodes are mutated in place (not reassigned wholesale).\n\nimport {\n Document,\n isMap,\n isPair,\n isSeq,\n parseDocument,\n YAMLMap,\n YAMLSeq,\n Scalar,\n Node,\n} from \"yaml\";\n\nexport type YamlDocument = Document.Parsed;\n\n/** Parse YAML into a CST-preserving Document. */\nexport function parseYaml(raw: string): YamlDocument {\n return parseDocument(raw);\n}\n\n/** Serialise back to string. Preserves comments + ordering of unchanged\n * nodes per the `yaml` library's contract. */\nexport function stringifyYaml(doc: YamlDocument): string {\n return doc.toString();\n}\n\nfunction splitPath(jsonPath: string): string[] {\n if (jsonPath === \"\" || jsonPath === undefined) return [];\n return jsonPath.split(\".\");\n}\n\n/** Get the JS value at the given jsonPath in the document. */\nexport function yamlGet(doc: YamlDocument, jsonPath: string): unknown {\n const parts = splitPath(jsonPath);\n if (parts.length === 0) return doc.toJS();\n return doc.getIn(parts, false) as unknown;\n}\n\nexport function yamlHas(doc: YamlDocument, jsonPath: string): boolean {\n const parts = splitPath(jsonPath);\n if (parts.length === 0) return true;\n return doc.hasIn(parts);\n}\n\n/** Set a value at jsonPath. Auto-creates intermediate maps. Existing\n * comments on parent map entries are preserved by the yaml library. */\nexport function yamlSet(doc: YamlDocument, jsonPath: string, value: unknown): void {\n const parts = splitPath(jsonPath);\n if (parts.length === 0) {\n throw new Error(\"yamlSet: jsonPath must be non-empty\");\n }\n doc.setIn(parts, value);\n}\n\n/** Delete a value at jsonPath. No-op if missing. */\nexport function yamlDelete(doc: YamlDocument, jsonPath: string): void {\n const parts = splitPath(jsonPath);\n if (parts.length === 0) {\n throw new Error(\"yamlDelete: jsonPath must be non-empty\");\n }\n doc.deleteIn(parts);\n}\n\n/** Re-export selected `yaml` lib types for downstream content-rule builders. */\nexport { isMap, isPair, isSeq, YAMLMap, YAMLSeq, Scalar };\nexport type { Node };\n","// `.structure` metadata file — read/write + floor check.\n//\n// Single JSON file at the block root holding the layout-version\n// integer and (in future) any other structurer metadata. Two\n// constants govern lifecycle gates:\n// - STRUCTURE_VERSION : latest known. Initial value 1.\n// - STRUCTURE_MIN_SUPPORTED : floor. Initial value 0.\n// Both are bumped by structurer releases; rule predicates may consult\n// `ctx.version` for one-shot version-gated transitions.\n\nimport type { FileSystem } from \"./fs/api\";\n\nexport const STRUCTURE_VERSION = 1;\nexport const STRUCTURE_MIN_SUPPORTED = 0;\n/** Block-relative path of the structurer metadata file. */\nexport const STRUCTURE_META_FILE = \".structure\";\n\nexport type StructureMeta = { version: number };\n\n/** Read `.structure`. Missing file or invalid payload → 0. */\nexport function readStructureVersion(fs: FileSystem): number {\n if (!fs.exists(STRUCTURE_META_FILE)) return 0;\n try {\n const raw = fs.read(STRUCTURE_META_FILE);\n const parsed = JSON.parse(raw) as Partial<StructureMeta>;\n if (typeof parsed?.version === \"number\") return parsed.version;\n return 0;\n } catch {\n return 0;\n }\n}\n\n/** Throw if version is below floor. */\nexport function assertVersionAboveFloor(\n version: number,\n floor: number = STRUCTURE_MIN_SUPPORTED,\n): void {\n if (version < floor) {\n throw new StructureVersionFloorError(version, floor);\n }\n}\n\nexport class StructureVersionFloorError extends Error {\n constructor(\n public readonly version: number,\n public readonly floor: number,\n ) {\n super(\n `Block .structure version is ${version}, below floor ${floor}. ` +\n `Bootstrap via the legacy-migration skill, then re-run.`,\n );\n this.name = \"StructureVersionFloorError\";\n }\n}\n\nexport function writeStructureVersion(fs: FileSystem, version: number = STRUCTURE_VERSION): void {\n const payload: StructureMeta = { version };\n // Compact, single-line — this is a tiny machine file, no pretty-print.\n fs.write(STRUCTURE_META_FILE, JSON.stringify(payload));\n}\n","// Engine runner — structural pass, managed pass, post-run recheck.\n//\n// `run(structure, fs, ctx, opts)` drives one block through the structural\n// pass, managed pass, and post-run recheck (DISCOVERY happens in the\n// caller, which constructs `ctx.modules`). The function is shared by\n// `check`, `refresh`,\n// `refresh --update-deps-only`, and `init`. The mode (see `currentMode`)\n// selects which leaves fire — a leaf fires iff its `modes` include the\n// current one:\n// - dryRun=true → check, mode \"default\" (no\n// writes)\n// - dryRun=false, updateDepsOnly=false → refresh, mode \"default\"\n// (writes + .structure bump +\n// post-run recheck)\n// - dryRun=false, updateDepsOnly=true → refresh --update-deps-only,\n// mode \"updateDeps\" (only\n// onUpdateDeps/onInitOrUpdate\n// leaves fire; no version\n// bump; no recheck)\n// - dryRun=false, opts.initMode=true → init, mode \"init\" (default\n// + onInitOrUpdate leaves +\n// seeds; no recheck — the\n// init→check test runs an\n// explicit dry-run afterwards)\n//\n// Idempotency invariant is enforced by the post-run recheck: after a\n// successful refresh, the runner reruns the lifecycle in dry-run mode (fresh\n// rediscover when supplied) and throws `RecheckError` on any non-empty\n// change list. The error carries the failing item's\n// (scope, path, primitive, action) tuple for diagnostics.\n\nimport { stringify as yamlStringify } from \"yaml\";\nimport type { ContentForm, FlatItem, RunMode, Structure, TriggerContext, ManagedBody } from \"./ir\";\nimport type { RunContext, Scope } from \"./api\";\nimport type { FileSystem } from \"./fs/api\";\nimport type { TemplateProvider } from \"./templates\";\nimport { substituteVars } from \"./templates\";\nimport { flatten } from \"./flatten\";\nimport { matchesGlob } from \"./glob\";\nimport { withRunContext } from \"./builders\";\nimport {\n withManagedBody,\n withManagedYaml,\n withManagedLines,\n resolveSdkSentinelsInJson,\n} from \"./content-rules\";\nimport { parseJson, stringifyJson } from \"./parsers/json\";\nimport type { JsonObject } from \"./parsers/json\";\nimport { parseYaml, stringifyYaml } from \"./parsers/yaml\";\nimport { parseLines, serializeLines } from \"./parsers/lines\";\nimport { writeStructureVersion, STRUCTURE_META_FILE } from \"./version\";\n\nexport type ChangeAction = \"create\" | \"update\" | \"delete\" | \"rename\" | \"noop\";\n\nexport type Change = {\n scope: Scope;\n /** Resolved (block-relative) path. For rename, the source path. */\n path: string;\n /** \"fixed\" | \"managed\" | \"scaffold\" | \"seed\" | \"remove\" | \"rename\" */\n primitive: string;\n action: ChangeAction;\n};\n\nexport type RunResult = {\n changes: Change[];\n};\n\nexport type RunOptions = {\n /** Called before the post-run recheck to obtain a fresh RunContext\n * reflecting the just-written FS state (re-reads `pnpm-workspace.yaml`).\n * If absent, recheck reuses the original ctx with `dryRun: true`. */\n rediscover?: (fs: FileSystem) => RunContext;\n /** Template provider used by `file(...)` and `tpl(...)` content forms.\n * Required whenever the structure references such forms. */\n templates?: TemplateProvider;\n /** Init mode: write seed leaves (only-if-missing semantics) and skip\n * the post-run recheck. The caller is expected to follow with an\n * explicit dry-run check (Layer-2 invariant). */\n initMode?: boolean;\n /** Sync accessor for prefetched npm \"latest\" versions, consumed by\n * `ensureCatalogLatest` inside `onUpdateDeps` managed bodies. The CLI\n * prefetches the catalog's package versions before the run (network)\n * and passes the resulting sync map here; unit tests pass a mock.\n * Absent → `ensureCatalogLatest` is a no-op (default refresh). */\n registryLookup?: (packageName: string) => string | undefined;\n};\n\nexport class RecheckError extends Error {\n constructor(public readonly failing: Change) {\n super(\n `Post-run recheck: rule set not idempotent. ` +\n `Failing item: ${failing.primitive} '${failing.path}' ` +\n `(scope=${failing.scope}, action=${failing.action}). Engine bug.`,\n );\n this.name = \"RecheckError\";\n }\n}\n\n/** Resolve a `ContentForm` to its on-disk string for the given file\n * path. `file` / `tpl` resolution goes through the configured\n * `TemplateProvider`; `generate` returns parsed structure → JSON/YAML\n * or a string. */\nfunction resolveContent(\n form: ContentForm,\n filePath: string,\n templates: TemplateProvider | undefined,\n isSdkInternal: boolean,\n): string {\n switch (form.kind) {\n case \"text\":\n return form.value;\n case \"file\": {\n if (!templates) {\n throw new Error(\n `file('${form.path}'): no TemplateProvider configured. ` +\n `Pass opts.templates to engine.run(...).`,\n );\n }\n return templates.staticRead(form.path);\n }\n case \"tpl\": {\n if (!templates) {\n throw new Error(\n `tpl('${form.path}'): no TemplateProvider configured. ` +\n `Pass opts.templates to engine.run(...).`,\n );\n }\n const raw = templates.textRead(form.path);\n const vars = typeof form.vars === \"function\" ? form.vars() : form.vars;\n return substituteVars(raw, vars);\n }\n case \"generate\": {\n const value = form.fn();\n if (filePath.endsWith(\".json\")) {\n // Resolve `sdk:` sentinels in the generated dep sections so the\n // initial content matches what the body rules re-assert.\n resolveSdkSentinelsInJson(value, isSdkInternal);\n // package.json stays fully expanded (oxfmt's package.json shape);\n // every other .json collapses to oxfmt's generic-file shape.\n return stringifyJson(value, { collapse: !filePath.endsWith(\"package.json\") });\n }\n if (filePath.endsWith(\".yaml\") || filePath.endsWith(\".yml\")) {\n return yamlStringify(value);\n }\n if (typeof value !== \"string\") {\n throw new Error(\n `generate() for '${filePath}' must return a string for non-JSON/YAML files; got ${typeof value}`,\n );\n }\n return value;\n }\n case \"binary\":\n throw new Error(\n `binary('${form.path}') cannot be resolved to a string; it is only valid ` +\n `inside seed()/scaffold(), which copy it verbatim via fs.writeBinary.`,\n );\n }\n}\n\n/** Write a leaf's content to disk, dispatching binary assets (copied\n * verbatim, never utf-8 decoded) from string content. */\nfunction writeLeafContent(\n fs: FileSystem,\n resolvedPath: string,\n form: ContentForm,\n templates: TemplateProvider | undefined,\n isSdkInternal: boolean,\n): void {\n if (form.kind === \"binary\") {\n if (!templates) {\n throw new Error(\n `binary('${form.path}'): no TemplateProvider configured. ` +\n `Pass opts.templates to engine.run(...).`,\n );\n }\n fs.writeBinary(resolvedPath, templates.staticReadBinary(form.path));\n return;\n }\n fs.write(resolvedPath, resolveContent(form, resolvedPath, templates, isSdkInternal));\n}\n\n/** Dispatch managed-body parse → mutate → serialize by file extension /\n * basename. JSON, YAML, and lines all share the same `(initial, body,\n * triggerContext) → newRaw` shape via the active-state wrappers in\n * `content-rules.ts`. */\nfunction runManagedBody(\n path: string,\n raw: string,\n body: ManagedBody,\n tctx: TriggerContext,\n registryLookup: ((packageName: string) => string | undefined) | undefined,\n): string {\n const base = path.split(\"/\").pop() ?? path;\n if (path.endsWith(\".json\")) {\n const parsed = parseJson(raw) as JsonObject;\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(`managed: parsed value at '${path}' is not a JSON object`);\n }\n withManagedBody(parsed, body, { triggerContext: tctx });\n // package.json stays fully expanded; other .json (tsconfig, …) collapses\n // to oxfmt's generic-file shape.\n return stringifyJson(parsed, { collapse: base !== \"package.json\" });\n }\n if (path.endsWith(\".yaml\") || path.endsWith(\".yml\")) {\n const doc = parseYaml(raw);\n withManagedYaml(doc, body, { triggerContext: tctx, getLatestVersion: registryLookup });\n return stringifyYaml(doc);\n }\n if (base === \".gitignore\" || base.endsWith(\".gitignore\")) {\n const lines = parseLines(raw);\n withManagedLines(lines, body, { triggerContext: tctx });\n return serializeLines(lines);\n }\n throw new Error(\n `managed('${path}'): unsupported file kind. Only .json, .yaml, .yml, .gitignore are dispatched.`,\n );\n}\n\nfunction buildSnapshot(fs: FileSystem): Set<string> {\n const files = fs.list(\"\");\n const out = new Set<string>();\n for (const f of files) {\n out.add(f);\n const parts = f.split(\"/\");\n for (let i = 1; i < parts.length; i++) {\n out.add(parts.slice(0, i).join(\"/\"));\n }\n }\n return out;\n}\n\nfunction snapshotHas(snap: Set<string>, p: string): boolean {\n const n = p === \"\" ? p : p.endsWith(\"/\") ? p.slice(0, -1) : p;\n return snap.has(n);\n}\n\n/** Build the trigger context for one leaf. `pathExists`/`pathMissing` are\n * block-relative; `filesMatch` resolves its glob MODULE-RELATIVE to\n * `modulePath` so the same predicate (`whenFilesExist(\"src/*.test.ts\")`)\n * reads the right module when a scope fans out. The snapshot is shared\n * across leaves; only the resolution prefix differs per item. */\nfunction buildTriggerCtx(snap: Set<string>, ctx: RunContext, modulePath: string): TriggerContext {\n return {\n ctx,\n version: ctx.version,\n pathExists: (p: string) => snapshotHas(snap, p),\n pathMissing: (p: string) => !snapshotHas(snap, p),\n filesMatch: (glob: string) => {\n const resolved = modulePath ? `${modulePath}/${glob}` : glob;\n for (const entry of snap) {\n if (matchesGlob(resolved, entry)) return true;\n }\n return false;\n },\n };\n}\n\nfunction passesTriggers(item: FlatItem, tctx: TriggerContext): boolean {\n for (const t of item.triggers) {\n if (!t(tctx)) return false;\n }\n return true;\n}\n\n/** Derive the active run mode from the context + init flag. `check`\n * (dryRun) and `refresh` share `\"default\"` — same leaves, the `dryRun`\n * flag alone decides whether writes land. */\nfunction currentMode(ctx: RunContext, initMode: boolean): RunMode {\n if (initMode) return \"init\";\n if (ctx.updateDepsOnly) return \"updateDeps\";\n return \"default\";\n}\n\nfunction filterByMode(items: FlatItem[], mode: RunMode): FlatItem[] {\n return items.filter((i) => i.modes.includes(mode));\n}\n\nfunction applyStructural(\n item: FlatItem,\n fs: FileSystem,\n dryRun: boolean,\n templates: TemplateProvider | undefined,\n initMode: boolean,\n isSdkInternal: boolean,\n): Change | undefined {\n const leaf = item.leaf;\n if (leaf.kind === \"fixed\") {\n const desired = resolveContent(leaf.content, item.resolvedPath, templates, isSdkInternal);\n const exists = fs.exists(item.resolvedPath);\n if (!exists) {\n if (!dryRun) fs.write(item.resolvedPath, desired);\n return {\n scope: item.scope,\n path: item.resolvedPath,\n primitive: \"fixed\",\n action: \"create\",\n };\n }\n const current = fs.read(item.resolvedPath);\n if (current === desired) return undefined;\n if (!dryRun) fs.write(item.resolvedPath, desired);\n return {\n scope: item.scope,\n path: item.resolvedPath,\n primitive: \"fixed\",\n action: \"update\",\n };\n }\n if (leaf.kind === \"scaffold\") {\n if (fs.exists(item.resolvedPath)) return undefined;\n if (!dryRun) {\n writeLeafContent(fs, item.resolvedPath, leaf.initial, templates, isSdkInternal);\n }\n return {\n scope: item.scope,\n path: item.resolvedPath,\n primitive: \"scaffold\",\n action: \"create\",\n };\n }\n if (leaf.kind === \"seed\") {\n // Init mode: write seeds once if missing (same shape as scaffold).\n // Refresh / check: seeds are off-limits to the engine — they belong\n // to the block author. Layer-2 init→check parity relies on the\n // init action depositing canonical seed content, then the check\n // pass simply skipping seeds (vacuously fine).\n if (!initMode) return undefined;\n if (fs.exists(item.resolvedPath)) return undefined;\n if (!dryRun) {\n writeLeafContent(fs, item.resolvedPath, leaf.initial, templates, isSdkInternal);\n }\n return {\n scope: item.scope,\n path: item.resolvedPath,\n primitive: \"seed\",\n action: \"create\",\n };\n }\n if (leaf.kind === \"remove\") {\n if (!fs.exists(item.resolvedPath)) return undefined;\n if (!dryRun) fs.delete(item.resolvedPath);\n return {\n scope: item.scope,\n path: item.resolvedPath,\n primitive: \"remove\",\n action: \"delete\",\n };\n }\n if (leaf.kind === \"rename\") {\n if (!fs.exists(item.resolvedPath)) return undefined;\n const to = item.resolvedTo!;\n if (fs.exists(to)) {\n // dest exists — treat as already-renamed; no change.\n return undefined;\n }\n if (!dryRun) fs.move(item.resolvedPath, to);\n return {\n scope: item.scope,\n path: item.resolvedPath,\n primitive: \"rename\",\n action: \"rename\",\n };\n }\n return undefined;\n}\n\nfunction applyManaged(\n item: FlatItem,\n fs: FileSystem,\n dryRun: boolean,\n tctx: TriggerContext,\n templates: TemplateProvider | undefined,\n registryLookup: ((packageName: string) => string | undefined) | undefined,\n isSdkInternal: boolean,\n): Change | undefined {\n if (item.leaf.kind !== \"managed\") return undefined;\n const leaf = item.leaf;\n const path = item.resolvedPath;\n const exists = fs.exists(path);\n\n let beforeRaw: string;\n let created = false;\n\n if (!exists) {\n beforeRaw = resolveContent(leaf.initial, path, templates, isSdkInternal);\n created = true;\n } else {\n beforeRaw = fs.read(path);\n }\n\n const after = runManagedBody(path, beforeRaw, leaf.body, tctx, registryLookup);\n\n if (created) {\n if (!dryRun) fs.write(path, after);\n return {\n scope: item.scope,\n path,\n primitive: \"managed\",\n action: \"create\",\n };\n }\n if (after === beforeRaw) return undefined;\n if (!dryRun) fs.write(path, after);\n return {\n scope: item.scope,\n path,\n primitive: \"managed\",\n action: \"update\",\n };\n}\n\n/** Execute one pass over the flattened items: structural items first\n * (declaration order), then managed items. Returns the change list. */\nfunction executePass(\n flat: FlatItem[],\n fs: FileSystem,\n ctx: RunContext,\n dryRun: boolean,\n templates: TemplateProvider | undefined,\n initMode: boolean,\n registryLookup: ((packageName: string) => string | undefined) | undefined,\n): Change[] {\n const items = filterByMode(flat, currentMode(ctx, initMode));\n const changes: Change[] = [];\n\n // Structural pass. The trigger context is per-item: `filesMatch` resolves\n // module-relative, so it must carry the leaf's bound module path.\n const snap1 = buildSnapshot(fs);\n for (const item of items) {\n if (item.leaf.kind === \"managed\") continue;\n const tctx1 = buildTriggerCtx(snap1, ctx, item.modulePath);\n if (!passesTriggers(item, tctx1)) continue;\n const change = applyStructural(item, fs, dryRun, templates, initMode, ctx.isSdkInternal);\n if (change) changes.push(change);\n }\n\n // Re-snapshot after structural pass — managed-body triggers see the\n // post-rename / post-delete world.\n const snap2 = buildSnapshot(fs);\n for (const item of items) {\n if (item.leaf.kind !== \"managed\") continue;\n const tctx2 = buildTriggerCtx(snap2, ctx, item.modulePath);\n if (!passesTriggers(item, tctx2)) continue;\n const change = applyManaged(\n item,\n fs,\n dryRun,\n tctx2,\n templates,\n registryLookup,\n ctx.isSdkInternal,\n );\n if (change) changes.push(change);\n }\n\n return changes;\n}\n\n/**\n * Run the structurer engine end-to-end. See module header for mode\n * semantics. Throws `RecheckError` if the post-run dry-run finds any\n * leftover diff after a successful refresh.\n */\nexport function run(\n structure: Structure,\n fs: FileSystem,\n ctx: RunContext,\n opts: RunOptions = {},\n): RunResult {\n return withRunContext(ctx, () => {\n const flat = flatten(structure, ctx);\n const initMode = !!opts.initMode;\n const changes = executePass(\n flat,\n fs,\n ctx,\n ctx.dryRun,\n opts.templates,\n initMode,\n opts.registryLookup,\n );\n\n const isRefreshDefault = !ctx.dryRun && !ctx.updateDepsOnly && !initMode;\n\n if (isRefreshDefault) {\n // version bump\n writeStructureVersion(fs);\n\n // post-run recheck. Fresh discovery → fresh flatten →\n // dry-run. Any change list emits RecheckError on the first item.\n const recheckCtxBase = opts.rediscover ? opts.rediscover(fs) : ctx;\n const recheckCtx: RunContext = { ...recheckCtxBase, dryRun: true };\n const recheckFlat = flatten(structure, recheckCtx);\n const recheckChanges = executePass(\n recheckFlat,\n fs,\n recheckCtx,\n true,\n opts.templates,\n false,\n opts.registryLookup,\n );\n // Ignore .structure self-write (already up to date after\n // writeStructureVersion above).\n const filtered = recheckChanges.filter((c) => c.path !== STRUCTURE_META_FILE);\n if (filtered.length > 0) {\n throw new RecheckError(filtered[0]!);\n }\n }\n\n // Init mode: write .structure so the resulting tree carries the\n // current version (matches what `init` ships to disk).\n if (initMode && !ctx.dryRun) {\n writeStructureVersion(fs);\n }\n\n return { changes };\n });\n}\n","// Workspace-package classification — the seven scope detection rules.\n//\n// Input: the parsed package.json of every workspace member, plus its\n// block-relative path. Output: `Module[]` (scope + name + path).\n// First-match wins on the detection rules; an explicit `block-scope`\n// override on package.json skips detection.\n\nimport type { Module, Scope } from \"./api\";\n\nexport const ALL_SCOPES: Scope[] = [\"root\", \"block\", \"model\", \"ui\", \"workflow\", \"test\", \"software\"];\n\nexport type WorkspacePackage = {\n /** Block-relative path of the package — \"\" or \".\" means the\n * workspace root. */\n path: string;\n /** Parsed package.json. */\n pkg: PackageJsonLike;\n};\n\nexport type PackageJsonLike = {\n name?: string;\n main?: string;\n files?: string[];\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n // Override field — value MUST be one of the seven scopes.\n \"block-scope\"?: string;\n \"block-software\"?: unknown;\n};\n\nexport class DiscoveryError extends Error {\n constructor(\n msg: string,\n public readonly path?: string,\n ) {\n super(msg);\n this.name = \"DiscoveryError\";\n }\n}\n\nfunction depKeys(pkg: PackageJsonLike): Set<string> {\n const all = new Set<string>();\n for (const section of [\n pkg.dependencies,\n pkg.devDependencies,\n pkg.peerDependencies,\n pkg.optionalDependencies,\n ]) {\n if (section) for (const k of Object.keys(section)) all.add(k);\n }\n return all;\n}\n\nfunction isRoot(p: string): boolean {\n return p === \"\" || p === \".\";\n}\n\n/**\n * Classify one package.\n *\n * @param wp The workspace package.\n * @param siblingNames Set of all workspace package `name`s (used by\n * rule 4 \"block\": depends on ≥2 sibling .model/.ui/.workflow).\n * @returns Scope or `undefined` if unclassified.\n */\nexport function classifyOne(wp: WorkspacePackage, siblingNames: Set<string>): Scope | undefined {\n const override = wp.pkg[\"block-scope\"];\n if (typeof override === \"string\") {\n if (!(ALL_SCOPES as string[]).includes(override)) {\n throw new DiscoveryError(\n `package.json \"block-scope\" must be one of ${ALL_SCOPES.join(\", \")}, got '${override}'`,\n wp.path,\n );\n }\n return override as Scope;\n }\n\n // Standalone implicit root: the package at path \"\" is present\n // because pnpm-workspace.yaml lives there, so it IS the workspace root —\n // classify it as `root` unconditionally, BEFORE any detection rule. A\n // nameless root carrying legacy facade cruft (`files: [\"index.d.ts\",\n // \"index.js\"]` + block-tools, e.g. sequence-properties) must NOT fall\n // through to the rule-4 block fallback and become a nameless second\n // `block` module — root-as-facade is a forbidden anti-pattern.\n // SDK-internal enumeration never produces a path-\"\" package (it scans\n // sub-package dirs), so this only ever fires in standalone mode.\n if (isRoot(wp.path)) return \"root\";\n\n const deps = depKeys(wp.pkg);\n\n // 1. software — top-level `block-software` field OR\n // (package-builder AND any @platforma-open/*runenv* dep).\n if (wp.pkg[\"block-software\"] !== undefined) return \"software\";\n if (deps.has(\"@platforma-sdk/package-builder\")) {\n for (const d of deps) {\n if (/^@platforma-open\\/.*runenv/.test(d)) return \"software\";\n }\n }\n\n // 2. workflow — @platforma-sdk/workflow-tengo in deps.\n if (deps.has(\"@platforma-sdk/workflow-tengo\")) return \"workflow\";\n\n // 3. ui — (ui-vue OR vue) AND main is not set.\n if ((deps.has(\"@platforma-sdk/ui-vue\") || deps.has(\"vue\")) && !wp.pkg.main) {\n return \"ui\";\n }\n\n // 4. block — block-tools in deps AND ≥2 sibling .model/.ui/.workflow.\n if (deps.has(\"@platforma-sdk/block-tools\")) {\n const matches = [...deps].filter(\n (d) =>\n siblingNames.has(d) &&\n (d.endsWith(\".model\") || d.endsWith(\".ui\") || d.endsWith(\".workflow\")),\n );\n if (matches.length >= 2) return \"block\";\n // Fallback: `files == [\"index.d.ts\", \"index.js\"]` + block-tools.\n const files = wp.pkg.files;\n if (\n Array.isArray(files) &&\n files.length === 2 &&\n files.includes(\"index.d.ts\") &&\n files.includes(\"index.js\")\n ) {\n return \"block\";\n }\n }\n\n // 5. model — @platforma-sdk/model in deps AND main is set.\n if (deps.has(\"@platforma-sdk/model\") && wp.pkg.main) return \"model\";\n\n // 6. test — @platforma-sdk/test in deps.\n if (deps.has(\"@platforma-sdk/test\")) return \"test\";\n\n // (root — the workspace root, path \"\", is classified above, before the\n // detection rules, so it can never reach this fallthrough.)\n return undefined;\n}\n\n/**\n * Classify a whole workspace. Throws on the first unclassified package\n * with a message that directs the operator to add `block-scope` to its\n * package.json.\n */\nexport function discoverModules(packages: WorkspacePackage[]): Module[] {\n const siblingNames = new Set<string>();\n for (const p of packages) {\n if (typeof p.pkg.name === \"string\") siblingNames.add(p.pkg.name);\n }\n const out: Module[] = [];\n for (const p of packages) {\n const scope = classifyOne(p, siblingNames);\n if (!scope) {\n throw new DiscoveryError(\n `Unclassified workspace package at '${p.path}'. ` +\n `Add a top-level \"block-scope\" string to its package.json.`,\n p.path,\n );\n }\n out.push({\n scope,\n name: p.pkg.name ?? p.path,\n path: isRoot(p.path) ? \"\" : p.path,\n });\n }\n return out;\n}\n","// RunContext assembly helpers + module-lookup helpers. The full\n// `RunContext` type lives in `api.ts` (rule authors see it via\n// `({ ctx }) => ...` trigger predicates). This file provides convenience\n// constructors and the scope-lookup helpers generators use.\n\nimport type { BlockVars, Module, RunContext, Scope } from \"./api\";\n\n/** All modules of `scope` (zero or more). Never throws. Use when \"zero or\n * more\" is the right intent (e.g. software). */\nexport function findModules(ctx: RunContext, scope: Scope): Module[] {\n return ctx.modules.filter((m) => m.scope === scope);\n}\n\n/** The single module of `scope`. Throws if absent OR if more than one\n * exists. Use when exactly one is required (model / ui / workflow). */\nexport function findModule(ctx: RunContext, scope: Scope): Module {\n const ms = findModules(ctx, scope);\n if (ms.length === 0) {\n throw new Error(`findModule: expected one '${scope}' module, found none`);\n }\n if (ms.length > 1) {\n throw new Error(`findModule: expected exactly one '${scope}' module, found ${ms.length}`);\n }\n return ms[0]!;\n}\n\n/** Workspace dep map `{ name: \"workspace:*\" }` for the single module of\n * `scope`. Throws if absent (via `findModule`) — guarantees the dep. */\nexport function scopeDepMap(ctx: RunContext, scope: Scope): Record<string, string> {\n return { [findModule(ctx, scope).name]: \"workspace:*\" };\n}\n\n/** Workspace dep map for ALL modules of `scope` (zero or more). Never\n * throws — use where multiple modules are legitimate (e.g. software). */\nexport function scopeDepMaps(ctx: RunContext, scope: Scope): Record<string, string> {\n const out: Record<string, string> = {};\n for (const m of findModules(ctx, scope)) out[m.name] = \"workspace:*\";\n return out;\n}\n\n/**\n * Module set produced by `init` for the given BlockVars: one module per\n * base scope (root/block/model/ui/workflow/test) plus, when a platform\n * was selected, one `software` module. `--platform` is single-valued, so\n * `init` produces at most one software module; multi-software shapes only\n * arise via DISCOVERY on existing blocks.\n *\n * Single source of truth shared by the real `init` constructor and the\n * `simulateInit` test helper — keeping them in lockstep is what makes the\n * init→check zero-diff invariant meaningful.\n */\nexport function modulesForInit(vars: BlockVars): Module[] {\n const facade = vars.facadeName;\n const mods: Module[] = [\n { scope: \"root\", name: facade, path: \"\" },\n { scope: \"block\", name: `${facade}.block`, path: \"block\" },\n { scope: \"model\", name: `${facade}.model`, path: \"model\" },\n { scope: \"ui\", name: `${facade}.ui`, path: \"ui\" },\n { scope: \"workflow\", name: `${facade}.workflow`, path: \"workflow\" },\n { scope: \"test\", name: `${facade}.test`, path: \"test\" },\n ];\n if (vars.softwarePlatform) {\n // Single software module lives at the flat `software/` dir with name\n // `${facade}.software` — matches the boilerplate and every real\n // single-software block. Multi-software blocks arise only via\n // DISCOVERY on existing workspaces, never from `init`.\n mods.push({\n scope: \"software\",\n name: `${facade}.software`,\n path: \"software\",\n });\n }\n return mods;\n}\n\nexport type CreateRunContextInput = {\n isSdkInternal?: boolean;\n updateDepsOnly?: boolean;\n modules: Module[];\n blockVars: BlockVars;\n version?: number;\n dryRun?: boolean;\n};\n\nexport function createRunContext(input: CreateRunContextInput): RunContext {\n return {\n isSdkInternal: input.isSdkInternal ?? false,\n updateDepsOnly: input.updateDepsOnly ?? false,\n modules: input.modules,\n blockVars: input.blockVars,\n version: input.version ?? 0,\n dryRun: input.dryRun ?? false,\n };\n}\n","// Filesystem-backed DISCOVERY.\n//\n// The engine runner consumes a fully-assembled `RunContext` (modules,\n// version, blockVars). This module is the \"caller\" that builds it from a\n// block directory, working through the engine's `FileSystem` abstraction\n// — so the same code path serves the CLI (NodeFileSystem) and the\n// in-memory init→check round-trip (MemoryFileSystem), which re-discovers\n// from the just-written FS instead of reusing init's module set, so a\n// discovery/classification regression surfaces in the parity invariant.\n//\n// Two enumeration modes:\n//\n// - Standalone (default): read the block-root `pnpm-workspace.yaml`,\n// read each `packages:` member's `package.json` (literal paths only —\n// globs are a hard error), classify via `discoverModules`. This is the\n// canonical path.\n//\n// - SDK-internal (`--sdk-internal`): in-monorepo blocks (e.g.\n// `etc/blocks/*`) have NO block-local `pnpm-workspace.yaml` — they\n// are members of the parent monorepo's workspace. The block's\n// modules are therefore enumerated by scanning the block directory\n// for sub-package `package.json` files (depth-limited, skipping\n// `node_modules`).\n//\n// `.structure` version is read (missing → 0) and floor-checked. BlockVars\n// are parsed from the block-scope module's `package.json` `name` (the\n// facade name), or — for the root-as-block shape — from the root package.\n\nimport { parse as parseYamlText } from \"yaml\";\nimport type { BlockVars, Module, RunContext } from \"./api\";\nimport type { FileSystem } from \"./fs/api\";\nimport { discoverModules, type WorkspacePackage, type PackageJsonLike } from \"./discovery\";\nimport { createRunContext } from \"./ctx\";\nimport { STRUCTURE_META_FILE, STRUCTURE_MIN_SUPPORTED, assertVersionAboveFloor } from \"./version\";\n\nexport class StructureCliError extends Error {\n constructor(msg: string) {\n super(msg);\n this.name = \"StructureCliError\";\n }\n}\n\n/** Join two block-relative path segments (\"\" = root). */\nfunction joinRel(a: string, b: string): string {\n return a === \"\" ? b : `${a}/${b}`;\n}\n\nfunction readJsonIfExists(fs: FileSystem, rel: string): PackageJsonLike | undefined {\n try {\n return JSON.parse(fs.read(rel)) as PackageJsonLike;\n } catch {\n return undefined;\n }\n}\n\n/** Resolve a single pnpm-workspace `packages:` entry to a block-relative\n * directory path. Entries are literal paths only — the structurer does\n * not expand globs: no real block uses them, and a globbing surface\n * with no caller is dead complexity. A `*` anywhere is a hard error. */\nfunction resolvePackagePath(pattern: string): string {\n if (pattern.includes(\"*\")) {\n throw new StructureCliError(\n `pnpm-workspace.yaml 'packages:' entry '${pattern}' contains a glob. ` +\n `The structurer requires literal package paths — replace the glob ` +\n `with one entry per package directory.`,\n );\n }\n const p = pattern.replace(/^\\.\\//, \"\").replace(/\\/$/, \"\");\n return p === \".\" ? \"\" : p;\n}\n\nfunction enumerateStandalone(fs: FileSystem): WorkspacePackage[] {\n let wsRaw: string;\n try {\n wsRaw = fs.read(\"pnpm-workspace.yaml\");\n } catch {\n throw new StructureCliError(\n `No pnpm-workspace.yaml found. This directory is empty or ` +\n `unrecognisable as a block — run 'block-tools structure init' instead, ` +\n `or pass --sdk-internal for an in-monorepo block.`,\n );\n }\n const ws = (parseYamlText(wsRaw) ?? {}) as { packages?: string[] };\n const patterns = Array.isArray(ws.packages) ? ws.packages : [];\n // The block root (\"\") is ALWAYS a member, discovered implicitly.\n // pnpm treats the directory holding pnpm-workspace.yaml as the implicit\n // workspace root, so the structurer reads the root package.json directly\n // — no real block lists \".\" in `packages:` (it would break turbo's task\n // graph), and the structurer never requires or writes it. The Set\n // dedupes if a workspace did list \".\".\n const dirs = new Set<string>([\"\"]);\n for (const pat of patterns) {\n const d = resolvePackagePath(pat);\n if (d === \"\" || fs.exists(d)) dirs.add(d);\n }\n const out: WorkspacePackage[] = [];\n for (const d of dirs) {\n const pkg = readJsonIfExists(fs, joinRel(d, \"package.json\"));\n if (pkg) out.push({ path: d, pkg });\n }\n return out;\n}\n\n/** SDK-internal enumeration: scan the block directory for sub-package\n * `package.json` files. Depth-limited to two levels (covers `block/`,\n * `model/`, … and `software/<name>/`), skipping `node_modules`. */\nfunction enumerateSdkInternal(fs: FileSystem): WorkspacePackage[] {\n const out: WorkspacePackage[] = [];\n const SKIP = new Set([\"node_modules\", \".turbo\", \"dist\", \".git\", \"block-pack\"]);\n\n function scan(rel: string, depth: number): void {\n const entries = fs.listDir(rel);\n for (const e of entries) {\n if (!e.isDirectory || SKIP.has(e.name)) continue;\n const childRel = joinRel(rel, e.name);\n const pkg = readJsonIfExists(fs, joinRel(childRel, \"package.json\"));\n if (pkg) out.push({ path: childRel, pkg });\n if (depth < 2) scan(childRel, depth + 1);\n }\n }\n scan(\"\", 1);\n return out;\n}\n\n/** Parse a facade package name `@npmOrg/orgScope.shortName` into BlockVars. */\nexport function parseBlockVars(facadeName: string): BlockVars {\n const slash = facadeName.indexOf(\"/\");\n if (!facadeName.startsWith(\"@\") || slash < 0) {\n throw new StructureCliError(\n `Cannot parse block name '${facadeName}': expected '@npm-org/org-scope.short-name'.`,\n );\n }\n const npmOrg = facadeName.slice(0, slash);\n const baseName = facadeName.slice(slash + 1);\n const dot = baseName.indexOf(\".\");\n if (dot < 0) {\n throw new StructureCliError(\n `Cannot parse block name '${facadeName}': base name '${baseName}' has no '.' separating org-scope from short-name.`,\n );\n }\n return {\n facadeName,\n baseName,\n npmOrg,\n orgScope: baseName.slice(0, dot),\n shortName: baseName.slice(dot + 1),\n };\n}\n\nfunction readVersion(fs: FileSystem): number {\n try {\n const parsed = JSON.parse(fs.read(STRUCTURE_META_FILE)) as { version?: number };\n return typeof parsed.version === \"number\" ? parsed.version : 0;\n } catch {\n return 0;\n }\n}\n\nexport type DiscoverInput = {\n /** Block-rooted filesystem (NodeFileSystem for the CLI, MemoryFileSystem\n * for the Layer-2 round-trip). */\n fs: FileSystem;\n isSdkInternal: boolean;\n updateDepsOnly?: boolean;\n dryRun?: boolean;\n};\n\n/**\n * Run DISCOVERY against a block filesystem and return a fully-assembled\n * `RunContext`, ready for `engine.run`. Throws `StructureCliError` /\n * `DiscoveryError` / `StructureVersionFloorError` on a non-block dir,\n * an unclassified package, or a below-floor version.\n */\nexport function discoverRunContext(input: DiscoverInput): RunContext {\n const { fs, isSdkInternal } = input;\n\n const packages = isSdkInternal ? enumerateSdkInternal(fs) : enumerateStandalone(fs);\n\n if (packages.length === 0) {\n throw new StructureCliError(\n `No workspace packages found. ` + `Run 'block-tools structure init' to scaffold a block.`,\n );\n }\n\n const modules: Module[] = discoverModules(packages);\n\n const version = readVersion(fs);\n assertVersionAboveFloor(version, STRUCTURE_MIN_SUPPORTED);\n\n // BlockVars from the block-scope module's name (facade). Fall back to\n // the root module if a block has the root-as-block shape.\n const blockMod =\n modules.find((m) => m.scope === \"block\") ?? modules.find((m) => m.scope === \"root\");\n if (!blockMod) {\n throw new StructureCliError(\n `Could not find a 'block' (or root-as-block) package to derive BlockVars from.`,\n );\n }\n const blockVars = parseBlockVars(blockMod.name);\n\n return createRunContext({\n isSdkInternal,\n updateDepsOnly: input.updateDepsOnly ?? false,\n modules,\n blockVars,\n version,\n dryRun: input.dryRun ?? false,\n });\n}\n","// Canonical top-level key order for `package.json` files.\n// Used by `enforceFieldOrder(canonicalPackageJsonOrder)` at the end of\n// every `*-package-json.ts` body.\n// Per-block extensions: rules call\n// `enforceFieldOrder([...canonicalPackageJsonOrder, \"customKey\"])`.\n//\n// This order is derived EMPIRICALLY from oxfmt (the canonical formatter run\n// by `ts-builder check`): a freshly-refreshed package.json must pass\n// `oxfmt --check` so `pnpm check` is green without a prior `pnpm fmt`. oxfmt\n// also alphabetises the dependency sections — the `*-package-json.ts` bodies\n// call `enforceAlphabeticalOrder` on each dep section to match (scripts and\n// `exports` keep source order; oxfmt does not reorder them).\nexport const canonicalPackageJsonOrder = [\n \"name\",\n \"version\",\n \"private\",\n \"description\",\n \"keywords\",\n \"files\",\n \"type\",\n \"main\",\n \"module\",\n \"types\",\n \"exports\",\n \"scripts\",\n \"dependencies\",\n \"devDependencies\",\n \"peerDependencies\",\n \"optionalDependencies\",\n \"packageManager\",\n \"pnpm\",\n \"block\",\n \"block-software\",\n] as const;\n","// Root `package.json`: the initial generator and the drift-correcting body\n// rules, co-located. The body re-asserts the canonical scripts, devDeps,\n// peerDeps, and the final field-order projection (enforceFieldOrder is the\n// LAST call).\n\nimport {\n ensureField,\n ensureScript,\n ensureDevDeps,\n ensurePeerDeps,\n removeField,\n pruneKeysMatching,\n enforceAlphabeticalOrder,\n enforceFieldOrder,\n type RunContext,\n} from \"../engine/api\";\nimport { canonicalPackageJsonOrder } from \"./shared/key-order\";\n\nexport function rootPackageJsonInitial(_ctx: RunContext): Record<string, unknown> {\n // No `name`: the root is never published. Body rules re-assert\n // (removeField(\"name\")) as a drift-corrector.\n return {\n version: \"1.0.0\",\n private: true,\n scripts: {\n fmt: \"turbo run fmt\",\n check: \"turbo run check\",\n build: \"turbo run build\",\n \"build:dev\": \"env PL_PKG_DEV=local turbo run build\",\n test: \"env PL_PKG_DEV=local turbo run test --concurrency 1\",\n \"test:dry-run\": \"env PL_PKG_DEV=local turbo run test --dry-run=json\",\n \"mark-stable\": \"turbo run mark-stable\",\n \"do-pack\": \"turbo run do-pack\",\n watch: \"turbo watch build\",\n changeset: \"changeset\",\n \"version-packages\": \"changeset version\",\n // Deprecated in favour of `update` (the full refresh → install →\n // refresh → format flow); kept for compatibility.\n \"update-sdk\": \"block-tools structure refresh --update-deps-only\",\n update:\n \"block-tools structure refresh --update-deps-only && pnpm i && block-tools structure refresh && pnpm fmt\",\n },\n peerDependencies: {\n oxlint: \"*\",\n oxfmt: \"*\",\n },\n devDependencies: {\n \"@changesets/cli\": \"catalog:\",\n \"@milaboratories/ts-builder\": \"sdk:\",\n \"@platforma-sdk/block-tools\": \"sdk:\",\n shx: \"catalog:\",\n turbo: \"catalog:\",\n },\n packageManager: \"pnpm@9.12.0\",\n };\n}\n\nexport function rootPackageJsonRules(): void {\n ensureField(\"packageManager\", \"pnpm@9.12.0\");\n\n // Root is never published — it carries no `name`; delete any stray one.\n removeField(\"name\");\n\n // Canonical lifecycle script set. `test` / `test:dry-run` carry the\n // PL_PKG_DEV wrapper; the live backend's env reaches the integration\n // tests via the turbo `test` task's passThroughEnv (no --env-mode=loose\n // needed).\n ensureScript(\"fmt\", \"turbo run fmt\");\n ensureScript(\"check\", \"turbo run check\");\n ensureScript(\"build\", \"turbo run build\");\n ensureScript(\"build:dev\", \"env PL_PKG_DEV=local turbo run build\");\n ensureScript(\"test\", \"env PL_PKG_DEV=local turbo run test --concurrency 1\");\n ensureScript(\"test:dry-run\", \"env PL_PKG_DEV=local turbo run test --dry-run=json\");\n ensureScript(\"mark-stable\", \"turbo run mark-stable\");\n ensureScript(\"do-pack\", \"turbo run do-pack\");\n ensureScript(\"watch\", \"turbo watch build\");\n ensureScript(\"changeset\", \"changeset\");\n ensureScript(\"version-packages\", \"changeset version\");\n // Deprecated in favour of `update`; kept for compatibility.\n ensureScript(\"update-sdk\", \"block-tools structure refresh --update-deps-only\");\n // Full SDK-update flow: bump catalog (deps-only) → install → re-apply\n // structure against the freshly-pulled deps → format the result, wrapped\n // as one script. `pnpm fmt` (turbo run fmt) leaves the tree oxfmt-clean\n // after the structural rewrite so a follow-up `pnpm check` passes.\n ensureScript(\n \"update\",\n \"block-tools structure refresh --update-deps-only && pnpm i && block-tools structure refresh && pnpm fmt\",\n );\n\n ensureDevDeps({\n \"@changesets/cli\": \"catalog:\",\n \"@milaboratories/ts-builder\": \"sdk:\",\n \"@platforma-sdk/block-tools\": \"sdk:\",\n shx: \"catalog:\",\n turbo: \"catalog:\",\n });\n\n ensurePeerDeps({\n oxlint: \"*\",\n oxfmt: \"*\",\n });\n\n // Strip committed dev-machine override clutter: keys like \"//pnpm\",\n // \"///pnpm\", \"--\" carrying a pnpm/overrides sub-object (often absolute\n // local paths). Left in place these are unknown top-level keys that oxfmt\n // shoves past the canonical sections, breaking `oxfmt --check`.\n pruneKeysMatching((key, value): boolean => {\n if (!/^(\\/\\/|--)/.test(key)) return false;\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as { pnpm?: unknown; overrides?: unknown };\n return v.pnpm !== undefined || v.overrides !== undefined;\n });\n\n enforceAlphabeticalOrder(\"dependencies\");\n enforceAlphabeticalOrder(\"devDependencies\");\n enforceAlphabeticalOrder(\"peerDependencies\");\n enforceAlphabeticalOrder(\"optionalDependencies\");\n enforceFieldOrder([...canonicalPackageJsonOrder]);\n}\n","// npm registry client used by the catalog ensure-family (`ensureCatalogLatest`).\n//\n// The content-rule builder is synchronous; the runner pre-resolves\n// \"latest\" versions via this client and passes a sync lookup function\n// to `withManagedYaml(..., { getLatestVersion })`. The real impl talks\n// to https://registry.npmjs.org with retry + Retry-After handling\n// ported from `tools/blocks-deps-updater/src/updater.ts`. The mock\n// impl wraps an in-memory map and is the only client used in unit\n// tests.\n\nimport { setTimeout as sleep } from \"node:timers/promises\";\n\nexport interface RegistryClient {\n getLatestVersion(packageName: string): Promise<string>;\n}\n\nconst RETRY_COUNT = 2;\nconst RETRY_BASE_MS = 500;\nconst TIMEOUT_MS = 30_000;\n\n/** Parse the HTTP Retry-After header (RFC 9110): either a delay in\n * seconds or an absolute HTTP-date. Returns the delay in ms, or null\n * if the header is missing / unparseable. */\nexport function parseRetryAfter(header: string | null): number | null {\n if (!header) return null;\n const seconds = Number(header);\n if (Number.isFinite(seconds) && seconds > 0) return seconds * 1000;\n const date = Date.parse(header);\n if (!Number.isNaN(date)) return Math.max(0, date - Date.now());\n return null;\n}\n\nasync function fetchWithRetry(url: string): Promise<Response> {\n for (let attempt = 1; ; attempt++) {\n let res: Response;\n // Only the network call is retry-eligible: a transport error\n // (timeout, DNS, reset) is transient. HTTP-status handling sits\n // OUTSIDE this catch so a non-retryable status (404/403) throws\n // immediately instead of being swallowed and retried.\n try {\n res = await fetch(url, { signal: AbortSignal.timeout(TIMEOUT_MS) });\n } catch (err) {\n if (attempt > RETRY_COUNT) throw err;\n const delay = RETRY_BASE_MS * 2 ** (attempt - 1) * (0.8 + 0.4 * Math.random());\n await sleep(delay);\n continue;\n }\n if (res.ok) return res;\n const retryable = res.status === 429 || res.status >= 500;\n if (!retryable || attempt > RETRY_COUNT) {\n throw new Error(`registry returned HTTP ${res.status}`);\n }\n const retryAfterMs = parseRetryAfter(res.headers.get(\"retry-after\"));\n if (retryAfterMs != null) {\n await sleep(retryAfterMs);\n continue;\n }\n const delay = RETRY_BASE_MS * 2 ** (attempt - 1) * (0.8 + 0.4 * Math.random());\n await sleep(delay);\n }\n}\n\n/** Live npm registry client. Hits the network on each call. */\nexport function createRealRegistryClient(): RegistryClient {\n return {\n async getLatestVersion(packageName: string): Promise<string> {\n const res = await fetchWithRetry(\n `https://registry.npmjs.org/-/package/${packageName}/dist-tags`,\n );\n const tags = (await res.json()) as Record<string, string>;\n const latest = tags.latest;\n if (!latest) {\n throw new Error(\"no 'latest' dist-tag in registry response\");\n }\n return latest;\n },\n };\n}\n\n/** In-memory client backed by a fixed `name → version` map. */\nexport function createMockRegistryClient(versions: Record<string, string>): RegistryClient {\n return {\n async getLatestVersion(packageName: string): Promise<string> {\n const v = versions[packageName];\n if (v === undefined) {\n throw new Error(`mock registry: no version configured for '${packageName}'`);\n }\n return v;\n },\n };\n}\n\n/** Resolve a batch of `name → latest` entries in parallel. */\nexport async function prefetchLatestVersions(\n client: RegistryClient,\n packageNames: readonly string[],\n): Promise<Map<string, string>> {\n const entries = await Promise.all(\n packageNames.map(async (n) => [n, await client.getLatestVersion(n)] as const),\n );\n return new Map(entries);\n}\n\n/** Build a sync lookup function (the shape `withManagedYaml` consumes)\n * from a prefetched map. Returns undefined for unknown names. */\nexport function makeSyncLookup(\n resolved: Map<string, string>,\n): (packageName: string) => string | undefined {\n return (name) => resolved.get(name);\n}\n\n/** Catalog package-name patterns the version-resolution rules\n * (`ensureCatalogLatest`) match against — the `@platforma-sdk/*` and\n * `@milaboratories/*` SDK families. Infra/runtime entries (turbo, shx,\n * …) are deliberately NOT here: they stay a curated floor, not auto-latest.\n * Shared so `init` (names from the SDK pin map) and `refresh\n * --update-deps-only` (names from the on-disk catalog) select the same\n * set. */\nexport const CATALOG_BUMP_PATTERNS: readonly RegExp[] = [/^@platforma-sdk\\//, /^@milaboratories\\//];\n\n/** True if `name` is a version-resolved SDK package (matches any bump\n * pattern). */\nexport function matchesBumpPattern(name: string): boolean {\n return CATALOG_BUMP_PATTERNS.some((p) => p.test(name));\n}\n\n/** Prefetch npm \"latest\" for `names` and return the sync lookup the\n * runner passes to the catalog ensure-family (`ensureCatalogLatest`).\n * Empty list → a lookup that\n * resolves nothing (no network). A network/registry failure REJECTS\n * (callers that require the network — `init` — let it propagate).\n * `client` defaults to the live npm client; tests inject a mock. */\nexport async function buildRegistryLookupForNames(\n names: readonly string[],\n client: RegistryClient = createRealRegistryClient(),\n): Promise<(packageName: string) => string | undefined> {\n if (names.length === 0) return () => undefined;\n const resolved = await prefetchLatestVersions(client, names);\n return makeSyncLookup(resolved);\n}\n","// Root `pnpm-workspace.yaml`: the catalog membership, the initial generator,\n// and the drift-correcting body rules, co-located.\n//\n// The catalog is split in two:\n// - SDK packages: `SDK_CATALOG_PACKAGES` is a list of package NAMES (catalog\n// membership only — no versions). On init the `onInitOrUpdate` frame fetches\n// npm latest for each (init requires network) and writes it; the keys must\n// exist in the catalog first for that in-place bump to land, so the initial\n// generator seeds them with an obviously-invalid placeholder that the bump\n// always overwrites. No version is stored here and there is no fallback.\n// - infra / tooling: a `~`-floored set we control deliberately. No rule\n// ever fetches these — refresh leaves them untouched and update-deps\n// does not match them. Bump the floor here when authoring the scaffold.\n//\n// Default refresh is purely structural: it verifies the workspace\n// `packages:` list matches the discovered modules and leaves every catalog\n// version exactly as the author/lockfile has it. Version resolution (writing\n// npm-latest for the SDK families) lives in the separate `onInitOrUpdate`\n// frame (`rootCatalogBumpRules`), which fires on init + update-deps only.\n\nimport { ensureWorkspaceModulePaths, type RunContext } from \"../engine/api\";\nimport { matchesBumpPattern } from \"../engine/registry-client\";\n\n/** SDK packages that live in the catalog (membership only — no versions).\n * Init fetches npm latest for each; refresh leaves them as the lockfile has\n * them. */\nexport const SDK_CATALOG_PACKAGES: readonly string[] = [\n \"@platforma-sdk/model\",\n \"@platforma-sdk/ui-vue\",\n \"@platforma-sdk/workflow-tengo\",\n \"@platforma-sdk/test\",\n \"@platforma-sdk/block-tools\",\n \"@platforma-sdk/tengo-builder\",\n \"@platforma-sdk/package-builder\",\n \"@milaboratories/ts-builder\",\n \"@milaboratories/ts-configs\",\n];\n\n/** Init-only catalog seed for every SDK package: an obviously-invalid version\n * the `onInitOrUpdate` bump always overwrites with npm latest. It exists only\n * so the catalog key is present for that in-place bump. It is never a\n * fallback — a real init requires network and overwrites it; were it ever to\n * reach a lockfile, `pnpm install` fails loudly on the unresolvable version. */\nconst SDK_CATALOG_INIT_PLACEHOLDER = \"0.0.0-init-must-fetch\";\n\n// Invariant: every SDK package must be fetched on init (match a bump pattern),\n// or its placeholder would ship un-resolved. Caught at load time.\nfor (const name of SDK_CATALOG_PACKAGES) {\n if (!matchesBumpPattern(name)) {\n throw new Error(\n `SDK_CATALOG_PACKAGES entry '${name}' matches no catalog bump pattern; ` +\n `its placeholder would never be resolved to npm latest on init. ` +\n `Add it to CATALOG_BUMP_PATTERNS or move it to the infra floor.`,\n );\n }\n}\n\n/** Infra / tooling — a `~`-floored curated set. Not exact-pinned on refresh\n * and not bumped by update-deps. */\nexport const INFRA_CATALOG_FLOOR: Record<string, string> = {\n turbo: \"~2.8.11\",\n shx: \"~0.4.0\",\n \"@changesets/cli\": \"~2.29.8\",\n vitest: \"~4.0.18\",\n // The seeded ui depends on `vue` (catalog:). `@platforma-sdk/ui-vue` pins\n // vue as an EXACT regular dependency (not a peer), so the block must pin the\n // SAME exact version — a floated `~` lets the ui resolve a newer 3.5.x than\n // ui-vue's, yielding two vue instances and a SdkPluginV3-vs-Plugin type\n // clash in `main.ts`. Keep this in lockstep with ui-vue's vue pin.\n vue: \"3.5.24\",\n};\n\n/** Catalog name of the python runenv. Added to a block's catalog only when\n * the block carries a software module. Pinned to an EXACT version — updating\n * the python runenv is an explicit author decision, never automatic. */\nexport const RUNENV_PYTHON = \"@platforma-open/milaboratories.runenv-python-3\";\nexport const RUNENV_PYTHON_VERSION = \"1.8.2\";\n\nexport function rootPnpmWorkspaceInitial(ctx: RunContext): Record<string, unknown> {\n // Non-root module paths only. The block root (\"\") is discovered\n // implicitly and must never be written as a \".\" entry — listing it breaks\n // turbo's task graph. Root stays in ctx.modules for rule fan-out.\n const paths = ctx.modules\n .filter((m) => m.path !== \"\")\n .map((m) => m.path)\n .sort();\n // SDK packages first (placeholder, overwritten by the init bump), then the\n // infra floor — matching the order the catalog is written.\n const catalog: Record<string, string> = {};\n for (const name of SDK_CATALOG_PACKAGES) catalog[name] = SDK_CATALOG_INIT_PLACEHOLDER;\n Object.assign(catalog, INFRA_CATALOG_FLOOR);\n if (ctx.modules.some((m) => m.scope === \"software\")) {\n catalog[RUNENV_PYTHON] = RUNENV_PYTHON_VERSION;\n }\n return {\n packages: paths,\n catalog,\n };\n}\n\nexport function rootPnpmWorkspaceRules(): void {\n ensureWorkspaceModulePaths();\n}\n","// Root `.gitignore` content rules.\n// The static template under templates/static/root/.gitignore carries the\n// canonical line set; the body re-asserts the same set via\n// `ensureGitignoreEntries` so any future edit that drops a required line\n// is restored.\n\nimport { ensureGitignoreEntries } from \"../engine/api\";\n\nexport const GITIGNORE_REQUIRED_LINES = [\n \".test_auth.json\",\n \"node_modules/\",\n \"dist/\",\n \"block-pack/\",\n \"dev/\",\n \"work/\",\n \"log/\",\n \".turbo\",\n \"vite.config.*.timestamp-*\",\n \"software/**/*.tgz\",\n \".DS_Store\",\n \".vscode/sftp.json\",\n \"test-dry-run.json\",\n];\n\nexport function rootGitignoreRules(): void {\n ensureGitignoreEntries(GITIGNORE_REQUIRED_LINES);\n}\n","// Root-scope rules — apply only to the standalone block layout (the\n// pnpm workspace + tooling around the block). `--sdk-internal` blocks\n// skip this whole scope: the parent monorepo owns root files. Hence the\n// `when(({ ctx }) => !ctx.isSdkInternal, ...)` wrapper.\n\nimport { scope, when, fixed, managed, file, generate } from \"../engine/api\";\nimport { getActiveRunContext } from \"../engine/builders\";\nimport { rootPackageJsonInitial, rootPackageJsonRules } from \"./root-package-json\";\nimport { rootPnpmWorkspaceInitial, rootPnpmWorkspaceRules } from \"./root-pnpm-workspace\";\nimport { rootGitignoreRules } from \"./root-gitignore\";\n\nexport function rootRules(): void {\n scope(\"root\", () => {\n when(\n ({ ctx }) => !ctx.isSdkInternal,\n () => {\n // see templates/static/root/turbo.json — verbatim canonical content.\n fixed(\"turbo.json\", file(\"root/turbo.json\"));\n fixed(\".vscode/settings.json\", file(\"root/.vscode/settings.json\"));\n\n managed(\n \"package.json\",\n generate(() => rootPackageJsonInitial(getActiveRunContext())),\n () => {\n rootPackageJsonRules();\n },\n );\n\n managed(\n \"pnpm-workspace.yaml\",\n generate(() => rootPnpmWorkspaceInitial(getActiveRunContext())),\n () => {\n rootPnpmWorkspaceRules();\n },\n );\n\n managed(\".gitignore\", file(\"root/.gitignore\"), () => {\n rootGitignoreRules();\n });\n },\n );\n });\n}\n","// Block-level (orchestrator) `package.json`: the initial generator and the\n// drift-correcting body rules, co-located. Workspace-scope deps reflect the\n// discovered modules at run time; the generator pre-computes them and the\n// body rule re-asserts them.\n\nimport {\n ensureField,\n ensureScript,\n ensureDevDep,\n ensureWorkspaceScopeDeps,\n enforceAlphabeticalOrder,\n enforceFieldOrder,\n type RunContext,\n} from \"../engine/api\";\nimport { getActiveRunContext } from \"../engine/builders\";\nimport { findModules, scopeDepMap } from \"../engine/ctx\";\nimport { canonicalPackageJsonOrder } from \"./shared/key-order\";\n\n/** The facade's `block.components` map: the dist artifact each module build\n * emits, keyed by role. Fully determined by the discovered modules — the\n * body rule re-asserts this exact value, so it is engine-managed (NOT an\n * author seed). Mirrors the artifact paths produced by each scope's build:\n * workflow → pl-tengo, model → build-model, ui → ts-builder. */\nexport function blockComponents(ctx: RunContext): Record<string, string> {\n const components: Record<string, string> = {};\n for (const m of findModules(ctx, \"workflow\"))\n components.workflow = `${m.name}/dist/tengo/tpl/main.plj.gz`;\n for (const m of findModules(ctx, \"model\")) components.model = `${m.name}/dist/model.json`;\n for (const m of findModules(ctx, \"ui\")) components.ui = `${m.name}/dist`;\n return components;\n}\n\n/** Fail loudly if any required `block.*` field is empty — a missing\n * title / description / logo / organization or empty components map would\n * otherwise produce an init block that `block-tools pack` rejects only\n * later. Asserted at generation time so the failure is immediate. */\nfunction assertBlockFieldsFilled(block: {\n components: Record<string, string>;\n meta: Record<string, unknown>;\n}): void {\n if (Object.keys(block.components).length === 0) {\n throw new Error(\"block.components is empty — no workflow/model/ui module was discovered\");\n }\n const meta = block.meta as {\n title?: unknown;\n description?: unknown;\n logo?: unknown;\n organization?: { name?: unknown; url?: unknown; logo?: unknown };\n };\n const required: [string, unknown][] = [\n [\"block.meta.title\", meta.title],\n [\"block.meta.description\", meta.description],\n [\"block.meta.logo\", meta.logo],\n [\"block.meta.organization.name\", meta.organization?.name],\n [\"block.meta.organization.url\", meta.organization?.url],\n [\"block.meta.organization.logo\", meta.organization?.logo],\n ];\n for (const [path, value] of required) {\n if (typeof value !== \"string\" || value === \"\") {\n throw new Error(`required block field '${path}' is empty`);\n }\n }\n}\n\nexport function blockPackageJsonInitial(ctx: RunContext): Record<string, unknown> {\n const v = ctx.blockVars;\n // The facade depends on its model / ui / workflow modules — not on its\n // software module (the workflow owns that dep) and not on its test module\n // (the test package depends on the facade, so a reciprocal dep would be a\n // pnpm/turbo cycle).\n const deps: Record<string, string> = {\n ...scopeDepMap(ctx, \"model\"),\n ...scopeDepMap(ctx, \"ui\"),\n ...scopeDepMap(ctx, \"workflow\"),\n };\n // `block.components` is engine-managed (re-asserted by the body rule);\n // `block.meta` is an author SEED — written once at init, never touched on\n // refresh, so the author owns title / description / organization / logo.\n // `block-tools pack` requires both. The author edits the placeholder meta\n // before publishing.\n const block = {\n components: blockComponents(ctx),\n meta: {\n title: v.shortName,\n description: `${v.shortName} block`,\n logo: \"file:logos/block-logo.png\",\n organization: {\n name: v.orgScope,\n url: \"https://example.com\",\n logo: \"file:logos/organization-logo.png\",\n },\n },\n };\n assertBlockFieldsFilled(block);\n return {\n name: `${v.facadeName}.block`,\n version: \"1.0.0\",\n // type:\"module\" intentionally omitted.\n files: [\"index.d.ts\", \"index.js\"],\n scripts: {\n build: \"shx rm -rf ./block-pack && block-tools pack\",\n \"mark-stable\":\n \"block-tools mark-stable -r 's3://milab-euce1-prod-pkgs-s3-block-registry/pub/releases/?region=eu-central-1'\",\n prepublishOnly:\n \"block-tools pack && block-tools publish -r 's3://milab-euce1-prod-pkgs-s3-block-registry/pub/releases/?region=eu-central-1'\",\n \"do-pack\": \"shx rm -f *.tgz && block-tools pack && pnpm pack && shx mv *.tgz package.tgz\",\n },\n dependencies: deps,\n devDependencies: { \"@platforma-sdk/block-tools\": \"sdk:\", shx: \"catalog:\" },\n block,\n };\n}\n\nexport function blockPackageJsonRules(): void {\n // type:\"module\" intentionally omitted: the facade's index.js is the\n // CommonJS dev-block descriptor (module.exports / __dirname); ESM would\n // break it. The facade has no TS sources to compile.\n ensureField(\"files\", [\"index.d.ts\", \"index.js\"]);\n\n ensureScript(\"build\", \"shx rm -rf ./block-pack && block-tools pack\");\n ensureScript(\n \"mark-stable\",\n \"block-tools mark-stable -r 's3://milab-euce1-prod-pkgs-s3-block-registry/pub/releases/?region=eu-central-1'\",\n );\n ensureScript(\n \"prepublishOnly\",\n \"block-tools pack && block-tools publish -r 's3://milab-euce1-prod-pkgs-s3-block-registry/pub/releases/?region=eu-central-1'\",\n );\n ensureScript(\n \"do-pack\",\n \"shx rm -f *.tgz && block-tools pack && pnpm pack && shx mv *.tgz package.tgz\",\n );\n\n // One workspace dep per discovered module in the facade's scopes. The\n // facade depends on model / ui / workflow — not software (the workflow\n // owns it) and not test (a reciprocal dep would be a pnpm/turbo cycle).\n ensureWorkspaceScopeDeps(\"model\");\n ensureWorkspaceScopeDeps(\"ui\");\n ensureWorkspaceScopeDeps(\"workflow\");\n\n ensureDevDep(\"@platforma-sdk/block-tools\", \"sdk:\");\n // shx powers the cross-platform build / do-pack scripts above.\n ensureDevDep(\"shx\", \"catalog:\");\n\n // `block.components` is fully determined by the discovered modules — keep\n // it in sync on refresh. `block.meta` is deliberately NOT touched here: it\n // is an author-owned seed (set once in the init package.json), so refresh\n // must never overwrite the author's title / description / logo.\n ensureField(\"block.components\", blockComponents(getActiveRunContext()));\n\n enforceAlphabeticalOrder(\"dependencies\");\n enforceAlphabeticalOrder(\"devDependencies\");\n enforceAlphabeticalOrder(\"peerDependencies\");\n enforceAlphabeticalOrder(\"optionalDependencies\");\n enforceFieldOrder([...canonicalPackageJsonOrder]);\n}\n","// Block-scope rules — the orchestrator package at `block/`.\n// Workspace-scope deps in the body resolve from ctx.modules.\n\nimport { scope, fixed, managed, seed, file, binaryFile, generate } from \"../engine/api\";\nimport { getActiveRunContext } from \"../engine/builders\";\nimport { blockPackageJsonInitial, blockPackageJsonRules } from \"./block-package-json\";\n\nexport function blockRules(): void {\n scope(\"block\", () => {\n fixed(\"index.js\", file(\"block/index.js\"));\n fixed(\"index.d.ts\", file(\"block/index.d.ts\"));\n\n // Placeholder logos referenced by `block.meta` (logo + organization.logo).\n // Binary seeds: written once at init, author-owned thereafter — refresh\n // never overwrites them, so a custom logo survives. `block-tools pack`\n // embeds these into the block pack; without them pack would fail on the\n // `file:logos/...` meta references.\n seed(\"logos/block-logo.png\", binaryFile(\"block/logos/block-logo.png\"));\n seed(\"logos/organization-logo.png\", binaryFile(\"block/logos/organization-logo.png\"));\n\n managed(\n \"package.json\",\n generate(() => blockPackageJsonInitial(getActiveRunContext())),\n () => {\n blockPackageJsonRules();\n },\n );\n });\n}\n","// Shared definition for co-located unit-test handling.\n//\n// A block's model / ui / workflow scope MAY carry co-located vitest unit\n// tests (`src/**/*.test.ts`, including nested `src/test/*.test.ts`). The\n// structurer wires the vitest `test` script and (for ui/model) node ambient\n// types into a scope ONLY when such files are present — so a test-less scope\n// stays free of a `test` script it would never run, and a freshly-init'd\n// (test-less) block remains a refresh fixpoint.\n\n/** Glob (module-relative) for co-located unit tests in a scope's `src/`. */\nexport const COLOCATED_TEST_GLOB = \"src/**/*.test.ts\";\n","// Model `package.json`: the initial generator and the drift-correcting body\n// rules, co-located. Identity (name/version) stays untouched; the body\n// enforces type/main/types/exports + canonical scripts + canonical dep sets,\n// then projects canonical field / dependency order.\n//\n// Authored oxfmt-clean: the model is one of the two scopes `ts-builder\n// check` runs oxfmt on, so neither half enforces field / dependency ordering\n// beyond what oxfmt itself produces — the enforce* calls match oxfmt's order\n// exactly, so refreshing a legacy block yields oxfmt-clean output and the\n// build→check gate (oxfmt --check) passes without a prior `pnpm fmt`.\n\nimport {\n ensureField,\n ensureScript,\n ensureDep,\n ensureDevDep,\n ensureDevDeps,\n ensurePeerDeps,\n enforceAlphabeticalOrder,\n enforceFieldOrder,\n when,\n whenFilesExist,\n type RunContext,\n} from \"../engine/api\";\nimport { canonicalPackageJsonOrder } from \"./shared/key-order\";\nimport { COLOCATED_TEST_GLOB } from \"./shared/colocated-tests\";\n\nexport function modelPackageJsonInitial(ctx: RunContext): Record<string, unknown> {\n const v = ctx.blockVars;\n return {\n name: `${v.facadeName}.model`,\n version: \"1.0.0\",\n type: \"module\",\n // The block-model build emits both index.cjs and index.js. `main` is\n // the CommonJS entry (require fallback); `module` the ESM entry.\n main: \"dist/index.cjs\",\n module: \"dist/index.js\",\n types: \"dist/index.d.ts\",\n exports: {\n \".\": {\n types: \"./dist/index.d.ts\",\n sources: \"./src/index.ts\",\n import: \"./dist/index.js\",\n },\n \"./dist/*\": \"./dist/*\",\n },\n scripts: {\n fmt: \"ts-builder format\",\n watch: \"ts-builder build --target block-model --watch\",\n build: \"ts-builder build --target block-model && block-tools build-model\",\n check: \"ts-builder check --target block-model\",\n // No `test`: the vitest `test` script is wired by the body rule ONLY\n // when co-located test files exist (a freshly-init'd model has none).\n },\n dependencies: {\n \"@platforma-sdk/model\": \"sdk:\",\n },\n devDependencies: {\n \"@milaboratories/ts-builder\": \"sdk:\",\n \"@milaboratories/ts-configs\": \"sdk:\",\n \"@platforma-sdk/block-tools\": \"sdk:\",\n vitest: \"catalog:\",\n },\n peerDependencies: {\n \"@types/node\": \"*\",\n typescript: \"*\",\n },\n };\n}\n\nexport function modelPackageJsonRules(): void {\n ensureField(\"type\", \"module\");\n // build emits both; main = CJS entry, module = ESM entry (prod convention).\n ensureField(\"main\", \"dist/index.cjs\");\n ensureField(\"module\", \"dist/index.js\");\n ensureField(\"types\", \"dist/index.d.ts\");\n ensureField(\"exports\", {\n \".\": {\n types: \"./dist/index.d.ts\",\n sources: \"./src/index.ts\",\n import: \"./dist/index.js\",\n },\n \"./dist/*\": \"./dist/*\",\n });\n\n ensureScript(\"fmt\", \"ts-builder format\");\n ensureScript(\"watch\", \"ts-builder build --target block-model --watch\");\n ensureScript(\"build\", \"ts-builder build --target block-model && block-tools build-model\");\n ensureScript(\"check\", \"ts-builder check --target block-model\");\n\n ensureDep(\"@platforma-sdk/model\", \"sdk:\");\n\n ensureDevDeps({\n \"@milaboratories/ts-builder\": \"sdk:\",\n \"@milaboratories/ts-configs\": \"sdk:\",\n \"@platforma-sdk/block-tools\": \"sdk:\",\n vitest: \"catalog:\",\n });\n\n ensurePeerDeps({\n \"@types/node\": \"*\",\n typescript: \"*\",\n });\n\n // The vitest `test` script + node ambient types are wired ONLY when the\n // model carries co-located unit tests (`src/**/*.test.ts`). A test-less\n // model gets neither — turbo simply has no `test` task for it, and the\n // scope stays a refresh fixpoint. When tests ARE present, `@types/node`\n // is promoted from peer to a devDep (the single-section invariant drops\n // the peer) so the tests' `node:*` imports resolve under the\n // `types: [\"node\"]` that model/tsconfig adds under the same predicate.\n // Runs AFTER ensurePeerDeps so the promotion is not reverted.\n when(whenFilesExist(COLOCATED_TEST_GLOB), () => {\n ensureScript(\"test\", \"vitest run --passWithNoTests\");\n ensureDevDep(\"@types/node\", \"*\");\n });\n\n enforceAlphabeticalOrder(\"dependencies\");\n enforceAlphabeticalOrder(\"devDependencies\");\n enforceAlphabeticalOrder(\"peerDependencies\");\n enforceAlphabeticalOrder(\"optionalDependencies\");\n enforceFieldOrder([...canonicalPackageJsonOrder]);\n}\n","// Model-scope rules. Static config files + managed package.json; the\n// `src/index.ts` seed is dropped by `init` and never touched again\n// (block author owns it).\n\nimport {\n scope,\n fixed,\n managed,\n seed,\n file,\n generate,\n when,\n whenFilesExist,\n ensureField,\n removeField,\n pruneKeysMatching,\n} from \"../engine/api\";\nimport { getActiveRunContext } from \"../engine/builders\";\nimport { modelPackageJsonInitial, modelPackageJsonRules } from \"./model-package-json\";\nimport { COLOCATED_TEST_GLOB } from \"./shared/colocated-tests\";\n\nexport function modelRules(): void {\n scope(\"model\", () => {\n // tsconfig is managed (not fixed) so node ambient types can be provided\n // CONDITIONALLY. The body still enforces the canonical shape —\n // `{extends, include}` with NO stray keys — and, ONLY when the model\n // carries co-located unit tests (`src/**/*.test.ts`), adds\n // `compilerOptions.types: [\"node\"]` so those tests type-check: provide\n // node types, do NOT exclude the tests. A test-less model is\n // canonicalised to bare `{extends, include}`\n // and stays a refresh fixpoint. The matching `@types/node` devDep is\n // wired by the package.json rule under the same predicate.\n managed(\"tsconfig.json\", file(\"model/tsconfig.json\"), () => {\n ensureField(\"extends\", \"@milaboratories/ts-configs/block/model\");\n // Canonical default carries no compilerOptions; drop any legacy block's\n // before (conditionally) re-adding only `types`.\n removeField(\"compilerOptions\");\n when(whenFilesExist(COLOCATED_TEST_GLOB), () => {\n ensureField(\"compilerOptions.types\", [\"node\"]);\n });\n ensureField(\"include\", [\"src/**/*\"]);\n // Strip anything else a legacy tsconfig carried (files, references, a\n // different extends layout) — keep only the canonical keys.\n pruneKeysMatching((k) => k !== \"extends\" && k !== \"include\" && k !== \"compilerOptions\");\n });\n fixed(\".oxlintrc.json\", file(\"model/.oxlintrc.json\"));\n fixed(\".oxfmtrc.json\", file(\"model/.oxfmtrc.json\"));\n\n // A minimal-but-REAL BlockModelV3: `build-model` rejects a non-model\n // export (\"Malformed model object\"), and a bare `.create(dataModel)`\n // still errors (\"Args rendering function not set\"). This seed is the\n // smallest chain that produces a valid `dist/model.json` — empty data\n // model, identity args, a single \"Main\" section. The block author owns\n // and extends it after init.\n seed(\"src/index.ts\", file(\"model/src/index.ts\"));\n\n managed(\n \"package.json\",\n generate(() => modelPackageJsonInitial(getActiveRunContext())),\n () => {\n modelPackageJsonRules();\n },\n );\n });\n}\n","// UI `package.json`: the initial generator and the drift-correcting body\n// rules, co-located.\n//\n// Authored oxfmt-clean: the ui is one of the two scopes `ts-builder check`\n// runs oxfmt on, so neither half enforces ordering beyond what oxfmt\n// produces — the enforce* calls match oxfmt's order exactly, so refreshing a\n// legacy block yields oxfmt-clean output and the build→check gate (oxfmt\n// --check) passes without a prior `pnpm fmt`.\n\nimport {\n ensureField,\n ensureScript,\n ensureDep,\n ensureDevDep,\n ensureDevDeps,\n ensurePeerDeps,\n ensureWorkspaceScopeDeps,\n removeDep,\n enforceAlphabeticalOrder,\n enforceFieldOrder,\n when,\n whenFilesExist,\n type RunContext,\n} from \"../engine/api\";\nimport { scopeDepMap } from \"../engine/ctx\";\nimport { canonicalPackageJsonOrder } from \"./shared/key-order\";\nimport { COLOCATED_TEST_GLOB } from \"./shared/colocated-tests\";\n\nexport function uiPackageJsonInitial(ctx: RunContext): Record<string, unknown> {\n const v = ctx.blockVars;\n return {\n name: `${v.facadeName}.ui`,\n version: \"1.0.0\",\n type: \"module\",\n scripts: {\n fmt: \"ts-builder format\",\n dev: \"ts-builder serve --target block-ui\",\n watch: \"ts-builder build --target block-ui --watch\",\n build: \"ts-builder build --target block-ui\",\n check: \"ts-builder check --target block-ui\",\n // No `test`: the vitest `test` script is wired by the body rule ONLY\n // when co-located test files exist (a freshly-init'd ui has none).\n },\n dependencies: {\n \"@platforma-sdk/ui-vue\": \"sdk:\",\n vue: \"catalog:\",\n // The seeded ui (app.ts) imports the block's model package; depend on\n // it — mirrors the body rule's `ensureWorkspaceScopeDeps(\"model\")`.\n ...scopeDepMap(ctx, \"model\"),\n },\n devDependencies: {\n \"@milaboratories/ts-builder\": \"sdk:\",\n \"@milaboratories/ts-configs\": \"sdk:\",\n vitest: \"catalog:\",\n },\n peerDependencies: {\n typescript: \"*\",\n },\n };\n}\n\nexport function uiPackageJsonRules(): void {\n ensureField(\"type\", \"module\");\n\n ensureScript(\"fmt\", \"ts-builder format\");\n ensureScript(\"dev\", \"ts-builder serve --target block-ui\");\n ensureScript(\"watch\", \"ts-builder build --target block-ui --watch\");\n ensureScript(\"build\", \"ts-builder build --target block-ui\");\n ensureScript(\"check\", \"ts-builder check --target block-ui\");\n\n ensureDep(\"@platforma-sdk/ui-vue\", \"sdk:\");\n // The seeded ui (main.ts) imports `createApp` from vue.\n ensureDep(\"vue\", \"catalog:\");\n // The seeded ui (app.ts) imports the block's model package.\n ensureWorkspaceScopeDeps(\"model\");\n\n ensureDevDeps({\n \"@milaboratories/ts-builder\": \"sdk:\",\n \"@milaboratories/ts-configs\": \"sdk:\",\n vitest: \"catalog:\",\n });\n\n // The ui builds with `--target block-ui` (types: []), so by default it\n // carries no browser/vitest/node ambient types — only the `typescript`\n // peer for IDE type resolution. Drop any stray `@types/node` a legacy\n // block declares...\n ensurePeerDeps({\n typescript: \"*\",\n });\n removeDep(\"@types/node\");\n\n // ...but a ui WITH co-located unit tests (`src/**/*.test.ts`) needs the\n // vitest `test` script AND node ambient types: re-add `@types/node` as a\n // devDep so `types: [\"node\"]` in ui/tsconfig (wired under the same\n // predicate) resolves the tests' `node:*` imports. A test-less ui keeps\n // the lean default (no test script, no @types/node) and stays a fixpoint.\n // Runs AFTER removeDep so the dev dep is not stripped.\n when(whenFilesExist(COLOCATED_TEST_GLOB), () => {\n ensureScript(\"test\", \"vitest run --passWithNoTests\");\n ensureDevDep(\"@types/node\", \"*\");\n });\n\n enforceAlphabeticalOrder(\"dependencies\");\n enforceAlphabeticalOrder(\"devDependencies\");\n enforceAlphabeticalOrder(\"peerDependencies\");\n enforceAlphabeticalOrder(\"optionalDependencies\");\n enforceFieldOrder([...canonicalPackageJsonOrder]);\n}\n","// UI-scope rules. Author owns src/main.ts and components; static config\n// files are engine-managed.\n\nimport {\n scope,\n fixed,\n managed,\n scaffold,\n seed,\n file,\n tpl,\n generate,\n blockVars,\n when,\n whenFilesExist,\n ensureField,\n removeField,\n pruneKeysMatching,\n} from \"../engine/api\";\nimport { getActiveRunContext } from \"../engine/builders\";\nimport { uiPackageJsonInitial, uiPackageJsonRules } from \"./ui-package-json\";\nimport { COLOCATED_TEST_GLOB } from \"./shared/colocated-tests\";\n\nexport function uiRules(): void {\n scope(\"ui\", () => {\n // tsconfig is managed (not fixed) so node ambient types can be provided\n // CONDITIONALLY. The body still enforces the canonical shape —\n // `{extends, include}` with NO stray keys — and, ONLY when the ui\n // carries co-located unit tests (`src/**/*.test.ts`), adds\n // `compilerOptions.types: [\"node\"]` so tests importing `node:*`\n // type-check under vue-tsc: provide node types, do NOT exclude the\n // tests. A test-less ui is canonicalised to\n // bare `{extends, include}` and stays a refresh fixpoint. The matching\n // `@types/node` devDep is wired by the package.json rule under the same\n // predicate.\n managed(\"tsconfig.json\", file(\"ui/tsconfig.json\"), () => {\n ensureField(\"extends\", \"@milaboratories/ts-configs/block/ui\");\n removeField(\"compilerOptions\");\n when(whenFilesExist(COLOCATED_TEST_GLOB), () => {\n ensureField(\"compilerOptions.types\", [\"node\"]);\n });\n ensureField(\"include\", [\"src/**/*\"]);\n pruneKeysMatching((k) => k !== \"extends\" && k !== \"include\" && k !== \"compilerOptions\");\n });\n fixed(\".oxlintrc.json\", file(\"ui/.oxlintrc.json\"));\n // Block-local oxfmt config — the ui is oxfmt-checked (`ts-builder check\n // --target block-ui`).\n fixed(\".oxfmtrc.json\", file(\"ui/.oxfmtrc.json\"));\n // scaffold (not fixed): index.html carries a block-specific CSP. Write\n // the canonical default only when absent; never overwrite an author's.\n scaffold(\"index.html\", file(\"ui/index.html\"));\n\n // A minimal-but-real UI: mount (main.ts), app wiring the block model\n // (app.ts), and a landing page (MainPage.vue). An empty main.ts would\n // trip oxlint `unicorn(no-empty-file)`. Author-owned seeds: written once\n // at init, untouched on refresh.\n seed(\"src/main.ts\", file(\"ui/src/main.ts\"));\n seed(\n \"src/app.ts\",\n tpl(\"ui/src/app.tpl.ts\", () => ({ modelPkg: `${blockVars().facadeName}.model` })),\n );\n seed(\n \"src/MainPage.vue\",\n tpl(\"ui/src/MainPage.tpl.vue\", () => ({ shortName: blockVars().shortName })),\n );\n\n managed(\n \"package.json\",\n generate(() => uiPackageJsonInitial(getActiveRunContext())),\n () => {\n uiPackageJsonRules();\n },\n );\n });\n}\n","// Workflow `package.json`: the initial generator and the drift-correcting\n// body rules, co-located. Workflow packages reference software modules at\n// workspace level when the block has any; the generator fills them from the\n// discovered modules and the body rule re-asserts them.\n\nimport {\n ensureField,\n ensureScript,\n ensureDep,\n ensureDevDeps,\n ensureWorkspaceScopeDeps,\n enforceAlphabeticalOrder,\n enforceFieldOrder,\n when,\n whenFilesExist,\n type RunContext,\n} from \"../engine/api\";\nimport { scopeDepMaps } from \"../engine/ctx\";\nimport { canonicalPackageJsonOrder } from \"./shared/key-order\";\nimport { COLOCATED_TEST_GLOB } from \"./shared/colocated-tests\";\n\nexport function workflowPackageJsonInitial(ctx: RunContext): Record<string, unknown> {\n const v = ctx.blockVars;\n return {\n name: `${v.facadeName}.workflow`,\n version: \"1.0.0\",\n type: \"module\",\n scripts: {\n // No `fmt`: the workflow is Tengo, not TS — nothing for oxlint/oxfmt\n // to process. Tengo is built and checked by pl-tengo.\n build: \"shx rm -rf dist && pl-tengo build\",\n check: \"pl-tengo check\",\n // No `test`: the vitest `test` script is wired by the body rule ONLY\n // when co-located test files exist (a freshly-init'd workflow has none).\n // Tengo source formatter (emacs batch). Falls back to a notice when\n // emacs is absent, so the script never hard-fails the environment.\n format: \"/usr/bin/env emacs --script ./format.el || echo 'No emacs.'\",\n },\n dependencies: {\n \"@platforma-sdk/workflow-tengo\": \"sdk:\",\n // Every block-local software module as a workspace dep (zero or more).\n ...scopeDepMaps(ctx, \"software\"),\n },\n devDependencies: {\n \"@platforma-sdk/tengo-builder\": \"sdk:\",\n \"@platforma-sdk/test\": \"sdk:\",\n vitest: \"catalog:\",\n shx: \"catalog:\",\n },\n };\n}\n\nexport function workflowPackageJsonRules(): void {\n ensureField(\"type\", \"module\");\n\n // No `fmt`: the workflow is Tengo, not TS. Build + check go through\n // pl-tengo. shx powers the cross-platform build clean-up.\n ensureScript(\"build\", \"shx rm -rf dist && pl-tengo build\");\n ensureScript(\"check\", \"pl-tengo check\");\n // Tengo source formatter (emacs batch); no-op notice when emacs is absent.\n ensureScript(\"format\", \"/usr/bin/env emacs --script ./format.el || echo 'No emacs.'\");\n // The vitest `test` script is wired ONLY when the workflow carries\n // co-located integration tests (`src/**/*.test.ts`, incl. `src/test/`).\n // A test-less workflow gets no `test` task and stays a refresh fixpoint.\n // (Workflow tests type-check via the standalone workflow/tsconfig with\n // `types: []` — they pull their types from `@platforma-sdk/test` — so no\n // node-types wiring is needed here, unlike model/ui.)\n when(whenFilesExist(COLOCATED_TEST_GLOB), () => {\n ensureScript(\"test\", \"vitest run --passWithNoTests\");\n });\n\n ensureDep(\"@platforma-sdk/workflow-tengo\", \"sdk:\");\n\n // Pulls in every block-local software module as a workspace dep so the\n // workflow can reference the produced runenv assets.\n ensureWorkspaceScopeDeps(\"software\");\n\n // @platforma-sdk/test: workflow integration tests (e.g. mixcr's\n // workflow/src/test/columns.test.ts) import it.\n ensureDevDeps({\n \"@platforma-sdk/tengo-builder\": \"sdk:\",\n \"@platforma-sdk/test\": \"sdk:\",\n vitest: \"catalog:\",\n shx: \"catalog:\",\n });\n\n enforceAlphabeticalOrder(\"dependencies\");\n enforceAlphabeticalOrder(\"devDependencies\");\n enforceAlphabeticalOrder(\"peerDependencies\");\n enforceAlphabeticalOrder(\"optionalDependencies\");\n enforceFieldOrder([...canonicalPackageJsonOrder]);\n}\n","// Workflow-scope rules. The Tengo entry point is a templated seed\n// (substitutes ${shortName}); other config files are static.\n\nimport {\n scope,\n managed,\n fixed,\n scaffold,\n seed,\n file,\n tpl,\n generate,\n remove,\n blockVars,\n} from \"../engine/api\";\nimport { getActiveRunContext } from \"../engine/builders\";\nimport { workflowPackageJsonInitial, workflowPackageJsonRules } from \"./workflow-package-json\";\n\nexport function workflowRules(): void {\n scope(\"workflow\", () => {\n // tsconfig for the TypeScript vitest integration tests under src/test\n // (e.g. mixcr's workflow/src/test/columns.test.ts). types:[] keeps the\n // isomorphic workflow free of ambient Node/DOM types.\n fixed(\"tsconfig.json\", file(\"workflow/tsconfig.json\"));\n // Tengo source formatter (emacs batch); the `format` script invokes it.\n fixed(\"format.el\", file(\"workflow/format.el\"));\n // scaffold (not fixed): tengo test config is author-tunable.\n scaffold(\"vitest.config.mts\", file(\"workflow/vitest.config.mts\"));\n // No workflow facade (index.js / index.d.ts): the block loader resolves the\n // workflow via the `block:` components dist path (workflow/dist/.../main.plj.gz),\n // never the JS facade. It was orphaned in production — dropped. Actively\n // removed so existing blocks that carry it get cleaned (idempotent on absence).\n remove(\"index.js\");\n remove(\"index.d.ts\");\n\n seed(\n \"src/main.tpl.tengo\",\n tpl(\"workflow/src/main.tpl.tengo\", () => ({\n shortName: blockVars().shortName,\n })),\n );\n\n managed(\n \"package.json\",\n generate(() => workflowPackageJsonInitial(getActiveRunContext())),\n () => {\n workflowPackageJsonRules();\n },\n );\n });\n}\n","// Test `package.json`: the initial generator and the drift-correcting body\n// rules, co-located.\n\nimport {\n ensureField,\n ensureScript,\n ensureDevDeps,\n ensurePeerDeps,\n removeDep,\n enforceAlphabeticalOrder,\n enforceFieldOrder,\n type RunContext,\n} from \"../engine/api\";\nimport { canonicalPackageJsonOrder } from \"./shared/key-order\";\n\nexport function testPackageJsonInitial(ctx: RunContext): Record<string, unknown> {\n const v = ctx.blockVars;\n return {\n name: `${v.facadeName}.test`,\n version: \"1.0.0\",\n private: true,\n type: \"module\",\n scripts: {\n // Type-only check (no oxlint/oxfmt — the test scope ships no lint/fmt\n // config). Slots into the turbo `check` task.\n check: \"ts-builder type-check --target block-test\",\n test: \"vitest run --passWithNoTests\",\n },\n peerDependencies: {\n typescript: \"*\",\n },\n devDependencies: {\n \"@platforma-sdk/test\": \"sdk:\",\n \"@milaboratories/ts-builder\": \"sdk:\",\n \"@milaboratories/ts-configs\": \"sdk:\",\n vitest: \"catalog:\",\n },\n };\n}\n\nexport function testPackageJsonRules(): void {\n ensureField(\"type\", \"module\");\n\n // Type-only check (no oxlint/oxfmt — the test scope ships no lint/fmt\n // config); slots into the turbo `check` task.\n ensureScript(\"check\", \"ts-builder type-check --target block-test\");\n ensureScript(\"test\", \"vitest run --passWithNoTests\");\n\n // @platforma-sdk/test is a test-time dep → devDependencies (matches prod).\n ensureDevDeps({\n \"@platforma-sdk/test\": \"sdk:\",\n \"@milaboratories/ts-builder\": \"sdk:\",\n \"@milaboratories/ts-configs\": \"sdk:\",\n vitest: \"catalog:\",\n });\n\n // The test tsconfig (@milaboratories/ts-configs/block/test) supplies the\n // ambient types; only the `typescript` peer is needed. Drop any stray\n // `@types/node` peer a legacy block declares.\n ensurePeerDeps({\n typescript: \"*\",\n });\n removeDep(\"@types/node\");\n\n enforceAlphabeticalOrder(\"dependencies\");\n enforceAlphabeticalOrder(\"devDependencies\");\n enforceAlphabeticalOrder(\"peerDependencies\");\n enforceAlphabeticalOrder(\"optionalDependencies\");\n enforceFieldOrder([...canonicalPackageJsonOrder]);\n}\n","// Test-scope rules.\n\nimport { scope, fixed, managed, scaffold, seed, file, text, generate } from \"../engine/api\";\nimport { getActiveRunContext } from \"../engine/builders\";\nimport { testPackageJsonInitial, testPackageJsonRules } from \"./test-package-json\";\n\nexport function testRules(): void {\n scope(\"test\", () => {\n // tsconfig carries `files: []` alongside `include: [\"src/**/*\"]`: tsc\n // errors TS18003 when an `include` matches nothing, so an empty `files`\n // lets the check pass on a test-less block while `include` still\n // type-checks real tests once present.\n fixed(\"tsconfig.json\", file(\"test/tsconfig.json\"));\n // scaffold (not fixed): integration tests legitimately tune timeout /\n // retry per block. Write the canonical default if absent; never\n // overwrite an author's config.\n scaffold(\"vitest.config.mts\", file(\"test/vitest.config.mts\"));\n\n // A trivial, backend-free demo test so a freshly-init'd block ships a\n // runnable suite (`pnpm test` green out of the box) rather than an empty\n // scope. Author-owned seed: written once at init, untouched on refresh.\n seed(\n \"src/demo.test.ts\",\n text(\n `import { expect, test } from \"vitest\";\\n\\n` +\n `test(\"scaffolded block sanity check\", () => {\\n` +\n ` expect(true).toBe(true);\\n` +\n `});\\n`,\n ),\n );\n\n managed(\n \"package.json\",\n generate(() => testPackageJsonInitial(getActiveRunContext())),\n () => {\n testPackageJsonRules();\n },\n );\n });\n}\n","// Software `package.json`: the initial generator and the drift-correcting\n// body rules, co-located. One body, N modules — fan-out is driven by\n// `ctx.modules`.\n//\n// Drift-correctors only: identity (name/version), `description`, and the\n// `block-software` descriptor are author-owned / opaque and left untouched\n// — re-asserting them would clobber real multi-software blocks on refresh.\n// The body enforces the structural essentials: ESM type, the publish\n// `files` glob, the lifecycle scripts, and the canonical devDeps.\n\nimport {\n ensureField,\n ensureScript,\n ensureDevDeps,\n enforceAlphabeticalOrder,\n enforceFieldOrder,\n type RunContext,\n} from \"../engine/api\";\nimport { canonicalPackageJsonOrder } from \"./shared/key-order\";\n\n/** The `block-software` package-builder descriptor for a python\n * entrypoint. Kept opaque by the engine; rule authors edit it via\n * `transformAt(\"block-software\", ...)`. The `:3.12.10` tag inside\n * `environment` is the runenv artifact tag (python version), distinct\n * from the npm catalog version. */\nfunction pythonBlockSoftware(): Record<string, unknown> {\n return {\n entrypoints: {\n main: {\n binary: {\n artifact: {\n type: \"python\",\n registry: \"platforma-open\",\n environment: \"@platforma-open/milaboratories.runenv-python-3:3.12.10\",\n dependencies: { toolset: \"pip\", requirements: \"requirements.txt\" },\n root: \"./src\",\n },\n cmd: [\"python\", \"{pkg}/main.py\"],\n },\n },\n },\n };\n}\n\nexport function softwarePackageJsonInitial(ctx: RunContext): Record<string, unknown> {\n const v = ctx.blockVars;\n return {\n name: `${v.facadeName}.software`,\n version: \"1.0.0\",\n type: \"module\",\n description: \"Block Software\",\n files: [\"./dist/**/*\"],\n scripts: {\n build: \"pl-pkg build\",\n prepublishOnly: \"pl-pkg prepublish\",\n changeset: \"changeset\",\n \"version-packages\": \"changeset version\",\n },\n \"block-software\": pythonBlockSoftware(),\n devDependencies: {\n \"@platforma-open/milaboratories.runenv-python-3\": \"catalog:\",\n \"@platforma-sdk/package-builder\": \"sdk:\",\n },\n };\n}\n\nexport function softwarePackageJsonRules(): void {\n ensureField(\"type\", \"module\");\n ensureField(\"files\", [\"./dist/**/*\"]);\n\n ensureScript(\"build\", \"pl-pkg build\");\n ensureScript(\"prepublishOnly\", \"pl-pkg prepublish\");\n ensureScript(\"changeset\", \"changeset\");\n ensureScript(\"version-packages\", \"changeset version\");\n\n ensureDevDeps({\n \"@platforma-open/milaboratories.runenv-python-3\": \"catalog:\",\n \"@platforma-sdk/package-builder\": \"sdk:\",\n });\n\n enforceAlphabeticalOrder(\"dependencies\");\n enforceAlphabeticalOrder(\"devDependencies\");\n enforceAlphabeticalOrder(\"peerDependencies\");\n enforceAlphabeticalOrder(\"optionalDependencies\");\n enforceFieldOrder([...canonicalPackageJsonOrder]);\n}\n","// Software-scope rules. One scope body, N modules — the engine fans out\n// once per discovered software module. Zero software modules → entire\n// scope body no-ops.\n//\n// Seeds (`software/src/main.py` + `requirements.txt`) are written once by\n// `init` and never touched again — the block author owns them.\n\nimport { scope, managed, seed, generate, text } from \"../engine/api\";\nimport { getActiveRunContext } from \"../engine/builders\";\nimport { softwarePackageJsonInitial, softwarePackageJsonRules } from \"./software-package-json\";\n\nconst MAIN_PY_SEED = `import sys\n\nprint(\"Hello from Python, \" + sys.argv[1] + \"!\")\n`;\n\nconst REQUIREMENTS_SEED = `# No dependencies specified for this script\n`;\n\nexport function softwareRules(): void {\n scope(\"software\", () => {\n seed(\"src/main.py\", text(MAIN_PY_SEED));\n seed(\"src/requirements.txt\", text(REQUIREMENTS_SEED));\n\n managed(\n \"package.json\",\n generate(() => softwarePackageJsonInitial(getActiveRunContext())),\n () => {\n softwarePackageJsonRules();\n },\n );\n });\n}\n","// Migrations + legacy cleanup live here.\n//\n// Two patterns coexist:\n//\n// 1. One-shot migrations gated on filesystem state. Folder renames,\n// cross-cutting one-time transforms. Use `when(pathExists/pathMissing)`\n// so the migration fires once and is idempotent on subsequent runs.\n//\n// 2. Legacy cleanup primitives. Unconditional `removeScript`,\n// `removeDep`, `remove(path)` calls naming artefacts the canonical\n// layout never produces. Idempotent by definition (no-op on absent\n// keys/paths). Each line is a one-way decision: every block converges.\n\nimport { scope, remove, managed, generate, removeScript, removeDep } from \"../engine/api\";\nimport { getActiveRunContext } from \"../engine/builders\";\nimport { rootPackageJsonInitial } from \"./root-package-json\";\n\nexport function testFrameworkMigration(): void {\n // No active rename-bearing migration yet. Reserved for the test\n // framework rollout.\n}\n\n// Unconditional legacy-cleanup rules. Each is a no-op on an\n// already-canonical block (remove on an absent path, removeScript /\n// removeDep on an absent key) and idempotent, so they sit at top level\n// with no `when` gate. The trailing comment on each line names the real\n// block(s) that carry the artefact being cleaned.\n//\n// Root-scope cleanup is skipped for `--sdk-internal` blocks (no root\n// module in that mode), so it never touches in-monorepo blocks.\nexport function legacyCleanup(): void {\n // eslint → oxlint: the canonical layout ships `.oxlintrc.json` /\n // `.oxfmtrc.json`; flat eslint configs are retired.\n scope(\"model\", () => {\n remove(\"eslint.config.mjs\"); // samples-and-data, mixcr-clonotyping, clonotype-clustering, antibody-sequence-liabilities\n remove(\"vite.config.mts\"); // samples-and-data (vite build → ts-builder)\n });\n scope(\"ui\", () => {\n remove(\"eslint.config.mjs\"); // samples-and-data, mixcr-clonotyping, clonotype-clustering, antibody-sequence-liabilities\n remove(\"vite.config.ts\"); // samples-and-data (vite build → ts-builder)\n remove(\"tsconfig.app.json\"); // samples-and-data (vite-era split tsconfig)\n remove(\"tsconfig.node.json\"); // samples-and-data (vite-era split tsconfig)\n });\n scope(\"test\", () => {\n remove(\"eslint.config.mjs\"); // all 5 experiment blocks\n });\n\n // Root-scope cleanup. The second `managed(\"package.json\")` body composes\n // after rootRules.\n scope(\"root\", () => {\n remove(\".prettierrc\"); // samples-and-data, sequence-properties (prettier → oxfmt)\n managed(\n \"package.json\",\n generate(() => rootPackageJsonInitial(getActiveRunContext())),\n () => {\n // `pretty` (prettier) is superseded by the canonical `fmt` (oxfmt);\n // the standalone deps-updater was merged into block-tools.\n removeScript(\"pretty\"); // samples-and-data\n removeDep(\"@platforma-sdk/blocks-deps-updater\"); // samples-and-data\n },\n );\n });\n}\n","// Catalog version-resolution + seeding rules. The single `onInitOrUpdate(...)`\n// frame here resolves the SDK catalog families to npm latest AND seeds any\n// missing standard catalog keys (SDK families + the curated infra floor +\n// the python runenv pin). Its leaves fire on `init` AND\n// `refresh --update-deps-only` (mode \"init\" + \"updateDeps\") — both mean\n// \"write current versions\" — and are skipped on a default refresh/check,\n// which leaves catalog versions exactly as the author/lockfile has them.\n//\n// The network value lives in `ensureCatalogLatest`, which reads prefetched\n// \"latest\" versions from the runner's `registryLookup` (the CLI / init\n// constructor prefetches the SDK catalog membership list before the run;\n// unit tests pass a mock). Seeding the SDK keys from the membership list\n// (not the on-disk catalog) is what fixes the install failures: a\n// migrated block that never carried `@milaboratories/ts-builder` etc. now\n// gets them ADDED on `--update-deps-only`, no manual catalog seed required.\n//\n// Wrapped in the same root-scope `when(!isSdkInternal)` guard as the rest of\n// the root rules — internal blocks get their catalog from the parent\n// monorepo, so catalog resolution never applies there.\n\nimport {\n onInitOrUpdate,\n scope,\n when,\n managed,\n generate,\n ensureCatalogLatest,\n ensureCatalogVersion,\n} from \"../engine/api\";\nimport { getActiveRunContext } from \"../engine/builders\";\nimport {\n rootPnpmWorkspaceInitial,\n SDK_CATALOG_PACKAGES,\n INFRA_CATALOG_FLOOR,\n RUNENV_PYTHON,\n RUNENV_PYTHON_VERSION,\n} from \"./root-pnpm-workspace\";\n\nexport function rootCatalogBumpRules(): void {\n onInitOrUpdate(() => {\n scope(\"root\", () => {\n when(\n ({ ctx }) => !ctx.isSdkInternal,\n () => {\n // On init, the default root rules create pnpm-workspace.yaml from\n // this same generator (the curated SDK placeholders + infra\n // floor); this leaf then overwrites the SDK entries with npm\n // latest (the floor entries are add-if-absent no-ops). On\n // update-deps the file already exists, so `initial` is not\n // exercised — but a ContentForm is required, so reuse the\n // generator.\n managed(\n \"pnpm-workspace.yaml\",\n generate(() => rootPnpmWorkspaceInitial(getActiveRunContext())),\n () => {\n // SDK families → npm latest, ADD-IF-ABSENT (seeds a migrated\n // block's missing standard keys + overwrites the init\n // placeholder).\n for (const name of SDK_CATALOG_PACKAGES) ensureCatalogLatest(name);\n // Curated infra floor → fixed version, ADD-IF-ABSENT (seeds\n // shx/turbo/vitest/vue/changesets when missing; never touches a\n // version the block already pins).\n for (const [name, version] of Object.entries(INFRA_CATALOG_FLOOR)) {\n ensureCatalogVersion(name, version);\n }\n // The python runenv pin is relevant only to software-bearing\n // blocks; seed it add-if-absent when one is present.\n if (getActiveRunContext().modules.some((m) => m.scope === \"software\")) {\n ensureCatalogVersion(RUNENV_PYTHON, RUNENV_PYTHON_VERSION);\n }\n },\n );\n },\n );\n });\n });\n}\n","// Canonical block structure — composes every scope's `*Rules()` function\n// inside a single `defineStructure(() => { ... })`. Re-evaluated by the\n// engine on every run; rule modules are imported by name so the\n// structure stays inspectable and the dep graph is explicit.\n\nimport { defineStructure } from \"./engine/api\";\nimport { rootRules } from \"./rules/root\";\nimport { blockRules } from \"./rules/block\";\nimport { modelRules } from \"./rules/model\";\nimport { uiRules } from \"./rules/ui\";\nimport { workflowRules } from \"./rules/workflow\";\nimport { testRules } from \"./rules/test\";\nimport { softwareRules } from \"./rules/software\";\nimport { testFrameworkMigration, legacyCleanup } from \"./rules/migrations\";\nimport { rootCatalogBumpRules } from \"./rules/root-catalog-bump\";\n\nexport const STRUCTURE = defineStructure(() => {\n rootRules();\n blockRules();\n modelRules();\n uiRules();\n workflowRules();\n testRules();\n softwareRules();\n testFrameworkMigration();\n legacyCleanup();\n rootCatalogBumpRules();\n});\n","// Shared driver for the `structure check` and `structure refresh`\n// oclif commands. Wraps DISCOVERY (discover-fs) + the engine runner for\n// one block path, handling the standalone vs `--sdk-internal` split, the\n// `--update-deps-only` registry prefetch, and the post-run recheck's\n// fresh re-discovery. Each block path is processed independently (no\n// cross-block state).\n\nimport path from \"node:path\";\nimport { NodeFileSystem } from \"../engine/fs/node\";\nimport { NodeTemplateProvider } from \"../engine/templates\";\nimport { run as engineRun, type Change } from \"../engine/runner\";\nimport { discoverRunContext } from \"../engine/discovery-fs\";\nimport { STRUCTURE } from \"../structure-definition\";\nimport { matchesBumpPattern, buildRegistryLookupForNames } from \"../engine/registry-client\";\nimport { SDK_CATALOG_PACKAGES } from \"../rules/root-pnpm-workspace\";\n\nexport type StructureMode = \"check\" | \"refresh\";\n\nexport type RunStructureInput = {\n /** User-supplied block path (resolved against cwd). */\n blockPath: string;\n isSdkInternal: boolean;\n updateDepsOnly: boolean;\n mode: StructureMode;\n /** `<block-tools>/src/structure/templates` (from oclif `config.root`). */\n templatesRoot: string;\n log: (msg: string) => void;\n};\n\nexport type RunStructureResult = {\n blockPath: string;\n changes: Change[];\n};\n\n/** Resolve the registry lookup for `--update-deps-only`: prefetch npm\n * \"latest\" for the SDK catalog MEMBERSHIP list (`SDK_CATALOG_PACKAGES`),\n * not the on-disk catalog keys, so the sync `ensureCatalogLatest` builder\n * can SEED a standard SDK key the block does not yet carry — reading\n * the on-disk catalog could never resolve an absent key. Mirrors\n * the `runInit` prefetch. A network failure during prefetch propagates. */\nasync function buildRegistryLookup(): Promise<(name: string) => string | undefined> {\n // Every SDK_CATALOG_PACKAGES entry matches a bump pattern (enforced at\n // load time in root-pnpm-workspace); filter defensively all the same.\n const names = SDK_CATALOG_PACKAGES.filter(matchesBumpPattern);\n return buildRegistryLookupForNames(names);\n}\n\nexport async function runStructureForPath(input: RunStructureInput): Promise<RunStructureResult> {\n const root = path.resolve(input.blockPath);\n const dryRun = input.mode === \"check\";\n\n const fs = new NodeFileSystem(root);\n const templates = new NodeTemplateProvider(input.templatesRoot);\n\n const ctx = discoverRunContext({\n fs,\n isSdkInternal: input.isSdkInternal,\n updateDepsOnly: input.updateDepsOnly,\n dryRun,\n });\n\n const registryLookup = input.updateDepsOnly ? await buildRegistryLookup() : undefined;\n\n const result = engineRun(STRUCTURE, fs, ctx, {\n templates,\n registryLookup,\n // Fresh re-discovery for the post-run recheck (default refresh only)\n // — re-reads the just-written tree so a rename that shifted the\n // module map is observed.\n rediscover: () =>\n discoverRunContext({\n fs,\n isSdkInternal: input.isSdkInternal,\n updateDepsOnly: false,\n dryRun: true,\n }),\n });\n\n return { blockPath: input.blockPath, changes: result.changes };\n}\n\n/** One-line-per-change summary for CLI output. */\nexport function formatChanges(blockPath: string, changes: Change[]): string {\n if (changes.length === 0) return ` ${blockPath}: up to date (0 changes)`;\n const lines = changes.map(\n (c) => ` ${c.action.padEnd(6)} ${c.primitive.padEnd(8)} ${c.path} [${c.scope}]`,\n );\n return ` ${blockPath}: ${changes.length} change(s)\\n${lines.join(\"\\n\")}`;\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport path from \"node:path\";\nimport { runStructureForPath, formatChanges } from \"../../structure/cli/run-structure\";\n\nexport default class StructureCheck extends Command {\n static override description =\n \"Check block(s) against the canonical structure (read-only). Exits non-zero if any diff would land — used as the CI gate.\";\n\n static override examples = [\n \"<%= config.bin %> <%= command.id %> ./my-block\",\n \"<%= config.bin %> <%= command.id %> --sdk-internal etc/blocks/*\",\n ];\n\n // Variadic positional block paths (shell-expanded globs).\n static override strict = false;\n\n static override flags = {\n \"sdk-internal\": Flags.boolean({\n description: \"block(s) live inside the SDK monorepo; skip root-scope rules\",\n }),\n };\n\n public async run(): Promise<void> {\n const { argv, flags } = await this.parse(StructureCheck);\n const paths = (argv as string[]).length > 0 ? (argv as string[]) : [\".\"];\n const templatesRoot = path.join(this.config.root, \"src\", \"structure\", \"templates\");\n\n let anyChanged = false;\n for (const p of paths) {\n const res = await runStructureForPath({\n blockPath: p,\n isSdkInternal: flags[\"sdk-internal\"],\n updateDepsOnly: false,\n mode: \"check\",\n templatesRoot,\n log: (m) => this.log(m),\n });\n this.log(formatChanges(p, res.changes));\n if (res.changes.length > 0) anyChanged = true;\n }\n\n if (anyChanged) {\n this.error(\n \"Structure check failed: one or more blocks are out of date. Run `structure refresh`.\",\n {\n exit: 1,\n },\n );\n }\n }\n}\n","// `block-tools structure init` constructor: collects BlockVars from CLI\n// flags (prompting for any missing field unless --non-interactive),\n// assembles `ctx.modules` via the shared `modulesForInit`, and runs the\n// engine in init mode against a NodeFileSystem rooted at the target dir.\n//\n// Replaces the manual `git clone platforma-block-boilerplate` workflow\n// and `pl-dev create-block`. `--platform` is single-valued: a\n// freshly-init'd block has at most one software module.\n\nimport { confirm, input, select } from \"@inquirer/prompts\";\nimport { NodeFileSystem } from \"./engine/fs/node\";\nimport { NodeTemplateProvider } from \"./engine/templates\";\nimport { run as engineRun } from \"./engine/runner\";\nimport { createRunContext, modulesForInit } from \"./engine/ctx\";\nimport { STRUCTURE } from \"./structure-definition\";\nimport { STRUCTURE_VERSION } from \"./engine/version\";\nimport { matchesBumpPattern, buildRegistryLookupForNames } from \"./engine/registry-client\";\nimport { SDK_CATALOG_PACKAGES } from \"./rules/root-pnpm-workspace\";\nimport type { BlockVars } from \"./engine/api\";\n\n/** Platform choices `init` can scaffold a software module for. Python is\n * the only platform with a real, buildable scaffold at v1; any other\n * value is rejected rather than scaffolded as a non-buildable placeholder,\n * which would defeat the \"init must produce a working block\" intent.\n * `softwarePlatform` stays in BlockVars for when another platform gets a\n * real scaffold. (Note: Tengo is the workflow language, not a software\n * platform.) */\nexport const SUPPORTED_PLATFORMS = [\"python\"] as const;\n\nexport type InitFlagValues = {\n npmOrg?: string;\n orgScope?: string;\n shortName?: string;\n /** Tri-state: true (--with-software), false (--no-software),\n * undefined (unspecified → prompt or, non-interactive, default off). */\n withSoftware?: boolean;\n platform?: string;\n nonInteractive: boolean;\n};\n\nexport type InitInput = {\n /** Resolved BlockVars (from `resolveBlockVars`). */\n vars: BlockVars;\n /** Resolved absolute target directory. */\n blockPath: string;\n /** `<block-tools>/src/structure/templates`. */\n templatesRoot: string;\n log: (msg: string) => void;\n};\n\nclass InitFlagError extends Error {\n constructor(flag: string) {\n super(\n `Missing required flag --${flag} in --non-interactive mode. ` +\n `Supply every BlockVars flag, or drop --non-interactive to be prompted.`,\n );\n this.name = \"InitFlagError\";\n }\n}\n\nasync function need(\n value: string | undefined,\n flag: string,\n nonInteractive: boolean,\n prompt: () => Promise<string>,\n): Promise<string> {\n if (value !== undefined && value !== \"\") return value;\n if (nonInteractive) throw new InitFlagError(flag);\n return prompt();\n}\n\n/** Resolve the full BlockVars (incl. softwarePlatform) from flags +\n * prompts. */\nexport async function resolveBlockVars(flags: InitFlagValues): Promise<BlockVars> {\n const npmOrg = await need(flags.npmOrg, \"npm-org\", flags.nonInteractive, () =>\n input({ message: \"npm org (e.g. @platforma-open):\", default: \"@platforma-open\" }),\n );\n const orgScope = await need(flags.orgScope, \"org-scope\", flags.nonInteractive, () =>\n input({ message: \"org scope (e.g. my-org):\" }),\n );\n const shortName = await need(flags.shortName, \"short-name\", flags.nonInteractive, () =>\n input({ message: \"block short name (e.g. mixcr-clonotyping):\" }),\n );\n\n // Software: explicit flag wins; otherwise prompt (interactive) or\n // default off (non-interactive).\n let hasSoftware: boolean;\n if (flags.withSoftware !== undefined) {\n hasSoftware = flags.withSoftware;\n } else if (flags.nonInteractive) {\n hasSoftware = false;\n } else {\n hasSoftware = await confirm({ message: \"Include a software module?\", default: false });\n }\n\n let softwarePlatform: string | undefined;\n if (hasSoftware) {\n softwarePlatform = await need(flags.platform, \"platform\", flags.nonInteractive, () =>\n select({\n message: \"Software platform:\",\n choices: SUPPORTED_PLATFORMS.map((p) => ({ name: p, value: p })),\n }),\n );\n if (!(SUPPORTED_PLATFORMS as readonly string[]).includes(softwarePlatform)) {\n throw new Error(\n `Unsupported --platform '${softwarePlatform}'. ` +\n `Only ${SUPPORTED_PLATFORMS.join(\", \")} ${\n SUPPORTED_PLATFORMS.length === 1 ? \"is\" : \"are\"\n } supported at v1.`,\n );\n }\n } else if (flags.platform) {\n throw new Error(\"--platform was given but software is disabled (--no-software).\");\n }\n\n const facadeName = `${npmOrg}/${orgScope}.${shortName}`;\n return {\n facadeName,\n baseName: `${orgScope}.${shortName}`,\n npmOrg,\n orgScope,\n shortName,\n softwarePlatform,\n };\n}\n\nexport async function runInit(init: InitInput): Promise<BlockVars> {\n const vars = init.vars;\n const modules = modulesForInit(vars);\n\n const fs = new NodeFileSystem(init.blockPath);\n const templates = new NodeTemplateProvider(init.templatesRoot);\n const ctx = createRunContext({\n blockVars: vars,\n modules,\n isSdkInternal: false,\n version: STRUCTURE_VERSION,\n dryRun: false,\n });\n\n // Init REQUIRES network: resolve the SDK catalog families to npm latest\n // before the run, so the generated block carries real current versions\n // (no placeholders). The names come from the SDK catalog package list —\n // there is no on-disk pnpm-workspace.yaml to read yet. A registry failure\n // aborts init rather than silently shipping an unresolved placeholder.\n const sdkNames = SDK_CATALOG_PACKAGES.filter(matchesBumpPattern);\n let registryLookup: (name: string) => string | undefined;\n try {\n registryLookup = await buildRegistryLookupForNames(sdkNames);\n } catch (err) {\n throw new Error(\n `init requires network access to resolve SDK catalog versions from npm, ` +\n `but the registry lookup failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n engineRun(STRUCTURE, fs, ctx, { templates, initMode: true, registryLookup });\n init.log(\n `Initialised block '${vars.facadeName}'${\n vars.softwarePlatform ? ` (software: ${vars.softwarePlatform})` : \" (no software)\"\n } at ${init.blockPath}`,\n );\n return vars;\n}\n","import { Args, Command, Flags } from \"@oclif/core\";\nimport path from \"node:path\";\nimport {\n resolveBlockVars,\n runInit,\n SUPPORTED_PLATFORMS,\n type InitFlagValues,\n} from \"../../structure/init-block-constructor\";\n\nexport default class StructureInit extends Command {\n static override description =\n \"Scaffold a fresh Platforma block from the canonical structure. Missing flags are prompted unless --non-interactive.\";\n\n static override examples = [\n \"<%= config.bin %> <%= command.id %> --npm-org @platforma-open --org-scope my-org --short-name demo --no-software --non-interactive\",\n \"<%= config.bin %> <%= command.id %> ./demo --npm-org @platforma-open --org-scope my-org --short-name demo --with-software --platform python --non-interactive\",\n ];\n\n static override args = {\n path: Args.string({\n description: \"target directory (default: <short-name> under the current directory)\",\n }),\n };\n\n static override flags = {\n \"npm-org\": Flags.string({ description: \"npm org, e.g. @platforma-open\" }),\n \"org-scope\": Flags.string({ description: \"org scope, e.g. my-org\" }),\n \"short-name\": Flags.string({ description: \"block short name, e.g. mixcr-clonotyping\" }),\n \"with-software\": Flags.boolean({ description: \"include a software module\" }),\n \"no-software\": Flags.boolean({ description: \"omit the software module\" }),\n platform: Flags.string({\n description: \"software platform (single-valued)\",\n options: [...SUPPORTED_PLATFORMS],\n }),\n \"non-interactive\": Flags.boolean({\n description: \"error on any missing flag instead of prompting\",\n }),\n };\n\n public async run(): Promise<void> {\n const { args, flags } = await this.parse(StructureInit);\n\n if (flags[\"with-software\"] && flags[\"no-software\"]) {\n this.error(\"--with-software and --no-software are mutually exclusive.\");\n }\n const withSoftware = flags[\"with-software\"] ? true : flags[\"no-software\"] ? false : undefined;\n\n const flagValues: InitFlagValues = {\n npmOrg: flags[\"npm-org\"],\n orgScope: flags[\"org-scope\"],\n shortName: flags[\"short-name\"],\n withSoftware,\n platform: flags.platform,\n nonInteractive: flags[\"non-interactive\"],\n };\n\n const vars = await resolveBlockVars(flagValues);\n const blockPath = args.path\n ? path.resolve(args.path)\n : path.resolve(process.cwd(), vars.shortName);\n const templatesRoot = path.join(this.config.root, \"src\", \"structure\", \"templates\");\n\n await runInit({ vars, blockPath, templatesRoot, log: (m) => this.log(m) });\n }\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport path from \"node:path\";\nimport { runStructureForPath, formatChanges } from \"../../structure/cli/run-structure\";\n\nexport default class StructureRefresh extends Command {\n static override description =\n \"Bring block(s) up to date with the canonical structure. Applies rules, writes files, bumps .structure version. Default mode is offline; --update-deps-only fires only catalog-bump rules (network).\";\n\n static override examples = [\n \"<%= config.bin %> <%= command.id %> ./my-block\",\n \"<%= config.bin %> <%= command.id %> --sdk-internal etc/blocks/*\",\n \"<%= config.bin %> <%= command.id %> --update-deps-only\",\n ];\n\n static override strict = false;\n\n static override flags = {\n \"sdk-internal\": Flags.boolean({\n description: \"block(s) live inside the SDK monorepo; skip root-scope rules\",\n }),\n \"update-deps-only\": Flags.boolean({\n description:\n \"fire ONLY catalog-bump rules (npm network). Follow with `pnpm install` then a plain refresh.\",\n }),\n };\n\n public async run(): Promise<void> {\n const { argv, flags } = await this.parse(StructureRefresh);\n const paths = (argv as string[]).length > 0 ? (argv as string[]) : [\".\"];\n const templatesRoot = path.join(this.config.root, \"src\", \"structure\", \"templates\");\n\n for (const p of paths) {\n const res = await runStructureForPath({\n blockPath: p,\n isSdkInternal: flags[\"sdk-internal\"],\n updateDepsOnly: flags[\"update-deps-only\"],\n mode: \"refresh\",\n templatesRoot,\n log: (m) => this.log(m),\n });\n this.log(formatChanges(p, res.changes));\n }\n }\n}\n","// DO NOT EDIT. This file was generated by oclif-index utility.\n\nimport Cmd0 from \"./build-meta\";\nimport Cmd1 from \"./build-model\";\nimport Cmd3 from \"./list-overview-snapshots\";\nimport Cmd4 from \"./mark-stable\";\nimport Cmd5 from \"./pack\";\nimport Cmd6 from \"./publish\";\nimport Cmd7 from \"./refresh-registry\";\nimport Cmd8 from \"./restore-overview-from-snapshot\";\nimport Cmd9 from \"./update-deps\";\nimport Cmd10 from \"./upload-package-v1\";\nimport Cmd11 from \"./structure/check\";\nimport Cmd12 from \"./structure/init\";\nimport Cmd13 from \"./structure/refresh\";\n\nexport const COMMANDS = {\n \"build-meta\": Cmd0,\n \"build-model\": Cmd1,\n \"list-overview-snapshots\": Cmd3,\n \"mark-stable\": Cmd4,\n pack: Cmd5,\n publish: Cmd6,\n \"refresh-registry\": Cmd7,\n \"restore-overview-from-snapshot\": Cmd8,\n \"update-deps\": Cmd9,\n \"upload-package-v1\": Cmd10,\n \"structure:check\": Cmd11,\n \"structure:init\": Cmd12,\n \"structure:refresh\": Cmd13,\n};\n"],"mappings":"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"}
|