- variable.md: add Naming Convention section - cli.md: update variable name examples - README.md: all examples use @scope/name format - CLAUDE.md: add variable naming rule to Architecture Notes Refs #29
5.3 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— useimport typefor type-only imports- Import paths — use
.jsextension in imports (ESM convention with bundler resolution) - Export style — named exports only, re-export from
index.ts
Biome Rules
noConsole: "error"globally (exceptpackages/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 schemaStore— 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 duringbootstrap(store, varStore), alongside user-defined variables created viaocas var set. bootstrap(store, varStore?)writes builtin name → hash bindings into the varStore when one is provided; called automatically byopenStore()andopenStoreAndVarStore().resolveHash(input, varStore)is the unified hash/name resolver in the CLI. Ifinputmatches 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.).- Variable naming: all names must follow
@scope/nameformat (@[a-zA-Z][a-zA-Z0-9]*/segments).@ocas/*is reserved for builtins. The@prefix ensures names are visually distinct from hashes. openStoreAndVarStore()in the CLI opens both stores and bootstraps once; prefer it over separateopenStore()+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
- docs/sync-readme.md — README sync conventions
Before Submitting
bun test— all tests passbun run check— no lint errorsbun 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:
- Checks you're on
mainwith a clean tree and pending changesets - Creates
release/<version>branch - Runs
changeset versionto fix versions and generate CHANGELOGs - Runs full validation (install, build, lint, test)
- Commits the version bump
After preparation, review changes and fix any issues on the release branch.
Publish
./scripts/publish.sh
This script:
- Validates you're on a
release/*branch with no pending changesets - Runs final build + test
- Publishes packages in order:
@ocas/core→@ocas/fs→@ocas/cli - 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.