@theholocron/astromech 5.0.0-alpha.162 → 5.0.0-alpha.164

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.
@@ -1,4 +1,4 @@
1
- import { n as TaskEntry, r as TasksConfig, t as TaskConfigItem } from "../schema.type-B9k8EoOb.mjs";
1
+ import { n as TaskEntry, r as TasksConfig, t as TaskConfigItem } from "../schema.type-BJmfOafW.mjs";
2
2
  import { Loaded } from "@theholocron/datapad";
3
3
  //#region src/config/schema/schema.d.ts
4
4
  /**
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as TasksConfig } from "./schema.type-B9k8EoOb.mjs";
1
+ import { r as TasksConfig } from "./schema.type-BJmfOafW.mjs";
2
2
  //#region src/generators/codecov/codecov.type.d.ts
3
3
  interface WorkspacePackage {
4
4
  slug: string;
@@ -161,7 +161,7 @@ declare function generateCombinedDeployContent(deployWith: Record<string, unknow
161
161
  * generating the thin caller. Handles:
162
162
  * - deploy shorthand: docs/storybook → type + storybook-projects
163
163
  * - preview: stripped (handled separately via extractPreviewConfig)
164
- * - run-chromatic object → run-chromatic: true + chromatic-projects
164
+ * - chromatic-projects entries' untraced array → newline-joined string
165
165
  * - plain arrays → JSON-stringified for YAML scalar quoting
166
166
  *
167
167
  * Used by both `holocron repo setup` and `sync-workflow-templates`.
package/dist/index.mjs CHANGED
@@ -215,7 +215,10 @@ var verification_performance_default$1 = "name: Audit the Performance\n\non: # y
215
215
  var verification_typeSafety_default$1 = "name: Typecheck\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n secrets:\n TURBO_TOKEN:\n required: false\n\njobs:\n typecheck:\n name: Run tsc --noEmit\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 10\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - uses: theholocron/.github/.github/actions/holocron@main\n name: Type check\n with:\n task: verification.typeSafety\n";
216
216
  //#endregion
217
217
  //#region src/templates/reusable/verification.unitTests.yml
218
- var verification_unitTests_default$1 = "name: Test\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n run-unit:\n description: Run unit tests with coverage (disable for UI-only repos that use Storybook testing exclusively)\n type: boolean\n required: false\n default: true\n run-storybook:\n description: Run Storybook vitest interaction tests (requires .storybook/ setup)\n type: boolean\n required: false\n default: false\n run-interaction:\n description: Run Storybook interaction and accessibility tests with Playwright\n type: boolean\n required: false\n default: false\n run-chromatic:\n description: Publish Storybook to Chromatic for visual regression testing\n type: boolean\n required: false\n default: false\n chromatic-projects:\n description: >\n JSON array of Chromatic projects to build, one matrix job per entry.\n Each entry: { \"tokenName\": \"WEB\", \"workingDir\": \"apps/web\", \"buildScript\": \"build:storybook\" }.\n tokenName maps to secret CHROMATIC_PROJECT_TOKEN_<TOKENNAME>; use \"default\"\n (or omit for the legacy empty-string form) to use the bare CHROMATIC_PROJECT_TOKEN\n secret for single-project repos.\n buildScript defaults to \"build:storybook\" when omitted.\n Default runs a single job from the repo root using CHROMATIC_PROJECT_TOKEN.\n type: string\n required: false\n default: '[{\"tokenName\":\"default\",\"workingDir\":\".\",\"buildScript\":\"build:storybook\"}]'\n run-user-flow:\n description: Run Cypress E2E user-flow tests (requires cypress.config.*)\n type: boolean\n required: false\n default: false\n wait-on-url:\n description: URL to wait for before running Cypress tests (default is Vite dev server; override for non-Vite stacks e.g. http://localhost:3000 for Next.js)\n type: string\n required: false\n default: \"http://localhost:5173\"\n secrets:\n CHROMATIC_PROJECT_TOKEN:\n required: false\n CYPRESS_RECORD_KEY:\n required: false\n TURBO_TOKEN:\n required: false\n\njobs:\n unit:\n name: Run unit tests and collect coverage\n if: ${{ inputs.run-unit }}\n permissions:\n contents: read\n id-token: write\n runs-on: ubuntu-latest\n timeout-minutes: 15\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - uses: theholocron/.github/.github/actions/holocron@main\n name: Run tests with coverage\n with:\n task: verification.unitTests\n\n # A Codecov upload must not fail silently. fail_ci_if_error makes a failed\n # upload fail this step (the action's default is to log the error and pass),\n # which fails the job and so the `Test / Conclusion` check. Whether that\n # blocks a merge is up to whether the check is required, not this workflow\n # (holocron#934).\n - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0\n name: Upload coverage to Codecov\n with:\n use_oidc: true\n fail_ci_if_error: true\n\n - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0\n name: Upload test results to Codecov\n if: ${{ !cancelled() }}\n with:\n use_oidc: true\n fail_ci_if_error: true\n report_type: test_results\n files: \"**/test-report.junit.xml\"\n\n storybook:\n name: Run Storybook interaction tests\n if: ${{ inputs.run-storybook }}\n permissions:\n contents: read\n id-token: write\n runs-on: ubuntu-latest\n timeout-minutes: 15\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: pnpm exec playwright install chromium --with-deps\n name: Install Playwright\n\n - run: pnpm test:storybook\n name: Run Storybook tests\n\n # A Codecov upload must not fail silently. fail_ci_if_error makes a failed\n # upload fail this step (the action's default is to log the error and pass),\n # which fails the job and so the `Test / Conclusion` check. Whether that\n # blocks a merge is up to whether the check is required, not this workflow\n # (holocron#934).\n - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0\n name: Upload coverage to Codecov\n with:\n use_oidc: true\n fail_ci_if_error: true\n\n - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0\n name: Upload test results to Codecov\n if: ${{ !cancelled() }}\n with:\n use_oidc: true\n fail_ci_if_error: true\n report_type: test_results\n files: \"**/test-report.junit.xml\"\n\n visual-and-composition:\n # No explicit matrix reference here — a skipped job (run-chromatic:\n # false, the common case) never expands its matrix, so a `${{\n # matrix.project.tokenName }}` in name: has nothing to resolve and\n # shows as raw template text in the checks UI. GitHub auto-appends\n # the matrix values in parens when the matrix *does* expand, so this\n # loses no distinctness across multiple Chromatic projects.\n name: Run visual and composition tests\n if: ${{ inputs.run-chromatic }}\n strategy:\n fail-fast: false\n matrix:\n project: ${{ fromJSON(inputs.chromatic-projects) }}\n permissions:\n contents: read\n statuses: write\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n with:\n fetch-depth: 0\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - uses: chromaui/action@14cfaef73576e69f95f47f60058063f46ca38719 # v18\n name: Publish to Chromatic\n with:\n projectToken: ${{ (matrix.project.tokenName == 'default' || matrix.project.tokenName == '') && secrets.CHROMATIC_PROJECT_TOKEN || secrets[format('CHROMATIC_PROJECT_TOKEN_{0}', matrix.project.tokenName)] }}\n token: ${{ github.token }}\n buildScriptName: ${{ matrix.project.buildScript || 'build:storybook' }}\n workingDir: ${{ matrix.project.workingDir || '.' }}\n storybookBaseDir: ${{ matrix.project.storybookBaseDir || '' }}\n untraced: ${{ matrix.project.untraced || '' }}\n onlyStoryFiles: ${{ matrix.project.onlyStoryFiles || '' }}\n exitZeroOnChanges: ${{ matrix.project.exitZeroOnChanges || false }}\n\n interaction-and-accessibility:\n name: Run interactions and accessibility tests\n if: ${{ inputs.run-interaction }}\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 15\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: pnpm exec playwright install --with-deps\n name: Install Playwright\n\n - run: pnpm test:storybook\n name: Run interaction and accessibility tests\n\n user-flow:\n name: Run user flow tests\n if: ${{ inputs.run-user-flow }}\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 15\n strategy:\n fail-fast: false\n matrix:\n containers: [1, 2]\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: pnpm exec cypress install\n name: Install Cypress binary\n\n - uses: cypress-io/github-action@1052aa98bbbe4f55210f844878213c07d9c8c399 # v6.7.13\n name: Cypress run\n with:\n start: pnpm dev\n wait-on: ${{ inputs.wait-on-url }}\n record: true\n parallel: true\n env:\n CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}\n GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n conclusion:\n name: Conclusion\n runs-on: ubuntu-latest\n if: always()\n needs: [unit, storybook, visual-and-composition, interaction-and-accessibility, user-flow]\n steps:\n - name: Check job statuses\n run: |\n if [[ \"$RESULTS\" == *\"failure\"* ]] || [[ \"$RESULTS\" == *\"cancelled\"* ]]; then\n exit 1\n fi\n env:\n RESULTS: ${{ join(needs.*.result, ',') }}\n";
218
+ var verification_unitTests_default$1 = "name: Test\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n run-unit:\n description: Run unit tests with coverage (disable for UI-only repos that use Storybook testing exclusively)\n type: boolean\n required: false\n default: true\n run-storybook:\n description: Run Storybook vitest interaction tests (requires .storybook/ setup)\n type: boolean\n required: false\n default: false\n run-interaction:\n description: Run Storybook interaction and accessibility tests with Playwright\n type: boolean\n required: false\n default: false\n run-user-flow:\n description: Run Cypress E2E user-flow tests (requires cypress.config.*)\n type: boolean\n required: false\n default: false\n wait-on-url:\n description: URL to wait for before running Cypress tests (default is Vite dev server; override for non-Vite stacks e.g. http://localhost:3000 for Next.js)\n type: string\n required: false\n default: \"http://localhost:5173\"\n secrets:\n CYPRESS_RECORD_KEY:\n required: false\n TURBO_TOKEN:\n required: false\n\njobs:\n unit:\n name: Run unit tests and collect coverage\n if: ${{ inputs.run-unit }}\n permissions:\n contents: read\n id-token: write\n runs-on: ubuntu-latest\n timeout-minutes: 15\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - uses: theholocron/.github/.github/actions/holocron@main\n name: Run tests with coverage\n with:\n task: verification.unitTests\n\n # A Codecov upload must not fail silently. fail_ci_if_error makes a failed\n # upload fail this step (the action's default is to log the error and pass),\n # which fails the job and so the `Test / Conclusion` check. Whether that\n # blocks a merge is up to whether the check is required, not this workflow\n # (holocron#934).\n - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0\n name: Upload coverage to Codecov\n with:\n use_oidc: true\n fail_ci_if_error: true\n\n - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0\n name: Upload test results to Codecov\n if: ${{ !cancelled() }}\n with:\n use_oidc: true\n fail_ci_if_error: true\n report_type: test_results\n files: \"**/test-report.junit.xml\"\n\n storybook:\n name: Run Storybook interaction tests\n if: ${{ inputs.run-storybook }}\n permissions:\n contents: read\n id-token: write\n runs-on: ubuntu-latest\n timeout-minutes: 15\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: pnpm exec playwright install chromium --with-deps\n name: Install Playwright\n\n - run: pnpm test:storybook\n name: Run Storybook tests\n\n # A Codecov upload must not fail silently. fail_ci_if_error makes a failed\n # upload fail this step (the action's default is to log the error and pass),\n # which fails the job and so the `Test / Conclusion` check. Whether that\n # blocks a merge is up to whether the check is required, not this workflow\n # (holocron#934).\n - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0\n name: Upload coverage to Codecov\n with:\n use_oidc: true\n fail_ci_if_error: true\n\n - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0\n name: Upload test results to Codecov\n if: ${{ !cancelled() }}\n with:\n use_oidc: true\n fail_ci_if_error: true\n report_type: test_results\n files: \"**/test-report.junit.xml\"\n\n interaction-and-accessibility:\n name: Run interactions and accessibility tests\n if: ${{ inputs.run-interaction }}\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 15\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: pnpm exec playwright install --with-deps\n name: Install Playwright\n\n - run: pnpm test:storybook\n name: Run interaction and accessibility tests\n\n user-flow:\n name: Run user flow tests\n if: ${{ inputs.run-user-flow }}\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 15\n strategy:\n fail-fast: false\n matrix:\n containers: [1, 2]\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: pnpm exec cypress install\n name: Install Cypress binary\n\n - uses: cypress-io/github-action@1052aa98bbbe4f55210f844878213c07d9c8c399 # v6.7.13\n name: Cypress run\n with:\n start: pnpm dev\n wait-on: ${{ inputs.wait-on-url }}\n record: true\n parallel: true\n env:\n CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}\n GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n conclusion:\n name: Conclusion\n runs-on: ubuntu-latest\n if: always()\n needs: [unit, storybook, interaction-and-accessibility, user-flow]\n steps:\n - name: Check job statuses\n run: |\n if [[ \"$RESULTS\" == *\"failure\"* ]] || [[ \"$RESULTS\" == *\"cancelled\"* ]]; then\n exit 1\n fi\n env:\n RESULTS: ${{ join(needs.*.result, ',') }}\n";
219
+ //#endregion
220
+ //#region src/templates/reusable/verification.visualRegression.yml
221
+ var verification_visualRegression_default$1 = "name: Visual Regression\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n chromatic-projects:\n description: >\n JSON array of Chromatic projects to build, one matrix job per entry.\n Each entry: { \"tokenName\": \"WEB\", \"workingDir\": \"apps/web\", \"buildScript\": \"build:storybook\" }.\n tokenName maps to secret CHROMATIC_PROJECT_TOKEN_<TOKENNAME>; use \"default\"\n (or omit for the legacy empty-string form) to use the bare CHROMATIC_PROJECT_TOKEN\n secret for single-project repos.\n buildScript defaults to \"build:storybook\" when omitted.\n Required -- this task only exists in a repo's workflow list when it\n opts into Chromatic at all (holocron#394/#1062): GitHub evaluates a\n job's `if:` before expanding its `strategy.matrix`, so no default\n here (empty or otherwise) can make a *disabled* Chromatic job\n disappear from PR checks -- only not generating this job's thin\n caller in the first place can. A repo that doesn't want Chromatic\n simply omits `verification.visualRegression` from its `tasks:`.\n type: string\n required: true\n secrets:\n CHROMATIC_PROJECT_TOKEN:\n required: false\n\njobs:\n visual-and-composition:\n name: Run visual and composition tests\n strategy:\n fail-fast: false\n matrix:\n project: ${{ fromJSON(inputs.chromatic-projects) }}\n permissions:\n contents: read\n statuses: write\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n with:\n fetch-depth: 0\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - uses: chromaui/action@14cfaef73576e69f95f47f60058063f46ca38719 # v18\n name: Publish to Chromatic\n with:\n projectToken: ${{ (matrix.project.tokenName == 'default' || matrix.project.tokenName == '') && secrets.CHROMATIC_PROJECT_TOKEN || secrets[format('CHROMATIC_PROJECT_TOKEN_{0}', matrix.project.tokenName)] }}\n token: ${{ github.token }}\n buildScriptName: ${{ matrix.project.buildScript || 'build:storybook' }}\n workingDir: ${{ matrix.project.workingDir || '.' }}\n storybookBaseDir: ${{ matrix.project.storybookBaseDir || '' }}\n untraced: ${{ matrix.project.untraced || '' }}\n onlyStoryFiles: ${{ matrix.project.onlyStoryFiles || '' }}\n exitZeroOnChanges: ${{ matrix.project.exitZeroOnChanges || false }}\n";
219
222
  //#endregion
