From 92a026fd74c7a1e83cd20b9ab1ab437d16a48f9d Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 22 Mar 2026 10:46:25 +0000 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20add=20/sprint=20skill=20=E2=80=94?= =?UTF-8?q?=20Odoo=20Project=20+=20GitHub=20approval=20integration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sprint & task management skill that connects to Odoo Project for task tracking and uses GitHub Issues for approval workflows (content review + deploy approval), avoiding direct calls to production Odoo for notifications. Commands: /sprint, /sprint add, /sprint new, /sprint close, /sprint approve, /sprint review, /sprint report https://claude.ai/code/session_01K1VcDbXz1uCxoGikqWSqup --- .agents/skills/gstack-sprint/SKILL.md | 729 +++++++++++++++++++++++++ .agents/skills/gstack/SKILL.md | 1 + SKILL.md | 1 + SKILL.md.tmpl | 1 + sprint/SKILL.md | 738 ++++++++++++++++++++++++++ sprint/SKILL.md.tmpl | 534 +++++++++++++++++++ 6 files changed, 2004 insertions(+) create mode 100644 .agents/skills/gstack-sprint/SKILL.md create mode 100644 sprint/SKILL.md create mode 100644 sprint/SKILL.md.tmpl diff --git a/.agents/skills/gstack-sprint/SKILL.md b/.agents/skills/gstack-sprint/SKILL.md new file mode 100644 index 000000000..06077b459 --- /dev/null +++ b/.agents/skills/gstack-sprint/SKILL.md @@ -0,0 +1,729 @@ +--- +name: sprint +description: | + Sprint & task management via Odoo Project. Create tasks, track sprints, + send approval requests, and view dashboards — all from terminal. + Use when asked to "manage tasks", "create sprint", "add task", "sprint status", + "send for approval", or "close sprint". + Proactively suggest when the user mentions task management or sprint planning. +--- + + + +## Preamble (run first) + +```bash +_UPD=$(~/.codex/skills/gstack/bin/gstack-update-check 2>/dev/null || .agents/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +[ -n "$_UPD" ] && echo "$_UPD" || true +mkdir -p ~/.gstack/sessions +touch ~/.gstack/sessions/"$PPID" +_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') +find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true +_CONTRIB=$(~/.codex/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.codex/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") +echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" +_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") +echo "LAKE_INTRO: $_LAKE_SEEN" +_TEL=$(~/.codex/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") +_TEL_START=$(date +%s) +_SESSION_ID="$$-$(date +%s)" +echo "TELEMETRY: ${_TEL:-off}" +echo "TEL_PROMPTED: $_TEL_PROMPTED" +mkdir -p ~/.gstack/analytics +echo '{"skill":"sprint","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.codex/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +``` + +If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke +them when the user explicitly asks. The user opted out of proactive suggestions. + +If output shows `UPGRADE_AVAILABLE `: read `~/.codex/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. + +If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. +Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete +thing when AI makes the marginal cost near-zero. Read more: https://garryslist.org/posts/boil-the-ocean" +Then offer to open the essay in their default browser: + +```bash +open https://garryslist.org/posts/boil-the-ocean +touch ~/.gstack/.completeness-intro-seen +``` + +Only run `open` if the user says yes. Always run `touch` to mark as seen. This only happens once. + +If `TEL_PROMPTED` is `no` AND `LAKE_INTRO` is `yes`: After the lake intro is handled, +ask the user about telemetry. Use AskUserQuestion: + +> Help gstack get better! Community mode shares usage data (which skills you use, how long +> they take, crash info) with a stable device ID so we can track trends and fix bugs faster. +> No code, file paths, or repo names are ever sent. +> Change anytime with `gstack-config set telemetry off`. + +Options: +- A) Help gstack get better! (recommended) +- B) No thanks + +If A: run `~/.codex/skills/gstack/bin/gstack-config set telemetry community` + +If B: ask a follow-up AskUserQuestion: + +> How about anonymous mode? We just learn that *someone* used gstack — no unique ID, +> no way to connect sessions. Just a counter that helps us know if anyone's out there. + +Options: +- A) Sure, anonymous is fine +- B) No thanks, fully off + +If B→A: run `~/.codex/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.codex/skills/gstack/bin/gstack-config set telemetry off` + +Always run: +```bash +touch ~/.gstack/.telemetry-prompted +``` + +This only happens once. If `TEL_PROMPTED` is `yes`, skip this entirely. + +## AskUserQuestion Format + +**ALWAYS follow this structure for every AskUserQuestion call:** +1. **Re-ground:** State the project, the current branch (use the `_BRANCH` value printed by the preamble — NOT any branch from conversation history or gitStatus), and the current plan/task. (1-2 sentences) +2. **Simplify:** Explain the problem in plain English a smart 16-year-old could follow. No raw function names, no internal jargon, no implementation details. Use concrete examples and analogies. Say what it DOES, not what it's called. +3. **Recommend:** `RECOMMENDATION: Choose [X] because [one-line reason]` — always prefer the complete option over shortcuts (see Completeness Principle). Include `Completeness: X/10` for each option. Calibration: 10 = complete implementation (all edge cases, full coverage), 7 = covers happy path but skips some edges, 3 = shortcut that defers significant work. If both options are 8+, pick the higher; if one is ≤5, flag it. +4. **Options:** Lettered options: `A) ... B) ... C) ...` — when an option involves effort, show both scales: `(human: ~X / CC: ~Y)` + +Assume the user hasn't looked at this window in 20 minutes and doesn't have the code open. If you'd need to read the source to understand your own explanation, it's too complex. + +Per-skill instructions may add additional formatting rules on top of this baseline. + +## Completeness Principle — Boil the Lake + +AI-assisted coding makes the marginal cost of completeness near-zero. When you present options: + +- If Option A is the complete implementation (full parity, all edge cases, 100% coverage) and Option B is a shortcut that saves modest effort — **always recommend A**. The delta between 80 lines and 150 lines is meaningless with CC+gstack. "Good enough" is the wrong instinct when "complete" costs minutes more. +- **Lake vs. ocean:** A "lake" is boilable — 100% test coverage for a module, full feature implementation, handling all edge cases, complete error paths. An "ocean" is not — rewriting an entire system from scratch, adding features to dependencies you don't control, multi-quarter platform migrations. Recommend boiling lakes. Flag oceans as out of scope. +- **When estimating effort**, always show both scales: human team time and CC+gstack time. The compression ratio varies by task type — use this reference: + +| Task type | Human team | CC+gstack | Compression | +|-----------|-----------|-----------|-------------| +| Boilerplate / scaffolding | 2 days | 15 min | ~100x | +| Test writing | 1 day | 15 min | ~50x | +| Feature implementation | 1 week | 30 min | ~30x | +| Bug fix + regression test | 4 hours | 15 min | ~20x | +| Architecture / design | 2 days | 4 hours | ~5x | +| Research / exploration | 1 day | 3 hours | ~3x | + +- This principle applies to test coverage, error handling, documentation, edge cases, and feature completeness. Don't skip the last 10% to "save time" — with AI, that 10% costs seconds. + +**Anti-patterns — DON'T do this:** +- BAD: "Choose B — it covers 90% of the value with less code." (If A is only 70 lines more, choose A.) +- BAD: "We can skip edge case handling to save time." (Edge case handling costs minutes with CC.) +- BAD: "Let's defer test coverage to a follow-up PR." (Tests are the cheapest lake to boil.) +- BAD: Quoting only human-team effort: "This would take 2 weeks." (Say: "2 weeks human / ~1 hour CC.") + +## Contributor Mode + +If `_CONTRIB` is `true`: you are in **contributor mode**. You're a gstack user who also helps make it better. + +**At the end of each major workflow step** (not after every single command), reflect on the gstack tooling you used. Rate your experience 0 to 10. If it wasn't a 10, think about why. If there is an obvious, actionable bug OR an insightful, interesting thing that could have been done better by gstack code or skill markdown — file a field report. Maybe our contributor will help make us better! + +**Calibration — this is the bar:** For example, `$B js "await fetch(...)"` used to fail with `SyntaxError: await is only valid in async functions` because gstack didn't wrap expressions in async context. Small, but the input was reasonable and gstack should have handled it — that's the kind of thing worth filing. Things less consequential than this, ignore. + +**NOT worth filing:** user's app bugs, network errors to user's URL, auth failures on user's site, user's own JS logic bugs. + +**To file:** write `~/.gstack/contributor-logs/{slug}.md` with **all sections below** (do not truncate — include every section through the Date/Version footer): + +``` +# {Title} + +Hey gstack team — ran into this while using /{skill-name}: + +**What I was trying to do:** {what the user/agent was attempting} +**What happened instead:** {what actually happened} +**My rating:** {0-10} — {one sentence on why it wasn't a 10} + +## Steps to reproduce +1. {step} + +## Raw output +``` +{paste the actual error or unexpected output here} +``` + +## What would make this a 10 +{one sentence: what gstack should have done differently} + +**Date:** {YYYY-MM-DD} | **Version:** {gstack version} | **Skill:** /{skill} +``` + +Slug: lowercase, hyphens, max 60 chars (e.g. `browse-js-no-await`). Skip if file already exists. Max 3 reports per session. File inline and continue — don't stop the workflow. Tell user: "Filed gstack field report: {title}" + +## Completion Status Protocol + +When completing a skill workflow, report status using one of: +- **DONE** — All steps completed successfully. Evidence provided for each claim. +- **DONE_WITH_CONCERNS** — Completed, but with issues the user should know about. List each concern. +- **BLOCKED** — Cannot proceed. State what is blocking and what was tried. +- **NEEDS_CONTEXT** — Missing information required to continue. State exactly what you need. + +### Escalation + +It is always OK to stop and say "this is too hard for me" or "I'm not confident in this result." + +Bad work is worse than no work. You will not be penalized for escalating. +- If you have attempted a task 3 times without success, STOP and escalate. +- If you are uncertain about a security-sensitive change, STOP and escalate. +- If the scope of work exceeds what you can verify, STOP and escalate. + +Escalation format: +``` +STATUS: BLOCKED | NEEDS_CONTEXT +REASON: [1-2 sentences] +ATTEMPTED: [what you tried] +RECOMMENDATION: [what the user should do next] +``` + +## Telemetry (run last) + +After the skill workflow completes (success, error, or abort), log the telemetry event. +Determine the skill name from the `name:` field in this file's YAML frontmatter. +Determine the outcome from the workflow result (success if completed normally, error +if it failed, abort if the user interrupted). + +**PLAN MODE EXCEPTION — ALWAYS RUN:** This command writes telemetry to +`~/.gstack/analytics/` (user config directory, not project files). The skill +preamble already writes to the same directory — this is the same pattern. +Skipping this command loses session duration and outcome data. + +Run this bash: + +```bash +_TEL_END=$(date +%s) +_TEL_DUR=$(( _TEL_END - _TEL_START )) +rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true +~/.codex/skills/gstack/bin/gstack-telemetry-log \ + --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ + --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & +``` + +Replace `SKILL_NAME` with the actual skill name from frontmatter, `OUTCOME` with +success/error/abort, and `USED_BROWSE` with true/false based on whether `$B` was used. +If you cannot determine the outcome, use "unknown". This runs in the background and +never blocks the user. + +# /sprint — Sprint & Task Management (Odoo Integration) + +Manage sprints and tasks via Odoo Project API. Supports task creation, sprint tracking, +approval workflows, and notifications — all through Odoo's built-in systems. + +## User-invocable + +When the user types `/sprint`, run this skill. + +## Arguments + +- `/sprint` — show current sprint dashboard +- `/sprint setup` — configure Odoo connection +- `/sprint add ` — create a new task in current sprint +- `/sprint new [name]` — start a new sprint (milestone) +- `/sprint close` — close current sprint with summary report +- `/sprint approve ` — send task for approval via Odoo chatter +- `/sprint review` — list tasks pending approval +- `/sprint report` — generate sprint report + +## Step 0: Load Odoo Config + +Check for existing Odoo configuration: + +```bash +cat ~/.gstack/odoo-config.json 2>/dev/null || echo "NOT_CONFIGURED" +``` + +If `NOT_CONFIGURED`, jump to **Setup Flow**. Otherwise, load the config values +(url, db, api_key, uid, project_id) and proceed with the requested command. + +## Setup Flow (triggered by `/sprint setup` or first run) + +Guide the user through Odoo API configuration: + +1. Ask for their Odoo instance URL (e.g., `https://odoo.mycompany.com`) +2. Ask for database name +3. Ask for API key (Settings → Users → API Keys in Odoo) +4. Ask for their Odoo user ID (uid) + +Then verify the connection: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.project", "search_read", [[]], {"fields": ["name", "id"], "limit": 20}] + } + }' +``` + +Show the list of projects and ask the user to pick one. Then save config: + +```bash +mkdir -p ~/.gstack +cat > ~/.gstack/odoo-config.json << 'CONFIGEOF' +{ + "url": "", + "db": "", + "uid": , + "api_key": "", + "project_id": , + "project_name": "" +} +CONFIGEOF +chmod 600 ~/.gstack/odoo-config.json +``` + +Confirm setup is complete and show the user their selected project. + +## Odoo API Helper + +All Odoo operations use JSON-RPC. The pattern for every call: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "", "", [], ] + } + }' +``` + +Replace ``, ``, ``, `` based on the operation. + +## Command: Dashboard (default — `/sprint`) + +Show the current sprint status by querying Odoo tasks: + +```bash +# 1. Get current sprint (latest milestone) +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.milestone", "search_read", + [[["project_id", "=", ], ["is_reached", "=", false]]], + {"fields": ["name", "id", "deadline"], "order": "create_date desc", "limit": 1} + ] + } + }' +``` + +```bash +# 2. Get all tasks in current sprint, grouped by stage +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "search_read", + [[["project_id", "=", ], ["milestone_id", "=", ]]], + {"fields": ["name", "id", "stage_id", "user_ids", "priority", "date_deadline", "tag_ids"], "order": "stage_id, priority desc"} + ] + } + }' +``` + +Format the output as a clean dashboard: + +``` +╔══════════════════════════════════════════════════╗ +║ Sprint: | Deadline: ║ +╠══════════════════════════════════════════════════╣ +║ ║ +║ 📋 New (3) ║ +║ #42 Setup CI/CD pipeline ★★ ║ +║ #43 Design landing page ★ ║ +║ #44 Write API docs ★ ║ +║ ║ +║ 🔄 In Progress (2) ║ +║ #40 User authentication ★★★ ║ +║ #41 Database migrations ★★ ║ +║ ║ +║ ✅ Done (5) ║ +║ #35 Project setup ★ ║ +║ ... ║ +║ ║ +║ Progress: ████████░░ 50% (5/10) ║ +╚══════════════════════════════════════════════════╝ +``` + +## Command: Add Task (`/sprint add `) + +Parse the description from the argument. Create a task in Odoo: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "create", + [{"name": "", "project_id": , "milestone_id": , "user_ids": []}], + {} + ] + } + }' +``` + +After creating, confirm with the task ID and link: +``` +Task # created: "" +Sprint: | Assigned to: you +Link: /web#id=&model=project.task&view_type=form +``` + +**Batch mode:** If the user provides multiple tasks (comma-separated or multi-line), +create all of them in sequence and show a summary table. + +## Command: New Sprint (`/sprint new [name]`) + +1. If no name given, ask the user for a sprint name +2. Ask for deadline (default: 2 weeks from today) +3. Create a milestone in Odoo: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.milestone", "create", + [{"name": "", "project_id": , "deadline": ""}], + {} + ] + } + }' +``` + +4. Confirm creation and show the new sprint in dashboard format + +## Command: Close Sprint (`/sprint close`) + +1. Get current sprint tasks and compute stats: + - Total tasks + - Completed vs incomplete + - Tasks by priority + +2. If there are incomplete tasks, ask: + - Move to next sprint? + - Mark as cancelled? + - Leave in current sprint? + +3. Mark milestone as reached: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.milestone", "write", + [[], {"is_reached": true}], + {} + ] + } + }' +``` + +4. Generate sprint report (see Report command) + +5. Ask if user wants to create the next sprint immediately + +## Command: Approve (`/sprint approve `) + +Send an approval request via **GitHub Issues** (avoids touching Odoo production for notifications): + +1. First, get task details from Odoo to build the approval context: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "read", + [[]], + {"fields": ["name", "description", "stage_id", "user_ids"]} + ] + } + }' +``` + +2. Create a GitHub Issue for the approval request: + +```bash +gh issue create \ + --title "🔍 Approval: " \ + --label "approval,sprint" \ + --body "$(cat <<'EOF' +## Approval Required + +**Odoo Task:** # +**Sprint:** +**Odoo Link:** /web#id=&model=project.task&view_type=form + +### Details + + +### Action needed +- [ ] Reviewed +- [ ] Approved + +Please comment with your approval or feedback. +Close this issue once approved. +EOF +)" +``` + +3. Update the Odoo task stage to "Review" so it's visible in both systems: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "write", + [[], {"stage_id": }], + {} + ] + } + }' +``` + +4. Confirm: "Approval request created as GitHub Issue. Odoo task moved to Review stage." + +GitHub notifications will handle alerting reviewers — no need to call Odoo's +mail system directly. + +## Command: Review (`/sprint review`) + +List pending approvals from **both** GitHub Issues and Odoo: + +```bash +# GitHub: open approval issues +gh issue list --label "approval" --state open --json number,title,createdAt,url +``` + +```bash +# Odoo: tasks in Review stage +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "search_read", + [[["project_id", "=", ], ["stage_id.name", "ilike", "review"]]], + {"fields": ["name", "id", "stage_id", "date_last_stage_update"], "order": "date_last_stage_update desc"} + ] + } + }' +``` + +Display combined review queue: +``` +Pending Approval: + GH #12 🔍 Approval: Setup CI/CD pipeline — opened Mar 20 + GH #15 🔍 Approval: Landing page design — opened Mar 19 + +Odoo tasks in Review: + #42 Setup CI/CD pipeline — since Mar 20 + #45 Landing page design — since Mar 19 + +No pending approvals? All clear! +``` + +## Command: Report (`/sprint report`) + +Generate a sprint summary report: + +1. Query all tasks in the current (or most recently closed) sprint +2. Compute metrics: + - Total tasks completed vs planned + - Completion rate + - Average task cycle time (created → done) + - Tasks by priority breakdown + - Velocity (tasks/sprint) + +3. Format as: + +``` +Sprint Report: +━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Period: Mar 8 – Mar 22, 2026 + +Completion: 8/10 tasks (80%) +Velocity: 8 tasks/sprint + +By Priority: + ★★★ Critical: 2/2 done + ★★ High: 3/4 done (1 carried over) + ★ Normal: 3/4 done (1 cancelled) + +Carried Over → Next Sprint: + #41 Database migrations (★★) + +Highlights: + - Shipped user auth end-to-end + - CI/CD pipeline fully automated + - Landing page live + +Blockers encountered: + - API rate limiting on 3rd party service (resolved) +``` + +4. Save report locally: + +```bash +mkdir -p ~/.gstack/sprint-reports +``` + +Use the Write tool to save a JSON snapshot to `~/.gstack/sprint-reports/-.json`. + +## Content Approval Flow + +When the user asks to approve content (blog posts, docs, marketing material): + +1. Ask for the content file path or paste +2. Create a task in Odoo with the content summary in the description +3. Create a GitHub Issue with `approval,content` labels containing the full content +4. If content is a file in the repo, reference the file path in the issue body + +```bash +gh issue create \ + --title "📝 Content Review: " \ + --label "approval,content,sprint" \ + --body "$(cat <<'EOF' +## Content Review Required + +**Type:** +**Odoo Task:** # +**File:** `` (if applicable) + +### Content + + +### Checklist +- [ ] Content accuracy reviewed +- [ ] Grammar/spelling checked +- [ ] Approved for publishing + +Please comment with feedback or close when approved. +EOF +)" +``` + +5. Confirm with links to both the GitHub Issue and Odoo task + +## Deploy Approval Flow + +When the user wants deploy approval: + +1. Gather deploy context automatically: + +```bash +# Get branch, PR, and change summary +BRANCH=$(git branch --show-current) +gh pr view --json title,number,url,additions,deletions,changedFiles 2>/dev/null || echo "NO_PR" +git diff --stat origin/$(gh repo view --json defaultBranchRef -q .defaultBranchRef.name)...HEAD +``` + +2. Create a GitHub Issue with deploy context: + +```bash +gh issue create \ + --title "🚀 Deploy Approval: " \ + --label "approval,deploy,sprint" \ + --body "$(cat <<'EOF' +## Deploy Approval Required + +**Branch:** +**PR:** (if exists) +**Changes:** files, +/- + +### Changed files + + +### Tests + + +### Checklist +- [ ] Code reviewed +- [ ] Tests passing +- [ ] Approved for production + +Close this issue to confirm deployment approval. +EOF +)" +``` + +3. Create/update corresponding Odoo task with deploy details +4. Tell the user: "Deploy approval created on GitHub. Close the issue when approved, then proceed with deployment." + +## Tone + +- Concise, action-oriented +- Show task IDs and links for easy reference +- Use visual formatting (tables, progress bars) for dashboards +- Confirm every action with what was created/updated +- If Odoo API errors occur, show the error and suggest fixes (wrong API key, network, permissions) + +## Important Rules + +- NEVER store Odoo passwords — only API keys (stored in ~/.gstack/odoo-config.json with 600 permissions) +- Always verify Odoo connection before operations +- Handle API errors gracefully — show the raw error if debugging is needed +- All dates in user's local timezone +- Task IDs always prefixed with # for readability +- Config file at ~/.gstack/odoo-config.json — never commit to repos + +## Telemetry + +```bash +mkdir -p ~/.gstack/analytics +echo '{"skill":"sprint","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename $(pwd))'","cmd":""}' >> ~/.gstack/analytics/skill-usage.jsonl +``` diff --git a/.agents/skills/gstack/SKILL.md b/.agents/skills/gstack/SKILL.md index 4bb9ba170..b44fe3284 100644 --- a/.agents/skills/gstack/SKILL.md +++ b/.agents/skills/gstack/SKILL.md @@ -26,6 +26,7 @@ description: | - Want to scope edits to one module/directory → suggest /freeze - Maximum safety mode (destructive warnings + edit restrictions) → suggest /guard - Removing edit restrictions → suggest /unfreeze + - Sprint/task management or Odoo integration → suggest /sprint - Upgrading gstack to latest version → suggest /gstack-upgrade If the user pushes back on skill suggestions ("stop suggesting things", diff --git a/SKILL.md b/SKILL.md index 46b7a558b..5a8997903 100644 --- a/SKILL.md +++ b/SKILL.md @@ -27,6 +27,7 @@ description: | - Want to scope edits to one module/directory → suggest /freeze - Maximum safety mode (destructive warnings + edit restrictions) → suggest /guard - Removing edit restrictions → suggest /unfreeze + - Sprint/task management or Odoo integration → suggest /sprint - Upgrading gstack to latest version → suggest /gstack-upgrade If the user pushes back on skill suggestions ("stop suggesting things", diff --git a/SKILL.md.tmpl b/SKILL.md.tmpl index 0c9859655..886fe8193 100644 --- a/SKILL.md.tmpl +++ b/SKILL.md.tmpl @@ -27,6 +27,7 @@ description: | - Want to scope edits to one module/directory → suggest /freeze - Maximum safety mode (destructive warnings + edit restrictions) → suggest /guard - Removing edit restrictions → suggest /unfreeze + - Sprint/task management or Odoo integration → suggest /sprint - Upgrading gstack to latest version → suggest /gstack-upgrade If the user pushes back on skill suggestions ("stop suggesting things", diff --git a/sprint/SKILL.md b/sprint/SKILL.md new file mode 100644 index 000000000..cb6d162af --- /dev/null +++ b/sprint/SKILL.md @@ -0,0 +1,738 @@ +--- +name: sprint +version: 1.0.0 +description: | + Sprint & task management via Odoo Project. Create tasks, track sprints, + send approval requests, and view dashboards — all from terminal. + Use when asked to "manage tasks", "create sprint", "add task", "sprint status", + "send for approval", or "close sprint". + Proactively suggest when the user mentions task management or sprint planning. +allowed-tools: + - Bash + - Read + - Write + - Glob + - Grep + - AskUserQuestion + - WebSearch +--- + + + +## Preamble (run first) + +```bash +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +[ -n "$_UPD" ] && echo "$_UPD" || true +mkdir -p ~/.gstack/sessions +touch ~/.gstack/sessions/"$PPID" +_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') +find ~/.gstack/sessions -mmin +120 -type f -delete 2>/dev/null || true +_CONTRIB=$(~/.claude/skills/gstack/bin/gstack-config get gstack_contributor 2>/dev/null || true) +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") +echo "BRANCH: $_BRANCH" +echo "PROACTIVE: $_PROACTIVE" +_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") +echo "LAKE_INTRO: $_LAKE_SEEN" +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") +_TEL_START=$(date +%s) +_SESSION_ID="$$-$(date +%s)" +echo "TELEMETRY: ${_TEL:-off}" +echo "TEL_PROMPTED: $_TEL_PROMPTED" +mkdir -p ~/.gstack/analytics +echo '{"skill":"sprint","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true +for _PF in ~/.gstack/analytics/.pending-*; do [ -f "$_PF" ] && ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true; break; done +``` + +If `PROACTIVE` is `"false"`, do not proactively suggest gstack skills — only invoke +them when the user explicitly asks. The user opted out of proactive suggestions. + +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If `JUST_UPGRADED `: tell user "Running gstack v{to} (just updated!)" and continue. + +If `LAKE_INTRO` is `no`: Before continuing, introduce the Completeness Principle. +Tell the user: "gstack follows the **Boil the Lake** principle — always do the complete +thing when AI makes the marginal cost near-zero. Read more: https://garryslist.org/posts/boil-the-ocean" +Then offer to open the essay in their default browser: + +```bash +open https://garryslist.org/posts/boil-the-ocean +touch ~/.gstack/.completeness-intro-seen +``` + +Only run `open` if the user says yes. Always run `touch` to mark as seen. This only happens once. + +If `TEL_PROMPTED` is `no` AND `LAKE_INTRO` is `yes`: After the lake intro is handled, +ask the user about telemetry. Use AskUserQuestion: + +> Help gstack get better! Community mode shares usage data (which skills you use, how long +> they take, crash info) with a stable device ID so we can track trends and fix bugs faster. +> No code, file paths, or repo names are ever sent. +> Change anytime with `gstack-config set telemetry off`. + +Options: +- A) Help gstack get better! (recommended) +- B) No thanks + +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` + +If B: ask a follow-up AskUserQuestion: + +> How about anonymous mode? We just learn that *someone* used gstack — no unique ID, +> no way to connect sessions. Just a counter that helps us know if anyone's out there. + +Options: +- A) Sure, anonymous is fine +- B) No thanks, fully off + +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` + +Always run: +```bash +touch ~/.gstack/.telemetry-prompted +``` + +This only happens once. If `TEL_PROMPTED` is `yes`, skip this entirely. + +## AskUserQuestion Format + +**ALWAYS follow this structure for every AskUserQuestion call:** +1. **Re-ground:** State the project, the current branch (use the `_BRANCH` value printed by the preamble — NOT any branch from conversation history or gitStatus), and the current plan/task. (1-2 sentences) +2. **Simplify:** Explain the problem in plain English a smart 16-year-old could follow. No raw function names, no internal jargon, no implementation details. Use concrete examples and analogies. Say what it DOES, not what it's called. +3. **Recommend:** `RECOMMENDATION: Choose [X] because [one-line reason]` — always prefer the complete option over shortcuts (see Completeness Principle). Include `Completeness: X/10` for each option. Calibration: 10 = complete implementation (all edge cases, full coverage), 7 = covers happy path but skips some edges, 3 = shortcut that defers significant work. If both options are 8+, pick the higher; if one is ≤5, flag it. +4. **Options:** Lettered options: `A) ... B) ... C) ...` — when an option involves effort, show both scales: `(human: ~X / CC: ~Y)` + +Assume the user hasn't looked at this window in 20 minutes and doesn't have the code open. If you'd need to read the source to understand your own explanation, it's too complex. + +Per-skill instructions may add additional formatting rules on top of this baseline. + +## Completeness Principle — Boil the Lake + +AI-assisted coding makes the marginal cost of completeness near-zero. When you present options: + +- If Option A is the complete implementation (full parity, all edge cases, 100% coverage) and Option B is a shortcut that saves modest effort — **always recommend A**. The delta between 80 lines and 150 lines is meaningless with CC+gstack. "Good enough" is the wrong instinct when "complete" costs minutes more. +- **Lake vs. ocean:** A "lake" is boilable — 100% test coverage for a module, full feature implementation, handling all edge cases, complete error paths. An "ocean" is not — rewriting an entire system from scratch, adding features to dependencies you don't control, multi-quarter platform migrations. Recommend boiling lakes. Flag oceans as out of scope. +- **When estimating effort**, always show both scales: human team time and CC+gstack time. The compression ratio varies by task type — use this reference: + +| Task type | Human team | CC+gstack | Compression | +|-----------|-----------|-----------|-------------| +| Boilerplate / scaffolding | 2 days | 15 min | ~100x | +| Test writing | 1 day | 15 min | ~50x | +| Feature implementation | 1 week | 30 min | ~30x | +| Bug fix + regression test | 4 hours | 15 min | ~20x | +| Architecture / design | 2 days | 4 hours | ~5x | +| Research / exploration | 1 day | 3 hours | ~3x | + +- This principle applies to test coverage, error handling, documentation, edge cases, and feature completeness. Don't skip the last 10% to "save time" — with AI, that 10% costs seconds. + +**Anti-patterns — DON'T do this:** +- BAD: "Choose B — it covers 90% of the value with less code." (If A is only 70 lines more, choose A.) +- BAD: "We can skip edge case handling to save time." (Edge case handling costs minutes with CC.) +- BAD: "Let's defer test coverage to a follow-up PR." (Tests are the cheapest lake to boil.) +- BAD: Quoting only human-team effort: "This would take 2 weeks." (Say: "2 weeks human / ~1 hour CC.") + +## Contributor Mode + +If `_CONTRIB` is `true`: you are in **contributor mode**. You're a gstack user who also helps make it better. + +**At the end of each major workflow step** (not after every single command), reflect on the gstack tooling you used. Rate your experience 0 to 10. If it wasn't a 10, think about why. If there is an obvious, actionable bug OR an insightful, interesting thing that could have been done better by gstack code or skill markdown — file a field report. Maybe our contributor will help make us better! + +**Calibration — this is the bar:** For example, `$B js "await fetch(...)"` used to fail with `SyntaxError: await is only valid in async functions` because gstack didn't wrap expressions in async context. Small, but the input was reasonable and gstack should have handled it — that's the kind of thing worth filing. Things less consequential than this, ignore. + +**NOT worth filing:** user's app bugs, network errors to user's URL, auth failures on user's site, user's own JS logic bugs. + +**To file:** write `~/.gstack/contributor-logs/{slug}.md` with **all sections below** (do not truncate — include every section through the Date/Version footer): + +``` +# {Title} + +Hey gstack team — ran into this while using /{skill-name}: + +**What I was trying to do:** {what the user/agent was attempting} +**What happened instead:** {what actually happened} +**My rating:** {0-10} — {one sentence on why it wasn't a 10} + +## Steps to reproduce +1. {step} + +## Raw output +``` +{paste the actual error or unexpected output here} +``` + +## What would make this a 10 +{one sentence: what gstack should have done differently} + +**Date:** {YYYY-MM-DD} | **Version:** {gstack version} | **Skill:** /{skill} +``` + +Slug: lowercase, hyphens, max 60 chars (e.g. `browse-js-no-await`). Skip if file already exists. Max 3 reports per session. File inline and continue — don't stop the workflow. Tell user: "Filed gstack field report: {title}" + +## Completion Status Protocol + +When completing a skill workflow, report status using one of: +- **DONE** — All steps completed successfully. Evidence provided for each claim. +- **DONE_WITH_CONCERNS** — Completed, but with issues the user should know about. List each concern. +- **BLOCKED** — Cannot proceed. State what is blocking and what was tried. +- **NEEDS_CONTEXT** — Missing information required to continue. State exactly what you need. + +### Escalation + +It is always OK to stop and say "this is too hard for me" or "I'm not confident in this result." + +Bad work is worse than no work. You will not be penalized for escalating. +- If you have attempted a task 3 times without success, STOP and escalate. +- If you are uncertain about a security-sensitive change, STOP and escalate. +- If the scope of work exceeds what you can verify, STOP and escalate. + +Escalation format: +``` +STATUS: BLOCKED | NEEDS_CONTEXT +REASON: [1-2 sentences] +ATTEMPTED: [what you tried] +RECOMMENDATION: [what the user should do next] +``` + +## Telemetry (run last) + +After the skill workflow completes (success, error, or abort), log the telemetry event. +Determine the skill name from the `name:` field in this file's YAML frontmatter. +Determine the outcome from the workflow result (success if completed normally, error +if it failed, abort if the user interrupted). + +**PLAN MODE EXCEPTION — ALWAYS RUN:** This command writes telemetry to +`~/.gstack/analytics/` (user config directory, not project files). The skill +preamble already writes to the same directory — this is the same pattern. +Skipping this command loses session duration and outcome data. + +Run this bash: + +```bash +_TEL_END=$(date +%s) +_TEL_DUR=$(( _TEL_END - _TEL_START )) +rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true +~/.claude/skills/gstack/bin/gstack-telemetry-log \ + --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ + --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & +``` + +Replace `SKILL_NAME` with the actual skill name from frontmatter, `OUTCOME` with +success/error/abort, and `USED_BROWSE` with true/false based on whether `$B` was used. +If you cannot determine the outcome, use "unknown". This runs in the background and +never blocks the user. + +# /sprint — Sprint & Task Management (Odoo Integration) + +Manage sprints and tasks via Odoo Project API. Supports task creation, sprint tracking, +approval workflows, and notifications — all through Odoo's built-in systems. + +## User-invocable + +When the user types `/sprint`, run this skill. + +## Arguments + +- `/sprint` — show current sprint dashboard +- `/sprint setup` — configure Odoo connection +- `/sprint add ` — create a new task in current sprint +- `/sprint new [name]` — start a new sprint (milestone) +- `/sprint close` — close current sprint with summary report +- `/sprint approve ` — send task for approval via Odoo chatter +- `/sprint review` — list tasks pending approval +- `/sprint report` — generate sprint report + +## Step 0: Load Odoo Config + +Check for existing Odoo configuration: + +```bash +cat ~/.gstack/odoo-config.json 2>/dev/null || echo "NOT_CONFIGURED" +``` + +If `NOT_CONFIGURED`, jump to **Setup Flow**. Otherwise, load the config values +(url, db, api_key, uid, project_id) and proceed with the requested command. + +## Setup Flow (triggered by `/sprint setup` or first run) + +Guide the user through Odoo API configuration: + +1. Ask for their Odoo instance URL (e.g., `https://odoo.mycompany.com`) +2. Ask for database name +3. Ask for API key (Settings → Users → API Keys in Odoo) +4. Ask for their Odoo user ID (uid) + +Then verify the connection: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.project", "search_read", [[]], {"fields": ["name", "id"], "limit": 20}] + } + }' +``` + +Show the list of projects and ask the user to pick one. Then save config: + +```bash +mkdir -p ~/.gstack +cat > ~/.gstack/odoo-config.json << 'CONFIGEOF' +{ + "url": "", + "db": "", + "uid": , + "api_key": "", + "project_id": , + "project_name": "" +} +CONFIGEOF +chmod 600 ~/.gstack/odoo-config.json +``` + +Confirm setup is complete and show the user their selected project. + +## Odoo API Helper + +All Odoo operations use JSON-RPC. The pattern for every call: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "", "", [], ] + } + }' +``` + +Replace ``, ``, ``, `` based on the operation. + +## Command: Dashboard (default — `/sprint`) + +Show the current sprint status by querying Odoo tasks: + +```bash +# 1. Get current sprint (latest milestone) +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.milestone", "search_read", + [[["project_id", "=", ], ["is_reached", "=", false]]], + {"fields": ["name", "id", "deadline"], "order": "create_date desc", "limit": 1} + ] + } + }' +``` + +```bash +# 2. Get all tasks in current sprint, grouped by stage +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "search_read", + [[["project_id", "=", ], ["milestone_id", "=", ]]], + {"fields": ["name", "id", "stage_id", "user_ids", "priority", "date_deadline", "tag_ids"], "order": "stage_id, priority desc"} + ] + } + }' +``` + +Format the output as a clean dashboard: + +``` +╔══════════════════════════════════════════════════╗ +║ Sprint: | Deadline: ║ +╠══════════════════════════════════════════════════╣ +║ ║ +║ 📋 New (3) ║ +║ #42 Setup CI/CD pipeline ★★ ║ +║ #43 Design landing page ★ ║ +║ #44 Write API docs ★ ║ +║ ║ +║ 🔄 In Progress (2) ║ +║ #40 User authentication ★★★ ║ +║ #41 Database migrations ★★ ║ +║ ║ +║ ✅ Done (5) ║ +║ #35 Project setup ★ ║ +║ ... ║ +║ ║ +║ Progress: ████████░░ 50% (5/10) ║ +╚══════════════════════════════════════════════════╝ +``` + +## Command: Add Task (`/sprint add `) + +Parse the description from the argument. Create a task in Odoo: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "create", + [{"name": "", "project_id": , "milestone_id": , "user_ids": []}], + {} + ] + } + }' +``` + +After creating, confirm with the task ID and link: +``` +Task # created: "" +Sprint: | Assigned to: you +Link: /web#id=&model=project.task&view_type=form +``` + +**Batch mode:** If the user provides multiple tasks (comma-separated or multi-line), +create all of them in sequence and show a summary table. + +## Command: New Sprint (`/sprint new [name]`) + +1. If no name given, ask the user for a sprint name +2. Ask for deadline (default: 2 weeks from today) +3. Create a milestone in Odoo: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.milestone", "create", + [{"name": "", "project_id": , "deadline": ""}], + {} + ] + } + }' +``` + +4. Confirm creation and show the new sprint in dashboard format + +## Command: Close Sprint (`/sprint close`) + +1. Get current sprint tasks and compute stats: + - Total tasks + - Completed vs incomplete + - Tasks by priority + +2. If there are incomplete tasks, ask: + - Move to next sprint? + - Mark as cancelled? + - Leave in current sprint? + +3. Mark milestone as reached: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.milestone", "write", + [[], {"is_reached": true}], + {} + ] + } + }' +``` + +4. Generate sprint report (see Report command) + +5. Ask if user wants to create the next sprint immediately + +## Command: Approve (`/sprint approve `) + +Send an approval request via **GitHub Issues** (avoids touching Odoo production for notifications): + +1. First, get task details from Odoo to build the approval context: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "read", + [[]], + {"fields": ["name", "description", "stage_id", "user_ids"]} + ] + } + }' +``` + +2. Create a GitHub Issue for the approval request: + +```bash +gh issue create \ + --title "🔍 Approval: " \ + --label "approval,sprint" \ + --body "$(cat <<'EOF' +## Approval Required + +**Odoo Task:** # +**Sprint:** +**Odoo Link:** /web#id=&model=project.task&view_type=form + +### Details + + +### Action needed +- [ ] Reviewed +- [ ] Approved + +Please comment with your approval or feedback. +Close this issue once approved. +EOF +)" +``` + +3. Update the Odoo task stage to "Review" so it's visible in both systems: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "write", + [[], {"stage_id": }], + {} + ] + } + }' +``` + +4. Confirm: "Approval request created as GitHub Issue. Odoo task moved to Review stage." + +GitHub notifications will handle alerting reviewers — no need to call Odoo's +mail system directly. + +## Command: Review (`/sprint review`) + +List pending approvals from **both** GitHub Issues and Odoo: + +```bash +# GitHub: open approval issues +gh issue list --label "approval" --state open --json number,title,createdAt,url +``` + +```bash +# Odoo: tasks in Review stage +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "search_read", + [[["project_id", "=", ], ["stage_id.name", "ilike", "review"]]], + {"fields": ["name", "id", "stage_id", "date_last_stage_update"], "order": "date_last_stage_update desc"} + ] + } + }' +``` + +Display combined review queue: +``` +Pending Approval: + GH #12 🔍 Approval: Setup CI/CD pipeline — opened Mar 20 + GH #15 🔍 Approval: Landing page design — opened Mar 19 + +Odoo tasks in Review: + #42 Setup CI/CD pipeline — since Mar 20 + #45 Landing page design — since Mar 19 + +No pending approvals? All clear! +``` + +## Command: Report (`/sprint report`) + +Generate a sprint summary report: + +1. Query all tasks in the current (or most recently closed) sprint +2. Compute metrics: + - Total tasks completed vs planned + - Completion rate + - Average task cycle time (created → done) + - Tasks by priority breakdown + - Velocity (tasks/sprint) + +3. Format as: + +``` +Sprint Report: +━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Period: Mar 8 – Mar 22, 2026 + +Completion: 8/10 tasks (80%) +Velocity: 8 tasks/sprint + +By Priority: + ★★★ Critical: 2/2 done + ★★ High: 3/4 done (1 carried over) + ★ Normal: 3/4 done (1 cancelled) + +Carried Over → Next Sprint: + #41 Database migrations (★★) + +Highlights: + - Shipped user auth end-to-end + - CI/CD pipeline fully automated + - Landing page live + +Blockers encountered: + - API rate limiting on 3rd party service (resolved) +``` + +4. Save report locally: + +```bash +mkdir -p ~/.gstack/sprint-reports +``` + +Use the Write tool to save a JSON snapshot to `~/.gstack/sprint-reports/-.json`. + +## Content Approval Flow + +When the user asks to approve content (blog posts, docs, marketing material): + +1. Ask for the content file path or paste +2. Create a task in Odoo with the content summary in the description +3. Create a GitHub Issue with `approval,content` labels containing the full content +4. If content is a file in the repo, reference the file path in the issue body + +```bash +gh issue create \ + --title "📝 Content Review: " \ + --label "approval,content,sprint" \ + --body "$(cat <<'EOF' +## Content Review Required + +**Type:** +**Odoo Task:** # +**File:** `` (if applicable) + +### Content + + +### Checklist +- [ ] Content accuracy reviewed +- [ ] Grammar/spelling checked +- [ ] Approved for publishing + +Please comment with feedback or close when approved. +EOF +)" +``` + +5. Confirm with links to both the GitHub Issue and Odoo task + +## Deploy Approval Flow + +When the user wants deploy approval: + +1. Gather deploy context automatically: + +```bash +# Get branch, PR, and change summary +BRANCH=$(git branch --show-current) +gh pr view --json title,number,url,additions,deletions,changedFiles 2>/dev/null || echo "NO_PR" +git diff --stat origin/$(gh repo view --json defaultBranchRef -q .defaultBranchRef.name)...HEAD +``` + +2. Create a GitHub Issue with deploy context: + +```bash +gh issue create \ + --title "🚀 Deploy Approval: " \ + --label "approval,deploy,sprint" \ + --body "$(cat <<'EOF' +## Deploy Approval Required + +**Branch:** +**PR:** (if exists) +**Changes:** files, +/- + +### Changed files + + +### Tests + + +### Checklist +- [ ] Code reviewed +- [ ] Tests passing +- [ ] Approved for production + +Close this issue to confirm deployment approval. +EOF +)" +``` + +3. Create/update corresponding Odoo task with deploy details +4. Tell the user: "Deploy approval created on GitHub. Close the issue when approved, then proceed with deployment." + +## Tone + +- Concise, action-oriented +- Show task IDs and links for easy reference +- Use visual formatting (tables, progress bars) for dashboards +- Confirm every action with what was created/updated +- If Odoo API errors occur, show the error and suggest fixes (wrong API key, network, permissions) + +## Important Rules + +- NEVER store Odoo passwords — only API keys (stored in ~/.gstack/odoo-config.json with 600 permissions) +- Always verify Odoo connection before operations +- Handle API errors gracefully — show the raw error if debugging is needed +- All dates in user's local timezone +- Task IDs always prefixed with # for readability +- Config file at ~/.gstack/odoo-config.json — never commit to repos + +## Telemetry + +```bash +mkdir -p ~/.gstack/analytics +echo '{"skill":"sprint","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename $(pwd))'","cmd":""}' >> ~/.gstack/analytics/skill-usage.jsonl +``` diff --git a/sprint/SKILL.md.tmpl b/sprint/SKILL.md.tmpl new file mode 100644 index 000000000..5bed79693 --- /dev/null +++ b/sprint/SKILL.md.tmpl @@ -0,0 +1,534 @@ +--- +name: sprint +version: 1.0.0 +description: | + Sprint & task management via Odoo Project. Create tasks, track sprints, + send approval requests, and view dashboards — all from terminal. + Use when asked to "manage tasks", "create sprint", "add task", "sprint status", + "send for approval", or "close sprint". + Proactively suggest when the user mentions task management or sprint planning. +allowed-tools: + - Bash + - Read + - Write + - Glob + - Grep + - AskUserQuestion + - WebSearch +--- + +{{PREAMBLE}} + +# /sprint — Sprint & Task Management (Odoo Integration) + +Manage sprints and tasks via Odoo Project API. Supports task creation, sprint tracking, +approval workflows, and notifications — all through Odoo's built-in systems. + +## User-invocable + +When the user types `/sprint`, run this skill. + +## Arguments + +- `/sprint` — show current sprint dashboard +- `/sprint setup` — configure Odoo connection +- `/sprint add ` — create a new task in current sprint +- `/sprint new [name]` — start a new sprint (milestone) +- `/sprint close` — close current sprint with summary report +- `/sprint approve ` — send task for approval via Odoo chatter +- `/sprint review` — list tasks pending approval +- `/sprint report` — generate sprint report + +## Step 0: Load Odoo Config + +Check for existing Odoo configuration: + +```bash +cat ~/.gstack/odoo-config.json 2>/dev/null || echo "NOT_CONFIGURED" +``` + +If `NOT_CONFIGURED`, jump to **Setup Flow**. Otherwise, load the config values +(url, db, api_key, uid, project_id) and proceed with the requested command. + +## Setup Flow (triggered by `/sprint setup` or first run) + +Guide the user through Odoo API configuration: + +1. Ask for their Odoo instance URL (e.g., `https://odoo.mycompany.com`) +2. Ask for database name +3. Ask for API key (Settings → Users → API Keys in Odoo) +4. Ask for their Odoo user ID (uid) + +Then verify the connection: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.project", "search_read", [[]], {"fields": ["name", "id"], "limit": 20}] + } + }' +``` + +Show the list of projects and ask the user to pick one. Then save config: + +```bash +mkdir -p ~/.gstack +cat > ~/.gstack/odoo-config.json << 'CONFIGEOF' +{ + "url": "", + "db": "", + "uid": , + "api_key": "", + "project_id": , + "project_name": "" +} +CONFIGEOF +chmod 600 ~/.gstack/odoo-config.json +``` + +Confirm setup is complete and show the user their selected project. + +## Odoo API Helper + +All Odoo operations use JSON-RPC. The pattern for every call: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "", "", [], ] + } + }' +``` + +Replace ``, ``, ``, `` based on the operation. + +## Command: Dashboard (default — `/sprint`) + +Show the current sprint status by querying Odoo tasks: + +```bash +# 1. Get current sprint (latest milestone) +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.milestone", "search_read", + [[["project_id", "=", ], ["is_reached", "=", false]]], + {"fields": ["name", "id", "deadline"], "order": "create_date desc", "limit": 1} + ] + } + }' +``` + +```bash +# 2. Get all tasks in current sprint, grouped by stage +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "search_read", + [[["project_id", "=", ], ["milestone_id", "=", ]]], + {"fields": ["name", "id", "stage_id", "user_ids", "priority", "date_deadline", "tag_ids"], "order": "stage_id, priority desc"} + ] + } + }' +``` + +Format the output as a clean dashboard: + +``` +╔══════════════════════════════════════════════════╗ +║ Sprint: | Deadline: ║ +╠══════════════════════════════════════════════════╣ +║ ║ +║ 📋 New (3) ║ +║ #42 Setup CI/CD pipeline ★★ ║ +║ #43 Design landing page ★ ║ +║ #44 Write API docs ★ ║ +║ ║ +║ 🔄 In Progress (2) ║ +║ #40 User authentication ★★★ ║ +║ #41 Database migrations ★★ ║ +║ ║ +║ ✅ Done (5) ║ +║ #35 Project setup ★ ║ +║ ... ║ +║ ║ +║ Progress: ████████░░ 50% (5/10) ║ +╚══════════════════════════════════════════════════╝ +``` + +## Command: Add Task (`/sprint add `) + +Parse the description from the argument. Create a task in Odoo: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "create", + [{"name": "", "project_id": , "milestone_id": , "user_ids": []}], + {} + ] + } + }' +``` + +After creating, confirm with the task ID and link: +``` +Task # created: "" +Sprint: | Assigned to: you +Link: /web#id=&model=project.task&view_type=form +``` + +**Batch mode:** If the user provides multiple tasks (comma-separated or multi-line), +create all of them in sequence and show a summary table. + +## Command: New Sprint (`/sprint new [name]`) + +1. If no name given, ask the user for a sprint name +2. Ask for deadline (default: 2 weeks from today) +3. Create a milestone in Odoo: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.milestone", "create", + [{"name": "", "project_id": , "deadline": ""}], + {} + ] + } + }' +``` + +4. Confirm creation and show the new sprint in dashboard format + +## Command: Close Sprint (`/sprint close`) + +1. Get current sprint tasks and compute stats: + - Total tasks + - Completed vs incomplete + - Tasks by priority + +2. If there are incomplete tasks, ask: + - Move to next sprint? + - Mark as cancelled? + - Leave in current sprint? + +3. Mark milestone as reached: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.milestone", "write", + [[], {"is_reached": true}], + {} + ] + } + }' +``` + +4. Generate sprint report (see Report command) + +5. Ask if user wants to create the next sprint immediately + +## Command: Approve (`/sprint approve `) + +Send an approval request via **GitHub Issues** (avoids touching Odoo production for notifications): + +1. First, get task details from Odoo to build the approval context: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "read", + [[]], + {"fields": ["name", "description", "stage_id", "user_ids"]} + ] + } + }' +``` + +2. Create a GitHub Issue for the approval request: + +```bash +gh issue create \ + --title "🔍 Approval: " \ + --label "approval,sprint" \ + --body "$(cat <<'EOF' +## Approval Required + +**Odoo Task:** # +**Sprint:** +**Odoo Link:** /web#id=&model=project.task&view_type=form + +### Details + + +### Action needed +- [ ] Reviewed +- [ ] Approved + +Please comment with your approval or feedback. +Close this issue once approved. +EOF +)" +``` + +3. Update the Odoo task stage to "Review" so it's visible in both systems: + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "write", + [[], {"stage_id": }], + {} + ] + } + }' +``` + +4. Confirm: "Approval request created as GitHub Issue. Odoo task moved to Review stage." + +GitHub notifications will handle alerting reviewers — no need to call Odoo's +mail system directly. + +## Command: Review (`/sprint review`) + +List pending approvals from **both** GitHub Issues and Odoo: + +```bash +# GitHub: open approval issues +gh issue list --label "approval" --state open --json number,title,createdAt,url +``` + +```bash +# Odoo: tasks in Review stage +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "search_read", + [[["project_id", "=", ], ["stage_id.name", "ilike", "review"]]], + {"fields": ["name", "id", "stage_id", "date_last_stage_update"], "order": "date_last_stage_update desc"} + ] + } + }' +``` + +Display combined review queue: +``` +Pending Approval: + GH #12 🔍 Approval: Setup CI/CD pipeline — opened Mar 20 + GH #15 🔍 Approval: Landing page design — opened Mar 19 + +Odoo tasks in Review: + #42 Setup CI/CD pipeline — since Mar 20 + #45 Landing page design — since Mar 19 + +No pending approvals? All clear! +``` + +## Command: Report (`/sprint report`) + +Generate a sprint summary report: + +1. Query all tasks in the current (or most recently closed) sprint +2. Compute metrics: + - Total tasks completed vs planned + - Completion rate + - Average task cycle time (created → done) + - Tasks by priority breakdown + - Velocity (tasks/sprint) + +3. Format as: + +``` +Sprint Report: +━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Period: Mar 8 – Mar 22, 2026 + +Completion: 8/10 tasks (80%) +Velocity: 8 tasks/sprint + +By Priority: + ★★★ Critical: 2/2 done + ★★ High: 3/4 done (1 carried over) + ★ Normal: 3/4 done (1 cancelled) + +Carried Over → Next Sprint: + #41 Database migrations (★★) + +Highlights: + - Shipped user auth end-to-end + - CI/CD pipeline fully automated + - Landing page live + +Blockers encountered: + - API rate limiting on 3rd party service (resolved) +``` + +4. Save report locally: + +```bash +mkdir -p ~/.gstack/sprint-reports +``` + +Use the Write tool to save a JSON snapshot to `~/.gstack/sprint-reports/-.json`. + +## Content Approval Flow + +When the user asks to approve content (blog posts, docs, marketing material): + +1. Ask for the content file path or paste +2. Create a task in Odoo with the content summary in the description +3. Create a GitHub Issue with `approval,content` labels containing the full content +4. If content is a file in the repo, reference the file path in the issue body + +```bash +gh issue create \ + --title "📝 Content Review: " \ + --label "approval,content,sprint" \ + --body "$(cat <<'EOF' +## Content Review Required + +**Type:** +**Odoo Task:** # +**File:** `` (if applicable) + +### Content + + +### Checklist +- [ ] Content accuracy reviewed +- [ ] Grammar/spelling checked +- [ ] Approved for publishing + +Please comment with feedback or close when approved. +EOF +)" +``` + +5. Confirm with links to both the GitHub Issue and Odoo task + +## Deploy Approval Flow + +When the user wants deploy approval: + +1. Gather deploy context automatically: + +```bash +# Get branch, PR, and change summary +BRANCH=$(git branch --show-current) +gh pr view --json title,number,url,additions,deletions,changedFiles 2>/dev/null || echo "NO_PR" +git diff --stat origin/$(gh repo view --json defaultBranchRef -q .defaultBranchRef.name)...HEAD +``` + +2. Create a GitHub Issue with deploy context: + +```bash +gh issue create \ + --title "🚀 Deploy Approval: " \ + --label "approval,deploy,sprint" \ + --body "$(cat <<'EOF' +## Deploy Approval Required + +**Branch:** +**PR:** (if exists) +**Changes:** files, +/- + +### Changed files + + +### Tests + + +### Checklist +- [ ] Code reviewed +- [ ] Tests passing +- [ ] Approved for production + +Close this issue to confirm deployment approval. +EOF +)" +``` + +3. Create/update corresponding Odoo task with deploy details +4. Tell the user: "Deploy approval created on GitHub. Close the issue when approved, then proceed with deployment." + +## Tone + +- Concise, action-oriented +- Show task IDs and links for easy reference +- Use visual formatting (tables, progress bars) for dashboards +- Confirm every action with what was created/updated +- If Odoo API errors occur, show the error and suggest fixes (wrong API key, network, permissions) + +## Important Rules + +- NEVER store Odoo passwords — only API keys (stored in ~/.gstack/odoo-config.json with 600 permissions) +- Always verify Odoo connection before operations +- Handle API errors gracefully — show the raw error if debugging is needed +- All dates in user's local timezone +- Task IDs always prefixed with # for readability +- Config file at ~/.gstack/odoo-config.json — never commit to repos + +## Telemetry + +```bash +mkdir -p ~/.gstack/analytics +echo '{"skill":"sprint","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename $(pwd))'","cmd":""}' >> ~/.gstack/analytics/skill-usage.jsonl +``` From 9a0919035d513e07ca28f9ea677d3f775f430a25 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 22 Mar 2026 10:47:02 +0000 Subject: [PATCH 2/8] chore: regenerate gstack-retro codex SKILL.md Picked up existing template changes during codex generation. https://claude.ai/code/session_01K1VcDbXz1uCxoGikqWSqup --- .agents/skills/gstack-retro/SKILL.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.agents/skills/gstack-retro/SKILL.md b/.agents/skills/gstack-retro/SKILL.md index 2a30b5273..5d17bf2bf 100644 --- a/.agents/skills/gstack-retro/SKILL.md +++ b/.agents/skills/gstack-retro/SKILL.md @@ -428,7 +428,7 @@ From commit diffs, estimate PR sizes and bucket them: - **Small** (<100 LOC) - **Medium** (100-500 LOC) - **Large** (500-1500 LOC) -- **XL** (1500+ LOC) — flag these with file counts +- **XL** (1500+ LOC) ### Step 8: Focus Score + Ship of the Week @@ -620,14 +620,13 @@ Narrative interpreting what the team-wide patterns mean: Narrative covering: - Commit type mix and what it reveals -- PR size discipline (are PRs staying small?) +- PR size distribution and what it reveals about shipping cadence - Fix-chain detection (sequences of fix commits on the same subsystem) - Version bump discipline ### Code Quality Signals - Test LOC ratio trend - Hotspot analysis (are the same files churning?) -- Any XL PRs that should have been split - Greptile signal ratio and trend (if history exists): "Greptile: X% signal (Y valid catches, Z false positives)" ### Test Health @@ -666,7 +665,7 @@ For each teammate (sorted by commits descending), write a section: - "Fixed the N+1 query that was causing 2s load times on the dashboard" - **Opportunity for growth**: 1 specific, constructive suggestion. Frame as investment, not criticism. Examples: - "Test coverage on the payment module is at 8% — worth investing in before the next feature lands on top of it" - - "3 of the 5 PRs were 800+ LOC — breaking these up would catch issues earlier and make review easier" + - "Most commits land in a single burst — spacing work across the day could reduce context-switching fatigue" - "All commits land between 1-4am — sustainable pace matters for code quality long-term" **AI collaboration note:** If many commits have `Co-Authored-By` AI trailers (e.g., Claude, Copilot), note the AI-assisted commit percentage as a team metric. Frame it neutrally — "N% of commits were AI-assisted" — without judgment. From acb77c7395fae642f9ae2e49280b6f6f5dba8401 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 22 Mar 2026 11:00:22 +0000 Subject: [PATCH 3/8] feat: add naming convention + Odoo/GitHub dual sync to /sprint - Naming: [SPRINT-XX] type: description (feat/fix/content/deploy/chore/design) - Tasks created in both Odoo Project and GitHub Issues - Milestones synced: Odoo milestone + GitHub milestone - Sprint close closes both milestones - Dashboard shows both OD# and GH# IDs - Config stores github_repo and current_sprint number https://claude.ai/code/session_01K1VcDbXz1uCxoGikqWSqup --- .agents/skills/gstack-sprint/SKILL.md | 192 ++++++++++++++++++------- sprint/SKILL.md | 194 +++++++++++++++++++------- sprint/SKILL.md.tmpl | 194 +++++++++++++++++++------- 3 files changed, 428 insertions(+), 152 deletions(-) diff --git a/.agents/skills/gstack-sprint/SKILL.md b/.agents/skills/gstack-sprint/SKILL.md index 06077b459..666f2d81b 100644 --- a/.agents/skills/gstack-sprint/SKILL.md +++ b/.agents/skills/gstack-sprint/SKILL.md @@ -1,10 +1,10 @@ --- name: sprint description: | - Sprint & task management via Odoo Project. Create tasks, track sprints, - send approval requests, and view dashboards — all from terminal. - Use when asked to "manage tasks", "create sprint", "add task", "sprint status", - "send for approval", or "close sprint". + Sprint & task management with dual sync: Odoo Project + GitHub Issues/Milestones. + Naming convention: [SPRINT-XX] type: description. Tasks created in both systems. + Approvals via GitHub Issues. Use when asked to "manage tasks", "create sprint", + "add task", "sprint status", "send for approval", or "close sprint". Proactively suggest when the user mentions task management or sprint planning. --- @@ -214,10 +214,36 @@ success/error/abort, and `USED_BROWSE` with true/false based on whether `$B` was If you cannot determine the outcome, use "unknown". This runs in the background and never blocks the user. -# /sprint — Sprint & Task Management (Odoo Integration) +# /sprint — Sprint & Task Management (Odoo + GitHub Sync) -Manage sprints and tasks via Odoo Project API. Supports task creation, sprint tracking, -approval workflows, and notifications — all through Odoo's built-in systems. +Manage sprints and tasks with **dual sync** between Odoo Project and GitHub. +Tasks are created in both systems with consistent naming. Approvals go through +GitHub Issues. Sprint tracking via Odoo milestones + GitHub Milestones. + +## Naming Convention + +All tasks follow this format: + +``` +[SPRINT-XX] type: description +``` + +**Types:** + +| Prefix | Dùng cho | Ví dụ | +|--------|----------|-------| +| `feat:` | Tính năng mới | `[SPRINT-01] feat: User authentication` | +| `fix:` | Bug fix | `[SPRINT-01] fix: Login redirect loop` | +| `content:` | Nội dung cần review | `[SPRINT-01] content: Blog post Q1 review` | +| `deploy:` | Deploy approval | `[SPRINT-01] deploy: Release v2.0` | +| `chore:` | Infra, vận hành | `[SPRINT-01] chore: Setup monitoring` | +| `design:` | Design/UI | `[SPRINT-01] design: Landing page mockup` | + +The sprint number auto-increments. When parsing user input for `/sprint add`, +detect if they included a type prefix. If not, ask or default to `feat:`. + +The naming convention is enforced on **both** Odoo task names and GitHub Issue titles +to keep the two systems in sync. ## User-invocable @@ -270,7 +296,17 @@ curl -s -X POST "/jsonrpc" \ }' ``` -Show the list of projects and ask the user to pick one. Then save config: +Show the list of projects and ask the user to pick one. + +5. Detect the GitHub repo for sync: + +```bash +gh repo view --json nameWithOwner -q .nameWithOwner +``` + +6. Ask for the current sprint number (default: 1). This is used for the `[SPRINT-XX]` prefix. + +7. Save config: ```bash mkdir -p ~/.gstack @@ -281,13 +317,16 @@ cat > ~/.gstack/odoo-config.json << 'CONFIGEOF' "uid": , "api_key": "", "project_id": , - "project_name": "" + "project_name": "", + "github_repo": "", + "current_sprint": , + "sprint_prefix": "SPRINT" } CONFIGEOF chmod 600 ~/.gstack/odoo-config.json ``` -Confirm setup is complete and show the user their selected project. +Confirm setup is complete and show the user their selected project and GitHub repo. ## Odoo API Helper @@ -349,33 +388,41 @@ curl -s -X POST "/jsonrpc" \ }' ``` -Format the output as a clean dashboard: +Format the output as a clean dashboard with naming convention: ``` -╔══════════════════════════════════════════════════╗ -║ Sprint: | Deadline: ║ -╠══════════════════════════════════════════════════╣ -║ ║ -║ 📋 New (3) ║ -║ #42 Setup CI/CD pipeline ★★ ║ -║ #43 Design landing page ★ ║ -║ #44 Write API docs ★ ║ -║ ║ -║ 🔄 In Progress (2) ║ -║ #40 User authentication ★★★ ║ -║ #41 Database migrations ★★ ║ -║ ║ -║ ✅ Done (5) ║ -║ #35 Project setup ★ ║ -║ ... ║ -║ ║ -║ Progress: ████████░░ 50% (5/10) ║ -╚══════════════════════════════════════════════════╝ +╔══════════════════════════════════════════════════════════════╗ +║ Sprint 01 | Deadline: Mar 22, 2026 ║ +║ Odoo: | GitHub: ║ +╠══════════════════════════════════════════════════════════════╣ +║ ║ +║ 📋 New (3) ║ +║ OD#42 GH#12 [SPRINT-01] feat: Setup CI/CD ★★ ║ +║ OD#43 GH#13 [SPRINT-01] design: Landing page ★ ║ +║ OD#44 GH#14 [SPRINT-01] chore: Write API docs ★ ║ +║ ║ +║ 🔄 In Progress (2) ║ +║ OD#40 GH#10 [SPRINT-01] feat: User auth ★★★ ║ +║ OD#41 GH#11 [SPRINT-01] feat: DB migrations ★★ ║ +║ ║ +║ ✅ Done (5) ║ +║ OD#35 GH#5 [SPRINT-01] chore: Project setup ★ ║ +║ ... ║ +║ ║ +║ Progress: ████████░░ 50% (5/10) ║ +╚══════════════════════════════════════════════════════════════╝ ``` +`OD#` = Odoo task ID, `GH#` = GitHub Issue number. Both are clickable links when shown in terminal. + ## Command: Add Task (`/sprint add `) -Parse the description from the argument. Create a task in Odoo: +Parse the description from the argument. Apply naming convention: + +1. If user input has no type prefix, ask or default to `feat:` +2. Format task name: `[SPRINT-XX] type: description` + +**Step 1: Create task in Odoo:** ```bash curl -s -X POST "/jsonrpc" \ @@ -387,28 +434,53 @@ curl -s -X POST "/jsonrpc" \ "service": "object", "method": "execute_kw", "args": ["", , "", "project.task", "create", - [{"name": "", "project_id": , "milestone_id": , "user_ids": []}], + [{"name": "[SPRINT-XX] type: description", "project_id": , "milestone_id": , "user_ids": []}], {} ] } }' ``` -After creating, confirm with the task ID and link: +**Step 2: Create matching GitHub Issue:** + +```bash +gh issue create \ + --title "[SPRINT-XX] type: description" \ + --label "sprint-XX,type" \ + --milestone "Sprint XX" \ + --body "$(cat <<'EOF' +**Odoo Task:** # +**Sprint:** Sprint XX +**Odoo Link:** /web#id=&model=project.task&view_type=form + +--- + +EOF +)" +``` + +If the GitHub Milestone "Sprint XX" doesn't exist yet, create it first: +```bash +gh api repos///milestones -f title="Sprint XX" -f due_on="" ``` -Task # created: "" -Sprint: | Assigned to: you -Link: /web#id=&model=project.task&view_type=form + +**Step 3: Confirm with IDs from both systems:** +``` +Task created (synced): + Odoo: #/web#id=&model=project.task + GitHub: # + Name: [SPRINT-XX] type: description ``` **Batch mode:** If the user provides multiple tasks (comma-separated or multi-line), -create all of them in sequence and show a summary table. +create all of them in sequence and show a summary table with both Odoo + GitHub IDs. ## Command: New Sprint (`/sprint new [name]`) -1. If no name given, ask the user for a sprint name +1. If no name given, auto-generate: `Sprint XX` (increment from config's `current_sprint`) 2. Ask for deadline (default: 2 weeks from today) -3. Create a milestone in Odoo: + +**Step 1: Create milestone in Odoo:** ```bash curl -s -X POST "/jsonrpc" \ @@ -420,28 +492,38 @@ curl -s -X POST "/jsonrpc" \ "service": "object", "method": "execute_kw", "args": ["", , "", "project.milestone", "create", - [{"name": "", "project_id": , "deadline": ""}], + [{"name": "Sprint XX", "project_id": , "deadline": ""}], {} ] } }' ``` -4. Confirm creation and show the new sprint in dashboard format +**Step 2: Create matching GitHub Milestone:** + +```bash +gh api repos///milestones \ + -f title="Sprint XX" \ + -f due_on="T23:59:59Z" \ + -f description="Sprint XX — created via /sprint" +``` + +**Step 3: Update config** — increment `current_sprint` in `~/.gstack/odoo-config.json` + +**Step 4: Confirm creation** and show the new sprint in dashboard format with links to both systems ## Command: Close Sprint (`/sprint close`) -1. Get current sprint tasks and compute stats: - - Total tasks - - Completed vs incomplete - - Tasks by priority +1. Get current sprint tasks from **both** systems and compute stats: + - Total tasks, completed vs incomplete + - Tasks by priority and type 2. If there are incomplete tasks, ask: - - Move to next sprint? - - Mark as cancelled? + - Move to next sprint? (updates both Odoo milestone + GitHub milestone) + - Mark as cancelled? (closes GitHub issue with "cancelled" label) - Leave in current sprint? -3. Mark milestone as reached: +3. **Close Odoo milestone:** ```bash curl -s -X POST "/jsonrpc" \ @@ -460,9 +542,19 @@ curl -s -X POST "/jsonrpc" \ }' ``` -4. Generate sprint report (see Report command) +4. **Close GitHub milestone:** + +```bash +# Get milestone number +gh api repos///milestones --jq '.[] | select(.title=="Sprint XX") | .number' + +# Close it +gh api repos///milestones/ -X PATCH -f state="closed" +``` + +5. Generate sprint report (see Report command) -5. Ask if user wants to create the next sprint immediately +6. Ask if user wants to create the next sprint immediately ## Command: Approve (`/sprint approve `) diff --git a/sprint/SKILL.md b/sprint/SKILL.md index cb6d162af..265b20aad 100644 --- a/sprint/SKILL.md +++ b/sprint/SKILL.md @@ -1,11 +1,11 @@ --- name: sprint -version: 1.0.0 +version: 1.1.0 description: | - Sprint & task management via Odoo Project. Create tasks, track sprints, - send approval requests, and view dashboards — all from terminal. - Use when asked to "manage tasks", "create sprint", "add task", "sprint status", - "send for approval", or "close sprint". + Sprint & task management with dual sync: Odoo Project + GitHub Issues/Milestones. + Naming convention: [SPRINT-XX] type: description. Tasks created in both systems. + Approvals via GitHub Issues. Use when asked to "manage tasks", "create sprint", + "add task", "sprint status", "send for approval", or "close sprint". Proactively suggest when the user mentions task management or sprint planning. allowed-tools: - Bash @@ -223,10 +223,36 @@ success/error/abort, and `USED_BROWSE` with true/false based on whether `$B` was If you cannot determine the outcome, use "unknown". This runs in the background and never blocks the user. -# /sprint — Sprint & Task Management (Odoo Integration) +# /sprint — Sprint & Task Management (Odoo + GitHub Sync) -Manage sprints and tasks via Odoo Project API. Supports task creation, sprint tracking, -approval workflows, and notifications — all through Odoo's built-in systems. +Manage sprints and tasks with **dual sync** between Odoo Project and GitHub. +Tasks are created in both systems with consistent naming. Approvals go through +GitHub Issues. Sprint tracking via Odoo milestones + GitHub Milestones. + +## Naming Convention + +All tasks follow this format: + +``` +[SPRINT-XX] type: description +``` + +**Types:** + +| Prefix | Dùng cho | Ví dụ | +|--------|----------|-------| +| `feat:` | Tính năng mới | `[SPRINT-01] feat: User authentication` | +| `fix:` | Bug fix | `[SPRINT-01] fix: Login redirect loop` | +| `content:` | Nội dung cần review | `[SPRINT-01] content: Blog post Q1 review` | +| `deploy:` | Deploy approval | `[SPRINT-01] deploy: Release v2.0` | +| `chore:` | Infra, vận hành | `[SPRINT-01] chore: Setup monitoring` | +| `design:` | Design/UI | `[SPRINT-01] design: Landing page mockup` | + +The sprint number auto-increments. When parsing user input for `/sprint add`, +detect if they included a type prefix. If not, ask or default to `feat:`. + +The naming convention is enforced on **both** Odoo task names and GitHub Issue titles +to keep the two systems in sync. ## User-invocable @@ -279,7 +305,17 @@ curl -s -X POST "/jsonrpc" \ }' ``` -Show the list of projects and ask the user to pick one. Then save config: +Show the list of projects and ask the user to pick one. + +5. Detect the GitHub repo for sync: + +```bash +gh repo view --json nameWithOwner -q .nameWithOwner +``` + +6. Ask for the current sprint number (default: 1). This is used for the `[SPRINT-XX]` prefix. + +7. Save config: ```bash mkdir -p ~/.gstack @@ -290,13 +326,16 @@ cat > ~/.gstack/odoo-config.json << 'CONFIGEOF' "uid": , "api_key": "", "project_id": , - "project_name": "" + "project_name": "", + "github_repo": "", + "current_sprint": , + "sprint_prefix": "SPRINT" } CONFIGEOF chmod 600 ~/.gstack/odoo-config.json ``` -Confirm setup is complete and show the user their selected project. +Confirm setup is complete and show the user their selected project and GitHub repo. ## Odoo API Helper @@ -358,33 +397,41 @@ curl -s -X POST "/jsonrpc" \ }' ``` -Format the output as a clean dashboard: +Format the output as a clean dashboard with naming convention: ``` -╔══════════════════════════════════════════════════╗ -║ Sprint: | Deadline: ║ -╠══════════════════════════════════════════════════╣ -║ ║ -║ 📋 New (3) ║ -║ #42 Setup CI/CD pipeline ★★ ║ -║ #43 Design landing page ★ ║ -║ #44 Write API docs ★ ║ -║ ║ -║ 🔄 In Progress (2) ║ -║ #40 User authentication ★★★ ║ -║ #41 Database migrations ★★ ║ -║ ║ -║ ✅ Done (5) ║ -║ #35 Project setup ★ ║ -║ ... ║ -║ ║ -║ Progress: ████████░░ 50% (5/10) ║ -╚══════════════════════════════════════════════════╝ +╔══════════════════════════════════════════════════════════════╗ +║ Sprint 01 | Deadline: Mar 22, 2026 ║ +║ Odoo: | GitHub: ║ +╠══════════════════════════════════════════════════════════════╣ +║ ║ +║ 📋 New (3) ║ +║ OD#42 GH#12 [SPRINT-01] feat: Setup CI/CD ★★ ║ +║ OD#43 GH#13 [SPRINT-01] design: Landing page ★ ║ +║ OD#44 GH#14 [SPRINT-01] chore: Write API docs ★ ║ +║ ║ +║ 🔄 In Progress (2) ║ +║ OD#40 GH#10 [SPRINT-01] feat: User auth ★★★ ║ +║ OD#41 GH#11 [SPRINT-01] feat: DB migrations ★★ ║ +║ ║ +║ ✅ Done (5) ║ +║ OD#35 GH#5 [SPRINT-01] chore: Project setup ★ ║ +║ ... ║ +║ ║ +║ Progress: ████████░░ 50% (5/10) ║ +╚══════════════════════════════════════════════════════════════╝ ``` +`OD#` = Odoo task ID, `GH#` = GitHub Issue number. Both are clickable links when shown in terminal. + ## Command: Add Task (`/sprint add `) -Parse the description from the argument. Create a task in Odoo: +Parse the description from the argument. Apply naming convention: + +1. If user input has no type prefix, ask or default to `feat:` +2. Format task name: `[SPRINT-XX] type: description` + +**Step 1: Create task in Odoo:** ```bash curl -s -X POST "/jsonrpc" \ @@ -396,28 +443,53 @@ curl -s -X POST "/jsonrpc" \ "service": "object", "method": "execute_kw", "args": ["", , "", "project.task", "create", - [{"name": "", "project_id": , "milestone_id": , "user_ids": []}], + [{"name": "[SPRINT-XX] type: description", "project_id": , "milestone_id": , "user_ids": []}], {} ] } }' ``` -After creating, confirm with the task ID and link: +**Step 2: Create matching GitHub Issue:** + +```bash +gh issue create \ + --title "[SPRINT-XX] type: description" \ + --label "sprint-XX,type" \ + --milestone "Sprint XX" \ + --body "$(cat <<'EOF' +**Odoo Task:** # +**Sprint:** Sprint XX +**Odoo Link:** /web#id=&model=project.task&view_type=form + +--- + +EOF +)" +``` + +If the GitHub Milestone "Sprint XX" doesn't exist yet, create it first: +```bash +gh api repos///milestones -f title="Sprint XX" -f due_on="" ``` -Task # created: "" -Sprint: | Assigned to: you -Link: /web#id=&model=project.task&view_type=form + +**Step 3: Confirm with IDs from both systems:** +``` +Task created (synced): + Odoo: #/web#id=&model=project.task + GitHub: # + Name: [SPRINT-XX] type: description ``` **Batch mode:** If the user provides multiple tasks (comma-separated or multi-line), -create all of them in sequence and show a summary table. +create all of them in sequence and show a summary table with both Odoo + GitHub IDs. ## Command: New Sprint (`/sprint new [name]`) -1. If no name given, ask the user for a sprint name +1. If no name given, auto-generate: `Sprint XX` (increment from config's `current_sprint`) 2. Ask for deadline (default: 2 weeks from today) -3. Create a milestone in Odoo: + +**Step 1: Create milestone in Odoo:** ```bash curl -s -X POST "/jsonrpc" \ @@ -429,28 +501,38 @@ curl -s -X POST "/jsonrpc" \ "service": "object", "method": "execute_kw", "args": ["", , "", "project.milestone", "create", - [{"name": "", "project_id": , "deadline": ""}], + [{"name": "Sprint XX", "project_id": , "deadline": ""}], {} ] } }' ``` -4. Confirm creation and show the new sprint in dashboard format +**Step 2: Create matching GitHub Milestone:** + +```bash +gh api repos///milestones \ + -f title="Sprint XX" \ + -f due_on="T23:59:59Z" \ + -f description="Sprint XX — created via /sprint" +``` + +**Step 3: Update config** — increment `current_sprint` in `~/.gstack/odoo-config.json` + +**Step 4: Confirm creation** and show the new sprint in dashboard format with links to both systems ## Command: Close Sprint (`/sprint close`) -1. Get current sprint tasks and compute stats: - - Total tasks - - Completed vs incomplete - - Tasks by priority +1. Get current sprint tasks from **both** systems and compute stats: + - Total tasks, completed vs incomplete + - Tasks by priority and type 2. If there are incomplete tasks, ask: - - Move to next sprint? - - Mark as cancelled? + - Move to next sprint? (updates both Odoo milestone + GitHub milestone) + - Mark as cancelled? (closes GitHub issue with "cancelled" label) - Leave in current sprint? -3. Mark milestone as reached: +3. **Close Odoo milestone:** ```bash curl -s -X POST "/jsonrpc" \ @@ -469,9 +551,19 @@ curl -s -X POST "/jsonrpc" \ }' ``` -4. Generate sprint report (see Report command) +4. **Close GitHub milestone:** + +```bash +# Get milestone number +gh api repos///milestones --jq '.[] | select(.title=="Sprint XX") | .number' + +# Close it +gh api repos///milestones/ -X PATCH -f state="closed" +``` + +5. Generate sprint report (see Report command) -5. Ask if user wants to create the next sprint immediately +6. Ask if user wants to create the next sprint immediately ## Command: Approve (`/sprint approve `) diff --git a/sprint/SKILL.md.tmpl b/sprint/SKILL.md.tmpl index 5bed79693..de851cd68 100644 --- a/sprint/SKILL.md.tmpl +++ b/sprint/SKILL.md.tmpl @@ -1,11 +1,11 @@ --- name: sprint -version: 1.0.0 +version: 1.1.0 description: | - Sprint & task management via Odoo Project. Create tasks, track sprints, - send approval requests, and view dashboards — all from terminal. - Use when asked to "manage tasks", "create sprint", "add task", "sprint status", - "send for approval", or "close sprint". + Sprint & task management with dual sync: Odoo Project + GitHub Issues/Milestones. + Naming convention: [SPRINT-XX] type: description. Tasks created in both systems. + Approvals via GitHub Issues. Use when asked to "manage tasks", "create sprint", + "add task", "sprint status", "send for approval", or "close sprint". Proactively suggest when the user mentions task management or sprint planning. allowed-tools: - Bash @@ -19,10 +19,36 @@ allowed-tools: {{PREAMBLE}} -# /sprint — Sprint & Task Management (Odoo Integration) +# /sprint — Sprint & Task Management (Odoo + GitHub Sync) -Manage sprints and tasks via Odoo Project API. Supports task creation, sprint tracking, -approval workflows, and notifications — all through Odoo's built-in systems. +Manage sprints and tasks with **dual sync** between Odoo Project and GitHub. +Tasks are created in both systems with consistent naming. Approvals go through +GitHub Issues. Sprint tracking via Odoo milestones + GitHub Milestones. + +## Naming Convention + +All tasks follow this format: + +``` +[SPRINT-XX] type: description +``` + +**Types:** + +| Prefix | Dùng cho | Ví dụ | +|--------|----------|-------| +| `feat:` | Tính năng mới | `[SPRINT-01] feat: User authentication` | +| `fix:` | Bug fix | `[SPRINT-01] fix: Login redirect loop` | +| `content:` | Nội dung cần review | `[SPRINT-01] content: Blog post Q1 review` | +| `deploy:` | Deploy approval | `[SPRINT-01] deploy: Release v2.0` | +| `chore:` | Infra, vận hành | `[SPRINT-01] chore: Setup monitoring` | +| `design:` | Design/UI | `[SPRINT-01] design: Landing page mockup` | + +The sprint number auto-increments. When parsing user input for `/sprint add`, +detect if they included a type prefix. If not, ask or default to `feat:`. + +The naming convention is enforced on **both** Odoo task names and GitHub Issue titles +to keep the two systems in sync. ## User-invocable @@ -75,7 +101,17 @@ curl -s -X POST "/jsonrpc" \ }' ``` -Show the list of projects and ask the user to pick one. Then save config: +Show the list of projects and ask the user to pick one. + +5. Detect the GitHub repo for sync: + +```bash +gh repo view --json nameWithOwner -q .nameWithOwner +``` + +6. Ask for the current sprint number (default: 1). This is used for the `[SPRINT-XX]` prefix. + +7. Save config: ```bash mkdir -p ~/.gstack @@ -86,13 +122,16 @@ cat > ~/.gstack/odoo-config.json << 'CONFIGEOF' "uid": , "api_key": "", "project_id": , - "project_name": "" + "project_name": "", + "github_repo": "", + "current_sprint": , + "sprint_prefix": "SPRINT" } CONFIGEOF chmod 600 ~/.gstack/odoo-config.json ``` -Confirm setup is complete and show the user their selected project. +Confirm setup is complete and show the user their selected project and GitHub repo. ## Odoo API Helper @@ -154,33 +193,41 @@ curl -s -X POST "/jsonrpc" \ }' ``` -Format the output as a clean dashboard: +Format the output as a clean dashboard with naming convention: ``` -╔══════════════════════════════════════════════════╗ -║ Sprint: | Deadline: ║ -╠══════════════════════════════════════════════════╣ -║ ║ -║ 📋 New (3) ║ -║ #42 Setup CI/CD pipeline ★★ ║ -║ #43 Design landing page ★ ║ -║ #44 Write API docs ★ ║ -║ ║ -║ 🔄 In Progress (2) ║ -║ #40 User authentication ★★★ ║ -║ #41 Database migrations ★★ ║ -║ ║ -║ ✅ Done (5) ║ -║ #35 Project setup ★ ║ -║ ... ║ -║ ║ -║ Progress: ████████░░ 50% (5/10) ║ -╚══════════════════════════════════════════════════╝ +╔══════════════════════════════════════════════════════════════╗ +║ Sprint 01 | Deadline: Mar 22, 2026 ║ +║ Odoo: | GitHub: ║ +╠══════════════════════════════════════════════════════════════╣ +║ ║ +║ 📋 New (3) ║ +║ OD#42 GH#12 [SPRINT-01] feat: Setup CI/CD ★★ ║ +║ OD#43 GH#13 [SPRINT-01] design: Landing page ★ ║ +║ OD#44 GH#14 [SPRINT-01] chore: Write API docs ★ ║ +║ ║ +║ 🔄 In Progress (2) ║ +║ OD#40 GH#10 [SPRINT-01] feat: User auth ★★★ ║ +║ OD#41 GH#11 [SPRINT-01] feat: DB migrations ★★ ║ +║ ║ +║ ✅ Done (5) ║ +║ OD#35 GH#5 [SPRINT-01] chore: Project setup ★ ║ +║ ... ║ +║ ║ +║ Progress: ████████░░ 50% (5/10) ║ +╚══════════════════════════════════════════════════════════════╝ ``` +`OD#` = Odoo task ID, `GH#` = GitHub Issue number. Both are clickable links when shown in terminal. + ## Command: Add Task (`/sprint add `) -Parse the description from the argument. Create a task in Odoo: +Parse the description from the argument. Apply naming convention: + +1. If user input has no type prefix, ask or default to `feat:` +2. Format task name: `[SPRINT-XX] type: description` + +**Step 1: Create task in Odoo:** ```bash curl -s -X POST "/jsonrpc" \ @@ -192,28 +239,53 @@ curl -s -X POST "/jsonrpc" \ "service": "object", "method": "execute_kw", "args": ["", , "", "project.task", "create", - [{"name": "", "project_id": , "milestone_id": , "user_ids": []}], + [{"name": "[SPRINT-XX] type: description", "project_id": , "milestone_id": , "user_ids": []}], {} ] } }' ``` -After creating, confirm with the task ID and link: +**Step 2: Create matching GitHub Issue:** + +```bash +gh issue create \ + --title "[SPRINT-XX] type: description" \ + --label "sprint-XX,type" \ + --milestone "Sprint XX" \ + --body "$(cat <<'EOF' +**Odoo Task:** # +**Sprint:** Sprint XX +**Odoo Link:** /web#id=&model=project.task&view_type=form + +--- + +EOF +)" +``` + +If the GitHub Milestone "Sprint XX" doesn't exist yet, create it first: +```bash +gh api repos///milestones -f title="Sprint XX" -f due_on="" ``` -Task # created: "" -Sprint: | Assigned to: you -Link: /web#id=&model=project.task&view_type=form + +**Step 3: Confirm with IDs from both systems:** +``` +Task created (synced): + Odoo: #/web#id=&model=project.task + GitHub: # + Name: [SPRINT-XX] type: description ``` **Batch mode:** If the user provides multiple tasks (comma-separated or multi-line), -create all of them in sequence and show a summary table. +create all of them in sequence and show a summary table with both Odoo + GitHub IDs. ## Command: New Sprint (`/sprint new [name]`) -1. If no name given, ask the user for a sprint name +1. If no name given, auto-generate: `Sprint XX` (increment from config's `current_sprint`) 2. Ask for deadline (default: 2 weeks from today) -3. Create a milestone in Odoo: + +**Step 1: Create milestone in Odoo:** ```bash curl -s -X POST "/jsonrpc" \ @@ -225,28 +297,38 @@ curl -s -X POST "/jsonrpc" \ "service": "object", "method": "execute_kw", "args": ["", , "", "project.milestone", "create", - [{"name": "", "project_id": , "deadline": ""}], + [{"name": "Sprint XX", "project_id": , "deadline": ""}], {} ] } }' ``` -4. Confirm creation and show the new sprint in dashboard format +**Step 2: Create matching GitHub Milestone:** + +```bash +gh api repos///milestones \ + -f title="Sprint XX" \ + -f due_on="T23:59:59Z" \ + -f description="Sprint XX — created via /sprint" +``` + +**Step 3: Update config** — increment `current_sprint` in `~/.gstack/odoo-config.json` + +**Step 4: Confirm creation** and show the new sprint in dashboard format with links to both systems ## Command: Close Sprint (`/sprint close`) -1. Get current sprint tasks and compute stats: - - Total tasks - - Completed vs incomplete - - Tasks by priority +1. Get current sprint tasks from **both** systems and compute stats: + - Total tasks, completed vs incomplete + - Tasks by priority and type 2. If there are incomplete tasks, ask: - - Move to next sprint? - - Mark as cancelled? + - Move to next sprint? (updates both Odoo milestone + GitHub milestone) + - Mark as cancelled? (closes GitHub issue with "cancelled" label) - Leave in current sprint? -3. Mark milestone as reached: +3. **Close Odoo milestone:** ```bash curl -s -X POST "/jsonrpc" \ @@ -265,9 +347,19 @@ curl -s -X POST "/jsonrpc" \ }' ``` -4. Generate sprint report (see Report command) +4. **Close GitHub milestone:** + +```bash +# Get milestone number +gh api repos///milestones --jq '.[] | select(.title=="Sprint XX") | .number' + +# Close it +gh api repos///milestones/ -X PATCH -f state="closed" +``` + +5. Generate sprint report (see Report command) -5. Ask if user wants to create the next sprint immediately +6. Ask if user wants to create the next sprint immediately ## Command: Approve (`/sprint approve `) From 6e960d34b5650af0aa5cc46bf8177f790ad854fb Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 22 Mar 2026 16:48:01 +0000 Subject: [PATCH 4/8] feat: add role definitions + task ownership to /sprint (v1.2.0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clear separation between PO (human) and AI Dev (Claude): - PO: vision, brief, review, approve, deploy decisions - AI Dev: plan, implement, test, document, report Task ownership rules prevent conflicts: - Each task type has a default owner - One task = one branch (sprint-XX/type/short-description) - Lock via stage transitions (New → In Progress → Review) - Never work on tasks already In Progress by someone else Decision matrix for ambiguous situations. https://claude.ai/code/session_01K1VcDbXz1uCxoGikqWSqup --- .agents/skills/gstack-sprint/SKILL.md | 96 +++++++++++++++++++++++++- sprint/SKILL.md | 98 ++++++++++++++++++++++++++- sprint/SKILL.md.tmpl | 98 ++++++++++++++++++++++++++- 3 files changed, 287 insertions(+), 5 deletions(-) diff --git a/.agents/skills/gstack-sprint/SKILL.md b/.agents/skills/gstack-sprint/SKILL.md index 666f2d81b..096f15faf 100644 --- a/.agents/skills/gstack-sprint/SKILL.md +++ b/.agents/skills/gstack-sprint/SKILL.md @@ -245,6 +245,92 @@ detect if they included a type prefix. If not, ask or default to `feat:`. The naming convention is enforced on **both** Odoo task names and GitHub Issue titles to keep the two systems in sync. +## Roles & Ownership + +This team has two roles. Every task must have exactly ONE owner — no shared ownership. + +### PO (Product Owner) — the human user + +| Responsibility | Examples | +|----------------|----------| +| **Vision & Strategy** | Decide what to build, product direction, priorities | +| **Brief tasks** | Describe what's needed (the "what" and "why") | +| **Review & Approve** | Approve plans, review outputs, accept/reject deliverables | +| **Deploy decisions** | Final go/no-go for production releases | +| **Stakeholder comms** | Talk to customers, partners, investors | + +PO **does NOT**: write code, write tests, create PRs, debug errors, or pick +implementation approach. PO focuses on outcomes, not how to get there. + +### AI Dev (Claude) — the AI agent + +| Responsibility | Examples | +|----------------|----------| +| **Plan & Architect** | Break briefs into technical tasks, propose approach | +| **Implement** | Write code, create files, refactor | +| **Test & QA** | Write tests, run CI, verify quality | +| **Document** | Update docs, changelogs, comments | +| **Report** | Sprint reports, status updates, blocker alerts | + +AI Dev **does NOT**: decide product direction, choose what to build next, +approve releases to production, or skip PO review. + +### Task Assignment Rules + +Every task has an `owner` field that prevents conflicts: + +| Task type | Owner | The other role... | +|-----------|-------|-------------------| +| `feat:` | **AI Dev** | PO briefs + approves result | +| `fix:` | **AI Dev** | PO reports bug + verifies fix | +| `content:` | **PO drafts → AI Dev reviews** | Or reverse: AI drafts → PO approves | +| `deploy:` | **AI Dev prepares → PO approves** | AI never deploys without PO approval | +| `chore:` | **AI Dev** | PO informed, no approval needed | +| `design:` | **PO decides → AI Dev implements** | AI proposes options, PO picks | + +### Conflict Prevention + +To prevent two people (or two AI sessions) editing the same thing: + +1. **One task = one branch.** Each task gets its own git branch: + `sprint-XX/type/short-description` (e.g., `sprint-01/feat/user-auth`) + +2. **Check before starting.** Before working on a task, AI Dev must: + ```bash + # Check if task branch already exists (someone else is working on it) + git branch -r | grep "sprint-XX/type/short-description" && echo "BRANCH EXISTS — check if task is already in progress" + ``` + +3. **Lock via stage.** When AI Dev starts a task: + - Move Odoo stage: New → In Progress + - Assign GitHub Issue to self + - This signals "hands off" to any other session + +4. **Never work on tasks in "In Progress" stage** unless you are the assignee. + If a task is already In Progress, ask the PO before touching it. + +5. **Handoff protocol.** When AI Dev finishes: + - Move stage: In Progress → Review + - Create PR + link to GitHub Issue + - `/sprint approve ` → sends PO notification + - PO reviews → approves or requests changes + +### Decision Matrix + +When unclear who should decide: + +| Question | Who decides | +|----------|-------------| +| "Should we build X?" | **PO** | +| "How should we build X?" | **AI Dev** (proposes) → **PO** (approves if major) | +| "Is this done?" | **PO** (acceptance) | +| "Is this code correct?" | **AI Dev** (tests prove it) | +| "Should we deploy?" | **PO** (final call) | +| "What's the priority?" | **PO** | +| "What's the deadline?" | **PO** sets, **AI Dev** flags if unrealistic | +| "Fix this bug" | **AI Dev** (autonomous, PO notified) | +| "Refactor this" | **AI Dev** (autonomous if chore, PO approves if risky) | + ## User-invocable When the user types `/sprint`, run this skill. @@ -464,11 +550,19 @@ If the GitHub Milestone "Sprint XX" doesn't exist yet, create it first: gh api repos///milestones -f title="Sprint XX" -f due_on="" ``` -**Step 3: Confirm with IDs from both systems:** +**Step 3: Create task branch** (for `feat:`, `fix:`, `design:` tasks): + +```bash +git checkout -b sprint-XX/type/short-description +``` + +**Step 4: Confirm with IDs from both systems:** ``` Task created (synced): Odoo: #/web#id=&model=project.task GitHub: # + Branch: sprint-XX/type/short-description + Owner: AI Dev (auto-assigned per task type rules) Name: [SPRINT-XX] type: description ``` diff --git a/sprint/SKILL.md b/sprint/SKILL.md index 265b20aad..c5cdc3fa3 100644 --- a/sprint/SKILL.md +++ b/sprint/SKILL.md @@ -1,6 +1,6 @@ --- name: sprint -version: 1.1.0 +version: 1.2.0 description: | Sprint & task management with dual sync: Odoo Project + GitHub Issues/Milestones. Naming convention: [SPRINT-XX] type: description. Tasks created in both systems. @@ -254,6 +254,92 @@ detect if they included a type prefix. If not, ask or default to `feat:`. The naming convention is enforced on **both** Odoo task names and GitHub Issue titles to keep the two systems in sync. +## Roles & Ownership + +This team has two roles. Every task must have exactly ONE owner — no shared ownership. + +### PO (Product Owner) — the human user + +| Responsibility | Examples | +|----------------|----------| +| **Vision & Strategy** | Decide what to build, product direction, priorities | +| **Brief tasks** | Describe what's needed (the "what" and "why") | +| **Review & Approve** | Approve plans, review outputs, accept/reject deliverables | +| **Deploy decisions** | Final go/no-go for production releases | +| **Stakeholder comms** | Talk to customers, partners, investors | + +PO **does NOT**: write code, write tests, create PRs, debug errors, or pick +implementation approach. PO focuses on outcomes, not how to get there. + +### AI Dev (Claude) — the AI agent + +| Responsibility | Examples | +|----------------|----------| +| **Plan & Architect** | Break briefs into technical tasks, propose approach | +| **Implement** | Write code, create files, refactor | +| **Test & QA** | Write tests, run CI, verify quality | +| **Document** | Update docs, changelogs, comments | +| **Report** | Sprint reports, status updates, blocker alerts | + +AI Dev **does NOT**: decide product direction, choose what to build next, +approve releases to production, or skip PO review. + +### Task Assignment Rules + +Every task has an `owner` field that prevents conflicts: + +| Task type | Owner | The other role... | +|-----------|-------|-------------------| +| `feat:` | **AI Dev** | PO briefs + approves result | +| `fix:` | **AI Dev** | PO reports bug + verifies fix | +| `content:` | **PO drafts → AI Dev reviews** | Or reverse: AI drafts → PO approves | +| `deploy:` | **AI Dev prepares → PO approves** | AI never deploys without PO approval | +| `chore:` | **AI Dev** | PO informed, no approval needed | +| `design:` | **PO decides → AI Dev implements** | AI proposes options, PO picks | + +### Conflict Prevention + +To prevent two people (or two AI sessions) editing the same thing: + +1. **One task = one branch.** Each task gets its own git branch: + `sprint-XX/type/short-description` (e.g., `sprint-01/feat/user-auth`) + +2. **Check before starting.** Before working on a task, AI Dev must: + ```bash + # Check if task branch already exists (someone else is working on it) + git branch -r | grep "sprint-XX/type/short-description" && echo "BRANCH EXISTS — check if task is already in progress" + ``` + +3. **Lock via stage.** When AI Dev starts a task: + - Move Odoo stage: New → In Progress + - Assign GitHub Issue to self + - This signals "hands off" to any other session + +4. **Never work on tasks in "In Progress" stage** unless you are the assignee. + If a task is already In Progress, ask the PO before touching it. + +5. **Handoff protocol.** When AI Dev finishes: + - Move stage: In Progress → Review + - Create PR + link to GitHub Issue + - `/sprint approve ` → sends PO notification + - PO reviews → approves or requests changes + +### Decision Matrix + +When unclear who should decide: + +| Question | Who decides | +|----------|-------------| +| "Should we build X?" | **PO** | +| "How should we build X?" | **AI Dev** (proposes) → **PO** (approves if major) | +| "Is this done?" | **PO** (acceptance) | +| "Is this code correct?" | **AI Dev** (tests prove it) | +| "Should we deploy?" | **PO** (final call) | +| "What's the priority?" | **PO** | +| "What's the deadline?" | **PO** sets, **AI Dev** flags if unrealistic | +| "Fix this bug" | **AI Dev** (autonomous, PO notified) | +| "Refactor this" | **AI Dev** (autonomous if chore, PO approves if risky) | + ## User-invocable When the user types `/sprint`, run this skill. @@ -473,11 +559,19 @@ If the GitHub Milestone "Sprint XX" doesn't exist yet, create it first: gh api repos///milestones -f title="Sprint XX" -f due_on="" ``` -**Step 3: Confirm with IDs from both systems:** +**Step 3: Create task branch** (for `feat:`, `fix:`, `design:` tasks): + +```bash +git checkout -b sprint-XX/type/short-description +``` + +**Step 4: Confirm with IDs from both systems:** ``` Task created (synced): Odoo: #/web#id=&model=project.task GitHub: # + Branch: sprint-XX/type/short-description + Owner: AI Dev (auto-assigned per task type rules) Name: [SPRINT-XX] type: description ``` diff --git a/sprint/SKILL.md.tmpl b/sprint/SKILL.md.tmpl index de851cd68..9246c28ec 100644 --- a/sprint/SKILL.md.tmpl +++ b/sprint/SKILL.md.tmpl @@ -1,6 +1,6 @@ --- name: sprint -version: 1.1.0 +version: 1.2.0 description: | Sprint & task management with dual sync: Odoo Project + GitHub Issues/Milestones. Naming convention: [SPRINT-XX] type: description. Tasks created in both systems. @@ -50,6 +50,92 @@ detect if they included a type prefix. If not, ask or default to `feat:`. The naming convention is enforced on **both** Odoo task names and GitHub Issue titles to keep the two systems in sync. +## Roles & Ownership + +This team has two roles. Every task must have exactly ONE owner — no shared ownership. + +### PO (Product Owner) — the human user + +| Responsibility | Examples | +|----------------|----------| +| **Vision & Strategy** | Decide what to build, product direction, priorities | +| **Brief tasks** | Describe what's needed (the "what" and "why") | +| **Review & Approve** | Approve plans, review outputs, accept/reject deliverables | +| **Deploy decisions** | Final go/no-go for production releases | +| **Stakeholder comms** | Talk to customers, partners, investors | + +PO **does NOT**: write code, write tests, create PRs, debug errors, or pick +implementation approach. PO focuses on outcomes, not how to get there. + +### AI Dev (Claude) — the AI agent + +| Responsibility | Examples | +|----------------|----------| +| **Plan & Architect** | Break briefs into technical tasks, propose approach | +| **Implement** | Write code, create files, refactor | +| **Test & QA** | Write tests, run CI, verify quality | +| **Document** | Update docs, changelogs, comments | +| **Report** | Sprint reports, status updates, blocker alerts | + +AI Dev **does NOT**: decide product direction, choose what to build next, +approve releases to production, or skip PO review. + +### Task Assignment Rules + +Every task has an `owner` field that prevents conflicts: + +| Task type | Owner | The other role... | +|-----------|-------|-------------------| +| `feat:` | **AI Dev** | PO briefs + approves result | +| `fix:` | **AI Dev** | PO reports bug + verifies fix | +| `content:` | **PO drafts → AI Dev reviews** | Or reverse: AI drafts → PO approves | +| `deploy:` | **AI Dev prepares → PO approves** | AI never deploys without PO approval | +| `chore:` | **AI Dev** | PO informed, no approval needed | +| `design:` | **PO decides → AI Dev implements** | AI proposes options, PO picks | + +### Conflict Prevention + +To prevent two people (or two AI sessions) editing the same thing: + +1. **One task = one branch.** Each task gets its own git branch: + `sprint-XX/type/short-description` (e.g., `sprint-01/feat/user-auth`) + +2. **Check before starting.** Before working on a task, AI Dev must: + ```bash + # Check if task branch already exists (someone else is working on it) + git branch -r | grep "sprint-XX/type/short-description" && echo "BRANCH EXISTS — check if task is already in progress" + ``` + +3. **Lock via stage.** When AI Dev starts a task: + - Move Odoo stage: New → In Progress + - Assign GitHub Issue to self + - This signals "hands off" to any other session + +4. **Never work on tasks in "In Progress" stage** unless you are the assignee. + If a task is already In Progress, ask the PO before touching it. + +5. **Handoff protocol.** When AI Dev finishes: + - Move stage: In Progress → Review + - Create PR + link to GitHub Issue + - `/sprint approve ` → sends PO notification + - PO reviews → approves or requests changes + +### Decision Matrix + +When unclear who should decide: + +| Question | Who decides | +|----------|-------------| +| "Should we build X?" | **PO** | +| "How should we build X?" | **AI Dev** (proposes) → **PO** (approves if major) | +| "Is this done?" | **PO** (acceptance) | +| "Is this code correct?" | **AI Dev** (tests prove it) | +| "Should we deploy?" | **PO** (final call) | +| "What's the priority?" | **PO** | +| "What's the deadline?" | **PO** sets, **AI Dev** flags if unrealistic | +| "Fix this bug" | **AI Dev** (autonomous, PO notified) | +| "Refactor this" | **AI Dev** (autonomous if chore, PO approves if risky) | + ## User-invocable When the user types `/sprint`, run this skill. @@ -269,11 +355,19 @@ If the GitHub Milestone "Sprint XX" doesn't exist yet, create it first: gh api repos///milestones -f title="Sprint XX" -f due_on="" ``` -**Step 3: Confirm with IDs from both systems:** +**Step 3: Create task branch** (for `feat:`, `fix:`, `design:` tasks): + +```bash +git checkout -b sprint-XX/type/short-description +``` + +**Step 4: Confirm with IDs from both systems:** ``` Task created (synced): Odoo: #/web#id=&model=project.task GitHub: # + Branch: sprint-XX/type/short-description + Owner: AI Dev (auto-assigned per task type rules) Name: [SPRINT-XX] type: description ``` From 234fc5ed1f6a4b68650913daf8c3619eca357b3d Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 22 Mar 2026 17:14:18 +0000 Subject: [PATCH 5/8] feat: add security/perf/maintain task types + ownership rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New task prefixes: security:, perf:, maintain: — each with clear ownership defaults: - security: AI Dev proactively scans + fixes, PO approves breaking changes - perf: PO sets targets, AI Dev profiles + optimizes - maintain: AI Dev handles minor deps, PO approves major upgrades Decision matrix extended for tech debt, dependency updates, and performance targets. https://claude.ai/code/session_01K1VcDbXz1uCxoGikqWSqup --- .agents/skills/gstack-sprint/SKILL.md | 10 ++++++++++ sprint/SKILL.md | 10 ++++++++++ sprint/SKILL.md.tmpl | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/.agents/skills/gstack-sprint/SKILL.md b/.agents/skills/gstack-sprint/SKILL.md index 096f15faf..9807034da 100644 --- a/.agents/skills/gstack-sprint/SKILL.md +++ b/.agents/skills/gstack-sprint/SKILL.md @@ -238,6 +238,9 @@ All tasks follow this format: | `deploy:` | Deploy approval | `[SPRINT-01] deploy: Release v2.0` | | `chore:` | Infra, vận hành | `[SPRINT-01] chore: Setup monitoring` | | `design:` | Design/UI | `[SPRINT-01] design: Landing page mockup` | +| `security:` | Bảo mật, audit | `[SPRINT-01] security: Fix SQL injection in search` | +| `perf:` | Tối ưu hiệu năng | `[SPRINT-01] perf: Optimize image loading` | +| `maintain:` | Bảo trì, nâng cấp deps | `[SPRINT-01] maintain: Upgrade React 18→19` | The sprint number auto-increments. When parsing user input for `/sprint add`, detect if they included a type prefix. If not, ask or default to `feat:`. @@ -287,6 +290,9 @@ Every task has an `owner` field that prevents conflicts: | `deploy:` | **AI Dev prepares → PO approves** | AI never deploys without PO approval | | `chore:` | **AI Dev** | PO informed, no approval needed | | `design:` | **PO decides → AI Dev implements** | AI proposes options, PO picks | +| `security:` | **AI Dev detects + fixes** | PO approves if breaking change. AI proactively scans. | +| `perf:` | **AI Dev profiles + optimizes** | PO sets targets ("page load < 2s"). AI decides how. | +| `maintain:` | **AI Dev** | PO approves major upgrades (breaking versions). Minor = autonomous. | ### Conflict Prevention @@ -330,6 +336,10 @@ When unclear who should decide: | "What's the deadline?" | **PO** sets, **AI Dev** flags if unrealistic | | "Fix this bug" | **AI Dev** (autonomous, PO notified) | | "Refactor this" | **AI Dev** (autonomous if chore, PO approves if risky) | +| "Is this secure?" | **AI Dev** (scans + fixes) → **PO** (approves if breaking) | +| "Too slow" | **PO** (sets target) → **AI Dev** (profiles + optimizes) | +| "Update dependencies" | **AI Dev** (minor auto, major needs PO approval) | +| "Tech debt" | **AI Dev** (flags) → **PO** (prioritizes vs features) | ## User-invocable diff --git a/sprint/SKILL.md b/sprint/SKILL.md index c5cdc3fa3..90dc1e33d 100644 --- a/sprint/SKILL.md +++ b/sprint/SKILL.md @@ -247,6 +247,9 @@ All tasks follow this format: | `deploy:` | Deploy approval | `[SPRINT-01] deploy: Release v2.0` | | `chore:` | Infra, vận hành | `[SPRINT-01] chore: Setup monitoring` | | `design:` | Design/UI | `[SPRINT-01] design: Landing page mockup` | +| `security:` | Bảo mật, audit | `[SPRINT-01] security: Fix SQL injection in search` | +| `perf:` | Tối ưu hiệu năng | `[SPRINT-01] perf: Optimize image loading` | +| `maintain:` | Bảo trì, nâng cấp deps | `[SPRINT-01] maintain: Upgrade React 18→19` | The sprint number auto-increments. When parsing user input for `/sprint add`, detect if they included a type prefix. If not, ask or default to `feat:`. @@ -296,6 +299,9 @@ Every task has an `owner` field that prevents conflicts: | `deploy:` | **AI Dev prepares → PO approves** | AI never deploys without PO approval | | `chore:` | **AI Dev** | PO informed, no approval needed | | `design:` | **PO decides → AI Dev implements** | AI proposes options, PO picks | +| `security:` | **AI Dev detects + fixes** | PO approves if breaking change. AI proactively scans. | +| `perf:` | **AI Dev profiles + optimizes** | PO sets targets ("page load < 2s"). AI decides how. | +| `maintain:` | **AI Dev** | PO approves major upgrades (breaking versions). Minor = autonomous. | ### Conflict Prevention @@ -339,6 +345,10 @@ When unclear who should decide: | "What's the deadline?" | **PO** sets, **AI Dev** flags if unrealistic | | "Fix this bug" | **AI Dev** (autonomous, PO notified) | | "Refactor this" | **AI Dev** (autonomous if chore, PO approves if risky) | +| "Is this secure?" | **AI Dev** (scans + fixes) → **PO** (approves if breaking) | +| "Too slow" | **PO** (sets target) → **AI Dev** (profiles + optimizes) | +| "Update dependencies" | **AI Dev** (minor auto, major needs PO approval) | +| "Tech debt" | **AI Dev** (flags) → **PO** (prioritizes vs features) | ## User-invocable diff --git a/sprint/SKILL.md.tmpl b/sprint/SKILL.md.tmpl index 9246c28ec..6a28d8817 100644 --- a/sprint/SKILL.md.tmpl +++ b/sprint/SKILL.md.tmpl @@ -43,6 +43,9 @@ All tasks follow this format: | `deploy:` | Deploy approval | `[SPRINT-01] deploy: Release v2.0` | | `chore:` | Infra, vận hành | `[SPRINT-01] chore: Setup monitoring` | | `design:` | Design/UI | `[SPRINT-01] design: Landing page mockup` | +| `security:` | Bảo mật, audit | `[SPRINT-01] security: Fix SQL injection in search` | +| `perf:` | Tối ưu hiệu năng | `[SPRINT-01] perf: Optimize image loading` | +| `maintain:` | Bảo trì, nâng cấp deps | `[SPRINT-01] maintain: Upgrade React 18→19` | The sprint number auto-increments. When parsing user input for `/sprint add`, detect if they included a type prefix. If not, ask or default to `feat:`. @@ -92,6 +95,9 @@ Every task has an `owner` field that prevents conflicts: | `deploy:` | **AI Dev prepares → PO approves** | AI never deploys without PO approval | | `chore:` | **AI Dev** | PO informed, no approval needed | | `design:` | **PO decides → AI Dev implements** | AI proposes options, PO picks | +| `security:` | **AI Dev detects + fixes** | PO approves if breaking change. AI proactively scans. | +| `perf:` | **AI Dev profiles + optimizes** | PO sets targets ("page load < 2s"). AI decides how. | +| `maintain:` | **AI Dev** | PO approves major upgrades (breaking versions). Minor = autonomous. | ### Conflict Prevention @@ -135,6 +141,10 @@ When unclear who should decide: | "What's the deadline?" | **PO** sets, **AI Dev** flags if unrealistic | | "Fix this bug" | **AI Dev** (autonomous, PO notified) | | "Refactor this" | **AI Dev** (autonomous if chore, PO approves if risky) | +| "Is this secure?" | **AI Dev** (scans + fixes) → **PO** (approves if breaking) | +| "Too slow" | **PO** (sets target) → **AI Dev** (profiles + optimizes) | +| "Update dependencies" | **AI Dev** (minor auto, major needs PO approval) | +| "Tech debt" | **AI Dev** (flags) → **PO** (prioritizes vs features) | ## User-invocable From 29f38ab80beee7470205fea52516706c17a38a2b Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 22 Mar 2026 17:15:52 +0000 Subject: [PATCH 6/8] feat: add API credential auto-discovery rules for AI Dev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AI Dev now follows a lookup chain before asking PO: env vars → config files → CLAUDE.md → secret manager. Only asks PO when all sources exhausted, then persists the answer so it never asks twice. https://claude.ai/code/session_01K1VcDbXz1uCxoGikqWSqup --- .agents/skills/gstack-sprint/SKILL.md | 20 ++++++++++++++++++++ sprint/SKILL.md | 20 ++++++++++++++++++++ sprint/SKILL.md.tmpl | 20 ++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/.agents/skills/gstack-sprint/SKILL.md b/.agents/skills/gstack-sprint/SKILL.md index 9807034da..d4483c631 100644 --- a/.agents/skills/gstack-sprint/SKILL.md +++ b/.agents/skills/gstack-sprint/SKILL.md @@ -294,6 +294,26 @@ Every task has an `owner` field that prevents conflicts: | `perf:` | **AI Dev profiles + optimizes** | PO sets targets ("page load < 2s"). AI decides how. | | `maintain:` | **AI Dev** | PO approves major upgrades (breaking versions). Minor = autonomous. | +### API & Credentials — AI Dev tự lấy + +Khi task cần gọi external API, AI Dev **tự tìm credentials** theo thứ tự: + +1. **Env vars** — kiểm tra `.env`, `.env.local`, env hiện tại +2. **Config files** — `.claude/settings.json`, `~/.config/`, project config +3. **CLAUDE.md** — credentials/endpoints đã ghi lại từ lần setup trước +4. **Secret manager** — nếu project dùng (1Password CLI, Vault, etc.) + +Chỉ hỏi PO khi **tất cả đều không có**. Khi PO cung cấp, AI Dev phải: +- Lưu vào `.env` hoặc CLAUDE.md (tuỳ loại) để lần sau không hỏi lại +- **Không bao giờ** commit credentials vào git + +| Tình huống | AI Dev làm gì | +|------------|---------------| +| API key có trong env | Dùng luôn, không hỏi | +| API key chưa có, biết service nào | Hỏi PO 1 lần, lưu lại | +| Cần API mới chưa từng dùng | Hỏi PO cách auth + endpoint | +| Key hết hạn / bị revoke | Báo PO, không tự tạo key mới | + ### Conflict Prevention To prevent two people (or two AI sessions) editing the same thing: diff --git a/sprint/SKILL.md b/sprint/SKILL.md index 90dc1e33d..55412550d 100644 --- a/sprint/SKILL.md +++ b/sprint/SKILL.md @@ -303,6 +303,26 @@ Every task has an `owner` field that prevents conflicts: | `perf:` | **AI Dev profiles + optimizes** | PO sets targets ("page load < 2s"). AI decides how. | | `maintain:` | **AI Dev** | PO approves major upgrades (breaking versions). Minor = autonomous. | +### API & Credentials — AI Dev tự lấy + +Khi task cần gọi external API, AI Dev **tự tìm credentials** theo thứ tự: + +1. **Env vars** — kiểm tra `.env`, `.env.local`, env hiện tại +2. **Config files** — `.claude/settings.json`, `~/.config/`, project config +3. **CLAUDE.md** — credentials/endpoints đã ghi lại từ lần setup trước +4. **Secret manager** — nếu project dùng (1Password CLI, Vault, etc.) + +Chỉ hỏi PO khi **tất cả đều không có**. Khi PO cung cấp, AI Dev phải: +- Lưu vào `.env` hoặc CLAUDE.md (tuỳ loại) để lần sau không hỏi lại +- **Không bao giờ** commit credentials vào git + +| Tình huống | AI Dev làm gì | +|------------|---------------| +| API key có trong env | Dùng luôn, không hỏi | +| API key chưa có, biết service nào | Hỏi PO 1 lần, lưu lại | +| Cần API mới chưa từng dùng | Hỏi PO cách auth + endpoint | +| Key hết hạn / bị revoke | Báo PO, không tự tạo key mới | + ### Conflict Prevention To prevent two people (or two AI sessions) editing the same thing: diff --git a/sprint/SKILL.md.tmpl b/sprint/SKILL.md.tmpl index 6a28d8817..da42869be 100644 --- a/sprint/SKILL.md.tmpl +++ b/sprint/SKILL.md.tmpl @@ -99,6 +99,26 @@ Every task has an `owner` field that prevents conflicts: | `perf:` | **AI Dev profiles + optimizes** | PO sets targets ("page load < 2s"). AI decides how. | | `maintain:` | **AI Dev** | PO approves major upgrades (breaking versions). Minor = autonomous. | +### API & Credentials — AI Dev tự lấy + +Khi task cần gọi external API, AI Dev **tự tìm credentials** theo thứ tự: + +1. **Env vars** — kiểm tra `.env`, `.env.local`, env hiện tại +2. **Config files** — `.claude/settings.json`, `~/.config/`, project config +3. **CLAUDE.md** — credentials/endpoints đã ghi lại từ lần setup trước +4. **Secret manager** — nếu project dùng (1Password CLI, Vault, etc.) + +Chỉ hỏi PO khi **tất cả đều không có**. Khi PO cung cấp, AI Dev phải: +- Lưu vào `.env` hoặc CLAUDE.md (tuỳ loại) để lần sau không hỏi lại +- **Không bao giờ** commit credentials vào git + +| Tình huống | AI Dev làm gì | +|------------|---------------| +| API key có trong env | Dùng luôn, không hỏi | +| API key chưa có, biết service nào | Hỏi PO 1 lần, lưu lại | +| Cần API mới chưa từng dùng | Hỏi PO cách auth + endpoint | +| Key hết hạn / bị revoke | Báo PO, không tự tạo key mới | + ### Conflict Prevention To prevent two people (or two AI sessions) editing the same thing: From 76990d1e8f65a7cc48760be44f67ffd71c4cbcd6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 22 Mar 2026 17:17:46 +0000 Subject: [PATCH 7/8] =?UTF-8?q?feat:=20add=20/sprint=20dashboard=20?= =?UTF-8?q?=E2=80=94=20project-level=20overview?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Full project dashboard pulling from Odoo + GitHub: - Sprint overview with progress bars + velocity trend - Ownership breakdown (AI Dev vs PO tasks) - Kanban-style task pipeline (New → In Progress → Review → Done) - Task distribution by type (feat/fix/security/perf/etc) - Auto-detected risks: overdue, at-risk, blocked, stale tasks - Pending approvals queue - Cumulative stats (cycle time, velocity, PRs merged) Health indicators auto-compute based on deadlines and expected vs actual sprint progress. https://claude.ai/code/session_01K1VcDbXz1uCxoGikqWSqup --- .agents/skills/gstack-sprint/SKILL.md | 137 ++++++++++++++++++++++++++ sprint/SKILL.md | 137 ++++++++++++++++++++++++++ sprint/SKILL.md.tmpl | 137 ++++++++++++++++++++++++++ 3 files changed, 411 insertions(+) diff --git a/.agents/skills/gstack-sprint/SKILL.md b/.agents/skills/gstack-sprint/SKILL.md index d4483c631..d31a0867a 100644 --- a/.agents/skills/gstack-sprint/SKILL.md +++ b/.agents/skills/gstack-sprint/SKILL.md @@ -375,6 +375,7 @@ When the user types `/sprint`, run this skill. - `/sprint approve ` — send task for approval via Odoo chatter - `/sprint review` — list tasks pending approval - `/sprint report` — generate sprint report +- `/sprint dashboard` — project-level overview (all sprints, health, risks) ## Step 0: Load Odoo Config @@ -920,6 +921,142 @@ EOF 3. Create/update corresponding Odoo task with deploy details 4. Tell the user: "Deploy approval created on GitHub. Close the issue when approved, then proceed with deployment." +## Command: Dashboard (`/sprint dashboard`) + +Project-level overview across **all sprints**. Pulls from both Odoo and GitHub. + +**Step 1: Get all milestones (sprints) from Odoo:** + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.milestone", "search_read", + [[["project_id", "=", ]]], + {"fields": ["name", "id", "deadline", "is_reached"], "order": "create_date desc"} + ] + } + }' +``` + +**Step 2: Get all tasks with stages:** + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "search_read", + [[["project_id", "=", ]]], + {"fields": ["name", "id", "stage_id", "milestone_id", "priority", "date_deadline", "tag_ids"], "order": "priority desc, create_date desc"} + ] + } + }' +``` + +**Step 3: Get GitHub Issues + PRs:** + +```bash +gh issue list --state all --label "sprint" --json number,title,state,labels,milestone,createdAt,closedAt --limit 100 +``` + +```bash +gh pr list --state all --json number,title,state,labels,milestone,createdAt,mergedAt --limit 50 +``` + +**Step 4: Compute metrics and render dashboard:** + +``` +╔══════════════════════════════════════════════════════════════╗ +║ PROJECT DASHBOARD ║ +║ ║ +╚══════════════════════════════════════════════════════════════╝ + +📊 Sprint Overview +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Sprint Tasks Done Progress Deadline +Sprint-03 ★ 5/12 5/12 ████░░░░ 42% Mar 29 +Sprint-02 ✓ 10/10 10/10 ████████ 100% Mar 15 +Sprint-01 ✓ 8/8 8/8 ████████ 100% Mar 1 + +★ = current ✓ = completed + +📈 Velocity Trend +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Sprint-01: ████████░░ 8 tasks +Sprint-02: ██████████ 10 tasks +Sprint-03: █████░░░░░ 5/12 (in progress) + +Avg velocity: 9 tasks/sprint + +👥 Ownership Breakdown (Current Sprint) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Owner In Progress Review Done Total +AI Dev 3 1 4 8 +PO 0 1 3 4 + +🔄 Task Pipeline (Current Sprint) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +New (3) In Progress (3) Review (2) Done (5) +├─ #51 feat: ├─ #48 feat: ├─ #46 feat: ├─ #41 feat: ✓ +├─ #52 fix: ├─ #49 perf: └─ #50 deploy: ├─ #42 fix: ✓ +└─ #53 security: └─ #47 maintain: ├─ #43 chore: ✓ + ├─ #44 feat: ✓ + └─ #45 fix: ✓ + +📋 By Type (Current Sprint) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +feat: 5 ██████████████░░░░░░ (42%) +fix: 3 ████████░░░░░░░░░░░░ (25%) +chore: 1 ███░░░░░░░░░░░░░░░░░ (8%) +security: 1 ███░░░░░░░░░░░░░░░░░ (8%) +perf: 1 ███░░░░░░░░░░░░░░░░░ (8%) +maintain: 1 ███░░░░░░░░░░░░░░░░░ (8%) + +⚠️ Risks & Blockers +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +🔴 Overdue: #48 feat: User auth (deadline Mar 20, 2 days late) +🟡 At risk: #49 perf: Image loading (deadline Mar 28, 1 day buffer) +🔵 Blocked: None +⏳ Stale: #53 security: (New for 5+ days, not started) + +🔍 Pending Approvals +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +GH #46 feat: Payment integration — waiting 2 days +GH #50 deploy: Release v2.0 — waiting 1 day + +📊 Cumulative Stats +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Total tasks (all sprints): 30 +Completed: 23 (77%) +Avg cycle time: 3.2 days +Longest task: #48 feat: User auth (8 days) +PRs merged: 18 +``` + +**Health indicators** — compute automatically: + +| Signal | Condition | Display | +|--------|-----------|---------| +| 🔴 Overdue | `deadline < today` and not Done | Show in Risks | +| 🟡 At risk | `deadline - today <= 2 days` and not Done | Show in Risks | +| 🔵 Blocked | Task in "Blocked" stage | Show in Risks | +| ⏳ Stale | In "New" stage for 5+ days | Show in Risks | +| ✅ On track | Sprint progress >= expected % based on elapsed time | Green header | +| ⚠️ Behind | Sprint progress < expected % by 20+ points | Yellow header | + +**Expected progress** = `(days_elapsed / sprint_duration) × 100`. If actual completion % +is 20+ points below expected, flag the sprint as "Behind schedule" in the header. + ## Tone - Concise, action-oriented diff --git a/sprint/SKILL.md b/sprint/SKILL.md index 55412550d..ccfab449a 100644 --- a/sprint/SKILL.md +++ b/sprint/SKILL.md @@ -384,6 +384,7 @@ When the user types `/sprint`, run this skill. - `/sprint approve ` — send task for approval via Odoo chatter - `/sprint review` — list tasks pending approval - `/sprint report` — generate sprint report +- `/sprint dashboard` — project-level overview (all sprints, health, risks) ## Step 0: Load Odoo Config @@ -929,6 +930,142 @@ EOF 3. Create/update corresponding Odoo task with deploy details 4. Tell the user: "Deploy approval created on GitHub. Close the issue when approved, then proceed with deployment." +## Command: Dashboard (`/sprint dashboard`) + +Project-level overview across **all sprints**. Pulls from both Odoo and GitHub. + +**Step 1: Get all milestones (sprints) from Odoo:** + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.milestone", "search_read", + [[["project_id", "=", ]]], + {"fields": ["name", "id", "deadline", "is_reached"], "order": "create_date desc"} + ] + } + }' +``` + +**Step 2: Get all tasks with stages:** + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "search_read", + [[["project_id", "=", ]]], + {"fields": ["name", "id", "stage_id", "milestone_id", "priority", "date_deadline", "tag_ids"], "order": "priority desc, create_date desc"} + ] + } + }' +``` + +**Step 3: Get GitHub Issues + PRs:** + +```bash +gh issue list --state all --label "sprint" --json number,title,state,labels,milestone,createdAt,closedAt --limit 100 +``` + +```bash +gh pr list --state all --json number,title,state,labels,milestone,createdAt,mergedAt --limit 50 +``` + +**Step 4: Compute metrics and render dashboard:** + +``` +╔══════════════════════════════════════════════════════════════╗ +║ PROJECT DASHBOARD ║ +║ ║ +╚══════════════════════════════════════════════════════════════╝ + +📊 Sprint Overview +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Sprint Tasks Done Progress Deadline +Sprint-03 ★ 5/12 5/12 ████░░░░ 42% Mar 29 +Sprint-02 ✓ 10/10 10/10 ████████ 100% Mar 15 +Sprint-01 ✓ 8/8 8/8 ████████ 100% Mar 1 + +★ = current ✓ = completed + +📈 Velocity Trend +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Sprint-01: ████████░░ 8 tasks +Sprint-02: ██████████ 10 tasks +Sprint-03: █████░░░░░ 5/12 (in progress) + +Avg velocity: 9 tasks/sprint + +👥 Ownership Breakdown (Current Sprint) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Owner In Progress Review Done Total +AI Dev 3 1 4 8 +PO 0 1 3 4 + +🔄 Task Pipeline (Current Sprint) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +New (3) In Progress (3) Review (2) Done (5) +├─ #51 feat: ├─ #48 feat: ├─ #46 feat: ├─ #41 feat: ✓ +├─ #52 fix: ├─ #49 perf: └─ #50 deploy: ├─ #42 fix: ✓ +└─ #53 security: └─ #47 maintain: ├─ #43 chore: ✓ + ├─ #44 feat: ✓ + └─ #45 fix: ✓ + +📋 By Type (Current Sprint) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +feat: 5 ██████████████░░░░░░ (42%) +fix: 3 ████████░░░░░░░░░░░░ (25%) +chore: 1 ███░░░░░░░░░░░░░░░░░ (8%) +security: 1 ███░░░░░░░░░░░░░░░░░ (8%) +perf: 1 ███░░░░░░░░░░░░░░░░░ (8%) +maintain: 1 ███░░░░░░░░░░░░░░░░░ (8%) + +⚠️ Risks & Blockers +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +🔴 Overdue: #48 feat: User auth (deadline Mar 20, 2 days late) +🟡 At risk: #49 perf: Image loading (deadline Mar 28, 1 day buffer) +🔵 Blocked: None +⏳ Stale: #53 security: (New for 5+ days, not started) + +🔍 Pending Approvals +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +GH #46 feat: Payment integration — waiting 2 days +GH #50 deploy: Release v2.0 — waiting 1 day + +📊 Cumulative Stats +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Total tasks (all sprints): 30 +Completed: 23 (77%) +Avg cycle time: 3.2 days +Longest task: #48 feat: User auth (8 days) +PRs merged: 18 +``` + +**Health indicators** — compute automatically: + +| Signal | Condition | Display | +|--------|-----------|---------| +| 🔴 Overdue | `deadline < today` and not Done | Show in Risks | +| 🟡 At risk | `deadline - today <= 2 days` and not Done | Show in Risks | +| 🔵 Blocked | Task in "Blocked" stage | Show in Risks | +| ⏳ Stale | In "New" stage for 5+ days | Show in Risks | +| ✅ On track | Sprint progress >= expected % based on elapsed time | Green header | +| ⚠️ Behind | Sprint progress < expected % by 20+ points | Yellow header | + +**Expected progress** = `(days_elapsed / sprint_duration) × 100`. If actual completion % +is 20+ points below expected, flag the sprint as "Behind schedule" in the header. + ## Tone - Concise, action-oriented diff --git a/sprint/SKILL.md.tmpl b/sprint/SKILL.md.tmpl index da42869be..1b7117901 100644 --- a/sprint/SKILL.md.tmpl +++ b/sprint/SKILL.md.tmpl @@ -180,6 +180,7 @@ When the user types `/sprint`, run this skill. - `/sprint approve ` — send task for approval via Odoo chatter - `/sprint review` — list tasks pending approval - `/sprint report` — generate sprint report +- `/sprint dashboard` — project-level overview (all sprints, health, risks) ## Step 0: Load Odoo Config @@ -725,6 +726,142 @@ EOF 3. Create/update corresponding Odoo task with deploy details 4. Tell the user: "Deploy approval created on GitHub. Close the issue when approved, then proceed with deployment." +## Command: Dashboard (`/sprint dashboard`) + +Project-level overview across **all sprints**. Pulls from both Odoo and GitHub. + +**Step 1: Get all milestones (sprints) from Odoo:** + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.milestone", "search_read", + [[["project_id", "=", ]]], + {"fields": ["name", "id", "deadline", "is_reached"], "order": "create_date desc"} + ] + } + }' +``` + +**Step 2: Get all tasks with stages:** + +```bash +curl -s -X POST "/jsonrpc" \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "call", + "params": { + "service": "object", + "method": "execute_kw", + "args": ["", , "", "project.task", "search_read", + [[["project_id", "=", ]]], + {"fields": ["name", "id", "stage_id", "milestone_id", "priority", "date_deadline", "tag_ids"], "order": "priority desc, create_date desc"} + ] + } + }' +``` + +**Step 3: Get GitHub Issues + PRs:** + +```bash +gh issue list --state all --label "sprint" --json number,title,state,labels,milestone,createdAt,closedAt --limit 100 +``` + +```bash +gh pr list --state all --json number,title,state,labels,milestone,createdAt,mergedAt --limit 50 +``` + +**Step 4: Compute metrics and render dashboard:** + +``` +╔══════════════════════════════════════════════════════════════╗ +║ PROJECT DASHBOARD ║ +║ ║ +╚══════════════════════════════════════════════════════════════╝ + +📊 Sprint Overview +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Sprint Tasks Done Progress Deadline +Sprint-03 ★ 5/12 5/12 ████░░░░ 42% Mar 29 +Sprint-02 ✓ 10/10 10/10 ████████ 100% Mar 15 +Sprint-01 ✓ 8/8 8/8 ████████ 100% Mar 1 + +★ = current ✓ = completed + +📈 Velocity Trend +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Sprint-01: ████████░░ 8 tasks +Sprint-02: ██████████ 10 tasks +Sprint-03: █████░░░░░ 5/12 (in progress) + +Avg velocity: 9 tasks/sprint + +👥 Ownership Breakdown (Current Sprint) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Owner In Progress Review Done Total +AI Dev 3 1 4 8 +PO 0 1 3 4 + +🔄 Task Pipeline (Current Sprint) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +New (3) In Progress (3) Review (2) Done (5) +├─ #51 feat: ├─ #48 feat: ├─ #46 feat: ├─ #41 feat: ✓ +├─ #52 fix: ├─ #49 perf: └─ #50 deploy: ├─ #42 fix: ✓ +└─ #53 security: └─ #47 maintain: ├─ #43 chore: ✓ + ├─ #44 feat: ✓ + └─ #45 fix: ✓ + +📋 By Type (Current Sprint) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +feat: 5 ██████████████░░░░░░ (42%) +fix: 3 ████████░░░░░░░░░░░░ (25%) +chore: 1 ███░░░░░░░░░░░░░░░░░ (8%) +security: 1 ███░░░░░░░░░░░░░░░░░ (8%) +perf: 1 ███░░░░░░░░░░░░░░░░░ (8%) +maintain: 1 ███░░░░░░░░░░░░░░░░░ (8%) + +⚠️ Risks & Blockers +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +🔴 Overdue: #48 feat: User auth (deadline Mar 20, 2 days late) +🟡 At risk: #49 perf: Image loading (deadline Mar 28, 1 day buffer) +🔵 Blocked: None +⏳ Stale: #53 security: (New for 5+ days, not started) + +🔍 Pending Approvals +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +GH #46 feat: Payment integration — waiting 2 days +GH #50 deploy: Release v2.0 — waiting 1 day + +📊 Cumulative Stats +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Total tasks (all sprints): 30 +Completed: 23 (77%) +Avg cycle time: 3.2 days +Longest task: #48 feat: User auth (8 days) +PRs merged: 18 +``` + +**Health indicators** — compute automatically: + +| Signal | Condition | Display | +|--------|-----------|---------| +| 🔴 Overdue | `deadline < today` and not Done | Show in Risks | +| 🟡 At risk | `deadline - today <= 2 days` and not Done | Show in Risks | +| 🔵 Blocked | Task in "Blocked" stage | Show in Risks | +| ⏳ Stale | In "New" stage for 5+ days | Show in Risks | +| ✅ On track | Sprint progress >= expected % based on elapsed time | Green header | +| ⚠️ Behind | Sprint progress < expected % by 20+ points | Yellow header | + +**Expected progress** = `(days_elapsed / sprint_duration) × 100`. If actual completion % +is 20+ points below expected, flag the sprint as "Behind schedule" in the header. + ## Tone - Concise, action-oriented From a1bebfd1f75ae1020cd80836b0906bfd745d68cc Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 23 Mar 2026 02:17:48 +0000 Subject: [PATCH 8/8] feat: add /sprint dashboard --html for local browser viewing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generates a standalone HTML file at ~/.gstack/dashboard.html with: - Dark theme, card-based layout, no external dependencies - All dashboard sections rendered as HTML (progress bars, kanban, velocity chart, risk badges — all pure CSS) - Clickable links to Odoo tasks and GitHub issues - Auto-opens in default browser via xdg-open/open - Responsive layout (flexbox/grid) Re-run anytime to refresh the data. https://claude.ai/code/session_01K1VcDbXz1uCxoGikqWSqup --- .agents/skills/gstack-sprint/SKILL.md | 37 +++++++++++++++++++++++++++ sprint/SKILL.md | 37 +++++++++++++++++++++++++++ sprint/SKILL.md.tmpl | 37 +++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/.agents/skills/gstack-sprint/SKILL.md b/.agents/skills/gstack-sprint/SKILL.md index d31a0867a..abfff95ed 100644 --- a/.agents/skills/gstack-sprint/SKILL.md +++ b/.agents/skills/gstack-sprint/SKILL.md @@ -376,6 +376,7 @@ When the user types `/sprint`, run this skill. - `/sprint review` — list tasks pending approval - `/sprint report` — generate sprint report - `/sprint dashboard` — project-level overview (all sprints, health, risks) +- `/sprint dashboard --html` — same dashboard, exported as local HTML file and opened in browser ## Step 0: Load Odoo Config @@ -1057,6 +1058,42 @@ PRs merged: 18 **Expected progress** = `(days_elapsed / sprint_duration) × 100`. If actual completion % is 20+ points below expected, flag the sprint as "Behind schedule" in the header. +### HTML Export (`/sprint dashboard --html`) + +When `--html` is passed, take all the same data from Steps 1–4 above and generate +a standalone HTML file with embedded CSS. No external dependencies — everything inline. + +Use the Write tool to create the file at `~/.gstack/dashboard.html`. + +The HTML dashboard should include: + +1. **Modern dark theme** — dark background (#1a1a2e), card-based layout, clean typography +2. **All sections from the terminal dashboard** rendered as HTML: + - Sprint overview table with colored progress bars (green ≥80%, yellow ≥50%, red <50%) + - Velocity trend as horizontal bar chart (pure CSS, no JS library needed) + - Task pipeline as a kanban board (4 columns: New, In Progress, Review, Done) + - Task type distribution as colored horizontal bars + - Risks section with color-coded badges (🔴🟡🔵⏳) + - Pending approvals as a card list + - Cumulative stats in a summary row at the top +3. **Clickable links** — Odoo task IDs link to `/web#id=&model=project.task&view_type=form`, + GitHub issues link to their URL +4. **Auto-refresh timestamp** in the footer: "Generated: Mar 23, 2026 14:30" +5. **Responsive** — works on any screen width (flexbox/grid) + +After writing the file, open it: + +```bash +# Linux +xdg-open ~/.gstack/dashboard.html 2>/dev/null || \ +# macOS +open ~/.gstack/dashboard.html 2>/dev/null || \ +echo "Dashboard saved to ~/.gstack/dashboard.html — open it in your browser" +``` + +Tell the user: "Dashboard exported to `~/.gstack/dashboard.html` and opened in your browser. +Re-run `/sprint dashboard --html` anytime to refresh." + ## Tone - Concise, action-oriented diff --git a/sprint/SKILL.md b/sprint/SKILL.md index ccfab449a..5ac3cf30e 100644 --- a/sprint/SKILL.md +++ b/sprint/SKILL.md @@ -385,6 +385,7 @@ When the user types `/sprint`, run this skill. - `/sprint review` — list tasks pending approval - `/sprint report` — generate sprint report - `/sprint dashboard` — project-level overview (all sprints, health, risks) +- `/sprint dashboard --html` — same dashboard, exported as local HTML file and opened in browser ## Step 0: Load Odoo Config @@ -1066,6 +1067,42 @@ PRs merged: 18 **Expected progress** = `(days_elapsed / sprint_duration) × 100`. If actual completion % is 20+ points below expected, flag the sprint as "Behind schedule" in the header. +### HTML Export (`/sprint dashboard --html`) + +When `--html` is passed, take all the same data from Steps 1–4 above and generate +a standalone HTML file with embedded CSS. No external dependencies — everything inline. + +Use the Write tool to create the file at `~/.gstack/dashboard.html`. + +The HTML dashboard should include: + +1. **Modern dark theme** — dark background (#1a1a2e), card-based layout, clean typography +2. **All sections from the terminal dashboard** rendered as HTML: + - Sprint overview table with colored progress bars (green ≥80%, yellow ≥50%, red <50%) + - Velocity trend as horizontal bar chart (pure CSS, no JS library needed) + - Task pipeline as a kanban board (4 columns: New, In Progress, Review, Done) + - Task type distribution as colored horizontal bars + - Risks section with color-coded badges (🔴🟡🔵⏳) + - Pending approvals as a card list + - Cumulative stats in a summary row at the top +3. **Clickable links** — Odoo task IDs link to `/web#id=&model=project.task&view_type=form`, + GitHub issues link to their URL +4. **Auto-refresh timestamp** in the footer: "Generated: Mar 23, 2026 14:30" +5. **Responsive** — works on any screen width (flexbox/grid) + +After writing the file, open it: + +```bash +# Linux +xdg-open ~/.gstack/dashboard.html 2>/dev/null || \ +# macOS +open ~/.gstack/dashboard.html 2>/dev/null || \ +echo "Dashboard saved to ~/.gstack/dashboard.html — open it in your browser" +``` + +Tell the user: "Dashboard exported to `~/.gstack/dashboard.html` and opened in your browser. +Re-run `/sprint dashboard --html` anytime to refresh." + ## Tone - Concise, action-oriented diff --git a/sprint/SKILL.md.tmpl b/sprint/SKILL.md.tmpl index 1b7117901..027ca3f7c 100644 --- a/sprint/SKILL.md.tmpl +++ b/sprint/SKILL.md.tmpl @@ -181,6 +181,7 @@ When the user types `/sprint`, run this skill. - `/sprint review` — list tasks pending approval - `/sprint report` — generate sprint report - `/sprint dashboard` — project-level overview (all sprints, health, risks) +- `/sprint dashboard --html` — same dashboard, exported as local HTML file and opened in browser ## Step 0: Load Odoo Config @@ -862,6 +863,42 @@ PRs merged: 18 **Expected progress** = `(days_elapsed / sprint_duration) × 100`. If actual completion % is 20+ points below expected, flag the sprint as "Behind schedule" in the header. +### HTML Export (`/sprint dashboard --html`) + +When `--html` is passed, take all the same data from Steps 1–4 above and generate +a standalone HTML file with embedded CSS. No external dependencies — everything inline. + +Use the Write tool to create the file at `~/.gstack/dashboard.html`. + +The HTML dashboard should include: + +1. **Modern dark theme** — dark background (#1a1a2e), card-based layout, clean typography +2. **All sections from the terminal dashboard** rendered as HTML: + - Sprint overview table with colored progress bars (green ≥80%, yellow ≥50%, red <50%) + - Velocity trend as horizontal bar chart (pure CSS, no JS library needed) + - Task pipeline as a kanban board (4 columns: New, In Progress, Review, Done) + - Task type distribution as colored horizontal bars + - Risks section with color-coded badges (🔴🟡🔵⏳) + - Pending approvals as a card list + - Cumulative stats in a summary row at the top +3. **Clickable links** — Odoo task IDs link to `/web#id=&model=project.task&view_type=form`, + GitHub issues link to their URL +4. **Auto-refresh timestamp** in the footer: "Generated: Mar 23, 2026 14:30" +5. **Responsive** — works on any screen width (flexbox/grid) + +After writing the file, open it: + +```bash +# Linux +xdg-open ~/.gstack/dashboard.html 2>/dev/null || \ +# macOS +open ~/.gstack/dashboard.html 2>/dev/null || \ +echo "Dashboard saved to ~/.gstack/dashboard.html — open it in your browser" +``` + +Tell the user: "Dashboard exported to `~/.gstack/dashboard.html` and opened in your browser. +Re-run `/sprint dashboard --html` anytime to refresh." + ## Tone - Concise, action-oriented