Skip to content

Latest commit

 

History

History
91 lines (70 loc) · 2.62 KB

File metadata and controls

91 lines (70 loc) · 2.62 KB

CLI Scripts

Prefer normal TypeScript files for repo scripts. The script should expose a small command surface, keep business logic importable, and avoid hiding real work inside YAML or shell strings.

Existing Examples

  • scripts/preview/preview.ts is run from the root preview script with trpc-cli scripts/preview/preview.ts.
  • apps/os/scripts/cli.ts and apps/semaphore/scripts/cli.ts use createCli({ ...import.meta, jsonInput: "auto" }) for richer app CLIs.
  • packages/iterate/pubme.js is a compact oRPC router wired into trpc-cli.
  • scripts/ci/*.ts are direct CI command modules. They are intentionally plain TypeScript because Depot YAML should call scripts, not embed large code strings.

Recommended Shape

For small scripts, export functions and let trpc-cli expose them:

trpc-cli scripts/preview/preview.ts --help

For app-style CLIs, use the existing pattern:

import { createBuiltInPrompts, createCli, isAgent, yamlTableConsoleLogger } from "trpc-cli";
import { isMainModule } from "@iterate-com/shared/dev/is-main-module";

export async function doThing(options: { name: string }) {
  return { ok: true, name: options.name };
}

if (isMainModule(import.meta.url)) {
  void createCli({
    ...import.meta,
    name: "my-script",
    jsonInput: "auto",
  }).run({
    logger: yamlTableConsoleLogger,
    prompts: isAgent() ? undefined : createBuiltInPrompts(),
  });
}

For validated command routers, use oRPC plus Zod as in packages/iterate/pubme.js:

import { os } from "@orpc/server";
import { createCli } from "trpc-cli";
import { z } from "zod";

const router = {
  publish: os
    .input(
      z.object({
        version: z.string().describe("Version to publish"),
        dryRun: z.boolean().default(false).describe("Print without changing state"),
      }),
    )
    .handler(async ({ input }) => input),
};

createCli({ router }).run();

trpc-cli also supports TypeBox schemas. This repo currently standardizes on Zod/oRPC in its examples; use TypeBox only when the script is already JSON-schema-first or the surrounding package uses TypeBox.

CI Scripts

Depot workflows should call scripts directly:

- name: Update PR dashboard
  run: pnpm tsx scripts/ci/pr-dashboard.ts

Keep CI scripts deterministic:

  • read secrets from environment variables or Doppler;
  • fail loudly when required env vars are missing;
  • keep Slack/GitHub helpers shared in scripts/ci;
  • make the real function exportable so it can be imported by tests later;
  • do not use interactive prompts in CI.

When a command needs human prompts locally, use isAgent() to disable prompts for agents and CI.