Add pi global install scripts (#57)

This commit is contained in:
dan bachelder 2026-03-11 13:34:03 -07:00 committed by GitHub
parent 0a955c0b98
commit a69a44a890
3 changed files with 112 additions and 0 deletions

View file

@ -38,6 +38,8 @@
"test": "node --import ./src/resources/extensions/gsd/tests/resolve-ts.mjs --experimental-strip-types --test 'src/resources/extensions/gsd/tests/*.test.ts' 'src/resources/extensions/gsd/tests/*.test.mjs' 'src/tests/*.test.ts'",
"dev": "tsc --watch",
"postinstall": "node scripts/postinstall.js",
"pi:install-global": "node scripts/install-pi-global.js",
"pi:uninstall-global": "node scripts/uninstall-pi-global.js",
"sync-pkg-version": "node scripts/sync-pkg-version.cjs",
"prepublishOnly": "npm run sync-pkg-version && npm run build"
},

View file

@ -0,0 +1,44 @@
#!/usr/bin/env node
import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
import os from 'node:os'
import { dirname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = dirname(fileURLToPath(import.meta.url))
const resourcesDir = resolve(__dirname, '..', 'src', 'resources')
const piRoot = join(os.homedir(), '.pi')
const piAgentDir = join(piRoot, 'agent')
const copyDir = (name) => {
const src = join(resourcesDir, name)
const dest = join(piAgentDir, name)
if (!existsSync(src)) return false
mkdirSync(dest, { recursive: true })
cpSync(src, dest, { recursive: true, force: true })
return true
}
mkdirSync(piAgentDir, { recursive: true })
const copied = []
if (copyDir('extensions')) copied.push('extensions')
if (copyDir('skills')) copied.push('skills')
if (copyDir('agents')) copied.push('agents')
const agentsMdSrc = join(resourcesDir, 'AGENTS.md')
if (existsSync(agentsMdSrc)) {
writeFileSync(join(piAgentDir, 'AGENTS.md'), readFileSync(agentsMdSrc))
copied.push('AGENTS.md')
}
const workflowSrc = join(resourcesDir, 'GSD-WORKFLOW.md')
if (existsSync(workflowSrc)) {
writeFileSync(join(piRoot, 'GSD-WORKFLOW.md'), readFileSync(workflowSrc))
copied.push('GSD-WORKFLOW.md')
}
process.stdout.write(
`Installed GSD resources for pi in ${piRoot}\n` +
`Copied: ${copied.join(', ')}\n` +
`Extensions are now available under ${join(piAgentDir, 'extensions')}\n`
)

View file

@ -0,0 +1,66 @@
#!/usr/bin/env node
import { existsSync, readFileSync, readdirSync, rmSync, rmdirSync } from 'node:fs'
import os from 'node:os'
import { dirname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = dirname(fileURLToPath(import.meta.url))
const resourcesDir = resolve(__dirname, '..', 'src', 'resources')
const piRoot = join(os.homedir(), '.pi')
const piAgentDir = join(piRoot, 'agent')
const removed = []
const skipped = []
function safeRemove(path, label) {
if (!existsSync(path)) return
rmSync(path, { recursive: true, force: true })
removed.push(label)
}
function removeResourceEntries(containerName) {
const srcDir = join(resourcesDir, containerName)
const destDir = join(piAgentDir, containerName)
if (!existsSync(srcDir) || !existsSync(destDir)) return
for (const entry of readdirSync(srcDir)) {
safeRemove(join(destDir, entry), `${containerName}/${entry}`)
}
try {
if (readdirSync(destDir).length === 0) {
rmdirSync(destDir)
removed.push(`${containerName}/`)
}
} catch {
// ignore non-empty or missing dirs
}
}
function removeIfContentMatches(targetPath, sourcePath, label) {
if (!existsSync(targetPath) || !existsSync(sourcePath)) return
try {
const target = readFileSync(targetPath, 'utf8')
const source = readFileSync(sourcePath, 'utf8')
if (target === source) {
rmSync(targetPath, { force: true })
removed.push(label)
} else {
skipped.push(`${label} (modified, left in place)`)
}
} catch {
skipped.push(`${label} (could not verify, left in place)`)
}
}
removeResourceEntries('extensions')
removeResourceEntries('skills')
removeResourceEntries('agents')
removeIfContentMatches(join(piAgentDir, 'AGENTS.md'), join(resourcesDir, 'AGENTS.md'), 'agent/AGENTS.md')
removeIfContentMatches(join(piRoot, 'GSD-WORKFLOW.md'), join(resourcesDir, 'GSD-WORKFLOW.md'), 'GSD-WORKFLOW.md')
process.stdout.write(
`Removed GSD resources from ${piRoot}\n` +
`Removed: ${removed.length ? removed.join(', ') : '(nothing)'}\n` +
(skipped.length ? `Skipped: ${skipped.join(', ')}\n` : '')
)