tractatus/scripts/check-token-checkpoint.js
TheFlow ac2db33732 fix(submissions): restructure Economist package and fix article display
- Create Economist SubmissionTracking package correctly:
  * mainArticle = full blog post content
  * coverLetter = 216-word SIR— letter
  * Links to blog post via blogPostId
- Archive 'Letter to The Economist' from blog posts (it's the cover letter)
- Fix date display on article cards (use published_at)
- Target publication already displaying via blue badge

Database changes:
- Make blogPostId optional in SubmissionTracking model
- Economist package ID: 68fa85ae49d4900e7f2ecd83
- Le Monde package ID: 68fa2abd2e6acd5691932150

Next: Enhanced modal with tabs, validation, export

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 08:47:42 +13:00

248 lines
6.5 KiB
JavaScript
Executable file

#!/usr/bin/env node
/**
* Token Checkpoint Monitor
*
* Checks if current token usage has passed defined checkpoints
* and generates pressure reports when thresholds are crossed.
*
* Usage:
* node scripts/check-token-checkpoint.js --tokens 55000
* node scripts/check-token-checkpoint.js --tokens 55000/200000
*
* This should be called AFTER each response when token count is visible
* in <system-warning> tags.
*
* Copyright 2025 Tractatus Project
* Licensed under Apache License 2.0
*/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const TOKEN_CHECKPOINTS_PATH = path.join(__dirname, '../.claude/token-checkpoints.json');
const SESSION_STATE_PATH = path.join(__dirname, '../.claude/session-state.json');
/**
* Color output
*/
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
red: '\x1b[31m',
cyan: '\x1b[36m'
};
function log(message, color = 'reset') {
console.log(`${colors[color]}${message}${colors.reset}`);
}
function header(message) {
console.log('');
log('═'.repeat(70), 'cyan');
log(` ${message}`, 'bright');
log('═'.repeat(70), 'cyan');
console.log('');
}
function section(message) {
console.log('');
log(`${message}`, 'blue');
}
function success(message) {
log(`${message}`, 'green');
}
function warning(message) {
log(`${message}`, 'yellow');
}
function error(message) {
log(`${message}`, 'red');
}
/**
* Parse token count from command line
*/
function parseTokenCount(arg) {
if (!arg) {
error('No token count provided');
console.log('Usage: node scripts/check-token-checkpoint.js --tokens 55000');
console.log(' or: node scripts/check-token-checkpoint.js --tokens 55000/200000');
process.exit(1);
}
// Handle both "55000" and "55000/200000" formats
const parts = arg.split('/');
const current = parseInt(parts[0]);
const budget = parts.length > 1 ? parseInt(parts[1]) : 200000;
if (isNaN(current) || isNaN(budget)) {
error(`Invalid token count: ${arg}`);
process.exit(1);
}
return { current, budget };
}
/**
* Load checkpoint configuration
*/
function loadCheckpoints() {
try {
if (!fs.existsSync(TOKEN_CHECKPOINTS_PATH)) {
error('Token checkpoints file not found');
error('Run: node scripts/session-init.js');
process.exit(1);
}
return JSON.parse(fs.readFileSync(TOKEN_CHECKPOINTS_PATH, 'utf8'));
} catch (err) {
error(`Failed to load checkpoints: ${err.message}`);
process.exit(1);
}
}
/**
* Check if any checkpoints have been passed
*/
function checkCheckpoints(current, checkpoints) {
const passed = [];
const upcoming = [];
for (const checkpoint of checkpoints.checkpoints) {
if (current >= checkpoint.tokens && !checkpoint.completed) {
passed.push(checkpoint);
} else if (current < checkpoint.tokens) {
upcoming.push(checkpoint);
}
}
return { passed, upcoming };
}
/**
* Mark checkpoint as completed
*/
function markCheckpointCompleted(checkpoints, checkpoint) {
const idx = checkpoints.checkpoints.findIndex(c => c.tokens === checkpoint.tokens);
if (idx !== -1) {
checkpoints.checkpoints[idx].completed = true;
checkpoints.checkpoints[idx].timestamp = new Date().toISOString();
}
// Update next_checkpoint to next uncompleted
const nextUncompleted = checkpoints.checkpoints.find(c => !c.completed);
checkpoints.next_checkpoint = nextUncompleted ? nextUncompleted.tokens : null;
checkpoints.overdue = false;
checkpoints.last_check = new Date().toISOString();
fs.writeFileSync(TOKEN_CHECKPOINTS_PATH, JSON.stringify(checkpoints, null, 2));
}
/**
* Generate pressure report for checkpoint
*/
function generatePressureReport(current, budget, checkpoint) {
try {
section(`Generating Pressure Report for ${checkpoint.percentage}% Checkpoint`);
const output = execSync(
`node scripts/check-session-pressure.js --tokens ${current}/${budget} --messages 1 --tasks 0`,
{ encoding: 'utf8', stdio: 'pipe' }
);
console.log(output);
return true;
} catch (err) {
error(`Pressure report failed: ${err.message}`);
return false;
}
}
/**
* Main execution
*/
function main() {
// Parse arguments
const args = process.argv.slice(2);
const tokensIdx = args.indexOf('--tokens');
if (tokensIdx === -1 || tokensIdx === args.length - 1) {
error('Missing --tokens argument');
console.log('Usage: node scripts/check-token-checkpoint.js --tokens 55000');
process.exit(1);
}
const tokenArg = args[tokensIdx + 1];
const { current, budget } = parseTokenCount(tokenArg);
header('Token Checkpoint Monitor');
log(` Current Token Usage: ${current.toLocaleString()} / ${budget.toLocaleString()}`, 'cyan');
log(` Percentage: ${((current / budget) * 100).toFixed(1)}%`, 'cyan');
// Load checkpoints
const checkpoints = loadCheckpoints();
// Check which checkpoints passed
const { passed, upcoming } = checkCheckpoints(current, checkpoints);
if (passed.length === 0) {
section('Checkpoint Status');
success('No new checkpoints passed');
if (upcoming.length > 0) {
const next = upcoming[0];
const remaining = next.tokens - current;
log(` Next checkpoint: ${next.tokens.toLocaleString()} tokens (${next.percentage}%)`, 'cyan');
log(` Remaining: ${remaining.toLocaleString()} tokens`, 'cyan');
} else {
success('All checkpoints completed!');
}
return;
}
// Process passed checkpoints
section('Checkpoints Passed');
for (const checkpoint of passed) {
warning(`Checkpoint ${checkpoint.percentage}% (${checkpoint.tokens.toLocaleString()} tokens) PASSED`);
// Mark as completed
markCheckpointCompleted(checkpoints, checkpoint);
success(`Marked checkpoint ${checkpoint.percentage}% as completed`);
// Generate pressure report
generatePressureReport(current, budget, checkpoint);
}
// Show upcoming checkpoints
if (upcoming.length > 0) {
section('Upcoming Checkpoints');
for (const checkpoint of upcoming) {
const remaining = checkpoint.tokens - current;
log(` ${checkpoint.percentage}%: ${checkpoint.tokens.toLocaleString()} tokens (${remaining.toLocaleString()} remaining)`, 'cyan');
}
}
console.log('');
log('═'.repeat(70), 'cyan');
success('Checkpoint monitoring complete');
log('═'.repeat(70), 'cyan');
console.log('');
}
// Run if called directly
if (require.main === module) {
main();
}
module.exports = { parseTokenCount, loadCheckpoints, checkCheckpoints };