Repository navigation
Releases: ianphil/msclaw
Release list
v0.9.1
What's Changed
Full Changelog: v0.9.0...v0.9.1
v0.9.0
What's New
⏰ Cron System — Scheduled Agent Autonomy
The headline feature of v0.9.0 is the Cron System, giving the MsClaw agent the ability to self-program recurring and one-shot work on a schedule — without human initiation.
Architecture highlights:
- CronEngine —
IHostedServicewith a 2-secondPeriodicTimerthat evaluates due jobs and dispatches to the appropriate executor. - CronToolProvider — 7 bundled tools (
cron_create,cron_list,cron_get,cron_update,cron_delete,cron_pause,cron_resume) registered viaIToolProvider, always visible in every session. - PromptJobExecutor — creates isolated LLM sessions per execution via
SessionPool. Each run gets a freshcron:{jobId}:{runId}session with full tool access. - CommandJobExecutor — runs shell commands via
Process.Start()with timeout enforcement. No LLM session, no token cost. - CronJobStore — in-memory
ConcurrentDictionarycache with atomic write-temp-then-rename persistence to~/.msclaw/cron/jobs.json. - ICronJobExecutor — pluggable executor abstraction. Adding a new job type requires only a new executor and payload variant — zero engine changes.
📅 Three Schedule Types
- One-shot — "Remind me in 20 minutes" fires once and finalizes
- Fixed interval — "Check every 30 minutes" fires repeatedly
- Cron expression — "Weekdays at 9am EST" →
0 9 * * 1-5with IANA timezone support via Cronos
🛡️ Reliability
- Transient/permanent error classification via
ICronErrorClassifier— exponential backoff (30s → 1m → 5m → 15m → 60m) on transient errors, immediate finalization on permanent errors - Atomic persistence — write-temp-then-rename prevents corruption on crash
- Overdue-on-startup — jobs that missed their window during downtime fire on the first engine tick
- Concurrency control — configurable limit (default: serial execution) prevents runaway parallel jobs
🎨 UI Integration
Cron job results now appear as purple-striped entries in the browser activity sidebar. Click to expand the full CronRunEvent JSON payload.
📐 Design Refinements
ICronRunHistoryStoresplit fromICronJobStoreper Interface Segregation Principle — consumers inject only the interface they needCronJobLifecycleextracted as a pure static helper for state transitions (success/failure/backoff), independently testable from the engineICronOutputSinkdecouples the engine from SignalR — future sinks (file logging, webhooks) require no engine changesCronStaggerCalculatorapplies deterministic per-job offsets to prevent load spikes from jobs at common times
📊 By the Numbers
- 77 tasks across 6 implementation phases (50 test, 27 impl)
- 19 source files in
Services/Cron/ - 11 test files with full unit test coverage
- Built with strict TDD (red → green → refactor) throughout
Full Changelog: v0.8.0...v0.9.0
v0.8.0
What's New
🔧 Tool Bridge — Provider Abstraction & Registry
The headline feature of v0.8.0 is the Tool Bridge, a complete provider-based abstraction for bridging external tool sources onto Copilot SDK sessions. This enables MsClaw agents to discover and invoke tools from any registered provider (MCPorter, cron, bundled utilities, and more).
Architecture highlights:
IToolProvider— plug-in interface for tool sources. Implement one method to expose your tools to the agent.IToolCatalog/IToolRegistrar— ISP-compliant read/write split. The catalog is the shared store; the registrar handles provider lifecycle.IToolExpander— session-aware lazy expansion. Only default tools are loaded at session creation; additional tools are loaded on-demand viaexpand_tools(supports both explicit load-by-name and keyword query modes).ToolBridgeHostedService— background service that registers providers at startup and refreshes them on surface changes.
🔒 Deadlock & Race Condition Fixes
Two subtle concurrency bugs were discovered and resolved during tool bridge development:
- Tool handler deadlock — calling
ResumeSessionAsyncfrom inside a tool handler deadlocked because the CLI blocks on the tool result via JSON-RPC. Replaced with deferred sync that callsResumeSessionbefore the nextSendAsync. - Abort race condition — the concurrency gate and stream CTS are now released atomically, preventing "already has an active run" errors. The UI disposes the event subscription before awaiting server-side abort for instant feedback.
🏠 Tilde Path Expansion
--mind and --new-mind arguments now expand a leading ~ to the user's home directory, so --mind ~/src/ernist works as expected on all platforms.
📐 Design Refinements
ToolBridgedecomposed into three focused types:ToolCatalogStore(shared data),ToolBridge(read),ToolRegistrar(write)SessionHolderupgraded from nullable property toTaskCompletionSourcefor thread-safe session bindingCallerRegistry.TryReleaseTOCTOU race fixed (try/catchSemaphoreFullException)ToolExpandercleaned up — vestigial gateway client and session holder parameters removed
📊 By the Numbers
- 52 tasks across 4 implementation phases
- Built with strict TDD (red → green → refactor) throughout
Full Changelog: v0.7.2...v0.8.0
v0.7.2
What's New
🔄 Silent Token Refresh & MSAL Cache Persistence
Authentication tokens now refresh silently in the background — no more unexpected login prompts mid-session. MSAL token cache is persisted so tokens survive gateway restarts.
🛡️ Graceful Auth-Free Mode
Entra ID authentication is now fully conditional. When no AzureAd:ClientId is configured, the gateway starts cleanly in local-only mode without crashing. This fixes IDW10106 errors that occurred when running as a dotnet tool without an app registration, and resolves appsettings.json not being found when ContentRootPath defaulted to CWD instead of the assembly directory.
Full Changelog: v0.7.0...v0.7.2
v0.7.0
What's New
🔐 Entra ID Authentication
MsClaw Gateway now supports Microsoft Entra ID (Azure AD) authentication end-to-end. The SignalR hub, OpenResponses endpoint, and chat UI are all protected behind JWT bearer auth. A new CLI-driven login flow (msclaw auth login) replaces the earlier browser-redirect approach — run it once, and the token is cached in ~/.msclaw/config.json for subsequent sessions.
🌐 Dev Tunnel Remote Access
Need to reach your agent from another machine? The gateway can now optionally spin up a persistent dev tunnel at startup, giving you a public URL with authentication baked in. Tunnel access defaults to private (owner-only), and the MSAL redirect URI is dynamically resolved so login works seamlessly through the tunnel.
🏗️ Major Code Health Refactoring
This release includes a significant code quality pass across the entire codebase:
MindPathsshared constants — canonical directory and file names in one place- Process leak fix in
MindReader(properusing, stderr capture, exit code checks) - God-class breakups —
StartCommandsplit into extension methods + banner builder;GatewayHostedServicesplit intoGatewayClientProxy - Session TTL with timer-based reaping added to
SessionPool(2 new tests) - Bounded channel on
SessionEventBridge(500 slots) to prevent unbounded memory growth - Extracted helper methods across
CliLocator,MindScaffold,MindValidator,IdentityLoader, andTunnelManager
📊 By the Numbers
- 146 tests passing (up from 107 in v0.5.4)
- Copilot SDK updated to 0.1.32
Full Changelog: v0.5.4...v0.7.0
v0.5.4
v0.5.0
What's Changed
Full Changelog: v0.4.0...v0.5.0
v0.4.0
v0.3.2
What's Changed
- Add bundled TUI chat scripts (pwsh + bash) by @Copilot in #11
- Resolve Copilot CLI from system PATH via CliLocator by @Copilot in #12
New Contributors
- @Copilot made their first contribution in #11
Full Changelog: v0.3.1...v0.3.2
