@pareto4/pp-core 1.7.1 → 1.8.1
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/.claude-plugin/plugin.json +1 -1
- package/bin/install.js +197 -81
- package/commands/pp-build-handoff.md +8 -2
- package/commands/pp-discovery-to-build.md +40 -0
- package/commands/pp-ns-project.md +3 -1
- package/gemini-extension.json +1 -1
- package/package.json +2 -1
- package/pareto-skills/_shared/create-project-board.sh +195 -0
- package/pareto-skills/_shared/pp-claude-md-protocol.md +306 -0
- package/pareto-skills/_shared/sync-phase-status.sh +139 -0
- package/pareto-skills/pp-brand/SKILL.md +644 -0
- package/pareto-skills/pp-brand/assets/crew/ParetoAgent.inline.html +120 -0
- package/pareto-skills/pp-brand/assets/crew/ParetoAgent.tsx +239 -0
- package/pareto-skills/pp-brand/assets/crew/build.svg +11 -0
- package/pareto-skills/pp-brand/assets/crew/deploy.svg +11 -0
- package/pareto-skills/pp-brand/assets/crew/discovery.svg +11 -0
- package/pareto-skills/pp-brand/assets/crew/plan.svg +11 -0
- package/pareto-skills/pp-brand/assets/crew/run.svg +11 -0
- package/pareto-skills/pp-brand/assets/crew/validate.svg +11 -0
- package/pareto-skills/pp-brand/assets/pareto-brand-preview.html +547 -0
- package/pareto-skills/pp-obsidian-notes/SKILL.md +127 -0
- package/pareto-skills/pp-obsidian-notes/templates/CLAUDE.md +29 -0
- package/pareto-skills/pp-obsidian-notes/templates/client-context.md +116 -0
- package/pareto-skills/pp-obsidian-notes/templates/meeting-note.md +66 -0
- package/pareto-skills/pp-obsidian-notes/templates/pareto-context.md +102 -0
- package/pareto-skills/pp-obsidian-notes/templates/proposal.md +117 -0
- package/pareto-skills/pp-project-setup/SKILL.md +1364 -0
- package/pp-core/bin/lib/clusters.cjs +4 -0
- package/pp-core/bin/lib/intel.cjs +1 -1
- package/pp-core/bin/lib/io.cjs +120 -0
- package/pp-core/bin/lib/profile-pipeline-command-router.cjs +1 -1
- package/pp-core/bin/lib/roadmap-parser.cjs +1 -1
- package/pp-core/bin/lib/runtime-artifact-conversion.cjs +2 -2
- package/pp-core/bin/lib/surface.cjs +1 -1
- package/pp-core/bin/lib/worktree-safety.cjs +2 -2
- package/pp-core/bin/pp-tools.cjs +23 -0
- package/pp-core/references/ui-brand.md +73 -11
- package/pp-core/templates/codebase/structure.md +5 -5
- package/pp-core/templates/spec.md +7 -7
- package/pp-core/workflows/add-backlog.md +1 -1
- package/pp-core/workflows/autonomous.md +4 -4
- package/pp-core/workflows/debug.md +1 -1
- package/pp-core/workflows/{build-handoff.md → discovery-to-build.md} +6 -3
- package/pp-core/workflows/execute-phase.md +9 -1
- package/pp-core/workflows/plan-phase.md +14 -12
- package/pp-core/workflows/pr-branch.md +5 -4
- package/pp-core/workflows/reapply-patches.md +1 -1
- package/pp-core/workflows/ship.md +1 -1
- package/pp-core/workflows/thread.md +1 -1
- package/pp-core/workflows/verify-work.md +6 -5
- package/scripts/lint-allow-test-rule-refs.allowlist.json +1 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# sync-phase-status.sh
|
|
3
|
+
#
|
|
4
|
+
# Move GitHub issues for a pp-core phase to a target board status.
|
|
5
|
+
# Reads .planning/github-issues.json to find issues mapped to the phase,
|
|
6
|
+
# then updates labels and board column.
|
|
7
|
+
#
|
|
8
|
+
# Used by pp-core workflows (plan-phase, execute-phase) at lifecycle transitions.
|
|
9
|
+
# Non-blocking — failures are logged but never stop the pp-core workflow.
|
|
10
|
+
#
|
|
11
|
+
# Usage:
|
|
12
|
+
# bash sync-phase-status.sh <phase_number> <target_status> [--label-add X] [--label-remove Y]
|
|
13
|
+
#
|
|
14
|
+
# Examples:
|
|
15
|
+
# bash sync-phase-status.sh 4 "To Do"
|
|
16
|
+
# bash sync-phase-status.sh 4 "In Progress" --label-add in-progress --label-remove verification
|
|
17
|
+
# bash sync-phase-status.sh 4 "Verification" --label-add verification --label-remove in-progress
|
|
18
|
+
#
|
|
19
|
+
# Environment:
|
|
20
|
+
# GITHUB_ISSUES_JSON — path to mapping file (default: .planning/github-issues.json)
|
|
21
|
+
#
|
|
22
|
+
# Exit code: always 0 (non-blocking). Errors go to stderr.
|
|
23
|
+
|
|
24
|
+
set -uo pipefail
|
|
25
|
+
|
|
26
|
+
PHASE="$1"
|
|
27
|
+
TARGET_STATUS="$2"
|
|
28
|
+
shift 2
|
|
29
|
+
|
|
30
|
+
LABEL_ADD=""
|
|
31
|
+
LABEL_REMOVE=""
|
|
32
|
+
|
|
33
|
+
while [[ $# -gt 0 ]]; do
|
|
34
|
+
case "$1" in
|
|
35
|
+
--label-add) LABEL_ADD="$2"; shift 2 ;;
|
|
36
|
+
--label-remove) LABEL_REMOVE="$2"; shift 2 ;;
|
|
37
|
+
*) shift ;;
|
|
38
|
+
esac
|
|
39
|
+
done
|
|
40
|
+
|
|
41
|
+
MAPPING="${GITHUB_ISSUES_JSON:-.planning/github-issues.json}"
|
|
42
|
+
|
|
43
|
+
if [ ! -f "$MAPPING" ]; then
|
|
44
|
+
echo "sync-phase-status: no mapping file at $MAPPING — skipping board sync" >&2
|
|
45
|
+
exit 0
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Extract repo and board info
|
|
49
|
+
REPO=$(jq -r '.repo // empty' "$MAPPING" 2>/dev/null)
|
|
50
|
+
BOARD_NUM=$(jq -r '.board.number // empty' "$MAPPING" 2>/dev/null)
|
|
51
|
+
BOARD_OWNER=$(jq -r '.board.owner // empty' "$MAPPING" 2>/dev/null)
|
|
52
|
+
|
|
53
|
+
if [ -z "$REPO" ]; then
|
|
54
|
+
echo "sync-phase-status: no repo in mapping file — skipping" >&2
|
|
55
|
+
exit 0
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Get all issue numbers for this phase (stories only — EPICs are derived)
|
|
59
|
+
ISSUE_NUMBERS=$(jq -r --arg p "$PHASE" '
|
|
60
|
+
[.issues | to_entries[]
|
|
61
|
+
| select(.value.phase == ($p | tonumber) and .value.type == "story")
|
|
62
|
+
| .value.number] | .[]
|
|
63
|
+
' "$MAPPING" 2>/dev/null)
|
|
64
|
+
|
|
65
|
+
if [ -z "$ISSUE_NUMBERS" ]; then
|
|
66
|
+
echo "sync-phase-status: no stories mapped to phase $PHASE — skipping" >&2
|
|
67
|
+
exit 0
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
COUNT=$(echo "$ISSUE_NUMBERS" | wc -l | tr -d ' ')
|
|
71
|
+
echo "sync-phase-status: moving $COUNT stories for phase $PHASE → $TARGET_STATUS"
|
|
72
|
+
|
|
73
|
+
# Update labels on each issue
|
|
74
|
+
for NUM in $ISSUE_NUMBERS; do
|
|
75
|
+
LABEL_CMD="gh issue edit $NUM -R $REPO"
|
|
76
|
+
[ -n "$LABEL_ADD" ] && LABEL_CMD="$LABEL_CMD --add-label $LABEL_ADD"
|
|
77
|
+
[ -n "$LABEL_REMOVE" ] && LABEL_CMD="$LABEL_CMD --remove-label $LABEL_REMOVE"
|
|
78
|
+
|
|
79
|
+
if [ -n "$LABEL_ADD" ] || [ -n "$LABEL_REMOVE" ]; then
|
|
80
|
+
eval "$LABEL_CMD" 2>/dev/null || echo " warn: label update failed for #$NUM" >&2
|
|
81
|
+
fi
|
|
82
|
+
done
|
|
83
|
+
|
|
84
|
+
# Update board column (if board info available)
|
|
85
|
+
if [ -n "$BOARD_NUM" ] && [ -n "$BOARD_OWNER" ]; then
|
|
86
|
+
# Resolve board project ID and Status field
|
|
87
|
+
PROJECT_ID=$(gh project view "$BOARD_NUM" --owner "$BOARD_OWNER" --format json --jq '.id' 2>/dev/null)
|
|
88
|
+
|
|
89
|
+
if [ -z "$PROJECT_ID" ]; then
|
|
90
|
+
echo "sync-phase-status: could not resolve project board — skipping column update" >&2
|
|
91
|
+
exit 0
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
STATUS_FIELD_ID=$(gh project field-list "$BOARD_NUM" --owner "$BOARD_OWNER" --format json \
|
|
95
|
+
--jq '.fields[] | select(.name=="Status") | .id' 2>/dev/null)
|
|
96
|
+
|
|
97
|
+
OPTION_ID=$(gh project field-list "$BOARD_NUM" --owner "$BOARD_OWNER" --format json \
|
|
98
|
+
--jq ".fields[] | select(.name==\"Status\") | .options[] | select(.name==\"$TARGET_STATUS\") | .id" 2>/dev/null)
|
|
99
|
+
|
|
100
|
+
if [ -z "$STATUS_FIELD_ID" ] || [ -z "$OPTION_ID" ]; then
|
|
101
|
+
echo "sync-phase-status: could not resolve Status field or option '$TARGET_STATUS' — skipping column update" >&2
|
|
102
|
+
exit 0
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# Get all board items and match by issue number (--limit 200 to avoid default 30 cap)
|
|
106
|
+
ITEMS_JSON=$(gh project item-list "$BOARD_NUM" --owner "$BOARD_OWNER" --format json --limit 200 2>/dev/null)
|
|
107
|
+
|
|
108
|
+
for NUM in $ISSUE_NUMBERS; do
|
|
109
|
+
ITEM_ID=$(echo "$ITEMS_JSON" | jq -r --argjson n "$NUM" '
|
|
110
|
+
.items[] | select(.content.number == $n) | .id
|
|
111
|
+
' 2>/dev/null)
|
|
112
|
+
|
|
113
|
+
if [ -n "$ITEM_ID" ] && [ "$ITEM_ID" != "null" ]; then
|
|
114
|
+
gh project item-edit \
|
|
115
|
+
--project-id "$PROJECT_ID" \
|
|
116
|
+
--id "$ITEM_ID" \
|
|
117
|
+
--field-id "$STATUS_FIELD_ID" \
|
|
118
|
+
--single-select-option-id "$OPTION_ID" 2>/dev/null \
|
|
119
|
+
&& echo " ✓ #$NUM → $TARGET_STATUS" \
|
|
120
|
+
|| echo " warn: board update failed for #$NUM" >&2
|
|
121
|
+
else
|
|
122
|
+
echo " warn: #$NUM not found on board — skipping column update" >&2
|
|
123
|
+
fi
|
|
124
|
+
done
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
# Update status in the mapping file
|
|
128
|
+
jq --arg p "$PHASE" --arg s "$TARGET_STATUS" '
|
|
129
|
+
.issues |= with_entries(
|
|
130
|
+
if (.value.phase == ($p | tonumber) and .value.type == "story")
|
|
131
|
+
then .value.status = $s
|
|
132
|
+
else .
|
|
133
|
+
end
|
|
134
|
+
)
|
|
135
|
+
| .last_synced = (now | strftime("%Y-%m-%d"))
|
|
136
|
+
' "$MAPPING" > "${MAPPING}.tmp" && mv "${MAPPING}.tmp" "$MAPPING"
|
|
137
|
+
|
|
138
|
+
echo "sync-phase-status: done — $COUNT stories updated in mapping"
|
|
139
|
+
exit 0
|