Summary
scaffold renames _npmrc → .npmrc from the template (via copyTemplate), then unconditionally overwrites that .npmrc when a non-default npm registry is detected. Any content the template had in _npmrc is silently lost.
Root Cause
packages/agent-core/src/scaffold.ts:
// Step 1: renames template's _npmrc → .npmrc
copyTemplate(templateDir, targetDir, replacements);
// Step 2: overwrites it entirely
if (sapiomRegistry !== DEFAULT_REGISTRY) {
writeFileSync(
path.join(targetDir, ".npmrc"),
`@sapiom:registry=${sapiomRegistry}\n`, // ❌ template content gone
);
}
DOTFILE_NAMES explicitly includes "_npmrc", so templates are expected to carry npmrc content. For any developer using a custom/private registry (Verdaccio, private npm), that content is silently dropped.
Fix
Append to the existing file instead of overwriting:
const npmrcPath = path.join(targetDir, ".npmrc");
const existing = existsSync(npmrcPath) ? readFileSync(npmrcPath, "utf8") : "";
const line = `@sapiom:registry=${sapiomRegistry}\n`;
if (!existing.includes(line)) {
writeFileSync(npmrcPath, existing + line);
}
Summary
scaffoldrenames_npmrc→.npmrcfrom the template (viacopyTemplate), then unconditionally overwrites that.npmrcwhen a non-default npm registry is detected. Any content the template had in_npmrcis silently lost.Root Cause
packages/agent-core/src/scaffold.ts:DOTFILE_NAMESexplicitly includes"_npmrc", so templates are expected to carry npmrc content. For any developer using a custom/private registry (Verdaccio, private npm), that content is silently dropped.Fix
Append to the existing file instead of overwriting: