Compare commits
2 Commits
e4ad2e0475
...
0dbccee979
| Author | SHA1 | Date | |
|---|---|---|---|
| 0dbccee979 | |||
| b56f7def02 |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "taiga-auto-sync",
|
||||
"version": "0.1.0",
|
||||
"description": "Injects IT Infra & Ops Taiga tracking rules on every Claude prompt.",
|
||||
"version": "0.1.0+codex.20260829130430",
|
||||
"description": "Automatically tracks material IT Infra & Ops work and guards Taiga writes.",
|
||||
"author": { "name": "Senkensha" },
|
||||
"hooks": "./hooks/claude-codex-hooks.json"
|
||||
}
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
{
|
||||
"name": "taiga-auto-sync",
|
||||
"version": "0.1.0",
|
||||
"description": "Injects Taiga tracking rules on every Codex prompt.",
|
||||
"version": "0.1.0+codex.20260829130430",
|
||||
"description": "Automatically tracks material IT Infra & Ops work and guards Taiga writes.",
|
||||
"author": {
|
||||
"name": "Local developer"
|
||||
},
|
||||
"hooks": "./hooks/claude-codex-hooks.json",
|
||||
"skills": "./skills/",
|
||||
"interface": {
|
||||
"displayName": "Taiga Auto Sync",
|
||||
"shortDescription": "Automatic Taiga tracking reminder.",
|
||||
"longDescription": "Injects the IT Infra & Ops Taiga contract before each prompt.",
|
||||
"shortDescription": "Automatic Infra/Ops Taiga tracking.",
|
||||
"longDescription": "Tracks material IT Infra & Ops work by context and validates Taiga writes.",
|
||||
"developerName": "Local developer",
|
||||
"category": "Productivity",
|
||||
"capabilities": ["Lifecycle hooks"],
|
||||
"capabilities": [
|
||||
"Skills",
|
||||
"Lifecycle hooks"
|
||||
],
|
||||
"defaultPrompt": "Help me use Taiga Auto Sync."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
{
|
||||
"hooks": {
|
||||
"UserPromptSubmit": [{
|
||||
"PreToolUse": [{
|
||||
"matcher": "^mcp__taiga__(user_story|task|issue)_create$",
|
||||
"hooks": [{
|
||||
"type": "command",
|
||||
"command": "sh \"${CLAUDE_PLUGIN_ROOT}/hooks/taiga-reminder.sh\"",
|
||||
"command": "python3 \"${CLAUDE_PLUGIN_ROOT}/hooks/taiga-write-guard.py\"",
|
||||
"timeout": 3,
|
||||
"statusMessage": "Checking Taiga tracking..."
|
||||
"statusMessage": "Checking Taiga item metadata..."
|
||||
}]
|
||||
}]
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
cat <<'EOF'
|
||||
TAIGA AUTO-SYNC: For material IT Infra & Ops work, create or update the matching Taiga item now through the scoped launcher. Do not track read-only/no-op work. A new User Story must use the Wiki description template; preserve its state file for progress, blocked, and verified done updates.
|
||||
EOF
|
||||
58
plugins/taiga-auto-sync/hooks/taiga-write-guard.py
Normal file
58
plugins/taiga-auto-sync/hooks/taiga-write-guard.py
Normal file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Reject Taiga item creation without the active-item metadata contract."""
|
||||
import json
|
||||
import sys
|
||||
|
||||
AREAS = {
|
||||
"infra", "network", "cloud", "security", "backup", "monitoring",
|
||||
"access", "automation", "support", "vendor",
|
||||
}
|
||||
|
||||
|
||||
def missing_fields(payload):
|
||||
item = payload.get("tool_input", {})
|
||||
tags = set(item.get("tags") or [])
|
||||
missing = []
|
||||
if not item.get("assigned_to"):
|
||||
missing.append("owner")
|
||||
if not item.get("milestone"):
|
||||
missing.append("current sprint")
|
||||
if not tags.intersection(AREAS):
|
||||
missing.append("area tag")
|
||||
if not any(tag.startswith("source:") for tag in tags):
|
||||
missing.append("source tag")
|
||||
if not any(tag.startswith(("repo:", "system:")) for tag in tags):
|
||||
missing.append("target tag")
|
||||
return missing
|
||||
|
||||
|
||||
def result(payload):
|
||||
missing = missing_fields(payload)
|
||||
if not missing:
|
||||
return None
|
||||
return {
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "PreToolUse",
|
||||
"permissionDecision": "deny",
|
||||
"permissionDecisionReason": (
|
||||
"Taiga item creation requires " + ", ".join(missing) +
|
||||
". Resolve or create the current WIB sprint first."
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
if sys.argv[1:] == ["--self-check"]:
|
||||
assert result({"tool_input": {"assigned_to": 1, "milestone": 1,
|
||||
"tags": ["infra", "source:codex", "repo:brain"]}}) is None
|
||||
assert result({"tool_input": {"tags": []}})
|
||||
print("self-check: ok")
|
||||
return
|
||||
output = result(json.load(sys.stdin))
|
||||
if output:
|
||||
print(json.dumps(output))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
15
plugins/taiga-auto-sync/skills/taiga-operations/SKILL.md
Normal file
15
plugins/taiga-auto-sync/skills/taiga-operations/SKILL.md
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
name: taiga-operations
|
||||
description: Automatically track material IT Infrastructure & Operations implementation in Taiga, including deploys, incidents, maintenance, access, backup, monitoring, and infrastructure changes. Do not use for read-only questions, exploration, status explanations, or unrelated product work.
|
||||
---
|
||||
|
||||
# Taiga Operations
|
||||
|
||||
Use this workflow automatically when the prompt requests material IT Infra & Ops work. The user does not need to ask for a Taiga update.
|
||||
|
||||
1. Do not create or update Taiga for reading, investigation without a change, planning only, no-op work, or secrets.
|
||||
2. Before creating or activating an item, find the sprint that covers today in WIB. If none exists, create the Monday–Sunday `YYYY-WNN Operations` sprint, then use it.
|
||||
3. Find an existing matching open item before creating a new one. Reuse its local state reference when available.
|
||||
4. Classify a standalone daily operation as an Issue. Use one User Story only for one outcome with two or more related Tasks; create those Tasks beneath it.
|
||||
5. Every active User Story, Task, and Issue needs an owner, current sprint, one area tag, one `source:<agent>` tag, and one `repo:<name>` or `system:<name>` tag.
|
||||
6. Use the Wiki template for the selected item type. Record only material `start`, `progress`, `blocked`, and verified `done` events. Never put credentials or sensitive evidence in Taiga or local state.
|
||||
Reference in New Issue
Block a user