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);