Skip to content

feat: provide an Orchestrator module for devtools services #5

Description

@artiphishle

Goal

Turn @ankhorage/devtools into a standalone @ankhorage/orchestrator module that can install and maintain repo tooling services for any TypeScript repository.

The module should let consumers choose which services to enable, such as:

  • lint
  • prettier
  • knip
  • changesets
  • workflows

It should deterministically copy the required files, update package.json, install packages, and maintain a ledger under .ankh/orchestrator/ledger.

Background

@ankhorage/devtools currently centralizes ESLint and Prettier config. Follow-up issues add Knip, Changesets, and workflow templates. This issue builds on those shared assets and turns them into an installable Orchestrator module.

The module must remain standalone: any TypeScript repository should be able to use it without depending on Ankhorage app-generation internals.

Desired user experience

A repo should be able to configure devtools services declaratively, for example:

// orchestrator.config.ts
import { defineOrchestratorConfig } from '@ankhorage/orchestrator';
import { devtoolsModule } from '@ankhorage/devtools/orchestrator';

export default defineOrchestratorConfig({
  modules: [
    devtoolsModule({
      services: {
        lint: true,
        prettier: true,
        knip: true,
        changesets: true,
        workflows: true,
      },
    }),
  ],
});

A consumer should also be able to choose only a subset:

devtoolsModule({
  services: {
    lint: true,
    prettier: false,
    knip: false,
    changesets: false,
    workflows: false,
  },
});

Required generated/managed files

The module should manage files such as:

  • ESLint config wrapper
  • Prettier config wrapper
  • Knip config wrapper
  • GitHub workflow files
  • Changesets config where applicable

Exact paths should follow current tool requirements and the decisions from the prior issues.

Required package.json updates

Depending on enabled services, the module should update scripts such as:

{
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint . --fix",
    "format": "prettier --write .",
    "format:check": "prettier --check .",
    "knip": "knip",
    "changeset": "changeset"
  }
}

The exact script commands should match the shared devtools setup after Knip, Changesets, and workflow issues are implemented.

Required package installation behavior

The module should ensure required packages are installed for enabled services.

Examples:

  • @ankhorage/devtools
  • service-specific dependencies when intentionally exposed through the consuming repo

Do not install unused service dependencies when a service is disabled.

Ledger requirements

The module must keep deterministic state in:

.ankh/orchestrator/ledger

The ledger should record:

  • managed files
  • service states
  • package.json script modifications
  • dependency modifications
  • module version or schema version
  • generated timestamp

The ledger must support future cleanup when services are disabled.

Config requirements

The repo-level Orchestrator config should live in the repository root as an Orchestrator config file.

The .ankh/ directory is the hidden Ankhorage/orchestrator state directory, similar in spirit to .expo or .github.

Service enable/disable config should be explicit and typed.

Non-goals

  • Do not make this module depend on Ankhorage app manifests, ZORA, Surface, Templates, or the CLI.
  • Do not add legacy compatibility mode.
  • Do not silently overwrite user-owned files without ledger awareness.
  • Do not install disabled services.
  • Do not implement Knip, Changesets, or workflow centralization inside this issue if their prerequisite issues are not done yet.
  • Do not weaken existing repo verification commands.

Implementation plan for Codex

Phase 1: Study Orchestrator module API

Inspect the current @ankhorage/orchestrator package and existing modules such as:

  • @ankhorage/orchestrator-module-expo-localization
  • @ankhorage/orchestrator-module-expo-google-fonts

Understand the expected module shape, planning context, generated operations, dependency declarations, and test patterns.

Phase 2: Define devtools module API

Add an Orchestrator module export to @ankhorage/devtools, for example:

@ankhorage/devtools/orchestrator

Define typed service config:

interface DevtoolsModuleOptions {
  services?: {
    lint?: boolean;
    prettier?: boolean;
    knip?: boolean;
    changesets?: boolean;
    workflows?: boolean;
  };
}

Decide safe defaults. Prefer explicit services over surprising opt-ins.

Phase 3: Implement planning operations

The module should plan operations for enabled services:

  • copy or render required config/template files
  • update package.json scripts
  • add required dependencies/devDependencies
  • write/update ledger entries

Keep operations deterministic and testable.

Phase 4: Implement ledger behavior

Ledger path:

.ankh/orchestrator/ledger

Define a schema and tests for:

  • first install
  • idempotent re-run
  • service enable
  • service disable cleanup
  • preserving user-owned files

Phase 5: Add tests

Tests should cover:

  • lint-only install
  • lint + prettier install
  • full service install
  • disabled services do not install packages or scripts
  • package.json script merging
  • workflow template output
  • ledger generation
  • idempotency

Phase 6: Documentation

README should document:

  • module usage
  • available services
  • defaults
  • generated files
  • ledger path
  • how to enable/disable services
  • standalone TypeScript repo usage

Phase 7: Verification

Run:

bun run build
bun run lint:fix
bun run test

If Knip is already integrated by then, also run:

bun run knip

Acceptance criteria

  • @ankhorage/devtools/orchestrator exports a usable Orchestrator module.
  • Consumers can enable/disable individual services.
  • Enabled services generate/copy the expected files.
  • package.json scripts are updated deterministically.
  • Required packages are installed only for enabled services.
  • Ledger entries are written under .ankh/orchestrator/ledger.
  • Re-running the module is idempotent.
  • Disabling a service can remove or mark previously managed files safely.
  • The module is standalone and usable in non-Ankhorage TypeScript repos.
  • README documents the module.
  • Changeset is included.

Dependency notes

This issue depends on or should follow:

  • shared Knip config issue
  • shared workflow template issue
  • shared Changesets dependency issue

The Orchestrator module should compose those shared assets rather than duplicating them.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions