CLI Reference

The Glyph CLI provides all the tools you need to create, develop, build, test, and validate extensions.

Getting Started

Scaffold a new project:

npx create-glyph-extension my-extensions
cd my-extensions
npm run dev

The scaffolder asks for:

PromptDefault
Project namedirectory argument
First source ID(required)
Source display name(required)
Languageen
Authorgit user.name
GitHub repo URL(optional)

This creates a complete project with an example source, build config, test setup, and a dev server landing page.

Commands

All commands are available via npm run scripts. Pass flags with --:

npm run dev                      # no flags
npm run dev -- --open            # with flags

glyph dev

Start a development server with hot reload.

npm run dev
npm run dev -- --port 3000
npm run dev -- --open
OptionDescription
--port <number>Port number (default: 8888)
--openOpen browser automatically
--url <url>Public base URL for tunnels (cloudflared, ngrok, etc)

The dev server:

  • Watches all sources for file changes
  • Rebuilds automatically on save
  • Picks up new sources added while running (via glyph add in another terminal)
  • Serves index.html, bundles, and static files
  • Prints all network interface URLs and deep links for iOS testing
  • Auto-increments port if taken
  • Accepts remote logs from the iOS app via a /api/log POST endpoint
  • Includes a Playground for testing extension methods in the browser (see below)

Interactive terminal commands:

KeyAction
hShow help
rRestart all builds
uShow server URLs
qQuit the dev server

Playground

The dev server landing page includes an interactive playground below the sources list. It lets you test your extension methods directly in the browser, no iOS device needed.

How it works:

  1. Select a source from the dropdown
  2. Pick a method tab: Search, Novel Details, Chapter, or Discover
  3. Enter the inputs (query, URL, etc.) and click Run
  4. View results as a visual Preview or raw JSON

The playground executes your extension code on the server (not in the browser), making real HTTP requests to the target website. This means no CORS issues and identical behavior to the app.

Navigation flow: Results are clickable. Click a search result to load its novel details, click a chapter to read its content. This mirrors the app’s navigation: browse → novel → chapter.

Runs alongside iOS testing: The deep link and sources list are still at the top of the page. You can test on your iPhone and in the playground at the same time.

glyph logcat

Start a standalone log receiver server. The iOS app streams logs here when connected to a dev server.

npx glyph logcat
npx glyph logcat -p 3000
OptionDescription
-p, --port <number>Port number (default: 9999)

The server listens for log entries on HTTP and displays them in the terminal with timestamps and color-coded levels:

  • INFO: blue
  • WARN: yellow
  • ERROR: red

Each entry includes a category tag so you can tell which source or subsystem produced it. This is the same log stream available through the /api/log endpoint in glyph dev, but as a dedicated process you can run in a separate terminal window.

glyph build

Build all extensions for production.

npm run build

Creates optimized ESM bundles in dist/. For each source:

  1. JS sources: Bundles with esbuild, validates, copies static assets
  2. Rust sources: Builds with cargo component, transpiles with JCO
  3. Generates dist/index.json with all sources

Progress is shown with listr2 spinners for each source. When the build finishes, you see the bundle size and timing for each source, plus the total build time. A .metafile.json file is written alongside each bundle for bundle analysis (compatible with esbuild’s bundle analyzer).

Exits with code 1 if any source fails validation.

glyph test

Run tests with vitest.

npm test
npm test -- --watch
npm test -- src/mysite.test.ts
npm test -- --generate
OptionDescription
--generateScaffold test files for sources that don’t have one yet

Arguments after -- are passed directly to vitest (except --generate, which is handled by the CLI). The CLI automatically injects the runtime test setup that provides WIT interface shims, no manual setup file needed in your project.

--generate creates a basic test file with the source imports and a placeholder test for each source missing a .test.ts file. Useful after adding several sources with glyph add.

glyph validate

Validate all extension sources.

npm run validate
npm run validate -- --typecheck
npm run validate -- --tests
npm run validate -- --smoke
npm run validate -- --fix
npm run validate -- --ci
OptionDescription
--typecheckRun tsc --noEmit (requires typescript)
--testsRun the test suite
--smokeRun smoke test (calls searchNovels with real HTTP)
--fixAuto-fix fixable issues
--ciJSON output, non-interactive

Base validation (always runs):

  • Bundle builds successfully
  • info object has all required fields: id, name, version, baseUrl, icon, language
  • Required methods exist: searchNovels, fetchNovelDetails, fetchChapterContent

Auto-fixable issues (--fix):

  • Missing icon → adds ${baseUrl}/favicon.ico
  • Missing version → adds 1.0.0
  • Missing language → adds en

CI output (--ci):

{
  "passed": true,
  "sources": [{ "id": "mysite", "passed": true, "errors": [] }]
}

Default output uses listr2 progress spinners (falls back to plain text in CI mode):

Validating 2 source(s)...
  ✓ mysite
  ✗ othersite
    - info.icon is missing (fixable with --fix)
    - searchNovels() is not implemented

1 of 2 sources passed.

glyph add

Add a new source to an existing project.

glyph add mysite                # TypeScript (default)
glyph add -l rust mysite        # Rust
OptionDescription
-l, --language <lang>Extension language: js (default) or rust

Prompts for:

PromptDefault
Source display name(required)
Languageen

Creates the full source directory structure:

TypeScript:

sources/mysite/
├── package.json
├── tsconfig.json
├── static/
└── src/
    ├── main.ts          # Skeleton with TODOs
    ├── parser.ts        # Empty parser class
    └── mysite.test.ts   # Test template

Rust:

sources/mysite/
├── Cargo.toml           # With [package.metadata.component] for WIT
├── source.json          # Extension metadata (incl. capabilities array)
├── static/
└── src/
    └── lib.rs           # Stub Guest implementation

See Rust Extensions for the full Rust workflow (prerequisites, source.json fields, the Guest trait, and current limitations).

glyph --version

Print the CLI version.

Error Messages

The CLI provides clear error messages when something is wrong:

SituationMessage
Not in a projectrepo.json not found. Are you in a Glyph extension project?
No sourcesNo sources found in sources/. Run "glyph add <name>" to create one.
Missing dependenciesDependencies not installed. Run "npm install" first.
Source already existssources/mysite already exists.
TypeScript not installedtypescript is required for --typecheck.