Skip to content

fathym-deno/command-line-interface

Repository files navigation

Error in user YAML: (<unknown>): mapping values are not allowed in this context at line 10 column 20
---
FrontmatterVersion: 1
DocumentType: Guide
Title: Fathym Command-Line Interface
Summary: CLI for managing Fathym runtimes, scaffolding projects, and operating local workloads.
Created: 2025-11-20
Updated: 2025-11-20
Owners:
  - fathym
References:
  - Label: Projects: Ref-Arch README
      Path: ../README.md
  - Label: Projects: Ref-Arch AGENTS
      Path: ../AGENTS.md
  - Label: Projects: Ref-Arch Guide
      Path: ../GUIDE.md
  - Label: Root README
    Path: ../../../README.md
  - Label: Root Agents Guide
    Path: ../../../AGENTS.md
  - Label: Root Workspace Guide
    Path: ../../../WORKSPACE_GUIDE.md
  - Label: Project Agents Guide
    Path: ./AGENTS.md
  - Label: Project Guide
    Path: ./GUIDE.md
---

Fathym Command-Line Interface

CLI for working with Fathym runtimes and micro-frameworks—covering scaffolding, project management, local development workflows, and operational utilities.

  • Goal: deliver a reliable CLI that automates common platform tasks (project setup, environment bootstrap, build/test/deploy flows).
  • Outputs: design notes, command reference, release packaging, and sample scripts showing usage across projects.
  • Code location: projects/ref-arch/command-line-interface/ (CLI runtime, commands/templates, tests, and runtime scripts).

Current Status

  • CLI runtime, commands, and tests moved here from @fathym/common; schema emission and runtime scripts live in ./scripts.
  • Depends on @fathym/common for core utilities and @fathym/dfs for file system abstractions.
  • Packaging tasks and compile/run helpers defined in deno.jsonc; adjust for release targets as needed.

Documentation Audit (2025-12-01)

  • Intent: Productionalize the CLI docs for launch readiness across guides, concepts, and API reference with explicit gap analysis, example QA, and an executable plan.
  • Outcome: Added a companion Documentation Production Plan that details remediation tracks, ownership, CI automation, compliance checks, and validation matrices; linked it from the readiness guide and docs index.
  • Next Steps: Implement doc:lint/doc:verify tasks, retrofit troubleshooting and security callouts, publish stability and compatibility matrices, and enforce doc impact summaries in CHANGELOG.md for releases.

Documentation Audit (2025-12-02)

  • Intent: Move beyond planning with a concrete audit of every doc/example to determine accuracy, usability, and compliance for launch.
  • Outcome: Published a Documentation Audit Report that inventories each doc area, flags verification gaps, and lists execution-ready fixes (install matrix, compatibility policy, troubleshooting/rollback, runnable snippets, compliance callouts).
  • Next Steps: Assign owners per area, capture expected outputs for prioritized snippets, wire doc:lint/doc:verify into CI, and update guides/API docs with stability and compatibility matrices.

Documentation Audit (2025-12-03)

  • Intent: Translate the readiness, production plan, and audit into a concrete, file-level execution playbook that can drive the remediation pass.
  • Outcome: Added a Documentation Implementation Runbook with sequenced tasks, validation criteria, and ownership to perform the comprehensive docs implementation pass.
  • Next Steps: Start at the top of the runbook task board (install/compatibility), capture real outputs for runnable snippets, and wire doc:lint/doc:verify into CI to gate merges.

How to Work in This Pod

  1. Review the root and portfolio Instruction Documents plus this project’s AGENTS and GUIDE.
  2. Declare intent before editing; summarize outcomes and open questions in a short log or in this README.
  3. Capture upstream provenance, release channels, and packaging details in UPSTREAM.md once known.
  4. Keep links relative; reference implementation repos/branches when selected.
  5. Record prompts or scripts used when designing commands or automations.

Features

Schema Validation & Complex Type Resolution

The CLI framework includes built-in runtime validation:

  • Schema Validation: Args and flags are validated against Zod schemas at runtime (not just help text)
  • Complex Type Resolution: ZodObject/ZodArray flags automatically resolve from file paths or inline JSON
  • fileCheck Meta: Control resolution with .meta({ fileCheck: true/false })
  • .Validate() Hook: Add custom validation with access to RootValidate() callback
// Complex types auto-resolve from files or inline JSON
const FlagsSchema = z.object({
  config: z.object({ host: z.string(), port: z.number() }), // --config ./config.json OR --config '{"host":"x"}'
  name: z.string(),
});

Command("deploy", "Deploy application")
  .Flags(FlagsSchema)
  .Validate(async ({ Params, RootValidate }) => {
    const result = await RootValidate();
    if (!result.success) return result;
    // Custom validation after schema validation
    return { success: true };
  })
  .Run(async ({ Params }) => {
    const config = Params.Flag("config"); // Already parsed object!
  })
  .Build();

See docs/api/validation.md for complete documentation.

Dynamic Path Routing (Segments)

