@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.
Files changed (146) hide show
  1. package/.license-guard.json +7 -0
  2. package/.publish-skill.json +4 -0
  3. package/CHANGELOG.md +1120 -0
  4. package/CLA.md +19 -0
  5. package/DEV-GUIDE-GENERAL-PUBLIC.md +882 -0
  6. package/LICENSE +52 -0
  7. package/README.md +238 -0
  8. package/SKILL.md +728 -0
  9. package/TECHNICAL.md +282 -0
  10. package/UNIVERSAL-INTERFACE.md +180 -0
  11. package/_trash/RELEASE-NOTES-v1-8-0.md +29 -0
  12. package/_trash/RELEASE-NOTES-v1-8-1.md +7 -0
  13. package/_trash/RELEASE-NOTES-v1-8-2.md +7 -0
  14. package/_trash/RELEASE-NOTES-v1-9-0.md +37 -0
  15. package/_trash/RELEASE-NOTES-v1-9-1.md +38 -0
  16. package/_trash/RELEASE-NOTES-v1-9-10.md +40 -0
  17. package/_trash/RELEASE-NOTES-v1-9-2.md +40 -0
  18. package/_trash/RELEASE-NOTES-v1-9-6.md +72 -0
  19. package/_trash/RELEASE-NOTES-v1-9-7.md +23 -0
  20. package/_trash/RELEASE-NOTES-v1-9-9.md +75 -0
  21. package/_trash/guide 2/DEV-GUIDE.md +487 -0
  22. package/_trash/guide 2/scripts/deploy-public.sh +152 -0
  23. package/package.json +27 -0
  24. package/scripts/SKILL-deploy-public.md +61 -0
  25. package/scripts/SKILL-post-merge-rename.md +47 -0
  26. package/scripts/deploy-public.sh +264 -0
  27. package/scripts/post-merge-rename.sh +205 -0
  28. package/scripts/publish-skill.sh +134 -0
  29. package/tools/deploy-public/LICENSE +52 -0
  30. package/tools/deploy-public/README.md +31 -0
  31. package/tools/deploy-public/SKILL.md +71 -0
  32. package/tools/deploy-public/deploy-public.sh +264 -0
  33. package/tools/deploy-public/package.json +9 -0
  34. package/tools/ldm-jobs/LICENSE +52 -0
  35. package/tools/ldm-jobs/README.md +46 -0
  36. package/tools/ldm-jobs/backup.sh +16 -0
  37. package/tools/ldm-jobs/branch-protect.sh +39 -0
  38. package/tools/ldm-jobs/crystal-capture.sh +19 -0
  39. package/tools/ldm-jobs/setup-shell.sh +27 -0
  40. package/tools/ldm-jobs/visibility-audit.sh +27 -0
  41. package/tools/post-merge-rename/LICENSE +52 -0
  42. package/tools/post-merge-rename/README.md +29 -0
  43. package/tools/post-merge-rename/SKILL.md +57 -0
  44. package/tools/post-merge-rename/package.json +9 -0
  45. package/tools/post-merge-rename/post-merge-rename.sh +122 -0
  46. package/tools/wip-branch-guard/INSTALL.md +41 -0
  47. package/tools/wip-branch-guard/guard.mjs +259 -0
  48. package/tools/wip-branch-guard/package.json +11 -0
  49. package/tools/wip-file-guard/CHANGELOG.md +6 -0
  50. package/tools/wip-file-guard/LICENSE +52 -0
  51. package/tools/wip-file-guard/README.md +113 -0
  52. package/tools/wip-file-guard/REFERENCE.md +86 -0
  53. package/tools/wip-file-guard/SKILL.md +105 -0
  54. package/tools/wip-file-guard/guard.mjs +128 -0
  55. package/tools/wip-file-guard/openclaw.plugin.json +8 -0
  56. package/tools/wip-file-guard/package.json +27 -0
  57. package/tools/wip-file-guard/test.sh +119 -0
  58. package/tools/wip-license-guard/LICENSE +52 -0
  59. package/tools/wip-license-guard/README.md +32 -0
  60. package/tools/wip-license-guard/SKILL.md +65 -0
  61. package/tools/wip-license-guard/cli.mjs +464 -0
  62. package/tools/wip-license-guard/core.mjs +310 -0
  63. package/tools/wip-license-guard/hook.mjs +146 -0
  64. package/tools/wip-license-guard/package.json +15 -0
  65. package/tools/wip-license-hook/CHANGELOG.md +17 -0
  66. package/tools/wip-license-hook/LICENSE +52 -0
  67. package/tools/wip-license-hook/README.md +200 -0
  68. package/tools/wip-license-hook/SKILL.md +111 -0
  69. package/tools/wip-license-hook/dist/cli/index.d.ts +15 -0
  70. package/tools/wip-license-hook/dist/cli/index.js +170 -0
  71. package/tools/wip-license-hook/dist/cli/index.js.map +1 -0
  72. package/tools/wip-license-hook/dist/core/detector.d.ts +12 -0
  73. package/tools/wip-license-hook/dist/core/detector.js +104 -0
  74. package/tools/wip-license-hook/dist/core/detector.js.map +1 -0
  75. package/tools/wip-license-hook/dist/core/index.d.ts +4 -0
  76. package/tools/wip-license-hook/dist/core/index.js +5 -0
  77. package/tools/wip-license-hook/dist/core/index.js.map +1 -0
  78. package/tools/wip-license-hook/dist/core/ledger.d.ts +49 -0
  79. package/tools/wip-license-hook/dist/core/ledger.js +72 -0
  80. package/tools/wip-license-hook/dist/core/ledger.js.map +1 -0
  81. package/tools/wip-license-hook/dist/core/reporter.d.ts +14 -0
  82. package/tools/wip-license-hook/dist/core/reporter.js +227 -0
  83. package/tools/wip-license-hook/dist/core/reporter.js.map +1 -0
  84. package/tools/wip-license-hook/dist/core/scanner.d.ts +39 -0
  85. package/tools/wip-license-hook/dist/core/scanner.js +325 -0
  86. package/tools/wip-license-hook/dist/core/scanner.js.map +1 -0
  87. package/tools/wip-license-hook/hooks/pre-pull.sh +55 -0
  88. package/tools/wip-license-hook/hooks/pre-push.sh +51 -0
  89. package/tools/wip-license-hook/mcp-server.mjs +119 -0
  90. package/tools/wip-license-hook/package-lock.json +54 -0
  91. package/tools/wip-license-hook/package.json +43 -0
  92. package/tools/wip-license-hook/src/cli/index.ts +189 -0
  93. package/tools/wip-license-hook/src/core/detector.ts +130 -0
  94. package/tools/wip-license-hook/src/core/index.ts +4 -0
  95. package/tools/wip-license-hook/src/core/ledger.ts +116 -0
  96. package/tools/wip-license-hook/src/core/reporter.ts +255 -0
  97. package/tools/wip-license-hook/src/core/scanner.ts +367 -0
  98. package/tools/wip-license-hook/tsconfig.json +16 -0
  99. package/tools/wip-readme-format/README.md +49 -0
  100. package/tools/wip-readme-format/SKILL.md +84 -0
  101. package/tools/wip-readme-format/format.mjs +570 -0
  102. package/tools/wip-readme-format/package.json +15 -0
  103. package/tools/wip-release/CHANGELOG.md +42 -0
  104. package/tools/wip-release/LICENSE +52 -0
  105. package/tools/wip-release/README.md +45 -0
  106. package/tools/wip-release/REFERENCE.md +100 -0
  107. package/tools/wip-release/SKILL.md +139 -0
  108. package/tools/wip-release/cli.js +161 -0
  109. package/tools/wip-release/core.mjs +1174 -0
  110. package/tools/wip-release/mcp-server.mjs +109 -0
  111. package/tools/wip-release/package.json +36 -0
  112. package/tools/wip-repo-init/README.md +38 -0
  113. package/tools/wip-repo-init/SKILL.md +77 -0
  114. package/tools/wip-repo-init/init.mjs +142 -0
  115. package/tools/wip-repo-init/package.json +11 -0
  116. package/tools/wip-repo-permissions-hook/LICENSE +52 -0
  117. package/tools/wip-repo-permissions-hook/README.md +86 -0
  118. package/tools/wip-repo-permissions-hook/SKILL.md +73 -0
  119. package/tools/wip-repo-permissions-hook/cli.js +83 -0
  120. package/tools/wip-repo-permissions-hook/core.mjs +122 -0
  121. package/tools/wip-repo-permissions-hook/guard.mjs +64 -0
  122. package/tools/wip-repo-permissions-hook/mcp-server.mjs +92 -0
  123. package/tools/wip-repo-permissions-hook/openclaw.plugin.json +8 -0
  124. package/tools/wip-repo-permissions-hook/package.json +31 -0
  125. package/tools/wip-repos/LICENSE +52 -0
  126. package/tools/wip-repos/README.md +77 -0
  127. package/tools/wip-repos/SKILL.md +80 -0
  128. package/tools/wip-repos/cli.mjs +176 -0
  129. package/tools/wip-repos/core.mjs +290 -0
  130. package/tools/wip-repos/mcp-server.mjs +157 -0
  131. package/tools/wip-repos/package.json +34 -0
  132. package/tools/wip-universal-installer/CHANGELOG.md +57 -0
  133. package/tools/wip-universal-installer/LICENSE +52 -0
  134. package/tools/wip-universal-installer/README.md +81 -0
  135. package/tools/wip-universal-installer/REFERENCE.md +122 -0
  136. package/tools/wip-universal-installer/SKILL.md +87 -0
  137. package/tools/wip-universal-installer/SPEC.md +180 -0
  138. package/tools/wip-universal-installer/detect.mjs +130 -0
  139. package/tools/wip-universal-installer/examples/minimal/README.md +20 -0
  140. package/tools/wip-universal-installer/examples/minimal/SKILL.md +28 -0
  141. package/tools/wip-universal-installer/examples/minimal/cli.mjs +4 -0
  142. package/tools/wip-universal-installer/examples/minimal/core.mjs +8 -0
  143. package/tools/wip-universal-installer/examples/minimal/mcp-server.mjs +27 -0
  144. package/tools/wip-universal-installer/examples/minimal/package.json +12 -0
  145. package/tools/wip-universal-installer/install.js +930 -0
  146. 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)