guardian-framework 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +463 -0
- package/dist/cli.js +12958 -0
- package/dist/exports.js +12765 -0
- package/package.json +61 -0
- package/templates/languages/go-patterns.md +411 -0
- package/templates/languages/java-patterns.md +545 -0
- package/templates/languages/python-patterns.md +312 -0
- package/templates/languages/rust-patterns.md +232 -0
- package/templates/languages/typescript-patterns.md +313 -0
- package/templates/pi/INDEX.md +437 -0
- package/templates/pi/agent/AGENTS.md +166 -0
- package/templates/pi/agents/architecture-coordinator.md +40 -0
- package/templates/pi/agents/architecture-validator.md +36 -0
- package/templates/pi/agents/bootstrap-implementer.md +37 -0
- package/templates/pi/agents/issue-factory.md +31 -0
- package/templates/pi/agents/operations-validator.md +32 -0
- package/templates/pi/agents/security-validator.md +33 -0
- package/templates/pi/architecture/CHANGELOG.md +78 -0
- package/templates/pi/architecture/decisions/ADR-template.md +76 -0
- package/templates/pi/architecture/diagrams/system-overview.md +159 -0
- package/templates/pi/architecture/modules/module-template.md +152 -0
- package/templates/pi/context/checklists.md +91 -0
- package/templates/pi/context/domain-workflow.md +180 -0
- package/templates/pi/context/output-formats.md +135 -0
- package/templates/pi/context/patterns-base.md +47 -0
- package/templates/pi/context/patterns.md +38 -0
- package/templates/pi/context/project.md +88 -0
- package/templates/pi/domain/exploration.md +93 -0
- package/templates/pi/domain/ubiquitous-language.md +24 -0
- package/templates/pi/extensions/architect-lib/generators.ts +528 -0
- package/templates/pi/extensions/architect-lib/helpers.ts +344 -0
- package/templates/pi/extensions/architect-lib/types.ts +117 -0
- package/templates/pi/extensions/architect.ts +1425 -0
- package/templates/pi/extensions/ask-user-question.ts +579 -0
- package/templates/pi/extensions/bash-guard.ts +556 -0
- package/templates/pi/extensions/config-reload.ts +115 -0
- package/templates/pi/extensions/coordinator.ts +304 -0
- package/templates/pi/extensions/curator.ts +543 -0
- package/templates/pi/extensions/domain-explorer.ts +990 -0
- package/templates/pi/extensions/filechanges.ts +656 -0
- package/templates/pi/extensions/goal-loop.ts +717 -0
- package/templates/pi/extensions/hooks.ts +452 -0
- package/templates/pi/extensions/kanban.ts +547 -0
- package/templates/pi/extensions/pipeline.ts +1246 -0
- package/templates/pi/extensions/plan-mode.ts +209 -0
- package/templates/pi/extensions/project-scaffolder.ts +284 -0
- package/templates/pi/extensions/read-only-mode.ts +192 -0
- package/templates/pi/extensions/redaction.ts +128 -0
- package/templates/pi/extensions/session-persistence.ts +174 -0
- package/templates/pi/extensions/slash-commands.ts +229 -0
- package/templates/pi/extensions/snippets.ts +201 -0
- package/templates/pi/extensions/validation-runner.ts +100 -0
- package/templates/pi/github/agents/architecture-coordinator.agent.md +27 -0
- package/templates/pi/github/agents/architecture-validator.agent.md +20 -0
- package/templates/pi/github/agents/bootstrap-implementer.agent.md +20 -0
- package/templates/pi/github/agents/epic-planner.agent.md +70 -0
- package/templates/pi/github/agents/issue-factory.agent.md +20 -0
- package/templates/pi/github/agents/operations-validator.agent.md +20 -0
- package/templates/pi/github/agents/security-validator.agent.md +20 -0
- package/templates/pi/github/copilot/settings.json +16 -0
- package/templates/pi/github/copilot-instructions.md +155 -0
- package/templates/pi/github/instructions/architecture.instructions.md +71 -0
- package/templates/pi/github/instructions/validation.instructions.md +69 -0
- package/templates/pi/github/workflows/01-planning-workflow.md +75 -0
- package/templates/pi/github/workflows/02-issue-generation-workflow.md +69 -0
- package/templates/pi/github/workflows/03-implementation-workflow.md +80 -0
- package/templates/pi/github/workflows/04-validation-workflow.md +68 -0
- package/templates/pi/preflight_report.json +99 -0
- package/templates/pi/prompts/blueprint-update.md +262 -0
- package/templates/pi/prompts/blueprint-validate.md +218 -0
- package/templates/pi/prompts/bug-fix.md +50 -0
- package/templates/pi/prompts/ci-blueprint.md +131 -0
- package/templates/pi/prompts/context-refresh.md +258 -0
- package/templates/pi/prompts/epic-plan.md +356 -0
- package/templates/pi/prompts/epic-template.md +186 -0
- package/templates/pi/prompts/feature-development.md +131 -0
- package/templates/pi/prompts/git-issues.md +243 -0
- package/templates/pi/prompts/hotfix.md +71 -0
- package/templates/pi/prompts/issue-closeout.md +342 -0
- package/templates/pi/prompts/issue-draft.md +218 -0
- package/templates/pi/prompts/issue-implementation-series.md +173 -0
- package/templates/pi/prompts/issue-merge.md +372 -0
- package/templates/pi/prompts/issue-template-set.md +392 -0
- package/templates/pi/prompts/issue-template.md +207 -0
- package/templates/pi/prompts/pattern-extract.md +269 -0
- package/templates/pi/prompts/plan-to-issues.md +430 -0
- package/templates/pi/prompts/refactoring.md +82 -0
- package/templates/pi/prompts/scope-analyzer.md +254 -0
- package/templates/pi/prompts/sync-check.md +230 -0
- package/templates/pi/scripts/categorize-issues.sh +171 -0
- package/templates/pi/scripts/ci/check_architecture_conformance.sh +748 -0
- package/templates/pi/scripts/ci/check_planning_packet.py +228 -0
- package/templates/pi/scripts/ci/run_hardening_stages.sh +264 -0
- package/templates/pi/scripts/ci/run_preflight.sh +649 -0
- package/templates/pi/scripts/ci/run_stage.sh +193 -0
- package/templates/pi/scripts/ci/stage_docs_policy.sh +82 -0
- package/templates/pi/scripts/ci/stage_integration.sh +3 -0
- package/templates/pi/scripts/ci/stage_lint.sh +130 -0
- package/templates/pi/scripts/ci/stage_migration_verify.sh +3 -0
- package/templates/pi/scripts/ci/stage_package_build.sh +3 -0
- package/templates/pi/scripts/ci/stage_release_readiness.sh +3 -0
- package/templates/pi/scripts/ci/stage_remaining.sh +242 -0
- package/templates/pi/scripts/ci/stage_security.sh +3 -0
- package/templates/pi/scripts/ci/stage_static_analysis.sh +114 -0
- package/templates/pi/scripts/ci/stage_unit.sh +119 -0
- package/templates/pi/scripts/ci/validate_agent_output.py +181 -0
- package/templates/pi/scripts/ci/validate_agent_output.sh +243 -0
- package/templates/pi/scripts/create-feature-branch.sh +136 -0
- package/templates/pi/scripts/create-mr.sh +117 -0
- package/templates/pi/scripts/fetch-issues.sh +131 -0
- package/templates/pi/scripts/generate-architecture.sh +161 -0
- package/templates/pi/scripts/git/close-epic.sh +69 -0
- package/templates/pi/scripts/git/close-issue.sh +35 -0
- package/templates/pi/scripts/git/create-tracking-issue.sh +174 -0
- package/templates/pi/scripts/git/link-issue-to-epic.sh +51 -0
- package/templates/pi/scripts/git/update-tracking-issue.sh +66 -0
- package/templates/pi/scripts/languages/go/validate-architecture.sh +139 -0
- package/templates/pi/scripts/languages/go/validate-canonical.sh +129 -0
- package/templates/pi/scripts/languages/go/validate-ci.sh +132 -0
- package/templates/pi/scripts/languages/go/validate-integration.sh +156 -0
- package/templates/pi/scripts/languages/go/validate-operations.sh +146 -0
- package/templates/pi/scripts/languages/go/validate-security.sh +135 -0
- package/templates/pi/scripts/languages/go/validate-tests.sh +125 -0
- package/templates/pi/scripts/languages/java/validate-annotations.sh +185 -0
- package/templates/pi/scripts/languages/java/validate-architecture.sh +159 -0
- package/templates/pi/scripts/languages/java/validate-canonical.sh +114 -0
- package/templates/pi/scripts/languages/java/validate-ci.sh +269 -0
- package/templates/pi/scripts/languages/java/validate-integration.sh +149 -0
- package/templates/pi/scripts/languages/java/validate-operations.sh +142 -0
- package/templates/pi/scripts/languages/java/validate-security.sh +174 -0
- package/templates/pi/scripts/languages/java/validate-spring-architecture.sh +227 -0
- package/templates/pi/scripts/languages/java/validate-tests.sh +159 -0
- package/templates/pi/scripts/languages/python/validate-architecture.sh +99 -0
- package/templates/pi/scripts/languages/python/validate-canonical.sh +124 -0
- package/templates/pi/scripts/languages/python/validate-ci.sh +130 -0
- package/templates/pi/scripts/languages/python/validate-integration.sh +119 -0
- package/templates/pi/scripts/languages/python/validate-operations.sh +107 -0
- package/templates/pi/scripts/languages/python/validate-security.sh +68 -0
- package/templates/pi/scripts/languages/python/validate-tests.sh +102 -0
- package/templates/pi/scripts/languages/rust/validate-architecture.sh +188 -0
- package/templates/pi/scripts/languages/rust/validate-canonical.sh +146 -0
- package/templates/pi/scripts/languages/rust/validate-ci.sh +147 -0
- package/templates/pi/scripts/languages/rust/validate-integration.sh +149 -0
- package/templates/pi/scripts/languages/rust/validate-operations.sh +154 -0
- package/templates/pi/scripts/languages/rust/validate-security.sh +153 -0
- package/templates/pi/scripts/languages/rust/validate-tests.sh +150 -0
- package/templates/pi/scripts/languages/typescript/validate-architecture.sh +157 -0
- package/templates/pi/scripts/languages/typescript/validate-canonical.sh +135 -0
- package/templates/pi/scripts/languages/typescript/validate-ci.sh +244 -0
- package/templates/pi/scripts/languages/typescript/validate-integration.sh +166 -0
- package/templates/pi/scripts/languages/typescript/validate-operations.sh +162 -0
- package/templates/pi/scripts/languages/typescript/validate-security.sh +169 -0
- package/templates/pi/scripts/languages/typescript/validate-tests.sh +158 -0
- package/templates/pi/scripts/merge-mr.sh +95 -0
- package/templates/pi/scripts/mr-validation.sh +228 -0
- package/templates/pi/scripts/validate-architecture-readiness.sh +153 -0
- package/templates/pi/scripts/validate-architecture.sh +22 -0
- package/templates/pi/scripts/validate-canonical.sh +22 -0
- package/templates/pi/scripts/validate-ci.sh +37 -0
- package/templates/pi/scripts/validate-integration.sh +22 -0
- package/templates/pi/scripts/validate-operations.sh +22 -0
- package/templates/pi/scripts/validate-security.sh +22 -0
- package/templates/pi/scripts/validate-tests.sh +22 -0
- package/templates/pi/scripts/validate-ubiquitous-language.sh +291 -0
- package/templates/pi/scripts/validation-cache.sh +139 -0
- package/templates/pi/skills/agents/architecture-coordinator.md +178 -0
- package/templates/pi/skills/agents/architecture-generator.md +79 -0
- package/templates/pi/skills/agents/architecture-validator.md +74 -0
- package/templates/pi/skills/agents/ci-mr-validator.md +46 -0
- package/templates/pi/skills/agents/code-developer.md +76 -0
- package/templates/pi/skills/agents/commit.md +46 -0
- package/templates/pi/skills/agents/curator.md +71 -0
- package/templates/pi/skills/agents/debug.md +59 -0
- package/templates/pi/skills/agents/documentation-maintainer.md +36 -0
- package/templates/pi/skills/agents/goal-loop.md +125 -0
- package/templates/pi/skills/agents/hooks.md +122 -0
- package/templates/pi/skills/agents/integration-validator.md +35 -0
- package/templates/pi/skills/agents/issue-creator.md +75 -0
- package/templates/pi/skills/agents/issue-factory.md +143 -0
- package/templates/pi/skills/agents/kanban.md +85 -0
- package/templates/pi/skills/agents/land.md +59 -0
- package/templates/pi/skills/agents/operations-validator.md +43 -0
- package/templates/pi/skills/agents/pipeline.md +113 -0
- package/templates/pi/skills/agents/plan-mode.md +77 -0
- package/templates/pi/skills/agents/pull.md +40 -0
- package/templates/pi/skills/agents/push.md +41 -0
- package/templates/pi/skills/agents/security-validator.md +85 -0
- package/templates/pi/skills/agents/session-persistence.md +119 -0
- package/templates/pi/skills/agents/slash-commands.md +117 -0
- package/templates/pi/skills/agents/snippets.md +99 -0
- package/templates/pi/skills/agents/subagent-registry.md +78 -0
- package/templates/pi/skills/agents/test-validator.md +42 -0
- package/templates/pi/skills/validators/architecture-validator.md +43 -0
- package/templates/pi/skills/validators/ci-validator.md +27 -0
- package/templates/pi/skills/validators/context-compaction.md +73 -0
- package/templates/pi/skills/validators/integration-validator.md +38 -0
- package/templates/pi/skills/validators/model-registry.md +96 -0
- package/templates/pi/skills/validators/operations-validator.md +34 -0
- package/templates/pi/skills/validators/security-guards.md +72 -0
- package/templates/pi/skills/validators/security-validator.md +41 -0
- package/templates/pi/skills/validators/system-prompt-tiers.md +69 -0
- package/templates/pi/skills/validators/test-validator.md +33 -0
- package/templates/pi/types.ts +62 -0
- package/templates/pi/validators/README.md +93 -0
- package/templates/pi/validators/default.toml +209 -0
- package/templates/pi/validators/spring.toml +142 -0
- package/templates/pi/workpad.md +53 -0
- package/templates/project/java/Dockerfile +14 -0
- package/templates/project/java/README.md +40 -0
- package/templates/project/java/pom.xml +132 -0
- package/templates/project/typescript/Dockerfile +15 -0
- package/templates/project/typescript/README.md +29 -0
- package/templates/project/typescript/package.json +23 -0
- package/templates/project/typescript/tsconfig.json +21 -0
- package/templates/workflow.md +123 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# create-feature-branch.sh — Create Branch for Issue Group
|
|
4
|
+
#
|
|
5
|
+
# Run as: bash .pi/scripts/create-feature-branch.sh <branch-name> [base-branch]
|
|
6
|
+
# ============================================================================
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
BRANCH_NAME="${1:-}"
|
|
10
|
+
BASE_BRANCH="${2:-main}"
|
|
11
|
+
|
|
12
|
+
RED='\033[0;31m'
|
|
13
|
+
GREEN='\033[0;32m'
|
|
14
|
+
YELLOW='\033[1;33m'
|
|
15
|
+
NC='\033[0m'
|
|
16
|
+
|
|
17
|
+
echo "============================================"
|
|
18
|
+
echo " Create Feature Branch"
|
|
19
|
+
echo "============================================"
|
|
20
|
+
echo ""
|
|
21
|
+
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
# Validate Input
|
|
24
|
+
# ---------------------------------------------------------------------------
|
|
25
|
+
if [ -z "$BRANCH_NAME" ]; then
|
|
26
|
+
echo -e "${RED}❌ Branch name required${NC}"
|
|
27
|
+
echo "Usage: create-feature-branch.sh <branch-name> [base-branch]"
|
|
28
|
+
echo ""
|
|
29
|
+
echo "Branch naming conventions:"
|
|
30
|
+
echo " feature/{component}-issues — Component batch"
|
|
31
|
+
echo " priority/{level}-{date} — Priority batch"
|
|
32
|
+
echo " issue/{number} — Single issue"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# ---------------------------------------------------------------------------
|
|
37
|
+
# Check Git State
|
|
38
|
+
# ---------------------------------------------------------------------------
|
|
39
|
+
if ! git rev-parse --is-inside-work-tree &> /dev/null; then
|
|
40
|
+
echo -e "${RED}❌ Not in a git repository${NC}"
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# Check for uncommitted changes
|
|
45
|
+
CHANGES=$(git status --porcelain | wc -l | tr -d ' ')
|
|
46
|
+
if [ "$CHANGES" -gt 0 ]; then
|
|
47
|
+
echo -e "${YELLOW}⚠️ Uncommitted changes detected${NC}"
|
|
48
|
+
git status --short
|
|
49
|
+
echo ""
|
|
50
|
+
echo "Options:"
|
|
51
|
+
echo " 1. Commit changes first"
|
|
52
|
+
echo " 2. Stash: git stash"
|
|
53
|
+
echo " 3. Force (not recommended): git checkout -f"
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# ---------------------------------------------------------------------------
|
|
58
|
+
# Fetch Latest
|
|
59
|
+
# ---------------------------------------------------------------------------
|
|
60
|
+
echo "Fetching latest from origin..."
|
|
61
|
+
git fetch origin "$BASE_BRANCH" 2>/dev/null || true
|
|
62
|
+
|
|
63
|
+
# ---------------------------------------------------------------------------
|
|
64
|
+
# Create Branch
|
|
65
|
+
# ---------------------------------------------------------------------------
|
|
66
|
+
echo "Creating branch: $BRANCH_NAME"
|
|
67
|
+
echo "Base: $BASE_BRANCH"
|
|
68
|
+
|
|
69
|
+
# Check if branch exists
|
|
70
|
+
if git show-ref --verify --quiet refs/heads/"$BRANCH_NAME"; then
|
|
71
|
+
echo -e "${YELLOW}⚠️ Branch already exists${NC}"
|
|
72
|
+
echo "Options:"
|
|
73
|
+
echo " 1. Use existing: git checkout $BRANCH_NAME"
|
|
74
|
+
echo " 2. Delete and recreate: git branch -D $BRANCH_NAME"
|
|
75
|
+
exit 1
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# Check if remote branch exists
|
|
79
|
+
if git show-ref --verify --quiet refs/remotes/origin/"$BRANCH_NAME"; then
|
|
80
|
+
echo -e "${YELLOW}⚠️ Remote branch exists${NC}"
|
|
81
|
+
echo " Use: git checkout -b $BRANCH_NAME origin/$BRANCH_NAME"
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Create branch
|
|
86
|
+
git checkout -b "$BRANCH_NAME" "origin/$BASE_BRANCH" 2>/dev/null || git checkout -b "$BRANCH_NAME" "$BASE_BRANCH"
|
|
87
|
+
|
|
88
|
+
echo -e "${GREEN}✅ Branch created: $BRANCH_NAME${NC}"
|
|
89
|
+
echo ""
|
|
90
|
+
echo "Current state:"
|
|
91
|
+
git log --oneline -3
|
|
92
|
+
echo ""
|
|
93
|
+
|
|
94
|
+
# ---------------------------------------------------------------------------
|
|
95
|
+
# Track in Plan File
|
|
96
|
+
# ---------------------------------------------------------------------------
|
|
97
|
+
PLAN_FILE=".claude/plans/$BRANCH_NAME.md"
|
|
98
|
+
mkdir -p ".claude/plans"
|
|
99
|
+
|
|
100
|
+
cat > "$PLAN_FILE" << EOF
|
|
101
|
+
# Implementation Plan: $BRANCH_NAME
|
|
102
|
+
|
|
103
|
+
**Branch:** $BRANCH_NAME
|
|
104
|
+
**Base:** $BASE_BRANCH
|
|
105
|
+
**Created:** $(date)
|
|
106
|
+
|
|
107
|
+
## Status
|
|
108
|
+
|
|
109
|
+
- [ ] Issues identified
|
|
110
|
+
- [ ] Implementation plan created
|
|
111
|
+
- [ ] Code implemented
|
|
112
|
+
- [ ] Tests passing
|
|
113
|
+
- [ ] MR created
|
|
114
|
+
- [ ] Pipeline green
|
|
115
|
+
- [ ] Merged
|
|
116
|
+
|
|
117
|
+
## Issues
|
|
118
|
+
|
|
119
|
+
<!-- Add issue numbers and descriptions -->
|
|
120
|
+
|
|
121
|
+
## Implementation Steps
|
|
122
|
+
|
|
123
|
+
<!-- Auto-generated from issue analysis -->
|
|
124
|
+
|
|
125
|
+
## Validation Checklist
|
|
126
|
+
|
|
127
|
+
- [ ] cargo build
|
|
128
|
+
- [ ] cargo test --all
|
|
129
|
+
- [ ] cargo clippy -- -D warnings
|
|
130
|
+
- [ ] cargo fmt --check
|
|
131
|
+
- [ ] cargo audit
|
|
132
|
+
EOF
|
|
133
|
+
|
|
134
|
+
echo "Plan file created: $PLAN_FILE"
|
|
135
|
+
|
|
136
|
+
exit 0
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Create Merge Request / Pull Request
|
|
3
|
+
#
|
|
4
|
+
# Creates a feature branch, pushes to remote, and opens a PR via GitHub CLI.
|
|
5
|
+
# Uses the current issue context to generate PR title and body.
|
|
6
|
+
#
|
|
7
|
+
# Usage: bash .pi/scripts/create-mr.sh \
|
|
8
|
+
# --issue-id "issue-github-gitlab-connector" \
|
|
9
|
+
# --epic-name "Module 1: Repository Ingestion"
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
detect_platform() {
|
|
14
|
+
# First: check guardian-manifest.json for repoTool
|
|
15
|
+
if [ -f "guardian-manifest.json" ]; then
|
|
16
|
+
local tool=$(jq -r '.repoTool // ""' guardian-manifest.json 2>/dev/null || echo "")
|
|
17
|
+
if [[ "$tool" == "glab" ]]; then echo "gitlab"; return; fi
|
|
18
|
+
if [[ "$tool" == "gh" ]]; then echo "github"; return; fi
|
|
19
|
+
fi
|
|
20
|
+
# Fallback: check environment or installed CLIs
|
|
21
|
+
if [[ -n "${GIT_PLATFORM:-}" ]]; then
|
|
22
|
+
echo "$GIT_PLATFORM"
|
|
23
|
+
elif command -v gh &>/dev/null && gh auth status &>/dev/null 2>&1; then
|
|
24
|
+
echo "github"
|
|
25
|
+
elif command -v glab &>/dev/null && glab auth status &>/dev/null 2>&1; then
|
|
26
|
+
echo "gitlab"
|
|
27
|
+
else
|
|
28
|
+
echo "none"
|
|
29
|
+
fi
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
ISSUE_ID=""
|
|
33
|
+
EPIC_NAME=""
|
|
34
|
+
|
|
35
|
+
while [[ $# -gt 0 ]]; do
|
|
36
|
+
case $1 in
|
|
37
|
+
--issue-id) ISSUE_ID="$2"; shift 2 ;;
|
|
38
|
+
--epic-name) EPIC_NAME="$2"; shift 2 ;;
|
|
39
|
+
*) shift ;;
|
|
40
|
+
esac
|
|
41
|
+
done
|
|
42
|
+
|
|
43
|
+
PLATFORM=$(detect_platform)
|
|
44
|
+
|
|
45
|
+
# Run pre-validation before creating MR
|
|
46
|
+
if ! bash .pi/scripts/validate-ci.sh 2>/dev/null; then
|
|
47
|
+
echo "CI validation failed. Aborting MR creation." >&2
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if [[ "$PLATFORM" == "none" ]]; then
|
|
53
|
+
echo "No git platform detected. Cannot create MR without gh/glab CLI."
|
|
54
|
+
echo "MR creation skipped — local only."
|
|
55
|
+
exit 0
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Determine branch name from issue ID
|
|
59
|
+
BRANCH_NAME="feature/${ISSUE_ID}"
|
|
60
|
+
|
|
61
|
+
# Ensure we're on the main branch before creating feature branch
|
|
62
|
+
git checkout -b "$BRANCH_NAME" 2>/dev/null || git checkout "$BRANCH_NAME" 2>/dev/null || true
|
|
63
|
+
|
|
64
|
+
# Push branch to remote
|
|
65
|
+
git push -u origin "$BRANCH_NAME" 2>/dev/null || git push origin "$BRANCH_NAME" 2>/dev/null || true
|
|
66
|
+
|
|
67
|
+
# Read issue file for context if available
|
|
68
|
+
ISSUE_FILE=".pi/issues/${ISSUE_ID}.md"
|
|
69
|
+
PR_BODY=""
|
|
70
|
+
if [[ -f "$ISSUE_FILE" ]]; then
|
|
71
|
+
# Extract the human-readable body (after frontmatter)
|
|
72
|
+
PR_BODY=$(awk '/^---$/{n++; next} n>=2{print}' "$ISSUE_FILE")
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
PR_TITLE="${ISSUE_ID}: Implement ${EPIC_NAME}"
|
|
76
|
+
|
|
77
|
+
case "$PLATFORM" in
|
|
78
|
+
github)
|
|
79
|
+
# Check if PR already exists
|
|
80
|
+
EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --json number 2>/dev/null || echo "[]")
|
|
81
|
+
if [[ "$EXISTING_PR" != "[]" ]]; then
|
|
82
|
+
echo "PR already exists for branch $BRANCH_NAME"
|
|
83
|
+
gh pr view --head "$BRANCH_NAME" --json url -q '.url' 2>/dev/null || true
|
|
84
|
+
exit 0
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
if [[ -n "$PR_BODY" ]]; then
|
|
88
|
+
PR_URL=$(gh pr create --head "$BRANCH_NAME" --title "$PR_TITLE" --body "$PR_BODY" 2>&1) || PR_URL=""
|
|
89
|
+
else
|
|
90
|
+
PR_URL=$(gh pr create --head "$BRANCH_NAME" --title "$PR_TITLE" 2>&1) || PR_URL=""
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
if [[ -n "$PR_URL" ]]; then
|
|
94
|
+
echo "MR_URL=$PR_URL"
|
|
95
|
+
echo "MR_BRANCH=$BRANCH_NAME"
|
|
96
|
+
else
|
|
97
|
+
echo "Failed to create PR" >&2
|
|
98
|
+
exit 1
|
|
99
|
+
fi
|
|
100
|
+
;;
|
|
101
|
+
|
|
102
|
+
gitlab)
|
|
103
|
+
if [[ -n "$PR_BODY" ]]; then
|
|
104
|
+
MR_URL=$(glab mr create --source-branch "$BRANCH_NAME" --title "$PR_TITLE" --description "$PR_BODY" 2>&1) || MR_URL=""
|
|
105
|
+
else
|
|
106
|
+
MR_URL=$(glab mr create --source-branch "$BRANCH_NAME" --title "$PR_TITLE" 2>&1) || MR_URL=""
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
if [[ -n "$MR_URL" ]]; then
|
|
110
|
+
echo "MR_URL=$MR_URL"
|
|
111
|
+
echo "MR_BRANCH=$BRANCH_NAME"
|
|
112
|
+
else
|
|
113
|
+
echo "Failed to create MR" >&2
|
|
114
|
+
exit 1
|
|
115
|
+
fi
|
|
116
|
+
;;
|
|
117
|
+
esac
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# fetch-issues.sh — Fetch Issues from GitHub or GitLab for Implementation
|
|
4
|
+
#
|
|
5
|
+
# Run as: bash .pi/scripts/fetch-issues.sh [limit] [state]
|
|
6
|
+
# Output: .claude/plans/issues-fetched.json
|
|
7
|
+
# ============================================================================
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
LIMIT="${1:-50}"
|
|
11
|
+
STATE="${2:-open}"
|
|
12
|
+
OUTPUT_DIR=".claude/plans"
|
|
13
|
+
OUTPUT_FILE="$OUTPUT_DIR/issues-fetched.json"
|
|
14
|
+
|
|
15
|
+
RED='\033[0;31m'
|
|
16
|
+
GREEN='\033[0;32m'
|
|
17
|
+
YELLOW='\033[1;33m'
|
|
18
|
+
NC='\033[0m'
|
|
19
|
+
|
|
20
|
+
detect_platform() {
|
|
21
|
+
if [ -f "guardian-manifest.json" ]; then
|
|
22
|
+
local tool=$(jq -r '.repoTool // ""' guardian-manifest.json 2>/dev/null || echo "")
|
|
23
|
+
if [[ "$tool" == "glab" ]]; then echo "gitlab"; return; fi
|
|
24
|
+
if [[ "$tool" == "gh" ]]; then echo "github"; return; fi
|
|
25
|
+
fi
|
|
26
|
+
if [[ -n "${GIT_PLATFORM:-}" ]]; then
|
|
27
|
+
echo "$GIT_PLATFORM"
|
|
28
|
+
elif command -v gh &>/dev/null && gh auth status &>/dev/null 2>&1; then
|
|
29
|
+
echo "github"
|
|
30
|
+
elif command -v glab &>/dev/null && glab auth status &>/dev/null 2>&1; then
|
|
31
|
+
echo "gitlab"
|
|
32
|
+
else
|
|
33
|
+
echo "none"
|
|
34
|
+
fi
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
echo "============================================"
|
|
38
|
+
echo " Fetch Issues"
|
|
39
|
+
echo "============================================"
|
|
40
|
+
echo ""
|
|
41
|
+
|
|
42
|
+
PLATFORM=$(detect_platform)
|
|
43
|
+
|
|
44
|
+
if [[ "$PLATFORM" == "none" ]]; then
|
|
45
|
+
echo -e "${RED}❌ No git platform detected${NC}"
|
|
46
|
+
echo " Install and authenticate gh (GitHub) or glab (GitLab) CLI."
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Ensure output directory exists
|
|
51
|
+
mkdir -p "$OUTPUT_DIR"
|
|
52
|
+
|
|
53
|
+
# ---------------------------------------------------------------------------
|
|
54
|
+
# Fetch Issues
|
|
55
|
+
# ---------------------------------------------------------------------------
|
|
56
|
+
echo "Fetching $STATE issues from $PLATFORM (limit: $LIMIT)..."
|
|
57
|
+
|
|
58
|
+
case "$PLATFORM" in
|
|
59
|
+
github)
|
|
60
|
+
gh issue list \
|
|
61
|
+
--state "$STATE" \
|
|
62
|
+
--limit "$LIMIT" \
|
|
63
|
+
--json number,title,labels,body,state,createdAt,updatedAt,assignees \
|
|
64
|
+
> "$OUTPUT_FILE"
|
|
65
|
+
;;
|
|
66
|
+
|
|
67
|
+
gitlab)
|
|
68
|
+
# glab does not export the same rich JSON schema as gh, so we build it
|
|
69
|
+
glab issue list \
|
|
70
|
+
--state "$STATE" \
|
|
71
|
+
--per-page "$LIMIT" \
|
|
72
|
+
--output json 2>/dev/null > "$OUTPUT_FILE.tmp" || true
|
|
73
|
+
|
|
74
|
+
# Convert glab output to match gh schema (if possible)
|
|
75
|
+
if [[ -s "$OUTPUT_FILE.tmp" ]]; then
|
|
76
|
+
jq '[.[] | {
|
|
77
|
+
number: (.iid // .id),
|
|
78
|
+
title,
|
|
79
|
+
labels: (.labels // []),
|
|
80
|
+
body: (.description // ""),
|
|
81
|
+
state: (.state | ascii_downcase),
|
|
82
|
+
createdAt: (.created_at // ""),
|
|
83
|
+
updatedAt: (.updated_at // ""),
|
|
84
|
+
assignees: ([.assignee? | select(. != null) | {login: .username, name: .name}] // [])
|
|
85
|
+
}]' "$OUTPUT_FILE.tmp" > "$OUTPUT_FILE" 2>/dev/null || mv "$OUTPUT_FILE.tmp" "$OUTPUT_FILE"
|
|
86
|
+
rm -f "$OUTPUT_FILE.tmp"
|
|
87
|
+
else
|
|
88
|
+
echo "[]" > "$OUTPUT_FILE"
|
|
89
|
+
rm -f "$OUTPUT_FILE.tmp"
|
|
90
|
+
fi
|
|
91
|
+
;;
|
|
92
|
+
esac
|
|
93
|
+
|
|
94
|
+
COUNT=$(jq 'length' "$OUTPUT_FILE")
|
|
95
|
+
echo -e "${GREEN}✅ Fetched $COUNT issues${NC}"
|
|
96
|
+
|
|
97
|
+
# ---------------------------------------------------------------------------
|
|
98
|
+
# Categorize by Priority
|
|
99
|
+
# ---------------------------------------------------------------------------
|
|
100
|
+
echo ""
|
|
101
|
+
echo "--- Priority Summary ---"
|
|
102
|
+
|
|
103
|
+
CRITICAL=$(jq '[.[] | select(.labels[]?.name == "critical" or .labels[]?.name == "priority/critical")] | length' "$OUTPUT_FILE")
|
|
104
|
+
HIGH=$(jq '[.[] | select(.labels[]?.name == "high" or .labels[]?.name == "priority/high")] | length' "$OUTPUT_FILE")
|
|
105
|
+
MEDIUM=$(jq '[.[] | select(.labels[]?.name == "medium" or .labels[]?.name == "priority/medium")] | length' "$OUTPUT_FILE")
|
|
106
|
+
LOW=$(jq '[.[] | select(.labels[]?.name == "low" or .labels[]?.name == "priority/low")] | length' "$OUTPUT_FILE")
|
|
107
|
+
UNLABEL=$(jq '[.[] | select(.labels | length == 0)] | length' "$OUTPUT_FILE")
|
|
108
|
+
|
|
109
|
+
echo -e " Critical: ${RED}${CRITICAL}${NC}"
|
|
110
|
+
echo -e " High: ${YELLOW}${HIGH}${NC}"
|
|
111
|
+
echo -e " Medium: ${GREEN}${MEDIUM}${NC}"
|
|
112
|
+
echo -e " Low: ${GREEN}${LOW}${NC}"
|
|
113
|
+
echo -e " No label: ${NC}${UNLABEL}${NC}"
|
|
114
|
+
|
|
115
|
+
# ---------------------------------------------------------------------------
|
|
116
|
+
# List Issues
|
|
117
|
+
# ---------------------------------------------------------------------------
|
|
118
|
+
echo ""
|
|
119
|
+
echo "--- Issue List ---"
|
|
120
|
+
jq -r '.[] | "#\(.number) - \(.title) [\(.labels[]?.name // "none")]"' "$OUTPUT_FILE" | head -20
|
|
121
|
+
|
|
122
|
+
if [ "$COUNT" -gt 20 ]; then
|
|
123
|
+
echo "... and $((COUNT - 20)) more"
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
echo ""
|
|
127
|
+
echo "============================================"
|
|
128
|
+
echo " Output: $OUTPUT_FILE"
|
|
129
|
+
echo "============================================"
|
|
130
|
+
|
|
131
|
+
exit 0
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Architecture Generator
|
|
3
|
+
#
|
|
4
|
+
# Generates canonical architecture modules from intent or existing documents.
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# bash .pi/scripts/generate-architecture.sh --intent "Build an auth system..."
|
|
8
|
+
# bash .pi/scripts/generate-architecture.sh --from "docs/prd.md,docs/design.md" --module "auth-system"
|
|
9
|
+
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
PI_DIR=".pi"
|
|
13
|
+
ARCH_DIR="${PI_DIR}/architecture"
|
|
14
|
+
MODULES_DIR="${ARCH_DIR}/modules"
|
|
15
|
+
|
|
16
|
+
INTENT=""
|
|
17
|
+
FROM_DOCS=""
|
|
18
|
+
MODULE_NAME=""
|
|
19
|
+
|
|
20
|
+
while [[ $# -gt 0 ]]; do
|
|
21
|
+
case $1 in
|
|
22
|
+
--intent) INTENT="$2"; shift 2 ;;
|
|
23
|
+
--from) FROM_DOCS="$2"; shift 2 ;;
|
|
24
|
+
--module) MODULE_NAME="$2"; shift 2 ;;
|
|
25
|
+
*) shift ;;
|
|
26
|
+
esac
|
|
27
|
+
done
|
|
28
|
+
|
|
29
|
+
# Validate inputs
|
|
30
|
+
if [[ -z "$INTENT" && -z "$FROM_DOCS" ]]; then
|
|
31
|
+
echo "Error: --intent or --from is required"
|
|
32
|
+
echo "Usage: $0 --intent \"description\" [--module name]"
|
|
33
|
+
echo " $0 --from \"file1.md,file2.md\" --module name"
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
if [[ -z "$MODULE_NAME" ]]; then
|
|
38
|
+
if [[ -n "$INTENT" ]]; then
|
|
39
|
+
# Derive module name from intent (first few words, lowercase)
|
|
40
|
+
MODULE_NAME=$(echo "$INTENT" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9 ]//g' | awk '{print $1"-"$2}' | head -c 40)
|
|
41
|
+
else
|
|
42
|
+
echo "Error: --module is required when using --from"
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
mkdir -p "$MODULES_DIR"
|
|
48
|
+
|
|
49
|
+
OUTPUT_FILE="${MODULES_DIR}/${MODULE_NAME}.md"
|
|
50
|
+
|
|
51
|
+
if [[ -f "$OUTPUT_FILE" ]]; then
|
|
52
|
+
echo "Warning: Module file already exists: $OUTPUT_FILE"
|
|
53
|
+
read -p "Overwrite? (y/N): " confirm
|
|
54
|
+
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
|
|
55
|
+
echo "Aborted."
|
|
56
|
+
exit 0
|
|
57
|
+
fi
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
echo "Generating architecture module: $OUTPUT_FILE"
|
|
61
|
+
echo ""
|
|
62
|
+
|
|
63
|
+
if [[ -n "$FROM_DOCS" ]]; then
|
|
64
|
+
# Extract content from existing documents
|
|
65
|
+
IFS=',' read -ra DOCS <<< "$FROM_DOCS"
|
|
66
|
+
echo "Reading documents:"
|
|
67
|
+
CONTEXT=""
|
|
68
|
+
for doc in "${DOCS[@]}"; do
|
|
69
|
+
doc=$(echo "$doc" | xargs) # trim whitespace
|
|
70
|
+
if [[ -f "$doc" ]]; then
|
|
71
|
+
echo " ✓ $doc"
|
|
72
|
+
CONTEXT="${CONTEXT}
|
|
73
|
+
--- Content from ${doc} ---
|
|
74
|
+
$(cat "$doc")
|
|
75
|
+
"
|
|
76
|
+
else
|
|
77
|
+
echo " ✗ $doc (not found)"
|
|
78
|
+
fi
|
|
79
|
+
done
|
|
80
|
+
|
|
81
|
+
echo ""
|
|
82
|
+
echo "=== EXTRACTED CONTEXT ==="
|
|
83
|
+
echo "$CONTEXT" | head -100
|
|
84
|
+
echo "..."
|
|
85
|
+
echo ""
|
|
86
|
+
echo "Generate the architecture module based on these documents."
|
|
87
|
+
echo "Run the /architect-generate command with the agent to create the module."
|
|
88
|
+
|
|
89
|
+
elif [[ -n "$INTENT" ]]; then
|
|
90
|
+
echo "Intent: $INTENT"
|
|
91
|
+
echo ""
|
|
92
|
+
|
|
93
|
+
# Generate a structured module template from intent
|
|
94
|
+
cat > "$OUTPUT_FILE" << TEMPLATE
|
|
95
|
+
# ${MODULE_NAME//-/ }
|
|
96
|
+
|
|
97
|
+
> Generated from intent on $(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
98
|
+
> Intent: ${INTENT}
|
|
99
|
+
|
|
100
|
+
## Overview
|
|
101
|
+
|
|
102
|
+
> TODO: Fill in the module overview based on the intent above.
|
|
103
|
+
|
|
104
|
+
## Components
|
|
105
|
+
|
|
106
|
+
### Component 1: [Name]
|
|
107
|
+
status: planned
|
|
108
|
+
description: [TODO: Describe what this component does]
|
|
109
|
+
depends: [TODO: List dependencies, or "none"]
|
|
110
|
+
|
|
111
|
+
### Component 2: [Name]
|
|
112
|
+
status: planned
|
|
113
|
+
description: [TODO: Describe what this component does]
|
|
114
|
+
depends: [TODO: Component 1, or other dependencies]
|
|
115
|
+
|
|
116
|
+
### Component 3: [Name]
|
|
117
|
+
status: planned
|
|
118
|
+
description: [TODO: Describe what this component does]
|
|
119
|
+
depends: [TODO: Dependencies]
|
|
120
|
+
|
|
121
|
+
### Architecture Observability
|
|
122
|
+
status: planned
|
|
123
|
+
description: Runbook, DR plan, metrics, tracing for the ${MODULE_NAME//-/ } module.
|
|
124
|
+
depends: [TODO: All other components]
|
|
125
|
+
|
|
126
|
+
## Interfaces
|
|
127
|
+
|
|
128
|
+
### Inputs
|
|
129
|
+
- [TODO: What does this module receive?]
|
|
130
|
+
|
|
131
|
+
### Outputs
|
|
132
|
+
- [TODO: What does this module produce?]
|
|
133
|
+
|
|
134
|
+
## Dependencies
|
|
135
|
+
|
|
136
|
+
### Internal
|
|
137
|
+
- [TODO: Other Guardian modules this depends on]
|
|
138
|
+
|
|
139
|
+
### External
|
|
140
|
+
- [TODO: Third-party services, APIs, databases]
|
|
141
|
+
|
|
142
|
+
## Failure Modes
|
|
143
|
+
|
|
144
|
+
- [TODO: What happens when this module fails?]
|
|
145
|
+
- [TODO: Recovery strategies]
|
|
146
|
+
|
|
147
|
+
## Security Considerations
|
|
148
|
+
|
|
149
|
+
- [TODO: Authentication, authorization, data protection]
|
|
150
|
+
TEMPLATE
|
|
151
|
+
|
|
152
|
+
echo "✓ Module template created: $OUTPUT_FILE"
|
|
153
|
+
echo ""
|
|
154
|
+
echo "Next steps:"
|
|
155
|
+
echo "1. Edit $OUTPUT_FILE to fill in the TODO sections"
|
|
156
|
+
echo "2. Run: /architect --epic \"${MODULE_NAME//-/ } v1\""
|
|
157
|
+
echo "3. Guardian will discover the planned components and generate issues"
|
|
158
|
+
fi
|
|
159
|
+
|
|
160
|
+
echo ""
|
|
161
|
+
echo "Done."
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Git Wrapper: Close Epic
|
|
3
|
+
#
|
|
4
|
+
# Closes the epic and all linked issues when the epic is complete.
|
|
5
|
+
#
|
|
6
|
+
# Usage: bash .pi/scripts/git/close-epic.sh \
|
|
7
|
+
# --epic-id 101 \
|
|
8
|
+
# --tracking-id 100 \
|
|
9
|
+
# --comment "Epic complete. All 5 issues done."
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
detect_platform() {
|
|
14
|
+
if [ -f "guardian-manifest.json" ]; then
|
|
15
|
+
local tool=$(jq -r '.repoTool // ""' guardian-manifest.json 2>/dev/null || echo "")
|
|
16
|
+
if [[ "$tool" == "glab" ]]; then echo "gitlab"; return; fi
|
|
17
|
+
if [[ "$tool" == "gh" ]]; then echo "github"; return; fi
|
|
18
|
+
fi
|
|
19
|
+
if [[ -n "${GIT_PLATFORM:-}" ]]; then echo "$GIT_PLATFORM"
|
|
20
|
+
elif command -v gh &>/dev/null && gh auth status &>/dev/null 2>&1; then echo "github"
|
|
21
|
+
elif command -v glab &>/dev/null && glab auth status &>/dev/null 2>&1; then echo "gitlab"
|
|
22
|
+
else echo "none"; fi
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
EPIC_ID=""
|
|
26
|
+
TRACKING_ID=""
|
|
27
|
+
COMMENT="Epic complete."
|
|
28
|
+
|
|
29
|
+
while [[ $# -gt 0 ]]; do
|
|
30
|
+
case $1 in
|
|
31
|
+
--epic-id) EPIC_ID="$2"; shift 2 ;;
|
|
32
|
+
--tracking-id) TRACKING_ID="$2"; shift 2 ;;
|
|
33
|
+
--comment) COMMENT="$2"; shift 2 ;;
|
|
34
|
+
*) shift ;;
|
|
35
|
+
esac
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
PLATFORM=$(detect_platform)
|
|
39
|
+
|
|
40
|
+
if [[ -z "$EPIC_ID" ]]; then
|
|
41
|
+
echo "Usage: $0 --epic-id <epic_number> [--tracking-id <tracking_id>] [--comment <comment>]"
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Close tracking issue first
|
|
46
|
+
if [[ -n "$TRACKING_ID" ]]; then
|
|
47
|
+
bash "$(dirname "$0")/close-issue.sh" --id "$TRACKING_ID"
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Close the epic
|
|
51
|
+
case "$PLATFORM" in
|
|
52
|
+
github)
|
|
53
|
+
gh issue close "$EPIC_ID" 2>/dev/null
|
|
54
|
+
if [[ -n "$COMMENT" ]]; then
|
|
55
|
+
gh issue comment "$EPIC_ID" --body "$COMMENT" 2>/dev/null
|
|
56
|
+
fi
|
|
57
|
+
echo "Closed GitHub epic #$EPIC_ID"
|
|
58
|
+
;;
|
|
59
|
+
gitlab)
|
|
60
|
+
glab issue update "$EPIC_ID" --state-event close 2>/dev/null
|
|
61
|
+
if [[ -n "$COMMENT" ]]; then
|
|
62
|
+
glab issue note "$EPIC_ID" --message "$COMMENT" 2>/dev/null
|
|
63
|
+
fi
|
|
64
|
+
echo "Closed GitLab epic #$EPIC_ID"
|
|
65
|
+
;;
|
|
66
|
+
*)
|
|
67
|
+
echo "Local epic #$EPIC_ID closed (no platform)"
|
|
68
|
+
;;
|
|
69
|
+
esac
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Git Wrapper: Close Issue
|
|
3
|
+
#
|
|
4
|
+
# Usage: bash .pi/scripts/git/close-issue.sh --id 101
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
detect_platform() {
|
|
9
|
+
if [ -f "guardian-manifest.json" ]; then
|
|
10
|
+
local tool=$(jq -r '.repoTool // ""' guardian-manifest.json 2>/dev/null || echo "")
|
|
11
|
+
if [[ "$tool" == "glab" ]]; then echo "gitlab"; return; fi
|
|
12
|
+
if [[ "$tool" == "gh" ]]; then echo "github"; return; fi
|
|
13
|
+
fi
|
|
14
|
+
if [[ -n "${GIT_PLATFORM:-}" ]]; then echo "$GIT_PLATFORM"
|
|
15
|
+
elif command -v gh &>/dev/null && gh auth status &>/dev/null 2>&1; then echo "github"
|
|
16
|
+
elif command -v glab &>/dev/null && glab auth status &>/dev/null 2>&1; then echo "gitlab"
|
|
17
|
+
else echo "none"; fi
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
ISSUE_ID=""
|
|
21
|
+
while [[ $# -gt 0 ]]; do
|
|
22
|
+
case $1 in
|
|
23
|
+
--id) ISSUE_ID="$2"; shift 2 ;;
|
|
24
|
+
*) shift ;;
|
|
25
|
+
esac
|
|
26
|
+
done
|
|
27
|
+
|
|
28
|
+
[[ -z "$ISSUE_ID" ]] && { echo "Usage: $0 --id <issue_number>"; exit 1; }
|
|
29
|
+
PLATFORM=$(detect_platform)
|
|
30
|
+
|
|
31
|
+
case "$PLATFORM" in
|
|
32
|
+
github) gh issue close "$ISSUE_ID" 2>/dev/null && echo "Closed GitHub issue #$ISSUE_ID" ;;
|
|
33
|
+
gitlab) glab issue update "$ISSUE_ID" --state-event close 2>/dev/null && echo "Closed GitLab issue #$ISSUE_ID" ;;
|
|
34
|
+
*) echo "Local issue #$ISSUE_ID marked as closed (no platform)" ;;
|
|
35
|
+
esac
|