220
223
  //#region src/generators/github-action-thin-callers/github-action-thin-callers.ts
221
224
  /**
@@ -227,6 +230,7 @@ var verification_unitTests_default$1 = "name: Test\n\non: # yamllint disable-lin
227
230
  */
228
231
  const WORKFLOW_TEMPLATES = {
229
232
  "verification.unitTests": "name: Verification\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main, alpha]\n pull_request:\n\nconcurrency:\n group: test-${{ github.ref }}\n cancel-in-progress: true\n\npermissions:\n contents: read\n id-token: write\n statuses: write\n\njobs:\n test:\n name: Test\n uses: theholocron/.github/.github/workflows/verification.unitTests.yml@main\n with:\n run-unit: true\n secrets: inherit\n",
233
+ "verification.visualRegression": "name: Visual Regression\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main, alpha]\n pull_request:\n\npermissions:\n contents: read\n statuses: write\n\njobs:\n visual-and-composition:\n name: Visual Regression\n uses: theholocron/.github/.github/workflows/verification.visualRegression.yml@main\n secrets: inherit\n",
230
234
  "verification.typeSafety": "name: Verification\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main, alpha]\n pull_request:\n\nconcurrency:\n group: typecheck-${{ github.ref }}\n cancel-in-progress: true\n\npermissions:\n contents: read\n\njobs:\n typecheck:\n name: Typecheck\n uses: theholocron/.github/.github/workflows/verification.typeSafety.yml@main\n secrets: inherit\n",
231
235
  "verification.performance": "name: Verification\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main, alpha]\n pull_request:\n\npermissions:\n contents: read\n\njobs:\n performance:\n name: Audit the Performance\n uses: theholocron/.github/.github/workflows/verification.performance.yml@main\n secrets: inherit\n",
232
236
  "sourceQuality.staticAnalysis": "name: Source Quality\n\non: # yamllint disable-line rule:truthy\n push:\n branches: [main, alpha]\n pull_request:\n\nconcurrency:\n group: source-quality-static-analysis-${{ github.ref }}\n cancel-in-progress: true\n\npermissions:\n contents: write\n statuses: write\n\njobs:\n static-analysis:\n name: Static Analysis\n uses: theholocron/.github/.github/workflows/sourceQuality.staticAnalysis.yml@main\n secrets: inherit\n",
@@ -443,7 +447,7 @@ function generateCombinedDeployContent(deployWith, paths, preview) {
443
447
  * generating the thin caller. Handles:
444
448
  * - deploy shorthand: docs/storybook → type + storybook-projects
445
449
  * - preview: stripped (handled separately via extractPreviewConfig)
446
- * - run-chromatic object → run-chromatic: true + chromatic-projects
450
+ * - chromatic-projects entries' untraced array → newline-joined string
447
451
  * - plain arrays → JSON-stringified for YAML scalar quoting
448
452
  *
449
453
  * Used by both `holocron repo setup` and `sync-workflow-templates`.
@@ -465,15 +469,11 @@ function normalizeWorkflowWith(raw) {
465
469
  })));
