diff --git a/README.md b/README.md index e4de615..a77ed5c 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Install or disable them dynamically with the `/plugin` command — enabling you - [security-guidance](./plugins/security-guidance) ### Workflow Orchestration +- [weft](./plugins/weft) - [angelos-symbo](./plugins/angelos-symbo) - [ceo-quality-controller-agent](./plugins/ceo-quality-controller-agent) - [claude-desktop-extension](./plugins/claude-desktop-extension) diff --git a/plugins/weft/.claude-plugin/marketplace.json b/plugins/weft/.claude-plugin/marketplace.json new file mode 100644 index 0000000..0d40c0a --- /dev/null +++ b/plugins/weft/.claude-plugin/marketplace.json @@ -0,0 +1,13 @@ +{ + "name": "dioptx-weft", + "owner": { + "name": "dioptx" + }, + "plugins": [ + { + "name": "weft", + "source": "./", + "description": "Deterministic workflow tracking with event-sourced logs for Claude Code" + } + ] +} diff --git a/plugins/weft/.claude-plugin/plugin.json b/plugins/weft/.claude-plugin/plugin.json new file mode 100644 index 0000000..4c79865 --- /dev/null +++ b/plugins/weft/.claude-plugin/plugin.json @@ -0,0 +1,5 @@ +{ + "name": "weft", + "version": "0.3.0", + "description": "Deterministic workflow tracking with event-sourced logs for Claude Code" +} diff --git a/plugins/weft/LICENSE b/plugins/weft/LICENSE new file mode 100644 index 0000000..5b9b12b --- /dev/null +++ b/plugins/weft/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 dioptx + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/weft/README.md b/plugins/weft/README.md new file mode 100644 index 0000000..48c736e --- /dev/null +++ b/plugins/weft/README.md @@ -0,0 +1,23 @@ +# weft + +**Deterministic workflow tracking for Claude Code — event-sourced state machine, smart skills, template management.** + +→ [dioptx/weft](https://github.com/dioptx/weft) (MIT, Python stdlib only, 191 tests) + +## Install + +``` +/plugin marketplace add dioptx/weft +/plugin install weft@dioptx-weft +``` + +## What it gives you + +- 11 slash commands (`/wf-start`, `/wf-step`, `/wf-status`, `/wf-rebuild`, `/wf-compose`, `/wf-dashboard`, etc.) +- 4 hooks (`SessionStart`, `PreToolUse`, `PreCompact`, `Stop`) +- 2 bundled templates (`generic`, `feature-workflow`) + custom-template authoring via heredoc +- Event-sourced state under `.claude/weft/events.jsonl` — fully reconstructible after compaction or restart + +## Demos + +See [the upstream README](https://github.com/dioptx/weft#readme) for 5 reproducible asciinema GIFs covering pitch, walkthrough, compose, extend, and audit. diff --git a/plugins/weft/core/__init__.py b/plugins/weft/core/__init__.py new file mode 100644 index 0000000..2455e30 --- /dev/null +++ b/plugins/weft/core/__init__.py @@ -0,0 +1,24 @@ +"""Weft — deterministic workflow tracking for Claude Code.""" + +import os +from datetime import datetime, timezone +from pathlib import Path + + +def weft_dir(project_dir: str | None = None) -> Path: + """Return the weft data directory for the given project.""" + base = project_dir or os.environ.get("CLAUDE_PROJECT_DIR", ".") + return Path(base) / ".claude" / "weft" + + +def now_iso() -> str: + """ISO 8601 UTC timestamp with millisecond precision.""" + now = datetime.now(timezone.utc) + return now.strftime("%Y-%m-%dT%H:%M:%S.") + f"{now.microsecond // 1000:03d}Z" + + +def now_dt_and_iso() -> tuple[datetime, str]: + """Return both the datetime and ISO string from a single now() call.""" + now = datetime.now(timezone.utc) + iso = now.strftime("%Y-%m-%dT%H:%M:%S.") + f"{now.microsecond // 1000:03d}Z" + return now, iso diff --git a/plugins/weft/core/cli.py b/plugins/weft/core/cli.py new file mode 100755 index 0000000..e14a18e --- /dev/null +++ b/plugins/weft/core/cli.py @@ -0,0 +1,354 @@ +#!/usr/bin/env python3 +"""Unified CLI entry point for weft. + +Usage: + python3 cli.py start