Files
ocas/CLAUDE.md
T
xiaoju 5463b44554 docs: update cards, README, CLAUDE.md for list pagination & ListEntry
- store.md: update Store interface (ListEntry[], ListOptions params, remove stale delete())
- variable.md: add sorting & pagination section
- README.md: add --sort/--limit/--offset/--desc flags
- CLAUDE.md: add ListOptions, ListEntry types and list-utils reference

Refs #27
2026-06-01 15:14:53 +00:00

5.1 KiB

CLAUDE.md — OCAS

Object Content Addressable Store — self-describing CAS with JSON Schema typed nodes.

Project Structure

Monorepo with 3 packages under packages/:

Package Directory Description
@ocas/core packages/core Core CAS engine — hashing, schema, store, verify, bootstrap
@ocas/fs packages/fs Filesystem-backed CAS store
@ocas/cli packages/cli CLI tool (ocas binary)

Tech Stack

  • Runtime: Bun
  • Language: TypeScript (strict mode, exactOptionalPropertyTypes, noUncheckedIndexedAccess)
  • Build: tsc --build (composite project references)
  • Test: bun test
  • Lint/Format: Biome (biome check . / biome format --write .)
  • Publish: Changesets + bun publish → npmjs (@ocas/*)

Commands

bun test          # Run all tests
bun run build     # Build all packages
bun run check     # Biome lint
bun run format    # Biome format (auto-fix)

Code Conventions

TypeScript

  • Strict mode — no any, no unchecked index access, no implicit overrides
  • verbatimModuleSyntax — use import type for type-only imports
  • Import paths — use .js extension in imports (ESM convention with bundler resolution)
  • Export style — named exports only, re-export from index.ts

Biome Rules

  • noConsole: "error" globally (except packages/cli)
  • Recommended ruleset enabled
  • Auto-organize imports via assist.actions.source.organizeImports
  • Indent: 2 spaces

Naming

  • Types: PascalCase (CasNode, Hash, Store)
  • Functions: camelCase (computeHash, createMemoryStore)
  • Constants: UPPER_SNAKE_CASE (BOOTSTRAP_STORE)
  • Files: kebab-case.ts
  • Test files: co-located as *.test.ts

Key Types

  • Hash — 13-character uppercase Crockford Base32 string (XXH64)
  • CasNode — content-addressed node with schema
  • Store — abstract storage interface (get/put)
  • VariableStore — SQLite-backed mutable bindings (name → hash)
  • ListOptions — sorting/pagination options (sort, desc, limit, offset)
  • ListEntry — list result entry (hash, created, updated)

List Utilities

packages/core/src/list-utils.ts provides applyListOptions() — in-memory sort/paginate for ListEntry[] arrays. Used by MemoryStore; FsStore pushes sort/limit to SQLite. Core layer treats limit: undefined as "no limit"; the CLI defaults to 100 in parseListOptions().

Architecture Notes

  • No "alias" concept — every name resolution flows through the VariableStore. Builtin schemas (@ocas/schema, @ocas/string, @ocas/output/*, …) are registered as variables during bootstrap(store, varStore), alongside user-defined variables created via ocas var set.
  • bootstrap(store, varStore?) writes builtin name → hash bindings into the varStore when one is provided; called automatically by openStore() and openStoreAndVarStore().
  • resolveHash(input, varStore) is the unified hash/name resolver in the CLI. If input matches the 13-char hash format it is returned as-is; otherwise the varStore is queried by exact name. This means every CLI command that accepts a hash argument also accepts a variable name (schema names, user vars, etc.).
  • openStoreAndVarStore() in the CLI opens both stores and bootstraps once; prefer it over separate openStore() + createVariableStore() to avoid double bootstrap.

Internal Dependencies

Workspace packages reference each other with workspace:* in package.json. This is resolved to real version numbers only during publishing (see below).

Git

  • Commit format: type: description (conventional commits)
  • Reference issues: Fixes #N / Closes #N
  • Author: 小橘 <xiaoju@shazhou.work>

Project Rules

Before Submitting

  1. bun test — all tests pass
  2. bun run check — no lint errors
  3. bun run build — builds cleanly

Release Process

Releases use a release branch workflow. main always keeps workspace:* for internal dependencies; version numbers are only fixed on the release branch.

Prepare

./scripts/prepare-release.sh

This script:

  1. Checks you're on main with a clean tree and pending changesets
  2. Creates release/<version> branch
  3. Runs changeset version to fix versions and generate CHANGELOGs
  4. Runs full validation (install, build, lint, test)
  5. Commits the version bump

After preparation, review changes and fix any issues on the release branch.

Publish

./scripts/publish.sh

This script:

  1. Validates you're on a release/* branch with no pending changesets
  2. Runs final build + test
  3. Publishes packages in order: @ocas/core@ocas/fs@ocas/cli
  4. Tags, pushes, merges back to main, cleans up the release branch

Adding a Changeset

Before releasing, add changesets for your changes:

bunx changeset        # interactive — pick packages + bump type + summary

Changesets live in .changeset/ as markdown files until consumed by prepare-release.sh.