Publish vault infrastructure changes to the DuckyAI template repo. Use when the user says "publish vault updates", "sync to template", "push to template", or "publish changes". Diffs personal vault against the template repo, strips personal content, stages changes for review.
Sync infrastructure changes from your personal DuckyAI vault to the DuckyAI-Template repo, stripping personal content and staging for review before commit.
This skill is included in the template. Any DuckyAI user can contribute improvements back to the shared template by running this skill.
version.json → templateRepo field, cloned to a temp directory. Falls back to if a local clone exists.C:\repos\DuckyAI-Templateversion.json (default: https://dev.azure.com/msazure/Azure%20AppConfig/_git/DuckyAI)# Read template repo URL from version.json
$versionFile = "version.json"
if (Test-Path $versionFile) {
$versionInfo = Get-Content $versionFile | ConvertFrom-Json
$templateUrl = $versionInfo.templateRepo
} else {
$templateUrl = "https://dev.azure.com/msazure/Azure%20AppConfig/_git/DuckyAI"
}
# Use local clone if available, otherwise clone to temp
$templateDir = "C:\repos\DuckyAI-Template"
if (-not (Test-Path $templateDir)) {
$templateDir = Join-Path $env:TEMP "duckyai-template-publish"
if (-not (Test-Path $templateDir)) {
git clone --depth 1 $templateUrl $templateDir
}
}
Ensure the template repo is on main and up to date:
git -C $templateDir checkout main
git -C $templateDir pull origin main
Infrastructure files that get synced from personal vault → template:
Direct copy (no transformation needed):
.github/prompts/*.prompt.md
.github/skills/code-review/SKILL.md
.github/skills/make-skill-template/SKILL.md
.github/skills/vault-setup/SKILL.md
.github/skills/vault-update/SKILL.md
.vscode/mcp.json
mcp-server/src/index.ts
mcp-server/package.json
mcp-server/tsconfig.json
scripts/sync-repos.ps1
Templates/*.md
DuckyAI.code-workspace
03-Knowledge/Documentation/DuckyAI MCP Server.md
03-Knowledge/Documentation/Obsidian Plugin Setup.md
Special merge (strip personal content):
.github/copilot-instructions.md
Never sync (blocklist):
00-Inbox/
01-Work/
02-People/
03-Knowledge/ (except the two docs above)
04-Periodic/
05-Archive/
Home.md
.env
scripts/repos.json
.repos/
.obsidian/
.github/skills/vault-publish/ (this skill itself — personal only)
For each file in the direct-copy list, compare the personal vault version against the template version:
$vaultRoot = Get-Location
$templateDir = "C:\repos\DuckyAI-Template"
# Compare each infrastructure file
$files = @(
".github/prompts/new-task.prompt.md",
".github/prompts/new-investigation.prompt.md",
".github/prompts/new-meeting.prompt.md",
".github/prompts/add-documentation.prompt.md",
".github/prompts/archive-task.prompt.md",
".github/prompts/prioritize-work.prompt.md",
".github/prompts/restructure-document.prompt.md",
".github/skills/code-review/SKILL.md",
".github/skills/make-skill-template/SKILL.md",
".github/skills/vault-setup/SKILL.md",
".github/skills/vault-update/SKILL.md",
".vscode/mcp.json",
"mcp-server/src/index.ts",
"mcp-server/package.json",
"mcp-server/tsconfig.json",
"scripts/sync-repos.ps1",
"DuckyAI.code-workspace",
"03-Knowledge/Documentation/DuckyAI MCP Server.md",
"03-Knowledge/Documentation/Obsidian Plugin Setup.md"
)
# Also glob Templates/*.md
$templateFiles = Get-ChildItem "Templates/*.md" -Name
foreach ($t in $templateFiles) { $files += "Templates/$t" }
For each file:
Report to the user:
Changed files:
📝 mcp-server/src/index.ts (modified)
🆕 .github/skills/new-skill/SKILL.md (new)
Unchanged:
✓ 15 files unchanged
Check for any new skill directories in .github/skills/ that exist in the personal vault but not in the template. Exclude vault-publish (personal only).
For each new skill found, add it to the copy list.
This file needs special handling because it has personal sections that must be replaced with placeholders.
Personal sections (replace with template placeholders):
[USER_NAME], [USER_ROLE] versionStructural sections (take from personal vault — these are the updates):
Algorithm:
copilot-instructions.mdcopilot-instructions.md## headers into sectionsFor each changed/new file, copy from personal vault to template:
foreach ($file in $changedFiles) {
$src = Join-Path $vaultRoot $file
$dst = Join-Path $templateDir $file
$dstDir = Split-Path $dst -Parent
if (-not (Test-Path $dstDir)) { New-Item -ItemType Directory -Force -Path $dstDir | Out-Null }
Copy-Item $src $dst -Force
}
For copilot-instructions.md, write the merged version (from Step 4) instead of copying.
Run a check for personal references in the staged files:
$personalPatterns = @() # Add patterns like usernames, team names, etc.
# Read patterns from a config if available, otherwise use common ones
$hits = Get-ChildItem $templateDir -Recurse -File -Exclude *.js,*.map |
Where-Object { $_.FullName -notlike "*node_modules*" -and $_.FullName -notlike "*.git\*" } |
Select-String -Pattern ($personalPatterns -join "|") -SimpleMatch
If any hits found, warn the user and list them. Do NOT proceed until the user confirms.
git -C $templateDir add -A
git -C $templateDir diff --staged --stat
Show the staged diff summary to the user.
Ask the user what to do next:
git -C $templateDir checkout . to revertAsk: "What kind of change is this?"
x.x.Xx.X.0X.0.0Then:
version.jsonCHANGELOG.md with new section (use Keep a Changelog format)version.json with new version + timestamp + changes arraygit -C $templateDir add -A
git -C $templateDir commit -m "v{version}: {summary}
Co-authored-by: Copilot <[email protected]>"
$username = $env:USERNAME
$branch = "users/$username/v{version}"
git -C $templateDir checkout -b $branch
git -C $templateDir push origin $branch
Create PR: https://dev.azure.com/msazure/Azure%20AppConfig/_git/DuckyAI/pullrequestcreate?sourceRef={branch}&targetRef=main
✅ Published vault updates to DuckyAI-Template
Version: {old} → {new}
Changed: {N} files
Branch: users/{username}/v{version}
PR: {url}
Don't forget to merge the PR!