fix: prevent getLoadedSkills crash and auto-build workspace packages (#1767)
Add defensive fallback in auto-prompts.ts so a missing getLoadedSkills export degrades gracefully (empty skill list) instead of crashing every auto-mode dispatch iteration. Add ensure-workspace-builds.cjs postinstall script that detects missing dist/ directories in workspace packages and rebuilds them automatically. This prevents stale-build issues after fresh clones where dist/ is gitignored but required at runtime by jiti-loaded extensions. Closes #1734 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
050d51475b
commit
d1b6a8a6b1
3 changed files with 60 additions and 2 deletions
|
|
@ -66,7 +66,7 @@
|
|||
"build:native": "node native/scripts/build.js",
|
||||
"build:native:dev": "node native/scripts/build.js --dev",
|
||||
"dev": "node scripts/dev.js",
|
||||
"postinstall": "node scripts/link-workspace-packages.cjs && node scripts/postinstall.js",
|
||||
"postinstall": "node scripts/link-workspace-packages.cjs && node scripts/ensure-workspace-builds.cjs && 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",
|
||||
|
|
|
|||
58
scripts/ensure-workspace-builds.cjs
Normal file
58
scripts/ensure-workspace-builds.cjs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* ensure-workspace-builds.cjs
|
||||
*
|
||||
* Checks whether workspace packages have been compiled (dist/ exists with
|
||||
* index.js). If any are missing, runs the build for those packages.
|
||||
*
|
||||
* Designed for the postinstall hook so that `npm install` in a fresh clone
|
||||
* produces a working runtime without a manual `npm run build` step.
|
||||
*
|
||||
* Skipped in CI (where the full build pipeline handles this) and when
|
||||
* installing as an end-user dependency (no packages/ directory).
|
||||
*/
|
||||
const { existsSync } = require('fs')
|
||||
const { resolve, join } = require('path')
|
||||
const { execSync } = require('child_process')
|
||||
|
||||
const root = resolve(__dirname, '..')
|
||||
const packagesDir = join(root, 'packages')
|
||||
|
||||
// Skip if packages/ doesn't exist (published tarball / end-user install)
|
||||
if (!existsSync(packagesDir)) process.exit(0)
|
||||
|
||||
// Skip in CI — the pipeline runs `npm run build` explicitly
|
||||
if (process.env.CI === 'true' || process.env.CI === '1') process.exit(0)
|
||||
|
||||
// Workspace packages that need dist/index.js at runtime.
|
||||
// Order matters: dependencies must build before dependents.
|
||||
const WORKSPACE_PACKAGES = [
|
||||
'native',
|
||||
'pi-tui',
|
||||
'pi-ai',
|
||||
'pi-agent-core',
|
||||
'pi-coding-agent',
|
||||
]
|
||||
|
||||
const missing = []
|
||||
for (const pkg of WORKSPACE_PACKAGES) {
|
||||
const distIndex = join(packagesDir, pkg, 'dist', 'index.js')
|
||||
if (!existsSync(distIndex)) {
|
||||
missing.push(pkg)
|
||||
}
|
||||
}
|
||||
|
||||
if (missing.length === 0) process.exit(0)
|
||||
|
||||
process.stderr.write(` Building ${missing.length} workspace package(s) missing dist/: ${missing.join(', ')}\n`)
|
||||
|
||||
for (const pkg of missing) {
|
||||
const pkgDir = join(packagesDir, pkg)
|
||||
try {
|
||||
execSync('npm run build', { cwd: pkgDir, stdio: 'pipe' })
|
||||
process.stderr.write(` ✓ ${pkg}\n`)
|
||||
} catch (err) {
|
||||
process.stderr.write(` ✗ ${pkg} build failed: ${err.message}\n`)
|
||||
// Non-fatal — the user can run `npm run build` manually
|
||||
}
|
||||
}
|
||||
|
|
@ -424,7 +424,7 @@ export function buildSkillActivationBlock(params: {
|
|||
params.taskPlanContent ?? undefined,
|
||||
);
|
||||
|
||||
const visibleSkills = getLoadedSkills().filter(skill => !skill.disableModelInvocation);
|
||||
const visibleSkills = (typeof getLoadedSkills === 'function' ? getLoadedSkills() : []).filter(skill => !skill.disableModelInvocation);
|
||||
const installedNames = new Set(visibleSkills.map(skill => normalizeSkillReference(skill.name)));
|
||||
const avoided = new Set(resolvePreferenceSkillNames(prefs?.avoid_skills ?? [], params.base));
|
||||
const matched = new Set<string>();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue