Job 1788336949112

Command: powershell -NoProfile -Command "Get-Content -LiteralPath 'C:\Users\ash\ChatGPTMasterBridge\Code.gs' -TotalCount 180"
Directory: projects
Status: SUCCESS
Exit code: 0

Cancel Job Rerun Command Refresh

const MASTER_REVISION = '20260902-master-bridge-v1';
const MASTER_ID = 'chatgpt-master-bridge-v1';
const DEFAULT_TARGET = 'pc';
const DEFAULT_SPREADSHEET_ID = '1HkbrZ7Phos3GVMBhi-1xPDr3wIBxRcBF6mNzabYqhmE';
const REGISTRY_PROPERTY = 'MASTER_BRIDGE_REGISTRY_V1';
const RELAY_KEY_PROPERTY = 'BRIDGE_RELAY_KEY';
const COMMANDS_SHEET = 'commands';
const RESULTS_SHEET = 'results';
const STATE_SHEET = 'state';
const ARTIFACTS_SHEET = 'artifacts';
const MAX_CELL_CHARS = 45000;

const COMMAND_HEADERS = ['id', 'created_at', 'action', 'payload_json', 'status', 'confirm', 'claimed_at', 'completed_at', 'result_ref', 'error', 'attempts', 'notes'];
const RESULT_HEADERS = ['id', 'command_id', 'completed_at', 'status', 'http_status', 'result_text', 'error', 'duration_ms', 'result_sha256', 'truncated'];
const STATE_HEADERS = ['key', 'value', 'updated_at', 'notes'];
const ARTIFACT_HEADERS = ['id', 'command_id', 'name', 'mime_type', 'size', 'sha256', 'drive_url_or_ref', 'created_at'];

function doGet(e) {
  return handleRequest_(e, null);
}

function doPost(e) {
  let body = {};
  if (e && e.postData && e.postData.contents) {
    try {
      body = JSON.parse(e.postData.contents);
    } catch (err) {
      return json_({ ok: false, error: 'invalid_json' }, 400);
    }
  }
  return handleRequest_(e, body);
}

function handleRequest_(e, body) {
  const params = (e && e.parameter) || {};
  const action = String((body && body.action) || params.action || 'status');
  const key = String((body && (body.relay_key || body.key)) || params.relay_key || params.key || '');
  const target = normalizeTarget_((body && body.target) || params.target || DEFAULT_TARGET);

  if (!validKey_(key, target)) {
    return json_({ ok: false, error: 'not_found' }, 404);
  }

  const lock = LockService.getScriptLock();
  lock.waitLock(10000);
  try {
    if (action === 'master_status') return masterStatus_();
    if (action === 'list_bridges') return listBridges_();
    if (action === 'create_bridge') return createBridge_(body || params || {});
    if (action === 'archive_bridge') return archiveBridge_(target);
    if (action === 'restore_bridge') return restoreBridge_(target);
    if (action === 'delete_bridge') return deleteBridge_(target, body || params || {});

    const bridge = requireBridge_(target, false);
    ensureSheets_(bridge.spreadsheet_id, target);

    if (action === 'status') return status_(bridge, target);
    if (action === 'poll') return poll_(bridge, target);
    if (action === 'result') return result_(bridge, target, body || {});
    if (action === 'heartbeat') return heartbeat_(bridge, target, body || {});
    return json_({ ok: false, error: 'unknown_action' }, 400);
  } catch (err) {
    return json_({ ok: false, error: String(err && err.message ? err.message : err) }, 500);
  } finally {
    lock.releaseLock();
  }
}

function validKey_(key, target) {
  const props = PropertiesService.getScriptProperties();
  let expected = props.getProperty(RELAY_KEY_PROPERTY) || '';

  // Zero-touch migration from the existing PC bridge: until the Master Script
  // owns a relay key in Script Properties, reuse the legacy PC state value.
  if (!expected) {
    try {
      expected = getStateValueById_(DEFAULT_SPREADSHEET_ID, 'relay_key') || '';
      if (expected && key === expected) props.setProperty(RELAY_KEY_PROPERTY, expected);
    } catch (err) {
      expected = '';
    }
  }
  return Boolean(expected && key && key === expected);
}

function registry_() {
  const props = PropertiesService.getScriptProperties();
  let registry = {};
  const raw = props.getProperty(REGISTRY_PROPERTY);
  if (raw) {
    try { registry = JSON.parse(raw) || {}; } catch (err) { registry = {}; }
  }

  // Seed the existing PC bridge automatically; no manual registration required.
  if (!registry[DEFAULT_TARGET]) {
    registry[DEFAULT_TARGET] = {
      target: DEFAULT_TARGET,
      spreadsheet_id: DEFAULT_SPREADSHEET_ID,
      title: 'ChatGPT Bridge Control',
      status: 'active',
      managed: false,
      created_at: '',
      updated_at: nowIso_(),
      revision: MASTER_REVISION
    };
    saveRegistry_(registry);
  }
  return registry;
}

function saveRegistry_(registry) {
  PropertiesService.getScriptProperties().setProperty(REGISTRY_PROPERTY, JSON.stringify(registry));
}

function normalizeTarget_(target) {
  const value = String(target || '').trim().toLowerCase();
  if (!value) return DEFAULT_TARGET;
  if (!/^[a-z0-9][a-z0-9._-]{1,63}$/.test(value)) throw new Error('invalid_target');
  return value;
}

function requireBridge_(target, allowArchived) {
  const registry = registry_();
  const bridge = registry[target];
  if (!bridge) throw new Error('unknown_target');
  if (bridge.status === 'deleted') throw new Error('target_deleted');
  if (!allowArchived && bridge.status !== 'active') throw new Error('target_not_active');
  return bridge;
}

function masterStatus_() {
  const registry = registry_();
  const targets = Object.keys(registry);
  let active = 0;
  let archived = 0;
  targets.forEach(function (t) {
    if (registry[t].status === 'active') active++;
    if (registry[t].status === 'archived') archived++;
  });
  return json_({
    ok: true,
    revision: MASTER_REVISION,
    master_id: MASTER_ID,
    default_target: DEFAULT_TARGET,
    bridge_count: targets.length,
    active_count: active,
    archived_count: archived,
    updated_at: nowIso_()
  });
}

function listBridges_() {
  const registry = registry_();
  const items = Object.keys(registry).sort().map(function (target) {
    const b = registry[target];
    return {
      target: target,
      title: b.title || '',
      spreadsheet_id: b.spreadsheet_id || '',
      status: b.status || 'unknown',
      managed: Boolean(b.managed),
      created_at: b.created_at || '',
      updated_at: b.updated_at || ''
    };
  });
  return json_({ ok: true, revision: MASTER_REVISION, bridges: items });
}

function createBridge_(body) {
  const target = normalizeTarget_(body.target || '');
  if (target === DEFAULT_TARGET) return json_({ ok: false, error: 'reserved_target' }, 400);

  const registry = registry_();
  if (registry[target] && registry[target].status !== 'deleted') {
    return json_({ ok: false, error: 'target_exists', bridge: registry[target] }, 409);
  }

  const title = sanitizeTitle_(String(body.title || ('ChatGPT Bridge - ' + target)));
  const ss = SpreadsheetApp.create(title);
  initializeManagedSpreadsheet_(ss, target);