WIP: A simple cli for daily tangled use cases and AI integration. This is for my personal use right now, but happy if others get mileage from it! :)
README.md

Generated Lexicon Code#

This directory contains automatically generated TypeScript code from AT Protocol lexicon definitions for the Tangled.org service.

⚠️ Do Not Edit#

IMPORTANT: All files in this directory are generated by @atproto/lex-cli and should not be manually edited. Any changes will be overwritten the next time code generation runs.

Source#

The lexicon definitions are vendored in /lexicons/ directory from:

  • Source: https://tangled.org/tangled.org/core/raw/master/lexicons/
  • Repository: https://tangled.org/tangled.org/core

Code Generation#

To regenerate this code after updating lexicons:

npm run codegen

This command:

  1. Runs @atproto/lex-cli to generate TypeScript types from lexicons
  2. Automatically fixes ES module imports by adding .js extensions
  3. Rewrites multiformats/cid imports to use the main package export

Dependencies#

The generated code requires:

  • @atproto/api - AT Protocol client library
  • @atproto/lexicon - Lexicon validation runtime
  • multiformats - CID (Content Identifier) support for content addressing

These are already included in package.json dependencies.

Note on multiformats: The code generator produces import { CID } from 'multiformats/cid' which TypeScript NodeNext module resolution cannot find. Our post-processing script (scripts/fix-lexicon-imports.js) automatically rewrites this to import { CID } from 'multiformats', which uses the main package export and resolves correctly.

Using Generated Types#

Define your own interfaces based on the lexicon schemas rather than importing from generated code. This avoids TypeScript compatibility issues with the generated code.

Example:

// src/lib/issues-api.ts
/**
 * Issue record type based on sh.tangled.repo.issue lexicon
 * @see lexicons/sh/tangled/issue/issue.json
 */
export interface IssueRecord {
  $type: 'sh.tangled.repo.issue';
  repo: string;
  title: string;
  body?: string;
  createdAt: string;
  mentions?: string[];
  references?: string[];
  [key: string]: unknown;  // Required for AT Protocol record compatibility
}

If you must import directly from generated code:

import type { Record as IssueRecord } from './lexicon/types/sh/tangled/repo/issue.js';

Note: Direct imports may cause TypeScript compilation issues. The generated code is excluded from TypeScript compilation (tsconfig.json excludes src/lexicon/**) to avoid compatibility problems.

Known Issues#

The generated code has some compatibility issues with strict TypeScript configurations:

  1. Unused imports: Generated code imports types that aren't always used (CID, BlobRef, $Typed, OmitKey)
  2. Property compatibility: needsCbor properties may not match current @atproto/lexicon types

These issues are inherent to the code generator. We work around them by:

  • Excluding src/lexicon/** from TypeScript compilation in tsconfig.json
  • Defining our own interfaces based on lexicon schemas for use in application code
  • Post-processing generated files to fix module resolution issues

Post-Processing#

After generation, scripts/fix-lexicon-imports.js automatically:

  • Adds .js extensions to relative imports for ES module compatibility
  • Rewrites import { CID } from 'multiformats/cid' to import { CID } from 'multiformats'
  • Ensures proper module resolution with TypeScript NodeNext

Structure#

src/lexicon/
├── README.md                    # This file
├── index.ts                     # Main exports (generated)
├── lexicons.ts                  # Lexicon schemas (generated)
├── util.ts                      # Utility types (generated)
└── types/
    └── sh/
        └── tangled/
            ├── repo/
            │   ├── issue.ts         # Issue record types
            │   ├── pull.ts          # Pull request types
            │   └── ...
            ├── actor/
            │   └── profile.ts
            ├── feed/
            ├── graph/
            └── ...

Updating Lexicons#

When Tangled.org updates their lexicon schemas:

  1. Fetch latest lexicons:

    npm run update-lexicons
    
  2. Regenerate TypeScript code:

    npm run codegen
    
  3. Review changes:

    • Check git diff to see what changed
    • Update any custom interfaces if lexicon schemas changed
    • Run tests: npm test
    • Verify TypeScript compiles: npm run typecheck
  4. Commit both lexicon and generated code changes:

    git add lexicons/ src/lexicon/
    git commit -m "Update Tangled lexicons and regenerate client code"
    

Troubleshooting#

TypeScript Errors#

If you see TypeScript errors from src/lexicon/**, this is expected. The generated code is excluded from compilation. As long as your application code (outside src/lexicon/) compiles, you're good.

Build Failures#

If the build fails after regenerating lexicons:

  1. Check if any lexicon schemas changed structure
  2. Update your custom interfaces to match new schemas
  3. Ensure scripts/fix-lexicon-imports.js ran successfully

Import Errors#

If you see module resolution errors:

  1. Ensure imports use .js extensions
  2. Run npm run codegen to regenerate and fix imports
  3. Check that multiformats is installed: npm ls multiformats

Reference#