import crypto from 'node:crypto'; import fs from 'node:fs/promises'; import path from 'node:path'; const AGENT_NAME = 'Claude Code'; const BASE_URL = String(process.env.FABRIQUE_BASE_URL || 'https://lblaster.com').replace(/\/+$/, ''); const API_BASE = BASE_URL + '/api/v1'; const SOURCE_FILE = path.resolve(process.env.FABRIQUE_SOURCE_FILE || 'dist/index.html'); const STATE_FILE = path.resolve(process.env.FABRIQUE_STATE_FILE || '.fabrique/claude-code-state.json'); const SLUG = String(process.env.FABRIQUE_SLUG || '').trim(); const html = await fs.readFile(SOURCE_FILE, 'utf8'); const htmlHash = crypto.createHash('sha256').update(html).digest('hex'); let state = null; try { state = JSON.parse(await fs.readFile(STATE_FILE, 'utf8')); } catch {} if (state && state.lastHash === htmlHash && state.url) { console.log('[' + AGENT_NAME + '] Aucun changement HTML detecte. URL conservee : ' + state.url); process.exit(0); } const hasExistingDeploy = !!(state && state.siteId && state.deleteToken); const endpoint = hasExistingDeploy ? API_BASE + '/sites/' + encodeURIComponent(state.siteId) : API_BASE + '/sites'; const payload = { html }; if (SLUG && !hasExistingDeploy) payload.slug = SLUG; const response = await fetch(endpoint, { method: hasExistingDeploy ? 'PUT' : 'POST', headers: { 'Content-Type': 'application/json', ...(hasExistingDeploy ? { 'X-Delete-Token': state.deleteToken } : {}) }, body: JSON.stringify(payload) }); const result = await response.json().catch(function () { return {}; }); if (!response.ok) { throw new Error(result.message || result.error || '[' + AGENT_NAME + '] Publication Fabrique impossible.'); } const data = result.data || result; const siteId = data.siteId || (state && state.siteId) || ''; const deleteToken = data.deleteToken || (state && state.deleteToken) || ''; const publicUrl = data.url || (siteId ? BASE_URL + '/fabric/' + siteId : ''); await fs.mkdir(path.dirname(STATE_FILE), { recursive: true }); await fs.writeFile(STATE_FILE, JSON.stringify({ agent: AGENT_NAME, siteId: siteId, deleteToken: deleteToken, url: publicUrl, lastHash: htmlHash, updatedAt: new Date().toISOString() }, null, 2)); console.log('[' + AGENT_NAME + '] Publication terminee : ' + publicUrl); console.log('[' + AGENT_NAME + '] Ajoute ce script dans .claude/settings.local.json via un hook PostToolUse ou Stop.');