The CLI framework supports Next.js-style file-based routing with dynamic segments. This enables commands like cli projects @pkg/name ref where @pkg/name is captured as a dynamic parameter.

Segment Types:

  • [param] - Required segment (captures any non-empty value)
  • [[param]] - Optional segment (may be omitted)
  • [...rest] - Rest/catch-all segment (captures one or more values as array)

Directory Structure:

commands/
├── projects/
│   ├── list.ts                    # cli projects list
│   └── [projectRef]/              # Dynamic segment folder
│       ├── .group.ts           # Group metadata for dynamic commands
│       ├── ref.ts                 # cli projects <projectRef> ref
│       ├── build.ts               # cli projects <projectRef> build
│       └── deps/
│           └── update.ts          # cli projects <projectRef> deps update

Defining Commands with Segments:

import { z } from "zod";
import { Command, CommandParams } from "@fathym/cli";

// Define segment schema
const SegmentsSchema = z.object({
  projectRef: z.string().describe("Project reference (@scope/name or path)"),
});

// Custom params class for typed access
class RefCommandParams
  extends CommandParams<[], {}, z.infer<typeof SegmentsSchema>> {
  get ProjectRef(): string {
    return this.Segment("projectRef") as string;
  }
}

export default Command("projects:[projectRef]:ref", "Display project details")
  .Segments(SegmentsSchema) // Define expected segments
  .Params(RefCommandParams)
  .Run(async ({ Params, Segments }) => {
    // Access via Params or directly via Segments
    console.log(`Project: ${Params.ProjectRef}`);
    console.log(`Project: ${Segments.projectRef}`);
    return 0;
  });

Accessing Segments in Commands:

Segments are available in two ways:

  1. Via ctx.Segments - Direct access to all extracted values
  2. Via ctx.Params.Segment('name') - Type-safe access through CommandParams
.Run(async ({ Segments, Params }) => {
  // Direct access
  const ref = Segments.projectRef;

  // Type-safe access (with custom Params class)
  const ref2 = Params.Segment('projectRef');

  // Rest segments are arrays
  const paths = Segments.path; // string[] for [...path]
})

Testing Dynamic Commands:

import { CommandIntent, CommandIntentSuite } from "@fathym/cli";
import refCommand from "./[projectRef]/ref.ts";

// Single test with segments
await CommandIntent("resolves project by name", refCommand, import.meta.url)
  .Segments({ projectRef: "@fathym/cli" }) // Mock segment value
  .ExpectSuccess()
  .Run();

// Multiple tests with shared segments
await CommandIntentSuite("ref command", refCommand, import.meta.url)
  .Segments({ projectRef: "@fathym/cli" }) // Applied to all tests
  .Add("shows project info")
  .ExpectSuccess()
  .Add("handles missing project")
  .Segments({ projectRef: "@nonexistent/pkg" }) // Override for this test
  .ExpectFailure()
  .Run();

Help Output:

Dynamic commands display segments in help output:

📘 Display project details

Usage:
  cli projects <projectRef> ref [options]

Segments:
  <projectRef> - Project reference (@scope/name or path)

Flags:
  --json - Output as JSON

--describe and --plan Output:

Both --describe and --plan flags include segment information:

{
  "name": "ref",
  "segments": [
    { "name": "projectRef", "type": "required", "description": "Project reference" }
  ],
  "args": [],
  "flags": [...]
}

See the test-cli examples in test-cli/commands/dynamic/ for working implementations.

Command Stack Architecture

The CLI framework uses a Command Stack pattern with nested middleware execution for runtime orchestration. The stack defines participants (CLIRuntime, GroupRuntime, FlagCommands), but execution follows a middleware pattern where each layer wraps the next.

Key Concepts:

  • Runtimes implement CommandStackItem - GroupRuntime and CLIRuntime provide Key and Wrap() directly
  • Nested middleware execution - Each Wrap() returns a CommandModule with $Command injected
  • Builder-first approach - FlagCommands and intent system accept builders, not built modules
  • IoC flows from executor - No parent IoC parameter needed in Wrap()

How it works:

// Stack is built from runtimes
const stack = CommandStackBuilder.Build(
  cliRuntime,
  groupRuntimes,
  flagCommands,
);

// Each item wraps the next, creating middleware layers
// CLI → Group → FlagCommand → Command
const executor = new CommandStackExecutor(stack);
await executor.Execute(inputCommand);

FlagCommand integration:

FlagCommands remain as builders until wrap time, allowing $Command and $FlagCommand injection:

// FlagCommands are builders, not built modules
export const HelpFlagCommand = FlagCommand("help", "Show help")
  .Run(async ({ Command, FlagCommand }) => {
    // $Command and $FlagCommand injected at wrap time
    console.log(Command.description);
  });
// Note: No .Build() call - stays as builder

UnknownCommand handling:

When no command matches, an UnknownCommand executes through the same stack pattern, ensuring consistent lifecycle hooks and middleware execution.

Related Projects

  • Fathym CLI (open-source): projects/open-source/fathym-cli now hosts the ftm commands/templates/docs. Use @fathym/cli runtime from this repo as the dependency.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors