azclaude-copilot 0.5.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -758,11 +758,11 @@ An agent is a sub-process. Use one when work must happen **in parallel** or **in
758
758
 
759
759
  ## Verified
760
760
 
761
- 1767 tests. Every template, command, capability, agent, hook, and CLI feature verified.
761
+ 1775 tests. Every template, command, capability, agent, hook, and CLI feature verified.
762
762
 
763
763
  ```bash
764
764
  bash tests/test-features.sh
765
- # Results: 1767 passed, 0 failed, 1767 total
765
+ # Results: 1775 passed, 0 failed, 1775 total
766
766
  ```
767
767
 
768
768
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "azclaude-copilot",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "AI coding environment — 39 commands, 10 skills, 15 agents, memory, reflexes, evolution. Install: npx azclaude-copilot@latest, then open Claude Code.",
5
5
  "bin": {
6
6
  "azclaude": "bin/cli.js",
@@ -195,6 +195,48 @@ try {
195
195
  }
196
196
  } catch (_) {}
197
197
 
198
+ // ── Compaction Guard — auto-snapshot before context is lost ─────────────────
199
+ // Reads context % signal from statusline (written to temp file after each turn).
200
+ // At >= 70%: warns Claude to save state. At >= 85%: auto-saves checkpoint.
201
+ try {
202
+ const ctxSignalPath = path.join(os.tmpdir(), `.azclaude-ctx-${process.ppid || process.pid}`);
203
+ if (fs.existsSync(ctxSignalPath)) {
204
+ const ctxSignal = JSON.parse(fs.readFileSync(ctxSignalPath, 'utf8'));
205
+ const pct = ctxSignal.ctxPct || 0;
206
+
207
+ if (pct >= 85) {
208
+ // AUTO-SAVE: context is critically high — save checkpoint before compaction wipes it
209
+ const checkpointDir = path.join(cfg, 'memory', 'checkpoints');
210
+ try { fs.mkdirSync(checkpointDir, { recursive: true }); } catch (_) {}
211
+ const ts = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 16);
212
+ const cpPath = path.join(checkpointDir, `${ts}-auto-compaction.md`);
213
+
214
+ // Only auto-save once per threshold crossing (check if already saved)
215
+ const autoSaveMarker = path.join(os.tmpdir(), `.azclaude-autosave-${process.ppid || process.pid}`);
216
+ if (!fs.existsSync(autoSaveMarker)) {
217
+ // Copy goals.md as checkpoint
218
+ if (fs.existsSync(goalsPath)) {
219
+ const goalsContent = fs.readFileSync(goalsPath, 'utf8');
220
+ const header = `---\ndate: ${new Date().toISOString()}\nlabel: auto-compaction-guard-${pct}pct\nfiles_in_progress: []\n---\n\n`;
221
+ fs.writeFileSync(cpPath, header + '## Auto-saved before compaction\n\n' + goalsContent);
222
+ fs.writeFileSync(autoSaveMarker, '');
223
+ }
224
+
225
+ console.log('');
226
+ console.log(`--- COMPACTION GUARD (${pct}%) ---`);
227
+ console.log(`Context at ${pct}% — AUTO-SAVED checkpoint to ${path.basename(cpPath)}`);
228
+ console.log('Run /snapshot NOW to save your reasoning and decisions (goals.md alone is not enough).');
229
+ console.log('--- END GUARD ---');
230
+ }
231
+ } else if (pct >= 70) {
232
+ console.log('');
233
+ console.log(`--- COMPACTION WARNING (${pct}%) ---`);
234
+ console.log(`Context at ${pct}% — compaction approaching. Run /snapshot to save session state.`);
235
+ console.log('--- END WARNING ---');
236
+ }
237
+ }
238
+ } catch (_) {}
239
+
198
240
  // ── First message only — inject full context ────────────────────────────────
199
241
  if (!isFirstMessage) process.exit(0);
200
242
 
@@ -117,6 +117,13 @@ process.stdin.on('end', () => {
117
117
  const empty = 10 - filled;
118
118
  const bar = '\u2593'.repeat(filled) + '\u2591'.repeat(empty);
119
119
 
120
+ // ── Compaction signal — write context % to temp file for hook to read ──
121
+ // This enables the UserPromptSubmit hook to auto-snapshot before compaction.
122
+ try {
123
+ const signalPath = path.join(require('os').tmpdir(), `.azclaude-ctx-${process.ppid || process.pid}`);
124
+ fs.writeFileSync(signalPath, JSON.stringify({ ctxPct, turnsLeft: compactHint ? parseInt(compactHint.replace(/[^0-9]/g,'')) : 999 }));
125
+ } catch (_) {}
126
+
120
127
  // ── Color thresholds ──
121
128
  let ctxColor, ctxWarn = '';
122
129
  if (ctxPct >= 80) { ctxColor = RED; ctxWarn = ' COMPACT SOON'; }