scripts/ci-state-update.mjs
scripts/ci-state-update.mjsBrowse 4 files
1,203 tokens
4,644 bytes
Token encoding: o200k_base
Snapshot 646e806
← Back to SKILL.md
1#!/usr/bin/env node2 3/**4 * CI State Update Script5 *6 * Deterministic state management for CI monitor actions.7 * Three commands: gate, post-action, cycle-check.8 *9 * Usage:10 * node ci-state-update.mjs gate --gate-type <local-fix|env-rerun> [counter args]11 * node ci-state-update.mjs post-action --action <type> [--cipe-url <url>] [--commit-sha <sha>]12 * node ci-state-update.mjs cycle-check --code <code> [--agent-triggered] [counter args]13 */14 15// --- Arg parsing ---16 17const args = process.argv.slice(2);18const command = args[0];19 20function getFlag(name) {21 return args.includes(name);22}23 24function getArg(name) {25 const idx = args.indexOf(name);26 return idx !== -1 && idx + 1 < args.length ? args[idx + 1] : null;27}28 29function output(result) {30 console.log(JSON.stringify(result));31}32 33// --- gate ---34// Check if an action is allowed and return incremented counter.35// Called before any local fix attempt or environment rerun.36 37function gate() {38 const gateType = getArg('--gate-type');39 40 if (gateType === 'local-fix') {41 const count = parseInt(getArg('--local-verify-count') || '0', 10);42 const max = parseInt(getArg('--local-verify-attempts') || '3', 10);43 if (count >= max) {44 return output({45 allowed: false,46 localVerifyCount: count,47 message: `Local fix budget exhausted (${count}/${max} attempts)`,48 });49 }50 return output({51 allowed: true,52 localVerifyCount: count + 1,53 message: null,54 });55 }56 57 if (gateType === 'env-rerun') {58 const count = parseInt(getArg('--env-rerun-count') || '0', 10);59 if (count >= 2) {60 return output({61 allowed: false,62 envRerunCount: count,63 message: `Environment issue persists after ${count} reruns. Manual investigation needed.`,64 });65 }66 return output({67 allowed: true,68 envRerunCount: count + 1,69 message: null,70 });71 }72 73 output({ allowed: false, message: `Unknown gate type: ${gateType}` });74}75 76// --- post-action ---77// Compute next state after an action is taken.78// Returns wait mode params and whether the action was agent-triggered.79 80function postAction() {81 const action = getArg('--action');82 const cipeUrl = getArg('--cipe-url');83 const commitSha = getArg('--commit-sha');84 85 // MCP-triggered or auto-applied: track by cipeUrl86 const cipeUrlActions = ['fix-auto-applying', 'apply-mcp', 'env-rerun'];87 // Local push: track by commitSha88 const commitShaActions = [89 'apply-local-push',90 'reject-fix-push',91 'local-fix-push',92 'auto-fix-push',93 'empty-commit-push',94 ];95 96 const trackByCipeUrl = cipeUrlActions.includes(action);97 const trackByCommitSha = commitShaActions.includes(action);98 99 if (!trackByCipeUrl && !trackByCommitSha) {100 return output({ error: `Unknown action: ${action}` });101 }102 103 // fix-auto-applying: self-healing did it, NOT the monitor104 const agentTriggered = action !== 'fix-auto-applying';105 106 output({107 waitMode: true,108 pollCount: 0,109 lastCipeUrl: trackByCipeUrl ? cipeUrl : null,110 expectedCommitSha: trackByCommitSha ? commitSha : null,111 agentTriggered,112 });113}114 115// --- cycle-check ---116// Cycle classification + counter resets when a new "done" code is received.117// Called at the start of handling each actionable code.118 119function cycleCheck() {120 const status = getArg('--code');121 const wasAgentTriggered = getFlag('--agent-triggered');122 let cycleCount = parseInt(getArg('--cycle-count') || '0', 10);123 const maxCycles = parseInt(getArg('--max-cycles') || '10', 10);124 let envRerunCount = parseInt(getArg('--env-rerun-count') || '0', 10);125 126 // Cycle classification: if previous cycle was agent-triggered, count it127 if (wasAgentTriggered) cycleCount++;128 129 // Reset env_rerun_count on non-environment status130 if (status !== 'environment_issue') envRerunCount = 0;131 132 // Cycle limit gates. limitReached is a terminal stop; approachingLimit is an133 // advisory warning emitted in the two cycles before the cap.134 const limitReached = cycleCount >= maxCycles;135 const approachingLimit = cycleCount >= maxCycles - 2;136 137 output({138 cycleCount,139 agentTriggered: false,140 envRerunCount,141 approachingLimit,142 limitReached,143 message: limitReached144 ? `Cycle limit reached (${cycleCount}/${maxCycles}). Stopping.`145 : approachingLimit146 ? `Approaching cycle limit (${cycleCount}/${maxCycles})`147 : null,148 });149}150 151// --- Dispatch ---152 153switch (command) {154 case 'gate':155 gate();156 break;157 case 'post-action':158 postAction();159 break;160 case 'cycle-check':161 cycleCheck();162 break;163 default:164 output({ error: `Unknown command: ${command}` });165}166