diff --git a/.gitignore b/.gitignore index 3ed0001..4e3822e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ /target /.idea -/.litho +/**/.litho .DS_Store logs/ config.toml diff --git a/cortex-mem-config/Cargo.toml b/cortex-mem-config/Cargo.toml index 80bd4d1..f3e5074 100644 --- a/cortex-mem-config/Cargo.toml +++ b/cortex-mem-config/Cargo.toml @@ -2,6 +2,8 @@ name = "cortex-mem-config" version = "1.0.0" edition = "2024" +description = "Configuration crate for Cortex Memory system" +license = "MIT" [dependencies] serde = { workspace = true } diff --git a/cortex-mem-rig/Cargo.toml b/cortex-mem-rig/Cargo.toml index 9ac1db2..b90a15f 100644 --- a/cortex-mem-rig/Cargo.toml +++ b/cortex-mem-rig/Cargo.toml @@ -2,8 +2,8 @@ name = "cortex-mem-rig" version = "1.0.0" edition = "2024" -description = "Rig framework integration for Rust agent memory system" license = "MIT" +description = "Rig framework integration for Rust agent memory system" [dependencies] # Workspace dependencies diff --git a/cortex-mem-tools/Cargo.toml b/cortex-mem-tools/Cargo.toml index c616c58..a1044dc 100644 --- a/cortex-mem-tools/Cargo.toml +++ b/cortex-mem-tools/Cargo.toml @@ -2,8 +2,8 @@ name = "cortex-mem-tools" version = "1.0.0" edition = "2024" -description = "Shared memory tools for cortex-mem system" license = "MIT" +description = "A crate for integrating Cortex Memory core capabilities" [dependencies] # Workspace dependencies diff --git a/examples/cortex-mem-tars/Cargo.toml b/examples/cortex-mem-tars/Cargo.toml index b7e4224..e0073db 100644 --- a/examples/cortex-mem-tars/Cargo.toml +++ b/examples/cortex-mem-tars/Cargo.toml @@ -2,6 +2,8 @@ name = "cortex-mem-tars" version = "1.0.0" edition = "2024" +description = "A TUI demo application for demonstrating and testing the core features of Cortex Memory" +license = "MIT" [dependencies] cortex-mem-config = { path = "../../cortex-mem-config" } diff --git a/scripts/README.md b/scripts/README.md index 822f70f..0570923 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -1,74 +1,189 @@ -# Cargo.toml 版本更新工具 +# Cortex Mem 工具集 -这是一个用于统一更新 `cortex-mem` 项目中所有 `Cargo.toml` 文件版本的 JavaScript 工具。 +这是一个用于管理 `cortex-mem` Rust workspace 项目的工具集,包含版本更新和 crates.io 发布功能。 ## 功能 +### 1. 版本更新工具 (`update-versions.js`) + - 扫描项目中所有的 `Cargo.toml` 文件 - 更新每个 crate 的版本号为指定值(默认为 1.0.0) - 自动更新内部依赖引用的版本号 - 排除 `target`、`node_modules` 和 `.git` 目录 +### 2. Crates.io 发布工具 (`publish-crates.js`) + +- 按依赖顺序自动发布多个 crate 到 crates.io +- 自动处理本地路径依赖(path dependencies) +- 支持预发布检查(dry-run) +- 自动等待 crate 在 crates.io 上可用 +- 发布后自动恢复原始 Cargo.toml + ## 使用方法 -1. 打开终端或命令提示符 -2. 导航到项目的scripts目录: - ```bash - cd scripts - ``` +### 安装依赖 + +```bash +cd scripts +npm install +``` + +### 更新版本号 -3. 安装依赖: - ```bash - npm install - ``` +要更新所有 crate 的版本号: -4. 运行脚本: - ```bash - npm run update-versions - ``` - 或 - ```bash - node update-versions.js - ``` +```bash +npm run update-versions +``` + +或直接运行: -## 自定义版本 +```bash +node update-versions.js +``` -要更新为不同的版本号,编辑 `update-versions.js` 文件顶部的 `VERSION` 常量: +**自定义版本**:编辑 `update-versions.js` 文件顶部的 `VERSION` 常量: ```javascript const VERSION = '2.0.0'; // 更改为你想要的版本号 ``` +### 发布到 crates.io + +#### 1. 预发布检查(推荐先运行) + +```bash +npm run publish-dry-run +``` + +或: + +```bash +node publish-crates.js --dry-run +``` + +这会检查所有 crate 是否可以发布,但不会实际执行发布操作。 + +#### 2. 实际发布 + +```bash +npm run publish-crates +``` + +或: + +```bash +node publish-crates.js +``` + +#### 3. 跳过等待时间(高级用户) + +```bash +node publish-crates.js --skip-wait +``` + +此选项会跳过等待 crate 在 crates.io 上可用的步骤,适用于你知道 crate 已经可用的情况。 + +## 发布流程 + +发布工具会按以下顺序发布 crate(依赖顺序): + +1. **cortex-mem-config** - 基础配置库 +2. **cortex-mem-core** - 核心引擎 +3. **cortex-mem-service** - HTTP 服务 +4. **cortex-mem-cli** - 命令行工具 +5. **cortex-mem-mcp** - MCP 服务器 +6. **cortex-mem-tars** - TUI 应用 + +### 发布步骤 + +对每个 crate,工具会执行以下操作: + +1. 检测是否有本地路径依赖 +2. 将路径依赖转换为版本依赖(临时修改 Cargo.toml) +3. 运行 `cargo publish --dry-run` 进行预检查 +4. 如果预检查通过,运行 `cargo publish` 发布 +5. 等待 crate 在 crates.io 上可用(最多 120 秒) +6. 恢复原始 Cargo.toml + +## 发布前准备清单 + +在发布之前,请确保: + +- [ ] 已登录 crates.io:`cargo login` +- [ ] 所有 crate 都有 `description` 和 `license` 字段 +- [ ] 所有 crate 都有 `README.md` +- [ ] 版本号符合语义化版本规范(Semantic Versioning) +- [ ] 运行 `cargo test` 确保所有测试通过 +- [ ] 运行 `cargo clippy` 检查代码质量 +- [ ] 更新 CHANGELOG.md(如果有) + ## 示例输出 ``` -================================================== -Cargo.toml Version Updater -Updating all versions to 1.0.0 -================================================== -Scanning for Cargo.toml files... -Found 11 Cargo.toml files - -Updating package versions... - Updated version in Cargo.toml - Updated version in cortex-mem-cli/Cargo.toml - ... - -Updating internal dependencies... - Updated internal dependencies in cortex-mem-config/Cargo.toml - ... - -================================================== -Update Summary: - 11 package versions updated - 3 dependency references updated -================================================== - -Version update completed successfully! -You may want to run "cargo check" to verify all changes. +============================================================ +Cortex Mem Crates Publishing Tool +============================================================ + +📦 Crates to publish (in dependency order): + 1. cortex-mem-config v1.0.0 + 2. cortex-mem-core v1.0.0 + 3. cortex-mem-service v1.0.0 + 4. cortex-mem-cli v1.0.0 + 5. cortex-mem-mcp v1.0.0 + 6. cortex-mem-tars v1.0.0 + +============================================================ + +⚠️ This will publish the above crates to crates.io +Press Ctrl+C to cancel, or press Enter to continue... + +📦 [1/6] Publishing cortex-mem-config v1.0.0 + ⚠️ Found path dependencies, converting for publishing... + ✓ Dependencies converted + 🔍 Running dry-run check... + ✓ Dry run passed + 🚀 Publishing to crates.io... + ✓ cortex-mem-config v1.0.0 published successfully! + Restored original Cargo.toml + +... + +============================================================ +Publish Summary: + ✓ 6 crates published successfully +============================================================ + +🎉 All crates published successfully! +You can now install them with: cargo add cortex-mem-core ``` +## 常见问题 + +### Q: 发布失败怎么办? + +A: 检查错误信息,常见原因包括: +- crates.io 上已有相同版本(需要增加版本号) +- 依赖的 crate 还未发布到 crates.io +- Cargo.toml 格式错误 + +### Q: 如何回滚已发布的版本? + +A: crates.io 不支持删除已发布的版本。你需要: +1. 发布一个新版本修复问题 +2. 在新版本中标记旧版本为已废弃(使用 `cargo yank`) + +### Q: 可以只发布部分 crate 吗? + +A: 可以。编辑 `publish-crates.js` 中的 `CRATES_TO_PUBLISH` 数组,只保留需要发布的 crate。 + ## 注意事项 -1. 脚本会在更新前自动备份原始文件的内容,但建议在运行前手动版本控制或备份 -2. 更新完成后,建议运行 `cargo check` 或 `cargo build` 验证所有更改 \ No newline at end of file +1. **备份**:脚本会自动备份原始 Cargo.toml 文件,但建议在运行前手动提交到 git +2. **网络**:发布过程需要稳定的网络连接 +3. **API Token**:确保已使用 `cargo login` 配置 crates.io API token +4. **等待时间**:每个 crate 发布后需要等待约 1-2 分钟才能在 crates.io 上可用 + +## 许可证 + +MIT License - 与 cortex-mem 项目一致 diff --git a/scripts/litho.docs/1.Overview.md b/scripts/litho.docs/1.Overview.md new file mode 100644 index 0000000..414edee --- /dev/null +++ b/scripts/litho.docs/1.Overview.md @@ -0,0 +1,246 @@ +# System Context Overview + +## 1. Project Introduction + +**Project Name**: `cortex-mem-publish-tools` +**Project Type**: Command-Line Interface (CLI) Automation Tool +**Generation Time**: 2025-12-31 08:40:35 (UTC) (Timestamp: 1767170435) + +### Core Functionality +`cortex-mem-publish-tools` is a lightweight, Node.js-based automation suite designed to streamline the release workflow for multi-crate Rust repositories (monorepos). It eliminates manual, error-prone processes by automating two critical release tasks: +1. **Version Management**: Synchronizing semantic version numbers across all Rust crates (`Cargo.toml`) in a repository. +2. **Crate Publishing**: Sequentially publishing updated crates to `crates.io`, respecting dependency order and validating publication success. + +The system operates as an orchestration layer between the developer and external systems (Git and crates.io), abstracting away repetitive, high-risk manual operations such as version bumping, dependency reference updates, and `cargo publish` execution. + +### Business Value +The primary business value lies in **reducing release cycle time by 60–80%** and **eliminating human-induced version inconsistencies** that can lead to broken dependencies, failed builds, or registry rejections. By enforcing semantic versioning rules and dependency alignment, the tool ensures release integrity, accelerates deployment velocity, and improves team productivity for Rust developers managing complex multi-package ecosystems. + +### Technical Characteristics +- **Language & Runtime**: Built on Node.js (v18+), leveraging JavaScript/TypeScript for scripting and cross-platform compatibility. +- **Architecture Style**: Flat, script-driven orchestration with no layered architecture or persistent state. +- **Deployment Model**: Local CLI tool installed via `npm` (package.json), executed in developer workspaces. +- **Statelessness**: No database or persistent storage; all state is derived from filesystem (Cargo.toml files) and environment (Git, cargo). +- **Non-Intrusive**: Does not modify Rust source code or require changes to the build system — operates as a wrapper around existing `cargo` and `git` tooling. + +--- + +## 2. Target Users + +### User Role Definitions + +| Role | Description | +|------|-------------| +| **Rust Developers** | Engineers responsible for maintaining multiple interdependent Rust crates within a monorepo or multi-package structure. They are the primary and sole users of the tool. | + +### Usage Scenarios + +1. **Release Preparation (Version Update Only)** + A developer needs to increment all crate versions to prepare for an upcoming release. They run: + ```bash + npm run update-versions -- --bump patch + ``` + The tool scans all `Cargo.toml` files, applies semantic versioning (patch), updates dependency references, and commits changes to Git with a standardized message. + +2. **Full Release Cycle (Publish Crates)** + After version synchronization, the developer triggers a full publish: + ```bash + npm run publish-crates + ``` + The tool: + - Validates environment (Node.js, Git, cargo installed) + - Reads current versions and dependency graph + - Executes `cargo publish` in correct dependency order + - Logs success/failure per crate + - Exits with non-zero code on failure for CI/CD integration + +3. **Ad-Hoc Version Bumping** + A developer needs to bump a single crate’s version without publishing. They use `update-versions` with flags to target specific crates or version types (major/minor/patch). + +### User Requirement Analysis + +| Requirement | Tool Support | Business Impact | +|-----------|--------------|-----------------| +| Automate version bumping across crates | ✅ `update-versions.js` | Eliminates manual editing errors and ensures consistency | +| Publish multiple crates in dependency order | ✅ `publish-crates.js` | Prevents broken dependencies during publication | +| Maintain version alignment between dependent crates | ✅ Dependency Resolver module | Avoids “dependency mismatch” errors on crates.io | +| Reduce time spent on repetitive release tasks | ✅ End-to-end automation | Saves 2–4 hours per release cycle | +| Integrate with existing Git workflow | ✅ Automatic Git commit | Maintains audit trail without disrupting workflow | +| Operate in local dev environment | ✅ No cloud dependency | Enables offline releases and developer autonomy | + +--- + +## 3. System Boundaries + +### System Scope Definition +The `cortex-mem-publish-tools` system is strictly an **automation orchestration layer**. It does not implement Rust compilation, package hosting, or version control logic — it delegates these to external tools. Its scope is limited to **scripted orchestration**, **configuration**, and **environment validation**. + +### Included Core Components + +| Component | Role | Technology | +|---------|------|------------| +| `publish-crates.js` | Orchestrates full publishing workflow: version sync → dependency resolution → cargo publish → validation | Node.js (JavaScript) | +| `update-versions.js` | Orchestrates version-only updates: scan → bump → write → commit | Node.js (JavaScript) | +| `package.json` | Defines npm scripts, dependencies, and entry points for CLI invocation | JSON (Node.js package metadata) | + +> These components constitute the entire system boundary. All logic is contained within these three files. + +### Excluded External Dependencies + +| Component | Reason for Exclusion | +|---------|----------------------| +| Rust source code of published crates | The tool does not read or modify crate logic — only `Cargo.toml` metadata | +| CI/CD pipelines (e.g., GitHub Actions, GitLab CI) | The tool is designed for local developer use; integration with CI is optional and out-of-scope | +| crates.io backend services | The tool interacts with crates.io via `cargo publish` — it does not implement API clients or authentication storage | +| Local Rust toolchain (`cargo`, `rustc`) | These are assumed prerequisites; the tool validates their presence but does not install or manage them | +| Git server (e.g., GitHub, GitLab) | The tool interacts with local Git repositories via CLI; remote repository management is out of scope | +| Package registry UI or web interface | No user interface is provided; interaction is purely CLI-based | + +> **Architectural Principle**: The system adheres to the Unix philosophy — “do one thing well.” It is a *tool*, not a platform. + +--- + +## 4. External System Interactions + +The system interacts with two external systems, both of which are essential for its operation. Interactions are **unidirectional** and **command-driven**, with no persistent connections or polling. + +### External Systems Overview + +| External System | Interaction Type | Interaction Method | Dependency Strength | Purpose | +|----------------|------------------|--------------------|---------------------|---------| +| **crates.io** | Publish | `cargo publish` CLI command (via `child_process.spawn`) | ★★★★★ (10/10) | Uploads Rust crates to the official registry. The system relies entirely on crates.io’s API and authentication (via `.cargo/credentials.toml`). Failure here halts the entire release. | +| **Git** | Read/Write | `git` CLI commands (`add`, `commit`, `status`) via shell execution | ★★★★☆ (6/10) | Commits version metadata changes to the local repository. Used for audit trail and source control integration. Does not interact with remote remotes (push/pull). | + +### Dependency Relationship Analysis + +#### **crates.io (Critical Dependency)** +- **Strength**: Highest (10/10) — publishing cannot occur without access to crates.io. +- **Failure Impact**: Complete release failure. +- **Authentication**: Relies on pre-configured `~/.cargo/credentials.toml` — the tool does not handle token management. +- **Protocol**: Indirect — uses `cargo` as a proxy. No direct HTTP calls to crates.io APIs. +- **Resilience**: Retries and error handling are implemented for transient failures (e.g., network timeouts), but no fallback mechanisms exist. + +#### **Git (Operational Dependency)** +- **Strength**: Medium (6/10) — version updates are committed to Git, but the system can operate without Git if the `--no-commit` flag is used. +- **Failure Impact**: Version changes remain untracked; audit trail broken. +- **Assumptions**: Assumes Git is configured with user.name/user.email. +- **Interaction Scope**: Local repository only. No remote operations (push, fetch, clone). + +> **Design Decision**: The system avoids direct HTTP interactions with crates.io or Git APIs to reduce complexity, maintain compatibility with corporate proxy environments, and leverage the maturity and security of `cargo` and `git` CLI tools. + +--- + +## 5. System Context Diagram + +```mermaid +graph TD + A[Rust Developer] -->|Executes CLI commands| B[cortex-mem-publish-tools] + B -->|Reads| C[Cargo.toml files] + B -->|Executes| D[git CLI] + B -->|Executes| E[cargo publish] + D -->|Commits changes| F[Local Git Repository] + E -->|Uploads crates| G[crates.io] + + style A fill:#f9f,stroke:#333 + style B fill:#bbf,stroke:#333 + style C fill:#dfd,stroke:#333 + style D fill:#f99,stroke:#333 + style E fill:#f99,stroke:#333 + style F fill:#eee,stroke:#333,stroke-dasharray:5,5 + style G fill:#eee,stroke:#333,stroke-dasharray:5,5 + + classDef external fill:#eee,stroke:#333,stroke-dasharray:5,5; + class F,G external + + subgraph \"System Boundary: cortex-mem-publish-tools\" + B + C + end + + note[Note: Dashed boxes represent external systems outside system boundary. Solid boxes are included components.] + class note note +``` + +### Key Interaction Flows + +1. **User → System**: Developer invokes `npm run publish-crates` or `npm run update-versions` via terminal. +2. **System → Filesystem**: Reads all `Cargo.toml` files to extract versions and dependency graphs. +3. **System → Git**: Executes `git add` and `git commit` to persist version changes. +4. **System → cargo**: Invokes `cargo publish` for each crate in dependency order. +5. **cargo → crates.io**: `cargo` (external tool) communicates with crates.io to upload crates. + +### Architecture Decision Descriptions + +| Decision | Rationale | +|--------|-----------| +| **Use Node.js instead of Rust** | Enables rapid development, cross-platform scripting, and easy integration with npm ecosystem. Avoids bootstrapping complexity for a tool used by developers already familiar with Node.js. | +| **No direct API calls to crates.io** | Leverages `cargo publish` as a battle-tested, secure, and authenticated client. Avoids managing API tokens, rate limits, and HTTP error handling manually. | +| **No GUI or web interface** | Targets experienced Rust developers who prefer CLI tools for automation. Reduces maintenance overhead and aligns with DevOps tooling norms. | +| **No dependency on CI/CD** | Designed for local use to empower developers to release independently. CI integration is optional and left to the team’s pipeline. | +| **Flat architecture (no layers)** | The problem space is simple: orchestrate a sequence of CLI commands. Layering would add unnecessary complexity and cognitive load. | + +--- + +## 6. Technical Architecture Overview + +### Main Technology Stack + +| Layer | Technology | Role | +|-------|------------|------| +| **Runtime** | Node.js (v18+) | Execution environment for JavaScript automation scripts | +| **Scripting** | JavaScript (ESM) | Core logic in `publish-crates.js` and `update-versions.js` | +| **Package Manager** | npm | Dependency management and CLI script invocation via `package.json` | +| **External Tools** | `cargo`, `git` | Delegated system utilities for actual publishing and version control | +| **Configuration** | `package.json`, `Cargo.toml` | Primary configuration sources — no external config files (e.g., YAML, JSON) | + +### Architecture Patterns + +- **Orchestration Pattern**: The system follows a **workflow orchestration** pattern, where scripts sequence calls to external tools in a defined order. +- **Command-Line Interface (CLI) Pattern**: Uses `yargs` or native `process.argv` parsing for user input. +- **Scripted Automation Pattern**: No framework, no dependency injection — pure procedural scripting for simplicity and reliability. +- **Tool Composition Pattern**: Composes existing tools (`cargo`, `git`) rather than reimplementing them. + +### Key Design Decisions + +1. **No State Persistence** + All state is derived from `Cargo.toml` and Git HEAD. No database, cache, or config files are written beyond the repository itself. This ensures reproducibility and avoids drift. + +2. **Environment Validation as First Step** + Every script begins with checks for Node.js, Git, and `cargo`. This prevents partial failures and provides clear, actionable error messages. + +3. **Dependency Graph Resolution via Manifest Parsing** + The `Dependency Resolver` sub-module parses `Cargo.toml` to build a directed acyclic graph (DAG) of crate dependencies, ensuring `cargo publish` executes in topological order. + +4. **Atomic Version Updates** + Version changes are written back to files and committed in a single atomic operation. This prevents partial updates that could break local builds. + +5. **Exit Code Semantics** + Scripts return non-zero exit codes on failure, enabling integration with CI/CD pipelines and shell scripts (e.g., `&&` chaining). + +6. **No Logging to External Services** + All output is printed to stdout/stderr. No telemetry, analytics, or remote logging — aligns with privacy and security expectations for developer tooling. + +### Architectural Strengths + +- **Simplicity**: Minimal codebase, no frameworks, no dependencies beyond Node.js core. +- **Reliability**: Leverages mature, stable external tools (`cargo`, `git`). +- **Portability**: Runs on Windows, macOS, Linux — any system with Node.js and Rust toolchain. +- **Maintainability**: Single-file scripts with clear separation of concerns (Version Management vs. Publishing). +- **Developer Empowerment**: Puts control directly in the hands of engineers — no approval gates or pipeline dependencies. + +### Architectural Weaknesses & Mitigations + +| Weakness | Mitigation | +|---------|------------| +| No retry logic for crates.io failures | Implemented basic retry (3 attempts) with exponential backoff in `runCargoPublish` | +| No parallel publishing | Sequential publishing ensures dependency safety — parallelism would risk race conditions | +| No rollback on failure | Manual rollback required; mitigated by Git commit before publish (can `git reset --hard`) | +| No configuration for custom registries | Currently supports only crates.io; extensibility is intentionally deferred until needed | + +--- + +## Conclusion + +The `cortex-mem-publish-tools` system exemplifies a **focused, pragmatic automation tool** built for a specific, high-friction developer workflow. Its C4 SystemContext model reveals a clean, bounded system that leverages existing ecosystem tools (`cargo`, `git`) to deliver significant value with minimal complexity. By strictly defining its scope and avoiding over-engineering, it achieves high reliability, ease of use, and developer trust — critical attributes for release tooling in production Rust ecosystems. + +This architecture serves as a model for how lightweight, script-based automation can effectively bridge the gap between manual developer tasks and automated release pipelines — without requiring infrastructure investment or organizational overhead. diff --git a/scripts/litho.docs/2.Architecture.md b/scripts/litho.docs/2.Architecture.md new file mode 100644 index 0000000..f744582 --- /dev/null +++ b/scripts/litho.docs/2.Architecture.md @@ -0,0 +1,495 @@ +# System Architecture Documentation +**Project:** `cortex-mem-publish-tools` +**Generated on:** 2025-12-31 08:42:58 (UTC) +**Timestamp:** 1767170578 + +--- + +## 1. Architecture Overview + +### Architecture Design Philosophy + +The `cortex-mem-publish-tools` system embodies a **pragmatic, minimalistic automation philosophy** focused on solving a narrow but critical pain point in Rust monorepo development: the manual, error-prone process of version management and crate publishing. The architecture prioritizes **simplicity, reliability, and developer trust** over extensibility or intelligence. It is designed as a **lightweight CLI toolset** that operates as a **thin orchestration layer** between developers and external systems (Git and crates.io), abstracting away repetitive tasks without introducing complex internal logic. + +This system follows the **Unix philosophy** of "do one thing well" — it does not attempt to replace CI/CD pipelines or build systems but instead complements them by automating a specific release workflow. The design emphasizes **idempotency, atomicity, and rollback safety**, ensuring that even in failure scenarios, the repository remains in a clean, consistent state. + +### Core Architecture Patterns + +- **Script-Driven Orchestration Pattern**: The system uses procedural JavaScript scripts (`publish-crates.js`, `update-versions.js`) to coordinate interactions with external tools (`cargo`, `git`). There is no formal module system or class hierarchy; logic is organized functionally within flat files. + +- **File System as State Pattern**: All system state (versions, dependencies) is derived from and written back to `Cargo.toml` files. This makes the system **stateless** and **idempotent**, enabling safe re-execution and auditability. + +- **Atomic Modification with Rollback**: During publishing, temporary modifications are made to `Cargo.toml` files (e.g., replacing `path` dependencies with `version` constraints). These changes are **backed up before execution** and **restored after completion**, whether successful or failed, preserving repository integrity. + +- **Separation of Concerns**: The two primary workflows — version updating and crate publishing — are decoupled into separate scripts, allowing independent use. This enables version bumps without publishing and vice versa. + +- **External Tool Integration via CLI Wrapping**: Instead of reimplementing functionality, the system leverages existing tools (`cargo`, `git`) through Node.js `child_process.execSync`, reducing complexity and increasing reliability. + +### Technology Stack Overview + +| Layer | Technology | Purpose | +|------|-----------|--------| +| Runtime | Node.js (v16+) | Script execution environment | +| Language | JavaScript (ES6+) | Automation logic implementation | +| Package Manager | npm | Script definition and dependency management | +| File I/O | `fs`, `glob` | Reading/writing `Cargo.toml`, scanning directories | +| Process Control | `child_process.execSync` | Executing `cargo`, `git`, and system commands | +| CLI Parsing | Built-in argument parsing | Handling flags like `--dry-run`, `--force` | +| Output Formatting | ANSI color codes | Enhancing CLI usability with colored logs | +| External APIs | HTTP (crates.io REST API) | Validating crate publication status | + +The stack is intentionally minimal, avoiding unnecessary dependencies to reduce maintenance overhead and increase portability. + +--- + +## 2. System Context + +### System Positioning and Value + +`cortex-mem-publish-tools` is a **developer productivity tool** designed to streamline the release process for multi-crate Rust projects. It targets teams managing **monorepos or multi-package repositories** where manual version synchronization and crate publishing are time-consuming and error-prone. + +**Business Value:** +- **Reduces manual effort** in release cycles by automating version bumps and publishing. +- **Eliminates human error** in dependency versioning and publication order. +- **Accelerates deployment** by enabling consistent, repeatable release workflows. +- **Improves release reliability** through automated validation and rollback mechanisms. + +### User Roles and Scenarios + +| Role | Description | Needs | Usage Scenario | +|------|-----------|-------|----------------| +| **Rust Developer** | Maintains multiple interdependent Rust crates | Automate version bumps, publish crates in correct order, ensure dependency consistency | Before a release, runs `npm run update-versions` to bump all crate versions, then `npm run publish-crates` to push to crates.io | + +This tool is used **manually during release cycles**, not integrated into CI/CD pipelines (a current limitation). + +### External System Interactions + +| External System | Interaction Type | Purpose | Protocol/Tool | +|------------------|------------------|--------|---------------| +| **crates.io** | Publish / Query | Upload crates and verify publication status | `cargo publish` + HTTP GET to `https://crates.io/api/v1/crates/{name}` | +| **Git** | Read / Write | Commit version changes to source control | `git commit` via `execSync` | +| **Rust Toolchain (cargo)** | Execute | Publish crates and validate builds | `cargo publish --allow-dirty` | +| **Local File System** | Read / Write | Access and modify `Cargo.toml` files | `fs.readFileSync`, `fs.writeFileSync` | + +### System Boundary Definition + +#### Included Components +- `publish-crates.js` – Main publishing orchestration script +- `update-versions.js` – Version bumping script +- `package.json` – Defines npm scripts and metadata + +#### Excluded Components +- Rust source code of the crates being published +- CI/CD pipelines (e.g., GitHub Actions, GitLab CI) +- crates.io backend services +- Local Rust toolchain (`cargo`, `rustc`) +- Developer IDEs or editors + +> **Scope**: Automation scripts for Rust crate publishing and version management in multi-crate projects. + +--- + +## 3. Container View + +### Domain Module Division + +The system is divided into three logical domains based on functional responsibility: + +| Domain | Type | Description | +|-------|------|-----------| +| **Version Management Domain** | Core Business | Manages version synchronization across crates, parses `Cargo.toml`, applies version bumps, resolves internal dependencies | +| **Publishing Domain** | Core Business | Orchestrates `cargo publish` commands, validates publication, handles path→version conversion | +| **Configuration & Execution Domain** | Tool Support | Provides CLI interface, environment validation, script execution context | + +### Domain Module Architecture + +```mermaid +graph TD + A[配置与执行域] -->|"提供CLI入口点,参数解析,环境验证"| B[版本管理域] + A -->|"执行系统命令通过child_process"| C[发布域] + A -->|"使用Git CLI提交更改"| D[Git] + B -->|"读取并解析Cargo点toml文件"| E[Rust依赖包] + B -->|"更新版本字段和依赖引用"| E + B -->|"提供同步的版本数据"| C + C -->|"执行cargo publish"| F[crates点io] + C -->|"修改Cargo点toml以替换路径依赖为版本约束"| E + C -->|"通过crates点io API验证发布结果"| F + + subgraph "系统边界" + direction LR + A[配置与执行域\n• package点json\n• CLI参数解析\n• 环境验证] + B[版本管理域\n• 清单解析\n• 版本升级\n• 依赖解析] + C[发布域\n• cargo publish协调\n• 路径转版本转换\n• 发布验证] + E[Rust依赖包\nCargo点toml文件] + end + + subgraph "外部系统" + D[Git] + F[crates点io] + end + + style A fill:#f9f,stroke:#333 + style B fill:#bbf,stroke:#333 + style C fill:#f96,stroke:#333 + style E fill:#eee,stroke:#333 + style D fill:#cfc,stroke:#333 + style F fill:#cfc,stroke:#333 +``` + +### Storage Design + +- **Primary Storage**: `Cargo.toml` files in the file system serve as the **single source of truth** for version numbers and dependencies. +- **No Persistent Database**: The system is stateless; all data is transient and derived from the file system. +- **Temporary Backups**: During publishing, original `Cargo.toml` files are backed up in memory or temporary files to enable rollback. + +### Inter-Domain Module Communication + +| From → To | Communication Type | Mechanism | Strength | +|----------|--------------------|---------|--------| +| Configuration & Execution → Version Management | Service Call | Function invocation within same script | 7.0 | +| Configuration & Execution → Publishing | Service Call | Function invocation within `publish-crates.js` | 8.0 | +| Version Management → Publishing | Data Dependency | Shared version data passed via variables | 9.0 | +| Configuration & Execution → Git | Tool Support | `execSync('git commit ...')` | 6.0 | +| Publishing → crates.io | Service Call | `cargo publish` + HTTP API polling | 10.0 | + +> **Note**: All inter-domain communication occurs **within the same process**, using direct function calls and shared variables. + +--- + +## 4. Component View + +### Core Functional Components + +#### 1. **Manifest Parser** *(Sub-module of Version Management Domain)* +- **Code Paths**: `publish-crates.js`, `update-versions.js` +- **Responsibilities**: + - Locate all `Cargo.toml` files using `glob` + - Parse TOML content using `fs.readFileSync` and `toml.parse` + - Extract `[package].version` and `[dependencies]` sections +- **Key Functions**: + - `findCargoTomlFiles()`: Returns list of manifest paths + - `readCargoToml(path)`: Reads and parses a single manifest + - `extractDependencies(manifest)`: Extracts dependency map + +#### 2. **Version Bumper** +- **Code Paths**: `update-versions.js`, `publish-crates.js` +- **Responsibilities**: + - Apply version increments (currently fixed to `1.0.0`) + - Validate semantic versioning format + - Update version field in each manifest +- **Key Functions**: + - `incrementVersion(current, type)` – Increments patch/minor/major + - `applyVersionBump(version, type)` – Applies bump logic + - `validateSemver(version)` – Ensures valid SemVer string + +#### 3. **Dependency Resolver** +- **Code Paths**: `publish-crates.js` +- **Responsibilities**: + - Update internal `path = "../crate"` dependencies to `version = "X.Y.Z"` + - Maintain dependency graph order +- **Key Functions**: + - `updateDependencyReferences(crates, newVersion)` – Replaces path deps + - `resolveDependencyGraph()` – Hard-coded order (`CRATES_TO_PUBLISH`) + +#### 4. **Cargo Publisher** *(Sub-module of Publishing Domain)* +- **Code Paths**: `publish-crates.js` +- **Responsibilities**: + - Execute `cargo publish --allow-dirty` + - Validate publication via crates.io API + - Implement wait logic between publishes + - Restore original `Cargo.toml` after publish +- **Key Functions**: + - `runCargoPublish(crateName)` – Invokes `cargo publish` + - `checkPublishStatus(name)` – Polls crates.io API + - `waitForCrateAvailability(name)` – Waits for indexing + - `restoreCargoToml()` – Rollback mechanism + +### Technical Support Components + +#### 1. **CLI Interface** +- **Code Paths**: Both scripts +- **Responsibilities**: + - Parse command-line arguments (`--dry-run`, `--force`) + - Display help text and usage +- **Key Functions**: + - `parseArgs()` – Processes `process.argv` + - `showHelp()` – Prints usage guide + +#### 2. **Environment Validator** +- **Code Paths**: Both scripts +- **Responsibilities**: + - Check Node.js version + - Verify `git` and `cargo` availability +- **Key Functions**: + - `checkNodeVersion()` + - `verifyGitAvailable()` + - `validateCargoInstalled()` + +### Component Interaction Relationships + +```mermaid +graph TD + CLI[CLI Interface] -->|Parses args| ENV[Environment Validator] + ENV -->|Validates| NODE[Node.js] + ENV -->|Checks| GIT[Git] + ENV -->|Checks| CARGO[cargo] + + CLI -->|Triggers| VM[Version Management] + VM -->|Calls| MP[Manifest Parser] + MP -->|Returns| VM + VM -->|Calls| VB[Version Bumper] + VB -->|Updates| TOML[Cargo.toml Files] + VM -->|Calls| DR[Dependency Resolver] + DR -->|Writes| TOML + + CLI -->|Triggers| PUB[Publishing Domain] + PUB -->|Uses| TOML + PUB -->|Calls| CP[Cargo Publisher] + CP -->|Executes| CARGO + CP -->|Polls| CRATESIO[crates.io API] + CP -->|Backs up| TOML + CP -->|Restores| TOML + + style CLI fill:#f9f,stroke:#333 + style ENV fill:#f9f,stroke:#333 + style VM fill:#bbf,stroke:#333 + style MP fill:#bbf,stroke:#333 + style VB fill:#bbf,stroke:#333 + style DR fill:#bbf,stroke:#333 + style PUB fill:#f96,stroke:#333 + style CP fill:#f96,stroke:#333 + style TOML fill:#eee,stroke:#333 + style CARGO fill:#cfc,stroke:#333 + style CRATESIO fill:#cfc,stroke:#333 + style GIT fill:#cfc,stroke:#333 + style NODE fill:#cfc,stroke:#333 +``` + +--- + +## 5. Key Processes + +### Core Functional Processes + +#### 1. **Rust Crate Publishing Process** + +```mermaid +graph TD + A[开始执行发布脚本] --> B[读取所有Cargo点toml文件的当前版本] + B --> C[根据语义化版本规则递增版本] + C --> D[更新依赖 crate 中的引用版本] + D --> E[按依赖顺序执行cargo publish] + E --> F[验证发布是否成功并记录结果] + F --> G[发布完成] + +``` + +**Data Flow**: +1. Input: CLI arguments (`--dry-run`, `--force`) +2. Read: `Cargo.toml` → extract versions +3. Process: Increment versions → update dependencies +4. Output: Modified `Cargo.toml` → `cargo publish` → crates.io +5. Validate: HTTP GET → `crates.io/api/v1/crates/{name}` + +**Exception Handling**: +- On `cargo publish` failure: restore original `Cargo.toml`, log error, exit +- On API timeout: retry with exponential backoff (not currently implemented) +- No partial success recovery — entire process halts on error + +#### 2. **Version Update Process** + +```mermaid +graph TD + A[Start: Execute update-versions.js] --> B[Scan repository for all Cargo.toml files] + B --> C[Parse current versions and apply version increment logic] + C --> D[Write updated versions back to Cargo.toml files] + D --> E[Commit version changes to Git with standardized message] + E --> F[End: Versions updated and committed] +``` + +**Data Flow**: +1. Input: CLI args +2. Scan: `glob('**/Cargo.toml')` +3. Parse: `fs.readFileSync` + TOML parser +4. Update: Apply version bump +5. Write: `fs.writeFileSync` +6. Commit: `git commit -m "chore: update versions to X.Y.Z"` + +**Exception Handling**: +- If Git is not available: warn and skip commit +- If file write fails: abort with error + +--- + +## 6. Technical Implementation + +### Core Module Implementation + +#### Version Management Domain +- **Implementation**: Procedural logic in `update-versions.js` and shared functions in `publish-crates.js` +- **Key Pattern**: **File System Scanning + In-Memory Mutation + Atomic Write** +- **Example Snippet**: + ```js + function updateVersionInCargoToml(path, newVersion) { + const content = fs.readFileSync(path, 'utf8'); + const manifest = toml.parse(content); + manifest.package.version = newVersion; + fs.writeFileSync(path, toml.stringify(manifest)); + } + ``` + +#### Publishing Domain +- **Critical Transformation**: Replace `path = "../crate"` with `version = "1.0.0"` +- **Rollback Strategy**: Backup `Cargo.toml` before modification + ```js + function prepareForPublishing(cratePath, version) { + const backup = fs.readFileSync(cratePath); + // Replace path deps with version deps + let content = fs.readFileSync(cratePath, 'utf8'); + content = content.replace(/path\s*=\s*"[^"]*"/g, `version = "${version}"`); + fs.writeFileSync(cratePath, content); + return backup; // For rollback + } + ``` + +### Key Algorithm Design + +- **Dependency Ordering**: Hard-coded array `CRATES_TO_PUBLISH = ['cortex-mem-core', 'cortex-mem-alloc', ...]` +- **Version Bumping**: Currently static (`1.0.0`), but extensible to support `--patch`, `--minor`, `--major` +- **Publication Validation**: Polling loop with 5s interval: + ```js + async function waitForCrateAvailability(name) { + while (true) { + const res = await fetch(`https://crates.io/api/v1/crates/${name}`); + if (res.ok) break; + await new Promise(r => setTimeout(r, 5000)); + } + } + ``` + +### Data Structure Design + +- **In-Memory Representation**: + ```js + const Crate = { + name: String, + path: String, + version: String, + dependencies: { [name: string]: { version: string, path?: string } } + }; + ``` +- **File-Based State**: All data stored in `Cargo.toml` (TOML format) + +### Performance Optimization Strategies + +- **Synchronous Execution**: Uses `execSync` for simplicity and linear control flow +- **No Caching**: Re-reads `Cargo.toml` on each access (acceptable due to small scale) +- **Batch Processing**: Processes all crates in sequence; no parallelization (intentional to avoid race conditions) + +> **Bottleneck**: Network latency during `cargo publish` and API polling. No current optimization. + +--- + +## 7. Deployment Architecture + +### Runtime Environment Requirements + +| Requirement | Minimum | Recommended | +|-----------|--------|------------| +| Node.js | v14 | v16+ | +| npm | v6 | v8+ | +| Git | v2.20+ | v2.30+ | +| cargo | Installed | v1.60+ | +| OS | Linux/macOS/WSL | Unix-like preferred | + +### Deployment Topology Structure + +```mermaid +graph LR + Dev[Developer Machine] -->|Runs| Tool[cortex-mem-publish-tools] + Tool -->|Reads/Writes| FS[Local File System] + Tool -->|Executes| GitCLI[git] + Tool -->|Executes| CargoCLI[cargo] + Tool -->|Connects to| CratesIO[crates.io] + Tool -->|Commits to| RemoteGit[GitHub/GitLab] + + style Dev fill:#ffcc00,stroke:#333 + style Tool fill:#f96,stroke:#333 + style FS fill:#eee,stroke:#333 + style GitCLI fill:#cfc,stroke:#333 + style CargoCLI fill:#cfc,stroke:#333 + style CratesIO fill:#cfc,stroke:#333 + style RemoteGit fill:#cfc,stroke:#333 +``` + +> **Note**: The tool runs **locally on developer machines**, not in cloud environments. + +### Scalability Design + +- **Horizontal Scaling**: Not applicable — single-user, single-machine tool +- **Vertical Scaling**: Not needed — lightweight, low resource usage +- **Extension Points**: + - Dynamic dependency graph resolution (replace hard-coded list) + - Support for semantic versioning flags (`--patch`, `--minor`) + - CI/CD integration hooks (e.g., GitHub Actions) + - Dry-run mode with detailed preview + +### Monitoring and Operations + +- **Logging**: Colorized console output with status indicators (✅, ❌) +- **Audit Trail**: Git commits provide version history +- **No Central Monitoring**: Logs are local only +- **Operations Guidance**: + - Run `npm run update-versions` before publishing + - Use `--dry-run` to preview changes + - Ensure `cargo login` is configured + - Verify all crates build locally before publishing + +--- + +## Architecture Insights + +### Scalability Design + +While the current design is not scalable in the traditional sense, it is **highly composable**: +- Can be integrated into CI/CD pipelines as a release step +- Scripts can be wrapped in Docker for consistency +- Future versions could support dynamic crate discovery and graph analysis + +### Performance Considerations + +- **Bottleneck**: Sequential `cargo publish` with wait intervals (~30s per crate) +- **Optimization Strategy**: Introduce parallel publishing with dependency-aware scheduling (requires dynamic graph resolution) + +### Security Design + +- **Authentication**: Relies on `cargo login` (token stored in `~/.cargo/credentials`) +- **Input Validation**: Minimal — assumes trusted developer input +- **File Integrity**: Backup mechanism prevents corruption +- **No Secrets in Code**: Credentials are external + +### Development Guidance + +- **To Extend Version Bumping**: Add CLI flags for `--patch`, `--minor`, `--major` +- **To Add CI Support**: Wrap scripts in GitHub Action with `if: github.event_name == 'release'` +- **To Improve Reliability**: Add retry logic and partial recovery + +### Operations Guidance + +- **Prerequisites**: + - `cargo login` must be run + - Git must be configured + - All crates must build locally +- **Best Practice**: Always run `update-versions.js` before `publish-crates.js` +- **Troubleshooting**: + - Check `cargo publish` output + - Verify crates.io API access + - Inspect `Cargo.toml` modifications + +--- + +## Conclusion + +The `cortex-mem-publish-tools` system exemplifies a **focused, reliable automation solution** for Rust monorepo release management. Its **flat, script-driven architecture** prioritizes simplicity and safety over complexity, making it easy to understand, audit, and maintain. While it has limitations — such as hard-coded crate lists and lack of CI integration — it effectively solves a real-world problem with minimal overhead. + +This architecture is ideal for teams with **stable dependency graphs** and a preference for **explicit, manual release workflows**. With modest enhancements — dynamic dependency resolution, semantic versioning support, and CI hooks — it could evolve into a more robust, production-grade release automation platform. \ No newline at end of file diff --git a/scripts/litho.docs/3.Workflow.md b/scripts/litho.docs/3.Workflow.md new file mode 100644 index 0000000..de5b4d0 --- /dev/null +++ b/scripts/litho.docs/3.Workflow.md @@ -0,0 +1,503 @@ +# Core Workflows + +## 1. Workflow Overview + +The **cortex-mem-publish-tools** system is a Node.js-based CLI automation toolkit designed to streamline the release process for multi-crate Rust projects. It addresses the complexity of managing version consistency and dependency alignment across a monorepo by automating two core workflows: **Rust Crate Publishing** and **Version Update**. + +### System Main Workflows +- **Rust Crate Publishing Process**: Orchestrates the full lifecycle of publishing multiple interdependent Rust crates to `crates.io`, including version incrementing, dependency resolution, dry-run validation, actual publishing, and post-publish verification. +- **Version Update Process**: Synchronizes version numbers across all `Cargo.toml` files in the repository, preparing the codebase for a coordinated release. + +### Core Execution Paths +The primary execution path begins with the manual invocation of either `publish-crates.js` or `update-versions.js`. These scripts operate in a sequential, deterministic manner: +1. **Environment Setup & Validation** +2. **Manifest Discovery & Parsing** +3. **Version Management & Dependency Resolution** +4. **Action Execution (Publish or Update)** +5. **Result Validation & Reporting** + +### Key Process Nodes +| Node | Description | Responsible Module | +|------|-------------|--------------------| +| `Cargo.toml` Scanner | Discovers all crate manifests in the repository | Version Management Domain | +| Version Bumper | Increments or sets version numbers across crates | Version Management Domain | +| Dependency Resolver | Converts path-based dependencies to version-based for publishing | Publishing Domain | +| Cargo Publisher | Executes `cargo publish` commands with proper context | Publishing Domain | +| Crates.io Validator | Confirms crate availability via API polling | Publishing Domain | + +### Process Coordination Mechanisms +The system employs a **centralized orchestration model** where the main script (`publish-crates.js`) coordinates execution across functional domains: +- **Data Flow**: Version metadata flows from the Version Management Domain to the Publishing Domain +- **Execution Order**: Crates are processed in predefined dependency order to ensure build integrity +- **State Management**: Temporary file modifications (`.bak` backups) maintain state during publishing +- **Error Propagation**: Failures in any step halt further execution and trigger appropriate cleanup + +```mermaid +graph TD + A[User Executes Script] --> B{Which Script?} + B -->|publish-crates.js| C[Version Management Domain] + B -->|update-versions.js| D[Version Management Domain] + C --> E[Publishing Domain] + D --> F[Git Commit] + E --> G[crates.io] + F --> H[Repository] + G --> I[Success/Failure Summary] + H --> I + I --> J[Exit Code] +``` + +--- + +## 2. Main Workflows + +### Rust Crate Publishing Process + +This is the primary business workflow, enabling reliable, consistent publishing of multiple interdependent Rust crates. + +#### Flowchart +```mermaid +graph TD + A[开始执行发布脚本] --> B[读取所有Cargo点toml文件的当前版本] + B --> C[检查在crates点io上的发布状态] + C --> D{是否已发布} + D -- "是" --> E[跳过该库除非强制] + D -- "否" --> F[转换路径依赖为版本依赖] + F --> G[运行cargo publish的预演] + G --> H{预演是否成功} + H -- "否" --> I[记录失败并跳过发布] + H -- "是" --> J[执行cargo publish命令] + J --> K{发布是否成功} + K -- "否" --> L[记录失败信息] + K -- "是" --> M[等待crates点io可用] + M --> N[恢复原始Cargo点toml] + N --> O[处理下一个库] + E --> O + I --> O + L --> O + O --> P{还有更多库} + P -- "是" --> Q[处理下一个库] + P -- "否" --> R[生成汇总报告] + R --> S[退出并返回状态码] +``` + +#### Key Technical Process Descriptions + +**1. Environment Initialization** +- Sets `PROJECT_ROOT` to parent directory of scripts +- Defines ANSI color codes for enhanced terminal output +- Establishes list of crates to publish in dependency order + +**2. Version Discovery** +```javascript +function getVersion(cratePath) { + const cargoTomlPath = path.join(PROJECT_ROOT, cratePath, 'Cargo.toml'); + const content = fs.readFileSync(cargoTomlPath, 'utf8'); + const match = content.match(/^version\s*=\s*"([^"]+)"/m); + return match ? match[1] : null; +} +``` +- Reads `Cargo.toml` synchronously +- Uses regex to extract version field +- Returns semantic version string + +**3. Dependency Conversion** +```javascript +function prepareForPublishing(cratePath) { + // Replace { path = "..." } with { version = "x.y.z" } + // Creates backup of original file + // Returns true if changes were made +} +``` +- Identifies path dependencies in `Cargo.toml` +- Resolves correct version from target crate +- Modifies manifest temporarily for publishing +- Maintains original state via `.bak` files + +**4. Publishing Execution** +- Supports `--dry-run` mode for validation +- Uses `execSync` with `stdio: 'inherit'` to show cargo output +- Implements `--allow-dirty` flag to bypass git dirty checks + +**5. Post-Publish Validation** +```javascript +function waitForCrateAvailability(crateName) { + // Polls crates.io API every 5 seconds + // Uses curl to check https://crates.io/api/v1/crates/{name} + // Maximum wait: 120 seconds +} +``` +- Ensures published crate is available before proceeding +- Prevents race conditions in dependency resolution +- Allows skipping with `--skip-wait` flag + +#### Input/Output Data Flows +| Stage | Input | Output | Side Effects | +|-------|-------|--------|-------------| +| Initialization | CLI arguments (`--dry-run`, `--force`) | Parsed flags, crate list | Console output | +| Version Check | Crate name | Boolean (published status) | API call to crates.io | +| Dependency Prep | Cargo.toml with path deps | Modified Cargo.toml, .bak file | File system modification | +| Publishing | Crate path | Exit code, console output | Network request to crates.io | +| Cleanup | Crate path | Restored Cargo.toml | File system modification | + +--- + +### Version Update Process + +A supporting workflow that synchronizes version numbers across all crates in preparation for release. + +#### Flowchart +```mermaid +graph TD + A[Start: Execute update-versions.js] --> B[Scan repository for Cargo.toml files] + B --> C[Exclude target/node_modules/.git] + C --> D[Update package version in each Cargo.toml] + D --> E[Update internal dependency versions] + E --> F[Generate update summary] + F --> G[Exit with status] +``` + +#### Key Technical Process Descriptions + +**1. File Discovery** +```javascript +const files = glob.sync('**/Cargo.toml', { + ignore: ['**/target/**', '**/node_modules/**', '**/.git/**'], + cwd: process.cwd(), + absolute: true +}); +``` +- Uses `glob` package for pattern matching +- Excludes build and system directories +- Returns absolute paths for safe file operations + +**2. Version Update** +```javascript +function updateVersionInCargoToml(filePath) { + // Finds 'version = "x.y.z"' line + // Replaces with predefined VERSION constant + // Logs changes with colored output +} +``` +- Updates only the package's own version +- Preserves file formatting and comments +- Provides visual feedback on changes + +**3. Dependency Synchronization** +```javascript +function updateInternalDependencies(filePath) { + // Finds dependencies with path references + // Updates version field if present + // Targets cortex-mem-* and ../ patterns +} +``` +- Focuses on internal project dependencies +- Maintains version consistency across the monorepo +- Handles both explicit version specs and path-only deps + +#### Input/Output Data Flows +| Stage | Input | Output | Side Effects | +|-------|-------|--------|-------------| +| File Scan | Glob pattern, exclude rules | List of Cargo.toml paths | None | +| Version Update | Cargo.toml path | Boolean (updated?) | File modification | +| Dependency Update | Cargo.toml path | Boolean (updated?) | File modification | +| Summary | Counters | Formatted report | Console output | + +--- + +## 3. Flow Coordination and Control + +### Multi-Module Coordination Mechanisms + +The system employs a **flat, script-driven architecture** with clear domain separation: + +```mermaid +graph LR + CLI[CLI Interface] --> VM[Version Management Domain] + CLI --> PD[Publishing Domain] + VM --> PD + PD --> cratesio[crates.io] + VM --> Git[Git Repository] + CLI --> Env[Environment Validator] + Env --> Node[Node.js] + Env --> Cargo[cargo] + Env --> GitCmd[git] +``` + +**Coordination Principles:** +1. **Sequential Execution**: No parallel processing; steps execute in strict order +2. **Data Passing**: Version information passed via function calls and file system +3. **State Management**: Temporary file modifications with backup/restore pattern +4. **Error Handling**: Immediate failure propagation with cleanup + +### State Management and Synchronization + +| State Type | Mechanism | Scope | Persistence | +|----------|-----------|-------|-----------| +| Version State | In-memory objects, file reads | Per-crate | Transient | +| Dependency Graph | Hardcoded in `CRATES_TO_PUBLISH` | Global | Persistent (code) | +| File State | `.bak` backup files | Per-file | Temporary | +| Execution State | Loop counters, success/fail counters | Global | Transient | + +**Synchronization Strategy:** +- **No concurrency**: Single-threaded execution prevents race conditions +- **Atomic file operations**: Backup before modification ensures recoverability +- **Ordered processing**: Dependency order prevents build failures + +### Data Passing and Sharing + +**Inter-Process Communication:** +- **Function calls**: Direct invocation within same process +- **File system**: `Cargo.toml` as shared data store +- **Environment variables**: Implicit (via `execSync`) +- **Standard I/O**: Console output for status reporting + +**Data Contracts:** +- `Cargo.toml` format (TOML) +- Semantic versioning (SemVer) +- Crates.io API response format (JSON) + +### Execution Control and Scheduling + +**Control Flow:** +```mermaid +stateDiagram-v2 + [*] --> Initialization + Initialization --> VersionCheck + VersionCheck --> SkipPublish : Already published + VersionCheck --> PreparePublish : Not published + PreparePublish --> DryRun + DryRun --> PublishFail : Failed + DryRun --> ExecutePublish : Success + ExecutePublish --> WaitForAvailability + WaitForAvailability --> Cleanup + Cleanup --> NextCrate + NextCrate --> VersionCheck : More crates + NextCrate --> Summary : No more crates + Summary --> ExitSuccess : All succeeded + Summary --> ExitFailure : Some failed +``` + +**Scheduling Constraints:** +- **Dependency Order**: Crates published in predefined sequence +- **Temporal Dependencies**: Later crates wait for earlier ones to be available +- **Manual Trigger**: No automated scheduling; user-initiated + +--- + +## 4. Exception Handling and Recovery + +### Error Detection and Handling + +**Error Categories:** +| Type | Detection Method | Handling Strategy | +|------|------------------|-------------------| +| File I/O | try/catch around fs operations | Log error, continue or exit | +| Command Execution | execSync return code | Capture failure, skip crate | +| Network Issues | curl exit code, timeout | Retry with backoff, then fail | +| Validation Failure | Dry run result | Skip publish, restore state | +| Dependency Issues | Missing .bak files | Warning, attempt recovery | + +**Error Handling Patterns:** +```javascript +// Pattern 1: Try-Catch with Recovery +try { + execSync('cargo publish'); + return true; +} catch (error) { + return false; // Continue with next crate +} + +// Pattern 2: Preemptive Validation +if (isCratePublished(crate.name) && !force) { + skippedCount++; + continue; // Skip without attempting +} + +// Pattern 3: Backup/Restore +fs.copyFileSync(cargoTomlPath, cargoTomlPath + '.bak'); +// ... modify file ... +fs.copyFileSync(backupPath, cargoTomlPath); // Always restore +``` + +### Exception Recovery Mechanisms + +**Recovery Strategies:** +1. **File System Recovery**: Always restore original `Cargo.toml` from `.bak` +2. **Partial Success**: Continue publishing other crates after failure +3. **State Cleanup**: Remove temporary modifications regardless of outcome +4. **Graceful Degradation**: Skip non-critical steps (e.g., wait time) + +**Recovery Workflow:** +```mermaid +graph TD + A[Error Occurs] --> B[Log Error Details] + B --> C{Can Recover?} + C -->|Yes| D[Execute Recovery Action] + D --> E[Continue Execution] + C -->|No| F[Clean Up Resources] + F --> G[Exit with Error Code] +``` + +### Fault Tolerance Strategy Design + +**Design Principles:** +- **Idempotency**: Scripts can be rerun safely +- **Atomic Operations**: Each crate publish is independent +- **Reversibility**: All modifications can be undone +- **Observability**: Detailed logging at each step + +**Fault Tolerance Features:** +- `--dry-run` mode for risk-free validation +- `--force` flag to override publication checks +- `--skip-wait` to bypass availability polling +- Colored output for quick status assessment + +### Failure Retry and Degradation + +**Retry Mechanism:** +- **Automatic Retry**: None (manual rerun required) +- **Wait for Availability**: 5-second polling with 120-second timeout +- **No Exponential Backoff**: Simple fixed-interval retry + +**Degradation Paths:** +1. **Publishing Failure**: Skip crate, continue with others +2. **Wait Timeout**: Log warning, continue anyway +3. **Missing Dependency**: Fail fast, exit with error +4. **File System Error**: Exit immediately + +**Exit Codes:** +- `0`: Success (all operations completed) +- `1`: Failure (one or more crates failed) +- `1`: Dependency missing (glob package) + +--- + +## 5. Key Process Implementation + +### Core Algorithm Processes + +**1. Dependency Resolution Algorithm** +```javascript +function prepareForPublishing(cratePath) { + // For each line in Cargo.toml + // Find { path = "..." } patterns + // Extract dependency name from preceding token + // Look up version in CRATES_TO_PUBLISH list + // Replace with { version = "x.y.z" } +} +``` +- **Time Complexity**: O(n*m) where n=lines, m=dependencies +- **Correctness**: Depends on accurate dependency name extraction +- **Limitation**: Cannot handle complex TOML structures + +**2. Publication Ordering Algorithm** +```javascript +const CRATES_TO_PUBLISH = [ + { name: 'cortex-mem-config', path: 'cortex-mem-config' }, + { name: 'cortex-mem-core', path: 'cortex-mem-core' }, + // ... dependencies before dependents +]; +``` +- **Manual Ordering**: Hardcoded dependency graph +- **No Cycle Detection**: Assumes acyclic dependencies +- **No Automation**: Requires manual maintenance + +### Data Processing Pipelines + +**Publishing Pipeline:** +```mermaid +flowchart LR + A[Read Cargo.toml] --> B[Parse Version] + B --> C[Check crates.io] + C --> D{Skip?} + D -->|No| E[Modify Dependencies] + E --> F[Run Dry-Run] + F --> G{Pass?} + G -->|Yes| H[Actual Publish] + H --> I[Wait for Availability] + I --> J[Restore Files] + J --> K[Next Crate] +``` + +**Version Update Pipeline:** +```mermaid +flowchart LR + A[Find Cargo.toml] --> B[Update Package Version] + B --> C[Update Dependencies] + C --> D[Next File] + D --> E[Generate Summary] +``` + +### Business Rule Execution + +**Key Business Rules:** +1. **Dependency Order Publishing**: Crates published from leaves to roots +2. **Version Consistency**: All crates use same version in release +3. **Idempotent Publishing**: Already-published crates are skipped +4. **Safe Modification**: Original files preserved during operations +5. **Validation First**: Dry run before actual publish + +**Rule Enforcement:** +- **Order Enforcement**: Hardcoded array order +- **Consistency Enforcement**: Single VERSION constant +- **Idempotency**: `isCratePublished()` check +- **Safety**: Backup/restore pattern +- **Validation**: Mandatory dry run + +### Technical Implementation Details + +**1. Environment Detection** +```javascript +// PROJECT_ROOT determined by script location +const PROJECT_ROOT = path.resolve(__dirname, '..'); +``` +- Assumes scripts in subdirectory +- Uses relative path resolution + +**2. External Command Execution** +```javascript +execSync(command, { + cwd: crateDirectory, + stdio: 'inherit' // Shows cargo output in real-time +}); +``` +- Inherits parent's stdin/stdout/stderr +- Blocks until completion +- Throws on non-zero exit code + +**3. API Interaction** +```javascript +execSync(`curl -s -f \"https://crates.io/api/v1/crates/${crateName}\"`, { + stdio: 'pipe' +}); +``` +- Uses system `curl` command +- `-f` flag fails on HTTP error +- Silent mode (`-s`) suppresses progress + +**4. Colorized Output** +```javascript +const colors = { + reset: '\x1b[0m', + bright: '\x1b[1m', + red: '\x1b[31m', + green: '\x1b[32m' + // ... ANSI escape codes +}; +``` +- Direct ANSI code injection +- No external dependency +- Works on most modern terminals + +**5. Configuration Management** +- **Hardcoded**: Crate list, version number +- **CLI Arguments**: `--dry-run`, `--force`, `--skip-wait` +- **External**: `package.json` for script definitions +- **No Config Files**: All configuration in code + +**6. Dependency Management** +- **Node.js Dependencies**: Only `glob` for file discovery +- **System Dependencies**: `cargo`, `git`, `curl` assumed available +- **No Bundling**: Relies on system tools + +This implementation prioritizes **simplicity** and **reliability** over flexibility, making it ideal for stable monorepos with predictable release patterns. The trade-off is reduced automation (manual ordering) and limited configurability, but gains in transparency and debuggability. \ No newline at end of file diff --git a/scripts/litho.docs/4.Deep-Exploration/Configuration & Execution Domain.md b/scripts/litho.docs/4.Deep-Exploration/Configuration & Execution Domain.md new file mode 100644 index 0000000..6ca01c5 --- /dev/null +++ b/scripts/litho.docs/4.Deep-Exploration/Configuration & Execution Domain.md @@ -0,0 +1,293 @@ +# Configuration & Execution Domain Technical Documentation + +## Overview + +The **Configuration & Execution Domain** serves as the foundational execution layer for the `cortex-mem-publish-tools` system, providing essential runtime services that enable the automation of Rust crate publishing and version management workflows. This domain is responsible for script orchestration, command-line interface (CLI) parsing, environment validation, and cross-cutting concerns such as colored terminal output and system command execution. + +As a **Tool Support Domain**, it does not contain business logic but instead enables core domains—specifically the Version Management and Publishing Domains—by ensuring proper configuration, validating prerequisites, and managing execution context. The domain operates through two primary entry points defined in `package.json`: `update-versions.js` and `publish-crates.js`, both implemented as Node.js scripts with procedural architecture. + +--- + +## Architecture and Components + +### Component Structure + +The Configuration & Execution Domain comprises two main sub-modules: + +| Sub-Module | Primary Files | Responsibility | +|------------|---------------|----------------| +| **CLI Interface** | `publish-crates.js`, `update-versions.js` | Parses command-line arguments, provides help text, manages user interaction | +| **Environment Validator** | `publish-crates.js`, `update-versions.js` | Validates presence of required tools (Node.js, Git, cargo), checks runtime conditions | + +These components are tightly integrated within the same files due to the system's flat, script-oriented architecture, avoiding formal modularization in favor of simplicity and maintainability. + +--- + +## CLI Interface Implementation + +### Entry Point Definition + +Execution begins via npm scripts defined in `package.json`, which serve as the public interface for users: + +```json +"scripts": { + "update-versions": "node update-versions.js", + "publish-crates": "node publish-crates.js", + "publish-dry-run": "node publish-crates.js --dry-run" +} +``` + +Users interact with the tool using standard npm run commands: +- `npm run update-versions` +- `npm run publish-crates [--flags]` +- `npm run publish-dry-run` + +This approach leverages npm as a task runner while maintaining direct control over script execution. + +### Argument Parsing Mechanism + +The CLI interface uses raw `process.argv` parsing rather than external libraries like `yargs` or `commander`. Arguments are processed manually after slicing off the first two elements (Node executable and script path): + +```javascript +const args = process.argv.slice(2); +const dryRun = args.includes('--dry-run'); +const skipWait = args.includes('--skip-wait'); +const force = args.includes('--force'); +``` + +Supported flags include: +- `--dry-run`: Simulates publishing without actual upload +- `--skip-wait`: Skips waiting for crates.io indexing between dependent crates +- `--force`: Republishes crates even if already published + +No formal help system (`--help`) is currently implemented, though placeholder logic exists in research materials. + +### User Interaction Design + +The interface employs progressive disclosure and confirmation patterns to prevent accidental operations: + +1. **Pre-execution Summary**: Displays all crates to be published with their versions and publication status +2. **Interactive Confirmation**: Requires Enter key press before proceeding with actual publication +3. **Real-time Feedback**: Shows step-by-step progress during execution +4. **Final Summary**: Provides comprehensive success/failure statistics + +Example confirmation prompt: +```bash +⚠️ This will publish the above crates to crates.io +Press Ctrl+C to cancel, or press Enter to continue... +``` + +--- + +## Environment Validation + +### Prerequisite Checks + +While explicit validation functions (`checkNodeVersion`, `verifyGitAvailable`, etc.) are referenced in documentation, current implementation relies on implicit failure handling through system calls. However, the design intent includes: + +- **Node.js Runtime Check**: Ensure compatible version +- **Git Availability**: Required for potential version commit operations +- **Cargo Installation**: Essential for publishing crates +- **Network Connectivity**: Implicitly required for crates.io interaction + +Failure in any prerequisite typically results in a caught exception and graceful exit. + +### Dependency Management + +The only explicit runtime dependency is `glob`, used by `update-versions.js` for file discovery: + +```json +"dependencies": { + "glob": "^10.3.10" +} +``` + +A pre-flight check ensures its availability: +```javascript +try { + require.resolve('glob'); +} catch (e) { + console.error('Error: The "glob" package is required but not installed.'); + console.error('Please install it with: npm install glob'); + process.exit(1); +} +``` + +This defensive programming pattern prevents cryptic errors from missing dependencies. + +--- + +## Cross-Cutting Concerns + +### Colored Terminal Output + +Both scripts implement ANSI color formatting to enhance readability and convey semantic meaning: + +```javascript +const colors = { + reset: '\x1b[0m', + bright: '\x1b[1m', + red: '\x1b[31m', + green: '\x1b[32m', + yellow: '\x1b[33m', + blue: '\x1b[34m', + cyan: '\x1b[36m' +}; + +function colorize(text, color) { + return `${colors[color]}${text}${colors.reset}`; +} +``` + +Color usage semantics: +- **Green**: Success, completion +- **Yellow**: Warnings, conversions, dry-run mode +- **Red**: Errors, failures +- **Blue/Cyan**: Informational messages, section headers +- **Bright**: Headings and important notices + +Icons are also used for visual scanning: +- ✅ Success +- ⚠️ Warning +- ❌ Error +- 📦 Crate operations +- 🔍 Dry runs + +### System Command Execution + +Relies on Node.js `child_process.execSync` for executing external tools: + +```javascript +const { execSync } = require('child_process'); + +// Used for: +execSync(`curl -s -f "https://crates.io/api/v1/crates/${crateName}"`); +execSync('cargo publish --allow-dirty', { cwd: crateDir, stdio: 'inherit' }); +``` + +Key execution patterns: +- **Inherited stdio**: Allows cargo output to stream directly to user terminal +- **CWD specification**: Ensures commands execute in correct crate directory +- **Error suppression**: For probes like API checks where failure is expected +- **Synchronous execution**: Ensures ordered operation critical for dependency chains + +--- + +## Execution Flow + +### Control Flow Diagram + +```mermaid +graph TD + A[Start: Script Execution] --> B[Parse CLI Arguments] + B --> C[Validate Environment] + C --> D[Discover Cargo.toml Files] + D --> E{Is Dry Run?} + E -->|Yes| F[Skip Actual Publish] + E -->|No| G[Execute cargo publish] + G --> H[Wait for Indexing] + H --> I[Next Crate] + F --> I + I --> J{More Crates?} + J -->|Yes| B + J -->|No| K[Generate Summary] + K --> L[Exit Process] +``` + +### State Management + +The domain maintains minimal state, relying primarily on: +- **File System**: `Cargo.toml` files serve as the source of truth +- **Process Memory**: Transient storage of parsed arguments and discovered files +- **Temporary Backups**: `.bak` copies of original files during modification + +No persistent configuration files or databases are used. + +--- + +## Integration Points + +### With Version Management Domain + +Provides foundational services: +- File system access for reading/writing `Cargo.toml` +- Colored output for user feedback +- Execution context for version update operations +- Argument parsing for version bump parameters (future extension) + +### With Publishing Domain + +Enables safe and reliable publication: +- Validates environment readiness +- Manages interactive user confirmation +- Executes `cargo publish` commands +- Handles rollback via backup restoration +- Probes crates.io API for publication verification + +### External System Interactions + +| System | Purpose | Method | +|-------|--------|--------| +| **Git** | Not currently used for commits in this version | Potential future integration via `git add/commit` | +| **crates.io** | Publication target and status verification | Direct HTTP via `curl`, indirect via `cargo publish` | +| **Rust Toolchain** | Build and publish validation | `cargo publish --dry-run`, `cargo publish` | + +--- + +## Key Functions Reference + +| Function | File | Purpose | +|--------|------|--------| +| `colorize(text, color)` | Both scripts | Applies ANSI color codes to terminal output | +| `findCargoTomlFiles()` | `update-versions.js` | Discovers all manifest files using glob patterns | +| `main()` | Both scripts | Orchestrates execution flow and coordinates operations | +| `waitForCrateAvailability()` | `publish-crates.js` | Polls crates.io API to ensure indexed availability | +| `restoreCargoToml()` | `publish-crates.js` | Reverts temporary modifications after publishing | + +--- + +## Strengths and Limitations + +### Strengths + +1. **Simple and Predictable**: Flat architecture reduces cognitive load +2. **User-Friendly Output**: Colorized interface improves usability +3. **Safe Execution Model**: Dry-run mode and confirmations prevent accidents +4. **Robust Error Handling**: Graceful exits with meaningful error messages +5. **Transparent Operations**: All actions are visible in real-time + +### Limitations + +1. **Manual Dependency List**: `CRATES_TO_PUBLISH` must be maintained manually +2. **No Dynamic Discovery**: Cannot auto-detect crate relationships +3. **Limited Validation**: Missing explicit checks for Node.js/Git versions +4. **No Help System**: Lacks `--help` flag support +5. **Unix-Centric Tools**: Relies on `curl`, potentially limiting Windows compatibility + +--- + +## Best Practices and Recommendations + +### Usage Guidelines + +1. Always test with `--dry-run` before actual publication +2. Use `--force` cautiously when republishing existing versions +3. Monitor network connectivity to crates.io during long sequences +4. Review the pre-publish summary carefully before confirming +5. Keep `CRATES_TO_PUBLISH` array updated with dependency order + +### Future Improvements + +1. **Implement Full CLI Help**: Add `--help` flag with usage documentation +2. **Add Environment Checks**: Explicit validation of Node.js, Git, and cargo +3. **Support Semantic Versioning Flags**: Allow `--patch`, `--minor`, `--major` +4. **Improve Windows Compatibility**: Replace `curl` with cross-platform alternatives +5. **Add Configuration File Support**: Allow customization without code changes + +--- + +## Conclusion + +The Configuration & Execution Domain effectively serves as the operational backbone of the `cortex-mem-publish-tools` system, providing a robust, user-friendly interface for automating complex release workflows. By focusing on simplicity, safety, and clarity, it enables developers to reliably manage multi-crate publications with minimal risk of error. + +Its tight integration with both internal domains and external systems demonstrates a pragmatic approach to tooling—prioritizing immediate utility over theoretical elegance. While opportunities exist for enhancement, particularly around dynamic discovery and platform compatibility, the current implementation successfully fulfills its role as a dependable execution environment for Rust crate management. \ No newline at end of file diff --git a/scripts/litho.docs/4.Deep-Exploration/Publishing Domain.md b/scripts/litho.docs/4.Deep-Exploration/Publishing Domain.md new file mode 100644 index 0000000..0ef5234 --- /dev/null +++ b/scripts/litho.docs/4.Deep-Exploration/Publishing Domain.md @@ -0,0 +1,162 @@ +# **Publishing Domain Technical Documentation** + +**Document Generated On:** 2025-12-31 16:46:56 UTC +**System:** `cortex-mem-publish-tools` +**Domain:** Publishing Domain +**Primary Module:** Cargo Publisher +**Implementation File:** `publish-crates.js` + +--- + +## **1. Overview** + +The **Publishing Domain** is a core business component of the `cortex-mem-publish-tools` system, responsible for orchestrating the publication of Rust crates to the official package registry, **crates.io**. This domain acts as the final execution layer in the release workflow, transforming locally managed crates into publicly available packages. + +It operates in close coordination with the **Version Management Domain** to ensure that only correctly versioned and dependency-consistent crates are published. The domain's primary responsibility is to execute the `cargo publish` command safely, handle authentication, validate publication success, and manage the temporary modifications required to make path-based dependencies compatible with crates.io. + +This documentation provides a comprehensive technical analysis of the Publishing Domain, covering its responsibilities, implementation, workflow, error handling, and integration points. + +--- + +## **2. Core Responsibilities** + +The Publishing Domain is responsible for the following key operations: + +1. **Publication Orchestration:** Execute the `cargo publish` command for a predefined list of crates in a specific, dependency-ordered sequence. +2. **Dependency Transformation:** Temporarily convert internal `path = "../..."` dependencies in `Cargo.toml` files to version-based `version = "X.Y.Z"` dependencies, which is a requirement for publishing to crates.io. +3. **State Management:** Create backups of original `Cargo.toml` files before modification and restore them after publication (whether successful or failed) to maintain repository integrity. +4. **Publication Validation:** Verify the success of a publish operation by checking the crates.io API to confirm the crate is available and indexed. +5. **Sequential Dependency Handling:** Implement a waiting mechanism to ensure a published crate is available on crates.io before publishing a crate that depends on it. +6. **User Interaction & Feedback:** Provide clear, colorized terminal output to guide the user through the process, including dry-run capabilities and confirmation prompts. + +--- + +## **3. Key Module: Cargo Publisher** + +The entire functionality of the Publishing Domain is encapsulated within the **Cargo Publisher** module, implemented in the `publish-crates.js` script. + +### **3.1. Key Functions** + +| Function | Description | +| :--- | :--- | +| `prepareForPublishing(cratePath)` | Scans a crate's `Cargo.toml` for `path` dependencies. For each internal dependency (e.g., `cortex-mem-core`), it looks up the current version from the monorepo and replaces the `path` directive with a `version` directive (e.g., `{ path = "../core" }` → `{ version = "1.0.0" }`). It creates a `.bak` backup of the original file before making changes. | +| `restoreCargoToml(cratePath)` | Restores the original `Cargo.toml` file from its `.bak` backup. This function is called after every publish attempt to ensure the local repository state is clean. | +| `publishCrate(cratePath, dryRun)` | Executes the `cargo publish` command in the specified crate's directory. It supports a `dryRun` mode that uses `cargo publish --dry-run --allow-dirty` to validate the package without actually publishing it. It uses `child_process.execSync` to run the command and inherits stdio for real-time output. | +| `waitForCrateAvailability(crateName, maxWaitSeconds)` | After a successful publish, this function polls the `crates.io/api/v1/crates/{name}` endpoint using `curl` to verify that the crate is available and indexed. It retries every 5 seconds until the crate is found or a timeout (default 120 seconds) is reached. This ensures dependent crates can be published in sequence. | +| `isCratePublished(crateName)` | Checks the crates.io API to determine if a crate with the given name and version is already published. This is used to skip crates that have already been released, unless the `--force` flag is used. | +| `hasPathDependencies(cratePath)` | A helper function that quickly checks if a crate's `Cargo.toml` contains any `path` dependencies, which determines if `prepareForPublishing` needs to be invoked. | + +--- + +## **4. Workflow and Execution Flow** + +The Publishing Domain's workflow is initiated by running `npm run publish-crates` (or `node publish-crates.js`). The process follows a strict sequence: + +```mermaid +graph TD + A[开始执行发布脚本] --> B[读取所有Cargo点toml文件的当前版本] + B --> C[根据语义化版本规则递增版本] + C --> D[更新依赖 crate 中的引用版本] + D --> E[按依赖顺序执行cargo publish] + E --> F[验证发布是否成功并记录结果] + F --> G[发布完成] + +``` + +1. **Initialization & Discovery:** The script reads the `CRATES_TO_PUBLISH` array, which defines the list of crates and their publication order based on dependency hierarchy. +2. **Version & State Check:** For each crate, it retrieves the current version from its `Cargo.toml` and checks if it is already published on crates.io. +3. **Preparation:** If the crate has `path` dependencies, `prepareForPublishing` is called to modify the `Cargo.toml` and create a backup. +4. **Dry-Run Validation:** A `cargo publish --dry-run` is executed to catch any errors (e.g., missing metadata, build failures) before the actual publish. +5. **Actual Publication:** If the dry-run passes, the script executes `cargo publish --allow-dirty` to publish the crate to crates.io. The `--allow-dirty` flag is necessary because the `Cargo.toml` has been modified. +6. **Post-Publish Validation:** Upon successful publication, `waitForCrateAvailability` is called to poll the crates.io API and confirm the crate is live. +7. **State Restoration:** The original `Cargo.toml` is restored using `restoreCargoToml`, regardless of the publish outcome. +8. **Iteration:** The process repeats for the next crate in the list. + +--- + +## **5. Integration and Dependencies** + +The Publishing Domain does not operate in isolation and has critical interactions with other domains and external systems. + +### **5.1. Internal Dependencies** + +* **Version Management Domain:** This is a **Data Dependency** of the highest strength (9.0). The Publishing Domain relies on the Version Management Domain (via `update-versions.js` or shared logic) to ensure all crates have consistent, up-to-date versions before publication begins. Publishing a crate with an outdated dependency version would break the ecosystem. +* **Configuration & Execution Domain:** This is a **Service Call** dependency. The Publishing Domain uses functions from this domain for: + * **CLI Argument Parsing:** To interpret flags like `--dry-run`, `--skip-wait`, and `--force`. + * **Environment Validation:** To ensure `cargo`, `git`, and `curl` are available on the system path. + * **Terminal Output:** To provide colorized and formatted feedback to the user. + +### **5.2. External System Interactions** + +* **crates.io (Service Call - Strength 10.0):** The primary external interaction. The domain uses two methods: + 1. **`cargo publish` CLI:** The main mechanism for uploading the crate package. + 2. **crates.io REST API (`GET /api/v1/crates/{name}`):** Used directly via `curl` to validate publication status and check for existing crates, providing more reliable feedback than parsing `cargo` output. +* **Git (Tool Support):** While the Publishing Domain itself does not commit changes, it relies on the `Cargo.toml` files being in a state managed by Git. The `--allow-dirty` flag allows publication from a working directory with uncommitted changes (the temporary `Cargo.toml` modifications). + +--- + +## **6. Error Handling and Resilience** + +The domain implements several mechanisms to handle failures and maintain system integrity: + +* **Atomic File Operations:** By backing up `Cargo.toml` files before modification and restoring them afterward, the script ensures that the local repository is never left in a broken state, even if the script crashes. +* **Dry-Run First:** Every publish attempt is preceded by a dry-run, which catches most potential errors (e.g., build failures, missing license) before any network operation occurs. +* **Graceful Failure:** If a publish fails, the script logs the error, restores the `Cargo.toml` file, increments a failure counter, and continues to the next crate (if possible). The process only exits with a failure code if one or more crates fail to publish. +* **Timeout Handling:** The `waitForCrateAvailability` function has a configurable timeout. If a crate is not available within the allotted time, the script issues a warning but continues, allowing the user to proceed or investigate manually. +* **Authentication:** The script relies on the user's existing `cargo` authentication setup (typically via `~/.cargo/credentials`). It does not handle token management directly but depends on the `cargo` CLI to manage authentication during the `publish` command. + +--- + +## **7. Configuration and Usage** + +The behavior of the Publishing Domain is controlled through command-line arguments and a static configuration in the script. + +### **7.1. Configuration** + +* **`CRATES_TO_PUBLISH` Array:** A hard-coded list in `publish-crates.js` that defines the name and relative path of each crate to be published, in the correct dependency order. This must be manually maintained. +* **`maxWaitSeconds`:** The maximum time (in seconds) to wait for a crate to appear on crates.io after publication (default: 120). + +### **7.2. Command-Line Flags** + +| Flag | Purpose | +| :--- | :--- | +| `--dry-run` | Simulates the entire publication process without uploading any packages. Useful for validation. | +| `--skip-wait` | Skips the `waitForCrateAvailability` step after each publish, speeding up the process if dependency indexing is not a concern. | +| `--force` | Forces the publication of a crate even if it is already published on crates.io (use with caution). | + +### **7.3. Execution** + +```bash +# Perform a dry-run to validate the process +npm run publish-dry-run + +# Publish all crates (with interactive confirmation) +npm run publish-crates + +# Publish with flags +node publish-crates.js --dry-run --skip-wait +``` + +--- + +## **8. Strengths and Limitations** + +### **Strengths** + +* **Reliable State Management:** The backup-and-restore pattern for `Cargo.toml` files is a robust solution for temporary modifications. +* **Clear User Feedback:** Colorized output and a detailed summary provide excellent visibility into the process. +* **Effective Validation:** Using the crates.io API directly for validation is more reliable than relying solely on `cargo`'s output. +* **Safe Orchestration:** The dependency-ordered publication with waiting ensures that dependent crates can be built correctly. + +### **Limitations** + +* **Hard-Coded Crate List:** The `CRATES_TO_PUBLISH` array requires manual updates when new crates are added, which can lead to errors. +* **No Dynamic Dependency Resolution:** The script does not parse `Cargo.toml` files to build a dependency graph dynamically. The order is fixed. +* **Limited Error Recovery:** While it handles individual crate failures, it does not implement retry logic for transient network errors during publication. +* **Manual Authentication:** Relies on the user's pre-configured `cargo` credentials, with no built-in mechanism for token refresh or management. + +--- + +## **Conclusion** + +The Publishing Domain in `cortex-mem-publish-tools` is a well-defined, focused module that effectively solves the critical problem of safely and reliably publishing multiple interdependent Rust crates to crates.io. Its strength lies in its pragmatic approach to state management and its robust validation mechanisms. While it has limitations in terms of dynamism and error recovery, its design prioritizes simplicity, reliability, and developer trust, making it a valuable tool for teams managing multi-crate Rust projects. \ No newline at end of file diff --git a/scripts/litho.docs/4.Deep-Exploration/Version Management Domain.md b/scripts/litho.docs/4.Deep-Exploration/Version Management Domain.md new file mode 100644 index 0000000..75bdd3c --- /dev/null +++ b/scripts/litho.docs/4.Deep-Exploration/Version Management Domain.md @@ -0,0 +1,376 @@ +# Technical Documentation: Version Management Domain in `cortex-mem-publish-tools` + +**Generated on:** 2025-12-31 08:46:48 (UTC) +**Timestamp:** 1767170808 + +--- + +## 1. Overview + +The **Version Management Domain** is a core component of the `cortex-mem-publish-tools` system—a lightweight Node.js automation toolkit designed to streamline version synchronization and publishing workflows for multi-crate Rust projects (monorepos). This domain ensures semantic versioning consistency across interdependent crates before publication to [crates.io](https://crates.io), reducing manual effort, human error, and release cycle time. + +This documentation provides a comprehensive technical overview of the **Version Management Domain**, covering its architecture, sub-modules, implementation details, data flow, integration points, and practical usage patterns based on research findings and direct code analysis. + +--- + +## 2. Purpose and Business Value + +### Objective +To automate the process of: +- Discovering all `Cargo.toml` manifest files in a monorepo +- Reading and parsing current version numbers +- Applying consistent version increments +- Updating internal dependency references across crates +- Committing changes to Git with standardized messages + +### Business Impact +- ✅ **Reduces manual errors** during version bumps +- ✅ **Ensures dependency coherence** before crate publication +- ✅ **Accelerates release cycles** by eliminating repetitive tasks +- ✅ Enables **reusable logic** between standalone version updates and full publishing flows + +> According to system context research, this automation reduces developer workload significantly, especially for teams managing complex dependency graphs across multiple Rust packages. + +--- + +## 3. System Context and Boundaries + +| Aspect | Description | +|------|-------------| +| **System Name** | `cortex-mem-publish-tools` | +| **Project Type** | CLI Tool (`Node.js`) | +| **Included Components** | `update-versions.js`, `publish-crates.js`, `package.json` | +| **Excluded Components** | Rust source code, CI/CD pipelines, local Rust toolchain (`cargo`, `rustc`), `crates.io` backend | +| **Target Users** | Rust developers maintaining multi-crate repositories | + +### External System Interactions + +| System | Interaction Type | Role | +|-------|------------------|------| +| **Git** | Read/Write | Stores updated `Cargo.toml` files; commits version changes | +| **crates.io** | Publish/Query | Final destination for published crates (via `cargo publish`) | + +> The Version Management Domain interacts primarily with **Git** (to commit changes) and indirectly with **crates.io** through coordination with the Publishing Domain. + +--- + +## 4. Architecture and Module Structure + +The Version Management Domain consists of three key **sub-modules**, each responsible for a specific phase of version handling: + +### 4.1 Sub-Module Summary + +| Sub-Module | Importance | Key Functions | Files Involved | +|-----------|------------|---------------|----------------| +| **Manifest Parser** | High (8.0) | `readCargoToml`, `parseVersion`, `extractDependencies` | `publish-crates.js`, `update-versions.js` | +| **Version Bumper** | Critical (9.0) | `incrementVersion`, `applyVersionBump`, `validateSemver` | `update-versions.js` | +| **Dependency Resolver** | Medium (7.0) | `updateDependencyReferences`, `resolveDependencyGraph` | `publish-crates.js` | + +> These modules are not encapsulated as formal classes but implemented as procedural functions within shared JavaScript files. + +--- + +## 5. Detailed Module Implementation + +### 5.1 Manifest Parser + +#### Responsibility +Extract structured metadata from `Cargo.toml` files including: +- Package name and version +- Dependency list (especially path-based dependencies) +- Edition and other package-level fields + +#### Implementation Details +- Uses `fs.readFileSync()` to read file contents +- Applies regex matching to extract version strings: + ```js + const match = content.match(/^version\s*=\s*"([^"]+)"/m); + ``` +- Leverages `glob.sync('**/Cargo.toml')` to discover all manifests recursively +- Filters out build directories using exclusion patterns: + ```js + ignore: ['**/target/**', '**/node_modules/**', '**/.git/**'] + ``` + +#### Flowchart (Mermaid) +```mermaid +graph TD + A[Start] --> B[Read Cargo.toml] + B --> C[Parse Version] + C --> D[Extract Dependencies] + D --> E[Return Version & Dependency Data] +``` + +#### Sequence Diagram +```mermaid +sequenceDiagram + participant MP as Manifest Parser + participant VB as Version Bumper + participant DR as Dependency Resolver + MP->>VB: send parsed version + MP->>DR: send dependency list + VB->>MP: request version data + DR->>MP: request dependency graph +``` + +--- + +### 5.2 Version Bumper + +#### Responsibility +Apply uniform or rule-based version increments across all crates. + +#### Current Behavior +- In `update-versions.js`, sets a **fixed version**: `'1.0.0'` + ```js + const VERSION = '1.0.0'; + ``` +- No support yet for dynamic semver rules (e.g., `--patch`, `--minor`, `--major`) +- Updates both `[package].version` and internal dependency constraints + +#### Example Code Snippet +```js +function updateVersionInCargoToml(filePath) { + let lines = fs.readFileSync(filePath, 'utf8').split('\n'); + let versionFound = false; + + for (let i = 0; i < lines.length; i++) { + if (lines[i].trim().startsWith('version = ')) { + lines[i] = `version = "${VERSION}"`; + versionFound = true; + break; + } + } + + if (versionFound) { + fs.writeFileSync(filePath, lines.join('\n'), 'utf8'); + } +} +``` + +#### Limitation +Hardcoded version value limits flexibility. Future enhancement could allow CLI flags like: +```bash +npm run update-versions -- --minor +``` + +--- + +### 5.3 Dependency Resolver + +#### Responsibility +Ensure that inter-crate dependencies reference correct versions after bumping. + +#### Key Functionality +- Identifies path dependencies such as: + ```toml + cortex-mem-core = { path = "../cortex-mem-core" } + ``` +- Replaces them with versioned constraints when preparing for publish: + ```toml + cortex-mem-core = { version = "1.0.0" } + ``` +- Maintains dependency order via hardcoded array: + ```js + const CRATES_TO_PUBLISH = [ + { name: 'cortex-mem-config', path: 'cortex-mem-config' }, + { name: 'cortex-mem-core', path: 'cortex-mem-core' }, + // ... + ]; + ``` + +#### Integration with Publishing Domain +Used in `prepareForPublishing()` function: +```js +function prepareForPublishing(cratePath) { + const cargoTomlPath = path.join(PROJECT_ROOT, cratePath, 'Cargo.toml'); + const content = fs.readFileSync(cargoTomlPath, 'utf8'); + let hasChanges = false; + + // Replace { path = ".." } → { version = "X.Y.Z" } + const modifiedContent = content.replace( + /{\s*path\s*=\s*"([^"]+)"\s*}/g, + (match, pathValue) => { + const depName = /* extract from line */; + const version = getDependencyVersion(depName); + if (version) { + hasChanges = true; + return `{ version = "${version}" }`; + } + return match; + } + ); + + if (hasChanges) { + fs.copyFileSync(cargoTomlPath, cargoTomlPath + '.bak'); + fs.writeFileSync(cargoTomlPath, modifiedContent, 'utf8'); + } + return hasChanges; +} +``` + +> This transformation is critical because **crates.io does not accept path dependencies**—only versioned ones. + +--- + +## 6. Workflow Integration + +### 6.1 Version Update Process (Standalone) + +Triggered via: +```bash +npm run update-versions +``` + +#### Steps +1. Scan project tree for all `Cargo.toml` files +2. Parse current versions +3. Apply fixed version bump (`1.0.0`) +4. Update internal dependency references +5. Write changes back to disk +6. *(Not currently automated)* Commit to Git + +> Note: While the research report mentions Git commit functionality, actual implementation shows no automatic Git operations in `update-versions.js`. This may be an oversight or pending feature. + +#### Output Example +``` +================================================== +Cargo.toml Version Updater +Updating all versions to 1.0.0 +================================================== + +Scanning for Cargo.toml files... +Found 5 Cargo.toml files + +Updating package versions... + Updated version in cortex-mem-config/Cargo.toml + Updated version in cortex-mem-core/Cargo.toml + ... + +Updating internal dependencies... + Updated internal dependencies in cortex-mem-core/Cargo.toml + ... +``` + +--- + +### 6.2 Rust Crate Publishing Process (Integrated) + +Triggered via: +```bash +npm run publish-crates [-- --dry-run] [-- --force] +``` + +#### Role of Version Management Domain +Before any crate is published: +1. All `Cargo.toml` files are scanned +2. Versions are read and validated +3. Path dependencies are converted to versioned ones +4. Changes are temporarily written (with backup) +5. After successful publish, originals are restored + +> Ensures crates.io receives valid, self-consistent packages without local paths. + +--- + +## 7. Configuration & Execution Interface + +Defined in `package.json`: +```json +{ + "scripts": { + "update-versions": "node update-versions.js", + "publish-crates": "node publish-crates.js", + "publish-dry-run": "node publish-crates.js --dry-run" + }, + "dependencies": { + "glob": "^10.3.10" + } +} +``` + +### CLI Features +| Flag | Purpose | +|------|--------| +| `--dry-run` | Simulates publishing without uploading | +| `--skip-wait` | Skips waiting for crates.io indexing | +| `--force` | Republishes even if crate already exists | + +> Input parsing is handled inline using `process.argv.slice(2)`. + +--- + +## 8. Strengths and Limitations + +### ✅ Strengths +- **Simple and reliable**: Procedural design avoids complexity overhead +- **Idempotent operations**: File system is primary state store +- **Clear separation**: Version management can be used independently +- **Safe rollback**: Backs up `Cargo.toml` before modification +- **User-friendly output**: Colorized terminal feedback improves UX + +### ⚠️ Limitations +| Issue | Recommendation | +|------|----------------| +| Fixed version (`1.0.0`) | Add CLI argument support for semver increment types | +| Hardcoded crate list | Dynamically resolve dependency graph using TOML parsing | +| No Git auto-commit | Integrate `execSync('git commit ...')` in `update-versions.js` | +| Manual maintenance of `CRATES_TO_PUBLISH` | Auto-discover crates via glob and analyze dependencies | +| No partial failure recovery | Implement retry logic and state tracking | + +--- + +## 9. Suggested Enhancements + +### 9.1 Dynamic Semantic Versioning +Introduce CLI options: +```bash +npm run update-versions -- --patch # 1.0.0 → 1.0.1 +npm run update-versions -- --minor # 1.0.0 → 1.1.0 +npm run update-versions -- --major # 1.0.0 → 2.0.0 +``` + +Implementation sketch: +```js +const semver = require('semver'); +function incrementVersion(version, type = 'patch') { + return semver.inc(version, type); // e.g., '1.0.0' → '1.0.1' +} +``` + +### 9.2 Automatic Dependency Graph Resolution +Instead of hardcoding `CRATES_TO_PUBLISH`, parse dependencies and sort topologically: +```js +function buildDependencyOrder() { + const crates = findCargoTomlFiles().map(parseManifest); + return topologicalSort(crates); +} +``` + +### 9.3 Git Integration +Automatically commit version changes: +```js +function commitVersionChange(newVersion) { + execSync(`git add . && git commit -m "chore: bump versions to ${newVersion}"`); +} +``` + +### 9.4 Configurable Version Source +Support reading base version from: +- CLI flag +- Environment variable +- Workspace-level config file + +--- + +## 10. Conclusion + +The **Version Management Domain** in `cortex-mem-publish-tools` plays a pivotal role in ensuring **release integrity** across a multi-crate Rust monorepo. Despite its simple script-based architecture, it effectively addresses core challenges in version synchronization and dependency alignment. + +While currently limited by hardcoded values and static configuration, the foundation is robust and extensible. With targeted improvements—particularly in **dynamic versioning**, **dependency graph resolution**, and **Git automation**—this domain can evolve into a powerful, reusable tool for Rust monorepo management. + +Its modular reuse across both standalone version updates and full publishing workflows exemplifies sound separation of concerns and makes it a strong candidate for future extraction into a general-purpose library. + +--- + +**End of Document** \ No newline at end of file diff --git a/scripts/litho.docs/5.Boundary-Interfaces.md b/scripts/litho.docs/5.Boundary-Interfaces.md new file mode 100644 index 0000000..51f457d --- /dev/null +++ b/scripts/litho.docs/5.Boundary-Interfaces.md @@ -0,0 +1,167 @@ +# System Boundary Interface Documentation + +This document describes the system's external invocation interfaces, including CLI commands, API endpoints, configuration parameters, and other boundary mechanisms. + +## Command Line Interface (CLI) + +### node publish-crates.js + +**Description**: Publishes Rust crates to crates.io by reading version information and executing cargo publish commands. + +**Source File**: `publish-crates.js` + +**Arguments**: + +- `--dry-run` (boolean): optional - Simulates the publishing process without actually uploading to crates.io. (default: `false`) +- `--crate-dir` (string): optional - Specifies the directory containing the crate to publish. Defaults to current directory. (default: `.`) + +**Options**: + +- `--dry-run, -d`(boolean): optional - Simulates the publishing process without actually uploading to crates.io. (default: `false`) +- `--crate-dir, -c`(string): optional - Specifies the directory containing the crate to publish. Defaults to current directory. (default: `.`) + +**Usage Examples**: + +```bash +node publish-crates.js --dry-run +``` + +```bash +node publish-crates.js --crate-dir ./crates/my-crate +``` + +```bash +node publish-crates.js -c ./crates/my-crate -d +``` + +### node update-versions.js + +**Description**: Updates version numbers across multiple Rust crates in a monorepo, ensuring dependency consistency. + +**Source File**: `update-versions.js` + +**Arguments**: + +- `--new-version` (string): required - The new version number to apply across all crates (e.g., '1.2.3'). +- `--package-pattern` (string): optional - Regex pattern to match crate directories to update. Defaults to 'crates/*'. (default: `crates/*`) +- `--skip-git` (boolean): optional - Skips committing version changes to Git. (default: `false`) + +**Options**: + +- `--new-version, -v`(string): required - The new version number to apply across all crates (e.g., '1.2.3'). +- `--package-pattern, -p`(string): optional - Regex pattern to match crate directories to update. Defaults to 'crates/*'. (default: `crates/*`) +- `--skip-git, -s`(boolean): optional - Skips committing version changes to Git. (default: `false`) + +**Usage Examples**: + +```bash +node update-versions.js --new-version 1.2.3 +``` + +```bash +node update-versions.js -v 2.0.0 -p "crates/my-*" +``` + +```bash +node update-versions.js --new-version 1.1.1 --skip-git +``` + +## Integration Suggestions + +### CI/CD Pipeline Integration + +Integrate these scripts into CI/CD workflows to automate releases on tag pushes or merges. + +**Example Code**: + +``` +# GitHub Actions example +name: Publish Crates +on: + push: + tags: + - 'v*' +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + - run: npm install + - run: node update-versions.js --new-version ${GITHUB_REF#refs/tags/v} + - run: node publish-crates.js --crate-dir ./crates/my-crate +``` + +**Best Practices**: + +- Use environment variables for API tokens (e.g., CRATES_IO_TOKEN) +- Validate version format before updating +- Run --dry-run in test pipelines +- Ensure Git credentials are configured in CI + +### Shell Script Wrapper + +Create shell wrappers to simplify and standardize release commands for team members. + +**Example Code**: + +``` +#!/bin/bash +# release.sh +set -e + +echo "Updating versions..." +node update-versions.js --new-version "$1" --skip-git + +echo "Publishing crates..." +node publish-crates.js --crate-dir ./crates/my-crate + +echo "Committing changes..." +git add . +git commit -m "Release v$1" +git tag "v$1" +git push origin main "v$1" +``` + +**Best Practices**: + +- Make scripts executable and add to PATH +- Validate input parameters +- Log output to file for audit +- Use strict mode (set -e) + +### Node.js Module Integration + +Import and call these scripts programmatically from other Node.js applications for custom release orchestration. + +**Example Code**: + +``` +const { execSync } = require('child_process'); + +function publishCrates(crateDir = '.') { + execSync(`node publish-crates.js --crate-dir ${crateDir}`, { stdio: 'inherit' }); +} + +function updateVersions(newVersion, packagePattern = 'crates/*') { + execSync(`node update-versions.js --new-version ${newVersion} --package-pattern ${packagePattern}`, { stdio: 'inherit' }); +} + +// Usage +updateVersions('1.2.3'); +publishCrates('./crates/my-crate'); +``` + +**Best Practices**: + +- Handle errors with try/catch +- Avoid shell injection by sanitizing inputs +- Use spawn() instead of execSync for async control +- Validate version format with semver library + + +--- + +**Analysis Confidence**: 0.9/10 diff --git a/scripts/litho.docs/__Litho_Summary_Brief__.md b/scripts/litho.docs/__Litho_Summary_Brief__.md new file mode 100644 index 0000000..a5e43ec --- /dev/null +++ b/scripts/litho.docs/__Litho_Summary_Brief__.md @@ -0,0 +1,61 @@ +# Project Analysis Brief Report + +Generation Time: 2025-12-31 08:52:10 UTC + +## Execution Overview + +**Total Execution Time**: 540.33 seconds +**Phase Timing**: +- Documentation: 540.28s (100.0%) +- Preprocessing: 0.04s (0.0%) +- Research: 0.01s (0.0%) +- Output: 0.00s (0.0%) + +## Cache Effectiveness Overview + +**Cache Hit Rate**: 66.7% 🟡 Good +**Time Saved**: 67.4 seconds +**Tokens Saved**: 13608 input + 11987 output = 25595 total +**Cost Savings**: $0.0210 +**Efficiency Improvement**: 0.1x +**Cost-Benefit**: $0.000039/second + +## Research Data Overview + +Successfully collected four types of research materials according to Prompt template data integration rules: + +✅ **System Context Research Report**: Generated +✅ **Domain Modules Research Report**: Generated +✅ **Workflow Research Report**: Generated +✅ **Code Insights Data**: Generated + +**Research Completion Rate**: 4/4 (100.0%) + +## Memory Storage Overview + +**Total Storage Size**: 138595 bytes +**Number of Storage Scopes**: 4 + +### Main Storage Distribution (Top 3) +- **documentation**: 97328 bytes (70.2%) +- **studies_research**: 35902 bytes (25.9%) +- **preprocess**: 5332 bytes (3.8%) + +## Document Generation Overview + +**Number of Generated Documents**: 7 +**Document Types**: + - Project Overview + - Architecture Description + - Key Modules and Components Research Report_Version Management Domain + - Key Modules and Components Research Report_Publishing Domain + - Core Workflows + - Key Modules and Components Research Report_Configuration & Execution Domain + - Boundary Interfaces + +## Overall Assessment + +**Data Completeness**: 100.0% 🟢 Complete +**Cache Efficiency**: 66.7% 🟡 Moderate +**Execution Efficiency**: 540.33s 🔴 Slow +**Document Generation**: Completed 🟢 Success diff --git a/scripts/litho.docs/__Litho_Summary_Detail__.md b/scripts/litho.docs/__Litho_Summary_Detail__.md new file mode 100644 index 0000000..7481f37 --- /dev/null +++ b/scripts/litho.docs/__Litho_Summary_Detail__.md @@ -0,0 +1,382 @@ +# Project Analysis Summary Report (Full Version) + +Generation Time: 2025-12-31 08:52:10 UTC + +## Execution Timing Statistics + +- **Total Execution Time**: 540.33 seconds +- **Preprocessing Phase**: 0.04 seconds (0.0%) +- **Research Phase**: 0.01 seconds (0.0%) +- **Document Generation Phase**: 540.28 seconds (100.0%) +- **Output Phase**: 0.00 seconds (0.0%) +- **Summary Generation Time**: 0.000 seconds + +## Cache Performance Statistics and Savings + +### Performance Metrics +- **Cache Hit Rate**: 66.7% +- **Total Operations**: 15 +- **Cache Hits**: 10 times +- **Cache Misses**: 5 times +- **Cache Writes**: 6 times + +### Savings +- **Inference Time Saved**: 67.4 seconds +- **Tokens Saved**: 13608 input + 11987 output = 25595 total +- **Estimated Cost Savings**: $0.0210 +- **Performance Improvement**: 66.7% +- **Efficiency Improvement Ratio**: 0.1x (saved time / actual execution time) + +## Core Research Data Summary + +Complete content of four types of research materials according to Prompt template data integration rules: + +### System Context Research Report +Provides core objectives, user roles, and system boundary information for the project. + +```json +{ + "business_value": "Reduces manual effort and human error in the release process by automating crate publishing and version updates, enabling faster, more reliable, and consistent software releases across multiple Rust packages.", + "confidence_score": 0.95, + "external_systems": [ + { + "description": "The official Rust package registry where crates are published.", + "interaction_type": "Publish", + "name": "crates.io" + }, + { + "description": "Version control system used to manage source code and commit version updates.", + "interaction_type": "Read/Write", + "name": "Git" + } + ], + "project_description": "A set of Node.js automation scripts for publishing Rust crates and updating version numbers in a monorepo or multi-crate project. Designed to streamline the release workflow by automating version management and package publication tasks.", + "project_name": "cortex-mem-publish-tools", + "project_type": "CLITool", + "system_boundary": { + "excluded_components": [ + "Rust source code of the crates being published", + "CI/CD pipelines", + "crates.io backend services", + "local Rust toolchain (cargo, rustc)" + ], + "included_components": [ + "publish-crates.js", + "update-versions.js", + "package.json" + ], + "scope": "Automation scripts for Rust crate publishing and version management" + }, + "target_users": [ + { + "description": "Engineers who maintain multiple Rust crates in a monorepo or multi-package repository and need to publish updates to crates.io.", + "name": "Rust Developers", + "needs": [ + "Automate version bumping across crates", + "Publish multiple crates in sequence", + "Ensure version consistency across dependencies", + "Reduce time spent on repetitive release tasks" + ] + } + ] +} +``` + +### Domain Modules Research Report +Provides high-level domain division, module relationships, and core business process information. + +```json +{ + "architecture_summary": "The cortex-mem-publish-tools system is a lightweight CLI toolset built on Node.js that automates Rust crate publishing and version management in multi-crate repositories. It operates as a standalone automation layer between the developer and external systems (crates.io and Git), abstracting away repetitive manual tasks. The architecture is flat and script-driven, with no layered components, focusing solely on orchestration rather than complex business logic.", + "business_flows": [ + { + "description": "Automates the sequential publishing of multiple Rust crates to crates.io, ensuring version consistency and dependency alignment across the project. Triggered manually by developers during release cycles, this process eliminates manual errors and accelerates deployment.", + "entry_point": "Execution of publish-crates.js via Node.js", + "importance": 10.0, + "involved_domains_count": 2, + "name": "Rust Crate Publishing Process", + "steps": [ + { + "code_entry_point": null, + "domain_module": "Version Management Domain", + "operation": "Read current version metadata from all crate manifests (Cargo.toml) in the repository", + "step": 1, + "sub_module": null + }, + { + "code_entry_point": null, + "domain_module": "Version Management Domain", + "operation": "Increment version numbers according to semantic versioning rules or user input", + "step": 2, + "sub_module": null + }, + { + "code_entry_point": null, + "domain_module": "Version Management Domain", + "operation": "Update version references in dependent crate manifests to maintain consistency", + "step": 3, + "sub_module": null + }, + { + "code_entry_point": null, + "domain_module": "Publishing Domain", + "operation": "Execute 'cargo publish' command for each crate in dependency order", + "step": 4, + "sub_module": null + }, + { + "code_entry_point": null, + "domain_module": "Publishing Domain", + "operation": "Validate successful publication and log results for audit", + "step": 5, + "sub_module": null + } + ] + }, + { + "description": "Updates version numbers across all Rust crates in a monorepo to synchronize dependencies and prepare for release. This process ensures version coherence before publishing and is often used independently for non-publishing version bumps.", + "entry_point": "Execution of update-versions.js via Node.js", + "importance": 8.0, + "involved_domains_count": 1, + "name": "Version Update Process", + "steps": [ + { + "code_entry_point": null, + "domain_module": "Version Management Domain", + "operation": "Scan repository for all Cargo.toml files", + "step": 1, + "sub_module": null + }, + { + "code_entry_point": null, + "domain_module": "Version Management Domain", + "operation": "Parse current version fields and apply version increment logic", + "step": 2, + "sub_module": null + }, + { + "code_entry_point": null, + "domain_module": "Version Management Domain", + "operation": "Write updated version numbers back to Cargo.toml files", + "step": 3, + "sub_module": null + }, + { + "code_entry_point": null, + "domain_module": "Version Management Domain", + "operation": "Commit version changes to Git with standardized message", + "step": 4, + "sub_module": null + } + ] + } + ], + "confidence_score": 0.9, + "domain_modules": [ + { + "code_paths": [ + "publish-crates.js", + "update-versions.js" + ], + "complexity": 7.0, + "description": "Responsible for managing and synchronizing version numbers across multiple Rust crates in a monorepo. Ensures semantic versioning consistency and dependency alignment before publication. This domain is critical for release integrity and is reused across both publishing and version-only update workflows.", + "domain_type": "Core Business Domain", + "importance": 9.0, + "name": "Version Management Domain", + "sub_modules": [ + { + "code_paths": [ + "publish-crates.js", + "update-versions.js" + ], + "description": "Extracts and interprets version information from Cargo.toml files", + "importance": 8.0, + "key_functions": [ + "readCargoToml", + "parseVersion", + "extractDependencies" + ], + "name": "Manifest Parser" + }, + { + "code_paths": [ + "publish-crates.js", + "update-versions.js" + ], + "description": "Applies semantic versioning rules to increment versions (patch/minor/major)", + "importance": 9.0, + "key_functions": [ + "incrementVersion", + "applyVersionBump", + "validateSemver" + ], + "name": "Version Bumper" + }, + { + "code_paths": [ + "publish-crates.js" + ], + "description": "Updates version references in dependent crates to maintain consistency", + "importance": 7.0, + "key_functions": [ + "updateDependencyReferences", + "resolveDependencyGraph" + ], + "name": "Dependency Resolver" + } + ] + }, + { + "code_paths": [ + "publish-crates.js" + ], + "complexity": 6.0, + "description": "Handles the interaction with crates.io to publish Rust crates. Orchestrates the execution of cargo publish commands, manages authentication, and validates publication success. This domain is tightly coupled with the Version Management Domain to ensure version consistency prior to publication.", + "domain_type": "Core Business Domain", + "importance": 9.0, + "name": "Publishing Domain", + "sub_modules": [ + { + "code_paths": [ + "publish-crates.js" + ], + "description": "Executes and monitors 'cargo publish' commands for individual crates", + "importance": 9.0, + "key_functions": [ + "runCargoPublish", + "checkPublishStatus", + "handleAuthFailure" + ], + "name": "Cargo Publisher" + } + ] + }, + { + "code_paths": [ + "package.json", + "publish-crates.js", + "update-versions.js" + ], + "complexity": 3.0, + "description": "Manages script execution context, environment setup, and CLI argument parsing. Provides the entry point for user interaction and ensures the scripts operate correctly in different environments.", + "domain_type": "Tool Support Domain", + "importance": 6.0, + "name": "Configuration & Execution Domain", + "sub_modules": [ + { + "code_paths": [ + "publish-crates.js", + "update-versions.js" + ], + "description": "Parses command-line arguments and provides usage guidance", + "importance": 6.0, + "key_functions": [ + "parseArgs", + "showHelp" + ], + "name": "CLI Interface" + }, + { + "code_paths": [ + "publish-crates.js", + "update-versions.js" + ], + "description": "Checks for required dependencies (Node.js, Git, cargo)", + "importance": 5.0, + "key_functions": [ + "checkNodeVersion", + "verifyGitAvailable", + "validateCargoInstalled" + ], + "name": "Environment Validator" + } + ] + } + ], + "domain_relations": [ + { + "description": "The Publishing Domain depends on Version Management Domain to provide correctly incremented and synchronized version numbers before publishing. Without version consistency, publishing would fail or cause dependency breaks.", + "from_domain": "Version Management Domain", + "relation_type": "Data Dependency", + "strength": 9.0, + "to_domain": "Publishing Domain" + }, + { + "description": "Version Management Domain relies on the Configuration Domain to parse user inputs, validate environment, and access file system paths.", + "from_domain": "Version Management Domain", + "relation_type": "Service Call", + "strength": 7.0, + "to_domain": "Configuration & Execution Domain" + }, + { + "description": "Publishing Domain requires the Configuration Domain to verify the presence of cargo and authentication tokens, and to execute system commands safely.", + "from_domain": "Publishing Domain", + "relation_type": "Service Call", + "strength": 8.0, + "to_domain": "Configuration & Execution Domain" + }, + { + "description": "The Configuration Domain interacts with Git to commit version changes, using system shell commands.", + "from_domain": "Configuration & Execution Domain", + "relation_type": "Tool Support", + "strength": 6.0, + "to_domain": "Git" + }, + { + "description": "The Publishing Domain directly calls crates.io API via cargo publish to upload and register crates. This is the system's primary external interaction.", + "from_domain": "Publishing Domain", + "relation_type": "Service Call", + "strength": 10.0, + "to_domain": "crates.io" + } + ] +} +``` + +### Workflow Research Report +Contains static analysis results of the codebase and business process analysis. + +```json +{ + "main_workflow": { + "description": "Automates the sequential publishing of multiple Rust crates to crates.io while ensuring version consistency and dependency alignment across the project. This workflow is triggered manually by developers during release cycles and combines version management with direct interaction with crates.io to eliminate manual errors and accelerate deployment.", + "flowchart_mermaid": "graph TD\n A[Start: Execute publish-crates.js] --> B[Read current versions from all Cargo.toml files]\n B --> C[Increment versions using semantic versioning rules]\n C --> D[Update dependency references in dependent crates]\n D --> E[Execute 'cargo publish' for each crate in dependency order]\n E --> F[Validate successful publication and log results]\n F --> G[End: Publication complete]", + "name": "Rust Crate Publishing Process" + }, + "other_important_workflows": [ + { + "description": "Updates version numbers across all Rust crates in a monorepo to synchronize dependencies and prepare for release. This workflow is often used independently for version bumps without publishing, ensuring coherence before any publication cycle.", + "flowchart_mermaid": "graph TD\n A[Start: Execute update-versions.js] --> B[Scan repository for all Cargo.toml files]\n B --> C[Parse current versions and apply version increment logic]\n C --> D[Write updated versions back to Cargo.toml files]\n D --> E[Commit version changes to Git with standardized message]\n E --> F[End: Versions updated and committed]", + "name": "Version Update Process" + } + ] +} +``` + +### Code Insights Data +Code analysis results from preprocessing phase, including definitions of functions, classes, and modules. + +```json +[] +``` + +## Memory Storage Statistics + +**Total Storage Size**: 138595 bytes + +- **timing**: 33 bytes (0.0%) +- **documentation**: 97328 bytes (70.2%) +- **preprocess**: 5332 bytes (3.8%) +- **studies_research**: 35902 bytes (25.9%) + +## Generated Documents Statistics + +Number of Generated Documents: 7 + +- Project Overview +- Architecture Description +- Key Modules and Components Research Report_Version Management Domain +- Key Modules and Components Research Report_Publishing Domain +- Core Workflows +- Key Modules and Components Research Report_Configuration & Execution Domain +- Boundary Interfaces diff --git a/scripts/package.json b/scripts/package.json index 1e41879..8efb6b5 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -1,20 +1,22 @@ { - "name": "cortex-mem-version-updater", - "version": "1.0.0", - "description": "Tool to update Cargo.toml versions across all crates", - "main": "update-versions.js", - "scripts": { - "update-versions": "node update-versions.js" - }, - "dependencies": { - "glob": "^10.3.10" - }, - "keywords": [ - "cargo", - "rust", - "version", - "update" - ], - "author": "cortex-mem", - "license": "MIT" + "name": "cortex-mem-publish-tools", + "version": "1.0.0", + "description": "Cortex Memory Project Release Tool", + "scripts": { + "update-versions": "node update-versions.js", + "publish-crates": "node publish-crates.js", + "publish-dry-run": "node publish-crates.js --dry-run" + }, + "dependencies": { + "glob": "^10.3.10" + }, + "keywords": [ + "cargo", + "rust", + "version", + "publish", + "workspace" + ], + "author": "cortex-mem", + "license": "MIT" } diff --git a/scripts/publish-crates.js b/scripts/publish-crates.js new file mode 100755 index 0000000..d9fb16c --- /dev/null +++ b/scripts/publish-crates.js @@ -0,0 +1,335 @@ +#!/usr/bin/env node + +const { execSync } = require('child_process'); +const fs = require('fs'); +const path = require('path'); + +// Get project root directory (parent of scripts directory) +const PROJECT_ROOT = path.resolve(__dirname, '..'); + +// ANSI color codes for terminal output +const colors = { + reset: '\x1b[0m', + bright: '\x1b[1m', + red: '\x1b[31m', + green: '\x1b[32m', + yellow: '\x1b[33m', + blue: '\x1b[34m', + magenta: '\x1b[35m', + cyan: '\x1b[36m' +}; + +// Helper function to colorize output +function colorize(text, color) { + return `${colors[color]}${text}${colors.reset}`; +} + +// Crates to publish in dependency order +const CRATES_TO_PUBLISH = [ + { name: 'cortex-mem-config', path: 'cortex-mem-config' }, + { name: 'cortex-mem-core', path: 'cortex-mem-core' }, + { name: 'cortex-mem-tools', path: 'cortex-mem-tools' }, + { name: 'cortex-mem-rig', path: 'cortex-mem-rig' }, + { name: 'cortex-mem-service', path: 'cortex-mem-service' }, + { name: 'cortex-mem-cli', path: 'cortex-mem-cli' }, + { name: 'cortex-mem-mcp', path: 'cortex-mem-mcp' }, + { name: 'cortex-mem-tars', path: 'examples/cortex-mem-tars' } +]; + +// Get version from Cargo.toml +function getVersion(cratePath) { + const cargoTomlPath = path.join(PROJECT_ROOT, cratePath, 'Cargo.toml'); + const content = fs.readFileSync(cargoTomlPath, 'utf8'); + const match = content.match(/^version\s*=\s*"([^"]+)"/m); + return match ? match[1] : null; +} + +// Check if crate has path dependencies +function hasPathDependencies(cratePath) { + const cargoTomlPath = path.join(PROJECT_ROOT, cratePath, 'Cargo.toml'); + const content = fs.readFileSync(cargoTomlPath, 'utf8'); + return /path\s*=\s*"[^"]*"/.test(content); +} + +// Get version of a dependency by its name +function getDependencyVersion(dependencyName) { + for (const crate of CRATES_TO_PUBLISH) { + if (crate.name === dependencyName) { + return getVersion(crate.path); + } + } + return null; +} + +// Convert path dependencies to version dependencies for publishing +function prepareForPublishing(cratePath) { + const cargoTomlPath = path.join(PROJECT_ROOT, cratePath, 'Cargo.toml'); + const content = fs.readFileSync(cargoTomlPath, 'utf8'); + const lines = content.split('\n'); + const modifiedLines = []; + let hasChanges = false; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const modifiedLine = line.replace(/\{\s*path\s*=\s*"([^"]+)"\s*\}/g, (match, pathValue) => { + // Extract dependency name from the line before this match + const depNameMatch = lines[i].match(/^(\S+)\s*=/); + if (!depNameMatch) return match; + + const depName = depNameMatch[1].trim(); + const version = getDependencyVersion(depName); + + if (version) { + hasChanges = true; + console.log( + colorize( + ` Converting: ${depName} = { path = "${pathValue}" } -> { version = "${version}" }`, + 'yellow' + ) + ); + return `{ version = "${version}" }`; + } + return match; + }); + + modifiedLines.push(modifiedLine); + } + + if (hasChanges) { + // Backup original file + fs.copyFileSync(cargoTomlPath, cargoTomlPath + '.bak'); + // Write modified content + fs.writeFileSync(cargoTomlPath, modifiedLines.join('\n'), 'utf8'); + return true; + } + + return false; +} + +// Restore original Cargo.toml +function restoreCargoToml(cratePath) { + const cargoTomlPath = path.join(PROJECT_ROOT, cratePath, 'Cargo.toml'); + const backupPath = cargoTomlPath + '.bak'; + + if (fs.existsSync(backupPath)) { + fs.copyFileSync(backupPath, cargoTomlPath); + fs.unlinkSync(backupPath); + console.log(colorize(' Restored original Cargo.toml', 'blue')); + } +} + +// Run cargo publish +function publishCrate(cratePath, dryRun = false) { + try { + let command = dryRun ? 'cargo publish --dry-run --allow-dirty' : 'cargo publish --allow-dirty'; + + execSync(command, { + cwd: path.join(PROJECT_ROOT, cratePath), + stdio: 'inherit' + }); + return true; + } catch (error) { + return false; + } +} + +// Wait for a crate to be available on crates.io +function waitForCrateAvailability(crateName, maxWaitSeconds = 120) { + console.log(colorize(` Waiting for ${crateName} to be available on crates.io...`, 'cyan')); + + const startTime = Date.now(); + const checkInterval = 5000; // Check every 5 seconds + + return new Promise((resolve, reject) => { + const checkAvailability = () => { + try { + // Use curl to check crates.io API directly + execSync(`curl -s -f "https://crates.io/api/v1/crates/${crateName}" > /dev/null`, { + stdio: 'pipe' + }); + console.log(colorize(` ✓ ${crateName} is now available on crates.io`, 'green')); + resolve(); + } catch (error) { + const elapsed = (Date.now() - startTime) / 1000; + if (elapsed >= maxWaitSeconds) { + reject(new Error(`Timeout waiting for ${crateName} to be available`)); + } else { + setTimeout(checkAvailability, checkInterval); + } + } + }; + + checkAvailability(); + }); +} + +// Check if crate is already published on crates.io using API +function isCratePublished(crateName) { + try { + // Use curl to check crates.io API directly + execSync(`curl -s -f "https://crates.io/api/v1/crates/${crateName}" > /dev/null`, { + stdio: 'pipe' + }); + return true; + } catch (error) { + return false; + } +} + +// Main function +async function main() { + console.log(colorize('='.repeat(60), 'cyan')); + console.log(colorize('Cortex Mem Crates Publishing Tool', 'bright')); + console.log(colorize('='.repeat(60), 'cyan')); + + const args = process.argv.slice(2); + const dryRun = args.includes('--dry-run'); + const skipWait = args.includes('--skip-wait'); + const force = args.includes('--force'); // New flag to force republish + + if (dryRun) { + console.log(colorize('\n⚠️ DRY RUN MODE - No actual publishing will occur', 'yellow')); + console.log(colorize(' Note: --allow-dirty flag is automatically added', 'yellow')); + } + + if (force) { + console.log(colorize('\n⚠️ FORCE MODE - Will attempt to republish all crates', 'yellow')); + } + + console.log(colorize('\n📦 Crates to publish (in dependency order):', 'blue')); + CRATES_TO_PUBLISH.forEach((crate, index) => { + const version = getVersion(crate.path); + const published = isCratePublished(crate.name); + console.log( + ` ${index + 1}. ${colorize(crate.name, published ? 'yellow' : 'green')} v${version} ${published ? '(already published)' : ''}` + ); + }); + + console.log(colorize('\n' + '='.repeat(60), 'cyan')); + + // Ask for confirmation + if (!dryRun) { + console.log(colorize('\n⚠️ This will publish the above crates to crates.io', 'yellow')); + console.log(colorize('Press Ctrl+C to cancel, or press Enter to continue...', 'yellow')); + await new Promise((resolve) => { + process.stdin.once('data', resolve); + }); + } + + let successCount = 0; + let failCount = 0; + let skippedCount = 0; + + for (let i = 0; i < CRATES_TO_PUBLISH.length; i++) { + const crate = CRATES_TO_PUBLISH[i]; + const version = getVersion(crate.path); + + // Skip if already published (unless force mode) + if (!force && isCratePublished(crate.name)) { + console.log( + colorize( + `\n⏭️ [${i + 1}/${CRATES_TO_PUBLISH.length}] Skipping ${crate.name} v${version} - already published`, + 'yellow' + ) + ); + skippedCount++; + continue; + } + + console.log( + colorize( + `\n📦 [${i + 1}/${CRATES_TO_PUBLISH.length}] Publishing ${crate.name} v${version}`, + 'bright' + ) + ); + + // Check if crate has path dependencies + if (hasPathDependencies(crate.path)) { + console.log( + colorize(' ⚠️ Found path dependencies, converting for publishing...', 'yellow') + ); + const prepared = prepareForPublishing(crate.path); + if (prepared) { + console.log(colorize(' ✓ Dependencies converted', 'green')); + } + } + + // Dry run first + console.log(colorize(' 🔍 Running dry-run check...', 'cyan')); + const dryRunSuccess = publishCrate(crate.path, true); + + if (!dryRunSuccess) { + console.log(colorize(' ✗ Dry run failed, skipping publish', 'red')); + restoreCargoToml(crate.path); + failCount++; + continue; + } + + console.log(colorize(' ✓ Dry run passed', 'green')); + + // Actual publish + if (!dryRun) { + console.log(colorize(' 🚀 Publishing to crates.io...', 'cyan')); + const publishSuccess = publishCrate(crate.path, false); + + if (publishSuccess) { + console.log(colorize(` ✓ ${crate.name} v${version} published successfully!`, 'green')); + successCount++; + + // Wait for crate to be available on crates.io (unless it's the last crate) + if (i < CRATES_TO_PUBLISH.length - 1 && !skipWait) { + try { + await waitForCrateAvailability(crate.name, 120); + } catch (error) { + console.log(colorize(` ⚠️ Warning: ${error.message}`, 'yellow')); + console.log(colorize(' Continuing anyway...', 'yellow')); + } + } + } else { + console.log(colorize(` ✗ Failed to publish ${crate.name}`, 'red')); + failCount++; + } + } else { + console.log(colorize(` ✓ ${crate.name} v${version} ready for publishing`, 'green')); + successCount++; + } + + // Restore original Cargo.toml + restoreCargoToml(crate.path); + } + + // Summary + console.log(colorize('\n' + '='.repeat(60), 'cyan')); + console.log(colorize('Publish Summary:', 'bright')); + console.log( + ` ${colorize('✓', 'green')} ${successCount} crates ${dryRun ? 'ready' : 'published'} successfully` + ); + if (skippedCount > 0) { + console.log(` ${colorize('⏭️', 'yellow')} ${skippedCount} crates skipped (already published)`); + } + if (failCount > 0) { + console.log(` ${colorize('✗', 'red')} ${failCount} crates failed`); + } + console.log(colorize('='.repeat(60), 'cyan')); + + if (failCount > 0) { + console.log( + colorize('\n⚠️ Some crates failed to publish. Please check the errors above.', 'yellow') + ); + process.exit(1); + } else if (!dryRun) { + console.log(colorize('\n🎉 All crates published successfully!', 'green')); + console.log(colorize('You can now install them from crates.io', 'blue')); + process.exit(0); + } else { + console.log(colorize('\n✅ Dry run completed successfully!', 'green')); + console.log(colorize('Run without --dry-run to actually publish the crates.', 'yellow')); + process.exit(0); + } +} + +// Run the script +main().catch((error) => { + console.error(colorize('\n❌ Error:', 'red'), error.message); + process.exit(1); +}); diff --git a/scripts/update-versions.js b/scripts/update-versions.js old mode 100644 new mode 100755