@wipcomputer/wip-ai-devops-toolbox 1.9.20
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-guard.json +7 -0
- package/.publish-skill.json +4 -0
- package/CHANGELOG.md +1120 -0
- package/CLA.md +19 -0
- package/DEV-GUIDE-GENERAL-PUBLIC.md +882 -0
- package/LICENSE +52 -0
- package/README.md +238 -0
- package/SKILL.md +728 -0
- package/TECHNICAL.md +282 -0
- package/UNIVERSAL-INTERFACE.md +180 -0
- package/_trash/RELEASE-NOTES-v1-8-0.md +29 -0
- package/_trash/RELEASE-NOTES-v1-8-1.md +7 -0
- package/_trash/RELEASE-NOTES-v1-8-2.md +7 -0
- package/_trash/RELEASE-NOTES-v1-9-0.md +37 -0
- package/_trash/RELEASE-NOTES-v1-9-1.md +38 -0
- package/_trash/RELEASE-NOTES-v1-9-10.md +40 -0
- package/_trash/RELEASE-NOTES-v1-9-2.md +40 -0
- package/_trash/RELEASE-NOTES-v1-9-6.md +72 -0
- package/_trash/RELEASE-NOTES-v1-9-7.md +23 -0
- package/_trash/RELEASE-NOTES-v1-9-9.md +75 -0
- package/_trash/guide 2/DEV-GUIDE.md +487 -0
- package/_trash/guide 2/scripts/deploy-public.sh +152 -0
- package/package.json +27 -0
- package/scripts/SKILL-deploy-public.md +61 -0
- package/scripts/SKILL-post-merge-rename.md +47 -0
- package/scripts/deploy-public.sh +264 -0
- package/scripts/post-merge-rename.sh +205 -0
- package/scripts/publish-skill.sh +134 -0
- package/tools/deploy-public/LICENSE +52 -0
- package/tools/deploy-public/README.md +31 -0
- package/tools/deploy-public/SKILL.md +71 -0
- package/tools/deploy-public/deploy-public.sh +264 -0
- package/tools/deploy-public/package.json +9 -0
- package/tools/ldm-jobs/LICENSE +52 -0
- package/tools/ldm-jobs/README.md +46 -0
- package/tools/ldm-jobs/backup.sh +16 -0
- package/tools/ldm-jobs/branch-protect.sh +39 -0
- package/tools/ldm-jobs/crystal-capture.sh +19 -0
- package/tools/ldm-jobs/setup-shell.sh +27 -0
- package/tools/ldm-jobs/visibility-audit.sh +27 -0
- package/tools/post-merge-rename/LICENSE +52 -0
- package/tools/post-merge-rename/README.md +29 -0
- package/tools/post-merge-rename/SKILL.md +57 -0
- package/tools/post-merge-rename/package.json +9 -0
- package/tools/post-merge-rename/post-merge-rename.sh +122 -0
- package/tools/wip-branch-guard/INSTALL.md +41 -0
- package/tools/wip-branch-guard/guard.mjs +259 -0
- package/tools/wip-branch-guard/package.json +11 -0
- package/tools/wip-file-guard/CHANGELOG.md +6 -0
- package/tools/wip-file-guard/LICENSE +52 -0
- package/tools/wip-file-guard/README.md +113 -0
- package/tools/wip-file-guard/REFERENCE.md +86 -0
- package/tools/wip-file-guard/SKILL.md +105 -0
- package/tools/wip-file-guard/guard.mjs +128 -0
- package/tools/wip-file-guard/openclaw.plugin.json +8 -0
- package/tools/wip-file-guard/package.json +27 -0
- package/tools/wip-file-guard/test.sh +119 -0
- package/tools/wip-license-guard/LICENSE +52 -0
- package/tools/wip-license-guard/README.md +32 -0
- package/tools/wip-license-guard/SKILL.md +65 -0
- package/tools/wip-license-guard/cli.mjs +464 -0
- package/tools/wip-license-guard/core.mjs +310 -0
- package/tools/wip-license-guard/hook.mjs +146 -0
- package/tools/wip-license-guard/package.json +15 -0
- package/tools/wip-license-hook/CHANGELOG.md +17 -0
- package/tools/wip-license-hook/LICENSE +52 -0
- package/tools/wip-license-hook/README.md +200 -0
- package/tools/wip-license-hook/SKILL.md +111 -0
- package/tools/wip-license-hook/dist/cli/index.d.ts +15 -0
- package/tools/wip-license-hook/dist/cli/index.js +170 -0
- package/tools/wip-license-hook/dist/cli/index.js.map +1 -0
- package/tools/wip-license-hook/dist/core/detector.d.ts +12 -0
- package/tools/wip-license-hook/dist/core/detector.js +104 -0
- package/tools/wip-license-hook/dist/core/detector.js.map +1 -0
- package/tools/wip-license-hook/dist/core/index.d.ts +4 -0
- package/tools/wip-license-hook/dist/core/index.js +5 -0
- package/tools/wip-license-hook/dist/core/index.js.map +1 -0
- package/tools/wip-license-hook/dist/core/ledger.d.ts +49 -0
- package/tools/wip-license-hook/dist/core/ledger.js +72 -0
- package/tools/wip-license-hook/dist/core/ledger.js.map +1 -0
- package/tools/wip-license-hook/dist/core/reporter.d.ts +14 -0
- package/tools/wip-license-hook/dist/core/reporter.js +227 -0
- package/tools/wip-license-hook/dist/core/reporter.js.map +1 -0
- package/tools/wip-license-hook/dist/core/scanner.d.ts +39 -0
- package/tools/wip-license-hook/dist/core/scanner.js +325 -0
- package/tools/wip-license-hook/dist/core/scanner.js.map +1 -0
- package/tools/wip-license-hook/hooks/pre-pull.sh +55 -0
- package/tools/wip-license-hook/hooks/pre-push.sh +51 -0
- package/tools/wip-license-hook/mcp-server.mjs +119 -0
- package/tools/wip-license-hook/package-lock.json +54 -0
- package/tools/wip-license-hook/package.json +43 -0
- package/tools/wip-license-hook/src/cli/index.ts +189 -0
- package/tools/wip-license-hook/src/core/detector.ts +130 -0
- package/tools/wip-license-hook/src/core/index.ts +4 -0
- package/tools/wip-license-hook/src/core/ledger.ts +116 -0
- package/tools/wip-license-hook/src/core/reporter.ts +255 -0
- package/tools/wip-license-hook/src/core/scanner.ts +367 -0
- package/tools/wip-license-hook/tsconfig.json +16 -0
- package/tools/wip-readme-format/README.md +49 -0
- package/tools/wip-readme-format/SKILL.md +84 -0
- package/tools/wip-readme-format/format.mjs +570 -0
- package/tools/wip-readme-format/package.json +15 -0
- package/tools/wip-release/CHANGELOG.md +42 -0
- package/tools/wip-release/LICENSE +52 -0
- package/tools/wip-release/README.md +45 -0
- package/tools/wip-release/REFERENCE.md +100 -0
- package/tools/wip-release/SKILL.md +139 -0
- package/tools/wip-release/cli.js +161 -0
- package/tools/wip-release/core.mjs +1174 -0
- package/tools/wip-release/mcp-server.mjs +109 -0
- package/tools/wip-release/package.json +36 -0
- package/tools/wip-repo-init/README.md +38 -0
- package/tools/wip-repo-init/SKILL.md +77 -0
- package/tools/wip-repo-init/init.mjs +142 -0
- package/tools/wip-repo-init/package.json +11 -0
- package/tools/wip-repo-permissions-hook/LICENSE +52 -0
- package/tools/wip-repo-permissions-hook/README.md +86 -0
- package/tools/wip-repo-permissions-hook/SKILL.md +73 -0
- package/tools/wip-repo-permissions-hook/cli.js +83 -0
- package/tools/wip-repo-permissions-hook/core.mjs +122 -0
- package/tools/wip-repo-permissions-hook/guard.mjs +64 -0
- package/tools/wip-repo-permissions-hook/mcp-server.mjs +92 -0
- package/tools/wip-repo-permissions-hook/openclaw.plugin.json +8 -0
- package/tools/wip-repo-permissions-hook/package.json +31 -0
- package/tools/wip-repos/LICENSE +52 -0
- package/tools/wip-repos/README.md +77 -0
- package/tools/wip-repos/SKILL.md +80 -0
- package/tools/wip-repos/cli.mjs +176 -0
- package/tools/wip-repos/core.mjs +290 -0
- package/tools/wip-repos/mcp-server.mjs +157 -0
- package/tools/wip-repos/package.json +34 -0
- package/tools/wip-universal-installer/CHANGELOG.md +57 -0
- package/tools/wip-universal-installer/LICENSE +52 -0
- package/tools/wip-universal-installer/README.md +81 -0
- package/tools/wip-universal-installer/REFERENCE.md +122 -0
- package/tools/wip-universal-installer/SKILL.md +87 -0
- package/tools/wip-universal-installer/SPEC.md +180 -0
- package/tools/wip-universal-installer/detect.mjs +130 -0
- package/tools/wip-universal-installer/examples/minimal/README.md +20 -0
- package/tools/wip-universal-installer/examples/minimal/SKILL.md +28 -0
- package/tools/wip-universal-installer/examples/minimal/cli.mjs +4 -0
- package/tools/wip-universal-installer/examples/minimal/core.mjs +8 -0
- package/tools/wip-universal-installer/examples/minimal/mcp-server.mjs +27 -0
- package/tools/wip-universal-installer/examples/minimal/package.json +12 -0
- package/tools/wip-universal-installer/install.js +930 -0
- package/tools/wip-universal-installer/package.json +36 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# post-merge-rename.sh
|
|
4
|
+
# Scans for branches merged into main and renames them with --merged-YYYY-MM-DD.
|
|
5
|
+
# Branches already renamed (containing --merged-) are skipped.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# bash post-merge-rename.sh # scan + rename all
|
|
9
|
+
# bash post-merge-rename.sh <branch> # rename a specific branch
|
|
10
|
+
# bash post-merge-rename.sh --dry-run # preview only
|
|
11
|
+
# bash post-merge-rename.sh --prune # rename + delete old merged branches (keep last 3 per developer)
|
|
12
|
+
# bash post-merge-rename.sh --prune --dry-run # preview prune
|
|
13
|
+
#
|
|
14
|
+
# Run this after merging a PR, or periodically to catch missed renames.
|
|
15
|
+
#
|
|
16
|
+
# Author: CC-mini (Opus 4.6)
|
|
17
|
+
# Date: 2026-03-08
|
|
18
|
+
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
DRY_RUN=false
|
|
22
|
+
PRUNE=false
|
|
23
|
+
SPECIFIC_BRANCH=""
|
|
24
|
+
KEEP_COUNT=3
|
|
25
|
+
|
|
26
|
+
for arg in "$@"; do
|
|
27
|
+
case "$arg" in
|
|
28
|
+
--dry-run) DRY_RUN=true ;;
|
|
29
|
+
--prune) PRUNE=true ;;
|
|
30
|
+
--help|-h)
|
|
31
|
+
echo "Usage: post-merge-rename.sh [<branch>] [--dry-run] [--prune]"
|
|
32
|
+
echo ""
|
|
33
|
+
echo "Scans for branches merged into main and renames them"
|
|
34
|
+
echo "with --merged-YYYY-MM-DD suffix."
|
|
35
|
+
echo ""
|
|
36
|
+
echo " --prune After renaming, delete old --merged branches."
|
|
37
|
+
echo " Keeps the last $KEEP_COUNT per developer prefix."
|
|
38
|
+
echo " Also deletes stale branches whose PRs are merged"
|
|
39
|
+
echo " but were never renamed."
|
|
40
|
+
exit 0
|
|
41
|
+
;;
|
|
42
|
+
*) SPECIFIC_BRANCH="$arg" ;;
|
|
43
|
+
esac
|
|
44
|
+
done
|
|
45
|
+
|
|
46
|
+
# Must be in a git repo
|
|
47
|
+
if ! git rev-parse --is-inside-work-tree &>/dev/null; then
|
|
48
|
+
echo "Error: not inside a git repo."
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Fetch latest remote state
|
|
53
|
+
git fetch origin --prune 2>/dev/null || true
|
|
54
|
+
|
|
55
|
+
rename_branch() {
|
|
56
|
+
local branch="$1"
|
|
57
|
+
local trimmed
|
|
58
|
+
trimmed=$(echo "$branch" | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//')
|
|
59
|
+
|
|
60
|
+
# Skip main
|
|
61
|
+
[[ "$trimmed" == "main" || "$trimmed" == "master" ]] && return
|
|
62
|
+
|
|
63
|
+
# Skip already renamed
|
|
64
|
+
[[ "$trimmed" == *"--merged-"* ]] && return
|
|
65
|
+
|
|
66
|
+
# Skip current branch (can't rename the checked-out branch)
|
|
67
|
+
local current
|
|
68
|
+
current=$(git branch --show-current)
|
|
69
|
+
if [[ "$trimmed" == "$current" ]]; then
|
|
70
|
+
echo " SKIP $trimmed (currently checked out)"
|
|
71
|
+
return
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# Find merge date: when this branch's tip became reachable from main
|
|
75
|
+
local merge_date
|
|
76
|
+
merge_date=$(git log main --format="%ai" --ancestry-path "$(git merge-base main "$trimmed" 2>/dev/null)..main" 2>/dev/null | tail -1 | cut -d' ' -f1)
|
|
77
|
+
|
|
78
|
+
# Fallback: use the branch tip's own date
|
|
79
|
+
if [[ -z "$merge_date" ]]; then
|
|
80
|
+
merge_date=$(git log "$trimmed" -1 --format="%ai" 2>/dev/null | cut -d' ' -f1)
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
if [[ -z "$merge_date" ]]; then
|
|
84
|
+
echo " SKIP $trimmed (could not determine merge date)"
|
|
85
|
+
return
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
local new_name="${trimmed}--merged-${merge_date}"
|
|
89
|
+
|
|
90
|
+
if $DRY_RUN; then
|
|
91
|
+
echo " [dry-run] $trimmed -> $new_name"
|
|
92
|
+
else
|
|
93
|
+
echo " Renaming: $trimmed -> $new_name"
|
|
94
|
+
|
|
95
|
+
# Rename local
|
|
96
|
+
git branch -m "$trimmed" "$new_name" 2>/dev/null || true
|
|
97
|
+
|
|
98
|
+
# Push new name to remote
|
|
99
|
+
git push origin "$new_name" 2>/dev/null || true
|
|
100
|
+
|
|
101
|
+
# Remove old name from remote
|
|
102
|
+
git push origin --delete "$trimmed" 2>/dev/null || true
|
|
103
|
+
fi
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if [[ -n "$SPECIFIC_BRANCH" && "$SPECIFIC_BRANCH" != "--dry-run" ]]; then
|
|
107
|
+
# Rename a specific branch
|
|
108
|
+
echo "Checking branch: $SPECIFIC_BRANCH"
|
|
109
|
+
if git merge-base --is-ancestor "$SPECIFIC_BRANCH" main 2>/dev/null; then
|
|
110
|
+
rename_branch "$SPECIFIC_BRANCH"
|
|
111
|
+
else
|
|
112
|
+
echo " $SPECIFIC_BRANCH is NOT merged into main. Leaving as-is."
|
|
113
|
+
fi
|
|
114
|
+
else
|
|
115
|
+
# Scan all local branches merged into main
|
|
116
|
+
echo "Scanning for merged branches..."
|
|
117
|
+
merged=$(git branch --merged main | grep -v "^\*" | grep -v "main$" | grep -v "master$" | grep -v "\-\-merged\-" || true)
|
|
118
|
+
|
|
119
|
+
if [[ -z "$merged" ]]; then
|
|
120
|
+
echo " No unrenamed merged branches found. All clean."
|
|
121
|
+
exit 0
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
while IFS= read -r branch; do
|
|
125
|
+
rename_branch "$branch"
|
|
126
|
+
done <<< "$merged"
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
# ── Prune old merged branches ────────────────────────────────────────
|
|
130
|
+
|
|
131
|
+
prune_branches() {
|
|
132
|
+
echo ""
|
|
133
|
+
echo "Pruning old merged branches (keeping last $KEEP_COUNT per developer)..."
|
|
134
|
+
|
|
135
|
+
# Get all remote --merged branches
|
|
136
|
+
local merged_branches
|
|
137
|
+
merged_branches=$(git branch -r | grep "\-\-merged\-" | sed 's|origin/||' | sed 's/^[[:space:]]*//' | sort)
|
|
138
|
+
|
|
139
|
+
if [[ -z "$merged_branches" ]]; then
|
|
140
|
+
echo " No --merged branches found. Nothing to prune."
|
|
141
|
+
return
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
# Extract unique developer prefixes (everything before the first /)
|
|
145
|
+
local prefixes
|
|
146
|
+
prefixes=$(echo "$merged_branches" | sed 's|/.*||' | sort -u)
|
|
147
|
+
|
|
148
|
+
for prefix in $prefixes; do
|
|
149
|
+
# Get all --merged branches for this prefix, sorted by date (newest first)
|
|
150
|
+
# The date is in the --merged-YYYY-MM-DD suffix
|
|
151
|
+
local branches_for_prefix
|
|
152
|
+
branches_for_prefix=$(echo "$merged_branches" | grep "^${prefix}/" | sort -t'-' -k$(echo "$prefix" | tr -cd '-' | wc -c | tr -d ' ' | xargs -I{} expr {} + 5) -r 2>/dev/null || echo "$merged_branches" | grep "^${prefix}/" | sort -r)
|
|
153
|
+
|
|
154
|
+
local count=0
|
|
155
|
+
while IFS= read -r branch; do
|
|
156
|
+
[[ -z "$branch" ]] && continue
|
|
157
|
+
count=$((count + 1))
|
|
158
|
+
|
|
159
|
+
if [[ $count -le $KEEP_COUNT ]]; then
|
|
160
|
+
echo " ✓ KEEP $branch"
|
|
161
|
+
else
|
|
162
|
+
if $DRY_RUN; then
|
|
163
|
+
echo " [dry-run] DELETE $branch"
|
|
164
|
+
else
|
|
165
|
+
git push origin --delete "$branch" 2>/dev/null && echo " ✗ DELETED $branch" || echo " ! FAILED to delete $branch"
|
|
166
|
+
git branch -d "$branch" 2>/dev/null || true
|
|
167
|
+
fi
|
|
168
|
+
fi
|
|
169
|
+
done <<< "$branches_for_prefix"
|
|
170
|
+
done
|
|
171
|
+
|
|
172
|
+
# Also clean up stale branches: branches without --merged suffix
|
|
173
|
+
# whose PRs are merged (they exist on remote but have no open PR)
|
|
174
|
+
echo ""
|
|
175
|
+
echo "Checking for stale unmerged-looking branches..."
|
|
176
|
+
|
|
177
|
+
local all_remote
|
|
178
|
+
all_remote=$(git branch -r | grep -v HEAD | grep -v "origin/main" | sed 's|origin/||' | sed 's/^[[:space:]]*//' | grep -v "\-\-merged\-" || true)
|
|
179
|
+
|
|
180
|
+
local current_branch
|
|
181
|
+
current_branch=$(git branch --show-current)
|
|
182
|
+
|
|
183
|
+
for branch in $all_remote; do
|
|
184
|
+
[[ -z "$branch" ]] && continue
|
|
185
|
+
# Skip the current working branch
|
|
186
|
+
[[ "$branch" == "$current_branch" ]] && continue
|
|
187
|
+
|
|
188
|
+
# Check if this branch is fully merged into main
|
|
189
|
+
if git merge-base --is-ancestor "origin/$branch" origin/main 2>/dev/null; then
|
|
190
|
+
if $DRY_RUN; then
|
|
191
|
+
echo " [dry-run] DELETE $branch (merged but never renamed)"
|
|
192
|
+
else
|
|
193
|
+
git push origin --delete "$branch" 2>/dev/null && echo " ✗ DELETED $branch (merged but never renamed)" || echo " ! FAILED to delete $branch"
|
|
194
|
+
git branch -d "$branch" 2>/dev/null || true
|
|
195
|
+
fi
|
|
196
|
+
fi
|
|
197
|
+
done
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if $PRUNE; then
|
|
201
|
+
prune_branches
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
echo ""
|
|
205
|
+
echo "Done."
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# publish-skill.sh ... publish SKILL.md to a website as plain text
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# bash publish-skill.sh <repo-path> <website-path> [--name <name>] [--deploy]
|
|
7
|
+
#
|
|
8
|
+
# Examples:
|
|
9
|
+
# # Copy SKILL.md to website install directory
|
|
10
|
+
# bash publish-skill.sh /path/to/memory-crystal-private /path/to/wip-websites/wip.computer --name memory-crystal
|
|
11
|
+
#
|
|
12
|
+
# # Copy and deploy to VPS
|
|
13
|
+
# bash publish-skill.sh /path/to/memory-crystal-private /path/to/wip-websites/wip.computer --name memory-crystal --deploy
|
|
14
|
+
#
|
|
15
|
+
# # Auto-detect name from package.json
|
|
16
|
+
# bash publish-skill.sh /path/to/memory-crystal-private /path/to/wip-websites/wip.computer --deploy
|
|
17
|
+
#
|
|
18
|
+
# Convention:
|
|
19
|
+
# SKILL.md in the repo -> install/{name}.txt on the website
|
|
20
|
+
# The website serves these as plain text at yoursite.com/install/{name}.txt
|
|
21
|
+
# Any AI can fetch the URL and get clean, parseable content.
|
|
22
|
+
#
|
|
23
|
+
# Config (optional, in repo root):
|
|
24
|
+
# .skill-publish.json:
|
|
25
|
+
# {
|
|
26
|
+
# "name": "memory-crystal",
|
|
27
|
+
# "website": "/path/to/website",
|
|
28
|
+
# "deploy_command": "bash deploy.sh"
|
|
29
|
+
# }
|
|
30
|
+
|
|
31
|
+
set -euo pipefail
|
|
32
|
+
|
|
33
|
+
REPO_PATH="${1:-}"
|
|
34
|
+
WEBSITE_PATH="${2:-}"
|
|
35
|
+
NAME=""
|
|
36
|
+
DO_DEPLOY=false
|
|
37
|
+
|
|
38
|
+
# Parse flags
|
|
39
|
+
shift 2 2>/dev/null || true
|
|
40
|
+
while [[ $# -gt 0 ]]; do
|
|
41
|
+
case "$1" in
|
|
42
|
+
--name) NAME="$2"; shift 2 ;;
|
|
43
|
+
--deploy) DO_DEPLOY=true; shift ;;
|
|
44
|
+
*) echo "Unknown flag: $1"; exit 1 ;;
|
|
45
|
+
esac
|
|
46
|
+
done
|
|
47
|
+
|
|
48
|
+
# ── Resolve from config if args are missing ──
|
|
49
|
+
|
|
50
|
+
if [[ -z "$REPO_PATH" ]]; then
|
|
51
|
+
echo "Usage: bash publish-skill.sh <repo-path> <website-path> [--name <name>] [--deploy]"
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# Try to load .skill-publish.json from repo
|
|
56
|
+
CONFIG_FILE="$REPO_PATH/.skill-publish.json"
|
|
57
|
+
if [[ -f "$CONFIG_FILE" ]]; then
|
|
58
|
+
if command -v node &>/dev/null; then
|
|
59
|
+
[[ -z "$WEBSITE_PATH" ]] && WEBSITE_PATH=$(node -p "require('$CONFIG_FILE').website || ''" 2>/dev/null || echo "")
|
|
60
|
+
[[ -z "$NAME" ]] && NAME=$(node -p "require('$CONFIG_FILE').name || ''" 2>/dev/null || echo "")
|
|
61
|
+
DEPLOY_CMD=$(node -p "require('$CONFIG_FILE').deploy_command || ''" 2>/dev/null || echo "")
|
|
62
|
+
fi
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
if [[ -z "$WEBSITE_PATH" ]]; then
|
|
66
|
+
echo "Error: website path required (arg 2 or .skill-publish.json)"
|
|
67
|
+
exit 1
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
# ── Auto-detect name from package.json ──
|
|
71
|
+
|
|
72
|
+
if [[ -z "$NAME" ]]; then
|
|
73
|
+
if [[ -f "$REPO_PATH/package.json" ]] && command -v node &>/dev/null; then
|
|
74
|
+
NAME=$(node -p "require('$REPO_PATH/package.json').name || ''" 2>/dev/null || echo "")
|
|
75
|
+
# Strip npm scope (@wipcomputer/foo -> foo)
|
|
76
|
+
NAME="${NAME#@*/}"
|
|
77
|
+
fi
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
if [[ -z "$NAME" ]]; then
|
|
81
|
+
echo "Error: could not determine skill name. Use --name or add to package.json"
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# ── Find SKILL.md ──
|
|
86
|
+
|
|
87
|
+
SKILL_FILE=""
|
|
88
|
+
|
|
89
|
+
# Check skills/*/SKILL.md first (standard location)
|
|
90
|
+
if [[ -z "$SKILL_FILE" ]]; then
|
|
91
|
+
FOUND=$(find "$REPO_PATH/skills" -maxdepth 2 -name "SKILL.md" 2>/dev/null | head -1)
|
|
92
|
+
[[ -n "$FOUND" ]] && SKILL_FILE="$FOUND"
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Check root SKILL.md
|
|
96
|
+
if [[ -z "$SKILL_FILE" && -f "$REPO_PATH/SKILL.md" ]]; then
|
|
97
|
+
SKILL_FILE="$REPO_PATH/SKILL.md"
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
if [[ -z "$SKILL_FILE" ]]; then
|
|
101
|
+
echo "Error: no SKILL.md found in $REPO_PATH"
|
|
102
|
+
exit 1
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# ── Publish ──
|
|
106
|
+
|
|
107
|
+
INSTALL_DIR="$WEBSITE_PATH/install"
|
|
108
|
+
mkdir -p "$INSTALL_DIR"
|
|
109
|
+
|
|
110
|
+
cp "$SKILL_FILE" "$INSTALL_DIR/$NAME.txt"
|
|
111
|
+
echo "Published: install/$NAME.txt (from $(basename "$SKILL_FILE"))"
|
|
112
|
+
|
|
113
|
+
# ── Deploy if requested ──
|
|
114
|
+
|
|
115
|
+
if [[ "$DO_DEPLOY" == "true" ]]; then
|
|
116
|
+
# Look for deploy script in website directory
|
|
117
|
+
DEPLOY_SCRIPT=""
|
|
118
|
+
if [[ -n "${DEPLOY_CMD:-}" ]]; then
|
|
119
|
+
DEPLOY_SCRIPT="$DEPLOY_CMD"
|
|
120
|
+
elif [[ -f "$WEBSITE_PATH/../deploy.sh" ]]; then
|
|
121
|
+
DEPLOY_SCRIPT="bash $WEBSITE_PATH/../deploy.sh"
|
|
122
|
+
elif [[ -f "$WEBSITE_PATH/deploy.sh" ]]; then
|
|
123
|
+
DEPLOY_SCRIPT="bash $WEBSITE_PATH/deploy.sh"
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
if [[ -n "$DEPLOY_SCRIPT" ]]; then
|
|
127
|
+
echo "Deploying website..."
|
|
128
|
+
eval "$DEPLOY_SCRIPT"
|
|
129
|
+
else
|
|
130
|
+
echo "Warning: --deploy requested but no deploy script found."
|
|
131
|
+
echo " Looked for: deploy.sh in website directory"
|
|
132
|
+
echo " Or set deploy_command in .skill-publish.json"
|
|
133
|
+
fi
|
|
134
|
+
fi
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Dual License: MIT + AGPLv3
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 WIP Computer, Inc.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
1. MIT License (local and personal use)
|
|
7
|
+
---------------------------------------
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
SOFTWARE.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
2. GNU Affero General Public License v3.0 (commercial and cloud use)
|
|
29
|
+
--------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
If you run this software as part of a hosted service, cloud platform,
|
|
32
|
+
marketplace listing, or any network-accessible offering for commercial
|
|
33
|
+
purposes, the AGPLv3 terms apply. You must either:
|
|
34
|
+
|
|
35
|
+
a) Release your complete source code under AGPLv3, or
|
|
36
|
+
b) Obtain a commercial license.
|
|
37
|
+
|
|
38
|
+
This program is free software: you can redistribute it and/or modify
|
|
39
|
+
it under the terms of the GNU Affero General Public License as published
|
|
40
|
+
by the Free Software Foundation, either version 3 of the License, or
|
|
41
|
+
(at your option) any later version.
|
|
42
|
+
|
|
43
|
+
This program is distributed in the hope that it will be useful,
|
|
44
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
45
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
46
|
+
GNU Affero General Public License for more details.
|
|
47
|
+
|
|
48
|
+
You should have received a copy of the GNU Affero General Public License
|
|
49
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
AGPLv3 for personal use is free. Commercial licenses available.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
###### WIP Computer
|
|
2
|
+
|
|
3
|
+
# Private-to-Public Sync
|
|
4
|
+
|
|
5
|
+
Publish safely. Syncs your private working repo to a clean public mirror. Excludes internal `ai/` folders automatically.
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
- Copies everything except `ai/` and `.git/` to the public repo
|
|
10
|
+
- Creates a PR on the public repo, merges it
|
|
11
|
+
- Syncs GitHub releases from private to public
|
|
12
|
+
- Cleans up deploy branches
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bash deploy-public.sh /path/to/private-repo org/public-repo
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
- git
|
|
23
|
+
- gh (GitHub CLI)
|
|
24
|
+
- bash
|
|
25
|
+
|
|
26
|
+
## Interfaces
|
|
27
|
+
|
|
28
|
+
- **CLI**: Shell script
|
|
29
|
+
- **Skill**: SKILL.md for agent instructions
|
|
30
|
+
|
|
31
|
+
## Part of [AI DevOps Toolbox](https://github.com/wipcomputer/wip-ai-devops-toolbox)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deploy-public
|
|
3
|
+
description: Private-to-public repo sync. Copies everything except ai/ to the public mirror. Creates PR, merges, syncs releases.
|
|
4
|
+
license: MIT
|
|
5
|
+
interface: [cli, skill]
|
|
6
|
+
metadata:
|
|
7
|
+
display-name: "Private-to-Public Sync"
|
|
8
|
+
version: "1.3.0"
|
|
9
|
+
homepage: "https://github.com/wipcomputer/wip-ai-devops-toolbox"
|
|
10
|
+
author: "Parker Todd Brooks"
|
|
11
|
+
category: dev-tools
|
|
12
|
+
capabilities:
|
|
13
|
+
- repo-sync
|
|
14
|
+
- release-sync
|
|
15
|
+
requires:
|
|
16
|
+
bins: [git, gh, bash]
|
|
17
|
+
openclaw:
|
|
18
|
+
requires:
|
|
19
|
+
bins: [git, gh, bash]
|
|
20
|
+
emoji: "🚢"
|
|
21
|
+
compatibility: Requires git, gh (GitHub CLI), bash.
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# deploy-public
|
|
25
|
+
|
|
26
|
+
Private-to-public repo sync. One script for all repos. Copies code, creates a PR on the public repo, merges it, and syncs GitHub releases.
|
|
27
|
+
|
|
28
|
+
## When to Use This Skill
|
|
29
|
+
|
|
30
|
+
**Use deploy-public for:**
|
|
31
|
+
- Publishing a private repo's code to its public counterpart
|
|
32
|
+
- After running `wip-release` on the private repo (release must exist first)
|
|
33
|
+
- Syncing release notes from private to public
|
|
34
|
+
|
|
35
|
+
**CRITICAL: Release order matters.**
|
|
36
|
+
1. Merge PR to private repo's main
|
|
37
|
+
2. Run `wip-release` (creates GitHub release with notes on private repo)
|
|
38
|
+
3. THEN run `deploy-public.sh` (pulls notes from private release)
|
|
39
|
+
|
|
40
|
+
If you skip step 2, the public release gets empty notes.
|
|
41
|
+
|
|
42
|
+
### Do NOT Use For
|
|
43
|
+
|
|
44
|
+
- Repos without a `-private` counterpart
|
|
45
|
+
- First-time repo setup (create the public repo on GitHub first)
|
|
46
|
+
|
|
47
|
+
## API Reference
|
|
48
|
+
|
|
49
|
+
### CLI
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
bash scripts/deploy-public.sh /path/to/private-repo org/public-repo
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Examples
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Deploy memory-crystal
|
|
59
|
+
bash scripts/deploy-public.sh /path/to/memory-crystal-private wipcomputer/memory-crystal
|
|
60
|
+
|
|
61
|
+
# Deploy wip-dev-tools
|
|
62
|
+
bash scripts/deploy-public.sh /path/to/wip-ai-devops-toolbox-private wipcomputer/wip-ai-devops-toolbox
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## What It Does
|
|
66
|
+
|
|
67
|
+
1. Clones the public repo to a temp directory
|
|
68
|
+
2. Copies all files from private repo (excluding `ai/`, `.git/`)
|
|
69
|
+
3. Creates a branch, commits, pushes, creates PR
|
|
70
|
+
4. Merges the PR (regular merge, never squash)
|
|
71
|
+
5. Syncs GitHub releases (pulls notes from private repo's releases)
|