diff --git a/docs/design-doc.md b/docs/design-doc.md new file mode 100644 index 0000000..0349feb --- /dev/null +++ b/docs/design-doc.md @@ -0,0 +1,257 @@ +# Project: OCIF Utilities + +## 1. Overview + +The OCIF Utilities project will establish a mono-repo containing a comprehensive suite of tools for working with the Open Canvas Interchange Format (OCIF) **version 0.4**. OCIF is a file format designed to ensure interoperability and data exchange across diverse infinite canvas applications. This initiative will deliver a core TypeScript library and a companion command-line interface (CLI), both distributable via NPM. These tools will enable users and developers to parse, validate, and convert OCIF files, as well as transform other common canvas file formats into OCIF and vice-versa, all while adhering to the OCIF v0.4 specification. + +## 2\. Goals + +- **Develop a Core TypeScript Library (ocif-lib):** + + - Publishable on NPM for easy integration into other projects. + - Provide programmatic access to OCIF v0.4 functionalities: + - **Parsing:** Convert OCIF v0.4 file content into a structured, typed JavaScript object. + - **Validation:** Verify OCIF files against the OCIF v0.4 specification, offering detailed and actionable error/warning messages that pinpoint deviations from the spec. + - **Conversion:** Transform data between OCIF v0.4 and other formats (e.g., TLDraw to OCIF, OCIF to SVG). + +- **Create a Command-Line Interface (ocif-cli):** + + - Publishable on NPM for global installation and ease of use. + - Utilize the ocif-lib for its underlying logic. + - Offer intuitive commands for: + - Validating OCIF v0.4 files. + - Converting files between supported formats (with OCIF v0.4 as a primary target/source). + - Displaying help and usage information. + +- **Prioritize Simplicity and Maintainability:** Start with the simplest viable product and evolve as needed, avoiding premature optimization or over-engineering. +- **User Experience:** Ensure clear, helpful error messages and straightforward command structures for both the library and CLI, with validation messages directly referencing OCIF v0.4 specification details. + +## 3\. Repository Structure (Initial Proposal) + +(No changes from the previous version of this section, but the contents of ocif-lib/src/ will be more spec-aware.) + +`ocif-utilities/` +`├── packages/` +`│ ├── ocif-lib/ # Core TypeScript library` +`│ │ ├── src/` +`│ │ │ ├── index.ts # Main library exports` +`│ │ │ ├── parser.ts # OCIF parsing logic` +`│ │ │ ├── validator.ts # OCIF validation logic` +`│ │ │ ├── converters/ # Directory for format conversion modules` +`│ │ │ │ ├── tldrawToOcif.ts` +`│ │ │ │ └── ocifToSvg.ts` +`│ │ │ ├── types.ts # TypeScript type definitions for OCIF v0.4` +`│ │ │ └── constants.ts # Constants from the spec (e.g., VERSION, element types)` +`│ │ ├── package.json` +`│ │ └── tsconfig.json` +`│ └── ocif-cli/ # Command-line interface` +`│ ├── src/` +`│ │ ├── index.ts # CLI entry point (registers commands)` +`│ │ ├── commands/ # Directory for CLI command handlers` +`│ │ │ ├── validate.ts` +`│ │ │ ├── convert.ts` +`│ │ │ └── help.ts # (Potentially integrated into a CLI framework)` +`│ │ └── utils/ # Utility functions for the CLI` +`│ ├── package.json` +`│ └── tsconfig.json` +`├── .gitignore` +`├── package.json # Root package.json (for workspace config, dev dependencies)` +`├── tsconfig.base.json # Shared TypeScript configuration` +`└── README.md # Project overview, setup, usage, contribution guidelines` + +## 4\. Core Library: ocif-lib + +- **Language:** TypeScript +- **Distribution:** NPM Package (e.g., @ocif/lib or ocif-lib) +- **Key Exports & Functionality:** + + - **OCIF_VERSION \= "0.4" (from constants.ts)** + - **Type Definitions (types.ts):** + + - These will be crucial and directly derived from the OCIF v0.4 spec. Example structure: + `// In packages/ocif-lib/src/types.ts` + + `export type ISO8601Timestamp = string;` + `export type ColorHex = string; // Or a more specific type if validation is added` + + `export interface CustomData {` + `[key: string]: any;` + `}` + + `export interface RootMetadata {` + `created_at: ISO8601Timestamp;` + `updated_at: ISO8601Timestamp;` + `custom_data?: CustomData;` + `}` + + `export interface CanvasMetadata {` + `name?: string;` + `created_at: ISO8601Timestamp;` + `updated_at: ISO8601Timestamp;` + `custom_data?: CustomData;` + `}` + + `export enum ElementType {` + `Rectangle = "rectangle",` + `Ellipse = "ellipse",` + `Text = "text",` + `Image = "image",` + `Line = "line",` + `Draw = "draw",` + `Group = "group",` + `Frame = "frame",` + `Embed = "embed",` + `StickyNote = "sticky_note",` + `Arrow = "arrow",` + `}` + + `export interface BaseElement {` + `id: string; // UUIDv4 recommended` + `type: ElementType;` + `created_at: ISO8601Timestamp;` + `updated_at: ISO8601Timestamp;` + `x: number;` + `y: number;` + `width: number; // Must be non-negative` + `height: number; // Must be non-negative` + `rotation: number; // In degrees` + `is_locked: boolean;` + `custom_data?: CustomData;` + `}` + + `// Specific Element Types extending BaseElement` + `export interface RectangleElement extends BaseElement {` + `type: ElementType.Rectangle;` + `fill_color?: ColorHex;` + `stroke_color?: ColorHex;` + `stroke_width?: number;` + `stroke_style?: "solid" | "dashed" | "dotted";` + `}` + + `export interface EllipseElement extends BaseElement {` + `type: ElementType.Ellipse;` + `fill_color?: ColorHex;` + `stroke_color?: ColorHex;` + `stroke_width?: number;` + `stroke_style?: "solid" | "dashed" | "dotted";` + `}` + + `export interface TextElement extends BaseElement {` + `type: ElementType.Text;` + `text: string;` + `font_family?: string;` + `font_size?: number;` + `text_align?: "left" | "center" | "right";` + `vertical_align?: "top" | "middle" | "bottom";` + `color?: ColorHex;` + `}` + + `export interface ImageElement extends BaseElement {` + `type: ElementType.Image;` + `url?: string;` + `data?: string; // Base64 encoded` + `mime_type?: string; // Required if data is present` + `opacity?: number; // 0.0 to 1.0` + `}` + + `export interface LineElement extends BaseElement {` + `type: ElementType.Line;` + `points: Array<[number, number]>; // At least two points` + `stroke_color?: ColorHex;` + `stroke_width?: number;` + `stroke_style?: "solid" | "dashed" | "dotted";` + `}` + + `// ... other element types (Draw, Group, Frame, Embed, StickyNote, Arrow)` + + `export interface Canvas {` + `id: string; // UUIDv4 recommended` + `elements: Array; // Actually a union of all specific element types` + `metadata?: CanvasMetadata;` + `}` + + `export interface OCIFData {` + `version: "0.4";` + `metadata: RootMetadata;` + `canvases: Array;` + `}` + + - **parse(ocifFileContent: string): Promise\** + - **Input:** The string content of an OCIF file. + - **Output:** A Promise resolving to a JavaScript object typed as OCIFData. + - **Process:** Will parse the JSON and perform initial structural checks. Deeper validation is deferred to the validate function. + - **Errors:** Throws descriptive errors on JSON syntax or fundamental structural parsing failures (e.g., if version or canvases is missing). + - **validate(data: OCIFData | object): Promise\<{ isValid: boolean; errors: Array\<{ path: string; message: string; code?: string }\>; warnings: Array\<{ path: string; message: string; code?: string }\> }\>** + - **Input:** A JavaScript object, ideally typed as OCIFData (output from parse), or a generic object if validating untrusted data. + - **Output:** A Promise resolving to an object containing: + - isValid: Boolean. + - errors: Array of error objects. Each error will include: + - path: A string path to the field causing the error (e.g., canvases\[0\].elements\[2\].width, metadata.created_at). + - message: Human-readable message explaining the error in context of the OCIF v0.4 spec (e.g., "Property 'width' must be a non-negative number.", "Element type 'my_custom_shape' is not a recognized OCIF element type.", "Image element 'img123' must have either a 'url' or a 'data' property."). + - code (optional): A code referencing a specific part of the OCIF spec or an internal error type. + - warnings: Similar structure for non-critical issues or best practice deviations. + - **Validation Logic will check:** + - Root object: version is "0.4", presence of metadata and canvases. + - RootMetadata: created_at, updated_at are valid ISO 8601\. + - Each Canvas: id presence, elements array, optional metadata structure. + - Each Element in Canvas.elements: + - Presence and correct types of id, type, created_at, updated_at, x, y, width, height (non-negative), rotation, is_locked. + - type is one of the allowed ElementType enum values. + - Type-specific properties: + - rectangle/ellipse: valid fill_color, stroke_color, stroke_width, stroke_style. + - text: presence of text string, valid font_family, font_size, text_align, vertical_align, color. + - image: presence of url OR data; mime_type if data is present; opacity between 0.0 and 1.0. + - line: points array has at least two coordinate pairs. + - draw: points array structure. + - group: element_ids is an array of strings. + - frame: optional name, optional fill_color. + - embed: presence of url. + - sticky_note: presence of text, color. + - arrow: presence of start_point, end_point. + - custom_data is an object if present. + - ID uniqueness (e.g., canvas IDs, element IDs within a canvas) could be a validation step. + - **Conversion Functions (example signatures):** + - **convert(options: { data: string | object; from: string; to: string }): Promise\** + - (No change in signature, but implementation will be aware of OCIF v0.4 types when from or to is 'ocif'). + - When converting _to_ OCIF, the output string must be a valid OCIF v0.4 document. The internal representation before stringification should match OCIFData. + - When converting _from_ OCIF, the input data (if an object) will be expected to conform to OCIFData. + +- **Modularity:** Functions should be individually exportable. Types and constants (like ElementType enum and OCIF_VERSION) will also be exported. + +## 5\. Command-Line Interface: ocif-cli + +- **Language:** TypeScript (depends on ocif-lib) +- **Distribution:** NPM Package (e.g., ocif or @ocif/cli for global installation) +- **Main Executable:** ocif +- **Proposed Commands:** + - **ocif help \[command\]** (No change) + - **ocif validate \** + - **Behavior:** + - For each file, it will read the content, then call ocifLib.parse() followed by ocifLib.validate(). + - Error messages will leverage the detailed path and message from the validate function, making them highly specific (e.g., INVALID: my_canvas.ocif \- canvases\[0\].elements\[1\].type: Unknown element type 'circle'. Allowed types are: rectangle, ellipse, ...). + - (Other details unchanged) + - **ocif convert \ \--to \ \[output_options\]** + - **Behavior:** + - When \--to ocif is specified, the CLI will ensure the output is a valid OCIF v0.4 document. + - When \--from ocif is specified, the CLI will parse and potentially validate the input OCIF file using ocif-lib before conversion. + - (Other details unchanged) + +## 6\. Development & Technical Details + +- **Error Handling:** Validation errors from ocif-lib will be central to providing actionable feedback in the CLI. +- **Testing:** + - **ocif-lib:** + - Extensive unit tests for validator.ts covering all rules in the OCIF v0.4 spec (valid and invalid cases for each property and element type). + - Unit tests for parser.ts for various valid and malformed OCIF strings. + - Unit tests for each implemented converter. + - Test with example OCIF v0.4 files. + - **ocif-cli:** (No change) +- **Documentation:** + - The ocif-lib API documentation should clearly reference OCIFData and other exported types from types.ts. +- (Other details unchanged) + +## 7\. OCIF Specification Adherence + +- The ocif-lib will be the canonical implementation for OCIF v0.4 parsing and validation within this project. +- All tools will explicitly target OCIF version "0.4" as defined in the provided specification. +- Future updates to the OCIF specification will require version bumps and corresponding updates to the library, types, and validation logic. diff --git a/docs/phased-implementation-plan.md b/docs/phased-implementation-plan.md new file mode 100644 index 0000000..9b26145 --- /dev/null +++ b/docs/phased-implementation-plan.md @@ -0,0 +1,214 @@ +# ocif-tools Phased Implementation Plan + +## Guiding Principles for Development + +- **Test-Driven Development (TDD):** For each new piece of functionality (especially in ocif-lib), tests will be written _before_ the implementation. This ensures clarity on requirements and verifiable correctness. +- **Incremental Builds:** Each phase builds upon the previous, creating usable and testable software at each step. +- **Focus on OCIF v0.4:** All development will strictly adhere to the provided OCIF v0.4 specification. +- **Separate Library and CLI Development:** While interdependent, treat ocif-lib and ocif-cli as distinct development efforts within their phases, with the library generally preceding CLI features that depend on it. + +## Development Plan: OCIF Utilities + +### Phase 0: Project Foundation & ocif-lib Scaffolding + +- **Goal:** Set up the development environment, monorepo structure, and define the core data structures for OCIF v0.4 in ocif-lib. +- **Tasks:** + 1. **Monorepo Setup:** + - Initialize project directory with Git. + - Set up npm/yarn/pnpm workspaces. + - Create packages/ocif-lib and packages/ocif-cli. + - Root package.json with workspace configuration and shared dev dependencies (TypeScript, ESLint, Prettier, Jest/Vitest). + 2. **ocif-lib Initial Setup:** + - package.json specific to ocif-lib. + - tsconfig.json for ocif-lib (extending a base tsconfig.base.json). + - Set up testing framework (e.g., Jest or Vitest) within ocif-lib. + - **Implement ocif-lib/src/types.ts:** Define all TypeScript interfaces and enums based on the OCIF v0.4 spec (e.g., OCIFData, RootMetadata, Canvas, CanvasMetadata, BaseElement, all specific Element types like RectangleElement, ImageElement, etc., ElementType enum, ISO8601Timestamp, ColorHex). + - **Implement ocif-lib/src/constants.ts:** Define OCIF_VERSION \= "0.4" and potentially an array of ElementType values for easier iteration if needed. + 3. **Tooling & CI:** + - Configure ESLint and Prettier for code consistency. + - Set up basic Continuous Integration (e.g., GitHub Actions) to run linting and (initially empty) tests. +- **Testing Strategy for Phase 0:** + - No functional tests yet, but ensure the project structure compiles. + - CI setup will verify tooling. + - The primary deliverable, types.ts, will be validated by its usage in subsequent phases. +- **Deliverables:** + - Initialized monorepo with configured tooling. + - ocif-lib package with complete types.ts and constants.ts reflecting OCIF v0.4. + - Basic CI pipeline. + +### Phase 1: ocif-lib \- Core OCIF v0.4 Validation (TDD) + +- **Goal:** Implement a robust OCIF v0.4 validator within ocif-lib, driven by a comprehensive test suite. +- **Tasks:** + 1. **Test Data Preparation:** + - Create a ocif-lib/test/fixtures/validation/ directory. + - **Valid Samples:** Develop 2-3 small but complete, valid OCIF v0.4 JSON files. + - **Invalid Unitary Samples:** Create numerous small OCIF JSON snippets, each designed to fail a _specific_ validation rule (e.g., missing version, incorrect version, invalid timestamp format in metadata.created_at, canvas.elements\[0\].width as a string, image element missing url and data, unknown element type, etc.). + - **Invalid Complex Samples:** Create 1-2 larger OCIF JSON files with multiple, varied errors. + - _(Self-correction: "Robust inputs from many different libraries" should be interpreted as crafting OCIF files that represent potential conversion targets, then introducing errors into those OCIF files to test the validator's strictness against the spec, not testing non-OCIF files with the OCIF validator directly)._ + 2. **Implement ocif-lib/src/validator.ts (TDD):** + - Define the validate(data: OCIFData | object): Promise\<{ isValid: boolean; errors: Array\<...\>; warnings: Array\<...\> }\> function signature. + - Iteratively implement validation logic: + - **Test First:** For each rule (e.g., "Root object must have 'version' property equal to '0.4'"): + - Write a test using a valid snippet that passes this rule. + - Write a test using an invalid snippet that fails this rule, asserting the expected error path and message. + - **Implement Rule:** Write the validation code to make the tests pass. + - **Refactor:** Clean up code if necessary. + - **Validation Coverage (based on OCIF v0.4 spec):** + - Root object structure (version, metadata, canvases). + - RootMetadata and CanvasMetadata fields and types. + - Canvas structure and id uniqueness (within the file). + - BaseElement properties: presence, types, constraints (e.g., width/height non-negative). + - Element.id uniqueness within its canvas. + - Element.type against ElementType enum. + - All type-specific properties for each ElementType (e.g., text.text presence, image requiring url or data, line.points having at least two entries, etc.). + - Data format validations (ISO 8601 timestamps, color formats if specified, opacity range). + - custom_data structure (must be an object if present). +- **Testing Strategy for Phase 1:** + - Heavy use of Jest/Vitest's describe, it, expect. + - Test suites organized by OCIF object type (root, metadata, canvas, specific elements). + - Ensure error objects contain accurate path and message properties. +- **Deliverables:** + - A thoroughly tested validator.ts module in ocif-lib. + - A comprehensive suite of validation test cases and fixture files. + - CI pipeline successfully running all validation tests. + +### Phase 2: ocif-lib \- OCIF v0.4 Parser (TDD) + +- **Goal:** Implement a parser that safely converts an OCIF v0.4 JSON string into a typed JavaScript object. +- **Tasks:** + 1. **Test Data Preparation (ocif-lib/test/fixtures/parsing/):** + - Use valid OCIF JSON strings (can reuse from validation fixtures). + - Create malformed JSON strings. + - Create valid JSON strings that are _not_ OCIF structures (e.g., \[\], {"foo": "bar"}). + 2. **Implement ocif-lib/src/parser.ts (TDD):** + - Define parse(ocifFileContent: string): Promise\ function signature. + - **Test First:** + - Test parsing of valid OCIF string to OCIFData object. + - Test parsing of malformed JSON (expect specific JSON parse error). + - Test parsing of valid JSON that isn't structurally OCIF (expect a meaningful error, e.g., "Not an OCIF object: 'version' property missing"). _The parser can do a light structural check before handing off to the more comprehensive validator._ + - **Implement:** Use JSON.parse() and add light initial checks (e.g., presence of version). +- **Testing Strategy for Phase 2:** + - Focus on successful parsing and graceful error handling for invalid JSON. +- **Deliverables:** + - A tested parser.ts module in ocif-lib. + - Parser test suite and fixtures. + +### Phase 3: ocif-cli \- Setup & validate Command (TDD) + +- **Goal:** Create the basic CLI application and implement the validate command, using the ocif-lib. +- **Tasks:** + 1. **ocif-cli Initial Setup:** + - package.json for ocif-cli (dependencies on ocif-lib, CLI argument parser like yargs or commander). + - tsconfig.json for ocif-cli. + - CLI entry point (src/index.ts) with shebang \#\!/usr/bin/env node. + - Configure bin in package.json to expose the ocif command. + - Setup testing for CLI (integration style, e.g., using execa to run compiled CLI commands and check stdout, stderr, exit codes). + 2. **Implement ocif validate \ command (TDD):** + - Define command structure using the chosen CLI framework. + - **Test First (CLI integration tests):** + - Test ocif validate valid_file.ocif (expect success message, exit code 0). + - Test ocif validate invalid_file.ocif (expect detailed error messages from ocif-lib\#validate, exit code 1). + - Test with multiple files (glob pattern, mix of valid/invalid). + - Test with non-existent file (expect CLI error message). + - Test output format for clarity. + - **Implement:** + - Logic to parse arguments and resolve file paths/globs. + - For each file: read content, call ocifLib.parse(), then ocifLib.validate(). + - Format and print results to console. + - Set process exit code based on validation outcomes. +- **Testing Strategy for Phase 3:** + - Focus on CLI behavior: argument parsing, file handling, correct invocation of ocif-lib, console output, and exit codes. + - Use fixture files from ocif-lib's validation tests as input for CLI tests. +- **Deliverables:** + - ocif-cli package with a working validate command. + - CLI test suite for the validate command. + +### Phase 4: ocif-lib \- Initial Converters (e.g., TLDraw to OCIF, OCIF to SVG) (TDD) + +- **Goal:** Implement core conversion functionalities in ocif-lib. +- **Tasks (repeated for each converter, e.g., TLDraw to OCIF):** + 1. **Research & Understand Source Format:** Deeply understand the structure of the source format (e.g., TLDraw's JSON). + 2. **Test Data Preparation (ocif-lib/test/fixtures/conversion/tldraw_to_ocif/):** + - Gather diverse sample files from the source format (e.g., various TLDraw files with different elements, properties). + - For each source sample, manually create the _expected_ OCIF v0.4 JSON output. This is critical for TDD. + 3. **Implement Converter Logic (e.g., converters/tldrawToOcif.ts) (TDD):** + - Define the main conversion function (e.g., tldrawToOcif(tldrawJson: object): Promise\). + - **Test First:** For each distinct element or feature in TLDraw: + - Write a test using a small TLDraw snippet. + - Assert that the converter produces the expected OCIF element(s) structure. + - **Implement:** Write mapping logic from TLDraw properties to OCIF v0.4 properties. Ensure generated OCIF data conforms to OCIFData types. + - **Self-Validate Output:** Internally, after generating the OCIF object, run it through ocifLib.validate() within the tests to ensure the converter produces valid OCIF. + 4. **Implement OCIF to SVG Converter:** + - Similar process: define OCIF input samples, manually determine expected SVG snippets/structure (SVG testing can be complex; might involve snapshot testing or checking for key element presence and attributes). +- **Testing Strategy for Phase 4:** + - Unit tests for each transformation rule within a converter. + - Ensure outputs are valid OCIF v0.4 (for toOcif converters) by re-using the validate function. + - For ocifToSvg, tests might check for the presence of specific SVG tags, correct attributes, or use snapshot testing for visual stability. +- **Deliverables:** + - Tested converter modules within ocif-lib (e.g., tldrawToOcif.ts, ocifToSvg.ts). + - Comprehensive test suites and fixture files for each converter. + +### Phase 5: ocif-cli \- convert Command (TDD) + +- **Goal:** Implement the convert command in the CLI, utilizing the converters from ocif-lib. +- **Tasks:** + 1. **Implement ocif convert \ \--to \ \[...\] command (TDD):** + - Define command structure, including options: \--from, \--to, \-o/--output. + - **Test First (CLI integration tests):** + - Test ocif convert input.tldr \--to ocif \-o output.ocif. + - Test ocif convert input.ocif \--to svg (default output naming). + - Test various combinations of options (format inference for \--from, output to directory). + - Test error handling (unsupported format, file I/O errors). + - **Implement:** + - Argument parsing and validation. + - File reading. + - Logic to select and call the appropriate ocifLib.convert function (or specific converter). + - Output file path determination and writing. + - User feedback messages. +- **Testing Strategy for Phase 5:** + - CLI integration tests covering various conversion scenarios, options, and error conditions. + - Use fixture files from ocif-lib converter tests as inputs. +- **Deliverables:** + - Working convert command in ocif-cli. + - CLI test suite for the convert command. + +### Phase 6: ocif-cli \- help Command & Polish + +- **Goal:** Ensure the CLI is user-friendly with good help messages and overall polish. +- **Tasks:** + 1. **Implement/Refine ocif help \[command\]:** + - Ensure chosen CLI framework generates helpful and accurate messages for ocif help, ocif validate \--help, ocif convert \--help. + 2. **Review CLI UX:** + - Check all console outputs for clarity, consistency, and usefulness. + - Error message review. + 3. **Code Cleanup:** General refactoring in both libraries. +- **Testing Strategy for Phase 6:** + - Manual testing of help commands. + - Automated tests for help output (if supported by CLI framework). +- **Deliverables:** + - Polished CLI with comprehensive help messages. + +### Phase 7: Documentation, Packaging & Release + +- **Goal:** Prepare comprehensive documentation and package the libraries for NPM release. +- **Tasks:** + 1. **Documentation:** + - **Root README.md:** Project overview, installation, quick start for CLI, contribution guidelines. + - **packages/ocif-lib/README.md:** Detailed API documentation (how to use parse, validate, convert), exported types, examples. Consider using TSDoc/TypeDoc to generate HTML API docs. + - **packages/ocif-cli/README.md:** Detailed usage for each command, all options explained, examples. + 2. **Packaging:** + - Finalize package.json files for both packages (versioning \- start with e.g., 0.1.0, author, license, keywords, repository link, files array for included files). + - Add build scripts to transpile TypeScript and prepare packages for publishing. + 3. **Pre-Release Testing:** + - Install packages locally from tarballs (npm pack) to simulate user installation. + - Perform final manual smoke tests. + 4. **Release:** + - Publish ocif-lib and ocif-cli to NPM. + - Tag the release in Git. +- **Testing Strategy for Phase 7:** + - Manual testing of documentation for clarity and accuracy. + - Testing the local installation and basic functionality of the packed NPM packages. +- **Deliverables:** + - Comprehensive documentation. + - Versioned ocif-lib and ocif-cli packages published on NPM.