Problem
The installer copies all hook files to every project regardless of tier:
// ide-config-generator.js:678
const HOOKS_TO_COPY = [
'synapse-engine.cjs',
'code-intel-pretool.cjs',
'precompact-session-digest.cjs', // ← only useful with aios-pro
'README.md',
];
precompact-session-digest.cjs is a PreCompact hook that:
- Detects if
aios-pro is installed
- If yes → extracts a session digest before context compaction
- If no → silent no-op (
aios-pro not available, skipping)
For free/community users, this hook:
- Is always copied (unnecessary file)
- Is always registered in
settings.local.json (unnecessary entry)
- Always results in a no-op (wasted process spawn on every compact)
Additionally, the hook is written as a module export (module.exports = async (context) => {...}) but registered as a command hook in settings.local.json. Command hooks must read JSON from stdin and write JSON to stdout — this hook does neither, causing errors when invoked as a command.
Proposed Solution
1. Tier-aware hook installation
During the wizard install step (where user selects free vs pro), conditionally select which hooks to copy:
const HOOKS_FREE = [
'synapse-engine.cjs',
'code-intel-pretool.cjs',
'README.md',
];
const HOOKS_PRO = [
...HOOKS_FREE,
'precompact-session-digest.cjs',
];
const HOOKS_TO_COPY = wizardState.tier === 'pro' ? HOOKS_PRO : HOOKS_FREE;
2. Rewrite precompact hook as command hook
precompact-session-digest.cjs currently exports a function (module pattern). For it to work as a Claude Code command hook registered in settings.local.json, it needs a stdin/stdout wrapper similar to synapse-engine.cjs:
// Read JSON from stdin
const input = await readStdin();
// Call the digest logic
await onPreCompact(input);
// Write result to stdout
process.stdout.write(JSON.stringify({ hookSpecificOutput: { ... } }));
Without this rewrite, even pro users will get errors when the hook is invoked as a command.
3. Dynamic registration in settings.local.json
createClaudeSettingsLocal() already reads from the hooks directory dynamically, so as long as step 1 doesn't copy the file for free users, it won't be registered. No change needed here.
Files to Modify
| File |
Change |
packages/installer/src/wizard/ide-config-generator.js |
Tier-aware HOOKS_TO_COPY |
.claude/hooks/precompact-session-digest.cjs |
Rewrite as command hook (stdin/stdout) |
.aios-core/hooks/unified/runners/precompact-runner.js |
May need adapter for command hook pattern |
Context
Problem
The installer copies all hook files to every project regardless of tier:
precompact-session-digest.cjsis a PreCompact hook that:aios-prois installedaios-pro not available, skipping)For free/community users, this hook:
settings.local.json(unnecessary entry)Additionally, the hook is written as a module export (
module.exports = async (context) => {...}) but registered as a command hook insettings.local.json. Command hooks must read JSON from stdin and write JSON to stdout — this hook does neither, causing errors when invoked as a command.Proposed Solution
1. Tier-aware hook installation
During the wizard install step (where user selects free vs pro), conditionally select which hooks to copy:
2. Rewrite precompact hook as command hook
precompact-session-digest.cjscurrently exports a function (module pattern). For it to work as a Claude Code command hook registered insettings.local.json, it needs a stdin/stdout wrapper similar tosynapse-engine.cjs:Without this rewrite, even pro users will get errors when the hook is invoked as a command.
3. Dynamic registration in settings.local.json
createClaudeSettingsLocal()already reads from the hooks directory dynamically, so as long as step 1 doesn't copy the file for free users, it won't be registered. No change needed here.Files to Modify
packages/installer/src/wizard/ide-config-generator.jsHOOKS_TO_COPY.claude/hooks/precompact-session-digest.cjs.aios-core/hooks/unified/runners/precompact-runner.jsContext
HOOK_EVENT_MAPalready correctly mapsprecompact-session-digest.cjs→PreCompactevent (MIS-3.1)pro-detector.jsalready exists atbin/utils/pro-detector.jsfor tier detection at runtime