466
470
  delete result["storybook"];
467
471
  }
468
- const runChromatic = raw["run-chromatic"];
469
- if (runChromatic !== null && typeof runChromatic === "object" && "projects" in runChromatic) {
470
- result["run-chromatic"] = true;
471
- const projects = runChromatic.projects.map((p) => ({
472
- ...p,
473
- ...Array.isArray(p.untraced) ? { untraced: p.untraced.join("\n") } : {}
474
- }));
475
- result["chromatic-projects"] = JSON.stringify(projects);
476
- }
472
+ const chromaticProjects = raw["chromatic-projects"];
473
+ if (Array.isArray(chromaticProjects)) result["chromatic-projects"] = chromaticProjects.map((p) => ({
474
+ ...p,
475
+ ...Array.isArray(p.untraced) ? { untraced: p.untraced.join("\n") } : {}
476
+ }));
477
477
  for (const [k, v] of Object.entries(result)) if (Array.isArray(v)) result[k] = JSON.stringify(v);
478
478
  return result;
479
479
  }
@@ -521,6 +521,7 @@ function deriveDeployPaths(raw) {
521
521
  /** `workflow_call` implementations → `.github/workflows/<name>.yml`. */
522
522
  const REUSABLE_WORKFLOWS = {
523
523
  "verification.unitTests": verification_unitTests_default$1,
524
+ "verification.visualRegression": verification_visualRegression_default$1,
524
525
  "verification.typeSafety": verification_typeSafety_default$1,
525
526
  "verification.performance": verification_performance_default$1,
526
527
  "sourceQuality.staticAnalysis": sourceQuality_staticAnalysis_default$1,
@@ -651,6 +652,7 @@ const TASKS = {
651
652
  dependsOn: ["^delivery.build"]
652
653
  }
653
654
  },
655
+ "verification.visualRegression": { local: null },
654
656
  "verification.performance": { local: { detect: [{
655
657
  when: /^lighthouse\.config\.(cjs|js|mjs|ts)$/,
656
658
  tool: "lhci",
@@ -928,10 +930,29 @@ function createTsconfig(options) {
928
930
  * vars to the registry default's cache-key hashing — the one thing that's
929
931
  * genuinely per-repo (e.g. a package tagging Sentry releases during its own
930
932
  * build needs `SENTRY_AUTH_TOKEN` in its cache key; most repos don't).
933
+ * `turbo.inputs` (holocron#845) appends extra input globs the same way —
934
+ * for a package whose layout the registry default doesn't cover (e.g. a
935
+ * flat-layout package with no `src/` directory at all).
931
936
  */
932
937
  /** Filed once per repo, unconditionally — every generated turbo.json's root. */
933
938
  const GLOBAL_DEPENDENCIES = ["pnpm-workspace.yaml", "tsconfig.json"];
934
939
  /**
940
+ * Guards against a malformed `turbo.inputs`/`turbo.passThroughEnv` override
941
+ * (review on holocron#845): a bare string instead of an array would
942
+ * otherwise spread into individual characters
943
+ * (`[..."**\/*.ts"]` → `["*", "*", "/", "*", ".", "t", "s"]`), silently
944
+ * emitting garbage entries instead of the intended single glob/env-var —
945
+ * the generated `turbo.json` would still be valid JSON, just wrong, with
946
+ * nothing surfacing the mistake. Only a config loaded from JSON or plain JS
947
+ * reaches this unchecked; a typed `holocron.config.ts` via `defineConfig`
948
+ * already rejects the wrong shape at compile time.
949
+ */
950
+ function validatedGlobList(value, taskName, field) {
951
+ if (value === void 0) return [];
952
+ if (!Array.isArray(value) || !value.every((item) => typeof item === "string")) throw new Error(`task "${taskName}": turbo.${field} must be an array of strings, got ${JSON.stringify(value)}`);
953
+ return value;
954
+ }
955
+ /**
935
956
  * `turbo.json` content for this manifest, pretty-printed — write it
936
957
  * directly, no merge (matches `thinCallers()` / `reusableTemplates()`: this
937
958
  * file is generated, not hand-edited). `null` when no task in the manifest
@@ -944,11 +965,16 @@ function turboConfig(config) {
944
965
  if (entry.local === false) continue;
945
966
  const turbo = TASKS[entry.name]?.turbo;
946
967
  if (!turbo) continue;
947
- const extraEnv = entry.turbo?.passThroughEnv;
948
- tasks[entry.name] = extraEnv && extraEnv.length > 0 ? {
968
+ const extraEnv = validatedGlobList(entry.turbo?.passThroughEnv, entry.name, "passThroughEnv");
969
+ const extraInputs = validatedGlobList(entry.turbo?.inputs, entry.name, "inputs");
970
+ const current = tasks[entry.name] ?? turbo;
971
+ const passThroughEnv = extraEnv.length > 0 ? [...current.passThroughEnv ?? [], ...extraEnv] : current.passThroughEnv;
972
+ const inputs = extraInputs.length > 0 ? [...current.inputs, ...extraInputs] : current.inputs;
973
+ tasks[entry.name] = {
949
974
  ...turbo,
950
- passThroughEnv: extraEnv
951
- } : turbo;
975
+ inputs,
976
+ ...passThroughEnv && passThroughEnv.length > 0 ? { passThroughEnv } : {}
977
+ };
952
978
  }
953
979
  if (Object.keys(tasks).length === 0) return null;
954
980
  return stringifyJson({
@@ -32,6 +32,15 @@ interface TaskEntry {
32
32
  turbo?: {
33
33
  /** Extra env vars turbo hashes into this task's cache key, appended to the registry default (empty when the task has none). */
34
34
  passThroughEnv?: string[];
35
+ /**
36
+ * Extra input globs appended to the registry default's `inputs`
37
+ * (holocron#845) — for a package whose layout the registry's
38
+ * `"src/**"` default doesn't cover (e.g. a flat-layout package with
39
+ * no `src/` directory at all). Appended, not replaced: the
40
+ * registry's other inputs (`package.json`, `tsdown.config.ts`, …)
41
+ * stay tracked without needing to be repeated here.
42
+ */
43
+ inputs?: string[];
35
44
  };
36
45
  }
37
46
  /** A task is either its bare name (all defaults) or an entry object. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/astromech",
3
- "version": "5.0.0-alpha.162",
3
+ "version": "5.0.0-alpha.164",
4
4
  "description": "The Holocron task runner — one task manifest drives `holocron run`, `holocron run ci`, the CI workflows, package.json scripts, linters, and required checks.",
5
5
  "keywords": [
6
6
  "ci",
@@ -48,7 +48,7 @@
48
48
  "@theholocron/fs-utils": "^1.15.1",
49
49
  "@theholocron/json-utils": "^1.15.1",
50
50
  "@theholocron/pkg-utils": "^1.15.1",
51
- "@theholocron/datapad": "5.0.0-alpha.162"
51
+ "@theholocron/datapad": "5.0.0-alpha.164"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@commitlint/config-conventional": "^21.2.3",